diff --git a/docs/bundle.js b/docs/bundle.js index 40225ef..93f1327 100644 --- a/docs/bundle.js +++ b/docs/bundle.js @@ -1 +1 @@ -(()=>{"use strict";var __webpack_modules__={221:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{eval("\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\nvar injectStylesIntoStyleTag = __webpack_require__(72);\nvar injectStylesIntoStyleTag_default = /*#__PURE__*/__webpack_require__.n(injectStylesIntoStyleTag);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleDomAPI.js\nvar styleDomAPI = __webpack_require__(825);\nvar styleDomAPI_default = /*#__PURE__*/__webpack_require__.n(styleDomAPI);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertBySelector.js\nvar insertBySelector = __webpack_require__(659);\nvar insertBySelector_default = /*#__PURE__*/__webpack_require__.n(insertBySelector);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\nvar setAttributesWithoutAttributes = __webpack_require__(56);\nvar setAttributesWithoutAttributes_default = /*#__PURE__*/__webpack_require__.n(setAttributesWithoutAttributes);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertStyleElement.js\nvar insertStyleElement = __webpack_require__(540);\nvar insertStyleElement_default = /*#__PURE__*/__webpack_require__.n(insertStyleElement);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleTagTransform.js\nvar styleTagTransform = __webpack_require__(113);\nvar styleTagTransform_default = /*#__PURE__*/__webpack_require__.n(styleTagTransform);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/css/common.css\nvar common = __webpack_require__(404);\n;// CONCATENATED MODULE: ./src/css/common.css\n\n \n \n \n \n \n \n \n \n \n\nvar options = {};\n\noptions.styleTagTransform = (styleTagTransform_default());\noptions.setAttributes = (setAttributesWithoutAttributes_default());\noptions.insert = insertBySelector_default().bind(null, \"head\");\noptions.domAPI = (styleDomAPI_default());\noptions.insertStyleElement = (insertStyleElement_default());\n\nvar update = injectStylesIntoStyleTag_default()(common/* default */.A, options);\n\n\n\n\n /* harmony default export */ const css_common = (common/* default */.A && common/* default */.A.locals ? common/* default */.A.locals : undefined);\n\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/welcome/welcome.css\nvar welcome = __webpack_require__(235);\n;// CONCATENATED MODULE: ./src/js/components/welcome/welcome.css\n\n \n \n \n \n \n \n \n \n \n\nvar welcome_options = {};\n\nwelcome_options.styleTagTransform = (styleTagTransform_default());\nwelcome_options.setAttributes = (setAttributesWithoutAttributes_default());\nwelcome_options.insert = insertBySelector_default().bind(null, \"head\");\nwelcome_options.domAPI = (styleDomAPI_default());\nwelcome_options.insertStyleElement = (insertStyleElement_default());\n\nvar welcome_update = injectStylesIntoStyleTag_default()(welcome/* default */.A, welcome_options);\n\n\n\n\n /* harmony default export */ const welcome_welcome = (welcome/* default */.A && welcome/* default */.A.locals ? welcome/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/welcome/welcome.js\n\n\n// Hide and unhide welcome buttons\nfunction unhideWelcomeButtons() {\n document.getElementById(\"welcome-page\").style.display = \"block\";\n}\nfunction hideWelcomeButtons() {\n document.getElementById(\"welcome-page\").style.display = \"none\";\n}\nconst Welcome = {\n show: unhideWelcomeButtons,\n hide: hideWelcomeButtons\n};\n/* harmony default export */ const components_welcome_welcome = (Welcome);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/prompt/prompt.css\nvar prompt_prompt = __webpack_require__(225);\n;// CONCATENATED MODULE: ./src/js/components/prompt/prompt.css\n\n \n \n \n \n \n \n \n \n \n\nvar prompt_options = {};\n\nprompt_options.styleTagTransform = (styleTagTransform_default());\nprompt_options.setAttributes = (setAttributesWithoutAttributes_default());\nprompt_options.insert = insertBySelector_default().bind(null, \"head\");\nprompt_options.domAPI = (styleDomAPI_default());\nprompt_options.insertStyleElement = (insertStyleElement_default());\n\nvar prompt_update = injectStylesIntoStyleTag_default()(prompt_prompt/* default */.A, prompt_options);\n\n\n\n\n /* harmony default export */ const components_prompt_prompt = (prompt_prompt/* default */.A && prompt_prompt/* default */.A.locals ? prompt_prompt/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/prompt/subcomponents/text.js\nfunction showPrompt() {\n document.getElementById(\"prompt-div\").style.display = \"block\";\n}\nfunction hidePrompt() {\n document.getElementById('prompt-div').style.display = 'none';\n}\nfunction updatePrompt(prompt) {\n document.getElementById('prompt').textContent = prompt;\n showPrompt();\n}\nconst Text = {\n show: showPrompt,\n hide: hidePrompt,\n update: function (text) {\n updatePrompt(text);\n }\n};\n/* harmony default export */ const subcomponents_text = (Text);\n;// CONCATENATED MODULE: ./src/js/components/prompt/subcomponents/buttons.js\nfunction showPromptButton(id) {\n // make buttons visible\n document.getElementById(id).style.display = 'inline';\n}\nfunction updatePromptButton(id, text) {\n document.getElementById(id).textContent = text;\n showPromptButton(id);\n}\nfunction hidePromptButton(id) {\n document.getElementById(id).style.display = 'none';\n}\nfunction unclickAll() {\n document.getElementById('option1').classList.remove('clicked');\n document.getElementById('option2').classList.remove('clicked');\n}\nfunction applyClickedStyle(button) {\n unclickAll();\n button.classList.add('clicked');\n}\nfunction addPromptButtonAction(button_id, action_fn) {\n const buttonElement = document.getElementById(button_id);\n buttonElement.addEventListener('click', action_fn);\n buttonElement.addEventListener('click', function () {\n applyClickedStyle(this);\n });\n}\nfunction removePromptButtonAction(button_id, action_fn) {\n document.getElementById(button_id).removeEventListener('click', action_fn);\n}\nfunction disable(button_id) {\n document.querySelector(`#${button_id}`).classList.add('disabled');\n}\nfunction enable(button_id) {\n document.querySelector(`#${button_id}`).classList.remove('disabled');\n}\nconst Left = {\n show: function () {\n showPromptButton('option1');\n },\n hide: function () {\n hidePromptButton('option1');\n },\n updateText: function (text) {\n updatePromptButton('option1', text);\n },\n addAction: function (action_fn) {\n addPromptButtonAction('option1', action_fn);\n },\n removeAction: function (action_fn) {\n removePromptButtonAction('option1', action_fn);\n },\n disable: function () {\n disable('option1');\n },\n enable: function () {\n enable('option1');\n }\n};\nconst Right = {\n show: function () {\n showPromptButton('option2');\n },\n hide: function () {\n hidePromptButton('option2');\n },\n updateText: function (text) {\n updatePromptButton('option2', text);\n },\n addAction: function (action_fn) {\n addPromptButtonAction('option2', action_fn);\n },\n removeAction: function (action_fn) {\n removePromptButtonAction('option2', action_fn);\n },\n disable: function () {\n disable('option2');\n },\n enable: function () {\n enable('option2');\n }\n};\nconst Buttons = {\n Left: Left,\n Right: Right,\n show: function () {\n showPromptButton('option1');\n showPromptButton('option2');\n },\n hide: function () {\n hidePromptButton('option1');\n hidePromptButton('option2');\n },\n reset: unclickAll\n};\n/* harmony default export */ const buttons = (Buttons);\n;// CONCATENATED MODULE: ./src/js/components/prompt/prompt.js\n\n\n\nconst Prompt = {\n Text: subcomponents_text,\n Buttons: buttons,\n hide: function () {\n subcomponents_text.hide();\n buttons.hide();\n },\n show: function () {\n subcomponents_text.show();\n buttons.show();\n }\n};\n/* harmony default export */ const js_components_prompt_prompt = (Prompt);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/sidebar/sidebar.css\nvar sidebar = __webpack_require__(263);\n;// CONCATENATED MODULE: ./src/js/components/sidebar/sidebar.css\n\n \n \n \n \n \n \n \n \n \n\nvar sidebar_options = {};\n\nsidebar_options.styleTagTransform = (styleTagTransform_default());\nsidebar_options.setAttributes = (setAttributesWithoutAttributes_default());\nsidebar_options.insert = insertBySelector_default().bind(null, \"head\");\nsidebar_options.domAPI = (styleDomAPI_default());\nsidebar_options.insertStyleElement = (insertStyleElement_default());\n\nvar sidebar_update = injectStylesIntoStyleTag_default()(sidebar/* default */.A, sidebar_options);\n\n\n\n\n /* harmony default export */ const sidebar_sidebar = (sidebar/* default */.A && sidebar/* default */.A.locals ? sidebar/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/constants/budget_constants.js\n// Set to equal current fiscal year\nvar FISCAL_YEAR = '26';\n\n// object categories (from obj part of account string)\nconst OBJ_CATEGORIES = {\n list: [\n // 'Salaries & Wages',\n // 'Employee Benefits',\n 'Professional & Contractual Services', 'Operating Supplies', 'Operating Services', 'Equipment Acquisition', 'Capital Outlays', 'Fixed Charges', 'Other Expenses']\n};\n\n// from the drop-down menu\nconst EMPLOYEE_TYPES = ['Regular', 'TASS', 'Seasonal', 'Uniform Fire', 'Uniform Police', 'Appointed', 'Elected', 'Long Term Disability'];\nconst OT_OBJECTS = ['601300 - Salar-Overtime-Gen City', '601305 - Salaries-Overtime-Police Unif', '601310 - Salaries-Overtime-Fire Unif', '602300 - Wages-Overtime-Gen City'];\n;// CONCATENATED MODULE: ./src/js/constants/excel_constants.js\n\n\n// sheets to expect on detail sheet\nconst SHEETS = {\n 'FTE, Salary-Wage, & Benefits': 'personnel',\n 'Overtime & Other Personnel': 'overtime',\n 'Non-Personnel': 'nonpersonnel',\n 'Revenue': 'revenue'\n};\n\n// where to find the general fund target\nconst TARGET_CELL_ADDRESS = 'C14';\nconst TOTAL_COLUMNS = {\n 'personnel': 'Total Sal/Wag & Ben Request',\n 'overtime': `FY${FISCAL_YEAR} Total OT/SP/Hol + FICA Request`,\n 'nonpersonnel': `FY${FISCAL_YEAR} Departmental Request Total`,\n 'revenue': `FY${FISCAL_YEAR} Departmental Estimate`\n};\n;// CONCATENATED MODULE: ./src/js/constants/index.js\n\n\n;// CONCATENATED MODULE: ./src/js/utils/common_utils.js\n// Function to format number as currency\nconst formatCurrency = (amount, return_zero = false) => {\n var amount = Math.round(parseFloat(amount));\n if (amount == NaN) {\n return \"$ -\";\n }\n if (amount < 0) {\n return '($' + amount.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',') + ')';\n } else if (amount == 0) {\n if (return_zero) {\n return '$0';\n }\n return \"$ -\";\n }\n return '$' + amount.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n};\n\n// function to convert formatted number to a float\nconst common_utils_unformatCurrency = formattedAmount => {\n if (!formattedAmount) {\n return 0;\n }\n ;\n // Remove any currency symbols and commas\n let numericalPart = formattedAmount.replace(/[^0-9.-]+/g, \"\");\n if (numericalPart == '-') {\n return 0;\n }\n return parseFloat(numericalPart);\n};\nfunction displayWithCommas(value) {\n if (value == 0) {\n return 0;\n }\n return formatCurrency(value).replace('$', '');\n}\nfunction cleanString(str) {\n return str.toLowerCase().replaceAll(' ', '-');\n}\nfunction removeNewLines(str) {\n // replace all new lines with spaces\n str = str.replaceAll(/[\\r\\n]+/g, \" \");\n // remove any extra spaces or trailing/leading whitespace\n str = str.replaceAll(' ', ' ');\n str = str.replaceAll(' ', ' ');\n str = str.replace(/^\\s+|\\s+$/g, '');\n return str;\n}\nfunction colSum(table, colName) {\n // fill with zero until there is something saved in storage\n if (!table || table == '') {\n return 0;\n }\n const headers = Object.keys(table[0]);\n if (headers.includes(colName)) {\n let sum = 0;\n for (let i = 0; i < table.length; i++) {\n var value = Math.round(parseFloat(table[i][colName]));\n // treat NaN (non-numerics) as zeroes\n if (value) {\n sum += value;\n }\n }\n return sum;\n } else {\n // console.error(`Could not find expected total column in saved data for ${name}. Returning 0. See StoredTable.totalCol() switch.`);\n return 0;\n }\n}\nfunction getUniqueValues(data, key) {\n const values = data.map(obj => obj[key]);\n return Array.from(new Set(values));\n}\n;// CONCATENATED MODULE: ./src/js/models/fund_lookup_table.js\n\n\nconst FundLookupTable = {\n retrieve: function () {\n return JSON.parse(localStorage.getItem('fund-lookup-table')) || {};\n },\n save: function (fundDict) {\n localStorage.setItem('fund-lookup-table', JSON.stringify(fundDict));\n },\n update: function (fundData) {\n const table = this.retrieve();\n for (let fund of Object.keys(fundData)) {\n // add to lookup table if not in there already\n if (!table[fund]) {\n // get fund name\n const fundName = fundData[fund][0]['Fund Name'];\n // add fund to dictionary\n table[fund] = {};\n table[fund]['name'] = fundName;\n table[fund]['viewed'] = false;\n // build lists of unique cost centers and appropriations\n table[fund]['approp'] = getUniqueValues(fundData[fund], 'Appropriation Name');\n table[fund]['cc'] = getUniqueValues(fundData[fund], 'Cost Center Name');\n }\n }\n // save any updates\n this.save(table);\n },\n getAll: function (key) {\n // function to aggregate all approps or CCs for every fund in one array\n const funds = this.retrieve();\n const ret = [];\n for (const fund in funds) {\n if (funds.hasOwnProperty(fund)) {\n for (let i in funds[fund][key]) {\n ret.push(funds[fund][key][i]);\n }\n }\n }\n return ret;\n },\n getCostCenters: function () {\n // get current fund\n const fund = current_fund.number();\n if (this.retrieve()[fund]) {\n return this.retrieve()[fund]['cc'];\n }\n // if no fund (ie. we're on the new initiative page), return all options\n return this.getAll('cc');\n },\n getApprops: function () {\n // get current fund\n const fund = current_fund.number();\n if (this.retrieve()[fund]) {\n return this.retrieve()[fund]['approp'];\n }\n // if no fund (ie. we're on the new initiative page), return all options\n return this.getAll('approp');\n },\n reset: function () {\n this.save({});\n },\n getName: function (number) {\n if (!number || !this.retrieve()) {\n return '';\n }\n ;\n return this.retrieve()[number]['name'];\n },\n listFunds: function () {\n return Object.keys(this.retrieve());\n },\n listFundNames: function () {\n const funds = this.retrieve();\n // initialize array\n var ret = [];\n Object.keys(funds).forEach(fund_number => {\n var fund_name = funds[fund_number]['name'];\n ret.push(fund_name);\n });\n return ret;\n },\n editFund: function (fund) {\n const table = this.retrieve();\n if (table[fund]) {\n table[fund]['viewed'] = true;\n this.save(table);\n } else {\n console.error('No fund selected.');\n }\n },\n listUneditedFunds: function () {\n const table = this.retrieve();\n const ret = [];\n this.listFunds().forEach(key => {\n if (!table[key]['viewed']) {\n ret.push(key);\n }\n });\n return ret;\n },\n fundsLeft: function () {\n return this.listUneditedFunds().length > 0;\n }\n};\n/* harmony default export */ const fund_lookup_table = (FundLookupTable);\n;// CONCATENATED MODULE: ./src/js/models/current_fund.js\n\nconst CurrentFund = {\n update: function (fund) {\n localStorage.setItem('fund', fund);\n },\n number: function () {\n return localStorage.getItem(\"fund\");\n },\n name: function () {\n return fund_lookup_table.getName(this.number());\n },\n reset: function () {\n this.update('');\n }\n};\n/* harmony default export */ const current_fund = (CurrentFund);\n;// CONCATENATED MODULE: ./src/js/models/account_string.js\n\nconst AccountString = {\n getNumber: function (input) {\n // isolate the numerical part of a appropriation/cost center/object\n const match = input.match(/^\\d+/);\n return match ? match[0] : null;\n },\n build: function (approp, cc, obj = null, fund = null) {\n // put together account string fund-approp-costcenter[-obj] (w optional object)\n if (!fund) {\n fund = current_fund.number();\n }\n ;\n // hits error here\n approp = this.getNumber(approp);\n cc = this.getNumber(cc);\n var string = `${fund}-${approp}-${cc}`;\n string = obj ? `${string}-${this.getNumber(obj)}` : string;\n return string;\n },\n getAccountStringSection: function (account_string, section) {\n const sections = account_string.split(\"-\");\n return sections.length > section ? sections[section] : null;\n },\n fund: function (account_string) {\n return this.getAccountStringSection(account_string, 0);\n },\n approp: function (account_string) {\n return this.getAccountStringSection(account_string, 1);\n },\n costCenter: function (account_string) {\n return this.getAccountStringSection(account_string, 2);\n },\n object: function (account_string) {\n return this.getAccountStringSection(account_string, 3);\n }\n};\n/* harmony default export */ const account_string = (AccountString);\n;// CONCATENATED MODULE: ./src/js/models/fund.js\n\n\n\n// Class to hold information on a specific fund and table\nclass StoredTable {\n constructor(page, fund) {\n this.name = `${page}_${fund}`;\n this.page = page;\n this.table = JSON.parse(localStorage.getItem(this.name));\n }\n totalCol() {\n return TOTAL_COLUMNS[this.page];\n }\n getSum() {\n // fill with zero until there is something saved in storage\n return colSum(this.table, this.totalCol(), this.name);\n }\n}\n\n// Holds all the detailed data for one fund's budget\nclass Fund {\n constructor(fund) {\n this.fund = fund;\n this.personnel = new StoredTable('personnel', fund);\n this.overtime = new StoredTable('overtime', fund);\n this.nonpersonnel = new StoredTable('nonpersonnel', fund);\n this.revenue = new StoredTable('revenue', fund);\n }\n getPersonnelCost() {\n return this.personnel.getSum() + this.overtime.getSum();\n }\n getNonPersonnelCost() {\n return this.nonpersonnel.getSum();\n }\n getRevenue() {\n return this.revenue.getSum();\n }\n getTotal() {\n return this.getNonPersonnelCost() + this.getPersonnelCost() - this.getRevenue();\n }\n}\n/* harmony default export */ const models_fund = (Fund);\n;// CONCATENATED MODULE: ./src/js/models/baseline.js\n\n\nclass Baseline {\n // baseline will just contain a list of funds, each with\n // running tallies for their budgets\n constructor() {\n const allFunds = fund_lookup_table.listFunds();\n this.funds = [];\n allFunds.forEach(fund => {\n this.funds.push(new models_fund(fund));\n });\n }\n static target() {\n return localStorage.getItem('target');\n }\n personnel() {\n let total = 0;\n this.funds.forEach(fund => {\n total += fund.getPersonnelCost();\n });\n return total;\n }\n nonpersonnel() {\n let total = 0;\n this.funds.forEach(fund => {\n total += fund.getNonPersonnelCost();\n });\n return total;\n }\n revenue() {\n let total = 0;\n this.funds.forEach(fund => {\n total += fund.getRevenue();\n });\n return total;\n }\n total() {\n return this.nonpersonnel() + this.personnel() - this.revenue();\n }\n}\n/* harmony default export */ const models_baseline = (Baseline);\n;// CONCATENATED MODULE: ./src/js/models/services.js\n// data structure to save the possible service options for the department\nconst Services = {\n save: function (services) {\n localStorage.setItem('services-list', JSON.stringify(services));\n },\n list: function () {\n return JSON.parse(localStorage.getItem('services-list')) || {};\n }\n};\n/* harmony default export */ const services = (Services);\n;// CONCATENATED MODULE: ./src/js/models/initiative.js\n// data structure to hold information on new initiatives\n\nclass Initiative {\n constructor(row) {\n this.data = row;\n this.name = row['Initiative Name'];\n }\n expenses() {\n if (this.data['Ballpark Total Expenses']) {\n return this.data['Ballpark Total Expenses'];\n } else {\n return 0;\n }\n }\n revenue() {\n if (this.data['Revenue']) {\n return this.data['Revenue'];\n } else {\n return 0;\n }\n }\n net() {\n return this.expenses() - this.revenue();\n }\n}\n/* harmony default export */ const initiative = (Initiative);\n;// CONCATENATED MODULE: ./src/js/models/supplemental.js\n\n\n\n// data structure to hold supplemental requests\nclass Supplemental {\n constructor() {\n this.table = JSON.parse(localStorage.getItem(this.name));\n this.initiatives = [];\n if (this.table) {\n this.table.forEach(row => {\n this.initiatives.push(new initiative(row));\n });\n }\n }\n getInits() {\n return this.table.map(item => {\n return item['Initiative Name'];\n });\n }\n expenses() {\n return colSum(this.table, 'Ballpark Total Expenses');\n }\n revenue() {\n return colSum(this.table, 'Revenue');\n }\n total() {\n return this.expenses() - this.revenue();\n }\n}\n/* harmony default export */ const supplemental = (Supplemental);\n;// CONCATENATED MODULE: ./src/js/models/index.js\n// models/index.js\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./src/js/components/sidebar/subcomponents/baseline_section.js\n\n\n\n\nconst BaselineSection = {\n _data: new models_baseline(),\n _genFund: new models_fund(1000),\n get data() {\n this._data = new models_baseline();\n return this._data;\n },\n set data(newData) {\n this._data = newData;\n },\n get genFund() {\n this._genFund = new models_fund(1000);\n return this._genFund;\n },\n set genFund(newFund) {\n this._genFund = newFund;\n },\n target_html() {\n return `\n \n \n \n
`;\n },\n fund_html(fund) {\n return `\n
${fund_lookup_table.getName(fund.fund)}
\n
\n \n \n \n \n
`;\n },\n linkEditBtns() {\n let btns = document.querySelectorAll('.edit-icon');\n btns.forEach(btn => {\n // Get the fund from the div the button is in\n let fund = btn.closest('.fund-div').id.replace('fund_', '');\n let page = btn.closest('.sidebar-stat-line').classList[1];\n btn.addEventListener('click', function () {\n current_fund.update(fund);\n visitPage(page);\n });\n });\n },\n update() {\n const baselineDiv = document.querySelector('#baseline-stats');\n baselineDiv.innerHTML = this.target_html();\n this.data.funds.forEach(fund => {\n var fundDiv = document.createElement('div');\n fundDiv.id = `fund_${fund.fund}`;\n fundDiv.classList.add('fund-div');\n fundDiv.innerHTML = this.fund_html(fund);\n baselineDiv.appendChild(fundDiv);\n });\n if (this.genFund.getTotal() <= models_baseline.target()) {\n document.querySelector('#GF-total .stat').style.color = \"green\";\n document.querySelector('#fund_1000 .sidebar-stat-line:last-of-type .stat').style.color = \"green\";\n } else {\n document.querySelector('#GF-total .stat').style.color = \"red\";\n document.querySelector('#fund_1000 .sidebar-stat-line:last-of-type .stat').style.color = \"red\";\n }\n this.linkEditBtns();\n }\n};\n;// CONCATENATED MODULE: ./src/js/components/sidebar/subcomponents/supp_section.js\n\n\n\nconst SuppSection = {\n html() {\n var supp = new supplemental();\n return `\n \n \n `;\n },\n linkEditBtns() {\n let btns = document.querySelectorAll('.edit-supp');\n btns.forEach(btn => {\n btn.addEventListener('click', function () {\n visitPage('new-inits');\n });\n });\n },\n update() {\n const suppDiv = document.querySelector('#supp-stats');\n suppDiv.innerHTML = this.html();\n this.linkEditBtns();\n }\n};\n/* harmony default export */ const supp_section = (SuppSection);\n;// CONCATENATED MODULE: ./src/js/components/sidebar/sidebar.js\n\n\n\n\n// fetch CSS variables saved in :root\nconst root = document.documentElement;\nconst sideBarWidth = getComputedStyle(root).getPropertyValue('--sidebar-width').trim();\nfunction hideSidebar() {\n document.getElementById('sidebar-panel').style.display = 'none';\n document.getElementById('main-panel').style.width = '100%';\n document.querySelector('header').style.width = '100%';\n}\nfunction showSidebar() {\n const sidebar = document.getElementById('sidebar-panel');\n const mainPanel = document.getElementById('main-panel');\n const header = document.querySelector('header');\n\n // update values\n updateTotals();\n sidebar.style.display = 'block'; // Show the sidebar\n\n // Calculate the remaining width for the main panel and header\n var contentWidth = document.documentElement.clientWidth;\n mainPanel.style.width = `${contentWidth - parseInt(sideBarWidth, 10)}px`;\n header.style.width = `${contentWidth - parseInt(sideBarWidth, 10)}px`;\n\n // add event listener to resize content if window is adjusted\n window.addEventListener('resize', showSidebar);\n}\nfunction updateSidebarTitle(new_title) {\n document.getElementById('sidebar-title').textContent = new_title;\n}\nfunction updateTotals() {\n supp_section.update();\n BaselineSection.update();\n}\nfunction resetAll() {\n localStorage.clear();\n // reset all stats to 0\n updateTotals();\n}\nconst Sidebar = {\n SuppSection: supp_section,\n BaselineSection: BaselineSection,\n hide: hideSidebar,\n show: showSidebar,\n updateTitle: updateSidebarTitle,\n updateTotals: updateTotals,\n reset: resetAll\n};\n/* harmony default export */ const components_sidebar_sidebar = (Sidebar);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/nav_buttons/nav_buttons.css\nvar nav_buttons = __webpack_require__(595);\n;// CONCATENATED MODULE: ./src/js/components/nav_buttons/nav_buttons.css\n\n \n \n \n \n \n \n \n \n \n\nvar nav_buttons_options = {};\n\nnav_buttons_options.styleTagTransform = (styleTagTransform_default());\nnav_buttons_options.setAttributes = (setAttributesWithoutAttributes_default());\nnav_buttons_options.insert = insertBySelector_default().bind(null, \"head\");\nnav_buttons_options.domAPI = (styleDomAPI_default());\nnav_buttons_options.insertStyleElement = (insertStyleElement_default());\n\nvar nav_buttons_update = injectStylesIntoStyleTag_default()(nav_buttons/* default */.A, nav_buttons_options);\n\n\n\n\n /* harmony default export */ const nav_buttons_nav_buttons = (nav_buttons/* default */.A && nav_buttons/* default */.A.locals ? nav_buttons/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/nav_buttons/nav_buttons.js\n\n\nfunction initializeNavButtons() {\n // initialize last button\n const last_btn = document.getElementById('btn-last');\n last_btn.addEventListener('click', lastPage);\n // initialize next button\n const next_btn = document.getElementById('btn-next');\n next_btn.addEventListener('click', nextPage);\n}\nfunction hideNavButtons() {\n document.getElementById('nav-btns').style.display = 'none';\n}\nfunction showNavButtons() {\n document.getElementById('nav-btns').style.display = 'block';\n initializeNavButtons();\n}\nfunction nav_buttons_disable(button_id) {\n document.getElementById(button_id).classList.add('disabled');\n}\nfunction nav_buttons_enable(button_id) {\n document.getElementById(button_id).classList.remove('disabled');\n}\nconst Next = {\n disable: function () {\n nav_buttons_disable('btn-next');\n },\n enable: function () {\n nav_buttons_enable('btn-next');\n },\n addAction: function (fn) {\n document.querySelector(`#btn-next`).addEventListener('click', fn);\n },\n removeAction: function (fn) {\n document.querySelector(`#btn-next`).removeEventListener('click', fn);\n }\n};\nconst Last = {\n disable: function () {\n nav_buttons_disable('btn-last');\n },\n enable: function () {\n nav_buttons_enable('btn-last');\n }\n};\nconst NavButtons = {\n hide: hideNavButtons,\n show: showNavButtons,\n Next: Next,\n Last: Last\n};\n/* harmony default export */ const components_nav_buttons_nav_buttons = (NavButtons);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/body/body.css\nvar body = __webpack_require__(9);\n;// CONCATENATED MODULE: ./src/js/components/body/body.css\n\n \n \n \n \n \n \n \n \n \n\nvar body_options = {};\n\nbody_options.styleTagTransform = (styleTagTransform_default());\nbody_options.setAttributes = (setAttributesWithoutAttributes_default());\nbody_options.insert = insertBySelector_default().bind(null, \"head\");\nbody_options.domAPI = (styleDomAPI_default());\nbody_options.insertStyleElement = (insertStyleElement_default());\n\nvar body_update = injectStylesIntoStyleTag_default()(body/* default */.A, body_options);\n\n\n\n\n /* harmony default export */ const body_body = (body/* default */.A && body/* default */.A.locals ? body/* default */.A.locals : undefined);\n\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/accordion/accordion.css\nvar accordion = __webpack_require__(995);\n;// CONCATENATED MODULE: ./src/js/components/accordion/accordion.css\n\n \n \n \n \n \n \n \n \n \n\nvar accordion_options = {};\n\naccordion_options.styleTagTransform = (styleTagTransform_default());\naccordion_options.setAttributes = (setAttributesWithoutAttributes_default());\naccordion_options.insert = insertBySelector_default().bind(null, \"head\");\naccordion_options.domAPI = (styleDomAPI_default());\naccordion_options.insertStyleElement = (insertStyleElement_default());\n\nvar accordion_update = injectStylesIntoStyleTag_default()(accordion/* default */.A, accordion_options);\n\n\n\n\n /* harmony default export */ const accordion_accordion = (accordion/* default */.A && accordion/* default */.A.locals ? accordion/* default */.A.locals : undefined);\n\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/table/table.css\nvar table = __webpack_require__(279);\n;// CONCATENATED MODULE: ./src/js/components/table/table.css\n\n \n \n \n \n \n \n \n \n \n\nvar table_options = {};\n\ntable_options.styleTagTransform = (styleTagTransform_default());\ntable_options.setAttributes = (setAttributesWithoutAttributes_default());\ntable_options.insert = insertBySelector_default().bind(null, \"head\");\ntable_options.domAPI = (styleDomAPI_default());\ntable_options.insertStyleElement = (insertStyleElement_default());\n\nvar table_update = injectStylesIntoStyleTag_default()(table/* default */.A, table_options);\n\n\n\n\n /* harmony default export */ const table_table = (table/* default */.A && table/* default */.A.locals ? table/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/headers.js\nfunction addTableHeaders(cols) {\n // Get the table element by its ID\n const table = document.getElementById('main-table');\n\n // Create a table header row element\n const headerRow = document.createElement('tr');\n cols.forEach(col => {\n // Create a header cell element\n const headerCell = document.createElement('th');\n headerCell.textContent = col['title'];\n headerCell.classList.add(col['className']);\n\n // Append the header cell to the header row\n headerRow.appendChild(headerCell);\n });\n\n // Append the header row to the table header\n let thead = table.querySelector('thead');\n thead.appendChild(headerRow);\n}\nconst Header = {\n add: function (header_array) {\n addTableHeaders(header_array);\n }\n};\n/* harmony default export */ const headers = (Header);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/rows.js\n\n\nasync function addNewRow(data_dictionary, columns = []) {\n // Get the table element by its ID\n const table = document.getElementById('main-table');\n\n // check if header has already been added\n let header_row = table.querySelector('thead tr');\n if (!header_row) {\n headers.add(columns);\n header_row = table.querySelector('thead tr');\n }\n\n // initialize new row of data\n const new_row = document.createElement('tr');\n\n // go through each header and add the right cell value depending on its class\n let thElements = header_row.querySelectorAll('th');\n thElements.forEach(header_cell => {\n // Create new cell and add it to the row\n const newCell = document.createElement('td');\n new_row.appendChild(newCell);\n // if the data has an appropriate class, add the info to the cell. \n // Otherwise, keep empty cell\n Object.keys(data_dictionary).forEach(className => {\n if (header_cell.classList.contains(className)) {\n newCell.textContent = data_dictionary[className];\n newCell.classList.add(className);\n }\n });\n });\n\n // Append the new row to the table body\n let tbody = table.querySelector('tbody');\n tbody.appendChild(new_row);\n}\nfunction saveRowEdits(row) {\n var cells = row.querySelectorAll('td');\n cells.forEach(cell => {\n // save dropdown values\n if (cell.querySelector('select')) {\n var serviceSelector = cell.querySelector('select');\n cell.textContent = serviceSelector.value;\n } else if (cell.querySelector('input')) {\n // save new entered value in textbox\n var textbox = cell.querySelector('input');\n var enteredValue = textbox.value;\n // update display and format with currency if relevant\n if (cell.classList.contains('cost')) {\n // if cost, remove commas first\n enteredValue = enteredValue.replaceAll(',', '');\n cell.textContent = formatCurrency(enteredValue);\n } else {\n cell.textContent = enteredValue;\n }\n // set value attribute to the new user input\n cell.setAttribute('value', enteredValue);\n }\n });\n}\nconst Rows = {\n add: function (data_dictionary, cols) {\n addNewRow(data_dictionary, cols);\n },\n saveEdits: function (row) {\n saveRowEdits(row);\n }\n};\n/* harmony default export */ const rows = (Rows);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/buttons.js\n\nfunction hideButton(className) {\n return function () {\n var buttons = document.getElementsByClassName(className);\n for (var i = 0; i < buttons.length; i++) {\n buttons[i].style.display = 'none';\n }\n };\n}\nfunction showButton(className) {\n return function () {\n var buttons = document.getElementsByClassName(className);\n for (var i = 0; i < buttons.length; i++) {\n buttons[i].style.display = 'inline';\n }\n };\n}\nfunction updateButtonText(className, text) {\n document.querySelector(`.${className}`).textContent = text;\n}\nfunction handleRowEdit(actionOnClick, updateCallback = null) {\n // attach an event listener to each edit button in every row\n var editButtons = document.getElementsByClassName('btn-edit');\n for (var i = 0; i < editButtons.length; i++) {\n editButtons[i].addEventListener('click', async function (event) {\n // Determine what was clicked on within the table\n var rowToEdit = event.target.closest('tr');\n // mark row as being edited\n rowToEdit.classList.add('active-editing');\n\n // turn relevant entries into textboxes, usually\n actionOnClick();\n\n // hide edit buttons\n Edit.hide();\n if (updateCallback) {\n initializeConfirmButton(updateCallback);\n }\n });\n }\n ;\n}\nfunction initializeConfirmButton(updateCallback) {\n // get element and add listener for click\n var rowToEdit = document.querySelector('.active-editing');\n const confirm_btn = rowToEdit.querySelector(\".btn-confirm\");\n // show the row's confirm button\n confirm_btn.style.display = 'block';\n confirm_btn.addEventListener('click', function () {\n ;\n // save row edits\n rows.saveEdits(rowToEdit);\n // update values in sidebar\n updateCallback();\n // make row no longer green\n rowToEdit.classList.remove('active-editing');\n // show edit buttons and hide confirm buttons\n Edit.show();\n Confirm.hide();\n });\n}\nconst Edit = {\n html: '',\n hide: hideButton('btn-edit'),\n show: showButton('btn-edit'),\n init: function (actionOnClick, updateCallback) {\n handleRowEdit(actionOnClick, updateCallback);\n }\n};\nconst Delete = {\n html: '',\n hide: hideButton('btn-delete'),\n show: showButton('btn-delete')\n};\nconst Confirm = {\n html: '',\n hide: hideButton('btn-confirm'),\n show: showButton('btn-confirm')\n};\nconst AddRow = {\n hide: hideButton('btn-add'),\n show: showButton('btn-add'),\n updateText: function (text) {\n updateButtonText('btn-add', text);\n }\n};\nconst buttons_Buttons = {\n Delete: Delete,\n Edit: Edit,\n Confirm: Confirm,\n AddRow: AddRow,\n edit_confirm_btns: Edit.html + Confirm.html,\n all_btns: Delete.html + Edit.html + Confirm.html\n};\n/* harmony default export */ const subcomponents_buttons = (buttons_Buttons);\n;// CONCATENATED MODULE: ./src/js/components/form/subcomponents/dropdown.js\nfunction createDropdown(dataArray) {\n // Creating a select element\n const selectElement = document.createElement('select');\n\n // add a default blank option to the dataArray\n dataArray = [''].concat(dataArray);\n\n // Looping through the array and creating an option for each element\n dataArray.forEach(item => {\n const optionElement = document.createElement('option');\n optionElement.value = item;\n optionElement.textContent = item;\n selectElement.appendChild(optionElement); // Appending the option to the select\n });\n\n // Return the select element so it can be appended to the document\n return selectElement;\n}\nconst Dropdown = {\n create: function (dataArray) {\n return createDropdown(dataArray);\n }\n};\n/* harmony default export */ const subcomponents_dropdown = (Dropdown);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/cells.js\n\n\n\n\n// return cell value attribute or 0 if it does not exist\nfunction getCellValue(row, className) {\n var cell = row.querySelector(`.${className}`);\n var cellValue = cell ? cell.getAttribute('value') : null;\n return cellValue ? parseFloat(cellValue) : 0;\n}\n\n// return text in cell\nfunction getCellText(row, className) {\n var cell = row.querySelector(`.${className}`);\n if (cell) {\n return cell.textContent;\n } else {\n //console.log(`Error retrieving cell text for class ${className}`);\n return '';\n }\n}\nfunction updateTableCell(row, col_class, new_value) {\n const cell = row.querySelector(`.${col_class}`);\n cell.setAttribute('value', new_value);\n cell.textContent = formatCurrency(new_value);\n}\nfunction createEditableCell(cellClass, isCost) {\n // get cell\n const cell = document.querySelector(`.active-editing td.${cellClass}`);\n // Create an input element to edit the value\n var textbox = document.createElement('input');\n textbox.type = 'text';\n if (isCost) {\n var value = cell.getAttribute('value');\n textbox.value = displayWithCommas(value);\n } else {\n textbox.value = cell.textContent;\n }\n // Clear the current content and append the textbox to the cell\n cell.innerHTML = '';\n cell.appendChild(textbox);\n}\nfunction cells_createDropdown(cellClass, optionArray) {\n // get cell\n const cell = document.querySelector(`.active-editing td.${cellClass}`);\n // add service dropdown\n const dropdown = subcomponents_dropdown.create(optionArray);\n dropdown.value = cell.textContent;\n // Clear the current content and append the textbox to the cell\n cell.innerHTML = '';\n cell.appendChild(dropdown);\n}\nconst Cell = {\n getValue: function (row, className) {\n return getCellValue(row, className);\n },\n getText: function (row, className) {\n return getCellText(row, className);\n },\n updateValue: function (row, col_class, new_value) {\n updateTableCell(row, col_class, new_value);\n },\n createTextbox: function (className, isCost) {\n createEditableCell(className, isCost);\n },\n createServiceDropdown: () => {\n cells_createDropdown('service', services.list());\n },\n createDropdown: cells_createDropdown\n};\n/* harmony default export */ const cells = (Cell);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/columns.js\n\n\n// position is index at which new column will be inserted\nfunction addCol(position, htmlContent = '', headerTitle = '') {\n // Get the table element by its ID\n let table = document.getElementById('main-table');\n\n // Validate position\n let maxPosition = table.rows[0].cells.length;\n if (position < 0 || position > maxPosition) {\n console.error(`Position ${position} is out of bounds.`);\n return;\n }\n\n // Insert the header if provided\n let thead = table.tHead;\n if (headerTitle && thead) {\n let th = document.createElement('th');\n th.innerHTML = headerTitle; // Use innerHTML to insert HTML content\n thead.rows[0].insertBefore(th, thead.rows[0].cells[position]);\n }\n\n // Insert new cells into each row of the table body\n let tbody = table.tBodies[0];\n if (tbody) {\n for (let i = 0; i < tbody.rows.length; i++) {\n let row = tbody.rows[i];\n let td = document.createElement('td');\n td.innerHTML = htmlContent; // Use innerHTML to insert HTML content\n row.insertBefore(td, row.cells[position]);\n }\n }\n}\nfunction ncols() {\n const table = document.getElementById('main-table');\n // Ensure that the row exists before counting the columns\n return table.rows[0].cells.length;\n}\nfunction addColToEnd(htmlContents = [], headerTitle = '') {\n // count columns and add new column to the end\n const position = ncols('main-table');\n addCol(position, htmlContents, headerTitle);\n}\nfunction assignClassToColumn(headerName, className) {\n // Get the table element by its ID\n let table = document.getElementById('main-table');\n\n // Find the index of the column by its header name\n const thead = table.tHead;\n let headerCellIndex = -1;\n const headerCells = thead.rows[0].cells; // Assuming the first row contains header cells ()\n for (let i = 0; i < headerCells.length; i++) {\n if (headerCells[i].textContent.trim() === headerName) {\n // assign the class to the header cell\n headerCells[i].classList.add(className);\n headerCellIndex = i;\n break;\n }\n }\n\n // error check\n if (headerCellIndex === -1) {\n console.error(`No header found with name \"${headerName}\"`);\n return;\n }\n\n // Assign the class to each cell in the specified column index within the tbody\n let tbody = table.tBodies[0];\n if (tbody) {\n let bodyRows = tbody.rows;\n for (let row of bodyRows) {\n if (row.cells[headerCellIndex]) {\n row.cells[headerCellIndex].classList.add(className);\n }\n }\n }\n}\nfunction addCostClass(headerName) {\n assignClassToColumn(headerName, 'cost');\n\n // Get all the cells with the specified class name\n const cells = document.querySelectorAll(`td.cost`);\n cells.forEach(cell => {\n // Get the current text content of the cell and assign it to 'value' attribute\n if (!cell.getAttribute('value')) {\n const cellText = cell.textContent.trim();\n const cellValue = isNaN(cellText) || cellText === '' ? 0 : parseFloat(cellText);\n cell.setAttribute('value', cellValue);\n\n // Now format the text content like currency and replace it in the cell\n const formattedCurrency = formatCurrency(parseFloat(cellValue));\n cell.textContent = formattedCurrency;\n }\n });\n}\nfunction assignColumnClasses(columnDefinitions) {\n columnDefinitions.forEach(column => {\n // Assign class to column\n assignClassToColumn(column.title, column.className);\n\n // If the column is a cost column, add the specific cost class\n if (column.isCost) {\n addCostClass(column.title);\n }\n\n // show the column\n if (!column.hide) {\n showColumnByTitle(column.title);\n }\n });\n}\nfunction hideColumn(index) {\n var table = document.getElementById('main-table');\n var rows = table.rows;\n for (var i = 0; i < rows.length; i++) {\n var cells = rows[i].cells;\n if (cells.length > index) {\n cells[index].style.display = 'none';\n }\n }\n}\n\n// Function to show a specific column\nfunction showColumn(index) {\n var table = document.getElementById('main-table');\n var rows = table.rows;\n for (var i = 0; i < rows.length; i++) {\n var cells = rows[i].cells;\n if (cells.length > index) {\n cells[index].style.display = 'table-cell';\n }\n }\n}\n\n// Function to get the column index by title\nfunction getColumnIndexByTitle(table, title) {\n var headers = table.querySelectorAll('th');\n for (var i = 0; i < headers.length; i++) {\n if (headers[i].innerText === title) {\n return i;\n }\n }\n return -1; // Column not found\n}\n\n// Function to hide a column by title\nfunction hideColumnByTitle(title) {\n var table = document.getElementById('main-table');\n var index = getColumnIndexByTitle(table, title);\n if (index !== -1) {\n hideColumn(index);\n } else {\n console.log(`Column with title \"${title}\" not found.`);\n }\n}\n\n// Function to show a column by title\nfunction showColumnByTitle(title) {\n var table = document.getElementById('main-table');\n var index = getColumnIndexByTitle(table, title);\n if (index !== -1) {\n showColumn(index);\n } else {\n console.log(`Column with title \"${title}\" not found.`);\n }\n}\nconst Column = {\n add: function (position, htmlContent, headerTitle) {\n return addCol(position, htmlContent, headerTitle);\n },\n addAtEnd: function (htmlContent, headerTitle) {\n return addColToEnd(htmlContent, headerTitle);\n },\n assignClasses: function (column_definitions) {\n return assignColumnClasses(column_definitions);\n },\n hide: function (colName) {\n hideColumnByTitle(colName);\n },\n show: function (colName) {\n showColumnByTitle(colName);\n }\n};\n/* harmony default export */ const columns = (Column);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/data.js\n\n\n\n\nfunction fillTable(data) {\n try {\n const table = document.getElementById('main-table');\n const thead = table.querySelector('thead');\n const tbody = table.querySelector('tbody');\n\n // clear existing data\n thead.innerHTML = '';\n tbody.innerHTML = '';\n\n // Create table header row\n const headerRow = document.createElement('tr');\n Object.keys(data[0]).forEach(key => {\n const header = document.createElement('th');\n header.textContent = key;\n headerRow.appendChild(header);\n });\n thead.appendChild(headerRow);\n\n // Create table body rows\n data.forEach(item => {\n const row = document.createElement('tr');\n Object.values(item).forEach(val => {\n const cell = document.createElement('td');\n cell.innerHTML = val;\n row.appendChild(cell);\n });\n tbody.appendChild(row);\n });\n } catch (error) {\n console.error('No table saved in localStorage:', error);\n }\n}\nasync function loadFromStorage() {\n // look up table name in storage\n if (current_fund.number()) {\n var key = `${current_page.load()}_${current_fund.number()}`;\n } else {\n var key = current_page.load();\n }\n // load from local storage\n const data = localStorage.getItem(key);\n // if nothing in storage, return a zero\n if (!data) {\n return 0;\n } else {\n // otherwise, fill table in HTML and return success (1)\n components_table_table.show();\n fillTable(await JSON.parse(data));\n return 1;\n }\n}\nfunction loadFunds() {\n // get list of funds from storage\n const fundDict = fund_lookup_table.retrieve();\n // build out data in correct format\n const ret = [];\n Object.keys(fundDict).forEach(key => {\n // determine if the fund has already been edited\n if (fundDict[key]['viewed']) {\n // todo: add a checkmark here\n ret.push({\n 'Fund': ` \n \n ${fundDict[key]['name']}\n `\n });\n } else {\n ret.push({\n 'Fund': ` \n ${fundDict[key]['name']}\n `\n });\n }\n });\n fillTable(ret);\n}\nfunction getColumnIndexByClass(tbody, className) {\n const firstRow = tbody.rows[0];\n if (!firstRow) return -1; // Return -1 if there's no row to examine\n for (let cellIndex = 0; cellIndex < firstRow.cells.length; cellIndex++) {\n if (firstRow.cells[cellIndex].classList.contains(className)) {\n return cellIndex;\n }\n }\n return -1; // Return -1 if class name not found\n}\nfunction sort(primaryClass, secondaryClass) {\n const table = document.getElementById('main-table');\n const tbody = table.tBodies[0];\n const rows = Array.from(tbody.rows);\n\n // Get the column indices by class name\n const primaryColIndex = getColumnIndexByClass(tbody, primaryClass);\n const secondaryColIndex = getColumnIndexByClass(tbody, secondaryClass);\n\n // exit if classes don't exist\n if (primaryColIndex === -1) {\n console.error(`Column class ${classA} not found in table`);\n return;\n } else if (secondaryColIndex === -1) {\n console.error(`Column class ${classB} not found in table`);\n return;\n }\n\n // Sort the rows based on the text content of the cells\n rows.sort((rowA, rowB) => {\n // Primary column comparison\n const primaryA = unformatCurrency(rowA.cells[primaryColIndex].textContent);\n const primaryB = unformatCurrency(rowB.cells[primaryColIndex].textContent);\n if (primaryA < primaryB) return -1;\n if (primaryA > primaryB) return 1;\n\n // Secondary column comparison (if primary is equal)\n const secondaryA = unformatCurrency(rowA.cells[secondaryColIndex].textContent);\n const secondaryB = unformatCurrency(rowB.cells[secondaryColIndex].textContent);\n if (secondaryA < secondaryB) return -1;\n if (secondaryA > secondaryB) return 1;\n\n // If both columns are equal\n return 0;\n });\n\n // Reattach sorted rows to the table body\n rows.forEach(row => tbody.appendChild(row));\n}\nconst Data = {\n load: loadFromStorage,\n loadFunds: loadFunds,\n sort: function (colA, colB) {\n sort(colA, colB);\n }\n};\n/* harmony default export */ const data = (Data);\n;// CONCATENATED MODULE: ./src/js/utils/XLSX_handlers.js\n\n\n\n\n\nfunction deleteTopRowsUntilFullData(data) {\n // function to try to find the top of the usable data\n let fullDataRowFound = false;\n while (!fullDataRowFound && data.length > 0) {\n const row = data[0]; // Get the top row\n let hasAllData = true;\n for (const cell of row) {\n if (cell == null || cell === '') {\n hasAllData = false;\n break;\n }\n }\n if (hasAllData && row.length > 1) {\n fullDataRowFound = true;\n } else {\n // delete the top row if it's not the header row\n data.shift();\n }\n }\n return data;\n}\nfunction processWorkbook(arrayBuffer) {\n const workbook = XLSX.read(arrayBuffer, {\n type: 'array'\n });\n workbook.SheetNames.forEach(sheetName => {\n // only convert sheets we need\n if (Object.keys(SHEETS).includes(sheetName)) {\n // read in sheets\n const sheet = workbook.Sheets[sheetName];\n const rawData = XLSX.utils.sheet_to_json(sheet, {\n header: 1,\n defval: ''\n });\n\n // Clean the data by removing top rows with incomplete data\n const dataRows = deleteTopRowsUntilFullData(rawData);\n\n // get new headers\n const headers = dataRows[0];\n\n // isolate Fund column to split data\n const fundIndex = headers.indexOf('Fund');\n if (fundIndex === -1) {\n console.error(`No 'Fund' column found in sheet ${sheetName}`);\n return;\n }\n\n // Save a dictionary of data for each fund for each sheet\n const fundData = {};\n dataRows.forEach(row => {\n const fund = row[fundIndex];\n if (fund && fund != \"Fund\") {\n if (!fundData[fund]) {\n fundData[fund] = [];\n }\n const rowData = {};\n headers.forEach((header, index) => {\n rowData[removeNewLines(header)] = row[index];\n });\n fundData[fund].push(rowData);\n }\n });\n\n // save fund number and name as we go along\n fund_lookup_table.update(fundData);\n Object.keys(fundData).forEach(fund => {\n const key = `${SHEETS[sheetName]}_${fund}`;\n localStorage.setItem(key, JSON.stringify(fundData[fund]));\n });\n }\n\n // But also save the possible services\n else if (sheetName == 'Drop-Down Menus') {\n const sheet = workbook.Sheets[sheetName];\n // Convert the sheet to JSON to easily manipulate data\n const sheetData = XLSX.utils.sheet_to_json(sheet, {\n header: 1\n });\n\n // Locate the \"services\" column header in row 0\n const headerRow = sheetData[0];\n const servicesIndex = headerRow.indexOf('Services');\n if (servicesIndex === -1) {\n console.error('Header \"Services\" not found');\n } else {\n // Extract data from the \"services\" column (excluding the header row)\n const servicesColumn = sheetData.slice(1).map(row => row[servicesIndex]);\n const cleanedServicesColumn = servicesColumn.filter(value => value != null);\n // save the data\n services.save(cleanedServicesColumn);\n }\n } else if (sheetName == 'Dept Summary') {\n const sheet = workbook.Sheets[sheetName];\n // get and save TARGET for general fund\n if (sheet[TARGET_CELL_ADDRESS]) {\n const cellValue = sheet[TARGET_CELL_ADDRESS].v; // Access the cell value\n localStorage.setItem('target', cellValue);\n } else {\n console.error(`Cell ${TARGET_CELL_ADDRESS} not found in sheet ${sheetName}`);\n }\n }\n });\n console.log('all excel data saved');\n}\n\n// Utility function to append a sheet to the workbook if data is present\nfunction appendSheetToWorkbook(workbook, data, sheetName) {\n if (data.length > 0) {\n const sheet = XLSX.utils.json_to_sheet(data);\n XLSX.utils.book_append_sheet(workbook, sheet, sheetName);\n }\n}\nfunction downloadXLSX() {\n const baseline = new models_baseline();\n const workbook = XLSX.utils.book_new(); // Create a new workbook\n\n const dataMap = {\n Personnel: 'personnel',\n Overtime: 'overtime',\n NonPersonnel: 'nonpersonnel',\n Revenue: 'revenue'\n };\n const sheetData = {\n Personnel: [],\n Overtime: [],\n NonPersonnel: [],\n Revenue: []\n };\n baseline.funds.forEach(fund => {\n Object.keys(dataMap).forEach(sheetName => {\n if (fund[dataMap[sheetName]] && fund[dataMap[sheetName]].table) {\n sheetData[sheetName].push(...fund[dataMap[sheetName]].table);\n }\n });\n });\n Object.keys(sheetData).forEach(sheetName => {\n appendSheetToWorkbook(workbook, sheetData[sheetName], sheetName);\n });\n\n // Generate a downloadable file\n const wbout = XLSX.write(workbook, {\n bookType: 'xlsx',\n type: 'array'\n });\n const blob = new Blob([wbout], {\n type: 'application/octet-stream'\n });\n\n // Create a link and trigger the download\n const link = document.createElement(\"a\");\n link.href = URL.createObjectURL(blob);\n link.download = \"Filled_Detail_Sheet.xlsx\";\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n}\nfunction excelSerialDateToJSDate(serial) {\n if (!serial) {\n return null;\n }\n ;\n // Excel considers 1900-01-01 as day 1, but JavaScript's Date considers\n // 1970-01-01 as day 0. Therefore, we calculate the number of milliseconds\n // between 1900-01-01 and 1970-01-01.\n const excelEpoch = new Date(Date.UTC(1899, 11, 30)); // JavaScript Consider December month as '11'\n\n // Calculate the JS date by adding serial days to the epoch date\n const date = new Date(excelEpoch.getTime() + serial * 24 * 60 * 60 * 1000);\n\n // Set the time part to zero (midnight)\n date.setUTCHours(0, 0, 0, 0);\n\n // Return the date part of the ISO string\n return date.toISOString().split('T')[0];\n}\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/tooltip/tooltip.css\nvar tooltip = __webpack_require__(843);\n;// CONCATENATED MODULE: ./src/js/components/tooltip/tooltip.css\n\n \n \n \n \n \n \n \n \n \n\nvar tooltip_options = {};\n\ntooltip_options.styleTagTransform = (styleTagTransform_default());\ntooltip_options.setAttributes = (setAttributesWithoutAttributes_default());\ntooltip_options.insert = insertBySelector_default().bind(null, \"head\");\ntooltip_options.domAPI = (styleDomAPI_default());\ntooltip_options.insertStyleElement = (insertStyleElement_default());\n\nvar tooltip_update = injectStylesIntoStyleTag_default()(tooltip/* default */.A, tooltip_options);\n\n\n\n\n /* harmony default export */ const tooltip_tooltip = (tooltip/* default */.A && tooltip/* default */.A.locals ? tooltip/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/tooltip/tooltip.js\n\n\n\n\n\n\nfunction hideTooltip() {\n document.getElementById('tooltip').style.visibility = 'hidden';\n}\nfunction showTooltip() {\n document.getElementById('tooltip').style.visibility = 'visible';\n}\nfunction editTooltipText(newText) {\n // edit text to display inside tooltip\n const tooltip = document.getElementById('tooltip');\n tooltip.innerHTML = newText;\n}\nfunction showAccountString(row) {\n const approp = cells.getText(row, 'approp-name');\n const cc = cells.getText(row, 'cc-name');\n const obj = cells.getText(row, 'object-name');\n const fund = cells.getText(row, 'fund-name');\n var message = `Fund: ${fund}
\n Appropriation: ${approp}
\n Cost Center: ${cc}`;\n if (obj) {\n message += `
Object: ${obj}`;\n }\n editTooltipText(message);\n}\nfunction showSalaryProjection(row) {\n const general_increase = cells.getText(row, 'general-increase-rate');\n const merit_increase = cells.getText(row, 'merit-increase-rate');\n const current_salary = cells.getValue(row, 'current-salary');\n const proj_salary = cells.getValue(row, 'avg-salary');\n if (current_salary) {\n var message = `The average salary/wage for this position was \n ${formatCurrency(current_salary)} as of September 20${FISCAL_YEAR - 2}. \n Given a ${general_increase * 100}% general increase rate and a ${merit_increase * 100}% \n merit increase, the FY${FISCAL_YEAR} projection for this position's average \n annual salary/wage is ${formatCurrency(proj_salary)}.`;\n } else {\n var message = `The average salary/wage for this position was \n unknown as of September 20${FISCAL_YEAR - 2}, or the position\n did not exist. The FY${FISCAL_YEAR} projection for this position's \n average annual salary/wage is ${formatCurrency(proj_salary)}.`;\n }\n editTooltipText(message);\n}\nfunction showFinalPersonnelCost(row) {\n const proj_salary = cells.getValue(row, 'avg-salary');\n const ftes = cells.getText(row, 'baseline-ftes');\n const fringe = parseFloat(cells.getText(row, 'fringe'));\n const avg_benefits = proj_salary * fringe;\n const message = `The total cost captures ${ftes} position(s) at\n an annual salary/wage of ${formatCurrency(proj_salary)}, \n plus fringe benefits that cost ${formatCurrency(avg_benefits)} \n per position per year, on average.`;\n editTooltipText(message);\n}\nfunction showFICA(row) {\n const fica = parseFloat(cells.getText(row, 'fica'));\n const ficaPercentage = (fica * 100).toFixed(2);\n const message = `This total is overtime / holiday / shift premium pay, plus FICA (payroll tax), \n which is ${ficaPercentage}% for this cost center.`;\n editTooltipText(message);\n}\nfunction showCPA(row) {\n const cpa = parseFloat(cells.getText(row, 'cpa'));\n const description = cells.getText(row, 'cpa-description');\n const vendor = cells.getText(row, 'vendor');\n var contract_end = cells.getText(row, 'contract-end');\n // convert to normal date format from excel \n contract_end = excelSerialDateToJSDate(contract_end);\n const remaining = cells.getValue(row, 'remaining');\n if (cpa) {\n var message = `CPA #${cpa}`;\n } else {\n var message = `No CPA`;\n }\n if (vendor) {\n message += `
Vendor: ${vendor}`;\n }\n ;\n if (description) {\n message += `
Description: ${description}`;\n }\n ;\n if (contract_end) {\n message += `
Contract End Date: ${contract_end}`;\n }\n if (remaining) {\n message += `
Amount Remaining on Contract: ${formatCurrency(remaining)}`;\n }\n editTooltipText(message);\n}\nfunction tooltip_link(element, displayFn) {\n // add class to show cell with an underline, etc\n element.classList.add('tooltip-cell');\n\n // Create and append (detail)\n const detail = document.createElement('span');\n detail.classList.add('detail');\n detail.textContent = '(detail)';\n element.appendChild(detail);\n\n // add event listener to show tooltip on mouseover\n element.addEventListener('click', function (event) {\n const row = event.target.closest('tr');\n displayFn(row);\n showTooltip();\n });\n // and hide when mouse moves off\n element.addEventListener('mouseout', function () {\n hideTooltip();\n });\n // Update tooltip position on mouse move\n element.addEventListener('mousemove', function (event) {\n const tooltip = document.getElementById('tooltip');\n tooltip.style.top = event.clientY + 10 + 'px';\n tooltip.style.left = event.clientX + 10 + 'px';\n });\n}\nfunction linkAccountStringCol() {\n // get all relevant cells\n document.querySelectorAll('td.account-string').forEach(cell => {\n tooltip_link(cell, showAccountString);\n });\n}\nfunction linkSalaryCol() {\n // get all relevant cells\n document.querySelectorAll('td.avg-salary').forEach(cell => {\n tooltip_link(cell, showSalaryProjection);\n });\n}\nfunction linkTotalPersonnelCostCol() {\n // get all relevant cells\n document.querySelectorAll('td.total-baseline').forEach(cell => {\n tooltip_link(cell, showFinalPersonnelCost);\n });\n}\nfunction linkTotalOTCol() {\n // get all relevant cells\n document.querySelectorAll('td.total').forEach(cell => {\n tooltip_link(cell, showFICA);\n });\n}\nfunction linkCPACol() {\n // get all relevant cells\n document.querySelectorAll('td.cpa').forEach(cell => {\n tooltip_link(cell, showCPA);\n });\n}\nconst Tooltip = {\n hide: hideTooltip,\n show: showTooltip,\n linkAll: () => {\n linkAccountStringCol();\n switch (current_page.load()) {\n case 'personnel':\n // linkAccountStringCol();\n linkSalaryCol();\n linkTotalPersonnelCostCol();\n break;\n case 'overtime':\n linkTotalOTCol();\n // linkAccountStringCol();\n break;\n case 'nonpersonnel':\n // linkAccountStringCol();\n linkCPACol();\n break;\n // case 'revenue':\n // linkAccountStringCol();\n // break;\n // case 'new-inits':\n // linkAccountStringCol();\n // break;\n default:\n break;\n }\n },\n unlink: function () {\n let details = document.querySelectorAll('.detail');\n details.forEach(span => {\n span.remove();\n });\n }\n};\n/* harmony default export */ const components_tooltip_tooltip = (Tooltip);\n;// CONCATENATED MODULE: ./src/js/utils/JSON_data_handlers.js\nasync function fetchJSON(jsonFilePath) {\n return fetch(jsonFilePath).then(response => {\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n return response.json();\n });\n}\nfunction convertToJSON(table, colsToRemove = []) {\n const rows = table.rows;\n // Extract headers from the first row\n const headerRow = rows[0].cells;\n const headers = [];\n for (let j = 0; j < headerRow.length; j++) {\n headers.push(headerRow[j].innerText);\n }\n\n // initialize data\n var tableData = [];\n for (var i = 1; i < rows.length; i++) {\n const cols = rows[i].cells;\n const rowData = {};\n headers.forEach((header, index) => {\n if (colsToRemove.includes(header)) {\n return;\n } else if (cols[index].classList.contains('cost')) {\n rowData[header] = cols[index].getAttribute('value');\n } else {\n rowData[header] = cols[index].innerText;\n }\n });\n tableData.push(rowData);\n }\n return JSON.stringify(tableData);\n}\n;// CONCATENATED MODULE: ./src/js/components/table/table.js\n\n\n\n\n\n\n\n\n\n\n\n\nfunction adjustTableWidth(width_pct) {\n const table = document.getElementById('main-table');\n table.style.width = width_pct;\n}\nfunction showTable() {\n const tableContainer = document.querySelector('.table-container');\n tableContainer.innerHTML = Table.html;\n const table = document.getElementById('main-table');\n table.style.display = 'table';\n}\nfunction hideTable() {\n // delete table object from table container\n const tableContainer = document.querySelector('.table-container');\n tableContainer.innerHTML = '';\n subcomponents_buttons.AddRow.hide();\n // delete search bar\n document.querySelector('#search-bar-container').innerHTML = '';\n}\nfunction saveTableData() {\n // remove the detail text\n components_tooltip_tooltip.unlink();\n // get table\n var table = document.getElementById('main-table');\n // determine save_as name\n if (current_fund.number()) {\n var save_as = `${current_page.load()}_${current_fund.number()}`;\n } else {\n var save_as = current_page.load();\n }\n localStorage.setItem(save_as, convertToJSON(table, ['Edit']));\n // update sidebar with new data\n components_sidebar_sidebar.updateTotals();\n // relink, depending on page\n components_tooltip_tooltip.linkAll();\n}\nconst Table = {\n html: `\n \n \n \n
`,\n Buttons: subcomponents_buttons,\n Cell: cells,\n Columns: columns,\n Header: headers,\n Rows: rows,\n Data: data,\n // functions\n adjustWidth: function (width_pct) {\n adjustTableWidth(width_pct);\n },\n // TODO: delete\n clear: hideTable,\n hide: hideTable,\n show: showTable,\n save: saveTableData\n};\n/* harmony default export */ const components_table_table = (Table);\n;// CONCATENATED MODULE: ./src/js/components/accordion/accordion.js\n\n\n\n\n\nfunction redirectForEdit() {\n const row = document.querySelector(`.active-editing`);\n const table = row.parentElement;\n const section = table.closest('.summary-container');\n // new initiative edits should all redirect to the new-inits page\n if (section.id == 'supp-accordion') {\n visitPage('new-inits');\n } else {\n const fund = table.id.replace('table-', '');\n current_fund.update(fund);\n const lineItem = row.querySelector('.line-item').textContent;\n // visit the correct page for editing\n switch (lineItem) {\n case 'Personnel Expenditures':\n visitPage('personnel');\n break;\n case 'Non-Personnel Expenditures':\n visitPage('nonpersonnel');\n break;\n case 'Revenues':\n visitPage('revenue');\n break;\n default:\n console.error('Name of line item in table does not match a page destination.');\n }\n }\n}\nconst ExpenseTable = {\n table_id: fund => {\n return `table-${cleanString(fund)}`;\n },\n init(fund) {\n // create empty table and put it in the accordion\n var table = document.createElement('table');\n table.id = this.table_id(fund);\n table.classList.add('accordion-table');\n var parent = document.querySelector(`#fund_${cleanString(fund)}_content .accordion-body`);\n parent.appendChild(table);\n },\n createNewCell(content, row, className) {\n const newCell = document.createElement('td');\n newCell.innerHTML = content;\n newCell.classList.add(className);\n row.appendChild(newCell);\n },\n addRow(fund_name, row_name, number) {\n var table = document.getElementById(this.table_id(fund_name));\n var new_row = document.createElement('tr');\n table.appendChild(new_row);\n // Create a cell for the line item label\n this.createNewCell(row_name, new_row, 'line-item');\n // create a cell for the amount\n this.createNewCell(formatCurrency(number), new_row, 'cost');\n // create Edit button \n var button = '';\n if (row_name != 'Net Expenditures (Revenues)') {\n button = components_table_table.Buttons.Edit.html;\n }\n this.createNewCell(button, new_row);\n },\n fillFromFund(fund) {\n this.init(fund);\n const fundObject = new models_fund(fund);\n this.addRow(fund, 'Personnel Expenditures', fundObject.getPersonnelCost());\n this.addRow(fund, 'Non-Personnel Expenditures', fundObject.getNonPersonnelCost());\n this.addRow(fund, 'Revenues', fundObject.getRevenue());\n this.addRow(fund, 'Net Expenditures (Revenues)', fundObject.getTotal());\n },\n fillFromInit(program) {\n this.init(program.name);\n this.addRow(program.name, 'Expenditures', program.expenses());\n this.addRow(program.name, 'Revenues', program.revenue());\n this.addRow(program.name, 'Net Expenditures (Revenues)', program.net());\n }\n};\nconst Item = {\n html: function (fund) {\n var id = cleanString(fund);\n return `

\n \n

\n
\n
\n
`;\n },\n add: function (fund, accordion_id) {\n // get accordion and add a new item to it\n const parent = document.querySelector(`#${accordion_id} .summary-accordion`);\n const item_element = document.createElement('div');\n item_element.classList.add('accordion-item');\n item_element.innerHTML = this.html(fund);\n parent.appendChild(item_element);\n },\n ExpenseTable: ExpenseTable,\n updateHeader: function (title, id, new_amount) {\n var id = cleanString(id);\n const header_btn = document.querySelector(`#fund_${id}_header button`);\n header_btn.querySelector('span.name').textContent = title;\n header_btn.querySelector('span.amount').textContent = formatCurrency(new_amount);\n }\n};\nconst AddInitButton = {\n init() {\n const btn = document.querySelector('.btn-add-init');\n btn.addEventListener('click', function () {\n visitPage('new-inits');\n });\n }\n};\nconst Accordion = {\n Item: Item,\n AddInitButton: AddInitButton,\n hide: function () {\n document.querySelector('#accordion-div').style.display = 'none';\n // reset to delete content\n document.querySelector('#baseline-accordion .summary-accordion').innerHTML = '';\n document.querySelector('#supp-accordion .summary-accordion').innerHTML = '';\n },\n show: function () {\n document.querySelector('#accordion-div').style.display = 'block';\n },\n async createBaseline() {\n var funds = fund_lookup_table.listFunds();\n funds.forEach(fund => {\n Item.add(fund, 'baseline-accordion');\n Item.ExpenseTable.fillFromFund(fund);\n const fundObject = new models_fund(fund);\n Item.updateHeader(fund_lookup_table.getName(fund), fund, fundObject.getTotal());\n });\n },\n createSupp() {\n const supp = new supplemental();\n supp.initiatives.forEach(program => {\n Item.add(program.name, 'supp-accordion');\n Item.ExpenseTable.fillFromInit(program);\n Item.updateHeader(program.name, program.name, program.net());\n });\n },\n updateTopLines() {\n // adjuse baseline\n const baseline = new models_baseline();\n const baselineAmount = document.querySelector('#baseline-title .top-line-amount');\n baselineAmount.textContent = formatCurrency(baseline.total());\n // adjust supplementals\n const supp = new supplemental();\n const suppAmount = document.querySelector('#supp-title .top-line-amount');\n suppAmount.textContent = formatCurrency(supp.total());\n // color-code baseline\n if (baseline.total() <= models_baseline.target()) {\n baselineAmount.style.color = 'green';\n } else {\n baselineAmount.style.color = 'red';\n }\n },\n build() {\n this.createBaseline();\n this.createSupp();\n // initialize edit buttons\n components_table_table.Buttons.Edit.init(redirectForEdit);\n this.AddInitButton.init();\n this.updateTopLines();\n }\n};\n/* harmony default export */ const components_accordion_accordion = (Accordion);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/file_upload/file_upload.css\nvar file_upload = __webpack_require__(39);\n;// CONCATENATED MODULE: ./src/js/components/file_upload/file_upload.css\n\n \n \n \n \n \n \n \n \n \n\nvar file_upload_options = {};\n\nfile_upload_options.styleTagTransform = (styleTagTransform_default());\nfile_upload_options.setAttributes = (setAttributesWithoutAttributes_default());\nfile_upload_options.insert = insertBySelector_default().bind(null, \"head\");\nfile_upload_options.domAPI = (styleDomAPI_default());\nfile_upload_options.insertStyleElement = (insertStyleElement_default());\n\nvar file_upload_update = injectStylesIntoStyleTag_default()(file_upload/* default */.A, file_upload_options);\n\n\n\n\n /* harmony default export */ const file_upload_file_upload = (file_upload/* default */.A && file_upload/* default */.A.locals ? file_upload/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/file_upload/file_upload.js\n\n\n\nconst FileUpload = {\n init: function () {\n const inputObject = document.getElementById('file-input');\n inputObject.addEventListener('change', function (event) {\n readXL(event);\n });\n },\n show: function () {\n const inputObject = document.getElementById('file-input');\n inputObject.style.display = '';\n },\n hide: function () {\n const inputObject = document.getElementById('file-input');\n inputObject.style.display = 'none';\n }\n};\nfunction readXL(event) {\n // read uploaded file\n const file = event.target.files[0];\n if (file) {\n // delete any stored data before re-populating with Excel data\n // Sidebar.reset()\n // read in new data\n const reader = new FileReader();\n reader.onload = function (e) {\n const arrayBuffer = e.target.result;\n processWorkbook(arrayBuffer);\n };\n reader.onerror = function (err) {\n console.error('Error reading file:', err);\n };\n reader.readAsArrayBuffer(file); // Read the file as an ArrayBuffer\n }\n}\n/* harmony default export */ const components_file_upload_file_upload = (FileUpload);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/modal/modal.css\nvar modal = __webpack_require__(95);\n;// CONCATENATED MODULE: ./src/js/components/modal/modal.css\n\n \n \n \n \n \n \n \n \n \n\nvar modal_options = {};\n\nmodal_options.styleTagTransform = (styleTagTransform_default());\nmodal_options.setAttributes = (setAttributesWithoutAttributes_default());\nmodal_options.insert = insertBySelector_default().bind(null, \"head\");\nmodal_options.domAPI = (styleDomAPI_default());\nmodal_options.insertStyleElement = (insertStyleElement_default());\n\nvar modal_update = injectStylesIntoStyleTag_default()(modal/* default */.A, modal_options);\n\n\n\n\n /* harmony default export */ const modal_modal = (modal/* default */.A && modal/* default */.A.locals ? modal/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/modal/modal.js\n\nfunction clearModal() {\n updateModalTitle('');\n document.getElementById('modal-body').innerHTML = '';\n}\nfunction hideModal() {\n $('#main-modal').modal('hide');\n}\nfunction showModal() {\n $('#main-modal').modal('show');\n}\nfunction showModalHandler() {\n showModal('main-modal');\n}\nconst Submit = {\n handler: null,\n init: function (onSubmit) {\n const modal = document.getElementById('main-modal');\n // add onSubmit function as handler\n this.handler = function (event) {\n event.preventDefault();\n onSubmit(event);\n };\n // Adding the handler reference as the event listener\n modal.addEventListener('submit', this.handler);\n\n // add event listener to enable close x\n const x = modal.querySelector('#modal-close-x');\n x.addEventListener('click', hideModal);\n },\n deinit: function () {\n const modal = document.getElementById('main-modal');\n if (this.handler !== null) {\n // Removing the event listener and clear the handler\n modal.removeEventListener('submit', this.handler);\n this.handler = null;\n }\n // remove event listener to enable close x\n const x = modal.querySelector('#modal-close-x');\n x.removeEventListener('click', hideModal);\n }\n};\nconst Link = {\n add: function (button_id) {\n document.getElementById(button_id).addEventListener('click', showModalHandler);\n },\n remove: function (button_id) {\n document.getElementById(button_id).removeEventListener('click', showModalHandler);\n }\n};\nfunction updateModalTitle(title) {\n document.getElementById('modal-title').textContent = title;\n}\nconst Title = {\n update: function (title) {\n updateModalTitle(title);\n }\n};\nconst Modal = {\n hide: hideModal,\n show: showModal,\n clear: clearModal,\n Title: Title,\n Link: Link,\n Submit: Submit\n};\n/* harmony default export */ const components_modal_modal = (Modal);\n;// CONCATENATED MODULE: ./src/js/components/body/body.js\n\n\n\n\n\n\n\n\n\n\nfunction resetPage() {\n // hide everything in the body\n components_welcome_welcome.hide();\n components_modal_modal.clear();\n components_modal_modal.hide();\n components_nav_buttons_nav_buttons.hide();\n js_components_prompt_prompt.hide();\n components_table_table.hide();\n components_sidebar_sidebar.hide();\n components_accordion_accordion.hide();\n components_file_upload_file_upload.hide();\n components_tooltip_tooltip.hide();\n js_components_prompt_prompt.Buttons.reset();\n // disable submit button\n components_modal_modal.Submit.deinit();\n}\nconst Body = {\n reset: resetPage\n};\n/* harmony default export */ const components_body_body = (Body);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/header/header.css\nvar header = __webpack_require__(107);\n;// CONCATENATED MODULE: ./src/js/components/header/header.css\n\n \n \n \n \n \n \n \n \n \n\nvar header_options = {};\n\nheader_options.styleTagTransform = (styleTagTransform_default());\nheader_options.setAttributes = (setAttributesWithoutAttributes_default());\nheader_options.insert = insertBySelector_default().bind(null, \"head\");\nheader_options.domAPI = (styleDomAPI_default());\nheader_options.insertStyleElement = (insertStyleElement_default());\n\nvar header_update = injectStylesIntoStyleTag_default()(header/* default */.A, header_options);\n\n\n\n\n /* harmony default export */ const header_header = (header/* default */.A && header/* default */.A.locals ? header/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/header/header.js\n\n\nconst Subtitle = {\n update: function (subtitle) {\n // get current fund\n var fund = current_fund.name();\n if (fund) {\n var subtitle = `${subtitle}: ${fund}`;\n }\n document.getElementById(\"subtitle\").textContent = subtitle;\n }\n};\n/* harmony default export */ const components_header_header = (Subtitle);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/form/form.css\nvar form_form = __webpack_require__(109);\n;// CONCATENATED MODULE: ./src/js/components/form/form.css\n\n \n \n \n \n \n \n \n \n \n\nvar form_options = {};\n\nform_options.styleTagTransform = (styleTagTransform_default());\nform_options.setAttributes = (setAttributesWithoutAttributes_default());\nform_options.insert = insertBySelector_default().bind(null, \"head\");\nform_options.domAPI = (styleDomAPI_default());\nform_options.insertStyleElement = (insertStyleElement_default());\n\nvar form_update = injectStylesIntoStyleTag_default()(form_form/* default */.A, form_options);\n\n\n\n\n /* harmony default export */ const components_form_form = (form_form/* default */.A && form_form/* default */.A.locals ? form_form/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/form/subcomponents/fields.js\n// function to add questions to forms\n\n\n\n// inputType is for validation ('number' or 'text', etc)\nfunction appendFormElement(label, inputEl, inputId, required) {\n // change if we want forms elsewhere\n const form = document.getElementById('new-form');\n\n // create outer wrapper for element\n const wrapper = document.createElement('div');\n\n // label question\n const labelEl = document.createElement('label');\n labelEl.textContent = label;\n\n // mark as required if applicable\n inputEl.required = required;\n\n // If an ID is provided, set it on the element\n if (inputId) {\n inputEl.id = inputId;\n }\n\n // add elements\n wrapper.appendChild(labelEl);\n wrapper.appendChild(inputEl);\n form.appendChild(wrapper);\n}\nconst NewField = {\n shortText: function (label, inputId, required = false) {\n const inputEl = document.createElement('input');\n inputEl.type = 'text';\n appendFormElement(label, inputEl, inputId, required);\n },\n longText: function (label, inputId, required = false) {\n const inputEl = document.createElement('textarea');\n appendFormElement(label, inputEl, inputId, required);\n },\n numericInput: function (label, inputId, required = false) {\n const inputEl = document.createElement('input');\n inputEl.type = 'number';\n appendFormElement(label, inputEl, inputId, required);\n },\n dropdown: function (label, inputId, optionArray, required = false) {\n var inputEl = subcomponents_dropdown.create(optionArray);\n appendFormElement(label, inputEl, inputId, required);\n }\n};\n/* harmony default export */ const fields = (NewField);\n;// CONCATENATED MODULE: ./src/js/components/form/subcomponents/submit.js\nfunction addSubmitButtonToForm(form_id) {\n // Find the form by its ID\n const form = document.getElementById(form_id);\n\n // Create the container `div` for the button\n const buttonContainer = document.createElement('div');\n buttonContainer.id = 'submit-btn-container';\n\n // Create the submit input\n const submitInput = document.createElement('input');\n submitInput.className = 'btn btn-submit'; // Use appropriate class for your design\n submitInput.type = 'submit';\n submitInput.value = 'Submit';\n\n // Append the submit input to the container\n buttonContainer.appendChild(submitInput);\n\n // Append the container to the form\n form.appendChild(buttonContainer);\n}\nconst SubmitButton = {\n add: function () {\n addSubmitButtonToForm('new-form');\n }\n};\n/* harmony default export */ const subcomponents_submit = (SubmitButton);\n;// CONCATENATED MODULE: ./src/js/components/form/form.js\n\n\n\n\nfunction fetchAllResponses(event) {\n // Assuming `event.target` is the form itself\n const form = event.target;\n\n // Initialize an empty array to hold the input values\n let formData = {};\n\n // Loop through each form element\n for (let i = 0; i < form.elements.length; i++) {\n const element = form.elements[i];\n\n // Exclude elements that aren't inputs, textareas, or select\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA' || element.tagName === 'SELECT') {\n // Exclude input types that are not considered for submission (such as `submit`)\n if (element.type !== 'submit' && element.type !== 'button') {\n formData[element.id] = element.value;\n }\n }\n }\n form.reset();\n return formData;\n}\nfunction addForm(element_id = 'modal-body', form_id = 'new-form') {\n const target_elem = document.getElementById(element_id);\n\n // create form\n const form = document.createElement('form');\n form.setAttribute('id', form_id);\n\n // Append the form to the modal body\n target_elem.appendChild(form);\n}\nconst Form = {\n new: function (parent_elem_id) {\n addForm(parent_elem_id, 'new-form');\n },\n fetchAllResponses: function (event) {\n return fetchAllResponses(event);\n },\n NewField: fields,\n Dropdown: subcomponents_dropdown,\n SubmitButton: subcomponents_submit\n};\n/* harmony default export */ const js_components_form_form = (Form);\n;// CONCATENATED MODULE: ./src/js/views/view_class.js\n\n\n\n\n\n\n\n\n\nclass View {\n constructor() {\n // page state in local storage\n this.page_state = '';\n\n // whether to display\n this.navButtons = true;\n this.sidebar = true;\n\n // text to show in the prompt area\n this.prompt = null;\n\n // subtitle text\n this.subtitle = '';\n\n // table object of class ViewTable or null\n this.table = null;\n }\n visit() {\n // update page state\n current_page.update(this.page_state);\n\n // start with a blank page\n components_body_body.reset();\n\n // default to showing navbuttons\n if (this.navButtons) {\n components_nav_buttons_nav_buttons.show();\n }\n ;\n\n // default to showing sidebar\n if (this.sidebar) {\n components_sidebar_sidebar.show();\n }\n ;\n\n // initialize prompt text and buttons\n if (this.prompt) {\n js_components_prompt_prompt.Text.update(this.prompt);\n }\n ;\n\n // initialize table\n if (this.table) {\n this.table.build();\n }\n\n // show page subtitle\n if (this.subtitle) {\n components_header_header.update(this.subtitle);\n }\n ;\n }\n cleanup() {\n return;\n }\n}\nclass ViewTable {\n constructor() {\n // Ensure methods retain the correct `this` context\n this.submitNewRow = this.submitNewRow.bind(this);\n this.columns = [{\n title: 'Account String',\n className: 'account-string'\n }, {\n title: 'Appropriation Name',\n className: 'approp-name',\n hide: true\n }, {\n title: 'Appropriation',\n className: 'approp',\n hide: true\n }, {\n title: 'Cost Center Name',\n className: 'cc-name',\n hide: true\n }, {\n title: 'Cost Center',\n className: 'cc',\n hide: true\n }, {\n title: 'Fund Name',\n className: 'fund-name',\n hide: true\n }, {\n title: 'Fund',\n className: 'fund',\n hide: true\n }, {\n title: 'Edit',\n className: 'edit'\n }];\n\n // whether to add an edit column\n this.addEdit = true;\n\n // message to show if there's no saved data\n this.noDataMessage = null;\n\n // text to show for new row button\n this.addButtonText = null;\n\n // whether to show as a datatable\n this.dataTable = true;\n }\n async build() {\n // build table from local storage and initialize edit buttons\n\n // add the add new row button if needed\n if (this.addButtonText) {\n this.setUpForm();\n }\n\n // fill table with new data from local storage\n if (await components_table_table.Data.load()) {\n // create a datatable object\n if (this.dataTable) {\n this.initDataTable();\n }\n\n // add an edit column if needed\n if (this.addEdit) {\n components_table_table.Columns.addAtEnd(components_table_table.Buttons.edit_confirm_btns, 'Edit');\n // activate edit buttons\n components_table_table.Buttons.Edit.init(this.actionOnEdit, this.updateTable);\n }\n\n // assign the correct classes based on the table columns\n components_table_table.Columns.assignClasses(this.columns);\n\n // Apply any update function to make sure sidebar is up to date\n this.updateTable();\n } else {\n // show a message if there's no saved table data for the selected fund\n if (this.noDataMessage) {\n js_components_prompt_prompt.Text.update(this.noDataMessage);\n }\n }\n }\n initDataTable() {\n components_table_table.adjustWidth('100%');\n // Initialize Datatables\n if (!$.fn.dataTable.isDataTable('#main-table')) {\n $('#main-table').DataTable({\n paging: false,\n // Disable pagination\n info: false // Disable table information display\n });\n }\n ;\n // Move the search bar outside the table container\n $('#main-table_filter').appendTo('#search-bar-container');\n }\n\n // placeholder for action on row edit click\n actionOnEdit() {\n return;\n }\n\n // update function for the sidebar; default to just saving the table\n updateTable() {\n components_table_table.save();\n }\n\n // extra questions of the form to add a new row\n addCustomQuestions() {\n return;\n }\n setUpForm() {\n // show add button\n components_table_table.Buttons.AddRow.show();\n components_table_table.Buttons.AddRow.updateText(this.addButtonText);\n\n // set up modal for form when add button is pressed\n components_modal_modal.clear();\n components_modal_modal.Link.add('add-btn');\n components_modal_modal.Title.update(this.addButtonText);\n\n // create form\n js_components_form_form.new('modal-body');\n\n // add custom questions\n this.addCustomQuestions();\n // add submit button\n js_components_form_form.SubmitButton.add();\n\n // Initialize form submission to table data\n components_modal_modal.Submit.init(this.submitNewRow);\n }\n editColumns(responses) {\n // get numbers from account string names\n if (responses['fund-name']) {\n responses['fund'] = account_string.getNumber(responses['fund-name']);\n }\n ;\n if (responses['approp-name']) {\n responses['approp'] = account_string.getNumber(responses['approp-name']);\n }\n ;\n if (responses['cc-name']) {\n responses['cc'] = account_string.getNumber(responses['cc-name']);\n }\n ;\n if (responses['object-name']) {\n responses['object'] = account_string.getNumber(responses['object-name']);\n }\n ;\n responses['account-string'] = account_string.build(responses['approp-name'], responses['cc-name'], responses['object-name'], responses['fund']);\n return responses;\n }\n submitNewRow(event) {\n // get answers from form, hide form, show answers in table\n var responses = js_components_form_form.fetchAllResponses(event);\n\n // edit inputs from modal\n responses = this.editColumns(responses);\n\n // make sure it's not an empty response\n if (Object.values(responses)[0] != '') {\n // change page view\n components_modal_modal.hide();\n\n // add data to table\n components_table_table.Rows.add(responses, this.columns);\n components_table_table.save();\n\n // rebuild table\n this.build();\n }\n }\n}\n;// CONCATENATED MODULE: ./src/js/views/00_welcome.js\n\n\n\nclass WelcomeView extends View {\n constructor() {\n super();\n this.page_state = 'welcome';\n this.subtitle = 'Welcome';\n this.sidebar = false;\n this.navButtons = false;\n }\n visit() {\n super.visit();\n\n // show welcome section\n components_welcome_welcome.show();\n\n // initialize links in buttons\n document.getElementById('step-upload').addEventListener('click', () => visitPage('upload'));\n document.getElementById('step-initiatives').addEventListener('click', () => visitPage('new-inits'));\n document.getElementById('step-revenue').addEventListener('click', () => visitPage('baseline-landing'));\n document.getElementById('step-finish').addEventListener('click', () => visitPage('summary'));\n }\n}\n/* harmony default export */ const _00_welcome = (WelcomeView);\n;// CONCATENATED MODULE: ./src/js/views/01_upload.js\n\n\n\nclass UploadView extends View {\n constructor() {\n super();\n this.page_state = 'upload';\n this.prompt = `Upload the baseline detail sheet given by your budget analyst.`;\n this.subtitle = 'Excel Upload';\n this.sidebar = false;\n }\n visit() {\n super.visit();\n // disable continue button until Excel file is uploaded and read\n components_nav_buttons_nav_buttons.Next.disable();\n components_file_upload_file_upload.show();\n components_file_upload_file_upload.init();\n components_nav_buttons_nav_buttons.Next.enable();\n }\n}\n/* harmony default export */ const _01_upload = (UploadView);\n;// CONCATENATED MODULE: ./src/js/views/02_baseline_landing.js\n\n\n\n\nclass FundView extends View {\n constructor() {\n super();\n this.page_state = 'baseline-landing';\n this.prompt = `We will now ask you a series of questions about your BASELINE budget request.\n At the end, we will ask you about any new initiatives (ie. supplemental requests).\n Select one of your funds then click continue.`;\n this.subtitle = 'Baseline Budget Request';\n this.table = new FundTable();\n this.sidebar = false;\n this.dataTable = false;\n }\n visit() {\n // remove fund selection\n localStorage.setItem(\"fund\", '');\n super.visit();\n }\n}\nclass FundTable extends ViewTable {\n constructor() {\n super();\n\n // add additional revenue columns to the table\n this.columns = [{\n title: 'Fund',\n className: 'fund-name'\n }];\n this.noDataMessage = 'No funds found.';\n this.addEdit = false;\n }\n build() {\n // load in fund data\n components_table_table.show();\n components_table_table.Data.loadFunds();\n components_table_table.Columns.assignClasses(this.columns);\n components_table_table.adjustWidth('30%');\n\n // disable next button until a fund is selected\n components_nav_buttons_nav_buttons.Next.disable();\n allowRowSelection();\n }\n}\nfunction allowRowSelection() {\n var tableRows = document.querySelectorAll(\"tbody tr\");\n\n // enable highlight on hover and on select\n tableRows.forEach(function (row) {\n row.addEventListener('mouseover', function () {\n this.classList.add('hover-effect');\n });\n row.addEventListener('mouseout', function () {\n this.classList.remove('hover-effect');\n });\n row.addEventListener('click', function () {\n selectFund(tableRows, this);\n });\n });\n}\nfunction selectFund(tableRows, selected_row) {\n // remove selected class from any other rows\n tableRows.forEach(function (tableRow) {\n tableRow.classList = '';\n });\n\n // add selected class to clicked row\n selected_row.classList.add('selected');\n\n // get fund and save selected fund\n var fund = selected_row.querySelector('.fund-name').textContent;\n var fundNumber = parseInt(fund);\n current_fund.update(fundNumber);\n\n // enable next step\n components_nav_buttons_nav_buttons.Next.enable();\n}\n/* harmony default export */ const _02_baseline_landing = (FundView);\n;// CONCATENATED MODULE: ./src/js/views/03_revenue.js\n\n\nclass RevenueView extends View {\n constructor(fiscal_year) {\n super();\n this.page_state = 'revenue';\n this.prompt = `Review and edit revenue line items. If you change the estimate or \n notice an error in an account string, please note it in the notes column. Click edit \n to change values in a row.`;\n this.subtitle = 'Revenues';\n this.table = new RevenueTable(fiscal_year);\n }\n}\nclass RevenueTable extends ViewTable {\n constructor(fiscal_year) {\n super();\n\n // add additional revenue columns to the table\n this.columns = this.columns.concat([{\n title: 'Recurring or One-Time',\n className: 'recurring'\n }, {\n title: 'Object Category',\n className: 'object-category'\n }, {\n title: `FY${fiscal_year} Departmental Estimate`,\n className: 'request',\n isCost: true\n }, {\n title: 'Departmental Estimate Notes',\n className: 'notes'\n }]);\n this.noDataMessage = 'No revenues for this fund.';\n }\n\n // action on row edit click: make cells editable\n actionOnEdit() {\n components_table_table.Cell.createTextbox('request', true);\n components_table_table.Cell.createTextbox('notes');\n components_table_table.Cell.createDropdown('recurring', ['One-Time', 'Recurring']);\n }\n}\n/* harmony default export */ const _03_revenue = (RevenueView);\n;// CONCATENATED MODULE: ./src/js/views/04_personnel.js\n\n\n\n\n\n\nclass PersonnelView extends View {\n constructor(fiscal_year) {\n super();\n this.page_state = 'personnel';\n this.prompt = `\n This table displays the number of FTEs in each job code for in your department's \n current (amended) FY25 budget. To make edits to the number of positions, click the\n \"Edit\" button on the row you would like to edit. The \"Total Cost\" column and the \n summary sidebar will also update to reflect any edits.`;\n this.subtitle = 'Personnel';\n this.table = new PersonnelTable(fiscal_year);\n }\n}\nclass PersonnelTable extends ViewTable {\n constructor(fiscal_year) {\n super();\n this.fiscal_year = fiscal_year;\n // add additional personnel columns to the table\n this.columns = this.columns.concat([{\n title: 'Job Title',\n className: 'job-name'\n }, {\n title: 'Employee Type',\n className: 'employee-type'\n }, {\n title: 'Service',\n className: 'service'\n }, {\n title: `FY${this.fiscal_year} Requested FTE`,\n className: 'baseline-ftes'\n }, {\n title: `FY${this.fiscal_year} Projected Average Salary/Wage`,\n className: 'avg-salary',\n isCost: true\n }, {\n title: 'Total Sal/Wag & Ben Request',\n className: 'total-baseline',\n isCost: true\n },\n // hidden columns\n {\n title: 'Fringe Benefits Rate',\n className: 'fringe',\n hide: true\n }, {\n title: 'General Increase Rate',\n className: 'general-increase-rate',\n hide: true\n }, {\n title: 'Step/Merit Increase Rate',\n className: 'merit-increase-rate',\n hide: true\n }, {\n title: `Average Salary/Wage as of 9/1/20${this.fiscal_year - 2}`,\n className: 'current-salary',\n isCost: true,\n hide: true\n }]);\n this.noDataMessage = 'No personnel expenditures for this fund.';\n this.addButtonText = 'Add new job';\n }\n\n // action on row edit click: make cells editable\n actionOnEdit() {\n components_table_table.Cell.createTextbox('baseline-ftes');\n components_table_table.Cell.createServiceDropdown(services.list());\n }\n updateTable() {\n // calculate for each row\n let rows = document.getElementsByTagName('tr');\n for (let i = 1; i < rows.length; i++) {\n // fetch values for calculations\n let avg_salary = components_table_table.Cell.getValue(rows[i], 'avg-salary');\n let fringe = parseFloat(components_table_table.Cell.getText(rows[i], 'fringe'));\n let baseline_ftes = components_table_table.Cell.getText(rows[i], 'baseline-ftes');\n\n // calcuate #FTEs x average salary + COLA adjustments + merit adjustments + fringe\n let total_baseline_cost = avg_salary * baseline_ftes * (1 + fringe);\n\n // update total column\n components_table_table.Cell.updateValue(rows[i], 'total-baseline', total_baseline_cost);\n }\n\n // Save the table after all updates are done\n components_table_table.save();\n }\n addCustomQuestions() {\n // form questions to add a new job\n js_components_form_form.NewField.shortText('Job Title:', 'job-name', true);\n js_components_form_form.NewField.dropdown('Employee Type:', 'employee-type', EMPLOYEE_TYPES, true), js_components_form_form.NewField.dropdown('Appropriation:', 'approp-name', fund_lookup_table.getApprops(), true);\n js_components_form_form.NewField.dropdown('Cost Center:', 'cc-name', fund_lookup_table.getCostCenters(), true);\n js_components_form_form.NewField.dropdown('Service', 'service', services.list(), true);\n js_components_form_form.NewField.shortText('Number of FTEs requested:', 'baseline-ftes', true);\n js_components_form_form.NewField.shortText(`Projected average salary IN FISCAL YEAR ${this.fiscal_year}:`, 'avg-salary', true);\n js_components_form_form.NewField.shortText(`Expected fringe rate (as a percentage)`, 'fringe', true);\n }\n editColumns(responses) {\n responses = super.editColumns(responses);\n // edit inputs from modal\n responses['avg-salary'] = common_utils_unformatCurrency(responses['avg-salary']);\n responses['fringe'] = parseFloat(responses['fringe']) / 100;\n return responses;\n }\n}\n/* harmony default export */ const _04_personnel = (PersonnelView);\n;// CONCATENATED MODULE: ./src/js/views/05_overtime.js\n\n\n\n\n\n\nclass OvertimeView extends View {\n constructor(fiscal_year) {\n super();\n this.page_state = 'overtime';\n this.prompt = `\n Please see your baseline overtime / holiday pay / shift premiums in the table below.\n Make any edits and continue.`;\n this.subtitle = 'Overtime Estimates';\n this.table = new OvertimeTable(fiscal_year);\n }\n}\nclass OvertimeTable extends ViewTable {\n constructor(fiscal_year) {\n super();\n\n // add additional OT columns to the table\n this.columns = this.columns.concat([{\n title: 'Service',\n className: 'service'\n }, {\n title: 'Recurring or One-Time',\n className: 'recurring'\n }, {\n title: 'Departmental Request OT/SP/Hol',\n className: 'OT-pay',\n isCost: true\n }, {\n title: `FY${fiscal_year} Total OT/SP/Hol + FICA Request`,\n className: 'total',\n isCost: true\n }, {\n title: 'Object Name',\n className: 'object-name'\n },\n // hidden columns\n {\n title: 'FICA Rate',\n className: 'fica',\n hide: true\n }]);\n this.noDataMessage = 'No overtime expenditures for this fund.';\n this.addButtonText = 'Add new cost center';\n }\n\n // action on row edit click: make cells editable\n actionOnEdit() {\n components_table_table.Cell.createTextbox('OT-pay', true);\n components_table_table.Cell.createServiceDropdown(services.list());\n components_table_table.Cell.createDropdown('recurring', ['One-Time', 'Recurring']);\n components_table_table.Cell.createDropdown('object-name', OT_OBJECTS);\n }\n updateTable() {\n // calculate for each row\n let rows = document.getElementsByTagName('tr');\n for (let i = 1; i < rows.length; i++) {\n // fetch values for calculations\n let OT_salary = components_table_table.Cell.getValue(rows[i], 'OT-pay');\n let fica_rate = components_table_table.Cell.getText(rows[i], 'fica');\n\n // add salary and wages and fringe benefits (FICA)\n let row_total = OT_salary * (1 + parseFloat(fica_rate));\n\n // update total\n components_table_table.Cell.updateValue(rows[i], 'total', row_total);\n }\n\n // Save the table after all updates are done\n components_table_table.save();\n }\n addCustomQuestions() {\n // form questions to add a new job\n js_components_form_form.NewField.dropdown('Appropriation:', 'approp-name', fund_lookup_table.getApprops(), true);\n js_components_form_form.NewField.dropdown('Cost Center:', 'cc-name', fund_lookup_table.getCostCenters(), true);\n js_components_form_form.NewField.dropdown('Object (salary or wage):', 'object-name', OT_OBJECTS, true);\n js_components_form_form.NewField.dropdown('Service', 'service', services.list(), true);\n js_components_form_form.NewField.dropdown('Recurring or One-Time', 'recurring', ['Recurring', 'One-Time'], true);\n js_components_form_form.NewField.shortText('Overtime amount requested:', 'OT-pay', true);\n }\n editColumns(responses) {\n responses = super.editColumns(responses);\n // edit inputs from modal\n responses['OT-pay'] = common_utils_unformatCurrency(responses['OT-pay']);\n responses['fica'] = 0.0765;\n return responses;\n }\n}\n/* harmony default export */ const _05_overtime = (OvertimeView);\n;// CONCATENATED MODULE: ./src/js/views/06_nonpersonnel.js\n\n\n\n\n\n\nclass NonPersonnelView extends View {\n constructor(fiscal_year) {\n super();\n this.page_state = 'nonpersonnel';\n this.prompt = 'Review and edit non-personnel line items.';\n this.subtitle = 'Non-Personnel';\n this.table = new NonPersonnelTable(fiscal_year);\n }\n}\nclass NonPersonnelTable extends ViewTable {\n constructor(fiscal_year) {\n super();\n\n // add additional personnel columns to the table\n this.columns = this.columns.concat([{\n title: `FY${fiscal_year} Departmental Request Total`,\n className: 'request',\n isCost: true\n }, {\n title: 'Service',\n className: 'service'\n }, {\n title: 'Recurring or One-Time',\n className: 'recurring'\n }, {\n title: 'CPA #',\n className: 'cpa'\n },\n // hidden columns\n {\n title: 'End Date',\n className: 'contract-end',\n hide: true\n }, {\n title: 'BPA/CPA Amount Remaining',\n className: 'remaining',\n isCost: true,\n hide: true\n }, {\n title: 'Object Name',\n className: 'object-name',\n hide: true\n }, {\n title: 'Object',\n className: 'object',\n hide: true\n }, {\n title: 'Vendor Name',\n className: 'vendor',\n hide: true\n }, {\n title: 'Object Category',\n className: 'object-category',\n hide: true\n }, {\n title: 'BPA/CPA Description',\n className: 'cpa-description',\n hide: true\n }]);\n this.noDataMessage = 'No non-personnel expenditures for this fund.';\n this.addButtonText = 'Add new job';\n }\n\n // action on row edit click: make cells editable\n actionOnEdit() {\n components_table_table.Cell.createTextbox('request', true);\n components_table_table.Cell.createServiceDropdown();\n components_table_table.Cell.createDropdown('recurring', ['One-Time', 'Recurring']);\n }\n addCustomQuestions() {\n // form questions to add a new row\n js_components_form_form.NewField.dropdown('Appropriation:', 'approp-name', fund_lookup_table.getApprops(), true);\n js_components_form_form.NewField.dropdown('Cost Center:', 'cc-name', fund_lookup_table.getCostCenters(), true);\n js_components_form_form.NewField.dropdown('Object Category:', 'object-category', OBJ_CATEGORIES.list, true);\n // TODO: maybe give dropdown based on selected obj category\n js_components_form_form.NewField.shortText('Object Number (if known):', 'object', false);\n js_components_form_form.NewField.dropdown('Service', 'service', services.list(), true);\n js_components_form_form.NewField.longText('Describe your new request:', 'cpa-description', true);\n js_components_form_form.NewField.dropdown('Recurring or One-Time', 'recurring', ['Recurring', 'One-Time'], true);\n js_components_form_form.NewField.shortText('Amount requested:', 'request', true);\n }\n editColumns(responses) {\n responses = super.editColumns(responses);\n responses['avg-salary'] = common_utils_unformatCurrency(responses['avg-salary']);\n responses['fringe'] = parseFloat(responses['fringe']) / 100;\n return responses;\n }\n}\n/* harmony default export */ const _06_nonpersonnel = (NonPersonnelView);\n;// CONCATENATED MODULE: ./src/js/views/07_new_initiatives.js\n\n\n\n\n\nconst dropdownOptions = ['N/A', 'One-Time', 'Recurring'];\n\n// set up page and initialize all buttons\nclass InitiativesView extends View {\n constructor() {\n super();\n this.page_state = 'new-inits';\n this.prompt = `\n This is the place to propose new initiatives for FY${FISCAL_YEAR}.\n New initiative submissions will count as supplemental line items and will be the starting \n point for a conversation with both OB and ODFS, who will help with the details.`;\n this.subtitle = 'New Initiatives';\n this.table = new InitiativesTable();\n }\n visit() {\n // remove fund selection\n localStorage.setItem(\"fund\", '');\n super.visit();\n }\n}\nclass InitiativesTable extends ViewTable {\n constructor() {\n super();\n\n // add additional columns to the table\n this.columns = this.columns.concat([{\n title: 'Initiative Name',\n className: 'init-name'\n }, {\n title: 'Ballpark Total Expenses',\n className: 'total',\n isCost: true\n }, {\n title: 'Personnel Cost',\n className: 'personnel',\n isCost: true\n }, {\n title: 'Non-personnel Cost',\n className: 'nonpersonnel',\n isCost: true\n }, {\n title: 'Revenue',\n className: 'revenue',\n isCost: true\n }, {\n title: 'Revenue Type',\n className: 'rev-type'\n },\n // hide the explanation columns\n {\n title: 'Q1',\n className: 'q1',\n hide: true\n }, {\n title: 'Q2',\n className: 'q2',\n hide: true\n }, {\n title: 'Q3',\n className: 'q3',\n hide: true\n }]);\n this.addButtonText = 'Add new initiative';\n }\n addCustomQuestions() {\n // general questions\n js_components_form_form.NewField.shortText('Initiative Name:', 'init-name', true);\n js_components_form_form.NewField.longText('What is the business case for the Initiative?', 'q1', true);\n js_components_form_form.NewField.longText(`Why is the initiative needed? What is the value-add to residents? \n What is the Department’s plan for implementing the Initiative?`, 'q2', true);\n js_components_form_form.NewField.longText(`Why can’t the Initiative be funded with the Department’s baseline budget?`, 'q3', true);\n\n // TODO: Edit to drop down\n js_components_form_form.NewField.dropdown('Fund:', 'fund-name', fund_lookup_table.listFundNames(), true);\n js_components_form_form.NewField.dropdown('Appropriation (if known):', 'approp-name', fund_lookup_table.getApprops(), true);\n js_components_form_form.NewField.dropdown('Cost Center (if known):', 'cc-name', fund_lookup_table.getCostCenters(), true);\n\n // Numbers\n js_components_form_form.NewField.numericInput('What is your ballpark estimate of TOTAL ADDITONAL expenses associated with this initiative?', 'total', false);\n js_components_form_form.NewField.numericInput('Estimate of ADDITONAL personnel cost?', 'personnel', false);\n js_components_form_form.NewField.numericInput('Estimate of ADDITONAL nonpersonnel cost?', 'nonpersonnel', false);\n js_components_form_form.NewField.numericInput('Estimate of ADDITONAL revenue (if applicable)?', 'revenue', false);\n js_components_form_form.NewField.dropdown(`If there will be revenue, is it one-time or recurring?`, 'rev-type', dropdownOptions);\n }\n\n // action on row edit click: make cells editable\n actionOnEdit() {\n components_table_table.Cell.createTextbox('total', true);\n components_table_table.Cell.createTextbox('revenue', true);\n components_table_table.Cell.createTextbox('personnel', true);\n components_table_table.Cell.createTextbox('nonpersonnel', true);\n components_table_table.Cell.createTextbox('init-name');\n components_table_table.Cell.createDropdown('rev-type', dropdownOptions);\n }\n}\n/* harmony default export */ const _07_new_initiatives = (InitiativesView);\n;// CONCATENATED MODULE: ./src/js/views/08_summary.js\n\n\n\n\n\n\n\n\nfunction compareToTarget() {\n const baseline = new models_baseline();\n if (baseline.total() <= models_baseline.target()) {\n js_components_prompt_prompt.Text.update(`Congrats! Your budget is below your target! \n Edit any line items below or download your completed Excel.`);\n } else {\n js_components_prompt_prompt.Text.update(`Your budget is above your target of ${formatCurrency(models_baseline.target())}. \n Please expand the summary table below and edit line items until you meet your target. \n When you meet the target, you will be able to download the Excel sheet.`);\n js_components_prompt_prompt.Buttons.Right.disable();\n }\n js_components_prompt_prompt.show();\n}\nfunction returnToWelcome() {\n const welcome = new _00_welcome();\n const left = document.getElementById('option1');\n console.log(left.l);\n welcome.visit();\n}\n;\nclass SummaryView extends View {\n constructor() {\n super();\n this.page_state = 'summary';\n this.subtitle = 'Summary';\n this.sidebar = false;\n }\n visit() {\n super.visit();\n\n // reset fund\n current_fund.reset();\n\n // show summary accordion\n Accordion.build();\n Accordion.show();\n\n // add prompt buttons\n js_components_prompt_prompt.Buttons.Right.updateText('Download Excel');\n js_components_prompt_prompt.Buttons.Left.updateText('Start over with new Excel upload');\n // add button links\n js_components_prompt_prompt.Buttons.Left.addAction(returnToWelcome);\n js_components_prompt_prompt.Buttons.Right.addAction(downloadXLSX);\n\n // update prompt text depending on target matching\n compareToTarget();\n }\n cleanup() {\n // delete event listeners\n js_components_prompt_prompt.Buttons.Left.removeAction(returnToWelcome);\n js_components_prompt_prompt.Buttons.Right.removeAction(downloadXLSX);\n js_components_prompt_prompt.Buttons.Right.enable();\n }\n}\n/* harmony default export */ const _08_summary = (SummaryView);\n;// CONCATENATED MODULE: ./src/js/views/view_logic.js\n\n\n\n\n\n\n\n\n\n\n\nfunction initializePages() {\n const PAGES = {\n 'welcome': new _00_welcome(),\n 'upload': new _01_upload(),\n 'baseline-landing': new _02_baseline_landing(),\n 'revenue': new _03_revenue(FISCAL_YEAR),\n 'personnel': new _04_personnel(FISCAL_YEAR),\n 'overtime': new _05_overtime(FISCAL_YEAR),\n 'nonpersonnel': new _06_nonpersonnel(FISCAL_YEAR),\n 'new-inits': new _07_new_initiatives(),\n 'summary': new _08_summary()\n };\n return PAGES;\n}\nfunction visitPage(new_page_key) {\n const PAGES = initializePages();\n\n // clean up from current page\n var page_state = current_page.load();\n PAGES[page_state].cleanup();\n\n // Use the page_state to access and call the corresponding function from PAGES\n if (PAGES[new_page_key]) {\n // Invokes the function if it exists in the PAGES map\n PAGES[new_page_key].visit();\n } else {\n console.error(`No page initializer found for state: ${new_page_key}`);\n }\n}\nfunction nextPage() {\n const PAGES = initializePages();\n var page_state = current_page.load();\n const keys = Object.keys(PAGES);\n\n // Find the index of the current key\n const currentIndex = keys.indexOf(page_state);\n\n // unless on personnel (which will go to overtime), return to summary if all funds are viewed\n const returnPages = ['revenue', 'nonpersonnel', 'new-inits', 'overtime'];\n if (!fund_lookup_table.fundsLeft() && returnPages.includes(current_page.load())) {\n visitPage('summary');\n return;\n }\n\n // if on non-personnel, circle back to fund selection unless all funds are edited\n if (current_page.load() == 'nonpersonnel') {\n // mark fund as viewed/edited\n fund_lookup_table.editFund(current_fund.number());\n // if any funds left to edit, go back to that page\n if (fund_lookup_table.fundsLeft()) {\n visitPage('baseline-landing');\n return;\n }\n }\n if (currentIndex >= 0 && currentIndex < keys.length - 1) {\n // Check if there is a next key, and get it\n const nextKey = keys[currentIndex + 1];\n // go to that page\n visitPage(nextKey);\n }\n}\nfunction lastPage() {\n const PAGES = initializePages();\n var page_state = current_page.load();\n const keys = Object.keys(PAGES);\n\n // Find the index of the current key\n const currentIndex = keys.indexOf(page_state);\n\n // if on new-inits, circle back to fund selection\n if (current_page.load() == 'new-inits') {\n visitPage('baseline-landing');\n return;\n }\n\n // Check if there is a next key\n if (currentIndex >= 1) {\n // Get the next key\n const lastKey = keys[currentIndex - 1];\n // go to that page\n visitPage(lastKey);\n }\n}\n;// CONCATENATED MODULE: ./src/js/models/current_page.js\n\nconst CurrentPage = {\n update: function (page) {\n localStorage.setItem('page_state', page);\n },\n load: function () {\n const pageState = localStorage.getItem('page_state');\n return pageState !== null ? pageState : 'welcome';\n },\n visit: function () {\n visitPage(this.load());\n }\n};\n/* harmony default export */ const current_page = (CurrentPage);\n;// CONCATENATED MODULE: ./src/js/init.js\n// import styles\n\n\n// import functions\n\ndocument.addEventListener('DOMContentLoaded', function () {\n current_page.visit();\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIxLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3hCQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDeEJBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFFQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUM5RUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3hCQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVFBOztBQUVBO0FBQ0E7QUFXQTs7QUM5QkE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FDekVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQy9HQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUNsQkE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUN6Q0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUNqREE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDVEE7O0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFFQTtBQUVBOztBQzdCQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTs7QUNsQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ3hDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDeEJBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3hCQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQzdCQTtBQUNBO0FBRUE7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUN6RUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDdkdBO0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFFQTs7QUN6QkE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBRUE7O0FDekVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ3JNQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7O0FDN0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7OztBQ3pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUMxTUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUM3RUE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7Ozs7QUNuTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3hCQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN2QkE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUM3RUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4QkE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDeEJBOztBQUVBOztBQUVBO0FBQ0E7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUNwREE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBOztBQ3pCQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFHQTtBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7O0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFBQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBOztBQUVBO0FBQ0E7QUFBQTtBQUFBOztBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFBQTtBQUFBOztBQUVBO0FBQ0E7QUFBQTtBQUFBOztBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUtBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUNyTkE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBOztBQy9CQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFHQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBRUE7O0FDM0ZBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUN6Q0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDekZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ3RFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFHQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTs7QUMzRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBRUE7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2R0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUNmQTtBQUNBOztBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2Nzcy9jb21tb24uY3NzPzhmZjYiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3dlbGNvbWUvd2VsY29tZS5jc3M/ZGVlMSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvd2VsY29tZS93ZWxjb21lLmpzPzUzNWEiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3Byb21wdC9wcm9tcHQuY3NzPzMyOGIiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3Byb21wdC9zdWJjb21wb25lbnRzL3RleHQuanM/ZjZkZiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvcHJvbXB0L3N1YmNvbXBvbmVudHMvYnV0dG9ucy5qcz84ZDNiIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9wcm9tcHQvcHJvbXB0LmpzP2E3NzEiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3NpZGViYXIvc2lkZWJhci5jc3M/M2JjNyIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbnN0YW50cy9idWRnZXRfY29uc3RhbnRzLmpzPzE1MDIiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb25zdGFudHMvZXhjZWxfY29uc3RhbnRzLmpzP2Y2ODciLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb25zdGFudHMvaW5kZXguanM/MjVjNCIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL3V0aWxzL2NvbW1vbl91dGlscy5qcz80NGYyIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvbW9kZWxzL2Z1bmRfbG9va3VwX3RhYmxlLmpzP2RjNjYiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9tb2RlbHMvY3VycmVudF9mdW5kLmpzP2U2ZGIiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9tb2RlbHMvYWNjb3VudF9zdHJpbmcuanM/NmM4ZCIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL21vZGVscy9mdW5kLmpzPzZjZmEiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9tb2RlbHMvYmFzZWxpbmUuanM/ZDQ5NCIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL21vZGVscy9zZXJ2aWNlcy5qcz8xMzlmIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvbW9kZWxzL2luaXRpYXRpdmUuanM/Zjk2YSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL21vZGVscy9zdXBwbGVtZW50YWwuanM/OTljZSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL21vZGVscy9pbmRleC5qcz8wNWUxIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9zaWRlYmFyL3N1YmNvbXBvbmVudHMvYmFzZWxpbmVfc2VjdGlvbi5qcz8xM2JkIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9zaWRlYmFyL3N1YmNvbXBvbmVudHMvc3VwcF9zZWN0aW9uLmpzPzBjNGUiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3NpZGViYXIvc2lkZWJhci5qcz84MGYwIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9uYXZfYnV0dG9ucy9uYXZfYnV0dG9ucy5jc3M/NzA3ZiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvbmF2X2J1dHRvbnMvbmF2X2J1dHRvbnMuanM/YWJkMSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvYm9keS9ib2R5LmNzcz9kMWM3Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9hY2NvcmRpb24vYWNjb3JkaW9uLmNzcz81YTZjIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy90YWJsZS90YWJsZS5jc3M/Nzg0YyIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvdGFibGUvc3ViY29tcG9uZW50cy9oZWFkZXJzLmpzPzE2MjMiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3RhYmxlL3N1YmNvbXBvbmVudHMvcm93cy5qcz9mYjc5Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy90YWJsZS9zdWJjb21wb25lbnRzL2J1dHRvbnMuanM/Yzk5MiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvZm9ybS9zdWJjb21wb25lbnRzL2Ryb3Bkb3duLmpzP2JhNmIiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3RhYmxlL3N1YmNvbXBvbmVudHMvY2VsbHMuanM/NzNjYiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvdGFibGUvc3ViY29tcG9uZW50cy9jb2x1bW5zLmpzPzY3NGEiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3RhYmxlL3N1YmNvbXBvbmVudHMvZGF0YS5qcz9kOWI2Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdXRpbHMvWExTWF9oYW5kbGVycy5qcz9iYThhIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy90b29sdGlwL3Rvb2x0aXAuY3NzP2JjOGMiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3Rvb2x0aXAvdG9vbHRpcC5qcz9kMjNjIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdXRpbHMvSlNPTl9kYXRhX2hhbmRsZXJzLmpzP2M5ZDIiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3RhYmxlL3RhYmxlLmpzPzMwNzEiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2FjY29yZGlvbi9hY2NvcmRpb24uanM/MWYzNyIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvZmlsZV91cGxvYWQvZmlsZV91cGxvYWQuY3NzP2RiMDkiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2ZpbGVfdXBsb2FkL2ZpbGVfdXBsb2FkLmpzPzUxODgiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL21vZGFsL21vZGFsLmNzcz80MGRiIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9tb2RhbC9tb2RhbC5qcz81NTMzIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9ib2R5L2JvZHkuanM/ZjliYSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvaGVhZGVyL2hlYWRlci5jc3M/NzJkNyIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvaGVhZGVyL2hlYWRlci5qcz9hMGE1Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9mb3JtL2Zvcm0uY3NzPzU0MTUiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2Zvcm0vc3ViY29tcG9uZW50cy9maWVsZHMuanM/NDU5ZiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvZm9ybS9zdWJjb21wb25lbnRzL3N1Ym1pdC5qcz9jNTk2Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9mb3JtL2Zvcm0uanM/ZDk0MiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL3ZpZXdzL3ZpZXdfY2xhc3MuanM/YTc5ZSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL3ZpZXdzLzAwX3dlbGNvbWUuanM/MDhiYiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL3ZpZXdzLzAxX3VwbG9hZC5qcz9jNDQ4Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdmlld3MvMDJfYmFzZWxpbmVfbGFuZGluZy5qcz83YjhlIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdmlld3MvMDNfcmV2ZW51ZS5qcz9iODc4Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdmlld3MvMDRfcGVyc29ubmVsLmpzP2ZiZmYiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy92aWV3cy8wNV9vdmVydGltZS5qcz9iZjcwIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdmlld3MvMDZfbm9ucGVyc29ubmVsLmpzPzRkM2QiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy92aWV3cy8wN19uZXdfaW5pdGlhdGl2ZXMuanM/NDFhNyIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL3ZpZXdzLzA4X3N1bW1hcnkuanM/OGIzMiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL3ZpZXdzL3ZpZXdfbG9naWMuanM/NDZjNiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL21vZGVscy9jdXJyZW50X3BhZ2UuanM/ZmZiMCIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2luaXQuanM/MWIyYSJdLCJzb3VyY2VzQ29udGVudCI6WyJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vY29tbW9uLmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xub3B0aW9ucy5pbnNlcnQgPSBpbnNlcnRGbi5iaW5kKG51bGwsIFwiaGVhZFwiKTtcbm9wdGlvbnMuZG9tQVBJID0gZG9tQVBJO1xub3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQgPSBpbnNlcnRTdHlsZUVsZW1lbnQ7XG5cbnZhciB1cGRhdGUgPSBBUEkoY29udGVudCwgb3B0aW9ucyk7XG5cblxuXG5leHBvcnQgKiBmcm9tIFwiISEuLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL2NvbW1vbi5jc3NcIjtcbiAgICAgICBleHBvcnQgZGVmYXVsdCBjb250ZW50ICYmIGNvbnRlbnQubG9jYWxzID8gY29udGVudC5sb2NhbHMgOiB1bmRlZmluZWQ7XG4iLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vd2VsY29tZS5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcbm9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi93ZWxjb21lLmNzc1wiO1xuICAgICAgIGV4cG9ydCBkZWZhdWx0IGNvbnRlbnQgJiYgY29udGVudC5sb2NhbHMgPyBjb250ZW50LmxvY2FscyA6IHVuZGVmaW5lZDtcbiIsImltcG9ydCAnLi93ZWxjb21lLmNzcyc7XHJcblxyXG4vLyBIaWRlIGFuZCB1bmhpZGUgd2VsY29tZSBidXR0b25zXHJcbmZ1bmN0aW9uIHVuaGlkZVdlbGNvbWVCdXR0b25zKCl7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIndlbGNvbWUtcGFnZVwiKS5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xyXG59XHJcbmZ1bmN0aW9uIGhpZGVXZWxjb21lQnV0dG9ucygpe1xyXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ3ZWxjb21lLXBhZ2VcIikuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgV2VsY29tZSA9IHtcclxuICAgIHNob3c6IHVuaGlkZVdlbGNvbWVCdXR0b25zLFxyXG4gICAgaGlkZSA6IGhpZGVXZWxjb21lQnV0dG9uc1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBXZWxjb21lOyIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9wcm9tcHQuY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vcHJvbXB0LmNzc1wiO1xuICAgICAgIGV4cG9ydCBkZWZhdWx0IGNvbnRlbnQgJiYgY29udGVudC5sb2NhbHMgPyBjb250ZW50LmxvY2FscyA6IHVuZGVmaW5lZDtcbiIsImZ1bmN0aW9uIHNob3dQcm9tcHQoKXtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwicHJvbXB0LWRpdlwiKS5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xyXG59XHJcblxyXG5mdW5jdGlvbiBoaWRlUHJvbXB0KCl7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHJvbXB0LWRpdicpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiB1cGRhdGVQcm9tcHQocHJvbXB0KXtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcm9tcHQnKS50ZXh0Q29udGVudCA9IHByb21wdDtcclxuICAgIHNob3dQcm9tcHQoKTtcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IFRleHQgPSB7XHJcbiAgICBzaG93IDogc2hvd1Byb21wdCxcclxuICAgIGhpZGUgOiBoaWRlUHJvbXB0LFxyXG4gICAgdXBkYXRlIDogZnVuY3Rpb24odGV4dCkgeyB1cGRhdGVQcm9tcHQodGV4dCkgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBUZXh0OyIsImZ1bmN0aW9uIHNob3dQcm9tcHRCdXR0b24oaWQpe1xyXG4gICAgLy8gbWFrZSBidXR0b25zIHZpc2libGVcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZSc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZVByb21wdEJ1dHRvbihpZCwgdGV4dCl7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkudGV4dENvbnRlbnQgPSB0ZXh0O1xyXG4gICAgc2hvd1Byb21wdEJ1dHRvbihpZCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGhpZGVQcm9tcHRCdXR0b24oaWQpe1xyXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVuY2xpY2tBbGwoKXtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvcHRpb24xJykuY2xhc3NMaXN0LnJlbW92ZSgnY2xpY2tlZCcpO1xyXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ29wdGlvbjInKS5jbGFzc0xpc3QucmVtb3ZlKCdjbGlja2VkJyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFwcGx5Q2xpY2tlZFN0eWxlKGJ1dHRvbil7XHJcbiAgICB1bmNsaWNrQWxsKCk7XHJcbiAgICBidXR0b24uY2xhc3NMaXN0LmFkZCgnY2xpY2tlZCcpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRQcm9tcHRCdXR0b25BY3Rpb24oYnV0dG9uX2lkLCBhY3Rpb25fZm4pe1xyXG4gICAgY29uc3QgYnV0dG9uRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGJ1dHRvbl9pZCk7XHJcbiAgICBidXR0b25FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYWN0aW9uX2ZuKTtcclxuICAgIGJ1dHRvbkVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpe1xyXG4gICAgICAgIGFwcGx5Q2xpY2tlZFN0eWxlKHRoaXMpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZVByb21wdEJ1dHRvbkFjdGlvbihidXR0b25faWQsIGFjdGlvbl9mbil7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChidXR0b25faWQpLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYWN0aW9uX2ZuKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZGlzYWJsZShidXR0b25faWQpe1xyXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgIyR7YnV0dG9uX2lkfWApLmNsYXNzTGlzdC5hZGQoJ2Rpc2FibGVkJyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGVuYWJsZShidXR0b25faWQpe1xyXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgIyR7YnV0dG9uX2lkfWApLmNsYXNzTGlzdC5yZW1vdmUoJ2Rpc2FibGVkJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBMZWZ0ID0ge1xyXG4gICAgc2hvdyA6IGZ1bmN0aW9uKCkgeyBzaG93UHJvbXB0QnV0dG9uKCdvcHRpb24xJykgfSxcclxuICAgIGhpZGUgOiBmdW5jdGlvbigpIHsgaGlkZVByb21wdEJ1dHRvbignb3B0aW9uMScpIH0sXHJcbiAgICB1cGRhdGVUZXh0IDogZnVuY3Rpb24odGV4dCkgeyB1cGRhdGVQcm9tcHRCdXR0b24oJ29wdGlvbjEnLCB0ZXh0KSB9LFxyXG4gICAgYWRkQWN0aW9uIDogZnVuY3Rpb24oYWN0aW9uX2ZuKSB7IGFkZFByb21wdEJ1dHRvbkFjdGlvbignb3B0aW9uMScsIGFjdGlvbl9mbikgfSxcclxuICAgIHJlbW92ZUFjdGlvbiA6IGZ1bmN0aW9uKGFjdGlvbl9mbikgeyByZW1vdmVQcm9tcHRCdXR0b25BY3Rpb24oJ29wdGlvbjEnLCBhY3Rpb25fZm4pIH0sXHJcbiAgICBkaXNhYmxlIDogZnVuY3Rpb24oKSB7IGRpc2FibGUoJ29wdGlvbjEnKSB9LFxyXG4gICAgZW5hYmxlIDogZnVuY3Rpb24oKSB7IGVuYWJsZSgnb3B0aW9uMScpIH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IFJpZ2h0ID0ge1xyXG4gICAgc2hvdyA6IGZ1bmN0aW9uKCkgeyBzaG93UHJvbXB0QnV0dG9uKCdvcHRpb24yJykgfSxcclxuICAgIGhpZGUgOiBmdW5jdGlvbigpIHsgaGlkZVByb21wdEJ1dHRvbignb3B0aW9uMicpIH0sXHJcbiAgICB1cGRhdGVUZXh0IDogZnVuY3Rpb24odGV4dCkgeyB1cGRhdGVQcm9tcHRCdXR0b24oJ29wdGlvbjInLCB0ZXh0KSB9LFxyXG4gICAgYWRkQWN0aW9uIDogZnVuY3Rpb24oYWN0aW9uX2ZuKSB7IGFkZFByb21wdEJ1dHRvbkFjdGlvbignb3B0aW9uMicsIGFjdGlvbl9mbikgfSxcclxuICAgIHJlbW92ZUFjdGlvbiA6IGZ1bmN0aW9uKGFjdGlvbl9mbikgeyByZW1vdmVQcm9tcHRCdXR0b25BY3Rpb24oJ29wdGlvbjInLCBhY3Rpb25fZm4pIH0sXHJcbiAgICBkaXNhYmxlIDogZnVuY3Rpb24oKSB7IGRpc2FibGUoJ29wdGlvbjInKSB9LFxyXG4gICAgZW5hYmxlIDogZnVuY3Rpb24oKSB7IGVuYWJsZSgnb3B0aW9uMicpIH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IEJ1dHRvbnMgPSB7XHJcbiAgICBMZWZ0IDogTGVmdCxcclxuICAgIFJpZ2h0IDogUmlnaHQsXHJcbiAgICBzaG93IDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgc2hvd1Byb21wdEJ1dHRvbignb3B0aW9uMScpO1xyXG4gICAgICAgIHNob3dQcm9tcHRCdXR0b24oJ29wdGlvbjInKTtcclxuICAgIH0sXHJcbiAgICBoaWRlIDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgaGlkZVByb21wdEJ1dHRvbignb3B0aW9uMScpO1xyXG4gICAgICAgIGhpZGVQcm9tcHRCdXR0b24oJ29wdGlvbjInKTtcclxuICAgIH0sXHJcbiAgICByZXNldCA6IHVuY2xpY2tBbGxcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgQnV0dG9uczsiLCJpbXBvcnQgJy4vcHJvbXB0LmNzcyc7XHJcblxyXG5pbXBvcnQgVGV4dCBmcm9tIFwiLi9zdWJjb21wb25lbnRzL3RleHQuanNcIjtcclxuaW1wb3J0IEJ1dHRvbnMgZnJvbSBcIi4vc3ViY29tcG9uZW50cy9idXR0b25zLmpzXCI7XHJcblxyXG5leHBvcnQgY29uc3QgUHJvbXB0ID0ge1xyXG4gICAgVGV4dCA6IFRleHQsXHJcbiAgICBCdXR0b25zIDogQnV0dG9ucyxcclxuICAgIGhpZGUgOiBmdW5jdGlvbigpe1xyXG4gICAgICAgIFRleHQuaGlkZSgpO1xyXG4gICAgICAgIEJ1dHRvbnMuaGlkZSgpO1xyXG4gICAgfSxcclxuICAgIHNob3cgOiBmdW5jdGlvbigpe1xyXG4gICAgICAgIFRleHQuc2hvdygpO1xyXG4gICAgICAgIEJ1dHRvbnMuc2hvdygpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBQcm9tcHQiLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vc2lkZWJhci5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcbm9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9zaWRlYmFyLmNzc1wiO1xuICAgICAgIGV4cG9ydCBkZWZhdWx0IGNvbnRlbnQgJiYgY29udGVudC5sb2NhbHMgPyBjb250ZW50LmxvY2FscyA6IHVuZGVmaW5lZDtcbiIsIi8vIFNldCB0byBlcXVhbCBjdXJyZW50IGZpc2NhbCB5ZWFyXHJcbmV4cG9ydCB2YXIgRklTQ0FMX1lFQVIgPSAnMjYnO1xyXG5cclxuLy8gb2JqZWN0IGNhdGVnb3JpZXMgKGZyb20gb2JqIHBhcnQgb2YgYWNjb3VudCBzdHJpbmcpXHJcbmV4cG9ydCBjb25zdCBPQkpfQ0FURUdPUklFUyA9IHtcclxuICAgIGxpc3QgOiBbXHJcbiAgICAgICAgLy8gJ1NhbGFyaWVzICYgV2FnZXMnLFxyXG4gICAgICAgIC8vICdFbXBsb3llZSBCZW5lZml0cycsXHJcbiAgICAgICAgJ1Byb2Zlc3Npb25hbCAmIENvbnRyYWN0dWFsIFNlcnZpY2VzJyxcclxuICAgICAgICAnT3BlcmF0aW5nIFN1cHBsaWVzJyxcclxuICAgICAgICAnT3BlcmF0aW5nIFNlcnZpY2VzJyxcclxuICAgICAgICAnRXF1aXBtZW50IEFjcXVpc2l0aW9uJyxcclxuICAgICAgICAnQ2FwaXRhbCBPdXRsYXlzJyxcclxuICAgICAgICAnRml4ZWQgQ2hhcmdlcycsXHJcbiAgICAgICAgJ090aGVyIEV4cGVuc2VzJ1xyXG4gICAgXVxyXG59XHJcblxyXG4vLyBmcm9tIHRoZSBkcm9wLWRvd24gbWVudVxyXG5leHBvcnQgY29uc3QgRU1QTE9ZRUVfVFlQRVMgPSBbXHJcbiAgICAnUmVndWxhcicsXHJcbiAgICAnVEFTUycsXHJcbiAgICAnU2Vhc29uYWwnLFxyXG4gICAgJ1VuaWZvcm0gRmlyZScsXHJcbiAgICAnVW5pZm9ybSBQb2xpY2UnLFxyXG4gICAgJ0FwcG9pbnRlZCcsXHJcbiAgICAnRWxlY3RlZCcsXHJcbiAgICAnTG9uZyBUZXJtIERpc2FiaWxpdHknXHJcbl1cclxuXHJcbmV4cG9ydCBjb25zdCBPVF9PQkpFQ1RTID0gW1xyXG4gICAgJzYwMTMwMCAtIFNhbGFyLU92ZXJ0aW1lLUdlbiBDaXR5JywgXHJcbiAgICAnNjAxMzA1IC0gU2FsYXJpZXMtT3ZlcnRpbWUtUG9saWNlIFVuaWYnLFxyXG4gICAgJzYwMTMxMCAtIFNhbGFyaWVzLU92ZXJ0aW1lLUZpcmUgVW5pZicsXHJcbiAgICAnNjAyMzAwIC0gV2FnZXMtT3ZlcnRpbWUtR2VuIENpdHknXHJcbl0iLCJpbXBvcnQgeyBGSVNDQUxfWUVBUiB9IGZyb20gXCIuL2J1ZGdldF9jb25zdGFudHNcIjtcclxuXHJcbi8vIHNoZWV0cyB0byBleHBlY3Qgb24gZGV0YWlsIHNoZWV0XHJcbmV4cG9ydCBjb25zdCBTSEVFVFMgPSB7XHJcbiAgICAnRlRFLCBTYWxhcnktV2FnZSwgJiBCZW5lZml0cycgOiAncGVyc29ubmVsJyAsXHJcbiAgICAnT3ZlcnRpbWUgJiBPdGhlciBQZXJzb25uZWwnIDogJ292ZXJ0aW1lJyxcclxuICAgICdOb24tUGVyc29ubmVsJyA6ICdub25wZXJzb25uZWwnLFxyXG4gICAgJ1JldmVudWUnIDogJ3JldmVudWUnXHJcbn1cclxuXHJcbi8vIHdoZXJlIHRvIGZpbmQgdGhlIGdlbmVyYWwgZnVuZCB0YXJnZXRcclxuZXhwb3J0IGNvbnN0IFRBUkdFVF9DRUxMX0FERFJFU1MgPSAnQzE0J1xyXG5cclxuZXhwb3J0IGNvbnN0IFRPVEFMX0NPTFVNTlMgPSB7XHJcbiAgICAncGVyc29ubmVsJzogJ1RvdGFsIFNhbC9XYWcgJiBCZW4gUmVxdWVzdCcsXHJcbiAgICAnb3ZlcnRpbWUnOmBGWSR7RklTQ0FMX1lFQVJ9IFRvdGFsIE9UL1NQL0hvbCArIEZJQ0EgUmVxdWVzdGAsXHJcbiAgICAnbm9ucGVyc29ubmVsJzogYEZZJHtGSVNDQUxfWUVBUn0gRGVwYXJ0bWVudGFsIFJlcXVlc3QgVG90YWxgLFxyXG4gICAgJ3JldmVudWUnOiBgRlkke0ZJU0NBTF9ZRUFSfSBEZXBhcnRtZW50YWwgRXN0aW1hdGVgXHJcbn07XHJcbiIsImV4cG9ydCAqIGZyb20gJy4vYnVkZ2V0X2NvbnN0YW50cyc7XHJcbmV4cG9ydCAqIGZyb20gJy4vZXhjZWxfY29uc3RhbnRzJzsiLCIvLyBGdW5jdGlvbiB0byBmb3JtYXQgbnVtYmVyIGFzIGN1cnJlbmN5XHJcbmV4cG9ydCBjb25zdCBmb3JtYXRDdXJyZW5jeSA9IChhbW91bnQsIHJldHVybl96ZXJvID0gZmFsc2UpID0+IHtcclxuICAgIHZhciBhbW91bnQgPSBNYXRoLnJvdW5kKHBhcnNlRmxvYXQoYW1vdW50KSk7XHJcbiAgICBpZiAoYW1vdW50ID09IE5hTil7XHJcbiAgICAgICAgcmV0dXJuIFwiJCAtXCJcclxuICAgIH1cclxuICAgIGlmIChhbW91bnQgPCAwKXtcclxuICAgICAgICByZXR1cm4gJygkJyArIGFtb3VudC50b1N0cmluZygpLnJlcGxhY2UoL1xcQig/PShcXGR7M30pKyg/IVxcZCkpL2csICcsJykgKyAnKSc7XHJcbiAgICB9IGVsc2UgaWYgKGFtb3VudCA9PSAwKSB7XHJcbiAgICAgICAgaWYgKHJldHVybl96ZXJvKXtcclxuICAgICAgICAgICAgcmV0dXJuICckMCc7ICAgIFxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gXCIkIC1cIlxyXG4gICAgfVxyXG4gICAgcmV0dXJuICckJyArIGFtb3VudC50b1N0cmluZygpLnJlcGxhY2UoL1xcQig/PShcXGR7M30pKyg/IVxcZCkpL2csICcsJyk7XHJcbn0gO1xyXG5cclxuLy8gZnVuY3Rpb24gdG8gY29udmVydCBmb3JtYXR0ZWQgbnVtYmVyIHRvIGEgZmxvYXRcclxuZXhwb3J0IGNvbnN0IHVuZm9ybWF0Q3VycmVuY3kgPSAoZm9ybWF0dGVkQW1vdW50KSA9PiB7XHJcbiAgICBpZiAoIWZvcm1hdHRlZEFtb3VudCkgeyByZXR1cm4gMCB9O1xyXG4gICAgLy8gUmVtb3ZlIGFueSBjdXJyZW5jeSBzeW1ib2xzIGFuZCBjb21tYXNcclxuICAgIGxldCBudW1lcmljYWxQYXJ0ID0gZm9ybWF0dGVkQW1vdW50LnJlcGxhY2UoL1teMC05Li1dKy9nLCBcIlwiKTtcclxuICAgIGlmIChudW1lcmljYWxQYXJ0ID09ICctJyl7XHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcGFyc2VGbG9hdChudW1lcmljYWxQYXJ0KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBkaXNwbGF5V2l0aENvbW1hcyh2YWx1ZSkge1xyXG4gICAgaWYgKHZhbHVlID09IDApe1xyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZvcm1hdEN1cnJlbmN5KHZhbHVlKS5yZXBsYWNlKCckJywgJycpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY2xlYW5TdHJpbmcoc3RyKXtcclxuICAgIHJldHVybiBzdHIudG9Mb3dlckNhc2UoKS5yZXBsYWNlQWxsKCcgJywgJy0nKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZU5ld0xpbmVzKHN0cil7XHJcbiAgICAvLyByZXBsYWNlIGFsbCBuZXcgbGluZXMgd2l0aCBzcGFjZXNcclxuICAgIHN0ciA9IHN0ci5yZXBsYWNlQWxsKC9bXFxyXFxuXSsvZywgXCIgXCIpO1xyXG4gICAgLy8gcmVtb3ZlIGFueSBleHRyYSBzcGFjZXMgb3IgdHJhaWxpbmcvbGVhZGluZyB3aGl0ZXNwYWNlXHJcbiAgICBzdHIgPSBzdHIucmVwbGFjZUFsbCgnICAnLCAnICcpO1xyXG4gICAgc3RyID0gc3RyLnJlcGxhY2VBbGwoJyAgJywgJyAnKTtcclxuICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJyk7XHJcbiAgICByZXR1cm4gc3RyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY29sU3VtKHRhYmxlLCBjb2xOYW1lKSB7XHJcbiAgICAvLyBmaWxsIHdpdGggemVybyB1bnRpbCB0aGVyZSBpcyBzb21ldGhpbmcgc2F2ZWQgaW4gc3RvcmFnZVxyXG4gICAgaWYoIXRhYmxlIHx8IHRhYmxlID09ICcnKXsgXHJcbiAgICAgICAgcmV0dXJuIDA7IFxyXG4gICAgfVxyXG4gICAgY29uc3QgaGVhZGVycyA9IE9iamVjdC5rZXlzKHRhYmxlWzBdKTtcclxuICAgIGlmIChoZWFkZXJzLmluY2x1ZGVzKGNvbE5hbWUpKSB7XHJcbiAgICAgICAgbGV0IHN1bSA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YWJsZS5sZW5ndGg7IGkrKyl7XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IE1hdGgucm91bmQocGFyc2VGbG9hdCh0YWJsZVtpXVtjb2xOYW1lXSkpO1xyXG4gICAgICAgICAgICAvLyB0cmVhdCBOYU4gKG5vbi1udW1lcmljcykgYXMgemVyb2VzXHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSkgeyBzdW0gKz0gdmFsdWU7IH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHN1bTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gY29uc29sZS5lcnJvcihgQ291bGQgbm90IGZpbmQgZXhwZWN0ZWQgdG90YWwgY29sdW1uIGluIHNhdmVkIGRhdGEgZm9yICR7bmFtZX0uIFJldHVybmluZyAwLiBTZWUgU3RvcmVkVGFibGUudG90YWxDb2woKSBzd2l0Y2guYCk7XHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0VW5pcXVlVmFsdWVzKGRhdGEsIGtleSkge1xyXG4gICAgY29uc3QgdmFsdWVzID0gZGF0YS5tYXAob2JqID0+IG9ialtrZXldKTtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQodmFsdWVzKSk7XHJcbn1cclxuIiwiaW1wb3J0IEN1cnJlbnRGdW5kIGZyb20gXCIuL2N1cnJlbnRfZnVuZC5qc1wiO1xyXG5pbXBvcnQgeyBnZXRVbmlxdWVWYWx1ZXMgfSBmcm9tIFwiLi4vdXRpbHMvY29tbW9uX3V0aWxzLmpzXCI7XHJcblxyXG5leHBvcnQgY29uc3QgRnVuZExvb2t1cFRhYmxlID0ge1xyXG4gICAgcmV0cmlldmUgOiBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZnVuZC1sb29rdXAtdGFibGUnKSkgfHwge307XHJcbiAgICB9LFxyXG4gICAgc2F2ZSA6IGZ1bmN0aW9uKGZ1bmREaWN0KXtcclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnZnVuZC1sb29rdXAtdGFibGUnLCBKU09OLnN0cmluZ2lmeShmdW5kRGljdCkpO1xyXG4gICAgfSxcclxuXHJcbiAgICB1cGRhdGUgOiBmdW5jdGlvbihmdW5kRGF0YSl7XHJcbiAgICAgICAgY29uc3QgdGFibGUgPSB0aGlzLnJldHJpZXZlKCk7XHJcblxyXG4gICAgICAgIGZvciAobGV0IGZ1bmQgb2YgT2JqZWN0LmtleXMoZnVuZERhdGEpKXtcclxuXHJcbiAgICAgICAgICAgIC8vIGFkZCB0byBsb29rdXAgdGFibGUgaWYgbm90IGluIHRoZXJlIGFscmVhZHlcclxuICAgICAgICAgICAgaWYgKCF0YWJsZVtmdW5kXSl7XHJcbiAgICAgICAgICAgICAgICAvLyBnZXQgZnVuZCBuYW1lXHJcbiAgICAgICAgICAgICAgICBjb25zdCBmdW5kTmFtZSA9IGZ1bmREYXRhW2Z1bmRdWzBdWydGdW5kIE5hbWUnXTtcclxuICAgICAgICAgICAgICAgIC8vIGFkZCBmdW5kIHRvIGRpY3Rpb25hcnlcclxuICAgICAgICAgICAgICAgIHRhYmxlW2Z1bmRdID0ge307XHJcbiAgICAgICAgICAgICAgICB0YWJsZVtmdW5kXVsnbmFtZSddID0gZnVuZE5hbWU7XHJcbiAgICAgICAgICAgICAgICB0YWJsZVtmdW5kXVsndmlld2VkJ10gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIC8vIGJ1aWxkIGxpc3RzIG9mIHVuaXF1ZSBjb3N0IGNlbnRlcnMgYW5kIGFwcHJvcHJpYXRpb25zXHJcbiAgICAgICAgICAgICAgICB0YWJsZVtmdW5kXVsnYXBwcm9wJ10gPSBnZXRVbmlxdWVWYWx1ZXMoZnVuZERhdGFbZnVuZF0sICdBcHByb3ByaWF0aW9uIE5hbWUnKTtcclxuICAgICAgICAgICAgICAgIHRhYmxlW2Z1bmRdWydjYyddID0gZ2V0VW5pcXVlVmFsdWVzKGZ1bmREYXRhW2Z1bmRdLCAnQ29zdCBDZW50ZXIgTmFtZScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNhdmUgYW55IHVwZGF0ZXNcclxuICAgICAgICB0aGlzLnNhdmUodGFibGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBnZXRBbGw6IGZ1bmN0aW9uKGtleSkge1xyXG4gICAgICAgIC8vIGZ1bmN0aW9uIHRvIGFnZ3JlZ2F0ZSBhbGwgYXBwcm9wcyBvciBDQ3MgZm9yIGV2ZXJ5IGZ1bmQgaW4gb25lIGFycmF5XHJcbiAgICAgICAgY29uc3QgZnVuZHMgPSB0aGlzLnJldHJpZXZlKCk7XHJcbiAgICAgICAgY29uc3QgcmV0ID0gW107XHJcbiAgICAgICAgZm9yIChjb25zdCBmdW5kIGluIGZ1bmRzKSB7XHJcbiAgICAgICAgICAgIGlmIChmdW5kcy5oYXNPd25Qcm9wZXJ0eShmdW5kKSkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSBpbiBmdW5kc1tmdW5kXVtrZXldKXtcclxuICAgICAgICAgICAgICAgICAgICByZXQucHVzaChmdW5kc1tmdW5kXVtrZXldW2ldKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmV0O1xyXG4gICAgfSxcclxuXHJcbiAgICBnZXRDb3N0Q2VudGVycyA6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIC8vIGdldCBjdXJyZW50IGZ1bmRcclxuICAgICAgICBjb25zdCBmdW5kID0gQ3VycmVudEZ1bmQubnVtYmVyKClcclxuICAgICAgICBpZiAodGhpcy5yZXRyaWV2ZSgpW2Z1bmRdKXtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmV0cmlldmUoKVtmdW5kXVsnY2MnXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gaWYgbm8gZnVuZCAoaWUuIHdlJ3JlIG9uIHRoZSBuZXcgaW5pdGlhdGl2ZSBwYWdlKSwgcmV0dXJuIGFsbCBvcHRpb25zXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QWxsKCdjYycpO1xyXG4gICAgfSxcclxuXHJcbiAgICBnZXRBcHByb3BzIDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgLy8gZ2V0IGN1cnJlbnQgZnVuZFxyXG4gICAgICAgIGNvbnN0IGZ1bmQgPSBDdXJyZW50RnVuZC5udW1iZXIoKVxyXG4gICAgICAgIGlmICh0aGlzLnJldHJpZXZlKClbZnVuZF0pe1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZXRyaWV2ZSgpW2Z1bmRdWydhcHByb3AnXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gaWYgbm8gZnVuZCAoaWUuIHdlJ3JlIG9uIHRoZSBuZXcgaW5pdGlhdGl2ZSBwYWdlKSwgcmV0dXJuIGFsbCBvcHRpb25zXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QWxsKCdhcHByb3AnKTtcclxuICAgIH0sXHJcblxyXG4gICAgcmVzZXQgOiBmdW5jdGlvbigpIHtcclxuICAgICAgICB0aGlzLnNhdmUoe30pO1xyXG4gICAgfSxcclxuICAgIGdldE5hbWUgOiBmdW5jdGlvbihudW1iZXIpe1xyXG4gICAgICAgIGlmKCFudW1iZXIgfHwgIXRoaXMucmV0cmlldmUoKSkgeyByZXR1cm4gJycgfTtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXRyaWV2ZSgpW251bWJlcl1bJ25hbWUnXTtcclxuICAgIH0sXHJcbiAgICBsaXN0RnVuZHMgOiBmdW5jdGlvbigpe1xyXG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnJldHJpZXZlKCkpO1xyXG4gICAgfSxcclxuICAgIGxpc3RGdW5kTmFtZXMgOiBmdW5jdGlvbigpe1xyXG4gICAgICAgIGNvbnN0IGZ1bmRzID0gdGhpcy5yZXRyaWV2ZSgpO1xyXG4gICAgICAgIC8vIGluaXRpYWxpemUgYXJyYXlcclxuICAgICAgICB2YXIgcmV0ID0gW107XHJcbiAgICAgICAgT2JqZWN0LmtleXMoZnVuZHMpLmZvckVhY2goIChmdW5kX251bWJlcikgPT4ge1xyXG4gICAgICAgICAgICB2YXIgZnVuZF9uYW1lID0gZnVuZHNbZnVuZF9udW1iZXJdWyduYW1lJ107XHJcbiAgICAgICAgICAgIHJldC5wdXNoKGZ1bmRfbmFtZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHJldDtcclxuICAgIH0sXHJcbiAgICBlZGl0RnVuZCA6IGZ1bmN0aW9uKGZ1bmQpe1xyXG4gICAgICAgIGNvbnN0IHRhYmxlID0gdGhpcy5yZXRyaWV2ZSgpO1xyXG4gICAgICAgIGlmICh0YWJsZVtmdW5kXSl7XHJcbiAgICAgICAgICAgIHRhYmxlW2Z1bmRdWyd2aWV3ZWQnXSA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuc2F2ZSh0YWJsZSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignTm8gZnVuZCBzZWxlY3RlZC4nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICB9LFxyXG4gICAgbGlzdFVuZWRpdGVkRnVuZHMgOiBmdW5jdGlvbigpe1xyXG4gICAgICAgIGNvbnN0IHRhYmxlID0gdGhpcy5yZXRyaWV2ZSgpO1xyXG4gICAgICAgIGNvbnN0IHJldCA9IFtdO1xyXG4gICAgICAgIHRoaXMubGlzdEZ1bmRzKCkuZm9yRWFjaChrZXkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIXRhYmxlW2tleV1bJ3ZpZXdlZCddKXtcclxuICAgICAgICAgICAgICAgIHJldC5wdXNoKGtleSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gcmV0O1xyXG4gICAgfSxcclxuICAgIGZ1bmRzTGVmdCA6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmxpc3RVbmVkaXRlZEZ1bmRzKCkubGVuZ3RoID4gMCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEZ1bmRMb29rdXBUYWJsZSIsIlxyXG5pbXBvcnQgRnVuZExvb2t1cFRhYmxlIGZyb20gXCIuL2Z1bmRfbG9va3VwX3RhYmxlXCI7XHJcblxyXG5leHBvcnQgY29uc3QgQ3VycmVudEZ1bmQgPSB7XHJcbiAgICB1cGRhdGUgOiBmdW5jdGlvbihmdW5kKXtcclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnZnVuZCcsIGZ1bmQpO1xyXG4gICAgfSxcclxuICAgIG51bWJlciA6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgcmV0dXJuIGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwiZnVuZFwiKTtcclxuICAgIH0sXHJcbiAgICBuYW1lIDogZnVuY3Rpb24oKXtcclxuICAgICAgICByZXR1cm4gRnVuZExvb2t1cFRhYmxlLmdldE5hbWUoIHRoaXMubnVtYmVyKCkpO1xyXG4gICAgfSxcclxuICAgIHJlc2V0IDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGUoJycpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBDdXJyZW50RnVuZDsiLCJpbXBvcnQgQ3VycmVudEZ1bmQgZnJvbSBcIi4vY3VycmVudF9mdW5kXCI7XHJcblxyXG5leHBvcnQgY29uc3QgQWNjb3VudFN0cmluZyA9IHtcclxuICAgIGdldE51bWJlcjogZnVuY3Rpb24oaW5wdXQpIHtcclxuICAgICAgICAvLyBpc29sYXRlIHRoZSBudW1lcmljYWwgcGFydCBvZiBhIGFwcHJvcHJpYXRpb24vY29zdCBjZW50ZXIvb2JqZWN0XHJcbiAgICAgICAgY29uc3QgbWF0Y2ggPSBpbnB1dC5tYXRjaCgvXlxcZCsvKTtcclxuICAgICAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFswXSA6IG51bGw7XHJcbiAgICB9LFxyXG5cclxuICAgIGJ1aWxkIDogZnVuY3Rpb24oYXBwcm9wLCBjYywgb2JqID0gbnVsbCwgZnVuZCA9IG51bGwpIHtcclxuICAgICAgICAvLyBwdXQgdG9nZXRoZXIgYWNjb3VudCBzdHJpbmcgZnVuZC1hcHByb3AtY29zdGNlbnRlclstb2JqXSAodyBvcHRpb25hbCBvYmplY3QpXHJcbiAgICAgICAgaWYgKCFmdW5kKSB7IGZ1bmQgPSBDdXJyZW50RnVuZC5udW1iZXIoKSB9O1xyXG4gICAgICAgIC8vIGhpdHMgZXJyb3IgaGVyZVxyXG4gICAgICAgIGFwcHJvcCA9IHRoaXMuZ2V0TnVtYmVyKGFwcHJvcCk7XHJcbiAgICAgICAgY2MgPSB0aGlzLmdldE51bWJlcihjYyk7XHJcbiAgICAgICAgdmFyIHN0cmluZyA9IGAke2Z1bmR9LSR7YXBwcm9wfS0ke2NjfWA7XHJcbiAgICAgICAgc3RyaW5nID0gb2JqID8gYCR7c3RyaW5nfS0ke3RoaXMuZ2V0TnVtYmVyKG9iail9YCA6IHN0cmluZztcclxuICAgICAgICByZXR1cm4gc3RyaW5nO1xyXG4gICAgfSxcclxuXHJcbiAgICBnZXRBY2NvdW50U3RyaW5nU2VjdGlvbiA6IGZ1bmN0aW9uKGFjY291bnRfc3RyaW5nLCBzZWN0aW9uKSB7XHJcbiAgICAgICAgY29uc3Qgc2VjdGlvbnMgPSBhY2NvdW50X3N0cmluZy5zcGxpdChcIi1cIik7XHJcbiAgICAgICAgcmV0dXJuIHNlY3Rpb25zLmxlbmd0aCA+IHNlY3Rpb24gPyBzZWN0aW9uc1tzZWN0aW9uXSA6IG51bGw7XHJcbiAgICB9LFxyXG5cclxuICAgIGZ1bmQgOiBmdW5jdGlvbihhY2NvdW50X3N0cmluZykgeyBcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRBY2NvdW50U3RyaW5nU2VjdGlvbihhY2NvdW50X3N0cmluZywgMCkgXHJcbiAgICB9LFxyXG5cclxuICAgIGFwcHJvcCA6IGZ1bmN0aW9uKGFjY291bnRfc3RyaW5nKSB7IFxyXG4gICAgICAgIHJldHVybiB0aGlzLmdldEFjY291bnRTdHJpbmdTZWN0aW9uKGFjY291bnRfc3RyaW5nLCAxKSBcclxuICAgIH0sXHJcblxyXG4gICAgY29zdENlbnRlciA6IGZ1bmN0aW9uKGFjY291bnRfc3RyaW5nKSB7IFxyXG4gICAgICAgIHJldHVybiB0aGlzLmdldEFjY291bnRTdHJpbmdTZWN0aW9uKGFjY291bnRfc3RyaW5nLCAyKSBcclxuICAgIH0sXHJcblxyXG4gICAgb2JqZWN0IDogZnVuY3Rpb24oYWNjb3VudF9zdHJpbmcpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRBY2NvdW50U3RyaW5nU2VjdGlvbihhY2NvdW50X3N0cmluZywgMykgXHJcbiAgICB9LFxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBBY2NvdW50U3RyaW5nOyIsIlxyXG5pbXBvcnQgeyBjb2xTdW0gfSBmcm9tIFwiLi4vdXRpbHMvY29tbW9uX3V0aWxzXCI7XHJcbmltcG9ydCB7IFRPVEFMX0NPTFVNTlMgfSBmcm9tICcuLi9jb25zdGFudHMvJztcclxuXHJcbi8vIENsYXNzIHRvIGhvbGQgaW5mb3JtYXRpb24gb24gYSBzcGVjaWZpYyBmdW5kIGFuZCB0YWJsZVxyXG5jbGFzcyBTdG9yZWRUYWJsZSB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYWdlLCBmdW5kKXtcclxuICAgICAgICB0aGlzLm5hbWUgPSBgJHtwYWdlfV8ke2Z1bmR9YDtcclxuICAgICAgICB0aGlzLnBhZ2UgPSBwYWdlO1xyXG4gICAgICAgIHRoaXMudGFibGUgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMubmFtZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHRvdGFsQ29sKCkge1xyXG4gICAgICAgIHJldHVybiBUT1RBTF9DT0xVTU5TW3RoaXMucGFnZV07XHJcbiAgICB9XHJcbiAgICBnZXRTdW0oKSB7XHJcbiAgICAgICAgLy8gZmlsbCB3aXRoIHplcm8gdW50aWwgdGhlcmUgaXMgc29tZXRoaW5nIHNhdmVkIGluIHN0b3JhZ2VcclxuICAgICAgICByZXR1cm4gY29sU3VtKHRoaXMudGFibGUsIHRoaXMudG90YWxDb2woKSwgdGhpcy5uYW1lKTtcclxuICAgIH1cclxuXHJcbn1cclxuXHJcbi8vIEhvbGRzIGFsbCB0aGUgZGV0YWlsZWQgZGF0YSBmb3Igb25lIGZ1bmQncyBidWRnZXRcclxuZXhwb3J0IGNsYXNzIEZ1bmQge1xyXG4gICAgY29uc3RydWN0b3IoZnVuZCl7XHJcbiAgICAgICAgdGhpcy5mdW5kID0gZnVuZDtcclxuICAgICAgICB0aGlzLnBlcnNvbm5lbCA9IG5ldyBTdG9yZWRUYWJsZSgncGVyc29ubmVsJywgZnVuZCk7XHJcbiAgICAgICAgdGhpcy5vdmVydGltZSA9IG5ldyBTdG9yZWRUYWJsZSgnb3ZlcnRpbWUnLCBmdW5kKTtcclxuICAgICAgICB0aGlzLm5vbnBlcnNvbm5lbCA9IG5ldyBTdG9yZWRUYWJsZSgnbm9ucGVyc29ubmVsJywgZnVuZCk7XHJcbiAgICAgICAgdGhpcy5yZXZlbnVlID0gbmV3IFN0b3JlZFRhYmxlKCdyZXZlbnVlJywgZnVuZCk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0UGVyc29ubmVsQ29zdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wZXJzb25uZWwuZ2V0U3VtKCkgKyB0aGlzLm92ZXJ0aW1lLmdldFN1bSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldE5vblBlcnNvbm5lbENvc3QoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubm9ucGVyc29ubmVsLmdldFN1bSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFJldmVudWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmV2ZW51ZS5nZXRTdW0oKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRUb3RhbCgpIHsgXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Tm9uUGVyc29ubmVsQ29zdCgpICsgdGhpcy5nZXRQZXJzb25uZWxDb3N0KCkgLSB0aGlzLmdldFJldmVudWUoKSBcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgRnVuZDsiLCJpbXBvcnQgRnVuZCBmcm9tIFwiLi9mdW5kLmpzXCI7XHJcbmltcG9ydCBGdW5kTG9va3VwVGFibGUgZnJvbSBcIi4vZnVuZF9sb29rdXBfdGFibGUuanNcIjtcclxuXHJcblxyXG5leHBvcnQgY2xhc3MgQmFzZWxpbmUge1xyXG4gICAgLy8gYmFzZWxpbmUgd2lsbCBqdXN0IGNvbnRhaW4gYSBsaXN0IG9mIGZ1bmRzLCBlYWNoIHdpdGhcclxuICAgIC8vIHJ1bm5pbmcgdGFsbGllcyBmb3IgdGhlaXIgYnVkZ2V0c1xyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgY29uc3QgYWxsRnVuZHMgPSBGdW5kTG9va3VwVGFibGUubGlzdEZ1bmRzKCk7XHJcbiAgICAgICAgdGhpcy5mdW5kcyA9IFtdO1xyXG4gICAgICAgIGFsbEZ1bmRzLmZvckVhY2goKGZ1bmQpID0+IHsgXHJcbiAgICAgICAgICAgIHRoaXMuZnVuZHMucHVzaChuZXcgRnVuZChmdW5kKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9IFxyXG5cclxuICAgIHN0YXRpYyB0YXJnZXQoKSB7IHJldHVybiBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgndGFyZ2V0JykgfTtcclxuXHJcbiAgICBwZXJzb25uZWwoKSB7XHJcbiAgICAgICAgbGV0IHRvdGFsID0gMDtcclxuICAgICAgICB0aGlzLmZ1bmRzLmZvckVhY2goZnVuZCA9PiB7XHJcbiAgICAgICAgICAgIHRvdGFsICs9IGZ1bmQuZ2V0UGVyc29ubmVsQ29zdCgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0b3RhbDtcclxuICAgIH1cclxuXHJcbiAgICBub25wZXJzb25uZWwoKSB7XHJcbiAgICAgICAgbGV0IHRvdGFsID0gMDtcclxuICAgICAgICB0aGlzLmZ1bmRzLmZvckVhY2goZnVuZCA9PiB7XHJcbiAgICAgICAgICAgIHRvdGFsICs9IGZ1bmQuZ2V0Tm9uUGVyc29ubmVsQ29zdCgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0b3RhbDtcclxuICAgIH1cclxuXHJcbiAgICByZXZlbnVlKCkge1xyXG4gICAgICAgIGxldCB0b3RhbCA9IDA7XHJcbiAgICAgICAgdGhpcy5mdW5kcy5mb3JFYWNoKGZ1bmQgPT4ge1xyXG4gICAgICAgICAgICB0b3RhbCArPSBmdW5kLmdldFJldmVudWUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdG90YWw7XHJcbiAgICB9XHJcblxyXG4gICAgdG90YWwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubm9ucGVyc29ubmVsKCkgKyB0aGlzLnBlcnNvbm5lbCgpIC0gdGhpcy5yZXZlbnVlKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEJhc2VsaW5lOyIsIi8vIGRhdGEgc3RydWN0dXJlIHRvIHNhdmUgdGhlIHBvc3NpYmxlIHNlcnZpY2Ugb3B0aW9ucyBmb3IgdGhlIGRlcGFydG1lbnRcclxuZXhwb3J0IGNvbnN0IFNlcnZpY2VzID0ge1xyXG4gICAgc2F2ZSA6IGZ1bmN0aW9uKHNlcnZpY2VzKXtcclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnc2VydmljZXMtbGlzdCcsIEpTT04uc3RyaW5naWZ5KHNlcnZpY2VzKSk7XHJcbiAgICB9LFxyXG4gICAgbGlzdCA6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3NlcnZpY2VzLWxpc3QnKSkgfHwge307XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFNlcnZpY2VzOyIsIlxyXG4vLyBkYXRhIHN0cnVjdHVyZSB0byBob2xkIGluZm9ybWF0aW9uIG9uIG5ldyBpbml0aWF0aXZlc1xyXG5cclxuZXhwb3J0IGNsYXNzIEluaXRpYXRpdmUge1xyXG4gICAgXHJcbiAgICBjb25zdHJ1Y3Rvcihyb3cpIHtcclxuICAgICAgICB0aGlzLmRhdGEgPSByb3c7XHJcbiAgICAgICAgdGhpcy5uYW1lID0gcm93WydJbml0aWF0aXZlIE5hbWUnXTtcclxuICAgIH1cclxuXHJcbiAgICBleHBlbnNlcygpIHsgXHJcbiAgICAgICAgaWYgKHRoaXMuZGF0YVsnQmFsbHBhcmsgVG90YWwgRXhwZW5zZXMnXSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXRhWydCYWxscGFyayBUb3RhbCBFeHBlbnNlcyddO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXZlbnVlKCkgeyBcclxuICAgICAgICBpZiAodGhpcy5kYXRhWydSZXZlbnVlJ10pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YVsnUmV2ZW51ZSddO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBuZXQoKSB7IHJldHVybiB0aGlzLmV4cGVuc2VzKCkgLSB0aGlzLnJldmVudWUoKSB9XHJcblxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBJbml0aWF0aXZlOyIsIlxyXG5pbXBvcnQgSW5pdGlhdGl2ZSBmcm9tIFwiLi9pbml0aWF0aXZlLmpzXCI7XHJcbmltcG9ydCB7IGNvbFN1bSwgZm9ybWF0Q3VycmVuY3kgfSBmcm9tIFwiLi4vdXRpbHMvY29tbW9uX3V0aWxzLmpzXCI7XHJcblxyXG4vLyBkYXRhIHN0cnVjdHVyZSB0byBob2xkIHN1cHBsZW1lbnRhbCByZXF1ZXN0c1xyXG5leHBvcnQgY2xhc3MgU3VwcGxlbWVudGFsIHtcclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHRoaXMudGFibGUgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMubmFtZSkpO1xyXG4gICAgICAgIHRoaXMuaW5pdGlhdGl2ZXMgPSBbXTtcclxuICAgICAgICBpZih0aGlzLnRhYmxlKXtcclxuICAgICAgICAgICAgdGhpcy50YWJsZS5mb3JFYWNoKChyb3cpID0+IHsgXHJcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRpYXRpdmVzLnB1c2gobmV3IEluaXRpYXRpdmUocm93KSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXRJbml0cygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy50YWJsZS5tYXAoKGl0ZW0pID0+IHsgcmV0dXJuIGl0ZW1bJ0luaXRpYXRpdmUgTmFtZSddIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGV4cGVuc2VzKCkge1xyXG4gICAgICAgIHJldHVybiBjb2xTdW0odGhpcy50YWJsZSwgJ0JhbGxwYXJrIFRvdGFsIEV4cGVuc2VzJyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV2ZW51ZSgpIHtcclxuICAgICAgICByZXR1cm4gY29sU3VtKHRoaXMudGFibGUsICdSZXZlbnVlJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdG90YWwoKXtcclxuICAgICAgICByZXR1cm4gdGhpcy5leHBlbnNlcygpIC0gdGhpcy5yZXZlbnVlKCk7XHJcbiAgICB9XHJcblxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBTdXBwbGVtZW50YWw7IiwiLy8gbW9kZWxzL2luZGV4LmpzXHJcblxyXG5leHBvcnQgeyBkZWZhdWx0IGFzIEFjY291bnRTdHJpbmcgfSBmcm9tICcuL2FjY291bnRfc3RyaW5nLmpzJztcclxuZXhwb3J0IHsgZGVmYXVsdCBhcyBCYXNlbGluZSB9IGZyb20gJy4vYmFzZWxpbmUuanMnO1xyXG5leHBvcnQgeyBkZWZhdWx0IGFzIEN1cnJlbnRGdW5kIH0gZnJvbSAnLi9jdXJyZW50X2Z1bmQuanMnO1xyXG5leHBvcnQgeyBkZWZhdWx0IGFzIEN1cnJlbnRQYWdlIH0gZnJvbSAnLi9jdXJyZW50X3BhZ2UuanMnO1xyXG5leHBvcnQgeyBkZWZhdWx0IGFzIEZ1bmQgfSBmcm9tICcuL2Z1bmQuanMnO1xyXG5leHBvcnQgeyBkZWZhdWx0IGFzIEZ1bmRMb29rdXBUYWJsZSB9IGZyb20gJy4vZnVuZF9sb29rdXBfdGFibGUuanMnO1xyXG5leHBvcnQgeyBkZWZhdWx0IGFzIEluaXRpYXRpdmUgfSBmcm9tICcuL2luaXRpYXRpdmUuanMnO1xyXG5leHBvcnQgeyBkZWZhdWx0IGFzIFNlcnZpY2VzIH0gZnJvbSAnLi9zZXJ2aWNlcy5qcyc7XHJcbmV4cG9ydCB7IGRlZmF1bHQgYXMgU3VwcGxlbWVudGFsIH0gZnJvbSAnLi9zdXBwbGVtZW50YWwuanMnO1xyXG4iLCJpbXBvcnQgeyBGSVNDQUxfWUVBUiB9IGZyb20gXCIuLi8uLi8uLi9jb25zdGFudHNcIjtcclxuaW1wb3J0IHsgQmFzZWxpbmUsIEZ1bmRMb29rdXBUYWJsZSwgRnVuZCwgQ3VycmVudEZ1bmQgfSBmcm9tIFwiLi4vLi4vLi4vbW9kZWxzXCI7XHJcbmltcG9ydCB7IGZvcm1hdEN1cnJlbmN5IH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL2NvbW1vbl91dGlsc1wiO1xyXG5pbXBvcnQgeyB2aXNpdFBhZ2UgfSBmcm9tIFwiLi4vLi4vLi4vdmlld3Mvdmlld19sb2dpY1wiO1xyXG5cclxuZXhwb3J0IGNvbnN0IEJhc2VsaW5lU2VjdGlvbiA9IHtcclxuICAgIF9kYXRhOiBuZXcgQmFzZWxpbmUoKSxcclxuICAgIF9nZW5GdW5kIDogbmV3IEZ1bmQoMTAwMCksXHJcblxyXG4gICAgZ2V0IGRhdGEoKSB7XHJcbiAgICAgICAgdGhpcy5fZGF0YSA9IG5ldyBCYXNlbGluZSgpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9kYXRhO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQgZGF0YShuZXdEYXRhKSB7XHJcbiAgICAgICAgdGhpcy5fZGF0YSA9IG5ld0RhdGE7XHJcbiAgICB9LFxyXG5cclxuICAgIGdldCBnZW5GdW5kKCkge1xyXG4gICAgICAgIHRoaXMuX2dlbkZ1bmQgPSBuZXcgRnVuZCgxMDAwKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2VuRnVuZDtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0IGdlbkZ1bmQobmV3RnVuZCkge1xyXG4gICAgICAgIHRoaXMuX2dlbkZ1bmQgPSBuZXdGdW5kO1xyXG4gICAgfSxcclxuXHJcbiAgICB0YXJnZXRfaHRtbCgpIHtcclxuICAgICAgICByZXR1cm4gYFxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPSdzaWRlYmFyLXN0YXQtbGluZScgaWQ9XCJiYXNlbGluZS10b3RhbFwiPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0LWxhYmVsXCI+QmFzZWxpbmUgdG90YWw6PC9zcGFuPiBcclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdFwiPiR7Zm9ybWF0Q3VycmVuY3kodGhpcy5kYXRhLnRvdGFsKCkpfTwvc3Bhbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9J3NpZGViYXItc3RhdC1saW5lJyBpZD1cInRhcmdldFwiPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0LWxhYmVsXCI+Rlkke0ZJU0NBTF9ZRUFSfSBHRiB0YXJnZXQ6PC9zcGFuPiBcclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdFwiPiR7Zm9ybWF0Q3VycmVuY3koQmFzZWxpbmUudGFyZ2V0KCkpfTwvc3Bhbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9J3NpZGViYXItc3RhdC1saW5lJyBpZD1cIkdGLXRvdGFsXCI+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXQtbGFiZWxcIj5DdXJyZW50IEdGIHRvdGFsOjwvc3Bhbj4gXHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXRcIj4ke2Zvcm1hdEN1cnJlbmN5KHRoaXMuZ2VuRnVuZC5nZXRUb3RhbCgpKX08L3NwYW4+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8YnI+YDtcclxuICAgIH0sXHJcbiAgICBcclxuICAgIGZ1bmRfaHRtbChmdW5kKSB7XHJcbiAgICAgICAgcmV0dXJuIGBcclxuICAgICAgICAgICAgPGg2PiR7RnVuZExvb2t1cFRhYmxlLmdldE5hbWUoZnVuZC5mdW5kKX08L2g2PlxyXG4gICAgICAgICAgICA8aHI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9J3NpZGViYXItc3RhdC1saW5lIHJldmVudWUnPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0LWxhYmVsXCI+UHJvamVjdGVkIHJldmVudWVzOjwvc3Bhbj4gXHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXRcIj4ke2Zvcm1hdEN1cnJlbmN5KGZ1bmQuZ2V0UmV2ZW51ZSgpKX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1lZGl0IGVkaXQtaWNvblwiIHRpdGxlPVwiRWRpdFwiPjwvaT5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9J3NpZGViYXItc3RhdC1saW5lIHBlcnNvbm5lbCc+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXQtbGFiZWxcIj5QZXJzb25uZWwgY29zdDo8L3NwYW4+IFxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0XCI+JHtmb3JtYXRDdXJyZW5jeShmdW5kLmdldFBlcnNvbm5lbENvc3QoKSl9PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtZWRpdCBlZGl0LWljb25cIiB0aXRsZT1cIkVkaXRcIj48L2k+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPSdzaWRlYmFyLXN0YXQtbGluZSBub25wZXJzb25uZWwnPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0LWxhYmVsXCI+Tm9uLXBlcnNvbm5lbCBjb3N0Ojwvc3Bhbj4gXHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXRcIj4ke2Zvcm1hdEN1cnJlbmN5KGZ1bmQuZ2V0Tm9uUGVyc29ubmVsQ29zdCgpKX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1lZGl0IGVkaXQtaWNvblwiIHRpdGxlPVwiRWRpdFwiPjwvaT5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9J3NpZGViYXItc3RhdC1saW5lIGZ1bmQtdG90YWwnPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0LWxhYmVsXCI+RnVuZCB0b3RhbDo8L3NwYW4+IFxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0XCI+JHtmb3JtYXRDdXJyZW5jeShmdW5kLmdldFRvdGFsKCkpfTwvc3Bhbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxicj5gO1xyXG4gICAgfSxcclxuXHJcbiAgICBsaW5rRWRpdEJ0bnMoKSB7XHJcbiAgICAgICAgbGV0IGJ0bnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZWRpdC1pY29uJyk7XHJcbiAgICAgICAgYnRucy5mb3JFYWNoKChidG4pID0+IHtcclxuICAgICAgICAgICAgLy8gR2V0IHRoZSBmdW5kIGZyb20gdGhlIGRpdiB0aGUgYnV0dG9uIGlzIGluXHJcbiAgICAgICAgICAgIGxldCBmdW5kID0gYnRuLmNsb3Nlc3QoJy5mdW5kLWRpdicpLmlkLnJlcGxhY2UoJ2Z1bmRfJywgJycpO1xyXG4gICAgICAgICAgICBsZXQgcGFnZSA9IGJ0bi5jbG9zZXN0KCcuc2lkZWJhci1zdGF0LWxpbmUnKS5jbGFzc0xpc3RbMV07XHJcbiAgICBcclxuICAgICAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBDdXJyZW50RnVuZC51cGRhdGUoZnVuZCk7XHJcbiAgICAgICAgICAgICAgICB2aXNpdFBhZ2UocGFnZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB1cGRhdGUoKSB7XHJcbiAgICAgICAgY29uc3QgYmFzZWxpbmVEaXYgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmFzZWxpbmUtc3RhdHMnKTtcclxuICAgICAgICBiYXNlbGluZURpdi5pbm5lckhUTUwgPSB0aGlzLnRhcmdldF9odG1sKCk7XHJcblxyXG4gICAgICAgIHRoaXMuZGF0YS5mdW5kcy5mb3JFYWNoKChmdW5kKSA9PiB7XHJcbiAgICAgICAgICAgIHZhciBmdW5kRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgICAgIGZ1bmREaXYuaWQgPSBgZnVuZF8ke2Z1bmQuZnVuZH1gO1xyXG4gICAgICAgICAgICBmdW5kRGl2LmNsYXNzTGlzdC5hZGQoJ2Z1bmQtZGl2Jyk7XHJcbiAgICAgICAgICAgIGZ1bmREaXYuaW5uZXJIVE1MID0gdGhpcy5mdW5kX2h0bWwoZnVuZCk7XHJcbiAgICAgICAgICAgIGJhc2VsaW5lRGl2LmFwcGVuZENoaWxkKGZ1bmREaXYpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZih0aGlzLmdlbkZ1bmQuZ2V0VG90YWwoKSA8PSBCYXNlbGluZS50YXJnZXQoKSl7XHJcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNHRi10b3RhbCAuc3RhdCcpLnN0eWxlLmNvbG9yID0gXCJncmVlblwiO1xyXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZnVuZF8xMDAwIC5zaWRlYmFyLXN0YXQtbGluZTpsYXN0LW9mLXR5cGUgLnN0YXQnKS5zdHlsZS5jb2xvciA9IFwiZ3JlZW5cIjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjR0YtdG90YWwgLnN0YXQnKS5zdHlsZS5jb2xvciA9IFwicmVkXCI7XHJcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNmdW5kXzEwMDAgLnNpZGViYXItc3RhdC1saW5lOmxhc3Qtb2YtdHlwZSAuc3RhdCcpLnN0eWxlLmNvbG9yID0gXCJyZWRcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5saW5rRWRpdEJ0bnMoKTtcclxuICAgIH1cclxufTsiLCJpbXBvcnQgeyBTdXBwbGVtZW50YWwgfSBmcm9tIFwiLi4vLi4vLi4vbW9kZWxzXCI7XHJcbmltcG9ydCB7IGZvcm1hdEN1cnJlbmN5IH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL2NvbW1vbl91dGlsc1wiO1xyXG5pbXBvcnQgeyB2aXNpdFBhZ2UgfSBmcm9tIFwiLi4vLi4vLi4vdmlld3Mvdmlld19sb2dpY1wiO1xyXG5cclxuZXhwb3J0IGNvbnN0IFN1cHBTZWN0aW9uID0ge1xyXG4gICAgaHRtbCgpIHtcclxuICAgICAgICB2YXIgc3VwcCA9IG5ldyBTdXBwbGVtZW50YWw7XHJcbiAgICAgICAgcmV0dXJuIGBcclxuICAgICAgICAgICAgPGRpdiBjbGFzcz0nc2lkZWJhci1zdGF0LWxpbmUnIGlkPVwic3VwcC1yZXZlbnVlXCI+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXQtbGFiZWxcIj5Fc3RpbWF0ZWQgcmV2ZW51ZXM6PC9zcGFuPiBcclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdFwiPiR7Zm9ybWF0Q3VycmVuY3koc3VwcC5yZXZlbnVlKCkpfTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWVkaXQgZWRpdC1zdXBwXCIgdGl0bGU9XCJFZGl0XCI+PC9pPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz0nc2lkZWJhci1zdGF0LWxpbmUnIGlkPVwic3VwcC1leHBlbnNlc1wiPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0LWxhYmVsXCI+RXNpbWF0ZWQgZXhwZW5kaXR1cmVzOjwvc3Bhbj4gXHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXRcIj4ke2Zvcm1hdEN1cnJlbmN5KHN1cHAuZXhwZW5zZXMoKSl9PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtZWRpdCBlZGl0LXN1cHBcIiB0aXRsZT1cIkVkaXRcIj48L2k+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPSdzaWRlYmFyLXN0YXQtbGluZScgaWQ9XCJzdXBwLXRvdGFsXCI+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXQtbGFiZWxcIj5Ub3RhbCBzdXBwbGVtZW50YWw6PC9zcGFuPiBcclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdFwiPiR7Zm9ybWF0Q3VycmVuY3koc3VwcC50b3RhbCgpKX08L3NwYW4+XHJcbiAgICAgICAgICAgIDwvZGl2PmBcclxuICAgIH0sXHJcblxyXG4gICAgbGlua0VkaXRCdG5zKCkge1xyXG4gICAgICAgIGxldCBidG5zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmVkaXQtc3VwcCcpO1xyXG4gICAgICAgIGJ0bnMuZm9yRWFjaCgoYnRuKSA9PiB7XHJcbiAgICAgICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgdmlzaXRQYWdlKCduZXctaW5pdHMnKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHVwZGF0ZSgpIHtcclxuICAgICAgICBjb25zdCBzdXBwRGl2ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3N1cHAtc3RhdHMnKTtcclxuICAgICAgICBzdXBwRGl2LmlubmVySFRNTCA9IHRoaXMuaHRtbCgpO1xyXG4gICAgICAgIHRoaXMubGlua0VkaXRCdG5zKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFN1cHBTZWN0aW9uOyIsImltcG9ydCAnLi9zaWRlYmFyLmNzcydcclxuaW1wb3J0IHsgQmFzZWxpbmVTZWN0aW9uIH0gZnJvbSAnLi9zdWJjb21wb25lbnRzL2Jhc2VsaW5lX3NlY3Rpb24nO1xyXG5cclxuaW1wb3J0IFN1cHBTZWN0aW9uIGZyb20gJy4vc3ViY29tcG9uZW50cy9zdXBwX3NlY3Rpb24nXHJcblxyXG4vLyBmZXRjaCBDU1MgdmFyaWFibGVzIHNhdmVkIGluIDpyb290XHJcbmNvbnN0IHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XHJcbmNvbnN0IHNpZGVCYXJXaWR0aCA9IGdldENvbXB1dGVkU3R5bGUocm9vdCkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1zaWRlYmFyLXdpZHRoJykudHJpbSgpO1xyXG5cclxuZnVuY3Rpb24gaGlkZVNpZGViYXIoKSB7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZWJhci1wYW5lbCcpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi1wYW5lbCcpLnN0eWxlLndpZHRoID0gJzEwMCUnOyBcclxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2hlYWRlcicpLnN0eWxlLndpZHRoID0gJzEwMCUnXHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNob3dTaWRlYmFyKCkge1xyXG4gICAgY29uc3Qgc2lkZWJhciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaWRlYmFyLXBhbmVsJyk7XHJcbiAgICBjb25zdCBtYWluUGFuZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi1wYW5lbCcpO1xyXG4gICAgY29uc3QgaGVhZGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaGVhZGVyJyk7XHJcblxyXG4gICAgLy8gdXBkYXRlIHZhbHVlc1xyXG4gICAgdXBkYXRlVG90YWxzKCk7XHJcbiAgICBzaWRlYmFyLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOyAvLyBTaG93IHRoZSBzaWRlYmFyXHJcbiAgICBcclxuICAgIC8vIENhbGN1bGF0ZSB0aGUgcmVtYWluaW5nIHdpZHRoIGZvciB0aGUgbWFpbiBwYW5lbCBhbmQgaGVhZGVyXHJcbiAgICB2YXIgY29udGVudFdpZHRoID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xyXG4gICAgbWFpblBhbmVsLnN0eWxlLndpZHRoID0gYCR7Y29udGVudFdpZHRoIC0gcGFyc2VJbnQoc2lkZUJhcldpZHRoLCAxMCl9cHhgOyBcclxuICAgIGhlYWRlci5zdHlsZS53aWR0aCA9IGAke2NvbnRlbnRXaWR0aCAtIHBhcnNlSW50KHNpZGVCYXJXaWR0aCwgMTApfXB4YDsgXHJcblxyXG4gICAgLy8gYWRkIGV2ZW50IGxpc3RlbmVyIHRvIHJlc2l6ZSBjb250ZW50IGlmIHdpbmRvdyBpcyBhZGp1c3RlZFxyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHNob3dTaWRlYmFyKTtcclxufVxyXG5cclxuZnVuY3Rpb24gdXBkYXRlU2lkZWJhclRpdGxlKG5ld190aXRsZSl7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZWJhci10aXRsZScpLnRleHRDb250ZW50ID0gbmV3X3RpdGxlO1xyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVUb3RhbHMoKXtcclxuICAgIFN1cHBTZWN0aW9uLnVwZGF0ZSgpO1xyXG4gICAgQmFzZWxpbmVTZWN0aW9uLnVwZGF0ZSgpO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZXNldEFsbCgpe1xyXG4gICAgbG9jYWxTdG9yYWdlLmNsZWFyKCk7XHJcbiAgICAvLyByZXNldCBhbGwgc3RhdHMgdG8gMFxyXG4gICAgdXBkYXRlVG90YWxzKCk7XHJcbn1cclxuXHJcbmNvbnN0IFNpZGViYXIgPSB7XHJcbiAgICBTdXBwU2VjdGlvbiA6IFN1cHBTZWN0aW9uLFxyXG4gICAgQmFzZWxpbmVTZWN0aW9uIDogQmFzZWxpbmVTZWN0aW9uLFxyXG4gICAgaGlkZTogaGlkZVNpZGViYXIsXHJcbiAgICBzaG93OiBzaG93U2lkZWJhcixcclxuICAgIHVwZGF0ZVRpdGxlOiB1cGRhdGVTaWRlYmFyVGl0bGUsXHJcbiAgICB1cGRhdGVUb3RhbHM6IHVwZGF0ZVRvdGFscyxcclxuICAgIHJlc2V0OiByZXNldEFsbFxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgU2lkZWJhcjsiLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vbmF2X2J1dHRvbnMuY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vbmF2X2J1dHRvbnMuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiaW1wb3J0ICcuL25hdl9idXR0b25zLmNzcyc7XHJcblxyXG5pbXBvcnQgeyBuZXh0UGFnZSwgbGFzdFBhZ2UgfSBmcm9tICcuLi8uLi92aWV3cy92aWV3X2xvZ2ljLmpzJ1xyXG5cclxuZnVuY3Rpb24gaW5pdGlhbGl6ZU5hdkJ1dHRvbnMoKXtcclxuICAgIC8vIGluaXRpYWxpemUgbGFzdCBidXR0b25cclxuICAgIGNvbnN0IGxhc3RfYnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2J0bi1sYXN0Jyk7XHJcbiAgICBsYXN0X2J0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGxhc3RQYWdlKTsgXHJcbiAgICAvLyBpbml0aWFsaXplIG5leHQgYnV0dG9uXHJcbiAgICBjb25zdCBuZXh0X2J0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdidG4tbmV4dCcpO1xyXG4gICAgbmV4dF9idG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBuZXh0UGFnZSk7IFxyXG59XHJcblxyXG5mdW5jdGlvbiBoaWRlTmF2QnV0dG9ucygpIHtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduYXYtYnRucycpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNob3dOYXZCdXR0b25zKCkge1xyXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25hdi1idG5zJykuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICBpbml0aWFsaXplTmF2QnV0dG9ucygpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBkaXNhYmxlKGJ1dHRvbl9pZCkge1xyXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYnV0dG9uX2lkKS5jbGFzc0xpc3QuYWRkKCdkaXNhYmxlZCcpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBlbmFibGUoYnV0dG9uX2lkKSB7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChidXR0b25faWQpLmNsYXNzTGlzdC5yZW1vdmUoJ2Rpc2FibGVkJyk7XHJcbn1cclxuXHJcbmNvbnN0IE5leHQgPSB7XHJcbiAgICBkaXNhYmxlIDogZnVuY3Rpb24oKSB7IGRpc2FibGUoJ2J0bi1uZXh0JykgfSxcclxuICAgIGVuYWJsZSA6IGZ1bmN0aW9uKCkgeyBlbmFibGUoJ2J0bi1uZXh0JykgfSxcclxuICAgIGFkZEFjdGlvbiA6IGZ1bmN0aW9uKGZuKSB7XHJcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgI2J0bi1uZXh0YCkuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmbik7XHJcbiAgICB9LFxyXG4gICAgcmVtb3ZlQWN0aW9uIDogZnVuY3Rpb24oZm4pIHtcclxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAjYnRuLW5leHRgKS5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIGZuKTtcclxuICAgIH0sXHJcbn1cclxuXHJcbmNvbnN0IExhc3QgPSB7XHJcbiAgICBkaXNhYmxlIDogZnVuY3Rpb24oKSB7IGRpc2FibGUoJ2J0bi1sYXN0JykgfSxcclxuICAgIGVuYWJsZSA6IGZ1bmN0aW9uKCkgeyBlbmFibGUoJ2J0bi1sYXN0JykgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgTmF2QnV0dG9ucyA9IHtcclxuICAgIGhpZGUgOiBoaWRlTmF2QnV0dG9ucyxcclxuICAgIHNob3cgOiBzaG93TmF2QnV0dG9ucyxcclxuICAgIE5leHQgOiBOZXh0LFxyXG4gICAgTGFzdCA6IExhc3RcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgTmF2QnV0dG9uczsiLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vYm9keS5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcbm9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9ib2R5LmNzc1wiO1xuICAgICAgIGV4cG9ydCBkZWZhdWx0IGNvbnRlbnQgJiYgY29udGVudC5sb2NhbHMgPyBjb250ZW50LmxvY2FscyA6IHVuZGVmaW5lZDtcbiIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9hY2NvcmRpb24uY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vYWNjb3JkaW9uLmNzc1wiO1xuICAgICAgIGV4cG9ydCBkZWZhdWx0IGNvbnRlbnQgJiYgY29udGVudC5sb2NhbHMgPyBjb250ZW50LmxvY2FscyA6IHVuZGVmaW5lZDtcbiIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi90YWJsZS5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcbm9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi90YWJsZS5jc3NcIjtcbiAgICAgICBleHBvcnQgZGVmYXVsdCBjb250ZW50ICYmIGNvbnRlbnQubG9jYWxzID8gY29udGVudC5sb2NhbHMgOiB1bmRlZmluZWQ7XG4iLCJmdW5jdGlvbiBhZGRUYWJsZUhlYWRlcnMoY29scyl7XHJcblxyXG4gICAgLy8gR2V0IHRoZSB0YWJsZSBlbGVtZW50IGJ5IGl0cyBJRFxyXG4gICAgY29uc3QgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi10YWJsZScpO1xyXG4gICAgXHJcbiAgICAvLyBDcmVhdGUgYSB0YWJsZSBoZWFkZXIgcm93IGVsZW1lbnRcclxuICAgIGNvbnN0IGhlYWRlclJvdyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RyJyk7XHJcblxyXG4gICAgY29scy5mb3JFYWNoKGNvbCA9PiB7XHJcbiAgICAgICAgLy8gQ3JlYXRlIGEgaGVhZGVyIGNlbGwgZWxlbWVudFxyXG4gICAgICAgIGNvbnN0IGhlYWRlckNlbGwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0aCcpO1xyXG4gICAgICAgIGhlYWRlckNlbGwudGV4dENvbnRlbnQgPSBjb2xbJ3RpdGxlJ107XHJcbiAgICAgICAgaGVhZGVyQ2VsbC5jbGFzc0xpc3QuYWRkKGNvbFsnY2xhc3NOYW1lJ10pO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIEFwcGVuZCB0aGUgaGVhZGVyIGNlbGwgdG8gdGhlIGhlYWRlciByb3dcclxuICAgICAgICBoZWFkZXJSb3cuYXBwZW5kQ2hpbGQoaGVhZGVyQ2VsbCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBBcHBlbmQgdGhlIGhlYWRlciByb3cgdG8gdGhlIHRhYmxlIGhlYWRlclxyXG4gICAgbGV0IHRoZWFkID0gdGFibGUucXVlcnlTZWxlY3RvcigndGhlYWQnKTtcclxuICAgIHRoZWFkLmFwcGVuZENoaWxkKGhlYWRlclJvdyk7XHJcbn1cclxuXHJcbmNvbnN0IEhlYWRlciA9IHtcclxuICAgIGFkZDogZnVuY3Rpb24oaGVhZGVyX2FycmF5KXtcclxuICAgICAgICBhZGRUYWJsZUhlYWRlcnMoaGVhZGVyX2FycmF5KVxyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgSGVhZGVyOyIsImltcG9ydCBIZWFkZXIgZnJvbSBcIi4vaGVhZGVycy5qc1wiO1xyXG5pbXBvcnQgeyBmb3JtYXRDdXJyZW5jeSB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9jb21tb25fdXRpbHMuanNcIjtcclxuXHJcbmFzeW5jIGZ1bmN0aW9uIGFkZE5ld1JvdyhkYXRhX2RpY3Rpb25hcnksIGNvbHVtbnMgPSBbXSl7XHJcbiAgICBcclxuICAgIC8vIEdldCB0aGUgdGFibGUgZWxlbWVudCBieSBpdHMgSURcclxuICAgIGNvbnN0IHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuXHJcbiAgICAvLyBjaGVjayBpZiBoZWFkZXIgaGFzIGFscmVhZHkgYmVlbiBhZGRlZFxyXG4gICAgbGV0IGhlYWRlcl9yb3cgPSB0YWJsZS5xdWVyeVNlbGVjdG9yKCd0aGVhZCB0cicpO1xyXG4gICAgaWYgKCFoZWFkZXJfcm93KSB7XHJcbiAgICAgICAgSGVhZGVyLmFkZChjb2x1bW5zKTtcclxuICAgICAgICBoZWFkZXJfcm93ID0gdGFibGUucXVlcnlTZWxlY3RvcigndGhlYWQgdHInKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBpbml0aWFsaXplIG5ldyByb3cgb2YgZGF0YVxyXG4gICAgY29uc3QgbmV3X3JvdyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RyJyk7XHJcblxyXG4gICAgLy8gZ28gdGhyb3VnaCBlYWNoIGhlYWRlciBhbmQgYWRkIHRoZSByaWdodCBjZWxsIHZhbHVlIGRlcGVuZGluZyBvbiBpdHMgY2xhc3NcclxuICAgIGxldCB0aEVsZW1lbnRzID0gaGVhZGVyX3Jvdy5xdWVyeVNlbGVjdG9yQWxsKCd0aCcpO1xyXG4gICAgdGhFbGVtZW50cy5mb3JFYWNoKCAoaGVhZGVyX2NlbGwpID0+IHtcclxuICAgICAgICAvLyBDcmVhdGUgbmV3IGNlbGwgYW5kIGFkZCBpdCB0byB0aGUgcm93XHJcbiAgICAgICAgY29uc3QgbmV3Q2VsbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RkJyk7XHJcbiAgICAgICAgbmV3X3Jvdy5hcHBlbmRDaGlsZChuZXdDZWxsKTtcclxuICAgICAgICAvLyBpZiB0aGUgZGF0YSBoYXMgYW4gYXBwcm9wcmlhdGUgY2xhc3MsIGFkZCB0aGUgaW5mbyB0byB0aGUgY2VsbC4gXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBrZWVwIGVtcHR5IGNlbGxcclxuICAgICAgICBPYmplY3Qua2V5cyhkYXRhX2RpY3Rpb25hcnkpLmZvckVhY2goIChjbGFzc05hbWUpID0+IHtcclxuICAgICAgICAgICAgaWYgKGhlYWRlcl9jZWxsLmNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpICl7XHJcbiAgICAgICAgICAgICAgICBuZXdDZWxsLnRleHRDb250ZW50ID0gZGF0YV9kaWN0aW9uYXJ5W2NsYXNzTmFtZV07XHJcbiAgICAgICAgICAgICAgICBuZXdDZWxsLmNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gQXBwZW5kIHRoZSBuZXcgcm93IHRvIHRoZSB0YWJsZSBib2R5XHJcbiAgICBsZXQgdGJvZHkgPSB0YWJsZS5xdWVyeVNlbGVjdG9yKCd0Ym9keScpO1xyXG4gICAgdGJvZHkuYXBwZW5kQ2hpbGQobmV3X3Jvdyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNhdmVSb3dFZGl0cyhyb3cpe1xyXG4gICAgdmFyIGNlbGxzID0gcm93LnF1ZXJ5U2VsZWN0b3JBbGwoJ3RkJylcclxuICAgIGNlbGxzLmZvckVhY2goIGNlbGwgPT4ge1xyXG4gICAgICAgIC8vIHNhdmUgZHJvcGRvd24gdmFsdWVzXHJcbiAgICAgICAgaWYgKGNlbGwucXVlcnlTZWxlY3Rvcignc2VsZWN0Jykpe1xyXG4gICAgICAgICAgICB2YXIgc2VydmljZVNlbGVjdG9yID0gY2VsbC5xdWVyeVNlbGVjdG9yKCdzZWxlY3QnKTtcclxuICAgICAgICAgICAgY2VsbC50ZXh0Q29udGVudCA9IHNlcnZpY2VTZWxlY3Rvci52YWx1ZTtcclxuICAgICAgICB9IGVsc2UgaWYgKGNlbGwucXVlcnlTZWxlY3RvcignaW5wdXQnKSkge1xyXG4gICAgICAgICAgICAvLyBzYXZlIG5ldyBlbnRlcmVkIHZhbHVlIGluIHRleHRib3hcclxuICAgICAgICAgICAgdmFyIHRleHRib3ggPSBjZWxsLnF1ZXJ5U2VsZWN0b3IoJ2lucHV0Jyk7XHJcbiAgICAgICAgICAgIHZhciBlbnRlcmVkVmFsdWUgPSB0ZXh0Ym94LnZhbHVlO1xyXG4gICAgICAgICAgICAvLyB1cGRhdGUgZGlzcGxheSBhbmQgZm9ybWF0IHdpdGggY3VycmVuY3kgaWYgcmVsZXZhbnRcclxuICAgICAgICAgICAgaWYgKCBjZWxsLmNsYXNzTGlzdC5jb250YWlucygnY29zdCcpICl7XHJcbiAgICAgICAgICAgICAgICAvLyBpZiBjb3N0LCByZW1vdmUgY29tbWFzIGZpcnN0XHJcbiAgICAgICAgICAgICAgICBlbnRlcmVkVmFsdWUgPSBlbnRlcmVkVmFsdWUucmVwbGFjZUFsbCgnLCcsICcnKTtcclxuICAgICAgICAgICAgICAgIGNlbGwudGV4dENvbnRlbnQgPSBmb3JtYXRDdXJyZW5jeShlbnRlcmVkVmFsdWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY2VsbC50ZXh0Q29udGVudCA9IGVudGVyZWRWYWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBzZXQgdmFsdWUgYXR0cmlidXRlIHRvIHRoZSBuZXcgdXNlciBpbnB1dFxyXG4gICAgICAgICAgICBjZWxsLnNldEF0dHJpYnV0ZSgndmFsdWUnLCBlbnRlcmVkVmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgIH0pXHJcbn1cclxuXHJcbmNvbnN0IFJvd3MgPSB7XHJcbiAgICBhZGQgOiBmdW5jdGlvbihkYXRhX2RpY3Rpb25hcnksIGNvbHMpe1xyXG4gICAgICAgIGFkZE5ld1JvdyhkYXRhX2RpY3Rpb25hcnksIGNvbHMpXHJcbiAgICB9LFxyXG4gICAgc2F2ZUVkaXRzIDogZnVuY3Rpb24ocm93KXtcclxuICAgICAgICBzYXZlUm93RWRpdHMocm93KVxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBSb3dzOyIsImltcG9ydCBSb3dzIGZyb20gJy4vcm93cy5qcydcclxuXHJcbmZ1bmN0aW9uIGhpZGVCdXR0b24oY2xhc3NOYW1lKXtcclxuICAgIHJldHVybiBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgYnV0dG9ucyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoY2xhc3NOYW1lKTtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ1dHRvbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgYnV0dG9uc1tpXS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gc2hvd0J1dHRvbihjbGFzc05hbWUpe1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHZhciBidXR0b25zID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShjbGFzc05hbWUpO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnV0dG9ucy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBidXR0b25zW2ldLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lJztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZUJ1dHRvblRleHQoY2xhc3NOYW1lLCB0ZXh0KXtcclxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYC4ke2NsYXNzTmFtZX1gKS50ZXh0Q29udGVudCA9IHRleHQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGhhbmRsZVJvd0VkaXQoYWN0aW9uT25DbGljaywgdXBkYXRlQ2FsbGJhY2sgPSBudWxsKXtcclxuICAgIC8vIGF0dGFjaCBhbiBldmVudCBsaXN0ZW5lciB0byBlYWNoIGVkaXQgYnV0dG9uIGluIGV2ZXJ5IHJvd1xyXG4gICAgdmFyIGVkaXRCdXR0b25zID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnYnRuLWVkaXQnKTtcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWRpdEJ1dHRvbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBlZGl0QnV0dG9uc1tpXS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIC8vIERldGVybWluZSB3aGF0IHdhcyBjbGlja2VkIG9uIHdpdGhpbiB0aGUgdGFibGVcclxuICAgICAgICAgICAgdmFyIHJvd1RvRWRpdCA9IGV2ZW50LnRhcmdldC5jbG9zZXN0KCd0cicpO1xyXG4gICAgICAgICAgICAvLyBtYXJrIHJvdyBhcyBiZWluZyBlZGl0ZWRcclxuICAgICAgICAgICAgcm93VG9FZGl0LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZS1lZGl0aW5nJyk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyB0dXJuIHJlbGV2YW50IGVudHJpZXMgaW50byB0ZXh0Ym94ZXMsIHVzdWFsbHlcclxuICAgICAgICAgICAgYWN0aW9uT25DbGljaygpO1xyXG5cclxuICAgICAgICAgICAgLy8gaGlkZSBlZGl0IGJ1dHRvbnNcclxuICAgICAgICAgICAgRWRpdC5oaWRlKCk7XHJcbiAgICAgICAgICAgIGlmKHVwZGF0ZUNhbGxiYWNrKXtcclxuICAgICAgICAgICAgICAgIGluaXRpYWxpemVDb25maXJtQnV0dG9uKHVwZGF0ZUNhbGxiYWNrKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxufVxyXG5cclxuZnVuY3Rpb24gaW5pdGlhbGl6ZUNvbmZpcm1CdXR0b24odXBkYXRlQ2FsbGJhY2spe1xyXG4gICAgLy8gZ2V0IGVsZW1lbnQgYW5kIGFkZCBsaXN0ZW5lciBmb3IgY2xpY2tcclxuICAgIHZhciByb3dUb0VkaXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYWN0aXZlLWVkaXRpbmcnKTtcclxuICAgIGNvbnN0IGNvbmZpcm1fYnRuID0gcm93VG9FZGl0LnF1ZXJ5U2VsZWN0b3IoXCIuYnRuLWNvbmZpcm1cIik7XHJcbiAgICAvLyBzaG93IHRoZSByb3cncyBjb25maXJtIGJ1dHRvblxyXG4gICAgY29uZmlybV9idG4uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICBjb25maXJtX2J0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7O1xyXG4gICAgICAgIC8vIHNhdmUgcm93IGVkaXRzXHJcbiAgICAgICAgUm93cy5zYXZlRWRpdHMocm93VG9FZGl0KTtcclxuICAgICAgICAvLyB1cGRhdGUgdmFsdWVzIGluIHNpZGViYXJcclxuICAgICAgICB1cGRhdGVDYWxsYmFjaygpO1xyXG4gICAgICAgIC8vIG1ha2Ugcm93IG5vIGxvbmdlciBncmVlblxyXG4gICAgICAgIHJvd1RvRWRpdC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUtZWRpdGluZycpO1xyXG4gICAgICAgIC8vIHNob3cgZWRpdCBidXR0b25zIGFuZCBoaWRlIGNvbmZpcm0gYnV0dG9uc1xyXG4gICAgICAgIEVkaXQuc2hvdygpO1xyXG4gICAgICAgIENvbmZpcm0uaGlkZSgpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmNvbnN0IEVkaXQgPSB7XHJcbiAgICBodG1sOiAnPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZWRpdFwiPkVkaXQgcm93PC9idXR0b24+JyxcclxuICAgIGhpZGU6IGhpZGVCdXR0b24oJ2J0bi1lZGl0JyksXHJcbiAgICBzaG93OiBzaG93QnV0dG9uKCdidG4tZWRpdCcpLFxyXG4gICAgaW5pdCA6IGZ1bmN0aW9uKGFjdGlvbk9uQ2xpY2ssIHVwZGF0ZUNhbGxiYWNrKXtcclxuICAgICAgICBoYW5kbGVSb3dFZGl0KGFjdGlvbk9uQ2xpY2ssIHVwZGF0ZUNhbGxiYWNrKVxyXG4gICAgfVxyXG59O1xyXG5cclxuY29uc3QgRGVsZXRlID0ge1xyXG4gICAgaHRtbDogJzxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRlbGV0ZVwiPkRlbGV0ZTwvYnV0dG9uPicsXHJcbiAgICBoaWRlOiBoaWRlQnV0dG9uKCdidG4tZGVsZXRlJyksXHJcbiAgICBzaG93OiBzaG93QnV0dG9uKCdidG4tZGVsZXRlJylcclxufTtcclxuXHJcbmNvbnN0IENvbmZpcm0gPSB7XHJcbiAgICBodG1sOiAnPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tY29uZmlybVwiPkNvbmZpcm08L2J1dHRvbj4nLFxyXG4gICAgaGlkZTogaGlkZUJ1dHRvbignYnRuLWNvbmZpcm0nKSxcclxuICAgIHNob3c6IHNob3dCdXR0b24oJ2J0bi1jb25maXJtJylcclxufTtcclxuXHJcbmNvbnN0IEFkZFJvdyA9IHtcclxuICAgIGhpZGU6IGhpZGVCdXR0b24oJ2J0bi1hZGQnKSxcclxuICAgIHNob3c6IHNob3dCdXR0b24oJ2J0bi1hZGQnKSxcclxuICAgIHVwZGF0ZVRleHQ6IGZ1bmN0aW9uKHRleHQpe1xyXG4gICAgICAgIHVwZGF0ZUJ1dHRvblRleHQoJ2J0bi1hZGQnLCB0ZXh0KTtcclxuICAgIH1cclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBCdXR0b25zID0ge1xyXG4gICAgRGVsZXRlOiBEZWxldGUsXHJcbiAgICBFZGl0IDogRWRpdCxcclxuICAgIENvbmZpcm0gOiBDb25maXJtLFxyXG4gICAgQWRkUm93IDogQWRkUm93LFxyXG4gICAgZWRpdF9jb25maXJtX2J0bnMgOiBFZGl0Lmh0bWwgKyBDb25maXJtLmh0bWwgLFxyXG4gICAgYWxsX2J0bnMgOiBEZWxldGUuaHRtbCArIEVkaXQuaHRtbCArIENvbmZpcm0uaHRtbFxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBCdXR0b25zOyIsImZ1bmN0aW9uIGNyZWF0ZURyb3Bkb3duKGRhdGFBcnJheSkge1xyXG5cclxuICAvLyBDcmVhdGluZyBhIHNlbGVjdCBlbGVtZW50XHJcbiAgY29uc3Qgc2VsZWN0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NlbGVjdCcpO1xyXG5cclxuICAvLyBhZGQgYSBkZWZhdWx0IGJsYW5rIG9wdGlvbiB0byB0aGUgZGF0YUFycmF5XHJcbiAgZGF0YUFycmF5ID0gWycnXS5jb25jYXQoZGF0YUFycmF5KTtcclxuXHJcbiAgLy8gTG9vcGluZyB0aHJvdWdoIHRoZSBhcnJheSBhbmQgY3JlYXRpbmcgYW4gb3B0aW9uIGZvciBlYWNoIGVsZW1lbnRcclxuICBkYXRhQXJyYXkuZm9yRWFjaChpdGVtID0+IHtcclxuICAgIGNvbnN0IG9wdGlvbkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKTtcclxuICAgIG9wdGlvbkVsZW1lbnQudmFsdWUgPSBpdGVtO1xyXG4gICAgb3B0aW9uRWxlbWVudC50ZXh0Q29udGVudCA9IGl0ZW07XHJcbiAgICBzZWxlY3RFbGVtZW50LmFwcGVuZENoaWxkKG9wdGlvbkVsZW1lbnQpOyAvLyBBcHBlbmRpbmcgdGhlIG9wdGlvbiB0byB0aGUgc2VsZWN0XHJcbiAgfSk7XHJcblxyXG4gIC8vIFJldHVybiB0aGUgc2VsZWN0IGVsZW1lbnQgc28gaXQgY2FuIGJlIGFwcGVuZGVkIHRvIHRoZSBkb2N1bWVudFxyXG4gIHJldHVybiBzZWxlY3RFbGVtZW50O1xyXG59XHJcblxyXG5cclxuZXhwb3J0IGNvbnN0IERyb3Bkb3duID0ge1xyXG4gICAgY3JlYXRlIDogZnVuY3Rpb24oZGF0YUFycmF5KSB7IHJldHVybiBjcmVhdGVEcm9wZG93bihkYXRhQXJyYXkpIH0sXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IERyb3Bkb3duOyIsImltcG9ydCB7IGZvcm1hdEN1cnJlbmN5LCBkaXNwbGF5V2l0aENvbW1hcyB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9jb21tb25fdXRpbHMuanNcIjtcclxuaW1wb3J0IFNlcnZpY2VzIGZyb20gXCIuLi8uLi8uLi9tb2RlbHMvc2VydmljZXMuanNcIjtcclxuaW1wb3J0IERyb3Bkb3duIGZyb20gXCIuLi8uLi9mb3JtL3N1YmNvbXBvbmVudHMvZHJvcGRvd24uanNcIjtcclxuXHJcbi8vIHJldHVybiBjZWxsIHZhbHVlIGF0dHJpYnV0ZSBvciAwIGlmIGl0IGRvZXMgbm90IGV4aXN0XHJcbmZ1bmN0aW9uIGdldENlbGxWYWx1ZShyb3csIGNsYXNzTmFtZSkge1xyXG4gICAgdmFyIGNlbGwgPSByb3cucXVlcnlTZWxlY3RvcihgLiR7Y2xhc3NOYW1lfWApO1xyXG4gICAgdmFyIGNlbGxWYWx1ZSA9IGNlbGwgPyBjZWxsLmdldEF0dHJpYnV0ZSgndmFsdWUnKSA6IG51bGw7XHJcbiAgICByZXR1cm4gY2VsbFZhbHVlID8gcGFyc2VGbG9hdChjZWxsVmFsdWUpIDogMDtcclxufVxyXG5cclxuLy8gcmV0dXJuIHRleHQgaW4gY2VsbFxyXG5mdW5jdGlvbiBnZXRDZWxsVGV4dChyb3csIGNsYXNzTmFtZSkge1xyXG4gICAgdmFyIGNlbGwgPSByb3cucXVlcnlTZWxlY3RvcihgLiR7Y2xhc3NOYW1lfWApO1xyXG4gICAgaWYgKGNlbGwpIHtcclxuICAgICAgICByZXR1cm4gY2VsbC50ZXh0Q29udGVudDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy9jb25zb2xlLmxvZyhgRXJyb3IgcmV0cmlldmluZyBjZWxsIHRleHQgZm9yIGNsYXNzICR7Y2xhc3NOYW1lfWApO1xyXG4gICAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gdXBkYXRlVGFibGVDZWxsKHJvdywgY29sX2NsYXNzLCBuZXdfdmFsdWUpe1xyXG4gICAgY29uc3QgY2VsbCA9IHJvdy5xdWVyeVNlbGVjdG9yKGAuJHtjb2xfY2xhc3N9YCk7XHJcbiAgICBjZWxsLnNldEF0dHJpYnV0ZSgndmFsdWUnLCBuZXdfdmFsdWUpO1xyXG4gICAgY2VsbC50ZXh0Q29udGVudCA9IGZvcm1hdEN1cnJlbmN5KG5ld192YWx1ZSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUVkaXRhYmxlQ2VsbChjZWxsQ2xhc3MsIGlzQ29zdCl7XHJcbiAgICAvLyBnZXQgY2VsbFxyXG4gICAgY29uc3QgY2VsbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYC5hY3RpdmUtZWRpdGluZyB0ZC4ke2NlbGxDbGFzc31gKTtcclxuICAgIC8vIENyZWF0ZSBhbiBpbnB1dCBlbGVtZW50IHRvIGVkaXQgdGhlIHZhbHVlXHJcbiAgICB2YXIgdGV4dGJveCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XHJcbiAgICB0ZXh0Ym94LnR5cGUgPSAndGV4dCc7XHJcbiAgICBpZiAoaXNDb3N0KXtcclxuICAgICAgICB2YXIgdmFsdWUgPSBjZWxsLmdldEF0dHJpYnV0ZSgndmFsdWUnKTtcclxuICAgICAgICB0ZXh0Ym94LnZhbHVlID0gZGlzcGxheVdpdGhDb21tYXModmFsdWUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB0ZXh0Ym94LnZhbHVlID0gY2VsbC50ZXh0Q29udGVudDtcclxuICAgIH1cclxuICAgIC8vIENsZWFyIHRoZSBjdXJyZW50IGNvbnRlbnQgYW5kIGFwcGVuZCB0aGUgdGV4dGJveCB0byB0aGUgY2VsbFxyXG4gICAgY2VsbC5pbm5lckhUTUwgPSAnJztcclxuICAgIGNlbGwuYXBwZW5kQ2hpbGQodGV4dGJveCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZURyb3Bkb3duKGNlbGxDbGFzcywgb3B0aW9uQXJyYXkpe1xyXG4gICAgLy8gZ2V0IGNlbGxcclxuICAgIGNvbnN0IGNlbGwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAuYWN0aXZlLWVkaXRpbmcgdGQuJHtjZWxsQ2xhc3N9YCk7XHJcbiAgICAvLyBhZGQgc2VydmljZSBkcm9wZG93blxyXG4gICAgY29uc3QgZHJvcGRvd24gPSBEcm9wZG93bi5jcmVhdGUob3B0aW9uQXJyYXkpO1xyXG4gICAgZHJvcGRvd24udmFsdWUgPSBjZWxsLnRleHRDb250ZW50O1xyXG4gICAgLy8gQ2xlYXIgdGhlIGN1cnJlbnQgY29udGVudCBhbmQgYXBwZW5kIHRoZSB0ZXh0Ym94IHRvIHRoZSBjZWxsXHJcbiAgICBjZWxsLmlubmVySFRNTCA9ICcnO1xyXG4gICAgY2VsbC5hcHBlbmRDaGlsZChkcm9wZG93bik7XHJcbn1cclxuXHJcbmNvbnN0IENlbGwgPSB7XHJcbiAgICBnZXRWYWx1ZTogZnVuY3Rpb24ocm93LCBjbGFzc05hbWUpIHtcclxuICAgICAgICByZXR1cm4gZ2V0Q2VsbFZhbHVlKHJvdywgY2xhc3NOYW1lKTsgXHJcbiAgICB9LFxyXG4gICAgZ2V0VGV4dDogZnVuY3Rpb24ocm93LCBjbGFzc05hbWUpIHtcclxuICAgICAgICByZXR1cm4gZ2V0Q2VsbFRleHQocm93LCBjbGFzc05hbWUpOyBcclxuICAgIH0sXHJcbiAgICB1cGRhdGVWYWx1ZTogZnVuY3Rpb24ocm93LCBjb2xfY2xhc3MsIG5ld192YWx1ZSkge1xyXG4gICAgICAgIHVwZGF0ZVRhYmxlQ2VsbChyb3csIGNvbF9jbGFzcywgbmV3X3ZhbHVlKTsgXHJcbiAgICB9LFxyXG4gICAgY3JlYXRlVGV4dGJveCA6IGZ1bmN0aW9uKGNsYXNzTmFtZSwgaXNDb3N0KSB7XHJcbiAgICAgICAgY3JlYXRlRWRpdGFibGVDZWxsKGNsYXNzTmFtZSwgaXNDb3N0KVxyXG4gICAgfSxcclxuICAgIGNyZWF0ZVNlcnZpY2VEcm9wZG93biA6ICAoKSA9PiB7IGNyZWF0ZURyb3Bkb3duKCdzZXJ2aWNlJywgU2VydmljZXMubGlzdCgpKSB9LFxyXG4gICAgY3JlYXRlRHJvcGRvd24gOiBjcmVhdGVEcm9wZG93blxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ2VsbDsiLCJpbXBvcnQgeyBmb3JtYXRDdXJyZW5jeSB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9jb21tb25fdXRpbHMuanNcIjtcclxuXHJcbi8vIHBvc2l0aW9uIGlzIGluZGV4IGF0IHdoaWNoIG5ldyBjb2x1bW4gd2lsbCBiZSBpbnNlcnRlZFxyXG5mdW5jdGlvbiBhZGRDb2wocG9zaXRpb24sIGh0bWxDb250ZW50ID0gJycsIGhlYWRlclRpdGxlID0gJycpIHtcclxuICAgIC8vIEdldCB0aGUgdGFibGUgZWxlbWVudCBieSBpdHMgSURcclxuICAgIGxldCB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYWluLXRhYmxlJyk7XHJcblxyXG4gICAgLy8gVmFsaWRhdGUgcG9zaXRpb25cclxuICAgIGxldCBtYXhQb3NpdGlvbiA9IHRhYmxlLnJvd3NbMF0uY2VsbHMubGVuZ3RoO1xyXG4gICAgaWYgKHBvc2l0aW9uIDwgMCB8fCBwb3NpdGlvbiA+IG1heFBvc2l0aW9uKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFBvc2l0aW9uICR7cG9zaXRpb259IGlzIG91dCBvZiBib3VuZHMuYCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICBcclxuICAgIC8vIEluc2VydCB0aGUgaGVhZGVyIGlmIHByb3ZpZGVkXHJcbiAgICBsZXQgdGhlYWQgPSB0YWJsZS50SGVhZDtcclxuICAgIGlmIChoZWFkZXJUaXRsZSAmJiB0aGVhZCkge1xyXG4gICAgICBsZXQgdGggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0aCcpO1xyXG4gICAgICB0aC5pbm5lckhUTUwgPSBoZWFkZXJUaXRsZTsgLy8gVXNlIGlubmVySFRNTCB0byBpbnNlcnQgSFRNTCBjb250ZW50XHJcbiAgICAgIHRoZWFkLnJvd3NbMF0uaW5zZXJ0QmVmb3JlKHRoLCB0aGVhZC5yb3dzWzBdLmNlbGxzW3Bvc2l0aW9uXSk7XHJcbiAgICB9XHJcbiAgXHJcbiAgICAvLyBJbnNlcnQgbmV3IGNlbGxzIGludG8gZWFjaCByb3cgb2YgdGhlIHRhYmxlIGJvZHlcclxuICAgIGxldCB0Ym9keSA9IHRhYmxlLnRCb2RpZXNbMF07XHJcbiAgICBpZiAodGJvZHkpIHtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0Ym9keS5yb3dzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgbGV0IHJvdyA9IHRib2R5LnJvd3NbaV07XHJcbiAgICAgICAgbGV0IHRkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGQnKTtcclxuICAgICAgICB0ZC5pbm5lckhUTUwgPSBodG1sQ29udGVudDsgLy8gVXNlIGlubmVySFRNTCB0byBpbnNlcnQgSFRNTCBjb250ZW50XHJcbiAgICAgICAgcm93Lmluc2VydEJlZm9yZSh0ZCwgcm93LmNlbGxzW3Bvc2l0aW9uXSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gbmNvbHMoKXtcclxuICAgIGNvbnN0IHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuICAgIC8vIEVuc3VyZSB0aGF0IHRoZSByb3cgZXhpc3RzIGJlZm9yZSBjb3VudGluZyB0aGUgY29sdW1uc1xyXG4gICAgcmV0dXJuIHRhYmxlLnJvd3NbMF0uY2VsbHMubGVuZ3RoO1xyXG59XHJcbiAgXHJcbmZ1bmN0aW9uIGFkZENvbFRvRW5kKGh0bWxDb250ZW50cyA9IFtdLCBoZWFkZXJUaXRsZSA9ICcnKXtcclxuICAgIC8vIGNvdW50IGNvbHVtbnMgYW5kIGFkZCBuZXcgY29sdW1uIHRvIHRoZSBlbmRcclxuICAgIGNvbnN0IHBvc2l0aW9uID0gbmNvbHMoJ21haW4tdGFibGUnKTtcclxuICAgIGFkZENvbChwb3NpdGlvbiwgaHRtbENvbnRlbnRzLCBoZWFkZXJUaXRsZSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFzc2lnbkNsYXNzVG9Db2x1bW4oaGVhZGVyTmFtZSwgY2xhc3NOYW1lKSB7XHJcbiAgICAvLyBHZXQgdGhlIHRhYmxlIGVsZW1lbnQgYnkgaXRzIElEXHJcbiAgICBsZXQgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi10YWJsZScpO1xyXG5cclxuICAgIC8vIEZpbmQgdGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gYnkgaXRzIGhlYWRlciBuYW1lXHJcbiAgICBjb25zdCB0aGVhZCA9IHRhYmxlLnRIZWFkO1xyXG4gICAgbGV0IGhlYWRlckNlbGxJbmRleCA9IC0xO1xyXG4gICAgY29uc3QgaGVhZGVyQ2VsbHMgPSB0aGVhZC5yb3dzWzBdLmNlbGxzOyAvLyBBc3N1bWluZyB0aGUgZmlyc3Qgcm93IGNvbnRhaW5zIGhlYWRlciBjZWxscyAoPHRoPilcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGVhZGVyQ2VsbHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpZiAoaGVhZGVyQ2VsbHNbaV0udGV4dENvbnRlbnQudHJpbSgpID09PSBoZWFkZXJOYW1lKSB7XHJcbiAgICAgICAgICAgIC8vIGFzc2lnbiB0aGUgY2xhc3MgdG8gdGhlIGhlYWRlciBjZWxsXHJcbiAgICAgICAgICAgIGhlYWRlckNlbGxzW2ldLmNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcclxuICAgICAgICAgICAgaGVhZGVyQ2VsbEluZGV4ID0gaTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIGVycm9yIGNoZWNrXHJcbiAgICBpZiAoaGVhZGVyQ2VsbEluZGV4ID09PSAtMSkge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYE5vIGhlYWRlciBmb3VuZCB3aXRoIG5hbWUgXCIke2hlYWRlck5hbWV9XCJgKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgXHJcbiAgICAvLyBBc3NpZ24gdGhlIGNsYXNzIHRvIGVhY2ggY2VsbCBpbiB0aGUgc3BlY2lmaWVkIGNvbHVtbiBpbmRleCB3aXRoaW4gdGhlIHRib2R5XHJcbiAgICBsZXQgdGJvZHkgPSB0YWJsZS50Qm9kaWVzWzBdO1xyXG4gICAgaWYgKHRib2R5KSB7XHJcbiAgICAgIGxldCBib2R5Um93cyA9IHRib2R5LnJvd3M7XHJcbiAgICAgIGZvciAobGV0IHJvdyBvZiBib2R5Um93cykge1xyXG4gICAgICAgIGlmIChyb3cuY2VsbHNbaGVhZGVyQ2VsbEluZGV4XSkge1xyXG4gICAgICAgICAgcm93LmNlbGxzW2hlYWRlckNlbGxJbmRleF0uY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbmZ1bmN0aW9uIGFkZENvc3RDbGFzcyhoZWFkZXJOYW1lKXtcclxuICAgIGFzc2lnbkNsYXNzVG9Db2x1bW4oIGhlYWRlck5hbWUsICdjb3N0Jyk7XHJcblxyXG4gICAgLy8gR2V0IGFsbCB0aGUgY2VsbHMgd2l0aCB0aGUgc3BlY2lmaWVkIGNsYXNzIG5hbWVcclxuICAgIGNvbnN0IGNlbGxzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgdGQuY29zdGApO1xyXG4gICAgICBcclxuICAgIGNlbGxzLmZvckVhY2goY2VsbCA9PiB7XHJcbiAgICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IHRleHQgY29udGVudCBvZiB0aGUgY2VsbCBhbmQgYXNzaWduIGl0IHRvICd2YWx1ZScgYXR0cmlidXRlXHJcbiAgICAgICAgaWYgKCFjZWxsLmdldEF0dHJpYnV0ZSgndmFsdWUnKSl7XHJcbiAgICAgICAgICAgIGNvbnN0IGNlbGxUZXh0ID0gY2VsbC50ZXh0Q29udGVudC50cmltKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGNlbGxWYWx1ZSA9IGlzTmFOKGNlbGxUZXh0KSB8fCBjZWxsVGV4dCA9PT0gJycgPyAwIDogcGFyc2VGbG9hdChjZWxsVGV4dCk7XHJcbiAgICAgICAgICAgIGNlbGwuc2V0QXR0cmlidXRlKCd2YWx1ZScsIGNlbGxWYWx1ZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBOb3cgZm9ybWF0IHRoZSB0ZXh0IGNvbnRlbnQgbGlrZSBjdXJyZW5jeSBhbmQgcmVwbGFjZSBpdCBpbiB0aGUgY2VsbFxyXG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRDdXJyZW5jeSA9IGZvcm1hdEN1cnJlbmN5KHBhcnNlRmxvYXQoY2VsbFZhbHVlKSk7XHJcbiAgICAgICAgICAgIGNlbGwudGV4dENvbnRlbnQgPSBmb3JtYXR0ZWRDdXJyZW5jeTtcclxuICAgICAgICB9XHJcbiAgICAgIFxyXG4gICAgfSk7XHJcblxyXG59XHJcblxyXG5mdW5jdGlvbiBhc3NpZ25Db2x1bW5DbGFzc2VzKGNvbHVtbkRlZmluaXRpb25zKSB7XHJcbiAgICBjb2x1bW5EZWZpbml0aW9ucy5mb3JFYWNoKGNvbHVtbiA9PiB7XHJcbiAgICAgICAgLy8gQXNzaWduIGNsYXNzIHRvIGNvbHVtblxyXG4gICAgICAgIGFzc2lnbkNsYXNzVG9Db2x1bW4oY29sdW1uLnRpdGxlLCBjb2x1bW4uY2xhc3NOYW1lKTtcclxuXHJcbiAgICAgICAgLy8gSWYgdGhlIGNvbHVtbiBpcyBhIGNvc3QgY29sdW1uLCBhZGQgdGhlIHNwZWNpZmljIGNvc3QgY2xhc3NcclxuICAgICAgICBpZiAoY29sdW1uLmlzQ29zdCkge1xyXG4gICAgICAgICAgICBhZGRDb3N0Q2xhc3MoY29sdW1uLnRpdGxlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIHNob3cgdGhlIGNvbHVtblxyXG4gICAgICAgIGlmICghY29sdW1uLmhpZGUpe1xyXG4gICAgICAgICAgICBzaG93Q29sdW1uQnlUaXRsZShjb2x1bW4udGl0bGUpO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBoaWRlQ29sdW1uKGluZGV4KSB7XHJcbiAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuICB2YXIgcm93cyA9IHRhYmxlLnJvd3M7XHJcblxyXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICB2YXIgY2VsbHMgPSByb3dzW2ldLmNlbGxzO1xyXG4gICAgICBpZiAoY2VsbHMubGVuZ3RoID4gaW5kZXgpIHtcclxuICAgICAgICAgIGNlbGxzW2luZGV4XS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICB9XHJcbiAgfVxyXG59XHJcblxyXG4vLyBGdW5jdGlvbiB0byBzaG93IGEgc3BlY2lmaWMgY29sdW1uXHJcbmZ1bmN0aW9uIHNob3dDb2x1bW4oaW5kZXgpIHtcclxuICB2YXIgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi10YWJsZScpO1xyXG4gIHZhciByb3dzID0gdGFibGUucm93cztcclxuXHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIHZhciBjZWxscyA9IHJvd3NbaV0uY2VsbHM7XHJcbiAgICAgIGlmIChjZWxscy5sZW5ndGggPiBpbmRleCkge1xyXG4gICAgICAgICAgY2VsbHNbaW5kZXhdLnN0eWxlLmRpc3BsYXkgPSAndGFibGUtY2VsbCc7XHJcbiAgICAgIH1cclxuICB9XHJcbn1cclxuXHJcbi8vIEZ1bmN0aW9uIHRvIGdldCB0aGUgY29sdW1uIGluZGV4IGJ5IHRpdGxlXHJcbmZ1bmN0aW9uIGdldENvbHVtbkluZGV4QnlUaXRsZSh0YWJsZSwgdGl0bGUpIHtcclxuICB2YXIgaGVhZGVycyA9IHRhYmxlLnF1ZXJ5U2VsZWN0b3JBbGwoJ3RoJyk7XHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZWFkZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGlmIChoZWFkZXJzW2ldLmlubmVyVGV4dCA9PT0gdGl0bGUpIHtcclxuICAgICAgICAgIHJldHVybiBpO1xyXG4gICAgICB9XHJcbiAgfVxyXG4gIHJldHVybiAtMTsgLy8gQ29sdW1uIG5vdCBmb3VuZFxyXG59XHJcblxyXG4vLyBGdW5jdGlvbiB0byBoaWRlIGEgY29sdW1uIGJ5IHRpdGxlXHJcbmZ1bmN0aW9uIGhpZGVDb2x1bW5CeVRpdGxlKHRpdGxlKSB7XHJcbiAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuICB2YXIgaW5kZXggPSBnZXRDb2x1bW5JbmRleEJ5VGl0bGUodGFibGUsIHRpdGxlKTtcclxuICBpZiAoaW5kZXggIT09IC0xKSB7XHJcbiAgICAgIGhpZGVDb2x1bW4oaW5kZXgpO1xyXG4gIH0gZWxzZSB7XHJcbiAgICAgIGNvbnNvbGUubG9nKGBDb2x1bW4gd2l0aCB0aXRsZSBcIiR7dGl0bGV9XCIgbm90IGZvdW5kLmApO1xyXG4gIH1cclxufVxyXG5cclxuLy8gRnVuY3Rpb24gdG8gc2hvdyBhIGNvbHVtbiBieSB0aXRsZVxyXG5mdW5jdGlvbiBzaG93Q29sdW1uQnlUaXRsZSh0aXRsZSkge1xyXG4gIHZhciB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYWluLXRhYmxlJyk7XHJcbiAgdmFyIGluZGV4ID0gZ2V0Q29sdW1uSW5kZXhCeVRpdGxlKHRhYmxlLCB0aXRsZSk7XHJcbiAgaWYgKGluZGV4ICE9PSAtMSkge1xyXG4gICAgICBzaG93Q29sdW1uKGluZGV4KTtcclxuICB9IGVsc2Uge1xyXG4gICAgICBjb25zb2xlLmxvZyhgQ29sdW1uIHdpdGggdGl0bGUgXCIke3RpdGxlfVwiIG5vdCBmb3VuZC5gKTtcclxuICB9XHJcbn1cclxuXHJcblxyXG5jb25zdCBDb2x1bW4gPSB7XHJcbiAgYWRkOiBmdW5jdGlvbihwb3NpdGlvbiwgaHRtbENvbnRlbnQsIGhlYWRlclRpdGxlKSB7XHJcbiAgICAgIHJldHVybiBhZGRDb2wocG9zaXRpb24sIGh0bWxDb250ZW50LCBoZWFkZXJUaXRsZSk7XHJcbiAgfSxcclxuICBhZGRBdEVuZDogZnVuY3Rpb24oaHRtbENvbnRlbnQsIGhlYWRlclRpdGxlKSB7XHJcbiAgICAgIHJldHVybiBhZGRDb2xUb0VuZChodG1sQ29udGVudCwgaGVhZGVyVGl0bGUpO1xyXG4gIH0sXHJcbiAgYXNzaWduQ2xhc3NlczogZnVuY3Rpb24oY29sdW1uX2RlZmluaXRpb25zKSB7XHJcbiAgICAgIHJldHVybiBhc3NpZ25Db2x1bW5DbGFzc2VzKGNvbHVtbl9kZWZpbml0aW9ucyk7XHJcbiAgfSxcclxuICBoaWRlIDogZnVuY3Rpb24oY29sTmFtZSkge1xyXG4gICAgICBoaWRlQ29sdW1uQnlUaXRsZShjb2xOYW1lKTtcclxuICB9LFxyXG4gIHNob3cgOiBmdW5jdGlvbihjb2xOYW1lKSB7XHJcbiAgICAgIHNob3dDb2x1bW5CeVRpdGxlKGNvbE5hbWUpO1xyXG4gIH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IENvbHVtbjsiLCJpbXBvcnQgRnVuZExvb2t1cFRhYmxlIGZyb20gJy4uLy4uLy4uL21vZGVscy9mdW5kX2xvb2t1cF90YWJsZS5qcyc7XHJcbmltcG9ydCBDdXJyZW50RnVuZCBmcm9tICcuLi8uLi8uLi9tb2RlbHMvY3VycmVudF9mdW5kLmpzJ1xyXG5pbXBvcnQgQ3VycmVudFBhZ2UgZnJvbSAnLi4vLi4vLi4vbW9kZWxzL2N1cnJlbnRfcGFnZS5qcydcclxuaW1wb3J0IFRhYmxlIGZyb20gJy4uL3RhYmxlLmpzJztcclxuXHJcbmZ1bmN0aW9uIGZpbGxUYWJsZShkYXRhKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIGNvbnN0IHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuICAgICAgICBjb25zdCB0aGVhZCA9IHRhYmxlLnF1ZXJ5U2VsZWN0b3IoJ3RoZWFkJyk7XHJcbiAgICAgICAgY29uc3QgdGJvZHkgPSB0YWJsZS5xdWVyeVNlbGVjdG9yKCd0Ym9keScpO1xyXG5cclxuICAgICAgICAvLyBjbGVhciBleGlzdGluZyBkYXRhXHJcbiAgICAgICAgdGhlYWQuaW5uZXJIVE1MID0gJyc7XHJcbiAgICAgICAgdGJvZHkuaW5uZXJIVE1MID0gJyc7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSB0YWJsZSBoZWFkZXIgcm93XHJcbiAgICAgICAgY29uc3QgaGVhZGVyUm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndHInKTtcclxuICAgICAgICBPYmplY3Qua2V5cyhkYXRhWzBdKS5mb3JFYWNoKGtleSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGhlYWRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RoJyk7XHJcbiAgICAgICAgICAgIGhlYWRlci50ZXh0Q29udGVudCA9IGtleTtcclxuICAgICAgICAgICAgaGVhZGVyUm93LmFwcGVuZENoaWxkKGhlYWRlcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhlYWQuYXBwZW5kQ2hpbGQoaGVhZGVyUm93KTtcclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlIHRhYmxlIGJvZHkgcm93c1xyXG4gICAgICAgIGRhdGEuZm9yRWFjaChpdGVtID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgcm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndHInKTtcclxuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyhpdGVtKS5mb3JFYWNoKHZhbCA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjZWxsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGQnKTtcclxuICAgICAgICAgICAgICAgIGNlbGwuaW5uZXJIVE1MID0gdmFsO1xyXG4gICAgICAgICAgICAgICAgcm93LmFwcGVuZENoaWxkKGNlbGwpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGJvZHkuYXBwZW5kQ2hpbGQocm93KTtcclxuICAgICAgICB9KTtcclxuICAgIH0gY2F0Y2goZXJyb3IpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdObyB0YWJsZSBzYXZlZCBpbiBsb2NhbFN0b3JhZ2U6JywgZXJyb3IpO1xyXG4gICAgfVxyXG59XHJcblxyXG5hc3luYyBmdW5jdGlvbiBsb2FkRnJvbVN0b3JhZ2UoKXtcclxuICAgIC8vIGxvb2sgdXAgdGFibGUgbmFtZSBpbiBzdG9yYWdlXHJcbiAgICBpZiAoQ3VycmVudEZ1bmQubnVtYmVyKCkpe1xyXG4gICAgICAgIHZhciBrZXkgPSBgJHtDdXJyZW50UGFnZS5sb2FkKCl9XyR7Q3VycmVudEZ1bmQubnVtYmVyKCl9YDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdmFyIGtleSA9IEN1cnJlbnRQYWdlLmxvYWQoKTtcclxuICAgIH1cclxuICAgIC8vIGxvYWQgZnJvbSBsb2NhbCBzdG9yYWdlXHJcbiAgICBjb25zdCBkYXRhID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oa2V5KTtcclxuICAgIC8vIGlmIG5vdGhpbmcgaW4gc3RvcmFnZSwgcmV0dXJuIGEgemVyb1xyXG4gICAgaWYgKCAhZGF0YSApIHtcclxuICAgICAgICByZXR1cm4gMDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gb3RoZXJ3aXNlLCBmaWxsIHRhYmxlIGluIEhUTUwgYW5kIHJldHVybiBzdWNjZXNzICgxKVxyXG4gICAgICAgIFRhYmxlLnNob3coKTtcclxuICAgICAgICBmaWxsVGFibGUoYXdhaXQgSlNPTi5wYXJzZShkYXRhKSk7XHJcbiAgICAgICAgcmV0dXJuIDE7XHJcbiAgICB9XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBsb2FkRnVuZHMoKXtcclxuICAgIC8vIGdldCBsaXN0IG9mIGZ1bmRzIGZyb20gc3RvcmFnZVxyXG4gICAgY29uc3QgZnVuZERpY3QgPSBGdW5kTG9va3VwVGFibGUucmV0cmlldmUoKTtcclxuICAgIC8vIGJ1aWxkIG91dCBkYXRhIGluIGNvcnJlY3QgZm9ybWF0XHJcbiAgICBjb25zdCByZXQgPSBbXTtcclxuICAgIE9iamVjdC5rZXlzKGZ1bmREaWN0KS5mb3JFYWNoKGtleSA9PiB7XHJcbiAgICAgICAgLy8gZGV0ZXJtaW5lIGlmIHRoZSBmdW5kIGhhcyBhbHJlYWR5IGJlZW4gZWRpdGVkXHJcbiAgICAgICAgaWYgKGZ1bmREaWN0W2tleV1bJ3ZpZXdlZCddKXtcclxuICAgICAgICAgICAgLy8gdG9kbzogYWRkIGEgY2hlY2ttYXJrIGhlcmVcclxuICAgICAgICAgICAgcmV0LnB1c2goeydGdW5kJyA6ICBgPHNwYW4gY2xhc3MgPSAndmlld2VkLWZ1bmQnPiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtY2hlY2tcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7ZnVuZERpY3Rba2V5XVsnbmFtZSddfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5gfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0LnB1c2goeydGdW5kJyA6IGA8c3BhbiBjbGFzcyA9ICd1bnZpZXdlZC1mdW5kJz4gXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7ZnVuZERpY3Rba2V5XVsnbmFtZSddfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5gfSk7ICAgXHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICBmaWxsVGFibGUocmV0KTtcclxufVxyXG5cclxuXHJcbmZ1bmN0aW9uIGdldENvbHVtbkluZGV4QnlDbGFzcyh0Ym9keSwgY2xhc3NOYW1lKSB7XHJcbiAgY29uc3QgZmlyc3RSb3cgPSB0Ym9keS5yb3dzWzBdO1xyXG4gIGlmICghZmlyc3RSb3cpIHJldHVybiAtMTsgLy8gUmV0dXJuIC0xIGlmIHRoZXJlJ3Mgbm8gcm93IHRvIGV4YW1pbmVcclxuICBmb3IgKGxldCBjZWxsSW5kZXggPSAwOyBjZWxsSW5kZXggPCBmaXJzdFJvdy5jZWxscy5sZW5ndGg7IGNlbGxJbmRleCsrKSB7XHJcbiAgICAgIGlmIChmaXJzdFJvdy5jZWxsc1tjZWxsSW5kZXhdLmNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpKSB7XHJcbiAgICAgICAgICByZXR1cm4gY2VsbEluZGV4O1xyXG4gICAgICB9XHJcbiAgfVxyXG4gIHJldHVybiAtMTsgLy8gUmV0dXJuIC0xIGlmIGNsYXNzIG5hbWUgbm90IGZvdW5kXHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNvcnQocHJpbWFyeUNsYXNzLCBzZWNvbmRhcnlDbGFzcykge1xyXG4gIGNvbnN0IHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuICBjb25zdCB0Ym9keSA9IHRhYmxlLnRCb2RpZXNbMF07XHJcbiAgY29uc3Qgcm93cyA9IEFycmF5LmZyb20odGJvZHkucm93cyk7XHJcblxyXG4gIC8vIEdldCB0aGUgY29sdW1uIGluZGljZXMgYnkgY2xhc3MgbmFtZVxyXG4gIGNvbnN0IHByaW1hcnlDb2xJbmRleCA9IGdldENvbHVtbkluZGV4QnlDbGFzcyh0Ym9keSwgcHJpbWFyeUNsYXNzKTtcclxuICBjb25zdCBzZWNvbmRhcnlDb2xJbmRleCA9IGdldENvbHVtbkluZGV4QnlDbGFzcyh0Ym9keSwgc2Vjb25kYXJ5Q2xhc3MpO1xyXG5cclxuICAvLyBleGl0IGlmIGNsYXNzZXMgZG9uJ3QgZXhpc3RcclxuICBpZiAocHJpbWFyeUNvbEluZGV4ID09PSAtMSApIHtcclxuICAgICAgY29uc29sZS5lcnJvcihgQ29sdW1uIGNsYXNzICR7Y2xhc3NBfSBub3QgZm91bmQgaW4gdGFibGVgKTtcclxuICAgICAgcmV0dXJuOyBcclxuICB9IGVsc2UgaWYgKHNlY29uZGFyeUNvbEluZGV4ID09PSAtMSkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBDb2x1bW4gY2xhc3MgJHtjbGFzc0J9IG5vdCBmb3VuZCBpbiB0YWJsZWApO1xyXG4gICAgICByZXR1cm47IFxyXG4gIH1cclxuXHJcbiAgLy8gU29ydCB0aGUgcm93cyBiYXNlZCBvbiB0aGUgdGV4dCBjb250ZW50IG9mIHRoZSBjZWxsc1xyXG4gIHJvd3Muc29ydCgocm93QSwgcm93QikgPT4ge1xyXG4gICAgICAvLyBQcmltYXJ5IGNvbHVtbiBjb21wYXJpc29uXHJcbiAgICAgIGNvbnN0IHByaW1hcnlBID0gdW5mb3JtYXRDdXJyZW5jeShyb3dBLmNlbGxzW3ByaW1hcnlDb2xJbmRleF0udGV4dENvbnRlbnQpO1xyXG4gICAgICBjb25zdCBwcmltYXJ5QiA9IHVuZm9ybWF0Q3VycmVuY3kocm93Qi5jZWxsc1twcmltYXJ5Q29sSW5kZXhdLnRleHRDb250ZW50KTtcclxuXHJcbiAgICAgIGlmIChwcmltYXJ5QSA8IHByaW1hcnlCKSByZXR1cm4gLTE7XHJcbiAgICAgIGlmIChwcmltYXJ5QSA+IHByaW1hcnlCKSByZXR1cm4gMTtcclxuXHJcbiAgICAgIC8vIFNlY29uZGFyeSBjb2x1bW4gY29tcGFyaXNvbiAoaWYgcHJpbWFyeSBpcyBlcXVhbClcclxuICAgICAgY29uc3Qgc2Vjb25kYXJ5QSA9IHVuZm9ybWF0Q3VycmVuY3kocm93QS5jZWxsc1tzZWNvbmRhcnlDb2xJbmRleF0udGV4dENvbnRlbnQpO1xyXG4gICAgICBjb25zdCBzZWNvbmRhcnlCID0gdW5mb3JtYXRDdXJyZW5jeShyb3dCLmNlbGxzW3NlY29uZGFyeUNvbEluZGV4XS50ZXh0Q29udGVudCk7XHJcblxyXG4gICAgICBpZiAoc2Vjb25kYXJ5QSA8IHNlY29uZGFyeUIpIHJldHVybiAtMTtcclxuICAgICAgaWYgKHNlY29uZGFyeUEgPiBzZWNvbmRhcnlCKSByZXR1cm4gMTtcclxuXHJcbiAgICAgIC8vIElmIGJvdGggY29sdW1ucyBhcmUgZXF1YWxcclxuICAgICAgcmV0dXJuIDA7XHJcbiAgfSk7XHJcblxyXG4gIC8vIFJlYXR0YWNoIHNvcnRlZCByb3dzIHRvIHRoZSB0YWJsZSBib2R5XHJcbiAgcm93cy5mb3JFYWNoKChyb3cpID0+IHRib2R5LmFwcGVuZENoaWxkKHJvdykpO1xyXG59XHJcblxyXG5cclxuZXhwb3J0IGNvbnN0IERhdGEgPSB7XHJcbiAgICBsb2FkIDogbG9hZEZyb21TdG9yYWdlLFxyXG4gICAgbG9hZEZ1bmRzIDogbG9hZEZ1bmRzLFxyXG4gICAgc29ydCA6IGZ1bmN0aW9uKGNvbEEsIGNvbEIpIHsgc29ydChjb2xBLCBjb2xCKSB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IERhdGE7IiwiXHJcblxyXG5pbXBvcnQgeyBTSEVFVFMsIFRBUkdFVF9DRUxMX0FERFJFU1MgfSBmcm9tICcuLi9jb25zdGFudHMvJztcclxuaW1wb3J0IEZ1bmRMb29rdXBUYWJsZSBmcm9tICcuLi9tb2RlbHMvZnVuZF9sb29rdXBfdGFibGUuanMnO1xyXG5pbXBvcnQgeyByZW1vdmVOZXdMaW5lcyB9IGZyb20gJy4vY29tbW9uX3V0aWxzLmpzJztcclxuaW1wb3J0IEJhc2VsaW5lIGZyb20gJy4uL21vZGVscy9iYXNlbGluZS5qcyc7XHJcbmltcG9ydCBTZXJ2aWNlcyBmcm9tICcuLi9tb2RlbHMvc2VydmljZXMuanMnO1xyXG5cclxuZnVuY3Rpb24gZGVsZXRlVG9wUm93c1VudGlsRnVsbERhdGEoZGF0YSkge1xyXG4gICAgLy8gZnVuY3Rpb24gdG8gdHJ5IHRvIGZpbmQgdGhlIHRvcCBvZiB0aGUgdXNhYmxlIGRhdGFcclxuICAgIGxldCBmdWxsRGF0YVJvd0ZvdW5kID0gZmFsc2U7XHJcblxyXG4gICAgd2hpbGUgKCFmdWxsRGF0YVJvd0ZvdW5kICYmIGRhdGEubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGNvbnN0IHJvdyA9IGRhdGFbMF07IC8vIEdldCB0aGUgdG9wIHJvd1xyXG4gICAgICAgIGxldCBoYXNBbGxEYXRhID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgZm9yIChjb25zdCBjZWxsIG9mIHJvdykge1xyXG4gICAgICAgICAgICBpZiAoY2VsbCA9PSBudWxsIHx8IGNlbGwgPT09ICcnKSB7XHJcbiAgICAgICAgICAgICAgICBoYXNBbGxEYXRhID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGhhc0FsbERhdGEgJiYgcm93Lmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgZnVsbERhdGFSb3dGb3VuZCA9IHRydWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gZGVsZXRlIHRoZSB0b3Agcm93IGlmIGl0J3Mgbm90IHRoZSBoZWFkZXIgcm93XHJcbiAgICAgICAgICAgIGRhdGEuc2hpZnQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGRhdGE7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBwcm9jZXNzV29ya2Jvb2soYXJyYXlCdWZmZXIpIHtcclxuICAgIGNvbnN0IHdvcmtib29rID0gWExTWC5yZWFkKGFycmF5QnVmZmVyLCB7IHR5cGU6ICdhcnJheScgfSk7XHJcbiAgICB3b3JrYm9vay5TaGVldE5hbWVzLmZvckVhY2goc2hlZXROYW1lID0+IHtcclxuICAgICAgICAvLyBvbmx5IGNvbnZlcnQgc2hlZXRzIHdlIG5lZWRcclxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoU0hFRVRTKS5pbmNsdWRlcyhzaGVldE5hbWUpKSB7XHJcbiAgICAgICAgICAgICAvLyByZWFkIGluIHNoZWV0c1xyXG4gICAgICAgICAgICBjb25zdCBzaGVldCA9IHdvcmtib29rLlNoZWV0c1tzaGVldE5hbWVdO1xyXG4gICAgICAgICAgICBjb25zdCByYXdEYXRhID0gWExTWC51dGlscy5zaGVldF90b19qc29uKHNoZWV0LCB7IGhlYWRlcjogMSwgZGVmdmFsOiAnJyB9KTtcclxuXHJcbiAgICAgICAgICAgIC8vIENsZWFuIHRoZSBkYXRhIGJ5IHJlbW92aW5nIHRvcCByb3dzIHdpdGggaW5jb21wbGV0ZSBkYXRhXHJcbiAgICAgICAgICAgIGNvbnN0IGRhdGFSb3dzID0gZGVsZXRlVG9wUm93c1VudGlsRnVsbERhdGEocmF3RGF0YSk7XHJcblxyXG4gICAgICAgICAgICAvLyBnZXQgbmV3IGhlYWRlcnNcclxuICAgICAgICAgICAgY29uc3QgaGVhZGVycyA9IGRhdGFSb3dzWzBdO1xyXG5cclxuICAgICAgICAgICAgLy8gaXNvbGF0ZSBGdW5kIGNvbHVtbiB0byBzcGxpdCBkYXRhXHJcbiAgICAgICAgICAgIGNvbnN0IGZ1bmRJbmRleCA9IGhlYWRlcnMuaW5kZXhPZignRnVuZCcpO1xyXG4gICAgICAgICAgICBpZiAoZnVuZEluZGV4ID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgTm8gJ0Z1bmQnIGNvbHVtbiBmb3VuZCBpbiBzaGVldCAke3NoZWV0TmFtZX1gKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gU2F2ZSBhIGRpY3Rpb25hcnkgb2YgZGF0YSBmb3IgZWFjaCBmdW5kIGZvciBlYWNoIHNoZWV0XHJcbiAgICAgICAgICAgIGNvbnN0IGZ1bmREYXRhID0ge307XHJcblxyXG4gICAgICAgICAgICBkYXRhUm93cy5mb3JFYWNoKHJvdyA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBmdW5kID0gcm93W2Z1bmRJbmRleF07XHJcbiAgICAgICAgICAgICAgICBpZihmdW5kICYmIGZ1bmQgIT0gXCJGdW5kXCIpe1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZnVuZERhdGFbZnVuZF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnVuZERhdGFbZnVuZF0gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgcm93RGF0YSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnMuZm9yRWFjaCgoaGVhZGVyLCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByb3dEYXRhW3JlbW92ZU5ld0xpbmVzKGhlYWRlcildID0gcm93W2luZGV4XTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICBmdW5kRGF0YVtmdW5kXS5wdXNoKHJvd0RhdGEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIC8vIHNhdmUgZnVuZCBudW1iZXIgYW5kIG5hbWUgYXMgd2UgZ28gYWxvbmdcclxuICAgICAgICAgICAgRnVuZExvb2t1cFRhYmxlLnVwZGF0ZShmdW5kRGF0YSk7ICAgICAgICAgICAgXHJcblxyXG4gICAgICAgICAgICBPYmplY3Qua2V5cyhmdW5kRGF0YSkuZm9yRWFjaChmdW5kID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IGAke1NIRUVUU1tzaGVldE5hbWVdfV8ke2Z1bmR9YDtcclxuICAgICAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkoZnVuZERhdGFbZnVuZF0pKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBCdXQgYWxzbyBzYXZlIHRoZSBwb3NzaWJsZSBzZXJ2aWNlc1xyXG4gICAgICAgIGVsc2UgaWYgKHNoZWV0TmFtZSA9PSAnRHJvcC1Eb3duIE1lbnVzJyl7XHJcbiAgICAgICAgICAgIGNvbnN0IHNoZWV0ID0gd29ya2Jvb2suU2hlZXRzW3NoZWV0TmFtZV07XHJcbiAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIHNoZWV0IHRvIEpTT04gdG8gZWFzaWx5IG1hbmlwdWxhdGUgZGF0YVxyXG4gICAgICAgICAgICBjb25zdCBzaGVldERhdGEgPSBYTFNYLnV0aWxzLnNoZWV0X3RvX2pzb24oc2hlZXQsIHsgaGVhZGVyOiAxIH0pO1xyXG5cclxuICAgICAgICAgICAgLy8gTG9jYXRlIHRoZSBcInNlcnZpY2VzXCIgY29sdW1uIGhlYWRlciBpbiByb3cgMFxyXG4gICAgICAgICAgICBjb25zdCBoZWFkZXJSb3cgPSBzaGVldERhdGFbMF07XHJcbiAgICAgICAgICAgIGNvbnN0IHNlcnZpY2VzSW5kZXggPSBoZWFkZXJSb3cuaW5kZXhPZignU2VydmljZXMnKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzZXJ2aWNlc0luZGV4ID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignSGVhZGVyIFwiU2VydmljZXNcIiBub3QgZm91bmQnKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgZGF0YSBmcm9tIHRoZSBcInNlcnZpY2VzXCIgY29sdW1uIChleGNsdWRpbmcgdGhlIGhlYWRlciByb3cpXHJcbiAgICAgICAgICAgICAgICBjb25zdCBzZXJ2aWNlc0NvbHVtbiA9IHNoZWV0RGF0YS5zbGljZSgxKS5tYXAocm93ID0+IHJvd1tzZXJ2aWNlc0luZGV4XSk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjbGVhbmVkU2VydmljZXNDb2x1bW4gPSBzZXJ2aWNlc0NvbHVtbi5maWx0ZXIodmFsdWUgPT4gdmFsdWUgIT0gbnVsbCk7XHJcbiAgICAgICAgICAgICAgICAvLyBzYXZlIHRoZSBkYXRhXHJcbiAgICAgICAgICAgICAgICBTZXJ2aWNlcy5zYXZlKGNsZWFuZWRTZXJ2aWNlc0NvbHVtbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGVsc2UgaWYoc2hlZXROYW1lID09ICdEZXB0IFN1bW1hcnknKXtcclxuICAgICAgICAgICAgY29uc3Qgc2hlZXQgPSB3b3JrYm9vay5TaGVldHNbc2hlZXROYW1lXTtcclxuICAgICAgICAgICAgLy8gZ2V0IGFuZCBzYXZlIFRBUkdFVCBmb3IgZ2VuZXJhbCBmdW5kXHJcbiAgICAgICAgICAgIGlmKHNoZWV0W1RBUkdFVF9DRUxMX0FERFJFU1NdKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjZWxsVmFsdWUgPSBzaGVldFtUQVJHRVRfQ0VMTF9BRERSRVNTXS52OyAvLyBBY2Nlc3MgdGhlIGNlbGwgdmFsdWVcclxuICAgICAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCd0YXJnZXQnLCBjZWxsVmFsdWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgQ2VsbCAke1RBUkdFVF9DRUxMX0FERFJFU1N9IG5vdCBmb3VuZCBpbiBzaGVldCAke3NoZWV0TmFtZX1gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnNvbGUubG9nKCdhbGwgZXhjZWwgZGF0YSBzYXZlZCcpO1xyXG59XHJcblxyXG4vLyBVdGlsaXR5IGZ1bmN0aW9uIHRvIGFwcGVuZCBhIHNoZWV0IHRvIHRoZSB3b3JrYm9vayBpZiBkYXRhIGlzIHByZXNlbnRcclxuZnVuY3Rpb24gYXBwZW5kU2hlZXRUb1dvcmtib29rKHdvcmtib29rLCBkYXRhLCBzaGVldE5hbWUpIHtcclxuICAgIGlmIChkYXRhLmxlbmd0aCA+IDApIHtcclxuICAgICAgICBjb25zdCBzaGVldCA9IFhMU1gudXRpbHMuanNvbl90b19zaGVldChkYXRhKTtcclxuICAgICAgICBYTFNYLnV0aWxzLmJvb2tfYXBwZW5kX3NoZWV0KHdvcmtib29rLCBzaGVldCwgc2hlZXROYW1lKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRvd25sb2FkWExTWCgpIHtcclxuICAgIGNvbnN0IGJhc2VsaW5lID0gbmV3IEJhc2VsaW5lKCk7XHJcbiAgICBjb25zdCB3b3JrYm9vayA9IFhMU1gudXRpbHMuYm9va19uZXcoKTsgLy8gQ3JlYXRlIGEgbmV3IHdvcmtib29rXHJcblxyXG4gICAgY29uc3QgZGF0YU1hcCA9IHtcclxuICAgICAgICBQZXJzb25uZWw6ICdwZXJzb25uZWwnLFxyXG4gICAgICAgIE92ZXJ0aW1lOiAnb3ZlcnRpbWUnLFxyXG4gICAgICAgIE5vblBlcnNvbm5lbDogJ25vbnBlcnNvbm5lbCcsXHJcbiAgICAgICAgUmV2ZW51ZTogJ3JldmVudWUnXHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IHNoZWV0RGF0YSA9IHtcclxuICAgICAgICBQZXJzb25uZWw6IFtdLFxyXG4gICAgICAgIE92ZXJ0aW1lOiBbXSxcclxuICAgICAgICBOb25QZXJzb25uZWw6IFtdLFxyXG4gICAgICAgIFJldmVudWU6IFtdXHJcbiAgICB9O1xyXG5cclxuICAgIGJhc2VsaW5lLmZ1bmRzLmZvckVhY2goZnVuZCA9PiB7XHJcbiAgICAgICAgT2JqZWN0LmtleXMoZGF0YU1hcCkuZm9yRWFjaChzaGVldE5hbWUgPT4ge1xyXG4gICAgICAgICAgICBpZiAoZnVuZFtkYXRhTWFwW3NoZWV0TmFtZV1dICYmIGZ1bmRbZGF0YU1hcFtzaGVldE5hbWVdXS50YWJsZSkge1xyXG4gICAgICAgICAgICAgICAgc2hlZXREYXRhW3NoZWV0TmFtZV0ucHVzaCguLi5mdW5kW2RhdGFNYXBbc2hlZXROYW1lXV0udGFibGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBPYmplY3Qua2V5cyhzaGVldERhdGEpLmZvckVhY2goc2hlZXROYW1lID0+IHtcclxuICAgICAgICBhcHBlbmRTaGVldFRvV29ya2Jvb2sod29ya2Jvb2ssIHNoZWV0RGF0YVtzaGVldE5hbWVdLCBzaGVldE5hbWUpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gR2VuZXJhdGUgYSBkb3dubG9hZGFibGUgZmlsZVxyXG4gICAgY29uc3Qgd2JvdXQgPSBYTFNYLndyaXRlKHdvcmtib29rLCB7IGJvb2tUeXBlOiAneGxzeCcsIHR5cGU6ICdhcnJheScgfSk7XHJcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3dib3V0XSwgeyB0eXBlOiAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJyB9KTtcclxuXHJcbiAgICAvLyBDcmVhdGUgYSBsaW5rIGFuZCB0cmlnZ2VyIHRoZSBkb3dubG9hZFxyXG4gICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xyXG4gICAgbGluay5ocmVmID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcclxuICAgIGxpbmsuZG93bmxvYWQgPSBcIkZpbGxlZF9EZXRhaWxfU2hlZXQueGxzeFwiO1xyXG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChsaW5rKTtcclxuICAgIGxpbmsuY2xpY2soKTtcclxuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBleGNlbFNlcmlhbERhdGVUb0pTRGF0ZShzZXJpYWwpIHtcclxuXHJcbiAgICBpZiAoIXNlcmlhbCkgeyByZXR1cm4gbnVsbCB9O1xyXG4gICAgLy8gRXhjZWwgY29uc2lkZXJzIDE5MDAtMDEtMDEgYXMgZGF5IDEsIGJ1dCBKYXZhU2NyaXB0J3MgRGF0ZSBjb25zaWRlcnNcclxuICAgIC8vIDE5NzAtMDEtMDEgYXMgZGF5IDAuIFRoZXJlZm9yZSwgd2UgY2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzXHJcbiAgICAvLyBiZXR3ZWVuIDE5MDAtMDEtMDEgYW5kIDE5NzAtMDEtMDEuXHJcbiAgICBjb25zdCBleGNlbEVwb2NoID0gbmV3IERhdGUoRGF0ZS5VVEMoMTg5OSwgMTEsIDMwKSk7IC8vIEphdmFTY3JpcHQgQ29uc2lkZXIgRGVjZW1iZXIgbW9udGggYXMgJzExJ1xyXG4gICAgXHJcbiAgICAvLyBDYWxjdWxhdGUgdGhlIEpTIGRhdGUgYnkgYWRkaW5nIHNlcmlhbCBkYXlzIHRvIHRoZSBlcG9jaCBkYXRlXHJcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoZXhjZWxFcG9jaC5nZXRUaW1lKCkgKyAoc2VyaWFsICogMjQgKiA2MCAqIDYwICogMTAwMCkpO1xyXG4gICAgXHJcbiAgICAvLyBTZXQgdGhlIHRpbWUgcGFydCB0byB6ZXJvIChtaWRuaWdodClcclxuICAgIGRhdGUuc2V0VVRDSG91cnMoMCwgMCwgMCwgMCk7XHJcbiAgICBcclxuICAgIC8vIFJldHVybiB0aGUgZGF0ZSBwYXJ0IG9mIHRoZSBJU08gc3RyaW5nXHJcbiAgICByZXR1cm4gZGF0ZS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF07XHJcbn1cclxuIiwiXG4gICAgICBpbXBvcnQgQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCI7XG4gICAgICBpbXBvcnQgZG9tQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRGbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanNcIjtcbiAgICAgIGltcG9ydCBzZXRBdHRyaWJ1dGVzIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0U3R5bGVFbGVtZW50IGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzXCI7XG4gICAgICBpbXBvcnQgc3R5bGVUYWdUcmFuc2Zvcm1GbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlVGFnVHJhbnNmb3JtLmpzXCI7XG4gICAgICBpbXBvcnQgY29udGVudCwgKiBhcyBuYW1lZEV4cG9ydCBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3Rvb2x0aXAuY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vdG9vbHRpcC5jc3NcIjtcbiAgICAgICBleHBvcnQgZGVmYXVsdCBjb250ZW50ICYmIGNvbnRlbnQubG9jYWxzID8gY29udGVudC5sb2NhbHMgOiB1bmRlZmluZWQ7XG4iLCJpbXBvcnQgeyBGSVNDQUxfWUVBUiB9IGZyb20gJy4uLy4uL2NvbnN0YW50cy8nO1xyXG5pbXBvcnQgQ2VsbCBmcm9tICcuLi90YWJsZS9zdWJjb21wb25lbnRzL2NlbGxzJztcclxuaW1wb3J0IHsgZm9ybWF0Q3VycmVuY3kgfSBmcm9tICcuLi8uLi91dGlscy9jb21tb25fdXRpbHMnO1xyXG5pbXBvcnQgQ3VycmVudFBhZ2UgZnJvbSAnLi4vLi4vbW9kZWxzL2N1cnJlbnRfcGFnZSc7XHJcbmltcG9ydCB7IGV4Y2VsU2VyaWFsRGF0ZVRvSlNEYXRlIH0gZnJvbSAnLi4vLi4vdXRpbHMvWExTWF9oYW5kbGVycyc7XHJcblxyXG5pbXBvcnQgJy4vdG9vbHRpcC5jc3MnXHJcblxyXG5mdW5jdGlvbiBoaWRlVG9vbHRpcCgpIHtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0b29sdGlwJykuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzaG93VG9vbHRpcCgpIHtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0b29sdGlwJykuc3R5bGUudmlzaWJpbGl0eSA9ICd2aXNpYmxlJztcclxufVxyXG5cclxuZnVuY3Rpb24gZWRpdFRvb2x0aXBUZXh0KG5ld1RleHQpe1xyXG4gICAgLy8gZWRpdCB0ZXh0IHRvIGRpc3BsYXkgaW5zaWRlIHRvb2x0aXBcclxuICAgIGNvbnN0IHRvb2x0aXAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndG9vbHRpcCcpO1xyXG4gICAgdG9vbHRpcC5pbm5lckhUTUwgPSBuZXdUZXh0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBzaG93QWNjb3VudFN0cmluZyhyb3cpe1xyXG4gICAgY29uc3QgYXBwcm9wID0gQ2VsbC5nZXRUZXh0KHJvdywgJ2FwcHJvcC1uYW1lJyk7XHJcbiAgICBjb25zdCBjYyA9ICBDZWxsLmdldFRleHQocm93LCAnY2MtbmFtZScpO1xyXG4gICAgY29uc3Qgb2JqID0gIENlbGwuZ2V0VGV4dChyb3csICdvYmplY3QtbmFtZScpO1xyXG4gICAgY29uc3QgZnVuZCA9IENlbGwuZ2V0VGV4dChyb3csICdmdW5kLW5hbWUnKTtcclxuICAgIHZhciBtZXNzYWdlID0gXHJcbiAgICAgICAgYDxzdHJvbmc+RnVuZDwvc3Ryb25nPjogJHtmdW5kfTxicj5cclxuICAgICAgICA8c3Ryb25nPkFwcHJvcHJpYXRpb248L3N0cm9uZz46ICR7YXBwcm9wfTxicj5cclxuICAgICAgICA8c3Ryb25nPkNvc3QgQ2VudGVyPC9zdHJvbmc+OiAke2NjfWA7XHJcbiAgICBpZiAob2JqKSB7IG1lc3NhZ2UgKz0gYDxicj48c3Ryb25nPk9iamVjdDwvc3Ryb25nPjogJHtvYmp9YH1cclxuICAgIGVkaXRUb29sdGlwVGV4dChtZXNzYWdlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2hvd1NhbGFyeVByb2plY3Rpb24ocm93KXtcclxuICAgIGNvbnN0IGdlbmVyYWxfaW5jcmVhc2UgPSBDZWxsLmdldFRleHQocm93LCAnZ2VuZXJhbC1pbmNyZWFzZS1yYXRlJyk7XHJcbiAgICBjb25zdCBtZXJpdF9pbmNyZWFzZSA9ICBDZWxsLmdldFRleHQocm93LCAnbWVyaXQtaW5jcmVhc2UtcmF0ZScpO1xyXG4gICAgY29uc3QgY3VycmVudF9zYWxhcnkgPSBDZWxsLmdldFZhbHVlKHJvdywgJ2N1cnJlbnQtc2FsYXJ5Jyk7XHJcbiAgICBjb25zdCBwcm9qX3NhbGFyeSA9IENlbGwuZ2V0VmFsdWUocm93LCAnYXZnLXNhbGFyeScpO1xyXG4gICAgaWYgKGN1cnJlbnRfc2FsYXJ5KXtcclxuICAgICAgICB2YXIgbWVzc2FnZSA9IGBUaGUgYXZlcmFnZSBzYWxhcnkvd2FnZSBmb3IgdGhpcyBwb3NpdGlvbiB3YXMgXHJcbiAgICAgICAgICAgICR7Zm9ybWF0Q3VycmVuY3koY3VycmVudF9zYWxhcnkpfSBhcyBvZiBTZXB0ZW1iZXIgMjAke0ZJU0NBTF9ZRUFSLTJ9LiBcclxuICAgICAgICAgICAgR2l2ZW4gYSAke2dlbmVyYWxfaW5jcmVhc2UqMTAwfSUgZ2VuZXJhbCBpbmNyZWFzZSByYXRlIGFuZCBhICR7bWVyaXRfaW5jcmVhc2UqMTAwfSUgXHJcbiAgICAgICAgICAgIG1lcml0IGluY3JlYXNlLCB0aGUgRlkke0ZJU0NBTF9ZRUFSfSBwcm9qZWN0aW9uIGZvciB0aGlzIHBvc2l0aW9uJ3MgYXZlcmFnZSBcclxuICAgICAgICAgICAgYW5udWFsIHNhbGFyeS93YWdlIGlzICR7Zm9ybWF0Q3VycmVuY3kocHJval9zYWxhcnkpfS5gO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB2YXIgbWVzc2FnZSA9IGBUaGUgYXZlcmFnZSBzYWxhcnkvd2FnZSBmb3IgdGhpcyBwb3NpdGlvbiB3YXMgXHJcbiAgICAgICAgICAgIHVua25vd24gYXMgb2YgU2VwdGVtYmVyIDIwJHtGSVNDQUxfWUVBUi0yfSwgb3IgdGhlIHBvc2l0aW9uXHJcbiAgICAgICAgICAgIGRpZCBub3QgZXhpc3QuIFRoZSBGWSR7RklTQ0FMX1lFQVJ9IHByb2plY3Rpb24gZm9yIHRoaXMgcG9zaXRpb24ncyBcclxuICAgICAgICAgICAgYXZlcmFnZSBhbm51YWwgc2FsYXJ5L3dhZ2UgaXMgJHtmb3JtYXRDdXJyZW5jeShwcm9qX3NhbGFyeSl9LmBcclxuICAgIH1cclxuXHJcbiAgICBlZGl0VG9vbHRpcFRleHQobWVzc2FnZSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNob3dGaW5hbFBlcnNvbm5lbENvc3Qocm93KXtcclxuICAgIGNvbnN0IHByb2pfc2FsYXJ5ID0gQ2VsbC5nZXRWYWx1ZShyb3csICdhdmctc2FsYXJ5Jyk7XHJcbiAgICBjb25zdCBmdGVzID0gQ2VsbC5nZXRUZXh0KHJvdywgJ2Jhc2VsaW5lLWZ0ZXMnKTtcclxuICAgIGNvbnN0IGZyaW5nZSA9IHBhcnNlRmxvYXQoQ2VsbC5nZXRUZXh0KHJvdywgJ2ZyaW5nZScpKTtcclxuICAgIGNvbnN0IGF2Z19iZW5lZml0cyA9IHByb2pfc2FsYXJ5ICogZnJpbmdlO1xyXG4gICAgY29uc3QgbWVzc2FnZSA9IGBUaGUgdG90YWwgY29zdCBjYXB0dXJlcyAke2Z0ZXN9IHBvc2l0aW9uKHMpIGF0XHJcbiAgICAgICAgICAgICAgICAgICAgYW4gYW5udWFsIHNhbGFyeS93YWdlIG9mICR7Zm9ybWF0Q3VycmVuY3kocHJval9zYWxhcnkpfSwgXHJcbiAgICAgICAgICAgICAgICAgICAgcGx1cyBmcmluZ2UgYmVuZWZpdHMgdGhhdCBjb3N0ICR7Zm9ybWF0Q3VycmVuY3koYXZnX2JlbmVmaXRzKX0gXHJcbiAgICAgICAgICAgICAgICAgICAgcGVyIHBvc2l0aW9uIHBlciB5ZWFyLCBvbiBhdmVyYWdlLmBcclxuICAgIGVkaXRUb29sdGlwVGV4dChtZXNzYWdlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2hvd0ZJQ0Eocm93KXtcclxuICAgIGNvbnN0IGZpY2EgPSBwYXJzZUZsb2F0KENlbGwuZ2V0VGV4dChyb3csICdmaWNhJykpO1xyXG4gICAgY29uc3QgZmljYVBlcmNlbnRhZ2UgPSAoZmljYSAqIDEwMCkudG9GaXhlZCgyKTtcclxuICAgIGNvbnN0IG1lc3NhZ2UgPSBgVGhpcyB0b3RhbCBpcyBvdmVydGltZSAvIGhvbGlkYXkgLyBzaGlmdCBwcmVtaXVtIHBheSwgcGx1cyBGSUNBIChwYXlyb2xsIHRheCksIFxyXG4gICAgICAgICAgICAgICAgICAgICB3aGljaCBpcyAke2ZpY2FQZXJjZW50YWdlfSUgZm9yIHRoaXMgY29zdCBjZW50ZXIuYFxyXG4gICAgZWRpdFRvb2x0aXBUZXh0KG1lc3NhZ2UpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzaG93Q1BBKHJvdyl7XHJcbiAgICBjb25zdCBjcGEgPSBwYXJzZUZsb2F0KENlbGwuZ2V0VGV4dChyb3csICdjcGEnKSk7XHJcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9IENlbGwuZ2V0VGV4dChyb3csICdjcGEtZGVzY3JpcHRpb24nKTtcclxuICAgIGNvbnN0IHZlbmRvciA9IENlbGwuZ2V0VGV4dChyb3csICd2ZW5kb3InKTtcclxuICAgIHZhciBjb250cmFjdF9lbmQgPSBDZWxsLmdldFRleHQocm93LCAnY29udHJhY3QtZW5kJyk7XHJcbiAgICAvLyBjb252ZXJ0IHRvIG5vcm1hbCBkYXRlIGZvcm1hdCBmcm9tIGV4Y2VsIFxyXG4gICAgY29udHJhY3RfZW5kID0gZXhjZWxTZXJpYWxEYXRlVG9KU0RhdGUoY29udHJhY3RfZW5kKTtcclxuICAgIGNvbnN0IHJlbWFpbmluZyA9IENlbGwuZ2V0VmFsdWUocm93LCAncmVtYWluaW5nJyk7XHJcbiAgICBpZiAoY3BhKSB7XHJcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBgPHN0cm9uZz5DUEEgIyR7Y3BhfTwvc3Ryb25nPmA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHZhciBtZXNzYWdlID0gYE5vIENQQWA7XHJcbiAgICB9XHJcbiAgICBpZiAodmVuZG9yKSB7bWVzc2FnZSArPSBgPGJyPjxzdHJvbmc+VmVuZG9yPC9zdHJvbmc+OiAke3ZlbmRvcn1gfTtcclxuICAgIGlmIChkZXNjcmlwdGlvbikge21lc3NhZ2UgKz0gYDxicj48c3Ryb25nPkRlc2NyaXB0aW9uPC9zdHJvbmc+OiAke2Rlc2NyaXB0aW9ufWB9O1xyXG4gICAgaWYgKGNvbnRyYWN0X2VuZCkge21lc3NhZ2UgKz0gYDxicj48c3Ryb25nPkNvbnRyYWN0IEVuZCBEYXRlPC9zdHJvbmc+OiAke2NvbnRyYWN0X2VuZH1gfVxyXG4gICAgaWYgKHJlbWFpbmluZykge21lc3NhZ2UgKz0gYDxicj48c3Ryb25nPkFtb3VudCBSZW1haW5pbmcgb24gQ29udHJhY3Q8L3N0cm9uZz46ICR7Zm9ybWF0Q3VycmVuY3kocmVtYWluaW5nKX1gfVxyXG5cclxuICAgIGVkaXRUb29sdGlwVGV4dChtZXNzYWdlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gbGluayhlbGVtZW50LCBkaXNwbGF5Rm4pIHtcclxuXHJcbiAgICAvLyBhZGQgY2xhc3MgdG8gc2hvdyBjZWxsIHdpdGggYW4gdW5kZXJsaW5lLCBldGNcclxuICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgndG9vbHRpcC1jZWxsJyk7XHJcblxyXG4gICAgLy8gQ3JlYXRlIGFuZCBhcHBlbmQgKGRldGFpbClcclxuICAgIGNvbnN0IGRldGFpbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcclxuICAgIGRldGFpbC5jbGFzc0xpc3QuYWRkKCdkZXRhaWwnKTtcclxuICAgIGRldGFpbC50ZXh0Q29udGVudCA9ICcoZGV0YWlsKSc7XHJcbiAgICBlbGVtZW50LmFwcGVuZENoaWxkKGRldGFpbCk7XHJcblxyXG4gICAgLy8gYWRkIGV2ZW50IGxpc3RlbmVyIHRvIHNob3cgdG9vbHRpcCBvbiBtb3VzZW92ZXJcclxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICBjb25zdCByb3cgPSBldmVudC50YXJnZXQuY2xvc2VzdCgndHInKTtcclxuICAgICAgICBkaXNwbGF5Rm4ocm93KTtcclxuICAgICAgICBzaG93VG9vbHRpcCgpO1xyXG4gICAgfSk7XHJcbiAgICAvLyBhbmQgaGlkZSB3aGVuIG1vdXNlIG1vdmVzIG9mZlxyXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBoaWRlVG9vbHRpcCgpO1xyXG4gICAgfSk7XHJcbiAgICAvLyBVcGRhdGUgdG9vbHRpcCBwb3NpdGlvbiBvbiBtb3VzZSBtb3ZlXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIGNvbnN0IHRvb2x0aXAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndG9vbHRpcCcpO1xyXG4gICAgICAgIHRvb2x0aXAuc3R5bGUudG9wID0gKGV2ZW50LmNsaWVudFkgKyAxMCkgKyAncHgnO1xyXG4gICAgICAgIHRvb2x0aXAuc3R5bGUubGVmdCA9IChldmVudC5jbGllbnRYICsgMTApICsgJ3B4JztcclxuICAgIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBsaW5rQWNjb3VudFN0cmluZ0NvbCgpIHtcclxuICAgIC8vIGdldCBhbGwgcmVsZXZhbnQgY2VsbHNcclxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3RkLmFjY291bnQtc3RyaW5nJykuZm9yRWFjaCggKGNlbGwpID0+IHtcclxuICAgICAgICBsaW5rKGNlbGwsIHNob3dBY2NvdW50U3RyaW5nKTtcclxuICAgIH0pXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxpbmtTYWxhcnlDb2woKSB7XHJcbiAgICAvLyBnZXQgYWxsIHJlbGV2YW50IGNlbGxzXHJcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCd0ZC5hdmctc2FsYXJ5JykuZm9yRWFjaCggKGNlbGwpID0+IHtcclxuICAgICAgICBsaW5rKGNlbGwsIHNob3dTYWxhcnlQcm9qZWN0aW9uKTtcclxuICAgIH0pXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxpbmtUb3RhbFBlcnNvbm5lbENvc3RDb2woKSB7XHJcbiAgICAvLyBnZXQgYWxsIHJlbGV2YW50IGNlbGxzXHJcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCd0ZC50b3RhbC1iYXNlbGluZScpLmZvckVhY2goIChjZWxsKSA9PiB7XHJcbiAgICAgICAgbGluayhjZWxsLCBzaG93RmluYWxQZXJzb25uZWxDb3N0KTtcclxuICAgIH0pXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxpbmtUb3RhbE9UQ29sKCkge1xyXG4gICAgLy8gZ2V0IGFsbCByZWxldmFudCBjZWxsc1xyXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgndGQudG90YWwnKS5mb3JFYWNoKCAoY2VsbCkgPT4ge1xyXG4gICAgICAgIGxpbmsoY2VsbCwgc2hvd0ZJQ0EpO1xyXG4gICAgfSlcclxufVxyXG5cclxuZnVuY3Rpb24gbGlua0NQQUNvbCgpIHtcclxuICAgIC8vIGdldCBhbGwgcmVsZXZhbnQgY2VsbHNcclxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3RkLmNwYScpLmZvckVhY2goIChjZWxsKSA9PiB7XHJcbiAgICAgICAgbGluayhjZWxsLCBzaG93Q1BBKTtcclxuICAgIH0pXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBUb29sdGlwID0ge1xyXG5cclxuICAgIGhpZGUgOiBoaWRlVG9vbHRpcCxcclxuICAgIHNob3cgOiBzaG93VG9vbHRpcCxcclxuXHJcbiAgICBsaW5rQWxsIDogKCkgPT4ge1xyXG4gICAgICAgIGxpbmtBY2NvdW50U3RyaW5nQ29sKCk7XHJcbiAgICAgICAgc3dpdGNoKEN1cnJlbnRQYWdlLmxvYWQoKSl7XHJcbiAgICAgICAgICAgIGNhc2UgJ3BlcnNvbm5lbCcgOlxyXG4gICAgICAgICAgICAgICAgLy8gbGlua0FjY291bnRTdHJpbmdDb2woKTtcclxuICAgICAgICAgICAgICAgIGxpbmtTYWxhcnlDb2woKTtcclxuICAgICAgICAgICAgICAgIGxpbmtUb3RhbFBlcnNvbm5lbENvc3RDb2woKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlICdvdmVydGltZSc6XHJcbiAgICAgICAgICAgICAgICBsaW5rVG90YWxPVENvbCgpO1xyXG4gICAgICAgICAgICAgICAgLy8gbGlua0FjY291bnRTdHJpbmdDb2woKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlICdub25wZXJzb25uZWwnOlxyXG4gICAgICAgICAgICAgICAgLy8gbGlua0FjY291bnRTdHJpbmdDb2woKTtcclxuICAgICAgICAgICAgICAgIGxpbmtDUEFDb2woKTsgIFxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIC8vIGNhc2UgJ3JldmVudWUnOlxyXG4gICAgICAgICAgICAvLyAgICAgbGlua0FjY291bnRTdHJpbmdDb2woKTtcclxuICAgICAgICAgICAgLy8gICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAvLyBjYXNlICduZXctaW5pdHMnOlxyXG4gICAgICAgICAgICAvLyAgICAgbGlua0FjY291bnRTdHJpbmdDb2woKTtcclxuICAgICAgICAgICAgLy8gICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgdW5saW5rIDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgbGV0IGRldGFpbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZGV0YWlsJyk7XHJcbiAgICAgICAgZGV0YWlscy5mb3JFYWNoKCAoc3BhbikgPT4ge1xyXG4gICAgICAgICAgICBzcGFuLnJlbW92ZSgpO1xyXG4gICAgICAgIH0pXHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFRvb2x0aXAiLCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gZmV0Y2hKU09OKGpzb25GaWxlUGF0aCkge1xyXG4gIHJldHVybiBmZXRjaChqc29uRmlsZVBhdGgpXHJcbiAgICAudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05ldHdvcmsgcmVzcG9uc2Ugd2FzIG5vdCBvaycpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRUb0pTT04odGFibGUsIGNvbHNUb1JlbW92ZSA9IFtdKXtcclxuICAgIGNvbnN0IHJvd3MgPSB0YWJsZS5yb3dzO1xyXG4gICAgLy8gRXh0cmFjdCBoZWFkZXJzIGZyb20gdGhlIGZpcnN0IHJvd1xyXG4gICAgY29uc3QgaGVhZGVyUm93ID0gcm93c1swXS5jZWxscztcclxuICAgIGNvbnN0IGhlYWRlcnMgPSBbXTtcclxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaGVhZGVyUm93Lmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgaGVhZGVycy5wdXNoKGhlYWRlclJvd1tqXS5pbm5lclRleHQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGluaXRpYWxpemUgZGF0YVxyXG4gICAgdmFyIHRhYmxlRGF0YSA9IFtdO1xyXG5cclxuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgcm93cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IGNvbHMgPSByb3dzW2ldLmNlbGxzO1xyXG4gICAgICAgIGNvbnN0IHJvd0RhdGEgPSB7fTtcclxuICAgICAgICAgICAgaGVhZGVycy5mb3JFYWNoKChoZWFkZXIsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29sc1RvUmVtb3ZlLmluY2x1ZGVzKGhlYWRlcikpe1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbHNbaW5kZXhdLmNsYXNzTGlzdC5jb250YWlucygnY29zdCcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcm93RGF0YVtoZWFkZXJdID0gY29sc1tpbmRleF0uZ2V0QXR0cmlidXRlKCd2YWx1ZScpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByb3dEYXRhW2hlYWRlcl0gPSBjb2xzW2luZGV4XS5pbm5lclRleHQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIHRhYmxlRGF0YS5wdXNoKHJvd0RhdGEpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRhYmxlRGF0YSk7XHJcbn1cclxuXHJcblxyXG4gICIsImltcG9ydCAnLi90YWJsZS5jc3MnO1xyXG5cclxuaW1wb3J0IEJ1dHRvbnMgZnJvbSAnLi9zdWJjb21wb25lbnRzL2J1dHRvbnMuanMnXHJcbmltcG9ydCBDZWxsIGZyb20gJy4vc3ViY29tcG9uZW50cy9jZWxscy5qcydcclxuaW1wb3J0IENvbHVtbnMgZnJvbSAnLi9zdWJjb21wb25lbnRzL2NvbHVtbnMuanMnXHJcbmltcG9ydCBIZWFkZXIgZnJvbSAnLi9zdWJjb21wb25lbnRzL2hlYWRlcnMuanMnXHJcbmltcG9ydCBSb3dzIGZyb20gJy4vc3ViY29tcG9uZW50cy9yb3dzLmpzJ1xyXG5pbXBvcnQgRGF0YSBmcm9tICcuL3N1YmNvbXBvbmVudHMvZGF0YS5qcydcclxuaW1wb3J0IFRvb2x0aXAgZnJvbSAnLi4vdG9vbHRpcC90b29sdGlwLmpzJztcclxuaW1wb3J0IHsgY29udmVydFRvSlNPTiB9IGZyb20gXCIuLi8uLi91dGlscy9KU09OX2RhdGFfaGFuZGxlcnMuanNcIjtcclxuaW1wb3J0IFNpZGViYXIgZnJvbSAnLi4vc2lkZWJhci9zaWRlYmFyLmpzJztcclxuaW1wb3J0IEN1cnJlbnRGdW5kIGZyb20gJy4uLy4uL21vZGVscy9jdXJyZW50X2Z1bmQuanMnO1xyXG5pbXBvcnQgQ3VycmVudFBhZ2UgZnJvbSAnLi4vLi4vbW9kZWxzL2N1cnJlbnRfcGFnZS5qcyc7XHJcblxyXG5mdW5jdGlvbiBhZGp1c3RUYWJsZVdpZHRoKHdpZHRoX3BjdCl7XHJcbiAgICBjb25zdCB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYWluLXRhYmxlJyk7XHJcbiAgICB0YWJsZS5zdHlsZS53aWR0aCA9IHdpZHRoX3BjdDtcclxufVxyXG5cclxuZnVuY3Rpb24gc2hvd1RhYmxlKCl7XHJcbiAgICBjb25zdCB0YWJsZUNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50YWJsZS1jb250YWluZXInKTtcclxuICAgIHRhYmxlQ29udGFpbmVyLmlubmVySFRNTCA9IFRhYmxlLmh0bWw7XHJcbiAgICBjb25zdCB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYWluLXRhYmxlJyk7XHJcbiAgICB0YWJsZS5zdHlsZS5kaXNwbGF5ID0gJ3RhYmxlJztcclxufVxyXG5cclxuZnVuY3Rpb24gaGlkZVRhYmxlKCl7XHJcblxyXG4gICAgLy8gZGVsZXRlIHRhYmxlIG9iamVjdCBmcm9tIHRhYmxlIGNvbnRhaW5lclxyXG4gICAgY29uc3QgdGFibGVDb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcudGFibGUtY29udGFpbmVyJyk7XHJcbiAgICB0YWJsZUNvbnRhaW5lci5pbm5lckhUTUwgPSAnJztcclxuICAgIEJ1dHRvbnMuQWRkUm93LmhpZGUoKTtcclxuICAgIC8vIGRlbGV0ZSBzZWFyY2ggYmFyXHJcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2VhcmNoLWJhci1jb250YWluZXInKS5pbm5lckhUTUwgPSAnJztcclxufVxyXG5cclxuZnVuY3Rpb24gc2F2ZVRhYmxlRGF0YSgpIHtcclxuICAgIC8vIHJlbW92ZSB0aGUgZGV0YWlsIHRleHRcclxuICAgIFRvb2x0aXAudW5saW5rKCk7XHJcbiAgICAvLyBnZXQgdGFibGVcclxuICAgIHZhciB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYWluLXRhYmxlJyk7XHJcbiAgICAvLyBkZXRlcm1pbmUgc2F2ZV9hcyBuYW1lXHJcbiAgICBpZiAoQ3VycmVudEZ1bmQubnVtYmVyKCkpIHtcclxuICAgICAgICB2YXIgc2F2ZV9hcyA9IGAke0N1cnJlbnRQYWdlLmxvYWQoKX1fJHtDdXJyZW50RnVuZC5udW1iZXIoKX1gO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB2YXIgc2F2ZV9hcyA9IEN1cnJlbnRQYWdlLmxvYWQoKTtcclxuICAgIH1cclxuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKHNhdmVfYXMsIGNvbnZlcnRUb0pTT04odGFibGUsIFsnRWRpdCddKSk7XHJcbiAgICAvLyB1cGRhdGUgc2lkZWJhciB3aXRoIG5ldyBkYXRhXHJcbiAgICBTaWRlYmFyLnVwZGF0ZVRvdGFscygpO1xyXG4gICAgLy8gcmVsaW5rLCBkZXBlbmRpbmcgb24gcGFnZVxyXG4gICAgVG9vbHRpcC5saW5rQWxsKCk7XHJcbn1cclxuXHJcbmNvbnN0IFRhYmxlID0ge1xyXG4gICAgaHRtbCA6IGBcclxuICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1ib3JkZXJlZCBtdC0zIGRpc3BsYXlcIiBpZD1cIm1haW4tdGFibGVcIj5cclxuICAgICAgICAgICAgPHRoZWFkIGNsYXNzPVwidGhlYWQtZGFya1wiPjwvdGhlYWQ+XHJcbiAgICAgICAgICAgIDx0Ym9keT48L3Rib2R5PlxyXG4gICAgICAgIDwvdGFibGU+YCxcclxuICAgIEJ1dHRvbnMgOiBCdXR0b25zLFxyXG4gICAgQ2VsbCA6IENlbGwsXHJcbiAgICBDb2x1bW5zIDogQ29sdW1ucyxcclxuICAgIEhlYWRlciA6IEhlYWRlcixcclxuICAgIFJvd3MgOiBSb3dzLFxyXG4gICAgRGF0YSA6IERhdGEsXHJcbiAgICAvLyBmdW5jdGlvbnNcclxuICAgIGFkanVzdFdpZHRoIDogZnVuY3Rpb24od2lkdGhfcGN0KXtcclxuICAgICAgICBhZGp1c3RUYWJsZVdpZHRoKHdpZHRoX3BjdClcclxuICAgIH0sXHJcbiAgICAvLyBUT0RPOiBkZWxldGVcclxuICAgIGNsZWFyIDogaGlkZVRhYmxlLFxyXG4gICAgaGlkZSA6IGhpZGVUYWJsZSxcclxuICAgIHNob3cgOiBzaG93VGFibGUsXHJcbiAgICBzYXZlIDogc2F2ZVRhYmxlRGF0YVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBUYWJsZTsiLCJpbXBvcnQgJy4vYWNjb3JkaW9uLmNzcydcclxuXHJcblxyXG5pbXBvcnQge0Jhc2VsaW5lLCBDdXJyZW50RnVuZCwgRnVuZCwgU3VwcGxlbWVudGFsLCBGdW5kTG9va3VwVGFibGV9IGZyb20gJy4uLy4uL21vZGVscydcclxuaW1wb3J0IHsgZm9ybWF0Q3VycmVuY3ksIGNsZWFuU3RyaW5nIH0gZnJvbSBcIi4uLy4uL3V0aWxzL2NvbW1vbl91dGlscy5qc1wiO1xyXG5pbXBvcnQgVGFibGUgZnJvbSBcIi4uL3RhYmxlL3RhYmxlLmpzXCI7XHJcbmltcG9ydCB7IHZpc2l0UGFnZSB9IGZyb20gJy4uLy4uL3ZpZXdzL3ZpZXdfbG9naWMuanMnO1xyXG5cclxuZnVuY3Rpb24gcmVkaXJlY3RGb3JFZGl0KCl7XHJcbiAgICBjb25zdCByb3cgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAuYWN0aXZlLWVkaXRpbmdgKTtcclxuICAgIGNvbnN0IHRhYmxlID0gcm93LnBhcmVudEVsZW1lbnQ7XHJcbiAgICBjb25zdCBzZWN0aW9uID0gdGFibGUuY2xvc2VzdCgnLnN1bW1hcnktY29udGFpbmVyJyk7XHJcbiAgICAvLyBuZXcgaW5pdGlhdGl2ZSBlZGl0cyBzaG91bGQgYWxsIHJlZGlyZWN0IHRvIHRoZSBuZXctaW5pdHMgcGFnZVxyXG4gICAgaWYgKHNlY3Rpb24uaWQgPT0gJ3N1cHAtYWNjb3JkaW9uJyl7XHJcbiAgICAgICAgdmlzaXRQYWdlKCduZXctaW5pdHMnKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IGZ1bmQgPSB0YWJsZS5pZC5yZXBsYWNlKCd0YWJsZS0nLCcnKTtcclxuICAgICAgICBDdXJyZW50RnVuZC51cGRhdGUoZnVuZCk7XHJcbiAgICAgICAgY29uc3QgbGluZUl0ZW0gPSByb3cucXVlcnlTZWxlY3RvcignLmxpbmUtaXRlbScpLnRleHRDb250ZW50O1xyXG4gICAgICAgIC8vIHZpc2l0IHRoZSBjb3JyZWN0IHBhZ2UgZm9yIGVkaXRpbmdcclxuICAgICAgICBzd2l0Y2gobGluZUl0ZW0pe1xyXG4gICAgICAgICAgICBjYXNlICdQZXJzb25uZWwgRXhwZW5kaXR1cmVzJzpcclxuICAgICAgICAgICAgICAgIHZpc2l0UGFnZSgncGVyc29ubmVsJyk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAnTm9uLVBlcnNvbm5lbCBFeHBlbmRpdHVyZXMnOlxyXG4gICAgICAgICAgICAgICAgdmlzaXRQYWdlKCdub25wZXJzb25uZWwnKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlICdSZXZlbnVlcyc6XHJcbiAgICAgICAgICAgICAgICB2aXNpdFBhZ2UoJ3JldmVudWUnKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTmFtZSBvZiBsaW5lIGl0ZW0gaW4gdGFibGUgZG9lcyBub3QgbWF0Y2ggYSBwYWdlIGRlc3RpbmF0aW9uLicpXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5jb25zdCBFeHBlbnNlVGFibGUgPSB7XHJcbiAgICB0YWJsZV9pZCA6IChmdW5kKSA9PiB7IHJldHVybiBgdGFibGUtJHtjbGVhblN0cmluZyhmdW5kKX1gIH0sXHJcbiAgICBpbml0KGZ1bmQpIHtcclxuICAgICAgICAvLyBjcmVhdGUgZW1wdHkgdGFibGUgYW5kIHB1dCBpdCBpbiB0aGUgYWNjb3JkaW9uXHJcbiAgICAgICAgdmFyIHRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGFibGUnKTtcclxuICAgICAgICB0YWJsZS5pZCA9IHRoaXMudGFibGVfaWQoZnVuZCk7XHJcbiAgICAgICAgdGFibGUuY2xhc3NMaXN0LmFkZCgnYWNjb3JkaW9uLXRhYmxlJyk7XHJcbiAgICAgICAgdmFyIHBhcmVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYCNmdW5kXyR7Y2xlYW5TdHJpbmcoZnVuZCl9X2NvbnRlbnQgLmFjY29yZGlvbi1ib2R5YCk7XHJcbiAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKHRhYmxlKTtcclxuICAgIH0sXHJcbiAgICBjcmVhdGVOZXdDZWxsKGNvbnRlbnQsIHJvdywgY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgY29uc3QgbmV3Q2VsbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RkJyk7XHJcbiAgICAgICAgbmV3Q2VsbC5pbm5lckhUTUwgPSBjb250ZW50O1xyXG4gICAgICAgIG5ld0NlbGwuY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xyXG4gICAgICAgIHJvdy5hcHBlbmRDaGlsZChuZXdDZWxsKTtcclxuICAgIH0sXHJcbiAgICBhZGRSb3coZnVuZF9uYW1lLCByb3dfbmFtZSwgbnVtYmVyKXtcclxuICAgICAgICB2YXIgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnRhYmxlX2lkKGZ1bmRfbmFtZSkpO1xyXG4gICAgICAgIHZhciBuZXdfcm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndHInKTtcclxuICAgICAgICB0YWJsZS5hcHBlbmRDaGlsZChuZXdfcm93KTtcclxuICAgICAgICAvLyBDcmVhdGUgYSBjZWxsIGZvciB0aGUgbGluZSBpdGVtIGxhYmVsXHJcbiAgICAgICAgdGhpcy5jcmVhdGVOZXdDZWxsKHJvd19uYW1lLCBuZXdfcm93LCAnbGluZS1pdGVtJyk7XHJcbiAgICAgICAgLy8gY3JlYXRlIGEgY2VsbCBmb3IgdGhlIGFtb3VudFxyXG4gICAgICAgIHRoaXMuY3JlYXRlTmV3Q2VsbChmb3JtYXRDdXJyZW5jeShudW1iZXIpLCBuZXdfcm93LCAnY29zdCcpO1xyXG4gICAgICAgIC8vIGNyZWF0ZSBFZGl0IGJ1dHRvbiBcclxuICAgICAgICB2YXIgYnV0dG9uID0gJyc7XHJcbiAgICAgICAgaWYgKHJvd19uYW1lICE9ICdOZXQgRXhwZW5kaXR1cmVzIChSZXZlbnVlcyknKXtcclxuICAgICAgICAgICAgYnV0dG9uID0gVGFibGUuQnV0dG9ucy5FZGl0Lmh0bWw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY3JlYXRlTmV3Q2VsbChidXR0b24sIG5ld19yb3cpO1xyXG4gICAgfSxcclxuICAgIGZpbGxGcm9tRnVuZChmdW5kKSB7XHJcbiAgICAgICAgdGhpcy5pbml0KGZ1bmQpO1xyXG4gICAgICAgIGNvbnN0IGZ1bmRPYmplY3QgPSBuZXcgRnVuZChmdW5kKTtcclxuICAgICAgICB0aGlzLmFkZFJvdyhmdW5kLCAnUGVyc29ubmVsIEV4cGVuZGl0dXJlcycsIGZ1bmRPYmplY3QuZ2V0UGVyc29ubmVsQ29zdCgpKTtcclxuICAgICAgICB0aGlzLmFkZFJvdyhmdW5kLCAnTm9uLVBlcnNvbm5lbCBFeHBlbmRpdHVyZXMnLCBmdW5kT2JqZWN0LmdldE5vblBlcnNvbm5lbENvc3QoKSk7XHJcbiAgICAgICAgdGhpcy5hZGRSb3coZnVuZCwgJ1JldmVudWVzJywgZnVuZE9iamVjdC5nZXRSZXZlbnVlKCkpO1xyXG4gICAgICAgIHRoaXMuYWRkUm93KGZ1bmQsICdOZXQgRXhwZW5kaXR1cmVzIChSZXZlbnVlcyknLCBmdW5kT2JqZWN0LmdldFRvdGFsKCkpO1xyXG4gICAgfSxcclxuICAgIGZpbGxGcm9tSW5pdChwcm9ncmFtKSB7XHJcbiAgICAgICAgdGhpcy5pbml0KHByb2dyYW0ubmFtZSk7XHJcbiAgICAgICAgdGhpcy5hZGRSb3cocHJvZ3JhbS5uYW1lLCAnRXhwZW5kaXR1cmVzJywgcHJvZ3JhbS5leHBlbnNlcygpKTtcclxuICAgICAgICB0aGlzLmFkZFJvdyhwcm9ncmFtLm5hbWUsICdSZXZlbnVlcycsIHByb2dyYW0ucmV2ZW51ZSgpKTtcclxuICAgICAgICB0aGlzLmFkZFJvdyhwcm9ncmFtLm5hbWUsICdOZXQgRXhwZW5kaXR1cmVzIChSZXZlbnVlcyknLCBwcm9ncmFtLm5ldCgpKTtcclxuICAgIH1cclxufVxyXG5cclxuY29uc3QgSXRlbSA9IHtcclxuICAgIGh0bWwgOiBmdW5jdGlvbihmdW5kKSB7XHJcbiAgICAgICAgdmFyIGlkID0gY2xlYW5TdHJpbmcoZnVuZCk7XHJcbiAgICAgICAgcmV0dXJuIGA8aDIgY2xhc3M9XCJhY2NvcmRpb24taGVhZGVyXCIgaWQ9XCJmdW5kXyR7aWR9X2hlYWRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJhY2NvcmRpb24tYnV0dG9uIGNvbGxhcHNlZFwiIHR5cGU9XCJidXR0b25cIiBkYXRhLWJzLXRvZ2dsZT1cImNvbGxhcHNlXCIgZGF0YS1icy10YXJnZXQ9XCIjZnVuZF8ke2lkfV9jb250ZW50XCIgYXJpYS1leHBhbmRlZD1cImZhbHNlXCIgYXJpYS1jb250cm9scz1cImZ1bmRfJHtpZH1fY29udGVudFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5hbWVcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYW1vdW50XCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgPC9oMj5cclxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJmdW5kXyR7aWR9X2NvbnRlbnRcIiBjbGFzcz1cImFjY29yZGlvbi1jb2xsYXBzZSBjb2xsYXBzZVwiIGFyaWEtbGFiZWxsZWRieT1cImZ1bmRfJHtpZH1faGVhZGVyXCIgZGF0YS1icy1wYXJlbnQ9XCIuc3VtbWFyeS1hY2NvcmRpb25cIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWNjb3JkaW9uLWJvZHlcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PmBcclxuICAgIH0sXHJcbiAgICBhZGQgOiBmdW5jdGlvbihmdW5kLCBhY2NvcmRpb25faWQpIHtcclxuICAgICAgICAvLyBnZXQgYWNjb3JkaW9uIGFuZCBhZGQgYSBuZXcgaXRlbSB0byBpdFxyXG4gICAgICAgIGNvbnN0IHBhcmVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYCMke2FjY29yZGlvbl9pZH0gLnN1bW1hcnktYWNjb3JkaW9uYCk7XHJcbiAgICAgICAgY29uc3QgaXRlbV9lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgaXRlbV9lbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2FjY29yZGlvbi1pdGVtJyk7XHJcbiAgICAgICAgaXRlbV9lbGVtZW50LmlubmVySFRNTCA9IHRoaXMuaHRtbChmdW5kKTtcclxuICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoaXRlbV9lbGVtZW50KTtcclxuICAgIH0sXHJcbiAgICBFeHBlbnNlVGFibGUgOiBFeHBlbnNlVGFibGUsXHJcbiAgICB1cGRhdGVIZWFkZXIgOiBmdW5jdGlvbih0aXRsZSwgaWQsIG5ld19hbW91bnQpIHtcclxuICAgICAgICB2YXIgaWQgPSBjbGVhblN0cmluZyhpZCk7XHJcbiAgICAgICAgY29uc3QgaGVhZGVyX2J0biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYCNmdW5kXyR7aWR9X2hlYWRlciBidXR0b25gKTtcclxuICAgICAgICBoZWFkZXJfYnRuLnF1ZXJ5U2VsZWN0b3IoJ3NwYW4ubmFtZScpLnRleHRDb250ZW50ID0gdGl0bGU7XHJcbiAgICAgICAgaGVhZGVyX2J0bi5xdWVyeVNlbGVjdG9yKCdzcGFuLmFtb3VudCcpLnRleHRDb250ZW50ID0gZm9ybWF0Q3VycmVuY3kobmV3X2Ftb3VudCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmNvbnN0IEFkZEluaXRCdXR0b24gPSB7XHJcbiAgICBpbml0KCkge1xyXG4gICAgICAgIGNvbnN0IGJ0biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5idG4tYWRkLWluaXQnKTtcclxuICAgICAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICB2aXNpdFBhZ2UoJ25ldy1pbml0cycpO1xyXG4gICAgICAgIH0pXHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBBY2NvcmRpb24gPSB7XHJcbiAgICBJdGVtIDogSXRlbSxcclxuICAgIEFkZEluaXRCdXR0b246IEFkZEluaXRCdXR0b24sXHJcbiAgICBoaWRlIDogZnVuY3Rpb24oKXtcclxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYWNjb3JkaW9uLWRpdicpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgLy8gcmVzZXQgdG8gZGVsZXRlIGNvbnRlbnRcclxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmFzZWxpbmUtYWNjb3JkaW9uIC5zdW1tYXJ5LWFjY29yZGlvbicpLmlubmVySFRNTCA9ICcnO1xyXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzdXBwLWFjY29yZGlvbiAuc3VtbWFyeS1hY2NvcmRpb24nKS5pbm5lckhUTUwgPSAnJztcclxuICAgIH0sXHJcbiAgICBzaG93IDogZnVuY3Rpb24oKXtcclxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYWNjb3JkaW9uLWRpdicpLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgfSxcclxuICAgIGFzeW5jIGNyZWF0ZUJhc2VsaW5lKCl7XHJcbiAgICAgICAgdmFyIGZ1bmRzID0gRnVuZExvb2t1cFRhYmxlLmxpc3RGdW5kcygpO1xyXG4gICAgICAgIGZ1bmRzLmZvckVhY2goZnVuZCA9PiB7XHJcbiAgICAgICAgICAgIEl0ZW0uYWRkKGZ1bmQsICdiYXNlbGluZS1hY2NvcmRpb24nKTtcclxuICAgICAgICAgICAgSXRlbS5FeHBlbnNlVGFibGUuZmlsbEZyb21GdW5kKGZ1bmQpO1xyXG4gICAgICAgICAgICBjb25zdCBmdW5kT2JqZWN0ID0gbmV3IEZ1bmQoZnVuZCk7XHJcbiAgICAgICAgICAgIEl0ZW0udXBkYXRlSGVhZGVyKEZ1bmRMb29rdXBUYWJsZS5nZXROYW1lKGZ1bmQpLCBmdW5kLCBmdW5kT2JqZWN0LmdldFRvdGFsKCkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSxcclxuICAgIGNyZWF0ZVN1cHAoKSB7XHJcbiAgICAgICAgY29uc3Qgc3VwcCA9IG5ldyBTdXBwbGVtZW50YWw7XHJcbiAgICAgICAgc3VwcC5pbml0aWF0aXZlcy5mb3JFYWNoKHByb2dyYW0gPT4ge1xyXG4gICAgICAgICAgICBJdGVtLmFkZChwcm9ncmFtLm5hbWUsICdzdXBwLWFjY29yZGlvbicpO1xyXG4gICAgICAgICAgICBJdGVtLkV4cGVuc2VUYWJsZS5maWxsRnJvbUluaXQocHJvZ3JhbSk7XHJcbiAgICAgICAgICAgIEl0ZW0udXBkYXRlSGVhZGVyKHByb2dyYW0ubmFtZSwgcHJvZ3JhbS5uYW1lLCBwcm9ncmFtLm5ldCgpKTtcclxuICAgICAgICB9KTtcclxuICAgIH0sXHJcbiAgICB1cGRhdGVUb3BMaW5lcygpIHtcclxuICAgICAgICAvLyBhZGp1c2UgYmFzZWxpbmVcclxuICAgICAgICBjb25zdCBiYXNlbGluZSA9IG5ldyBCYXNlbGluZTtcclxuICAgICAgICBjb25zdCBiYXNlbGluZUFtb3VudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiYXNlbGluZS10aXRsZSAudG9wLWxpbmUtYW1vdW50JylcclxuICAgICAgICBiYXNlbGluZUFtb3VudC50ZXh0Q29udGVudCA9IGZvcm1hdEN1cnJlbmN5KGJhc2VsaW5lLnRvdGFsKCkpO1xyXG4gICAgICAgIC8vIGFkanVzdCBzdXBwbGVtZW50YWxzXHJcbiAgICAgICAgY29uc3Qgc3VwcCA9IG5ldyBTdXBwbGVtZW50YWw7XHJcbiAgICAgICAgY29uc3Qgc3VwcEFtb3VudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzdXBwLXRpdGxlIC50b3AtbGluZS1hbW91bnQnKVxyXG4gICAgICAgIHN1cHBBbW91bnQudGV4dENvbnRlbnQgPSBmb3JtYXRDdXJyZW5jeShzdXBwLnRvdGFsKCkpO1xyXG4gICAgICAgIC8vIGNvbG9yLWNvZGUgYmFzZWxpbmVcclxuICAgICAgICBpZiAoYmFzZWxpbmUudG90YWwoKSA8PSBCYXNlbGluZS50YXJnZXQoKSl7XHJcbiAgICAgICAgICAgIGJhc2VsaW5lQW1vdW50LnN0eWxlLmNvbG9yID0gJ2dyZWVuJztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBiYXNlbGluZUFtb3VudC5zdHlsZS5jb2xvciA9ICdyZWQnO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBidWlsZCgpIHtcclxuICAgICAgICB0aGlzLmNyZWF0ZUJhc2VsaW5lKCk7XHJcbiAgICAgICAgdGhpcy5jcmVhdGVTdXBwKCk7XHJcbiAgICAgICAgLy8gaW5pdGlhbGl6ZSBlZGl0IGJ1dHRvbnNcclxuICAgICAgICBUYWJsZS5CdXR0b25zLkVkaXQuaW5pdChyZWRpcmVjdEZvckVkaXQpO1xyXG4gICAgICAgIHRoaXMuQWRkSW5pdEJ1dHRvbi5pbml0KCk7XHJcbiAgICAgICAgdGhpcy51cGRhdGVUb3BMaW5lcygpO1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuZXhwb3J0IGRlZmF1bHQgQWNjb3JkaW9uO1xyXG4iLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vZmlsZV91cGxvYWQuY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vZmlsZV91cGxvYWQuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiaW1wb3J0ICcuL2ZpbGVfdXBsb2FkLmNzcyc7XHJcblxyXG5pbXBvcnQgeyBwcm9jZXNzV29ya2Jvb2sgfSBmcm9tIFwiLi4vLi4vdXRpbHMvWExTWF9oYW5kbGVycy5qc1wiO1xyXG5pbXBvcnQgU2lkZWJhciBmcm9tICcuLi9zaWRlYmFyL3NpZGViYXIuanMnO1xyXG5cclxuZXhwb3J0IGNvbnN0IEZpbGVVcGxvYWQgPSB7XHJcbiAgICBpbml0IDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgY29uc3QgaW5wdXRPYmplY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmlsZS1pbnB1dCcpO1xyXG4gICAgICAgIGlucHV0T2JqZWN0LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGZ1bmN0aW9uKGV2ZW50KSB7cmVhZFhMKGV2ZW50KSB9KTtcclxuICAgIH0sXHJcbiAgICBzaG93IDogZnVuY3Rpb24oKXtcclxuICAgICAgICBjb25zdCBpbnB1dE9iamVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaWxlLWlucHV0Jyk7XHJcbiAgICAgICAgaW5wdXRPYmplY3Quc3R5bGUuZGlzcGxheSA9ICcnO1xyXG4gICAgfSxcclxuICAgIGhpZGUgOiBmdW5jdGlvbigpe1xyXG4gICAgICAgIGNvbnN0IGlucHV0T2JqZWN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbGUtaW5wdXQnKTtcclxuICAgICAgICBpbnB1dE9iamVjdC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiByZWFkWEwoZXZlbnQpIHtcclxuXHJcbiAgICAvLyByZWFkIHVwbG9hZGVkIGZpbGVcclxuICAgIGNvbnN0IGZpbGUgPSBldmVudC50YXJnZXQuZmlsZXNbMF07XHJcblxyXG4gICAgaWYgKGZpbGUpIHtcclxuICAgICAgICAvLyBkZWxldGUgYW55IHN0b3JlZCBkYXRhIGJlZm9yZSByZS1wb3B1bGF0aW5nIHdpdGggRXhjZWwgZGF0YVxyXG4gICAgICAgIC8vIFNpZGViYXIucmVzZXQoKVxyXG4gICAgICAgIC8vIHJlYWQgaW4gbmV3IGRhdGFcclxuICAgICAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xyXG4gICAgICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGFycmF5QnVmZmVyID0gZS50YXJnZXQucmVzdWx0O1xyXG4gICAgICAgICAgICBwcm9jZXNzV29ya2Jvb2soYXJyYXlCdWZmZXIpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmVhZGVyLm9uZXJyb3IgPSBmdW5jdGlvbihlcnIpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgcmVhZGluZyBmaWxlOicsIGVycik7XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZSk7IC8vIFJlYWQgdGhlIGZpbGUgYXMgYW4gQXJyYXlCdWZmZXJcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgRmlsZVVwbG9hZDsiLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vbW9kYWwuY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vbW9kYWwuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiXHJcbmltcG9ydCAnLi9tb2RhbC5jc3MnO1xyXG5cclxuZnVuY3Rpb24gY2xlYXJNb2RhbCgpe1xyXG4gICAgdXBkYXRlTW9kYWxUaXRsZSgnJyk7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9kYWwtYm9keScpLmlubmVySFRNTCA9ICcnO1xyXG59XHJcblxyXG5mdW5jdGlvbiBoaWRlTW9kYWwoKSB7XHJcbiAgICAkKCcjbWFpbi1tb2RhbCcpLm1vZGFsKCdoaWRlJyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNob3dNb2RhbCgpIHtcclxuICAgICQoJyNtYWluLW1vZGFsJykubW9kYWwoJ3Nob3cnKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2hvd01vZGFsSGFuZGxlcigpIHtcclxuICAgIHNob3dNb2RhbCgnbWFpbi1tb2RhbCcpO1xyXG59XHJcblxyXG5jb25zdCBTdWJtaXQgPSB7XHJcbiAgICBoYW5kbGVyOiBudWxsLCBcclxuXHJcbiAgICBpbml0OiBmdW5jdGlvbihvblN1Ym1pdCkge1xyXG4gICAgICAgIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tbW9kYWwnKTtcclxuICAgICAgICAvLyBhZGQgb25TdWJtaXQgZnVuY3Rpb24gYXMgaGFuZGxlclxyXG4gICAgICAgIHRoaXMuaGFuZGxlciA9IGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIG9uU3VibWl0KGV2ZW50KTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIEFkZGluZyB0aGUgaGFuZGxlciByZWZlcmVuY2UgYXMgdGhlIGV2ZW50IGxpc3RlbmVyXHJcbiAgICAgICAgbW9kYWwuYWRkRXZlbnRMaXN0ZW5lcignc3VibWl0JywgdGhpcy5oYW5kbGVyKTtcclxuXHJcbiAgICAgICAgLy8gYWRkIGV2ZW50IGxpc3RlbmVyIHRvIGVuYWJsZSBjbG9zZSB4XHJcbiAgICAgICAgY29uc3QgeCA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJyNtb2RhbC1jbG9zZS14Jyk7XHJcbiAgICAgICAgeC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGhpZGVNb2RhbCk7XHJcbiAgICB9LFxyXG5cclxuICAgIGRlaW5pdDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi1tb2RhbCcpO1xyXG4gICAgICAgIGlmICh0aGlzLmhhbmRsZXIgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgLy8gUmVtb3ZpbmcgdGhlIGV2ZW50IGxpc3RlbmVyIGFuZCBjbGVhciB0aGUgaGFuZGxlclxyXG4gICAgICAgICAgICBtb2RhbC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdWJtaXQnLCB0aGlzLmhhbmRsZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZXIgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyByZW1vdmUgZXZlbnQgbGlzdGVuZXIgdG8gZW5hYmxlIGNsb3NlIHhcclxuICAgICAgICBjb25zdCB4ID0gbW9kYWwucXVlcnlTZWxlY3RvcignI21vZGFsLWNsb3NlLXgnKTtcclxuICAgICAgICB4LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgaGlkZU1vZGFsKTtcclxuICAgIH1cclxufTtcclxuXHJcbmNvbnN0IExpbmsgPSB7XHJcbiAgICBhZGQgOiBmdW5jdGlvbihidXR0b25faWQpe1xyXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGJ1dHRvbl9pZCkuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzaG93TW9kYWxIYW5kbGVyKVxyXG4gICAgfSxcclxuICAgIHJlbW92ZSA6IGZ1bmN0aW9uKGJ1dHRvbl9pZCl7XHJcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYnV0dG9uX2lkKS5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHNob3dNb2RhbEhhbmRsZXIpXHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZU1vZGFsVGl0bGUodGl0bGUpIHtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2RhbC10aXRsZScpLnRleHRDb250ZW50ID0gdGl0bGU7XHJcbn1cclxuXHJcbmNvbnN0IFRpdGxlID0ge1xyXG4gICAgdXBkYXRlIDogZnVuY3Rpb24odGl0bGUpIHsgdXBkYXRlTW9kYWxUaXRsZSh0aXRsZSkgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgTW9kYWwgPSB7XHJcbiAgICBoaWRlIDogaGlkZU1vZGFsLFxyXG4gICAgc2hvdyA6IHNob3dNb2RhbCxcclxuICAgIGNsZWFyIDogY2xlYXJNb2RhbCxcclxuICAgIFRpdGxlIDogVGl0bGUsXHJcbiAgICBMaW5rIDogTGluayxcclxuICAgIFN1Ym1pdDogU3VibWl0XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IE1vZGFsOyIsImltcG9ydCAnLi9ib2R5LmNzcyc7XHJcblxyXG5pbXBvcnQgV2VsY29tZSBmcm9tICcuLi8uLi9jb21wb25lbnRzL3dlbGNvbWUvd2VsY29tZS5qcydcclxuaW1wb3J0IEFjY29yZGlvbiBmcm9tICcuLi9hY2NvcmRpb24vYWNjb3JkaW9uLmpzJztcclxuaW1wb3J0IEZpbGVVcGxvYWQgZnJvbSAnLi4vZmlsZV91cGxvYWQvZmlsZV91cGxvYWQuanMnO1xyXG5pbXBvcnQgTW9kYWwgZnJvbSAnLi4vbW9kYWwvbW9kYWwuanMnO1xyXG5pbXBvcnQgTmF2QnV0dG9ucyBmcm9tICcuLi9uYXZfYnV0dG9ucy9uYXZfYnV0dG9ucy5qcyc7XHJcbmltcG9ydCBQcm9tcHQgZnJvbSAnLi4vcHJvbXB0L3Byb21wdC5qcyc7XHJcbmltcG9ydCBTaWRlYmFyIGZyb20gJy4uL3NpZGViYXIvc2lkZWJhci5qcyc7XHJcbmltcG9ydCBUYWJsZSBmcm9tICcuLi90YWJsZS90YWJsZS5qcyc7XHJcbmltcG9ydCBUb29sdGlwIGZyb20gJy4uL3Rvb2x0aXAvdG9vbHRpcC5qcyc7ICBcclxuXHJcbmZ1bmN0aW9uIHJlc2V0UGFnZSgpIHtcclxuICAgIC8vIGhpZGUgZXZlcnl0aGluZyBpbiB0aGUgYm9keVxyXG4gICAgV2VsY29tZS5oaWRlKCk7XHJcbiAgICBNb2RhbC5jbGVhcigpO1xyXG4gICAgTW9kYWwuaGlkZSgpO1xyXG4gICAgTmF2QnV0dG9ucy5oaWRlKCk7XHJcbiAgICBQcm9tcHQuaGlkZSgpO1xyXG4gICAgVGFibGUuaGlkZSgpO1xyXG4gICAgU2lkZWJhci5oaWRlKCk7XHJcbiAgICBBY2NvcmRpb24uaGlkZSgpO1xyXG4gICAgRmlsZVVwbG9hZC5oaWRlKCk7XHJcbiAgICBUb29sdGlwLmhpZGUoKTtcclxuXHJcbiAgICBQcm9tcHQuQnV0dG9ucy5yZXNldCgpO1xyXG4gICAgLy8gZGlzYWJsZSBzdWJtaXQgYnV0dG9uXHJcbiAgICBNb2RhbC5TdWJtaXQuZGVpbml0KCk7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBCb2R5ID0ge1xyXG4gICAgcmVzZXQgOiByZXNldFBhZ2VcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgQm9keTsiLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vaGVhZGVyLmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xub3B0aW9ucy5pbnNlcnQgPSBpbnNlcnRGbi5iaW5kKG51bGwsIFwiaGVhZFwiKTtcbm9wdGlvbnMuZG9tQVBJID0gZG9tQVBJO1xub3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQgPSBpbnNlcnRTdHlsZUVsZW1lbnQ7XG5cbnZhciB1cGRhdGUgPSBBUEkoY29udGVudCwgb3B0aW9ucyk7XG5cblxuXG5leHBvcnQgKiBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL2hlYWRlci5jc3NcIjtcbiAgICAgICBleHBvcnQgZGVmYXVsdCBjb250ZW50ICYmIGNvbnRlbnQubG9jYWxzID8gY29udGVudC5sb2NhbHMgOiB1bmRlZmluZWQ7XG4iLCJpbXBvcnQgJy4vaGVhZGVyLmNzcyc7XHJcblxyXG5pbXBvcnQgQ3VycmVudEZ1bmQgZnJvbSAnLi4vLi4vbW9kZWxzL2N1cnJlbnRfZnVuZCc7XHJcblxyXG5leHBvcnQgY29uc3QgU3VidGl0bGUgPSB7XHJcbiAgICB1cGRhdGUgOiBmdW5jdGlvbihzdWJ0aXRsZSl7XHJcbiAgICAgICAgLy8gZ2V0IGN1cnJlbnQgZnVuZFxyXG4gICAgICAgIHZhciBmdW5kID0gQ3VycmVudEZ1bmQubmFtZSgpO1xyXG4gICAgICAgIGlmIChmdW5kKXtcclxuICAgICAgICAgICAgdmFyIHN1YnRpdGxlID0gYCR7c3VidGl0bGV9OiAke2Z1bmR9YDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzdWJ0aXRsZVwiKS50ZXh0Q29udGVudCA9IHN1YnRpdGxlO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBTdWJ0aXRsZTsiLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vZm9ybS5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcbm9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9mb3JtLmNzc1wiO1xuICAgICAgIGV4cG9ydCBkZWZhdWx0IGNvbnRlbnQgJiYgY29udGVudC5sb2NhbHMgPyBjb250ZW50LmxvY2FscyA6IHVuZGVmaW5lZDtcbiIsIi8vIGZ1bmN0aW9uIHRvIGFkZCBxdWVzdGlvbnMgdG8gZm9ybXNcclxuXHJcbmltcG9ydCBEcm9wZG93biBmcm9tIFwiLi9kcm9wZG93blwiO1xyXG5cclxuLy8gaW5wdXRUeXBlIGlzIGZvciB2YWxpZGF0aW9uICgnbnVtYmVyJyBvciAndGV4dCcsIGV0YylcclxuZnVuY3Rpb24gYXBwZW5kRm9ybUVsZW1lbnQobGFiZWwsIGlucHV0RWwsIGlucHV0SWQsIHJlcXVpcmVkKSB7XHJcblxyXG4gICAgLy8gY2hhbmdlIGlmIHdlIHdhbnQgZm9ybXMgZWxzZXdoZXJlXHJcbiAgICBjb25zdCBmb3JtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25ldy1mb3JtJyk7XHJcblxyXG4gICAgLy8gY3JlYXRlIG91dGVyIHdyYXBwZXIgZm9yIGVsZW1lbnRcclxuICAgIGNvbnN0IHdyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsgIFxyXG5cclxuICAgIC8vIGxhYmVsIHF1ZXN0aW9uXHJcbiAgICBjb25zdCBsYWJlbEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcclxuICAgIGxhYmVsRWwudGV4dENvbnRlbnQgPSBsYWJlbDtcclxuXHJcbiAgICAvLyBtYXJrIGFzIHJlcXVpcmVkIGlmIGFwcGxpY2FibGVcclxuICAgIGlucHV0RWwucmVxdWlyZWQgPSByZXF1aXJlZDtcclxuXHJcbiAgICAvLyBJZiBhbiBJRCBpcyBwcm92aWRlZCwgc2V0IGl0IG9uIHRoZSBlbGVtZW50XHJcbiAgICBpZiAoaW5wdXRJZCkge1xyXG4gICAgICAgIGlucHV0RWwuaWQgPSBpbnB1dElkO1xyXG4gICAgfVxyXG4gIFxyXG4gICAgLy8gYWRkIGVsZW1lbnRzXHJcbiAgICB3cmFwcGVyLmFwcGVuZENoaWxkKGxhYmVsRWwpO1xyXG4gICAgd3JhcHBlci5hcHBlbmRDaGlsZChpbnB1dEVsKTtcclxuICAgIGZvcm0uYXBwZW5kQ2hpbGQod3JhcHBlcik7XHJcbn0gXHJcblxyXG5leHBvcnQgY29uc3QgTmV3RmllbGQgPSB7XHJcbiAgICBzaG9ydFRleHQgOiBmdW5jdGlvbihsYWJlbCwgaW5wdXRJZCwgcmVxdWlyZWQgPSBmYWxzZSkge1xyXG4gICAgICAgIGNvbnN0IGlucHV0RWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xyXG4gICAgICAgIGlucHV0RWwudHlwZSA9ICd0ZXh0JztcclxuICAgICAgICBhcHBlbmRGb3JtRWxlbWVudChsYWJlbCwgaW5wdXRFbCwgaW5wdXRJZCxyZXF1aXJlZCk7XHJcbiAgICB9LFxyXG4gICAgbG9uZ1RleHQgOiBmdW5jdGlvbihsYWJlbCwgaW5wdXRJZCwgcmVxdWlyZWQgPSBmYWxzZSkge1xyXG4gICAgICAgIGNvbnN0IGlucHV0RWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xyXG4gICAgICAgIGFwcGVuZEZvcm1FbGVtZW50KGxhYmVsLCBpbnB1dEVsLCBpbnB1dElkLCByZXF1aXJlZCk7XHJcbiAgICB9LFxyXG4gICAgbnVtZXJpY0lucHV0IDogZnVuY3Rpb24obGFiZWwsIGlucHV0SWQsIHJlcXVpcmVkID0gZmFsc2UpIHtcclxuICAgICAgICBjb25zdCBpbnB1dEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcclxuICAgICAgICBpbnB1dEVsLnR5cGUgPSAnbnVtYmVyJztcclxuICAgICAgICBhcHBlbmRGb3JtRWxlbWVudChsYWJlbCwgaW5wdXRFbCwgaW5wdXRJZCxyZXF1aXJlZCk7XHJcbiAgICB9LFxyXG4gICAgZHJvcGRvd24gOiBmdW5jdGlvbihsYWJlbCwgaW5wdXRJZCwgb3B0aW9uQXJyYXksIHJlcXVpcmVkID0gZmFsc2Upe1xyXG4gICAgICAgIHZhciBpbnB1dEVsID0gRHJvcGRvd24uY3JlYXRlKG9wdGlvbkFycmF5KTtcclxuICAgICAgICBhcHBlbmRGb3JtRWxlbWVudChsYWJlbCwgaW5wdXRFbCwgaW5wdXRJZCwgcmVxdWlyZWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBOZXdGaWVsZDsiLCJmdW5jdGlvbiBhZGRTdWJtaXRCdXR0b25Ub0Zvcm0oZm9ybV9pZCkge1xyXG4gICAgLy8gRmluZCB0aGUgZm9ybSBieSBpdHMgSURcclxuICAgIGNvbnN0IGZvcm0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChmb3JtX2lkKTtcclxuICBcclxuICAgIC8vIENyZWF0ZSB0aGUgY29udGFpbmVyIGBkaXZgIGZvciB0aGUgYnV0dG9uXHJcbiAgICBjb25zdCBidXR0b25Db250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgIGJ1dHRvbkNvbnRhaW5lci5pZCA9ICdzdWJtaXQtYnRuLWNvbnRhaW5lcic7XHJcbiAgICBcclxuICAgIC8vIENyZWF0ZSB0aGUgc3VibWl0IGlucHV0XHJcbiAgICBjb25zdCBzdWJtaXRJbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XHJcbiAgICBzdWJtaXRJbnB1dC5jbGFzc05hbWUgPSAnYnRuIGJ0bi1zdWJtaXQnOyAvLyBVc2UgYXBwcm9wcmlhdGUgY2xhc3MgZm9yIHlvdXIgZGVzaWduXHJcbiAgICBzdWJtaXRJbnB1dC50eXBlID0gJ3N1Ym1pdCc7XHJcbiAgICBzdWJtaXRJbnB1dC52YWx1ZSA9ICdTdWJtaXQnO1xyXG5cclxuICAgIC8vIEFwcGVuZCB0aGUgc3VibWl0IGlucHV0IHRvIHRoZSBjb250YWluZXJcclxuICAgIGJ1dHRvbkNvbnRhaW5lci5hcHBlbmRDaGlsZChzdWJtaXRJbnB1dCk7XHJcbiAgICBcclxuICAgIC8vIEFwcGVuZCB0aGUgY29udGFpbmVyIHRvIHRoZSBmb3JtXHJcbiAgICBmb3JtLmFwcGVuZENoaWxkKGJ1dHRvbkNvbnRhaW5lcik7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBTdWJtaXRCdXR0b24gPSB7XHJcbiAgICBhZGQgOiBmdW5jdGlvbigpIHsgYWRkU3VibWl0QnV0dG9uVG9Gb3JtKCduZXctZm9ybScpIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgU3VibWl0QnV0dG9uOyIsImltcG9ydCAnLi9mb3JtLmNzcyc7XHJcblxyXG5pbXBvcnQgRHJvcGRvd24gZnJvbSBcIi4vc3ViY29tcG9uZW50cy9kcm9wZG93bi5qc1wiO1xyXG5pbXBvcnQgTmV3RmllbGQgZnJvbSBcIi4vc3ViY29tcG9uZW50cy9maWVsZHMuanNcIjtcclxuaW1wb3J0IFN1Ym1pdEJ1dHRvbiBmcm9tIFwiLi9zdWJjb21wb25lbnRzL3N1Ym1pdC5qc1wiO1xyXG5cclxuZnVuY3Rpb24gZmV0Y2hBbGxSZXNwb25zZXMoZXZlbnQpIHtcclxuXHJcbiAgICAvLyBBc3N1bWluZyBgZXZlbnQudGFyZ2V0YCBpcyB0aGUgZm9ybSBpdHNlbGZcclxuICAgIGNvbnN0IGZvcm0gPSBldmVudC50YXJnZXQ7XHJcbiAgICBcclxuICAgIC8vIEluaXRpYWxpemUgYW4gZW1wdHkgYXJyYXkgdG8gaG9sZCB0aGUgaW5wdXQgdmFsdWVzXHJcbiAgICBsZXQgZm9ybURhdGEgPSB7fTtcclxuICAgIFxyXG4gICAgLy8gTG9vcCB0aHJvdWdoIGVhY2ggZm9ybSBlbGVtZW50XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZvcm0uZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgY29uc3QgZWxlbWVudCA9IGZvcm0uZWxlbWVudHNbaV07XHJcbiAgICAgIFxyXG4gICAgICAvLyBFeGNsdWRlIGVsZW1lbnRzIHRoYXQgYXJlbid0IGlucHV0cywgdGV4dGFyZWFzLCBvciBzZWxlY3RcclxuICAgICAgaWYgKGVsZW1lbnQudGFnTmFtZSA9PT0gJ0lOUFVUJyB8fFxyXG4gICAgICAgICAgZWxlbWVudC50YWdOYW1lID09PSAnVEVYVEFSRUEnIHx8XHJcbiAgICAgICAgICBlbGVtZW50LnRhZ05hbWUgPT09ICdTRUxFQ1QnKSB7XHJcbiAgICAgICAgLy8gRXhjbHVkZSBpbnB1dCB0eXBlcyB0aGF0IGFyZSBub3QgY29uc2lkZXJlZCBmb3Igc3VibWlzc2lvbiAoc3VjaCBhcyBgc3VibWl0YClcclxuICAgICAgICBpZiAoZWxlbWVudC50eXBlICE9PSAnc3VibWl0JyAmJiBlbGVtZW50LnR5cGUgIT09ICdidXR0b24nKSB7XHJcbiAgICAgICAgICBmb3JtRGF0YVtlbGVtZW50LmlkXSA9IGVsZW1lbnQudmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGZvcm0ucmVzZXQoKTtcclxuICAgIHJldHVybiBmb3JtRGF0YTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkRm9ybShlbGVtZW50X2lkID0gJ21vZGFsLWJvZHknLCBmb3JtX2lkID0gJ25ldy1mb3JtJykge1xyXG4gIFxyXG4gIGNvbnN0IHRhcmdldF9lbGVtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudF9pZCk7XHJcblxyXG4gIC8vIGNyZWF0ZSBmb3JtXHJcbiAgY29uc3QgZm9ybSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2Zvcm0nKTtcclxuICBmb3JtLnNldEF0dHJpYnV0ZSgnaWQnLCBmb3JtX2lkKTtcclxuXHJcbiAgLy8gQXBwZW5kIHRoZSBmb3JtIHRvIHRoZSBtb2RhbCBib2R5XHJcbiAgdGFyZ2V0X2VsZW0uYXBwZW5kQ2hpbGQoZm9ybSk7XHJcblxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgRm9ybSA9IHtcclxuICBuZXcgOiBmdW5jdGlvbihwYXJlbnRfZWxlbV9pZCkgeyBhZGRGb3JtKHBhcmVudF9lbGVtX2lkLCAnbmV3LWZvcm0nKSB9LFxyXG4gIGZldGNoQWxsUmVzcG9uc2VzIDogZnVuY3Rpb24oZXZlbnQpIHsgcmV0dXJuIGZldGNoQWxsUmVzcG9uc2VzKGV2ZW50KSB9LFxyXG4gIE5ld0ZpZWxkIDogTmV3RmllbGQsXHJcbiAgRHJvcGRvd24gOiBEcm9wZG93bixcclxuICBTdWJtaXRCdXR0b24gOiBTdWJtaXRCdXR0b25cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgRm9ybTsiLCJpbXBvcnQgUHJvbXB0IGZyb20gXCIuLi9jb21wb25lbnRzL3Byb21wdC9wcm9tcHQuanNcIjtcclxuaW1wb3J0IFNpZGViYXIgZnJvbSBcIi4uL2NvbXBvbmVudHMvc2lkZWJhci9zaWRlYmFyLmpzXCI7XHJcbmltcG9ydCBOYXZCdXR0b25zIGZyb20gXCIuLi9jb21wb25lbnRzL25hdl9idXR0b25zL25hdl9idXR0b25zLmpzXCI7XHJcbmltcG9ydCBCb2R5IGZyb20gXCIuLi9jb21wb25lbnRzL2JvZHkvYm9keS5qc1wiO1xyXG5pbXBvcnQgU3VidGl0bGUgZnJvbSBcIi4uL2NvbXBvbmVudHMvaGVhZGVyL2hlYWRlci5qc1wiO1xyXG5pbXBvcnQgVGFibGUgZnJvbSBcIi4uL2NvbXBvbmVudHMvdGFibGUvdGFibGUuanNcIjtcclxuaW1wb3J0IEZvcm0gZnJvbSBcIi4uL2NvbXBvbmVudHMvZm9ybS9mb3JtLmpzXCI7XHJcbmltcG9ydCBNb2RhbCBmcm9tIFwiLi4vY29tcG9uZW50cy9tb2RhbC9tb2RhbC5qc1wiO1xyXG5cclxuaW1wb3J0IHsgQ3VycmVudFBhZ2UsIEFjY291bnRTdHJpbmcgfSBmcm9tICcuLi9tb2RlbHMvJ1xyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBWaWV3IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICAvLyBwYWdlIHN0YXRlIGluIGxvY2FsIHN0b3JhZ2VcclxuICAgICAgICB0aGlzLnBhZ2Vfc3RhdGUgPSAnJztcclxuXHJcbiAgICAgICAgLy8gd2hldGhlciB0byBkaXNwbGF5XHJcbiAgICAgICAgdGhpcy5uYXZCdXR0b25zID0gdHJ1ZTsgXHJcbiAgICAgICAgdGhpcy5zaWRlYmFyID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgLy8gdGV4dCB0byBzaG93IGluIHRoZSBwcm9tcHQgYXJlYVxyXG4gICAgICAgIHRoaXMucHJvbXB0ID0gbnVsbDtcclxuXHJcbiAgICAgICAgLy8gc3VidGl0bGUgdGV4dFxyXG4gICAgICAgIHRoaXMuc3VidGl0bGUgPSAnJztcclxuXHJcbiAgICAgICAgLy8gdGFibGUgb2JqZWN0IG9mIGNsYXNzIFZpZXdUYWJsZSBvciBudWxsXHJcbiAgICAgICAgdGhpcy50YWJsZSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgdmlzaXQoKSB7XHJcbiAgICAgICAgLy8gdXBkYXRlIHBhZ2Ugc3RhdGVcclxuICAgICAgICBDdXJyZW50UGFnZS51cGRhdGUodGhpcy5wYWdlX3N0YXRlKTtcclxuXHJcbiAgICAgICAgLy8gc3RhcnQgd2l0aCBhIGJsYW5rIHBhZ2VcclxuICAgICAgICBCb2R5LnJlc2V0KCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gZGVmYXVsdCB0byBzaG93aW5nIG5hdmJ1dHRvbnNcclxuICAgICAgICBpZiAodGhpcy5uYXZCdXR0b25zKSB7IE5hdkJ1dHRvbnMuc2hvdygpOyB9O1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIGRlZmF1bHQgdG8gc2hvd2luZyBzaWRlYmFyXHJcbiAgICAgICAgaWYgKHRoaXMuc2lkZWJhcikgeyBTaWRlYmFyLnNob3coKSB9O1xyXG5cclxuICAgICAgICAvLyBpbml0aWFsaXplIHByb21wdCB0ZXh0IGFuZCBidXR0b25zXHJcbiAgICAgICAgaWYgKHRoaXMucHJvbXB0KSB7IFByb21wdC5UZXh0LnVwZGF0ZSh0aGlzLnByb21wdCkgfTtcclxuICAgICAgICBcclxuICAgICAgICAvLyBpbml0aWFsaXplIHRhYmxlXHJcbiAgICAgICAgaWYgKHRoaXMudGFibGUpIHsgdGhpcy50YWJsZS5idWlsZCgpOyB9XHJcblxyXG4gICAgICAgIC8vIHNob3cgcGFnZSBzdWJ0aXRsZVxyXG4gICAgICAgIGlmICh0aGlzLnN1YnRpdGxlKSB7IFN1YnRpdGxlLnVwZGF0ZSh0aGlzLnN1YnRpdGxlKSB9O1xyXG4gICAgfVxyXG5cclxuICAgIGNsZWFudXAoKSB7IHJldHVybjsgfVxyXG5cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFZpZXdUYWJsZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKXtcclxuICAgICAgICAvLyBFbnN1cmUgbWV0aG9kcyByZXRhaW4gdGhlIGNvcnJlY3QgYHRoaXNgIGNvbnRleHRcclxuICAgICAgICB0aGlzLnN1Ym1pdE5ld1JvdyA9IHRoaXMuc3VibWl0TmV3Um93LmJpbmQodGhpcyk7XHJcblxyXG4gICAgICAgIHRoaXMuY29sdW1ucyA9IFtcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0FjY291bnQgU3RyaW5nJywgY2xhc3NOYW1lOiAnYWNjb3VudC1zdHJpbmcnIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdBcHByb3ByaWF0aW9uIE5hbWUnLCBjbGFzc05hbWU6ICdhcHByb3AtbmFtZScsIGhpZGU6IHRydWUgfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0FwcHJvcHJpYXRpb24nLCBjbGFzc05hbWU6ICdhcHByb3AnLCBoaWRlOiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdDb3N0IENlbnRlciBOYW1lJywgY2xhc3NOYW1lOiAnY2MtbmFtZScsICBoaWRlOiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdDb3N0IENlbnRlcicsIGNsYXNzTmFtZTogJ2NjJywgIGhpZGU6IHRydWUgfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0Z1bmQgTmFtZScsIGNsYXNzTmFtZTogJ2Z1bmQtbmFtZScsICBoaWRlOiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdGdW5kJywgY2xhc3NOYW1lOiAnZnVuZCcsICBoaWRlOiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdFZGl0JywgY2xhc3NOYW1lOiAnZWRpdCcgfSxcclxuICAgICAgICBdO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIHdoZXRoZXIgdG8gYWRkIGFuIGVkaXQgY29sdW1uXHJcbiAgICAgICAgdGhpcy5hZGRFZGl0ID0gdHJ1ZSA7XHJcblxyXG4gICAgICAgIC8vIG1lc3NhZ2UgdG8gc2hvdyBpZiB0aGVyZSdzIG5vIHNhdmVkIGRhdGFcclxuICAgICAgICB0aGlzLm5vRGF0YU1lc3NhZ2UgPSBudWxsO1xyXG4gICBcclxuICAgICAgICAvLyB0ZXh0IHRvIHNob3cgZm9yIG5ldyByb3cgYnV0dG9uXHJcbiAgICAgICAgdGhpcy5hZGRCdXR0b25UZXh0ID0gbnVsbCA7XHJcblxyXG4gICAgICAgIC8vIHdoZXRoZXIgdG8gc2hvdyBhcyBhIGRhdGF0YWJsZVxyXG4gICAgICAgIHRoaXMuZGF0YVRhYmxlID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBidWlsZCgpIHtcclxuICAgIC8vIGJ1aWxkIHRhYmxlIGZyb20gbG9jYWwgc3RvcmFnZSBhbmQgaW5pdGlhbGl6ZSBlZGl0IGJ1dHRvbnNcclxuXHJcbiAgICAgICAgLy8gYWRkIHRoZSBhZGQgbmV3IHJvdyBidXR0b24gaWYgbmVlZGVkXHJcbiAgICAgICAgaWYgKHRoaXMuYWRkQnV0dG9uVGV4dCkgeyBcclxuICAgICAgICAgICAgdGhpcy5zZXRVcEZvcm0oKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGZpbGwgdGFibGUgd2l0aCBuZXcgZGF0YSBmcm9tIGxvY2FsIHN0b3JhZ2VcclxuICAgICAgICBpZihhd2FpdCBUYWJsZS5EYXRhLmxvYWQoKSkgeyAgICAgIFxyXG5cclxuICAgICAgICAgICAgLy8gY3JlYXRlIGEgZGF0YXRhYmxlIG9iamVjdFxyXG4gICAgICAgICAgICBpZih0aGlzLmRhdGFUYWJsZSl7dGhpcy5pbml0RGF0YVRhYmxlKCl9XHJcblxyXG4gICAgICAgICAgICAvLyBhZGQgYW4gZWRpdCBjb2x1bW4gaWYgbmVlZGVkXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmFkZEVkaXQpIHsgXHJcbiAgICAgICAgICAgICAgICBUYWJsZS5Db2x1bW5zLmFkZEF0RW5kKFRhYmxlLkJ1dHRvbnMuZWRpdF9jb25maXJtX2J0bnMsICdFZGl0Jyk7IFxyXG4gICAgICAgICAgICAgICAgLy8gYWN0aXZhdGUgZWRpdCBidXR0b25zXHJcbiAgICAgICAgICAgICAgICBUYWJsZS5CdXR0b25zLkVkaXQuaW5pdCh0aGlzLmFjdGlvbk9uRWRpdCwgdGhpcy51cGRhdGVUYWJsZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIC8vIGFzc2lnbiB0aGUgY29ycmVjdCBjbGFzc2VzIGJhc2VkIG9uIHRoZSB0YWJsZSBjb2x1bW5zXHJcbiAgICAgICAgICAgIFRhYmxlLkNvbHVtbnMuYXNzaWduQ2xhc3Nlcyh0aGlzLmNvbHVtbnMpO1xyXG5cclxuICAgICAgICAgICAgLy8gQXBwbHkgYW55IHVwZGF0ZSBmdW5jdGlvbiB0byBtYWtlIHN1cmUgc2lkZWJhciBpcyB1cCB0byBkYXRlXHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVGFibGUoKTtcclxuXHJcbiAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgIC8vIHNob3cgYSBtZXNzYWdlIGlmIHRoZXJlJ3Mgbm8gc2F2ZWQgdGFibGUgZGF0YSBmb3IgdGhlIHNlbGVjdGVkIGZ1bmRcclxuICAgICAgICAgICAgaWYgKHRoaXMubm9EYXRhTWVzc2FnZSkge1xyXG4gICAgICAgICAgICAgICAgUHJvbXB0LlRleHQudXBkYXRlKHRoaXMubm9EYXRhTWVzc2FnZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGluaXREYXRhVGFibGUoKSB7XHJcbiAgICAgICAgVGFibGUuYWRqdXN0V2lkdGgoJzEwMCUnKTtcclxuICAgICAgICAvLyBJbml0aWFsaXplIERhdGF0YWJsZXNcclxuICAgICAgICBpZiAoICEkLmZuLmRhdGFUYWJsZS5pc0RhdGFUYWJsZSgnI21haW4tdGFibGUnKSApIHtcclxuICAgICAgICAgICAgJCgnI21haW4tdGFibGUnKS5EYXRhVGFibGUoe1xyXG4gICAgICAgICAgICAgICAgcGFnaW5nOiBmYWxzZSwgLy8gRGlzYWJsZSBwYWdpbmF0aW9uXHJcbiAgICAgICAgICAgICAgICBpbmZvOiBmYWxzZSwgLy8gRGlzYWJsZSB0YWJsZSBpbmZvcm1hdGlvbiBkaXNwbGF5XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLy8gTW92ZSB0aGUgc2VhcmNoIGJhciBvdXRzaWRlIHRoZSB0YWJsZSBjb250YWluZXJcclxuICAgICAgICAkKCcjbWFpbi10YWJsZV9maWx0ZXInKS5hcHBlbmRUbygnI3NlYXJjaC1iYXItY29udGFpbmVyJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcGxhY2Vob2xkZXIgZm9yIGFjdGlvbiBvbiByb3cgZWRpdCBjbGlja1xyXG4gICAgYWN0aW9uT25FZGl0KCkgeyByZXR1cm4gfVxyXG5cclxuICAgIC8vIHVwZGF0ZSBmdW5jdGlvbiBmb3IgdGhlIHNpZGViYXI7IGRlZmF1bHQgdG8ganVzdCBzYXZpbmcgdGhlIHRhYmxlXHJcbiAgICB1cGRhdGVUYWJsZSgpIHsgVGFibGUuc2F2ZSgpIH1cclxuXHJcbiAgICAvLyBleHRyYSBxdWVzdGlvbnMgb2YgdGhlIGZvcm0gdG8gYWRkIGEgbmV3IHJvd1xyXG4gICAgYWRkQ3VzdG9tUXVlc3Rpb25zKCkgeyByZXR1cm4gfTtcclxuXHJcbiAgICBzZXRVcEZvcm0oKSB7XHJcbiAgICAgICAgLy8gc2hvdyBhZGQgYnV0dG9uXHJcbiAgICAgICAgVGFibGUuQnV0dG9ucy5BZGRSb3cuc2hvdygpO1xyXG4gICAgICAgIFRhYmxlLkJ1dHRvbnMuQWRkUm93LnVwZGF0ZVRleHQodGhpcy5hZGRCdXR0b25UZXh0KTtcclxuXHJcbiAgICAgICAgLy8gc2V0IHVwIG1vZGFsIGZvciBmb3JtIHdoZW4gYWRkIGJ1dHRvbiBpcyBwcmVzc2VkXHJcbiAgICAgICAgTW9kYWwuY2xlYXIoKTtcclxuICAgICAgICBNb2RhbC5MaW5rLmFkZCgnYWRkLWJ0bicpO1xyXG4gICAgICAgIE1vZGFsLlRpdGxlLnVwZGF0ZSh0aGlzLmFkZEJ1dHRvblRleHQpO1xyXG5cclxuICAgICAgICAvLyBjcmVhdGUgZm9ybVxyXG4gICAgICAgIEZvcm0ubmV3KCdtb2RhbC1ib2R5Jyk7XHJcblxyXG4gICAgICAgIC8vIGFkZCBjdXN0b20gcXVlc3Rpb25zXHJcbiAgICAgICAgdGhpcy5hZGRDdXN0b21RdWVzdGlvbnMoKTtcclxuICAgICAgICAvLyBhZGQgc3VibWl0IGJ1dHRvblxyXG4gICAgICAgIEZvcm0uU3VibWl0QnV0dG9uLmFkZCgpO1xyXG5cclxuICAgICAgICAvLyBJbml0aWFsaXplIGZvcm0gc3VibWlzc2lvbiB0byB0YWJsZSBkYXRhXHJcbiAgICAgICAgTW9kYWwuU3VibWl0LmluaXQodGhpcy5zdWJtaXROZXdSb3cpO1xyXG4gICAgfVxyXG5cclxuICAgIGVkaXRDb2x1bW5zKHJlc3BvbnNlcykgeyBcclxuICAgICAgICAvLyBnZXQgbnVtYmVycyBmcm9tIGFjY291bnQgc3RyaW5nIG5hbWVzXHJcbiAgICAgICAgaWYocmVzcG9uc2VzWydmdW5kLW5hbWUnXSl7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlc1snZnVuZCddID0gQWNjb3VudFN0cmluZy5nZXROdW1iZXIocmVzcG9uc2VzWydmdW5kLW5hbWUnXSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBpZihyZXNwb25zZXNbJ2FwcHJvcC1uYW1lJ10pe1xyXG4gICAgICAgICAgICByZXNwb25zZXNbJ2FwcHJvcCddID0gQWNjb3VudFN0cmluZy5nZXROdW1iZXIocmVzcG9uc2VzWydhcHByb3AtbmFtZSddKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmKHJlc3BvbnNlc1snY2MtbmFtZSddKXtcclxuICAgICAgICAgICAgcmVzcG9uc2VzWydjYyddID0gQWNjb3VudFN0cmluZy5nZXROdW1iZXIocmVzcG9uc2VzWydjYy1uYW1lJ10pO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgaWYocmVzcG9uc2VzWydvYmplY3QtbmFtZSddKXtcclxuICAgICAgICAgICAgcmVzcG9uc2VzWydvYmplY3QnXSA9IEFjY291bnRTdHJpbmcuZ2V0TnVtYmVyKHJlc3BvbnNlc1snb2JqZWN0LW5hbWUnXSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXNwb25zZXNbJ2FjY291bnQtc3RyaW5nJ10gPSBcclxuICAgICAgICAgICAgQWNjb3VudFN0cmluZy5idWlsZChyZXNwb25zZXNbJ2FwcHJvcC1uYW1lJ10sIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlc1snY2MtbmFtZSddLCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZXNbJ29iamVjdC1uYW1lJ10sIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlc1snZnVuZCddKTtcclxuICAgICAgICByZXR1cm4gcmVzcG9uc2VzO1xyXG4gICAgfVxyXG5cclxuICAgIHN1Ym1pdE5ld1JvdyhldmVudCkge1xyXG4gICAgICAgIC8vIGdldCBhbnN3ZXJzIGZyb20gZm9ybSwgaGlkZSBmb3JtLCBzaG93IGFuc3dlcnMgaW4gdGFibGVcclxuICAgICAgICB2YXIgcmVzcG9uc2VzID0gRm9ybS5mZXRjaEFsbFJlc3BvbnNlcyhldmVudCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gZWRpdCBpbnB1dHMgZnJvbSBtb2RhbFxyXG4gICAgICAgIHJlc3BvbnNlcyA9IHRoaXMuZWRpdENvbHVtbnMocmVzcG9uc2VzKTtcclxuICAgICAgICBcclxuICAgICAgICAvLyBtYWtlIHN1cmUgaXQncyBub3QgYW4gZW1wdHkgcmVzcG9uc2VcclxuICAgICAgICBpZiAoT2JqZWN0LnZhbHVlcyhyZXNwb25zZXMpWzBdICE9ICcnKXtcclxuXHJcbiAgICAgICAgICAgIC8vIGNoYW5nZSBwYWdlIHZpZXdcclxuICAgICAgICAgICAgTW9kYWwuaGlkZSgpO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gYWRkIGRhdGEgdG8gdGFibGVcclxuICAgICAgICAgICAgVGFibGUuUm93cy5hZGQocmVzcG9uc2VzLCB0aGlzLmNvbHVtbnMpO1xyXG4gICAgICAgICAgICBUYWJsZS5zYXZlKCk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyByZWJ1aWxkIHRhYmxlXHJcbiAgICAgICAgICAgIHRoaXMuYnVpbGQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG59IiwiXHJcbmltcG9ydCBXZWxjb21lIGZyb20gJy4uL2NvbXBvbmVudHMvd2VsY29tZS93ZWxjb21lLmpzJztcclxuaW1wb3J0IHsgVmlldyB9IGZyb20gJy4vdmlld19jbGFzcy5qcyc7XHJcbmltcG9ydCB7IHZpc2l0UGFnZSB9IGZyb20gJy4vdmlld19sb2dpYy5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgV2VsY29tZVZpZXcgZXh0ZW5kcyBWaWV3IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIHRoaXMucGFnZV9zdGF0ZSA9ICd3ZWxjb21lJztcclxuICAgICAgICB0aGlzLnN1YnRpdGxlID0gJ1dlbGNvbWUnO1xyXG4gICAgICAgIHRoaXMuc2lkZWJhciA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMubmF2QnV0dG9ucyA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHZpc2l0KCkge1xyXG4gICAgICAgIHN1cGVyLnZpc2l0KCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gc2hvdyB3ZWxjb21lIHNlY3Rpb25cclxuICAgICAgICBXZWxjb21lLnNob3coKTtcclxuXHJcbiAgICAgICAgLy8gaW5pdGlhbGl6ZSBsaW5rcyBpbiBidXR0b25zXHJcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0ZXAtdXBsb2FkJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB2aXNpdFBhZ2UoJ3VwbG9hZCcpKTtcclxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RlcC1pbml0aWF0aXZlcycpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdmlzaXRQYWdlKCduZXctaW5pdHMnKSk7XHJcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0ZXAtcmV2ZW51ZScpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdmlzaXRQYWdlKCdiYXNlbGluZS1sYW5kaW5nJykpO1xyXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGVwLWZpbmlzaCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdmlzaXRQYWdlKCdzdW1tYXJ5JykpO1xyXG5cclxuICAgIH1cclxuXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFdlbGNvbWVWaWV3O1xyXG4iLCJpbXBvcnQgeyBWaWV3IH0gZnJvbSAnLi92aWV3X2NsYXNzLmpzJ1xyXG5cclxuaW1wb3J0IEZpbGVVcGxvYWQgZnJvbSBcIi4uL2NvbXBvbmVudHMvZmlsZV91cGxvYWQvZmlsZV91cGxvYWQuanNcIjtcclxuaW1wb3J0IE5hdkJ1dHRvbnMgZnJvbSBcIi4uL2NvbXBvbmVudHMvbmF2X2J1dHRvbnMvbmF2X2J1dHRvbnMuanNcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBVcGxvYWRWaWV3IGV4dGVuZHMgVmlldyB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLnBhZ2Vfc3RhdGUgPSAndXBsb2FkJztcclxuICAgICAgICB0aGlzLnByb21wdCA9IGBVcGxvYWQgdGhlIGJhc2VsaW5lIGRldGFpbCBzaGVldCBnaXZlbiBieSB5b3VyIGJ1ZGdldCBhbmFseXN0LmA7XHJcbiAgICAgICAgdGhpcy5zdWJ0aXRsZSA9ICdFeGNlbCBVcGxvYWQnO1xyXG4gICAgICAgIHRoaXMuc2lkZWJhciA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHZpc2l0KCkge1xyXG4gICAgICAgIHN1cGVyLnZpc2l0KCk7XHJcbiAgICAgICAgLy8gZGlzYWJsZSBjb250aW51ZSBidXR0b24gdW50aWwgRXhjZWwgZmlsZSBpcyB1cGxvYWRlZCBhbmQgcmVhZFxyXG4gICAgICAgIE5hdkJ1dHRvbnMuTmV4dC5kaXNhYmxlKCk7XHJcbiAgICAgICAgRmlsZVVwbG9hZC5zaG93KCk7XHJcbiAgICAgICAgRmlsZVVwbG9hZC5pbml0KCk7XHJcbiAgICAgICAgTmF2QnV0dG9ucy5OZXh0LmVuYWJsZSgpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBVcGxvYWRWaWV3OyIsImltcG9ydCBOYXZCdXR0b25zIGZyb20gXCIuLi9jb21wb25lbnRzL25hdl9idXR0b25zL25hdl9idXR0b25zLmpzXCI7XHJcbmltcG9ydCBUYWJsZSBmcm9tIFwiLi4vY29tcG9uZW50cy90YWJsZS90YWJsZS5qc1wiO1xyXG5pbXBvcnQgeyBWaWV3LCBWaWV3VGFibGUgfSBmcm9tICcuL3ZpZXdfY2xhc3MuanMnXHJcbmltcG9ydCBDdXJyZW50RnVuZCBmcm9tIFwiLi4vbW9kZWxzL2N1cnJlbnRfZnVuZC5qc1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEZ1bmRWaWV3IGV4dGVuZHMgVmlldyB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLnBhZ2Vfc3RhdGUgPSAnYmFzZWxpbmUtbGFuZGluZyc7XHJcbiAgICAgICAgdGhpcy5wcm9tcHQgPSBgV2Ugd2lsbCBub3cgYXNrIHlvdSBhIHNlcmllcyBvZiBxdWVzdGlvbnMgYWJvdXQgeW91ciBCQVNFTElORSBidWRnZXQgcmVxdWVzdC5cclxuICAgICAgICAgICAgQXQgdGhlIGVuZCwgd2Ugd2lsbCBhc2sgeW91IGFib3V0IGFueSBuZXcgaW5pdGlhdGl2ZXMgKGllLiBzdXBwbGVtZW50YWwgcmVxdWVzdHMpLlxyXG4gICAgICAgICAgICBTZWxlY3Qgb25lIG9mIHlvdXIgZnVuZHMgdGhlbiBjbGljayBjb250aW51ZS5gO1xyXG4gICAgICAgIHRoaXMuc3VidGl0bGUgPSAnQmFzZWxpbmUgQnVkZ2V0IFJlcXVlc3QnO1xyXG4gICAgICAgIHRoaXMudGFibGUgPSBuZXcgRnVuZFRhYmxlKCk7XHJcbiAgICAgICAgdGhpcy5zaWRlYmFyID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5kYXRhVGFibGUgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICB2aXNpdCgpIHtcclxuICAgICAgICAvLyByZW1vdmUgZnVuZCBzZWxlY3Rpb25cclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShcImZ1bmRcIiwgJycpO1xyXG4gICAgICAgIHN1cGVyLnZpc2l0KCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmNsYXNzIEZ1bmRUYWJsZSBleHRlbmRzIFZpZXdUYWJsZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuXHJcbiAgICAgICAgLy8gYWRkIGFkZGl0aW9uYWwgcmV2ZW51ZSBjb2x1bW5zIHRvIHRoZSB0YWJsZVxyXG4gICAgICAgIHRoaXMuY29sdW1ucyA9IFtcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0Z1bmQnLCBjbGFzc05hbWU6ICdmdW5kLW5hbWUnIH1cclxuICAgICAgICBdO1xyXG5cclxuICAgICAgICB0aGlzLm5vRGF0YU1lc3NhZ2UgPSAnTm8gZnVuZHMgZm91bmQuJ1xyXG4gICAgICAgIHRoaXMuYWRkRWRpdCA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGJ1aWxkKCl7XHJcbiAgICAgICAgLy8gbG9hZCBpbiBmdW5kIGRhdGFcclxuICAgICAgICBUYWJsZS5zaG93KCk7XHJcbiAgICAgICAgVGFibGUuRGF0YS5sb2FkRnVuZHMoKTtcclxuICAgICAgICBUYWJsZS5Db2x1bW5zLmFzc2lnbkNsYXNzZXModGhpcy5jb2x1bW5zKTtcclxuICAgICAgICBUYWJsZS5hZGp1c3RXaWR0aCgnMzAlJyk7XHJcblxyXG4gICAgICAgIC8vIGRpc2FibGUgbmV4dCBidXR0b24gdW50aWwgYSBmdW5kIGlzIHNlbGVjdGVkXHJcbiAgICAgICAgTmF2QnV0dG9ucy5OZXh0LmRpc2FibGUoKTtcclxuICAgICAgICBhbGxvd1Jvd1NlbGVjdGlvbigpO1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuZnVuY3Rpb24gYWxsb3dSb3dTZWxlY3Rpb24oKXtcclxuICAgIFxyXG4gICAgdmFyIHRhYmxlUm93cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJ0Ym9keSB0clwiKTtcclxuICAgIFxyXG4gICAgLy8gZW5hYmxlIGhpZ2hsaWdodCBvbiBob3ZlciBhbmQgb24gc2VsZWN0XHJcbiAgICB0YWJsZVJvd3MuZm9yRWFjaChmdW5jdGlvbihyb3cpIHtcclxuICAgICAgICByb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnaG92ZXItZWZmZWN0Jyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3V0JywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2xhc3NMaXN0LnJlbW92ZSgnaG92ZXItZWZmZWN0Jyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGVjdEZ1bmQodGFibGVSb3dzLCB0aGlzKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZWxlY3RGdW5kKHRhYmxlUm93cywgc2VsZWN0ZWRfcm93KXtcclxuXHJcbiAgICAvLyByZW1vdmUgc2VsZWN0ZWQgY2xhc3MgZnJvbSBhbnkgb3RoZXIgcm93c1xyXG4gICAgdGFibGVSb3dzLmZvckVhY2goZnVuY3Rpb24odGFibGVSb3cpIHtcclxuICAgICAgICB0YWJsZVJvdy5jbGFzc0xpc3QgPSAnJztcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIGFkZCBzZWxlY3RlZCBjbGFzcyB0byBjbGlja2VkIHJvd1xyXG4gICAgc2VsZWN0ZWRfcm93LmNsYXNzTGlzdC5hZGQoJ3NlbGVjdGVkJyk7XHJcblxyXG4gICAgLy8gZ2V0IGZ1bmQgYW5kIHNhdmUgc2VsZWN0ZWQgZnVuZFxyXG4gICAgdmFyIGZ1bmQgPSBzZWxlY3RlZF9yb3cucXVlcnlTZWxlY3RvcignLmZ1bmQtbmFtZScpLnRleHRDb250ZW50O1xyXG4gICAgdmFyIGZ1bmROdW1iZXIgPSBwYXJzZUludChmdW5kKTtcclxuICAgIEN1cnJlbnRGdW5kLnVwZGF0ZShmdW5kTnVtYmVyKTtcclxuXHJcbiAgICAvLyBlbmFibGUgbmV4dCBzdGVwXHJcbiAgICBOYXZCdXR0b25zLk5leHQuZW5hYmxlKCk7XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEZ1bmRWaWV3OyIsImltcG9ydCB7IFZpZXcsIFZpZXdUYWJsZSB9IGZyb20gJy4vdmlld19jbGFzcy5qcydcclxuXHJcbmltcG9ydCBUYWJsZSBmcm9tICcuLi9jb21wb25lbnRzL3RhYmxlL3RhYmxlLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBSZXZlbnVlVmlldyBleHRlbmRzIFZpZXcge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGZpc2NhbF95ZWFyKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLnBhZ2Vfc3RhdGUgPSAncmV2ZW51ZSc7XHJcbiAgICAgICAgdGhpcy5wcm9tcHQgPSBgUmV2aWV3IGFuZCBlZGl0IHJldmVudWUgbGluZSBpdGVtcy4gSWYgeW91IGNoYW5nZSB0aGUgZXN0aW1hdGUgb3IgXHJcbiAgICAgICAgICAgIG5vdGljZSBhbiBlcnJvciBpbiBhbiBhY2NvdW50IHN0cmluZywgcGxlYXNlIG5vdGUgaXQgaW4gdGhlIG5vdGVzIGNvbHVtbi4gQ2xpY2sgZWRpdCBcclxuICAgICAgICAgICAgdG8gY2hhbmdlIHZhbHVlcyBpbiBhIHJvdy5gO1xyXG4gICAgICAgIHRoaXMuc3VidGl0bGUgPSAnUmV2ZW51ZXMnO1xyXG4gICAgICAgIHRoaXMudGFibGUgPSBuZXcgUmV2ZW51ZVRhYmxlKGZpc2NhbF95ZWFyKTtcclxuICAgIH1cclxufVxyXG5cclxuY2xhc3MgUmV2ZW51ZVRhYmxlIGV4dGVuZHMgVmlld1RhYmxlIHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihmaXNjYWxfeWVhcikge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcblxyXG4gICAgICAgIC8vIGFkZCBhZGRpdGlvbmFsIHJldmVudWUgY29sdW1ucyB0byB0aGUgdGFibGVcclxuICAgICAgICB0aGlzLmNvbHVtbnMgPSB0aGlzLmNvbHVtbnMuY29uY2F0KFtcclxuICAgICAgICAgICAgeyB0aXRsZTogJ1JlY3VycmluZyBvciBPbmUtVGltZScsIGNsYXNzTmFtZTogJ3JlY3VycmluZyd9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnT2JqZWN0IENhdGVnb3J5JywgY2xhc3NOYW1lOiAnb2JqZWN0LWNhdGVnb3J5J30sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6IGBGWSR7ZmlzY2FsX3llYXJ9IERlcGFydG1lbnRhbCBFc3RpbWF0ZWAsIGNsYXNzTmFtZTogJ3JlcXVlc3QnLCBpc0Nvc3Q6IHRydWV9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnRGVwYXJ0bWVudGFsIEVzdGltYXRlIE5vdGVzJywgY2xhc3NOYW1lOiAnbm90ZXMnfSxcclxuICAgICAgICBdKTtcclxuXHJcbiAgICAgICAgdGhpcy5ub0RhdGFNZXNzYWdlID0gJ05vIHJldmVudWVzIGZvciB0aGlzIGZ1bmQuJ1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGFjdGlvbiBvbiByb3cgZWRpdCBjbGljazogbWFrZSBjZWxscyBlZGl0YWJsZVxyXG4gICAgYWN0aW9uT25FZGl0KCkgeyBcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVRleHRib3goJ3JlcXVlc3QnLCB0cnVlKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVRleHRib3goJ25vdGVzJyk7XHJcbiAgICAgICAgVGFibGUuQ2VsbC5jcmVhdGVEcm9wZG93bigncmVjdXJyaW5nJywgWydPbmUtVGltZScsICdSZWN1cnJpbmcnXSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFJldmVudWVWaWV3OyIsImltcG9ydCB7IFZpZXcsIFZpZXdUYWJsZSB9IGZyb20gJy4vdmlld19jbGFzcy5qcydcclxuXHJcbmltcG9ydCBUYWJsZSBmcm9tIFwiLi4vY29tcG9uZW50cy90YWJsZS90YWJsZS5qc1wiO1xyXG5pbXBvcnQgRm9ybSBmcm9tIFwiLi4vY29tcG9uZW50cy9mb3JtL2Zvcm0uanNcIjtcclxuXHJcbmltcG9ydCB7IFNlcnZpY2VzLCBGdW5kTG9va3VwVGFibGUgfSBmcm9tICcuLi9tb2RlbHMvJztcclxuaW1wb3J0IHsgdW5mb3JtYXRDdXJyZW5jeSB9IGZyb20gXCIuLi91dGlscy9jb21tb25fdXRpbHMuanNcIjtcclxuaW1wb3J0IHsgRU1QTE9ZRUVfVFlQRVMgfSBmcm9tICcuLi9jb25zdGFudHMvYnVkZ2V0X2NvbnN0YW50cy5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgUGVyc29ubmVsVmlldyBleHRlbmRzIFZpZXcge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGZpc2NhbF95ZWFyKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLnBhZ2Vfc3RhdGUgPSAncGVyc29ubmVsJztcclxuICAgICAgICB0aGlzLnByb21wdCA9IGBcclxuICAgICAgICAgICAgVGhpcyB0YWJsZSBkaXNwbGF5cyB0aGUgbnVtYmVyIG9mIEZURXMgaW4gZWFjaCBqb2IgY29kZSBmb3IgaW4geW91ciBkZXBhcnRtZW50J3MgXHJcbiAgICAgICAgICAgIGN1cnJlbnQgKGFtZW5kZWQpIEZZMjUgYnVkZ2V0LiBUbyBtYWtlIGVkaXRzIHRvIHRoZSBudW1iZXIgb2YgcG9zaXRpb25zLCBjbGljayB0aGVcclxuICAgICAgICAgICAgXCJFZGl0XCIgYnV0dG9uIG9uIHRoZSByb3cgeW91IHdvdWxkIGxpa2UgdG8gZWRpdC4gVGhlIFwiVG90YWwgQ29zdFwiIGNvbHVtbiBhbmQgdGhlIFxyXG4gICAgICAgICAgICBzdW1tYXJ5IHNpZGViYXIgd2lsbCBhbHNvIHVwZGF0ZSB0byByZWZsZWN0IGFueSBlZGl0cy5gO1xyXG4gICAgICAgIHRoaXMuc3VidGl0bGUgPSAnUGVyc29ubmVsJztcclxuICAgICAgICB0aGlzLnRhYmxlID0gbmV3IFBlcnNvbm5lbFRhYmxlKGZpc2NhbF95ZWFyKTtcclxuICAgIH1cclxufVxyXG5cclxuXHJcbmNsYXNzIFBlcnNvbm5lbFRhYmxlIGV4dGVuZHMgVmlld1RhYmxlIHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihmaXNjYWxfeWVhcikge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy5maXNjYWxfeWVhciA9IGZpc2NhbF95ZWFyO1xyXG4gICAgICAgIC8vIGFkZCBhZGRpdGlvbmFsIHBlcnNvbm5lbCBjb2x1bW5zIHRvIHRoZSB0YWJsZVxyXG4gICAgICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuY29sdW1ucy5jb25jYXQoW1xyXG4gICAgICAgICAgICB7IHRpdGxlOiAnSm9iIFRpdGxlJywgY2xhc3NOYW1lOiAnam9iLW5hbWUnIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdFbXBsb3llZSBUeXBlJywgY2xhc3NOYW1lOiAnZW1wbG95ZWUtdHlwZSd9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnU2VydmljZScsIGNsYXNzTmFtZTogJ3NlcnZpY2UnIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6IGBGWSR7dGhpcy5maXNjYWxfeWVhcn0gUmVxdWVzdGVkIEZURWAsIGNsYXNzTmFtZTogJ2Jhc2VsaW5lLWZ0ZXMnIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6IGBGWSR7dGhpcy5maXNjYWxfeWVhcn0gUHJvamVjdGVkIEF2ZXJhZ2UgU2FsYXJ5L1dhZ2VgLCBjbGFzc05hbWU6ICdhdmctc2FsYXJ5JywgaXNDb3N0OiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdUb3RhbCBTYWwvV2FnICYgQmVuIFJlcXVlc3QnLCBjbGFzc05hbWU6ICd0b3RhbC1iYXNlbGluZScsIGlzQ29zdDogdHJ1ZSB9LFxyXG4gICAgICAgICAgICAvLyBoaWRkZW4gY29sdW1uc1xyXG4gICAgICAgICAgICB7IHRpdGxlOiAnRnJpbmdlIEJlbmVmaXRzIFJhdGUnLCBjbGFzc05hbWU6ICdmcmluZ2UnLCBoaWRlOiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdHZW5lcmFsIEluY3JlYXNlIFJhdGUnLCBjbGFzc05hbWU6ICdnZW5lcmFsLWluY3JlYXNlLXJhdGUnLCBoaWRlOiB0cnVlfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ1N0ZXAvTWVyaXQgSW5jcmVhc2UgUmF0ZScsIGNsYXNzTmFtZTogJ21lcml0LWluY3JlYXNlLXJhdGUnLCBoaWRlOiB0cnVlfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogYEF2ZXJhZ2UgU2FsYXJ5L1dhZ2UgYXMgb2YgOS8xLzIwJHt0aGlzLmZpc2NhbF95ZWFyLTJ9YCwgY2xhc3NOYW1lOiAnY3VycmVudC1zYWxhcnknLCBpc0Nvc3Q6IHRydWUsIGhpZGU6IHRydWV9XHJcbiAgICAgICAgXSk7XHJcblxyXG4gICAgICAgIHRoaXMubm9EYXRhTWVzc2FnZSA9ICdObyBwZXJzb25uZWwgZXhwZW5kaXR1cmVzIGZvciB0aGlzIGZ1bmQuJ1xyXG4gICAgICAgIHRoaXMuYWRkQnV0dG9uVGV4dCA9ICdBZGQgbmV3IGpvYicgO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGFjdGlvbiBvbiByb3cgZWRpdCBjbGljazogbWFrZSBjZWxscyBlZGl0YWJsZVxyXG4gICAgYWN0aW9uT25FZGl0KCkgeyBcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVRleHRib3goJ2Jhc2VsaW5lLWZ0ZXMnKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVNlcnZpY2VEcm9wZG93bihTZXJ2aWNlcy5saXN0KCkpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZVRhYmxlKCl7XHJcbiAgICAgICAgLy8gY2FsY3VsYXRlIGZvciBlYWNoIHJvd1xyXG4gICAgICAgIGxldCByb3dzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RyJyk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCByb3dzLmxlbmd0aDsgaSsrKXtcclxuICAgICAgICAgICAgLy8gZmV0Y2ggdmFsdWVzIGZvciBjYWxjdWxhdGlvbnNcclxuICAgICAgICAgICAgbGV0IGF2Z19zYWxhcnkgPSBUYWJsZS5DZWxsLmdldFZhbHVlKHJvd3NbaV0sICdhdmctc2FsYXJ5Jyk7XHJcbiAgICAgICAgICAgIGxldCBmcmluZ2UgPSBwYXJzZUZsb2F0KFRhYmxlLkNlbGwuZ2V0VGV4dChyb3dzW2ldLCAnZnJpbmdlJykpO1xyXG4gICAgICAgICAgICBsZXQgYmFzZWxpbmVfZnRlcyA9IFRhYmxlLkNlbGwuZ2V0VGV4dChyb3dzW2ldLCAnYmFzZWxpbmUtZnRlcycpO1xyXG5cclxuICAgICAgICAgICAgLy8gY2FsY3VhdGUgI0ZURXMgeCBhdmVyYWdlIHNhbGFyeSArIENPTEEgYWRqdXN0bWVudHMgKyBtZXJpdCBhZGp1c3RtZW50cyArIGZyaW5nZVxyXG4gICAgICAgICAgICBsZXQgdG90YWxfYmFzZWxpbmVfY29zdCA9IGF2Z19zYWxhcnkgKiBiYXNlbGluZV9mdGVzICogKDEgKyBmcmluZ2UpO1xyXG5cclxuICAgICAgICAgICAgLy8gdXBkYXRlIHRvdGFsIGNvbHVtblxyXG4gICAgICAgICAgICBUYWJsZS5DZWxsLnVwZGF0ZVZhbHVlKHJvd3NbaV0sICd0b3RhbC1iYXNlbGluZScsIHRvdGFsX2Jhc2VsaW5lX2Nvc3QpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU2F2ZSB0aGUgdGFibGUgYWZ0ZXIgYWxsIHVwZGF0ZXMgYXJlIGRvbmVcclxuICAgICAgICBUYWJsZS5zYXZlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkQ3VzdG9tUXVlc3Rpb25zKCl7XHJcbiAgICAgICAgLy8gZm9ybSBxdWVzdGlvbnMgdG8gYWRkIGEgbmV3IGpvYlxyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuc2hvcnRUZXh0KCdKb2IgVGl0bGU6JywgJ2pvYi1uYW1lJywgdHJ1ZSk7IFxyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oJ0VtcGxveWVlIFR5cGU6JywgJ2VtcGxveWVlLXR5cGUnLCBFTVBMT1lFRV9UWVBFUywgdHJ1ZSksXHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignQXBwcm9wcmlhdGlvbjonLCAnYXBwcm9wLW5hbWUnLCBGdW5kTG9va3VwVGFibGUuZ2V0QXBwcm9wcygpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdDb3N0IENlbnRlcjonLCAnY2MtbmFtZScsIEZ1bmRMb29rdXBUYWJsZS5nZXRDb3N0Q2VudGVycygpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdTZXJ2aWNlJywgJ3NlcnZpY2UnLCBTZXJ2aWNlcy5saXN0KCksIHRydWUpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuc2hvcnRUZXh0KCdOdW1iZXIgb2YgRlRFcyByZXF1ZXN0ZWQ6JywgJ2Jhc2VsaW5lLWZ0ZXMnLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLnNob3J0VGV4dChgUHJvamVjdGVkIGF2ZXJhZ2Ugc2FsYXJ5IElOIEZJU0NBTCBZRUFSICR7dGhpcy5maXNjYWxfeWVhcn06YCwgJ2F2Zy1zYWxhcnknLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLnNob3J0VGV4dChgRXhwZWN0ZWQgZnJpbmdlIHJhdGUgKGFzIGEgcGVyY2VudGFnZSlgLCAnZnJpbmdlJywgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWRpdENvbHVtbnMocmVzcG9uc2VzKXtcclxuICAgICAgICByZXNwb25zZXMgPSBzdXBlci5lZGl0Q29sdW1ucyhyZXNwb25zZXMpO1xyXG4gICAgICAgIC8vIGVkaXQgaW5wdXRzIGZyb20gbW9kYWxcclxuICAgICAgICByZXNwb25zZXNbJ2F2Zy1zYWxhcnknXSA9IHVuZm9ybWF0Q3VycmVuY3kocmVzcG9uc2VzWydhdmctc2FsYXJ5J10pO1xyXG4gICAgICAgIHJlc3BvbnNlc1snZnJpbmdlJ10gPSBwYXJzZUZsb2F0KHJlc3BvbnNlc1snZnJpbmdlJ10pIC8gMTAwO1xyXG4gICAgICAgIHJldHVybiByZXNwb25zZXM7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFBlcnNvbm5lbFZpZXc7IiwiXHJcblxyXG5pbXBvcnQgeyBWaWV3LCBWaWV3VGFibGUgfSBmcm9tICcuL3ZpZXdfY2xhc3MuanMnXHJcbmltcG9ydCBUYWJsZSBmcm9tICcuLi9jb21wb25lbnRzL3RhYmxlL3RhYmxlLmpzJztcclxuaW1wb3J0IEZvcm0gZnJvbSAnLi4vY29tcG9uZW50cy9mb3JtL2Zvcm0uanMnO1xyXG5pbXBvcnQgeyBGdW5kTG9va3VwVGFibGUsIFNlcnZpY2VzIH0gZnJvbSAnLi4vbW9kZWxzLyc7XHJcbmltcG9ydCB7IHVuZm9ybWF0Q3VycmVuY3kgfSBmcm9tICcuLi91dGlscy9jb21tb25fdXRpbHMuanMnO1xyXG5pbXBvcnQgeyBPVF9PQkpFQ1RTIH0gZnJvbSAnLi4vY29uc3RhbnRzLyc7XHJcblxyXG5leHBvcnQgY2xhc3MgT3ZlcnRpbWVWaWV3IGV4dGVuZHMgVmlldyB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZmlzY2FsX3llYXIpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIHRoaXMucGFnZV9zdGF0ZSA9ICdvdmVydGltZSc7XHJcbiAgICAgICAgdGhpcy5wcm9tcHQgPSBgXHJcbiAgICAgICAgICAgIFBsZWFzZSBzZWUgeW91ciBiYXNlbGluZSBvdmVydGltZSAvIGhvbGlkYXkgcGF5IC8gc2hpZnQgcHJlbWl1bXMgaW4gdGhlIHRhYmxlIGJlbG93LlxyXG4gICAgICAgICAgICBNYWtlIGFueSBlZGl0cyBhbmQgY29udGludWUuYDtcclxuICAgICAgICB0aGlzLnN1YnRpdGxlID0gJ092ZXJ0aW1lIEVzdGltYXRlcyc7XHJcbiAgICAgICAgdGhpcy50YWJsZSA9IG5ldyBPdmVydGltZVRhYmxlKGZpc2NhbF95ZWFyKTtcclxuICAgIH1cclxufVxyXG5cclxuY2xhc3MgT3ZlcnRpbWVUYWJsZSBleHRlbmRzIFZpZXdUYWJsZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZmlzY2FsX3llYXIpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG5cclxuICAgICAgICAvLyBhZGQgYWRkaXRpb25hbCBPVCBjb2x1bW5zIHRvIHRoZSB0YWJsZVxyXG4gICAgICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuY29sdW1ucy5jb25jYXQoW1xyXG4gICAgICAgICAgICB7IHRpdGxlOiAnU2VydmljZScsIGNsYXNzTmFtZTogJ3NlcnZpY2UnIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdSZWN1cnJpbmcgb3IgT25lLVRpbWUnLCBjbGFzc05hbWU6ICdyZWN1cnJpbmcnfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0RlcGFydG1lbnRhbCBSZXF1ZXN0IE9UL1NQL0hvbCcsIGNsYXNzTmFtZTogJ09ULXBheScsIGlzQ29zdDogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiBgRlkke2Zpc2NhbF95ZWFyfSBUb3RhbCBPVC9TUC9Ib2wgKyBGSUNBIFJlcXVlc3RgLCBjbGFzc05hbWUgOiAndG90YWwnLCBpc0Nvc3Q6IHRydWV9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnT2JqZWN0IE5hbWUnLCBjbGFzc05hbWU6ICdvYmplY3QtbmFtZSd9LFxyXG4gICAgICAgICAgICAvLyBoaWRkZW4gY29sdW1uc1xyXG4gICAgICAgICAgICB7IHRpdGxlOiAnRklDQSBSYXRlJywgY2xhc3NOYW1lOiAnZmljYScsIGhpZGU6IHRydWV9LFxyXG4gICAgICAgIF0pO1xyXG5cclxuICAgICAgICB0aGlzLm5vRGF0YU1lc3NhZ2UgPSAnTm8gb3ZlcnRpbWUgZXhwZW5kaXR1cmVzIGZvciB0aGlzIGZ1bmQuJ1xyXG4gICAgICAgIHRoaXMuYWRkQnV0dG9uVGV4dCA9ICdBZGQgbmV3IGNvc3QgY2VudGVyJyA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYWN0aW9uIG9uIHJvdyBlZGl0IGNsaWNrOiBtYWtlIGNlbGxzIGVkaXRhYmxlXHJcbiAgICBhY3Rpb25PbkVkaXQoKSB7IFxyXG4gICAgICAgIFRhYmxlLkNlbGwuY3JlYXRlVGV4dGJveCgnT1QtcGF5JywgdHJ1ZSk7XHJcbiAgICAgICAgVGFibGUuQ2VsbC5jcmVhdGVTZXJ2aWNlRHJvcGRvd24oU2VydmljZXMubGlzdCgpKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZURyb3Bkb3duKCdyZWN1cnJpbmcnLCBbJ09uZS1UaW1lJywgJ1JlY3VycmluZyddKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZURyb3Bkb3duKCdvYmplY3QtbmFtZScsIE9UX09CSkVDVFMpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZVRhYmxlKCl7XHJcblxyXG4gICAgICAgIC8vIGNhbGN1bGF0ZSBmb3IgZWFjaCByb3dcclxuICAgICAgICBsZXQgcm93cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCd0cicpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcm93cy5sZW5ndGg7IGkrKyl7XHJcbiAgICAgICAgICAgIC8vIGZldGNoIHZhbHVlcyBmb3IgY2FsY3VsYXRpb25zXHJcbiAgICAgICAgICAgIGxldCBPVF9zYWxhcnkgPSBUYWJsZS5DZWxsLmdldFZhbHVlKHJvd3NbaV0sICdPVC1wYXknKTtcclxuICAgICAgICAgICAgbGV0IGZpY2FfcmF0ZSA9IFRhYmxlLkNlbGwuZ2V0VGV4dChyb3dzW2ldLCAnZmljYScpO1xyXG5cclxuICAgICAgICAgICAgLy8gYWRkIHNhbGFyeSBhbmQgd2FnZXMgYW5kIGZyaW5nZSBiZW5lZml0cyAoRklDQSlcclxuICAgICAgICAgICAgbGV0IHJvd190b3RhbCA9IE9UX3NhbGFyeSAqICgxICsgcGFyc2VGbG9hdChmaWNhX3JhdGUpKTtcclxuXHJcbiAgICAgICAgICAgIC8vIHVwZGF0ZSB0b3RhbFxyXG4gICAgICAgICAgICBUYWJsZS5DZWxsLnVwZGF0ZVZhbHVlKHJvd3NbaV0sICd0b3RhbCcsIHJvd190b3RhbCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTYXZlIHRoZSB0YWJsZSBhZnRlciBhbGwgdXBkYXRlcyBhcmUgZG9uZVxyXG4gICAgICAgIFRhYmxlLnNhdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRDdXN0b21RdWVzdGlvbnMoKXtcclxuICAgICAgICAvLyBmb3JtIHF1ZXN0aW9ucyB0byBhZGQgYSBuZXcgam9iXHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignQXBwcm9wcmlhdGlvbjonLCAnYXBwcm9wLW5hbWUnLCBGdW5kTG9va3VwVGFibGUuZ2V0QXBwcm9wcygpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdDb3N0IENlbnRlcjonLCAnY2MtbmFtZScsIEZ1bmRMb29rdXBUYWJsZS5nZXRDb3N0Q2VudGVycygpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdPYmplY3QgKHNhbGFyeSBvciB3YWdlKTonLCAnb2JqZWN0LW5hbWUnLCBPVF9PQkpFQ1RTLCB0cnVlKTsgXHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignU2VydmljZScsICdzZXJ2aWNlJywgU2VydmljZXMubGlzdCgpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdSZWN1cnJpbmcgb3IgT25lLVRpbWUnLCAncmVjdXJyaW5nJywgWydSZWN1cnJpbmcnLCAnT25lLVRpbWUnXSwgdHJ1ZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5zaG9ydFRleHQoJ092ZXJ0aW1lIGFtb3VudCByZXF1ZXN0ZWQ6JywgJ09ULXBheScsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGVkaXRDb2x1bW5zKHJlc3BvbnNlcyl7XHJcbiAgICAgICAgcmVzcG9uc2VzID0gc3VwZXIuZWRpdENvbHVtbnMocmVzcG9uc2VzKTtcclxuICAgICAgICAvLyBlZGl0IGlucHV0cyBmcm9tIG1vZGFsXHJcbiAgICAgICAgcmVzcG9uc2VzWydPVC1wYXknXSA9IHVuZm9ybWF0Q3VycmVuY3kocmVzcG9uc2VzWydPVC1wYXknXSk7XHJcbiAgICAgICAgcmVzcG9uc2VzWydmaWNhJ10gPSAwLjA3NjU7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlcztcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgT3ZlcnRpbWVWaWV3OyIsImltcG9ydCB7IFZpZXcsIFZpZXdUYWJsZSB9IGZyb20gJy4vdmlld19jbGFzcy5qcydcclxuaW1wb3J0IEZvcm0gZnJvbSAnLi4vY29tcG9uZW50cy9mb3JtL2Zvcm0uanMnO1xyXG5pbXBvcnQgVGFibGUgZnJvbSAnLi4vY29tcG9uZW50cy90YWJsZS90YWJsZS5qcyc7XHJcbmltcG9ydCB7IEZ1bmRMb29rdXBUYWJsZSwgU2VydmljZXMgfSBmcm9tICcuLi9tb2RlbHMvJztcclxuaW1wb3J0IHsgdW5mb3JtYXRDdXJyZW5jeSB9IGZyb20gJy4uL3V0aWxzL2NvbW1vbl91dGlscy5qcyc7XHJcbmltcG9ydCB7IE9CSl9DQVRFR09SSUVTIH0gZnJvbSAnLi4vY29uc3RhbnRzLyc7XHJcblxyXG5leHBvcnQgY2xhc3MgTm9uUGVyc29ubmVsVmlldyBleHRlbmRzIFZpZXcge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGZpc2NhbF95ZWFyKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLnBhZ2Vfc3RhdGUgPSAnbm9ucGVyc29ubmVsJztcclxuICAgICAgICB0aGlzLnByb21wdCA9ICdSZXZpZXcgYW5kIGVkaXQgbm9uLXBlcnNvbm5lbCBsaW5lIGl0ZW1zLic7XHJcbiAgICAgICAgdGhpcy5zdWJ0aXRsZSA9ICdOb24tUGVyc29ubmVsJztcclxuICAgICAgICB0aGlzLnRhYmxlID0gbmV3IE5vblBlcnNvbm5lbFRhYmxlKGZpc2NhbF95ZWFyKTtcclxuICAgIH1cclxufVxyXG5cclxuY2xhc3MgTm9uUGVyc29ubmVsVGFibGUgZXh0ZW5kcyBWaWV3VGFibGUge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGZpc2NhbF95ZWFyKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuXHJcbiAgICAgICAgLy8gYWRkIGFkZGl0aW9uYWwgcGVyc29ubmVsIGNvbHVtbnMgdG8gdGhlIHRhYmxlXHJcbiAgICAgICAgdGhpcy5jb2x1bW5zID0gdGhpcy5jb2x1bW5zLmNvbmNhdChbXHJcbiAgICAgICAgICAgIHsgdGl0bGU6IGBGWSR7ZmlzY2FsX3llYXJ9IERlcGFydG1lbnRhbCBSZXF1ZXN0IFRvdGFsYCwgY2xhc3NOYW1lOiAncmVxdWVzdCcsIGlzQ29zdDogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnU2VydmljZScsIGNsYXNzTmFtZSA6ICdzZXJ2aWNlJyB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnUmVjdXJyaW5nIG9yIE9uZS1UaW1lJywgY2xhc3NOYW1lOiAncmVjdXJyaW5nJ30sXHJcbiAgICAgICAgICAgIHsgdGl0bGUgOiAnQ1BBICMnLCBjbGFzc05hbWUgOiAnY3BhJ30sXHJcbiAgICAgICAgICAgIC8vIGhpZGRlbiBjb2x1bW5zXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdFbmQgRGF0ZScsIGNsYXNzTmFtZTogJ2NvbnRyYWN0LWVuZCcsIGhpZGU6IHRydWV9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnQlBBL0NQQSBBbW91bnQgUmVtYWluaW5nJywgY2xhc3NOYW1lOiAncmVtYWluaW5nJywgaXNDb3N0OiB0cnVlICwgaGlkZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdPYmplY3QgTmFtZScsIGNsYXNzTmFtZTogJ29iamVjdC1uYW1lJywgaGlkZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdPYmplY3QnLCBjbGFzc05hbWU6ICdvYmplY3QnLCBoaWRlOiB0cnVlfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ1ZlbmRvciBOYW1lJywgY2xhc3NOYW1lOiAndmVuZG9yJywgaGlkZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdPYmplY3QgQ2F0ZWdvcnknLCBjbGFzc05hbWU6ICdvYmplY3QtY2F0ZWdvcnknLCBoaWRlOiB0cnVlfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0JQQS9DUEEgRGVzY3JpcHRpb24nLCBjbGFzc05hbWU6ICdjcGEtZGVzY3JpcHRpb24nLCBoaWRlOiB0cnVlfSBcclxuICAgICAgICBdKTtcclxuXHJcbiAgICAgICAgdGhpcy5ub0RhdGFNZXNzYWdlID0gJ05vIG5vbi1wZXJzb25uZWwgZXhwZW5kaXR1cmVzIGZvciB0aGlzIGZ1bmQuJ1xyXG4gICAgICAgIHRoaXMuYWRkQnV0dG9uVGV4dCA9ICdBZGQgbmV3IGpvYicgO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGFjdGlvbiBvbiByb3cgZWRpdCBjbGljazogbWFrZSBjZWxscyBlZGl0YWJsZVxyXG4gICAgYWN0aW9uT25FZGl0KCkgeyBcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVRleHRib3goJ3JlcXVlc3QnLCB0cnVlKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVNlcnZpY2VEcm9wZG93bigpO1xyXG4gICAgICAgIFRhYmxlLkNlbGwuY3JlYXRlRHJvcGRvd24oJ3JlY3VycmluZycsIFsnT25lLVRpbWUnLCAnUmVjdXJyaW5nJ10pO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZEN1c3RvbVF1ZXN0aW9ucygpe1xyXG4gICAgICAgIC8vIGZvcm0gcXVlc3Rpb25zIHRvIGFkZCBhIG5ldyByb3dcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdBcHByb3ByaWF0aW9uOicsICdhcHByb3AtbmFtZScsIEZ1bmRMb29rdXBUYWJsZS5nZXRBcHByb3BzKCksIHRydWUpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oJ0Nvc3QgQ2VudGVyOicsICdjYy1uYW1lJywgRnVuZExvb2t1cFRhYmxlLmdldENvc3RDZW50ZXJzKCksIHRydWUpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oJ09iamVjdCBDYXRlZ29yeTonLCAnb2JqZWN0LWNhdGVnb3J5JywgT0JKX0NBVEVHT1JJRVMubGlzdCwgdHJ1ZSk7XHJcbiAgICAgICAgLy8gVE9ETzogbWF5YmUgZ2l2ZSBkcm9wZG93biBiYXNlZCBvbiBzZWxlY3RlZCBvYmogY2F0ZWdvcnlcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLnNob3J0VGV4dCgnT2JqZWN0IE51bWJlciAoaWYga25vd24pOicsICdvYmplY3QnLCBmYWxzZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignU2VydmljZScsICdzZXJ2aWNlJywgU2VydmljZXMubGlzdCgpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmxvbmdUZXh0KCdEZXNjcmliZSB5b3VyIG5ldyByZXF1ZXN0OicsICdjcGEtZGVzY3JpcHRpb24nLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdSZWN1cnJpbmcgb3IgT25lLVRpbWUnLCAncmVjdXJyaW5nJywgWydSZWN1cnJpbmcnLCAnT25lLVRpbWUnXSwgdHJ1ZSk7IFxyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuc2hvcnRUZXh0KCdBbW91bnQgcmVxdWVzdGVkOicsICdyZXF1ZXN0JywgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWRpdENvbHVtbnMocmVzcG9uc2VzKXtcclxuICAgICAgICByZXNwb25zZXMgPSBzdXBlci5lZGl0Q29sdW1ucyhyZXNwb25zZXMpO1xyXG4gICAgICAgIHJlc3BvbnNlc1snYXZnLXNhbGFyeSddID0gdW5mb3JtYXRDdXJyZW5jeShyZXNwb25zZXNbJ2F2Zy1zYWxhcnknXSk7XHJcbiAgICAgICAgcmVzcG9uc2VzWydmcmluZ2UnXSA9IHBhcnNlRmxvYXQocmVzcG9uc2VzWydmcmluZ2UnXSkgLyAxMDA7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlcztcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgTm9uUGVyc29ubmVsVmlldzsiLCJcclxuaW1wb3J0IHsgVmlldywgVmlld1RhYmxlIH0gZnJvbSAnLi92aWV3X2NsYXNzLmpzJ1xyXG5pbXBvcnQgVGFibGUgZnJvbSBcIi4uL2NvbXBvbmVudHMvdGFibGUvdGFibGUuanNcIjtcclxuaW1wb3J0IEZvcm0gZnJvbSBcIi4uL2NvbXBvbmVudHMvZm9ybS9mb3JtLmpzXCI7XHJcbmltcG9ydCBGdW5kTG9va3VwVGFibGUgZnJvbSAnLi4vbW9kZWxzL2Z1bmRfbG9va3VwX3RhYmxlLmpzJztcclxuaW1wb3J0IHsgRklTQ0FMX1lFQVIgfSBmcm9tICcuLi9jb25zdGFudHMvJztcclxuXHJcblxyXG5jb25zdCBkcm9wZG93bk9wdGlvbnMgPSBbJ04vQScsICdPbmUtVGltZScsICdSZWN1cnJpbmcnXVxyXG5cclxuLy8gc2V0IHVwIHBhZ2UgYW5kIGluaXRpYWxpemUgYWxsIGJ1dHRvbnNcclxuZXhwb3J0IGNsYXNzIEluaXRpYXRpdmVzVmlldyBleHRlbmRzIFZpZXcge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy5wYWdlX3N0YXRlID0gJ25ldy1pbml0cyc7XHJcbiAgICAgICAgdGhpcy5wcm9tcHQgPSBgXHJcbiAgICAgICAgICAgIFRoaXMgaXMgdGhlIHBsYWNlIHRvIHByb3Bvc2UgbmV3IGluaXRpYXRpdmVzIGZvciBGWSR7RklTQ0FMX1lFQVJ9LlxyXG4gICAgICAgICAgICBOZXcgaW5pdGlhdGl2ZSBzdWJtaXNzaW9ucyB3aWxsIGNvdW50IGFzIHN1cHBsZW1lbnRhbCBsaW5lIGl0ZW1zIGFuZCB3aWxsIGJlIHRoZSBzdGFydGluZyBcclxuICAgICAgICAgICAgcG9pbnQgZm9yIGEgY29udmVyc2F0aW9uIHdpdGggYm90aCBPQiBhbmQgT0RGUywgd2hvIHdpbGwgaGVscCB3aXRoIHRoZSBkZXRhaWxzLmA7XHJcbiAgICAgICAgdGhpcy5zdWJ0aXRsZSA9ICdOZXcgSW5pdGlhdGl2ZXMnO1xyXG4gICAgICAgIHRoaXMudGFibGUgPSBuZXcgSW5pdGlhdGl2ZXNUYWJsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHZpc2l0KCkge1xyXG4gICAgICAgIC8vIHJlbW92ZSBmdW5kIHNlbGVjdGlvblxyXG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFwiZnVuZFwiLCAnJyk7XHJcbiAgICAgICAgc3VwZXIudmlzaXQoKTtcclxuICAgIH1cclxuXHJcbn1cclxuXHJcbmNsYXNzIEluaXRpYXRpdmVzVGFibGUgZXh0ZW5kcyBWaWV3VGFibGUge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcblxyXG4gICAgICAgIC8vIGFkZCBhZGRpdGlvbmFsIGNvbHVtbnMgdG8gdGhlIHRhYmxlXHJcbiAgICAgICAgdGhpcy5jb2x1bW5zID0gdGhpcy5jb2x1bW5zLmNvbmNhdChbXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdJbml0aWF0aXZlIE5hbWUnLCBjbGFzc05hbWU6ICdpbml0LW5hbWUnIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdCYWxscGFyayBUb3RhbCBFeHBlbnNlcycsIGNsYXNzTmFtZTogJ3RvdGFsJywgaXNDb3N0OiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdQZXJzb25uZWwgQ29zdCcsIGNsYXNzTmFtZTogJ3BlcnNvbm5lbCcsIGlzQ29zdDogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnTm9uLXBlcnNvbm5lbCBDb3N0JywgY2xhc3NOYW1lOiAnbm9ucGVyc29ubmVsJywgaXNDb3N0OiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdSZXZlbnVlJywgY2xhc3NOYW1lOiAncmV2ZW51ZScsIGlzQ29zdDogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnUmV2ZW51ZSBUeXBlJywgY2xhc3NOYW1lOiAncmV2LXR5cGUnIH0sXHJcblxyXG4gICAgICAgICAgICAvLyBoaWRlIHRoZSBleHBsYW5hdGlvbiBjb2x1bW5zXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdRMScsIGNsYXNzTmFtZTogJ3ExJywgaGlkZTogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnUTInLCBjbGFzc05hbWU6ICdxMicsIGhpZGU6IHRydWUgfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ1EzJywgY2xhc3NOYW1lOiAncTMnLCBoaWRlOiB0cnVlIH1cclxuICAgICAgICBdKTtcclxuXHJcbiAgICAgICAgdGhpcy5hZGRCdXR0b25UZXh0ID0gJ0FkZCBuZXcgaW5pdGlhdGl2ZScgO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZEN1c3RvbVF1ZXN0aW9ucygpe1xyXG5cclxuICAgICAgICAvLyBnZW5lcmFsIHF1ZXN0aW9uc1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuc2hvcnRUZXh0KCdJbml0aWF0aXZlIE5hbWU6JywgJ2luaXQtbmFtZScsIHRydWUpOyBcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmxvbmdUZXh0KCdXaGF0IGlzIHRoZSBidXNpbmVzcyBjYXNlIGZvciB0aGUgSW5pdGlhdGl2ZT8nLCAncTEnLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmxvbmdUZXh0KGBXaHkgaXMgdGhlIGluaXRpYXRpdmUgbmVlZGVkPyBXaGF0IGlzIHRoZSB2YWx1ZS1hZGQgdG8gcmVzaWRlbnRzPyBcclxuICAgICAgICAgICAgV2hhdCBpcyB0aGUgRGVwYXJ0bWVudOKAmXMgcGxhbiBmb3IgaW1wbGVtZW50aW5nIHRoZSBJbml0aWF0aXZlP2AsICdxMicsIHRydWUpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQubG9uZ1RleHQoYFdoeSBjYW7igJl0IHRoZSBJbml0aWF0aXZlIGJlIGZ1bmRlZCB3aXRoIHRoZSBEZXBhcnRtZW504oCZcyBiYXNlbGluZSBidWRnZXQ/YCwgJ3EzJywgdHJ1ZSk7XHJcblxyXG4gICAgICAgIC8vIFRPRE86IEVkaXQgdG8gZHJvcCBkb3duXHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignRnVuZDonLCAnZnVuZC1uYW1lJywgRnVuZExvb2t1cFRhYmxlLmxpc3RGdW5kTmFtZXMoKSwgdHJ1ZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignQXBwcm9wcmlhdGlvbiAoaWYga25vd24pOicsICdhcHByb3AtbmFtZScsIEZ1bmRMb29rdXBUYWJsZS5nZXRBcHByb3BzKCksIHRydWUpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oJ0Nvc3QgQ2VudGVyIChpZiBrbm93bik6JywgJ2NjLW5hbWUnLCBGdW5kTG9va3VwVGFibGUuZ2V0Q29zdENlbnRlcnMoKSwgdHJ1ZSk7XHJcblxyXG4gICAgICAgIC8vIE51bWJlcnNcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLm51bWVyaWNJbnB1dCgnV2hhdCBpcyB5b3VyIGJhbGxwYXJrIGVzdGltYXRlIG9mIFRPVEFMIEFERElUT05BTCBleHBlbnNlcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBpbml0aWF0aXZlPycsIFxyXG4gICAgICAgICAgICAndG90YWwnLCBmYWxzZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5udW1lcmljSW5wdXQoJ0VzdGltYXRlIG9mIEFERElUT05BTCBwZXJzb25uZWwgY29zdD8nLCAncGVyc29ubmVsJywgZmFsc2UpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQubnVtZXJpY0lucHV0KCdFc3RpbWF0ZSBvZiBBRERJVE9OQUwgbm9ucGVyc29ubmVsIGNvc3Q/JywgJ25vbnBlcnNvbm5lbCcsIGZhbHNlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLm51bWVyaWNJbnB1dCgnRXN0aW1hdGUgb2YgQURESVRPTkFMIHJldmVudWUgKGlmIGFwcGxpY2FibGUpPycsICdyZXZlbnVlJywgZmFsc2UpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oYElmIHRoZXJlIHdpbGwgYmUgcmV2ZW51ZSwgaXMgaXQgb25lLXRpbWUgb3IgcmVjdXJyaW5nP2AsIFxyXG4gICAgICAgICAgICAncmV2LXR5cGUnLCBkcm9wZG93bk9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGFjdGlvbiBvbiByb3cgZWRpdCBjbGljazogbWFrZSBjZWxscyBlZGl0YWJsZVxyXG4gICAgYWN0aW9uT25FZGl0KCkgeyBcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVRleHRib3goJ3RvdGFsJywgdHJ1ZSk7XHJcbiAgICAgICAgVGFibGUuQ2VsbC5jcmVhdGVUZXh0Ym94KCdyZXZlbnVlJywgdHJ1ZSk7XHJcbiAgICAgICAgVGFibGUuQ2VsbC5jcmVhdGVUZXh0Ym94KCdwZXJzb25uZWwnLCB0cnVlKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVRleHRib3goJ25vbnBlcnNvbm5lbCcsIHRydWUpO1xyXG4gICAgICAgIFRhYmxlLkNlbGwuY3JlYXRlVGV4dGJveCgnaW5pdC1uYW1lJyk7XHJcbiAgICAgICAgVGFibGUuQ2VsbC5jcmVhdGVEcm9wZG93bigncmV2LXR5cGUnLCBkcm9wZG93bk9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgSW5pdGlhdGl2ZXNWaWV3OyIsImltcG9ydCBDdXJyZW50RnVuZCBmcm9tICcuLi9tb2RlbHMvY3VycmVudF9mdW5kLmpzJztcclxuaW1wb3J0IEJhc2VsaW5lIGZyb20gJy4uL21vZGVscy9iYXNlbGluZS5qcyc7XHJcbmltcG9ydCB7IEFjY29yZGlvbiB9IGZyb20gXCIuLi9jb21wb25lbnRzL2FjY29yZGlvbi9hY2NvcmRpb24uanNcIjtcclxuaW1wb3J0IHsgZm9ybWF0Q3VycmVuY3kgfSBmcm9tICcuLi91dGlscy9jb21tb25fdXRpbHMuanMnO1xyXG5pbXBvcnQgeyBWaWV3IH0gZnJvbSBcIi4vdmlld19jbGFzcy5qc1wiO1xyXG5pbXBvcnQgUHJvbXB0IGZyb20gXCIuLi9jb21wb25lbnRzL3Byb21wdC9wcm9tcHQuanNcIjtcclxuaW1wb3J0IHsgZG93bmxvYWRYTFNYIH0gZnJvbSBcIi4uL3V0aWxzL1hMU1hfaGFuZGxlcnMuanNcIjtcclxuaW1wb3J0IFdlbGNvbWVWaWV3IGZyb20gJy4vMDBfd2VsY29tZS5qcyc7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY29tcGFyZVRvVGFyZ2V0KCl7XHJcbiAgICBjb25zdCBiYXNlbGluZSA9IG5ldyBCYXNlbGluZTtcclxuICAgIGlmIChiYXNlbGluZS50b3RhbCgpIDw9IEJhc2VsaW5lLnRhcmdldCgpKXtcclxuICAgICAgICBQcm9tcHQuVGV4dC51cGRhdGUoYENvbmdyYXRzISBZb3VyIGJ1ZGdldCBpcyBiZWxvdyB5b3VyIHRhcmdldCEgXHJcbiAgICAgICAgICAgIEVkaXQgYW55IGxpbmUgaXRlbXMgYmVsb3cgb3IgZG93bmxvYWQgeW91ciBjb21wbGV0ZWQgRXhjZWwuYCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIFByb21wdC5UZXh0LnVwZGF0ZShgWW91ciBidWRnZXQgaXMgYWJvdmUgeW91ciB0YXJnZXQgb2YgJHtmb3JtYXRDdXJyZW5jeShCYXNlbGluZS50YXJnZXQoKSl9LiBcclxuICAgICAgICAgICAgUGxlYXNlIGV4cGFuZCB0aGUgc3VtbWFyeSB0YWJsZSBiZWxvdyBhbmQgZWRpdCBsaW5lIGl0ZW1zIHVudGlsIHlvdSBtZWV0IHlvdXIgdGFyZ2V0LiBcclxuICAgICAgICAgICAgV2hlbiB5b3UgbWVldCB0aGUgdGFyZ2V0LCB5b3Ugd2lsbCBiZSBhYmxlIHRvIGRvd25sb2FkIHRoZSBFeGNlbCBzaGVldC5gKTtcclxuICAgICAgICBQcm9tcHQuQnV0dG9ucy5SaWdodC5kaXNhYmxlKCk7XHJcbiAgICB9XHJcbiAgICBQcm9tcHQuc2hvdygpO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZXR1cm5Ub1dlbGNvbWUoKSB7XHJcbiAgICBjb25zdCB3ZWxjb21lID0gbmV3IFdlbGNvbWVWaWV3KCk7XHJcbiAgICBjb25zdCBsZWZ0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ29wdGlvbjEnKTtcclxuICAgIGNvbnNvbGUubG9nKGxlZnQubClcclxuICAgIHdlbGNvbWUudmlzaXQoKTtcclxufTtcclxuXHJcbmV4cG9ydCBjbGFzcyBTdW1tYXJ5VmlldyBleHRlbmRzIFZpZXcge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy5wYWdlX3N0YXRlID0gJ3N1bW1hcnknO1xyXG4gICAgICAgIHRoaXMuc3VidGl0bGUgPSAnU3VtbWFyeSc7XHJcbiAgICAgICAgdGhpcy5zaWRlYmFyID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgdmlzaXQoKSB7XHJcbiAgICAgICAgc3VwZXIudmlzaXQoKTtcclxuXHJcbiAgICAgICAgLy8gcmVzZXQgZnVuZFxyXG4gICAgICAgIEN1cnJlbnRGdW5kLnJlc2V0KCk7XHJcblxyXG4gICAgICAgIC8vIHNob3cgc3VtbWFyeSBhY2NvcmRpb25cclxuICAgICAgICBBY2NvcmRpb24uYnVpbGQoKTtcclxuICAgICAgICBBY2NvcmRpb24uc2hvdygpO1xyXG5cclxuICAgICAgICAvLyBhZGQgcHJvbXB0IGJ1dHRvbnNcclxuICAgICAgICBQcm9tcHQuQnV0dG9ucy5SaWdodC51cGRhdGVUZXh0KCdEb3dubG9hZCBFeGNlbCcpO1xyXG4gICAgICAgIFByb21wdC5CdXR0b25zLkxlZnQudXBkYXRlVGV4dCgnU3RhcnQgb3ZlciB3aXRoIG5ldyBFeGNlbCB1cGxvYWQnKTtcclxuICAgICAgICAvLyBhZGQgYnV0dG9uIGxpbmtzXHJcbiAgICAgICAgUHJvbXB0LkJ1dHRvbnMuTGVmdC5hZGRBY3Rpb24ocmV0dXJuVG9XZWxjb21lKTtcclxuICAgICAgICBQcm9tcHQuQnV0dG9ucy5SaWdodC5hZGRBY3Rpb24oZG93bmxvYWRYTFNYKTtcclxuXHJcbiAgICAgICAgLy8gdXBkYXRlIHByb21wdCB0ZXh0IGRlcGVuZGluZyBvbiB0YXJnZXQgbWF0Y2hpbmdcclxuICAgICAgICBjb21wYXJlVG9UYXJnZXQoKTtcclxuICAgIH1cclxuXHJcbiAgICBjbGVhbnVwKCkge1xyXG4gICAgICAgIC8vIGRlbGV0ZSBldmVudCBsaXN0ZW5lcnNcclxuICAgICAgICBQcm9tcHQuQnV0dG9ucy5MZWZ0LnJlbW92ZUFjdGlvbihyZXR1cm5Ub1dlbGNvbWUpO1xyXG4gICAgICAgIFByb21wdC5CdXR0b25zLlJpZ2h0LnJlbW92ZUFjdGlvbihkb3dubG9hZFhMU1gpO1xyXG4gICAgICAgIFByb21wdC5CdXR0b25zLlJpZ2h0LmVuYWJsZSgpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBTdW1tYXJ5VmlldzsiLCJpbXBvcnQgV2VsY29tZVZpZXcgZnJvbSAnLi8wMF93ZWxjb21lLmpzJztcclxuaW1wb3J0IFVwbG9hZFZpZXcgZnJvbSAnLi8wMV91cGxvYWQuanMnO1xyXG5pbXBvcnQgRnVuZFZpZXcgZnJvbSAnLi8wMl9iYXNlbGluZV9sYW5kaW5nLmpzJztcclxuaW1wb3J0IFJldmVudWVWaWV3IGZyb20gJy4vMDNfcmV2ZW51ZS5qcyc7XHJcbmltcG9ydCBQZXJzb25uZWxWaWV3IGZyb20gJy4vMDRfcGVyc29ubmVsLmpzJztcclxuaW1wb3J0IE92ZXJ0aW1lVmlldyBmcm9tICcuLzA1X292ZXJ0aW1lLmpzJztcclxuaW1wb3J0IE5vblBlcnNvbm5lbFZpZXcgZnJvbSAnLi8wNl9ub25wZXJzb25uZWwuanMnO1xyXG5pbXBvcnQgSW5pdGlhdGl2ZXNWaWV3IGZyb20gJy4vMDdfbmV3X2luaXRpYXRpdmVzLmpzJztcclxuaW1wb3J0IFN1bW1hcnlWaWV3IGZyb20gJy4vMDhfc3VtbWFyeS5qcyc7XHJcblxyXG5pbXBvcnQgeyBGdW5kTG9va3VwVGFibGUsIEN1cnJlbnRGdW5kLCBDdXJyZW50UGFnZSB9IGZyb20gJy4uL21vZGVscy8nO1xyXG5pbXBvcnQgeyBGSVNDQUxfWUVBUiB9IGZyb20gJy4uL2NvbnN0YW50cy8nO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVQYWdlcygpIHtcclxuICAgIGNvbnN0IFBBR0VTID0ge1xyXG4gICAgICAgICd3ZWxjb21lJzogbmV3IFdlbGNvbWVWaWV3KCksXHJcbiAgICAgICAgJ3VwbG9hZCc6IG5ldyBVcGxvYWRWaWV3KCksXHJcbiAgICAgICAgJ2Jhc2VsaW5lLWxhbmRpbmcnOiBuZXcgRnVuZFZpZXcoKSxcclxuICAgICAgICAncmV2ZW51ZSc6IG5ldyBSZXZlbnVlVmlldyhGSVNDQUxfWUVBUiksXHJcbiAgICAgICAgJ3BlcnNvbm5lbCc6IG5ldyBQZXJzb25uZWxWaWV3KEZJU0NBTF9ZRUFSKSxcclxuICAgICAgICAnb3ZlcnRpbWUnOiBuZXcgT3ZlcnRpbWVWaWV3KEZJU0NBTF9ZRUFSKSxcclxuICAgICAgICAnbm9ucGVyc29ubmVsJzogbmV3IE5vblBlcnNvbm5lbFZpZXcoRklTQ0FMX1lFQVIpLFxyXG4gICAgICAgICduZXctaW5pdHMnOiBuZXcgSW5pdGlhdGl2ZXNWaWV3KCksXHJcbiAgICAgICAgJ3N1bW1hcnknOiBuZXcgU3VtbWFyeVZpZXcoKSxcclxuICAgIH07XHJcbiAgICByZXR1cm4gUEFHRVM7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB2aXNpdFBhZ2UobmV3X3BhZ2Vfa2V5KXtcclxuXHJcbiAgICBjb25zdCBQQUdFUyA9IGluaXRpYWxpemVQYWdlcygpO1xyXG5cclxuICAgIC8vIGNsZWFuIHVwIGZyb20gY3VycmVudCBwYWdlXHJcbiAgICB2YXIgcGFnZV9zdGF0ZSA9IEN1cnJlbnRQYWdlLmxvYWQoKTtcclxuICAgIFBBR0VTW3BhZ2Vfc3RhdGVdLmNsZWFudXAoKTtcclxuICAgIFxyXG4gICAgLy8gVXNlIHRoZSBwYWdlX3N0YXRlIHRvIGFjY2VzcyBhbmQgY2FsbCB0aGUgY29ycmVzcG9uZGluZyBmdW5jdGlvbiBmcm9tIFBBR0VTXHJcbiAgICBpZiAoUEFHRVNbbmV3X3BhZ2Vfa2V5XSkge1xyXG4gICAgICAgIC8vIEludm9rZXMgdGhlIGZ1bmN0aW9uIGlmIGl0IGV4aXN0cyBpbiB0aGUgUEFHRVMgbWFwXHJcbiAgICAgICAgUEFHRVNbbmV3X3BhZ2Vfa2V5XS52aXNpdCgpOyBcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihgTm8gcGFnZSBpbml0aWFsaXplciBmb3VuZCBmb3Igc3RhdGU6ICR7bmV3X3BhZ2Vfa2V5fWApO1xyXG4gICAgfX1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBuZXh0UGFnZSgpe1xyXG5cclxuICAgIGNvbnN0IFBBR0VTID0gaW5pdGlhbGl6ZVBhZ2VzKCk7XHJcblxyXG4gICAgdmFyIHBhZ2Vfc3RhdGUgPSBDdXJyZW50UGFnZS5sb2FkKCk7XHJcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoUEFHRVMpO1xyXG4gIFxyXG4gICAgLy8gRmluZCB0aGUgaW5kZXggb2YgdGhlIGN1cnJlbnQga2V5XHJcbiAgICBjb25zdCBjdXJyZW50SW5kZXggPSBrZXlzLmluZGV4T2YocGFnZV9zdGF0ZSk7XHJcblxyXG4gICAgLy8gdW5sZXNzIG9uIHBlcnNvbm5lbCAod2hpY2ggd2lsbCBnbyB0byBvdmVydGltZSksIHJldHVybiB0byBzdW1tYXJ5IGlmIGFsbCBmdW5kcyBhcmUgdmlld2VkXHJcbiAgICBjb25zdCByZXR1cm5QYWdlcyA9IFsncmV2ZW51ZScsICdub25wZXJzb25uZWwnLCAnbmV3LWluaXRzJywgJ292ZXJ0aW1lJ107XHJcbiAgICBpZiAoIUZ1bmRMb29rdXBUYWJsZS5mdW5kc0xlZnQoKSAmJiByZXR1cm5QYWdlcy5pbmNsdWRlcyhDdXJyZW50UGFnZS5sb2FkKCkpKSB7XHJcbiAgICAgICAgdmlzaXRQYWdlKCdzdW1tYXJ5Jyk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGlmIG9uIG5vbi1wZXJzb25uZWwsIGNpcmNsZSBiYWNrIHRvIGZ1bmQgc2VsZWN0aW9uIHVubGVzcyBhbGwgZnVuZHMgYXJlIGVkaXRlZFxyXG4gICAgaWYgKEN1cnJlbnRQYWdlLmxvYWQoKSA9PSAnbm9ucGVyc29ubmVsJyl7XHJcbiAgICAgICAgLy8gbWFyayBmdW5kIGFzIHZpZXdlZC9lZGl0ZWRcclxuICAgICAgICBGdW5kTG9va3VwVGFibGUuZWRpdEZ1bmQoQ3VycmVudEZ1bmQubnVtYmVyKCkpO1xyXG4gICAgICAgIC8vIGlmIGFueSBmdW5kcyBsZWZ0IHRvIGVkaXQsIGdvIGJhY2sgdG8gdGhhdCBwYWdlXHJcbiAgICAgICAgaWYgKCBGdW5kTG9va3VwVGFibGUuZnVuZHNMZWZ0KCkgKXtcclxuICAgICAgICAgICAgdmlzaXRQYWdlKCdiYXNlbGluZS1sYW5kaW5nJyk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGN1cnJlbnRJbmRleCA+PSAwICYmIGN1cnJlbnRJbmRleCA8IGtleXMubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgIC8vIENoZWNrIGlmIHRoZXJlIGlzIGEgbmV4dCBrZXksIGFuZCBnZXQgaXRcclxuICAgICAgICBjb25zdCBuZXh0S2V5ID0ga2V5c1tjdXJyZW50SW5kZXggKyAxXTtcclxuICAgICAgICAvLyBnbyB0byB0aGF0IHBhZ2VcclxuICAgICAgICB2aXNpdFBhZ2UobmV4dEtleSk7XHJcbiAgICB9IFxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbGFzdFBhZ2UoKXtcclxuXHJcbiAgICBjb25zdCBQQUdFUyA9IGluaXRpYWxpemVQYWdlcygpO1xyXG5cclxuICAgIHZhciBwYWdlX3N0YXRlID0gQ3VycmVudFBhZ2UubG9hZCgpO1xyXG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKFBBR0VTKTtcclxuICBcclxuICAgIC8vIEZpbmQgdGhlIGluZGV4IG9mIHRoZSBjdXJyZW50IGtleVxyXG4gICAgY29uc3QgY3VycmVudEluZGV4ID0ga2V5cy5pbmRleE9mKHBhZ2Vfc3RhdGUpO1xyXG5cclxuICAgIC8vIGlmIG9uIG5ldy1pbml0cywgY2lyY2xlIGJhY2sgdG8gZnVuZCBzZWxlY3Rpb25cclxuICAgIGlmIChDdXJyZW50UGFnZS5sb2FkKCkgPT0gJ25ldy1pbml0cycpe1xyXG4gICAgICAgIHZpc2l0UGFnZSgnYmFzZWxpbmUtbGFuZGluZycpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIFxyXG4gICAgLy8gQ2hlY2sgaWYgdGhlcmUgaXMgYSBuZXh0IGtleVxyXG4gICAgaWYgKGN1cnJlbnRJbmRleCA+PSAxKSB7XHJcbiAgICAgICAgLy8gR2V0IHRoZSBuZXh0IGtleVxyXG4gICAgICAgIGNvbnN0IGxhc3RLZXkgPSBrZXlzW2N1cnJlbnRJbmRleCAtIDFdO1xyXG4gICAgICAgIC8vIGdvIHRvIHRoYXQgcGFnZVxyXG4gICAgICAgIHZpc2l0UGFnZShsYXN0S2V5KTtcclxuICAgIH0gXHJcbn0iLCJpbXBvcnQgeyB2aXNpdFBhZ2UgfSBmcm9tIFwiLi4vdmlld3Mvdmlld19sb2dpY1wiO1xyXG5cclxuZXhwb3J0IGNvbnN0IEN1cnJlbnRQYWdlID0ge1xyXG4gICAgdXBkYXRlIDogZnVuY3Rpb24ocGFnZSl7XHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ3BhZ2Vfc3RhdGUnLCBwYWdlKTtcclxuICAgIH0sXHJcbiAgICBsb2FkIDogZnVuY3Rpb24oKXtcclxuICAgICAgICBjb25zdCBwYWdlU3RhdGUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgncGFnZV9zdGF0ZScpO1xyXG4gICAgICAgIHJldHVybiBwYWdlU3RhdGUgIT09IG51bGwgPyBwYWdlU3RhdGUgOiAnd2VsY29tZSc7XHJcbiAgICB9LFxyXG4gICAgdmlzaXQgOiBmdW5jdGlvbigpe1xyXG4gICAgICAgIHZpc2l0UGFnZSh0aGlzLmxvYWQoKSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEN1cnJlbnRQYWdlOyIsIi8vIGltcG9ydCBzdHlsZXNcclxuaW1wb3J0ICcuLi9jc3MvY29tbW9uLmNzcyc7XHJcblxyXG4vLyBpbXBvcnQgZnVuY3Rpb25zXHJcbmltcG9ydCBDdXJyZW50UGFnZSBmcm9tICcuL21vZGVscy9jdXJyZW50X3BhZ2UuanMnO1xyXG5cclxuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGZ1bmN0aW9uICgpIHtcclxuICAgIEN1cnJlbnRQYWdlLnZpc2l0KCk7XHJcbn0pO1xyXG5cclxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///221\n")},404:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `:root {\r\n /* colors */\r\n --orange: #FB6523;\r\n --yellow: #D99733;\r\n --blue: #43748E;\r\n --lightBlue: #b7c9e2;\r\n --darkGray: #373A37;\r\n --mediumGray: #D0D0D0;\r\n --lightGray: #F2F2F2;\r\n --white: #FBFDFB;\r\n --black: #212121;\r\n --green: #71BC78;\r\n --citygreen: #004445;\r\n --spiritgreen: #279989;\r\n --palegreen: #9FD5B3;\r\n --verypalegreen: #DFF5E3;\r\n --accentyellow: #feb70d;\r\n --nearblack: #18252a;\r\n /* fonts */\r\n font-family: \'Nunito\', sans-serif;\r\n font-size: 14px;\r\n /* spacing */\r\n --header-height : 125px;\r\n --sidebar-width: 300px;\r\n}\r\n\r\n/* Button styling */\r\n\r\n.btn {\r\n cursor: pointer;\r\n padding: 10px;\r\n margin-top: 5px;\r\n margin-right : 2px;\r\n margin-left: 2px;\r\n border-radius: 10px;\r\n background-color: gray;\r\n color: white; \r\n}\r\n\r\n/* Font application for all text */\r\nbody, button, input, textarea, select, .sidebar, table {\r\n font-family: var(--font-family), sans-serif;\r\n }\r\n\r\n#main-panel {\r\n /* display: flex; */\r\n /* flex-direction: column; */\r\n justify-content: center; /* This will center content vertically */\r\n min-height: calc(100vh - var(--header-height)) ; \r\n /* max-width: calc(100vw - var(--sidebar-width)); */\r\n padding-top: 25px;\r\n padding-bottom: 25px;\r\n margin: 0;\r\n}\r\n\r\n/* Font awesome */\r\n\r\ni.fas.fa-check { \r\n font-size: 1.5em;\r\n color: var(--spiritgreen);\r\n margin-right: 10px;\r\n}\r\n\r\n/* div.row {\r\n margin: 0px;\r\n} */`, "",{"version":3,"sources":["webpack://./src/css/common.css"],"names":[],"mappings":"AAAA;IACI,WAAW;IACX,iBAAiB;IACjB,iBAAiB;IACjB,eAAe;IACf,oBAAoB;IACpB,mBAAmB;IACnB,qBAAqB;IACrB,oBAAoB;IACpB,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,oBAAoB;IACpB,sBAAsB;IACtB,oBAAoB;IACpB,wBAAwB;IACxB,uBAAuB;IACvB,oBAAoB;IACpB,UAAU;IACV,iCAAiC;IACjC,eAAe;IACf,YAAY;IACZ,uBAAuB;IACvB,sBAAsB;AAC1B;;AAEA,mBAAmB;;AAEnB;IACI,eAAe;IACf,aAAa;IACb,eAAe;IACf,kBAAkB;IAClB,gBAAgB;IAChB,mBAAmB;IACnB,sBAAsB;IACtB,YAAY;AAChB;;AAEA,mCAAmC;AACnC;IACI,2CAA2C;EAC7C;;AAEF;IACI,mBAAmB;IACnB,4BAA4B;IAC5B,uBAAuB,EAAE,wCAAwC;IACjE,+CAA+C;IAC/C,oDAAoD;IACpD,iBAAiB;IACjB,oBAAoB;IACpB,SAAS;AACb;;AAEA,iBAAiB;;AAEjB;IACI,gBAAgB;IAChB,yBAAyB;IACzB,kBAAkB;AACtB;;AAEA;;GAEG","sourcesContent":[":root {\\r\\n /* colors */\\r\\n --orange: #FB6523;\\r\\n --yellow: #D99733;\\r\\n --blue: #43748E;\\r\\n --lightBlue: #b7c9e2;\\r\\n --darkGray: #373A37;\\r\\n --mediumGray: #D0D0D0;\\r\\n --lightGray: #F2F2F2;\\r\\n --white: #FBFDFB;\\r\\n --black: #212121;\\r\\n --green: #71BC78;\\r\\n --citygreen: #004445;\\r\\n --spiritgreen: #279989;\\r\\n --palegreen: #9FD5B3;\\r\\n --verypalegreen: #DFF5E3;\\r\\n --accentyellow: #feb70d;\\r\\n --nearblack: #18252a;\\r\\n /* fonts */\\r\\n font-family: \'Nunito\', sans-serif;\\r\\n font-size: 14px;\\r\\n /* spacing */\\r\\n --header-height : 125px;\\r\\n --sidebar-width: 300px;\\r\\n}\\r\\n\\r\\n/* Button styling */\\r\\n\\r\\n.btn {\\r\\n cursor: pointer;\\r\\n padding: 10px;\\r\\n margin-top: 5px;\\r\\n margin-right : 2px;\\r\\n margin-left: 2px;\\r\\n border-radius: 10px;\\r\\n background-color: gray;\\r\\n color: white; \\r\\n}\\r\\n\\r\\n/* Font application for all text */\\r\\nbody, button, input, textarea, select, .sidebar, table {\\r\\n font-family: var(--font-family), sans-serif;\\r\\n }\\r\\n\\r\\n#main-panel {\\r\\n /* display: flex; */\\r\\n /* flex-direction: column; */\\r\\n justify-content: center; /* This will center content vertically */\\r\\n min-height: calc(100vh - var(--header-height)) ; \\r\\n /* max-width: calc(100vw - var(--sidebar-width)); */\\r\\n padding-top: 25px;\\r\\n padding-bottom: 25px;\\r\\n margin: 0;\\r\\n}\\r\\n\\r\\n/* Font awesome */\\r\\n\\r\\ni.fas.fa-check { \\r\\n font-size: 1.5em;\\r\\n color: var(--spiritgreen);\\r\\n margin-right: 10px;\\r\\n}\\r\\n\\r\\n/* div.row {\\r\\n margin: 0px;\\r\\n} */"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDA0LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvY3NzL2NvbW1vbi5jc3M/ZjdjYSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgOnJvb3Qge1xyXG4gICAgLyogY29sb3JzICovXHJcbiAgICAtLW9yYW5nZTogI0ZCNjUyMztcclxuICAgIC0teWVsbG93OiAjRDk5NzMzO1xyXG4gICAgLS1ibHVlOiAjNDM3NDhFO1xyXG4gICAgLS1saWdodEJsdWU6ICNiN2M5ZTI7XHJcbiAgICAtLWRhcmtHcmF5OiAjMzczQTM3O1xyXG4gICAgLS1tZWRpdW1HcmF5OiAjRDBEMEQwO1xyXG4gICAgLS1saWdodEdyYXk6ICNGMkYyRjI7XHJcbiAgICAtLXdoaXRlOiAjRkJGREZCO1xyXG4gICAgLS1ibGFjazogIzIxMjEyMTtcclxuICAgIC0tZ3JlZW46ICM3MUJDNzg7XHJcbiAgICAtLWNpdHlncmVlbjogIzAwNDQ0NTtcclxuICAgIC0tc3Bpcml0Z3JlZW46ICMyNzk5ODk7XHJcbiAgICAtLXBhbGVncmVlbjogIzlGRDVCMztcclxuICAgIC0tdmVyeXBhbGVncmVlbjogI0RGRjVFMztcclxuICAgIC0tYWNjZW50eWVsbG93OiAjZmViNzBkO1xyXG4gICAgLS1uZWFyYmxhY2s6ICMxODI1MmE7XHJcbiAgICAvKiBmb250cyAqL1xyXG4gICAgZm9udC1mYW1pbHk6ICdOdW5pdG8nLCBzYW5zLXNlcmlmO1xyXG4gICAgZm9udC1zaXplOiAxNHB4O1xyXG4gICAgLyogc3BhY2luZyAqL1xyXG4gICAgLS1oZWFkZXItaGVpZ2h0IDogMTI1cHg7XHJcbiAgICAtLXNpZGViYXItd2lkdGg6IDMwMHB4O1xyXG59XHJcblxyXG4vKiBCdXR0b24gc3R5bGluZyAqL1xyXG5cclxuLmJ0biB7XHJcbiAgICBjdXJzb3I6IHBvaW50ZXI7XHJcbiAgICBwYWRkaW5nOiAxMHB4O1xyXG4gICAgbWFyZ2luLXRvcDogNXB4O1xyXG4gICAgbWFyZ2luLXJpZ2h0IDogMnB4O1xyXG4gICAgbWFyZ2luLWxlZnQ6IDJweDtcclxuICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiBncmF5O1xyXG4gICAgY29sb3I6IHdoaXRlOyBcclxufVxyXG5cclxuLyogRm9udCBhcHBsaWNhdGlvbiBmb3IgYWxsIHRleHQgICovXHJcbmJvZHksIGJ1dHRvbiwgaW5wdXQsIHRleHRhcmVhLCBzZWxlY3QsIC5zaWRlYmFyLCB0YWJsZSB7XHJcbiAgICBmb250LWZhbWlseTogdmFyKC0tZm9udC1mYW1pbHkpLCBzYW5zLXNlcmlmO1xyXG4gIH1cclxuXHJcbiNtYWluLXBhbmVsIHtcclxuICAgIC8qIGRpc3BsYXk6IGZsZXg7ICovXHJcbiAgICAvKiBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyAqL1xyXG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7IC8qIFRoaXMgd2lsbCBjZW50ZXIgY29udGVudCB2ZXJ0aWNhbGx5ICovXHJcbiAgICBtaW4taGVpZ2h0OiBjYWxjKDEwMHZoIC0gdmFyKC0taGVhZGVyLWhlaWdodCkpIDsgXHJcbiAgICAvKiBtYXgtd2lkdGg6IGNhbGMoMTAwdncgLSB2YXIoLS1zaWRlYmFyLXdpZHRoKSk7ICAqL1xyXG4gICAgcGFkZGluZy10b3A6IDI1cHg7XHJcbiAgICBwYWRkaW5nLWJvdHRvbTogMjVweDtcclxuICAgIG1hcmdpbjogMDtcclxufVxyXG5cclxuLyogRm9udCBhd2Vzb21lICovXHJcblxyXG5pLmZhcy5mYS1jaGVjayB7IFxyXG4gICAgZm9udC1zaXplOiAxLjVlbTtcclxuICAgIGNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XHJcbiAgICBtYXJnaW4tcmlnaHQ6IDEwcHg7XHJcbn1cclxuXHJcbi8qIGRpdi5yb3cge1xyXG4gICAgbWFyZ2luOiAwcHg7XHJcbn0gKi9gLCBcIlwiLHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIndlYnBhY2s6Ly8uL3NyYy9jc3MvY29tbW9uLmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLFdBQVc7SUFDWCxpQkFBaUI7SUFDakIsaUJBQWlCO0lBQ2pCLGVBQWU7SUFDZixvQkFBb0I7SUFDcEIsbUJBQW1CO0lBQ25CLHFCQUFxQjtJQUNyQixvQkFBb0I7SUFDcEIsZ0JBQWdCO0lBQ2hCLGdCQUFnQjtJQUNoQixnQkFBZ0I7SUFDaEIsb0JBQW9CO0lBQ3BCLHNCQUFzQjtJQUN0QixvQkFBb0I7SUFDcEIsd0JBQXdCO0lBQ3hCLHVCQUF1QjtJQUN2QixvQkFBb0I7SUFDcEIsVUFBVTtJQUNWLGlDQUFpQztJQUNqQyxlQUFlO0lBQ2YsWUFBWTtJQUNaLHVCQUF1QjtJQUN2QixzQkFBc0I7QUFDMUI7O0FBRUEsbUJBQW1COztBQUVuQjtJQUNJLGVBQWU7SUFDZixhQUFhO0lBQ2IsZUFBZTtJQUNmLGtCQUFrQjtJQUNsQixnQkFBZ0I7SUFDaEIsbUJBQW1CO0lBQ25CLHNCQUFzQjtJQUN0QixZQUFZO0FBQ2hCOztBQUVBLG1DQUFtQztBQUNuQztJQUNJLDJDQUEyQztFQUM3Qzs7QUFFRjtJQUNJLG1CQUFtQjtJQUNuQiw0QkFBNEI7SUFDNUIsdUJBQXVCLEVBQUUsd0NBQXdDO0lBQ2pFLCtDQUErQztJQUMvQyxvREFBb0Q7SUFDcEQsaUJBQWlCO0lBQ2pCLG9CQUFvQjtJQUNwQixTQUFTO0FBQ2I7O0FBRUEsaUJBQWlCOztBQUVqQjtJQUNJLGdCQUFnQjtJQUNoQix5QkFBeUI7SUFDekIsa0JBQWtCO0FBQ3RCOztBQUVBOztHQUVHXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjpyb290IHtcXHJcXG4gICAgLyogY29sb3JzICovXFxyXFxuICAgIC0tb3JhbmdlOiAjRkI2NTIzO1xcclxcbiAgICAtLXllbGxvdzogI0Q5OTczMztcXHJcXG4gICAgLS1ibHVlOiAjNDM3NDhFO1xcclxcbiAgICAtLWxpZ2h0Qmx1ZTogI2I3YzllMjtcXHJcXG4gICAgLS1kYXJrR3JheTogIzM3M0EzNztcXHJcXG4gICAgLS1tZWRpdW1HcmF5OiAjRDBEMEQwO1xcclxcbiAgICAtLWxpZ2h0R3JheTogI0YyRjJGMjtcXHJcXG4gICAgLS13aGl0ZTogI0ZCRkRGQjtcXHJcXG4gICAgLS1ibGFjazogIzIxMjEyMTtcXHJcXG4gICAgLS1ncmVlbjogIzcxQkM3ODtcXHJcXG4gICAgLS1jaXR5Z3JlZW46ICMwMDQ0NDU7XFxyXFxuICAgIC0tc3Bpcml0Z3JlZW46ICMyNzk5ODk7XFxyXFxuICAgIC0tcGFsZWdyZWVuOiAjOUZENUIzO1xcclxcbiAgICAtLXZlcnlwYWxlZ3JlZW46ICNERkY1RTM7XFxyXFxuICAgIC0tYWNjZW50eWVsbG93OiAjZmViNzBkO1xcclxcbiAgICAtLW5lYXJibGFjazogIzE4MjUyYTtcXHJcXG4gICAgLyogZm9udHMgKi9cXHJcXG4gICAgZm9udC1mYW1pbHk6ICdOdW5pdG8nLCBzYW5zLXNlcmlmO1xcclxcbiAgICBmb250LXNpemU6IDE0cHg7XFxyXFxuICAgIC8qIHNwYWNpbmcgKi9cXHJcXG4gICAgLS1oZWFkZXItaGVpZ2h0IDogMTI1cHg7XFxyXFxuICAgIC0tc2lkZWJhci13aWR0aDogMzAwcHg7XFxyXFxufVxcclxcblxcclxcbi8qIEJ1dHRvbiBzdHlsaW5nICovXFxyXFxuXFxyXFxuLmJ0biB7XFxyXFxuICAgIGN1cnNvcjogcG9pbnRlcjtcXHJcXG4gICAgcGFkZGluZzogMTBweDtcXHJcXG4gICAgbWFyZ2luLXRvcDogNXB4O1xcclxcbiAgICBtYXJnaW4tcmlnaHQgOiAycHg7XFxyXFxuICAgIG1hcmdpbi1sZWZ0OiAycHg7XFxyXFxuICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IGdyYXk7XFxyXFxuICAgIGNvbG9yOiB3aGl0ZTsgXFxyXFxufVxcclxcblxcclxcbi8qIEZvbnQgYXBwbGljYXRpb24gZm9yIGFsbCB0ZXh0ICAqL1xcclxcbmJvZHksIGJ1dHRvbiwgaW5wdXQsIHRleHRhcmVhLCBzZWxlY3QsIC5zaWRlYmFyLCB0YWJsZSB7XFxyXFxuICAgIGZvbnQtZmFtaWx5OiB2YXIoLS1mb250LWZhbWlseSksIHNhbnMtc2VyaWY7XFxyXFxuICB9XFxyXFxuXFxyXFxuI21haW4tcGFuZWwge1xcclxcbiAgICAvKiBkaXNwbGF5OiBmbGV4OyAqL1xcclxcbiAgICAvKiBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyAqL1xcclxcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgLyogVGhpcyB3aWxsIGNlbnRlciBjb250ZW50IHZlcnRpY2FsbHkgKi9cXHJcXG4gICAgbWluLWhlaWdodDogY2FsYygxMDB2aCAtIHZhcigtLWhlYWRlci1oZWlnaHQpKSA7IFxcclxcbiAgICAvKiBtYXgtd2lkdGg6IGNhbGMoMTAwdncgLSB2YXIoLS1zaWRlYmFyLXdpZHRoKSk7ICAqL1xcclxcbiAgICBwYWRkaW5nLXRvcDogMjVweDtcXHJcXG4gICAgcGFkZGluZy1ib3R0b206IDI1cHg7XFxyXFxuICAgIG1hcmdpbjogMDtcXHJcXG59XFxyXFxuXFxyXFxuLyogRm9udCBhd2Vzb21lICovXFxyXFxuXFxyXFxuaS5mYXMuZmEtY2hlY2sgeyBcXHJcXG4gICAgZm9udC1zaXplOiAxLjVlbTtcXHJcXG4gICAgY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcXHJcXG4gICAgbWFyZ2luLXJpZ2h0OiAxMHB4O1xcclxcbn1cXHJcXG5cXHJcXG4vKiBkaXYucm93IHtcXHJcXG4gICAgbWFyZ2luOiAwcHg7XFxyXFxufSAqL1wiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuLy8gRXhwb3J0c1xuZXhwb3J0IGRlZmF1bHQgX19fQ1NTX0xPQURFUl9FWFBPUlRfX187XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///404\n')},995:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.summary-accordion {\r\n width: 60%;\r\n margin: auto;\r\n}\r\n\r\n.accordion-title {\r\n margin-left: 20%;\r\n font-weight: bold;\r\n padding-bottom: 10px;\r\n padding-left: 15px;\r\n padding-top: 30px;\r\n}\r\n\r\n.accordion-button:active, .accordion-button:not(.collapsed) {\r\n background-color: var(--palegreen);\r\n color: var(--citygreen);\r\n}\r\n\r\n.accordion-table { \r\n width: 100%;\r\n font-size: 1.2em;\r\n /* border-collapse: separate; This is required for rounded corners */\r\n}\r\n\r\n.accordion-table td:last-child {\r\n text-align: right;\r\n padding-right: 15px;\r\n padding-bottom: 5px\r\n}\r\n\r\n.accordion-table tr {\r\n border-bottom: 1px solid black;\r\n border-top: none;\r\n border-right: none;\r\n border-left: none;\r\n}\r\n\r\n.accordion-table tr:last-child {\r\n border-bottom: none;\r\n background-color: var(--mediumGray);\r\n height : 50px;\r\n}\r\n\r\nspan.amount {\r\n font-weight: bold;\r\n position: absolute;\r\n right: 0;\r\n margin-right: 60px;\r\n}\r\n\r\n.accordion-header button {\r\n font-size: 0.6em;\r\n}\r\n\r\n.btn-add-init {\r\n background-color: var(--spiritgreen);\r\n border-color: var(--citygreen);\r\n /* position: absolute; */\r\n right: 0;\r\n /* margin-left: 20px; */\r\n /* margin-right: calc(20vw + 15px); */\r\n margin-top: 15px;\r\n}\r\n\r\n#supp-title {\r\n margin-top: 20px;\r\n}\r\n\r\n.btn-add-init:hover {\r\n background-color: var(--palegreen);\r\n}\r\n.add-init-btn-div{\r\n text-align: center;\r\n}\r\n\r\nspan.top-line-amount {\r\n font-weight: bold;\r\n position: absolute;\r\n right: 0;\r\n margin-right: calc(20vw + 20px);\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/accordion/accordion.css"],"names":[],"mappings":"AAAA;IACI,UAAU;IACV,YAAY;AAChB;;AAEA;IACI,gBAAgB;IAChB,iBAAiB;IACjB,oBAAoB;IACpB,kBAAkB;IAClB,iBAAiB;AACrB;;AAEA;IACI,kCAAkC;IAClC,uBAAuB;AAC3B;;AAEA;IACI,WAAW;IACX,gBAAgB;IAChB,oEAAoE;AACxE;;AAEA;IACI,iBAAiB;IACjB,mBAAmB;IACnB;AACJ;;AAEA;IACI,8BAA8B;IAC9B,gBAAgB;IAChB,kBAAkB;IAClB,iBAAiB;AACrB;;AAEA;IACI,mBAAmB;IACnB,mCAAmC;IACnC,aAAa;AACjB;;AAEA;IACI,iBAAiB;IACjB,kBAAkB;IAClB,QAAQ;IACR,kBAAkB;AACtB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,oCAAoC;IACpC,8BAA8B;IAC9B,wBAAwB;IACxB,QAAQ;IACR,uBAAuB;IACvB,qCAAqC;IACrC,gBAAgB;AACpB;;AAEA;GACG,gBAAgB;AACnB;;AAEA;IACI,kCAAkC;AACtC;AACA;IACI,kBAAkB;AACtB;;AAEA;IACI,iBAAiB;IACjB,kBAAkB;IAClB,QAAQ;IACR,+BAA+B;AACnC","sourcesContent":[".summary-accordion {\\r\\n width: 60%;\\r\\n margin: auto;\\r\\n}\\r\\n\\r\\n.accordion-title {\\r\\n margin-left: 20%;\\r\\n font-weight: bold;\\r\\n padding-bottom: 10px;\\r\\n padding-left: 15px;\\r\\n padding-top: 30px;\\r\\n}\\r\\n\\r\\n.accordion-button:active, .accordion-button:not(.collapsed) {\\r\\n background-color: var(--palegreen);\\r\\n color: var(--citygreen);\\r\\n}\\r\\n\\r\\n.accordion-table { \\r\\n width: 100%;\\r\\n font-size: 1.2em;\\r\\n /* border-collapse: separate; This is required for rounded corners */\\r\\n}\\r\\n\\r\\n.accordion-table td:last-child {\\r\\n text-align: right;\\r\\n padding-right: 15px;\\r\\n padding-bottom: 5px\\r\\n}\\r\\n\\r\\n.accordion-table tr {\\r\\n border-bottom: 1px solid black;\\r\\n border-top: none;\\r\\n border-right: none;\\r\\n border-left: none;\\r\\n}\\r\\n\\r\\n.accordion-table tr:last-child {\\r\\n border-bottom: none;\\r\\n background-color: var(--mediumGray);\\r\\n height : 50px;\\r\\n}\\r\\n\\r\\nspan.amount {\\r\\n font-weight: bold;\\r\\n position: absolute;\\r\\n right: 0;\\r\\n margin-right: 60px;\\r\\n}\\r\\n\\r\\n.accordion-header button {\\r\\n font-size: 0.6em;\\r\\n}\\r\\n\\r\\n.btn-add-init {\\r\\n background-color: var(--spiritgreen);\\r\\n border-color: var(--citygreen);\\r\\n /* position: absolute; */\\r\\n right: 0;\\r\\n /* margin-left: 20px; */\\r\\n /* margin-right: calc(20vw + 15px); */\\r\\n margin-top: 15px;\\r\\n}\\r\\n\\r\\n#supp-title {\\r\\n margin-top: 20px;\\r\\n}\\r\\n\\r\\n.btn-add-init:hover {\\r\\n background-color: var(--palegreen);\\r\\n}\\r\\n.add-init-btn-div{\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\nspan.top-line-amount {\\r\\n font-weight: bold;\\r\\n position: absolute;\\r\\n right: 0;\\r\\n margin-right: calc(20vw + 20px);\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTk1LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9hY2NvcmRpb24vYWNjb3JkaW9uLmNzcz9mMGY4Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIEltcG9ydHNcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvc291cmNlTWFwcy5qc1wiO1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL2FwaS5qc1wiO1xudmFyIF9fX0NTU19MT0FERVJfRVhQT1JUX19fID0gX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fKF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18pO1xuLy8gTW9kdWxlXG5fX19DU1NfTE9BREVSX0VYUE9SVF9fXy5wdXNoKFttb2R1bGUuaWQsIGAuc3VtbWFyeS1hY2NvcmRpb24ge1xyXG4gICAgd2lkdGg6IDYwJTtcclxuICAgIG1hcmdpbjogYXV0bztcclxufVxyXG5cclxuLmFjY29yZGlvbi10aXRsZSB7XHJcbiAgICBtYXJnaW4tbGVmdDogMjAlO1xyXG4gICAgZm9udC13ZWlnaHQ6IGJvbGQ7XHJcbiAgICBwYWRkaW5nLWJvdHRvbTogMTBweDtcclxuICAgIHBhZGRpbmctbGVmdDogMTVweDtcclxuICAgIHBhZGRpbmctdG9wOiAzMHB4O1xyXG59XHJcblxyXG4uYWNjb3JkaW9uLWJ1dHRvbjphY3RpdmUsIC5hY2NvcmRpb24tYnV0dG9uOm5vdCguY29sbGFwc2VkKSB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1wYWxlZ3JlZW4pO1xyXG4gICAgY29sb3I6IHZhcigtLWNpdHlncmVlbik7XHJcbn1cclxuXHJcbi5hY2NvcmRpb24tdGFibGUgeyBcclxuICAgIHdpZHRoOiAxMDAlO1xyXG4gICAgZm9udC1zaXplOiAxLjJlbTtcclxuICAgIC8qIGJvcmRlci1jb2xsYXBzZTogc2VwYXJhdGU7IFRoaXMgaXMgcmVxdWlyZWQgZm9yIHJvdW5kZWQgY29ybmVycyAqL1xyXG59XHJcblxyXG4uYWNjb3JkaW9uLXRhYmxlIHRkOmxhc3QtY2hpbGQge1xyXG4gICAgdGV4dC1hbGlnbjogcmlnaHQ7XHJcbiAgICBwYWRkaW5nLXJpZ2h0OiAxNXB4O1xyXG4gICAgcGFkZGluZy1ib3R0b206IDVweFxyXG59XHJcblxyXG4uYWNjb3JkaW9uLXRhYmxlIHRyIHtcclxuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCBibGFjaztcclxuICAgIGJvcmRlci10b3A6IG5vbmU7XHJcbiAgICBib3JkZXItcmlnaHQ6IG5vbmU7XHJcbiAgICBib3JkZXItbGVmdDogbm9uZTtcclxufVxyXG5cclxuLmFjY29yZGlvbi10YWJsZSB0cjpsYXN0LWNoaWxkIHtcclxuICAgIGJvcmRlci1ib3R0b206IG5vbmU7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1tZWRpdW1HcmF5KTtcclxuICAgIGhlaWdodCA6IDUwcHg7XHJcbn1cclxuXHJcbnNwYW4uYW1vdW50IHtcclxuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xyXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgcmlnaHQ6IDA7XHJcbiAgICBtYXJnaW4tcmlnaHQ6IDYwcHg7XHJcbn1cclxuXHJcbi5hY2NvcmRpb24taGVhZGVyIGJ1dHRvbiB7XHJcbiAgICBmb250LXNpemU6IDAuNmVtO1xyXG59XHJcblxyXG4uYnRuLWFkZC1pbml0IHtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcclxuICAgIC8qIHBvc2l0aW9uOiBhYnNvbHV0ZTsgKi9cclxuICAgIHJpZ2h0OiAwO1xyXG4gICAgLyogbWFyZ2luLWxlZnQ6IDIwcHg7ICovXHJcbiAgICAvKiBtYXJnaW4tcmlnaHQ6IGNhbGMoMjB2dyArIDE1cHgpOyAqL1xyXG4gICAgbWFyZ2luLXRvcDogMTVweDtcclxufVxyXG5cclxuI3N1cHAtdGl0bGUge1xyXG4gICBtYXJnaW4tdG9wOiAyMHB4O1xyXG59XHJcblxyXG4uYnRuLWFkZC1pbml0OmhvdmVyIHtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXBhbGVncmVlbik7XHJcbn1cclxuLmFkZC1pbml0LWJ0bi1kaXZ7XHJcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XHJcbn1cclxuXHJcbnNwYW4udG9wLWxpbmUtYW1vdW50IHtcclxuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xyXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgcmlnaHQ6IDA7XHJcbiAgICBtYXJnaW4tcmlnaHQ6IGNhbGMoMjB2dyArIDIwcHgpO1xyXG59YCwgXCJcIix7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCJ3ZWJwYWNrOi8vLi9zcmMvanMvY29tcG9uZW50cy9hY2NvcmRpb24vYWNjb3JkaW9uLmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLFVBQVU7SUFDVixZQUFZO0FBQ2hCOztBQUVBO0lBQ0ksZ0JBQWdCO0lBQ2hCLGlCQUFpQjtJQUNqQixvQkFBb0I7SUFDcEIsa0JBQWtCO0lBQ2xCLGlCQUFpQjtBQUNyQjs7QUFFQTtJQUNJLGtDQUFrQztJQUNsQyx1QkFBdUI7QUFDM0I7O0FBRUE7SUFDSSxXQUFXO0lBQ1gsZ0JBQWdCO0lBQ2hCLG9FQUFvRTtBQUN4RTs7QUFFQTtJQUNJLGlCQUFpQjtJQUNqQixtQkFBbUI7SUFDbkI7QUFDSjs7QUFFQTtJQUNJLDhCQUE4QjtJQUM5QixnQkFBZ0I7SUFDaEIsa0JBQWtCO0lBQ2xCLGlCQUFpQjtBQUNyQjs7QUFFQTtJQUNJLG1CQUFtQjtJQUNuQixtQ0FBbUM7SUFDbkMsYUFBYTtBQUNqQjs7QUFFQTtJQUNJLGlCQUFpQjtJQUNqQixrQkFBa0I7SUFDbEIsUUFBUTtJQUNSLGtCQUFrQjtBQUN0Qjs7QUFFQTtJQUNJLGdCQUFnQjtBQUNwQjs7QUFFQTtJQUNJLG9DQUFvQztJQUNwQyw4QkFBOEI7SUFDOUIsd0JBQXdCO0lBQ3hCLFFBQVE7SUFDUix1QkFBdUI7SUFDdkIscUNBQXFDO0lBQ3JDLGdCQUFnQjtBQUNwQjs7QUFFQTtHQUNHLGdCQUFnQjtBQUNuQjs7QUFFQTtJQUNJLGtDQUFrQztBQUN0QztBQUNBO0lBQ0ksa0JBQWtCO0FBQ3RCOztBQUVBO0lBQ0ksaUJBQWlCO0lBQ2pCLGtCQUFrQjtJQUNsQixRQUFRO0lBQ1IsK0JBQStCO0FBQ25DXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi5zdW1tYXJ5LWFjY29yZGlvbiB7XFxyXFxuICAgIHdpZHRoOiA2MCU7XFxyXFxuICAgIG1hcmdpbjogYXV0bztcXHJcXG59XFxyXFxuXFxyXFxuLmFjY29yZGlvbi10aXRsZSB7XFxyXFxuICAgIG1hcmdpbi1sZWZ0OiAyMCU7XFxyXFxuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xcclxcbiAgICBwYWRkaW5nLWJvdHRvbTogMTBweDtcXHJcXG4gICAgcGFkZGluZy1sZWZ0OiAxNXB4O1xcclxcbiAgICBwYWRkaW5nLXRvcDogMzBweDtcXHJcXG59XFxyXFxuXFxyXFxuLmFjY29yZGlvbi1idXR0b246YWN0aXZlLCAuYWNjb3JkaW9uLWJ1dHRvbjpub3QoLmNvbGxhcHNlZCkge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1wYWxlZ3JlZW4pO1xcclxcbiAgICBjb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcXHJcXG59XFxyXFxuXFxyXFxuLmFjY29yZGlvbi10YWJsZSB7IFxcclxcbiAgICB3aWR0aDogMTAwJTtcXHJcXG4gICAgZm9udC1zaXplOiAxLjJlbTtcXHJcXG4gICAgLyogYm9yZGVyLWNvbGxhcHNlOiBzZXBhcmF0ZTsgVGhpcyBpcyByZXF1aXJlZCBmb3Igcm91bmRlZCBjb3JuZXJzICovXFxyXFxufVxcclxcblxcclxcbi5hY2NvcmRpb24tdGFibGUgdGQ6bGFzdC1jaGlsZCB7XFxyXFxuICAgIHRleHQtYWxpZ246IHJpZ2h0O1xcclxcbiAgICBwYWRkaW5nLXJpZ2h0OiAxNXB4O1xcclxcbiAgICBwYWRkaW5nLWJvdHRvbTogNXB4XFxyXFxufVxcclxcblxcclxcbi5hY2NvcmRpb24tdGFibGUgdHIge1xcclxcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgYmxhY2s7XFxyXFxuICAgIGJvcmRlci10b3A6IG5vbmU7XFxyXFxuICAgIGJvcmRlci1yaWdodDogbm9uZTtcXHJcXG4gICAgYm9yZGVyLWxlZnQ6IG5vbmU7XFxyXFxufVxcclxcblxcclxcbi5hY2NvcmRpb24tdGFibGUgdHI6bGFzdC1jaGlsZCB7XFxyXFxuICAgIGJvcmRlci1ib3R0b206IG5vbmU7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLW1lZGl1bUdyYXkpO1xcclxcbiAgICBoZWlnaHQgOiA1MHB4O1xcclxcbn1cXHJcXG5cXHJcXG5zcGFuLmFtb3VudCB7XFxyXFxuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xcclxcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICAgIHJpZ2h0OiAwO1xcclxcbiAgICBtYXJnaW4tcmlnaHQ6IDYwcHg7XFxyXFxufVxcclxcblxcclxcbi5hY2NvcmRpb24taGVhZGVyIGJ1dHRvbiB7XFxyXFxuICAgIGZvbnQtc2l6ZTogMC42ZW07XFxyXFxufVxcclxcblxcclxcbi5idG4tYWRkLWluaXQge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XFxyXFxuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcXHJcXG4gICAgLyogcG9zaXRpb246IGFic29sdXRlOyAqL1xcclxcbiAgICByaWdodDogMDtcXHJcXG4gICAgLyogbWFyZ2luLWxlZnQ6IDIwcHg7ICovXFxyXFxuICAgIC8qIG1hcmdpbi1yaWdodDogY2FsYygyMHZ3ICsgMTVweCk7ICovXFxyXFxuICAgIG1hcmdpbi10b3A6IDE1cHg7XFxyXFxufVxcclxcblxcclxcbiNzdXBwLXRpdGxlIHtcXHJcXG4gICBtYXJnaW4tdG9wOiAyMHB4O1xcclxcbn1cXHJcXG5cXHJcXG4uYnRuLWFkZC1pbml0OmhvdmVyIHtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tcGFsZWdyZWVuKTtcXHJcXG59XFxyXFxuLmFkZC1pbml0LWJ0bi1kaXZ7XFxyXFxuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcXHJcXG59XFxyXFxuXFxyXFxuc3Bhbi50b3AtbGluZS1hbW91bnQge1xcclxcbiAgICBmb250LXdlaWdodDogYm9sZDtcXHJcXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbiAgICByaWdodDogMDtcXHJcXG4gICAgbWFyZ2luLXJpZ2h0OiBjYWxjKDIwdncgKyAyMHB4KTtcXHJcXG59XCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///995\n')},9:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `body {\r\n background-color: var(--lightGray);\r\n margin: 0;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/body/body.css"],"names":[],"mappings":"AAAA;IACI,kCAAkC;IAClC,SAAS;AACb","sourcesContent":["body {\\r\\n background-color: var(--lightGray);\\r\\n margin: 0;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOS5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9ib2R5L2JvZHkuY3NzPzM2ZTAiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYGJvZHkge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tbGlnaHRHcmF5KTtcclxuICAgIG1hcmdpbjogMDtcclxufWAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2pzL2NvbXBvbmVudHMvYm9keS9ib2R5LmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLGtDQUFrQztJQUNsQyxTQUFTO0FBQ2JcIixcInNvdXJjZXNDb250ZW50XCI6W1wiYm9keSB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWxpZ2h0R3JheSk7XFxyXFxuICAgIG1hcmdpbjogMDtcXHJcXG59XCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9\n')},39:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#file-input {\r\n margin-left: 40%;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/file_upload/file_upload.css"],"names":[],"mappings":"AAAA;IACI,gBAAgB;AACpB","sourcesContent":["#file-input {\\r\\n margin-left: 40%;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2ZpbGVfdXBsb2FkL2ZpbGVfdXBsb2FkLmNzcz9jNTU4Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIEltcG9ydHNcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvc291cmNlTWFwcy5qc1wiO1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL2FwaS5qc1wiO1xudmFyIF9fX0NTU19MT0FERVJfRVhQT1JUX19fID0gX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fKF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18pO1xuLy8gTW9kdWxlXG5fX19DU1NfTE9BREVSX0VYUE9SVF9fXy5wdXNoKFttb2R1bGUuaWQsIGAjZmlsZS1pbnB1dCB7XHJcbiAgICBtYXJnaW4tbGVmdDogNDAlO1xyXG59YCwgXCJcIix7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCJ3ZWJwYWNrOi8vLi9zcmMvanMvY29tcG9uZW50cy9maWxlX3VwbG9hZC9maWxlX3VwbG9hZC5jc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7SUFDSSxnQkFBZ0I7QUFDcEJcIixcInNvdXJjZXNDb250ZW50XCI6W1wiI2ZpbGUtaW5wdXQge1xcclxcbiAgICBtYXJnaW4tbGVmdDogNDAlO1xcclxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcbi8vIEV4cG9ydHNcbmV4cG9ydCBkZWZhdWx0IF9fX0NTU19MT0FERVJfRVhQT1JUX19fO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///39\n')},109:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `textarea {height: 100px; width: 100%;}\r\n\r\ntextarea, input {\r\n margin-bottom: 20px;\r\n}\r\n\r\n.btn-submit {\r\n margin-top: 20px;\r\n width: 60%;\r\n margin-left: 20%;\r\n background-color: var(--spiritgreen);\r\n}\r\n\r\n#new-form label {\r\n display: block; /* Ensure label is on its own line */\r\n margin-bottom: 0.25em; \r\n}\r\n\r\n#new-form select {\r\n min-width: 300px;\r\n margin-bottom: 1.25em;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/form/form.css"],"names":[],"mappings":"AAAA,UAAU,aAAa,EAAE,WAAW,CAAC;;AAErC;IACI,mBAAmB;AACvB;;AAEA;IACI,gBAAgB;IAChB,UAAU;IACV,gBAAgB;IAChB,oCAAoC;AACxC;;AAEA;IACI,cAAc,EAAE,oCAAoC;IACpD,qBAAqB;AACzB;;AAEA;IACI,gBAAgB;IAChB,qBAAqB;AACzB","sourcesContent":["textarea {height: 100px; width: 100%;}\\r\\n\\r\\ntextarea, input {\\r\\n margin-bottom: 20px;\\r\\n}\\r\\n\\r\\n.btn-submit {\\r\\n margin-top: 20px;\\r\\n width: 60%;\\r\\n margin-left: 20%;\\r\\n background-color: var(--spiritgreen);\\r\\n}\\r\\n\\r\\n#new-form label {\\r\\n display: block; /* Ensure label is on its own line */\\r\\n margin-bottom: 0.25em; \\r\\n}\\r\\n\\r\\n#new-form select {\\r\\n min-width: 300px;\\r\\n margin-bottom: 1.25em;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA5LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2Zvcm0vZm9ybS5jc3M/ZTM4YSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgdGV4dGFyZWEge2hlaWdodDogMTAwcHg7IHdpZHRoOiAxMDAlO31cclxuXHJcbnRleHRhcmVhLCBpbnB1dCB7XHJcbiAgICBtYXJnaW4tYm90dG9tOiAyMHB4O1xyXG59XHJcblxyXG4uYnRuLXN1Ym1pdCB7XHJcbiAgICBtYXJnaW4tdG9wOiAyMHB4O1xyXG4gICAgd2lkdGg6IDYwJTtcclxuICAgIG1hcmdpbi1sZWZ0OiAyMCU7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XHJcbn1cclxuXHJcbiNuZXctZm9ybSBsYWJlbCB7XHJcbiAgICBkaXNwbGF5OiBibG9jazsgLyogRW5zdXJlIGxhYmVsIGlzIG9uIGl0cyBvd24gbGluZSAqL1xyXG4gICAgbWFyZ2luLWJvdHRvbTogMC4yNWVtOyBcclxufVxyXG5cclxuI25ldy1mb3JtIHNlbGVjdCB7XHJcbiAgICBtaW4td2lkdGg6IDMwMHB4O1xyXG4gICAgbWFyZ2luLWJvdHRvbTogMS4yNWVtO1xyXG59YCwgXCJcIix7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCJ3ZWJwYWNrOi8vLi9zcmMvanMvY29tcG9uZW50cy9mb3JtL2Zvcm0uY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBLFVBQVUsYUFBYSxFQUFFLFdBQVcsQ0FBQzs7QUFFckM7SUFDSSxtQkFBbUI7QUFDdkI7O0FBRUE7SUFDSSxnQkFBZ0I7SUFDaEIsVUFBVTtJQUNWLGdCQUFnQjtJQUNoQixvQ0FBb0M7QUFDeEM7O0FBRUE7SUFDSSxjQUFjLEVBQUUsb0NBQW9DO0lBQ3BELHFCQUFxQjtBQUN6Qjs7QUFFQTtJQUNJLGdCQUFnQjtJQUNoQixxQkFBcUI7QUFDekJcIixcInNvdXJjZXNDb250ZW50XCI6W1widGV4dGFyZWEge2hlaWdodDogMTAwcHg7IHdpZHRoOiAxMDAlO31cXHJcXG5cXHJcXG50ZXh0YXJlYSwgaW5wdXQge1xcclxcbiAgICBtYXJnaW4tYm90dG9tOiAyMHB4O1xcclxcbn1cXHJcXG5cXHJcXG4uYnRuLXN1Ym1pdCB7XFxyXFxuICAgIG1hcmdpbi10b3A6IDIwcHg7XFxyXFxuICAgIHdpZHRoOiA2MCU7XFxyXFxuICAgIG1hcmdpbi1sZWZ0OiAyMCU7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcXHJcXG59XFxyXFxuXFxyXFxuI25ldy1mb3JtIGxhYmVsIHtcXHJcXG4gICAgZGlzcGxheTogYmxvY2s7IC8qIEVuc3VyZSBsYWJlbCBpcyBvbiBpdHMgb3duIGxpbmUgKi9cXHJcXG4gICAgbWFyZ2luLWJvdHRvbTogMC4yNWVtOyBcXHJcXG59XFxyXFxuXFxyXFxuI25ldy1mb3JtIHNlbGVjdCB7XFxyXFxuICAgIG1pbi13aWR0aDogMzAwcHg7XFxyXFxuICAgIG1hcmdpbi1ib3R0b206IDEuMjVlbTtcXHJcXG59XCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///109\n')},107:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `\r\nh1 {\r\n text-align: center;\r\n}\r\n\r\nh2 {\r\n color: var(--darkGray);\r\n text-align: center;\r\n}\r\n\r\nheader {\r\n align-items: center;\r\n background-color: white;\r\n padding: 5px;\r\n border-bottom: 1px solid var(--citygreen); \r\n /* border: 1px solid var(--citygreen); */\r\n height: var(--header-height);\r\n /* width: calc(100vw - var(--sidebar-width)); */\r\n padding-left: 20px;\r\n}\r\n\r\n/* Logo styling */\r\n#logo {\r\n height: 50px; /* Or your desired size */\r\n margin-right: 20px; /* Optional: space between logo and title */\r\n margin-bottom: -50px;\r\n margin-top: 20px;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/header/header.css"],"names":[],"mappings":";AACA;IACI,kBAAkB;AACtB;;AAEA;IACI,sBAAsB;IACtB,kBAAkB;AACtB;;AAEA;IACI,mBAAmB;IACnB,uBAAuB;IACvB,YAAY;IACZ,yCAAyC;IACzC,yCAAyC;IACzC,4BAA4B;IAC5B,+CAA+C;IAC/C,kBAAkB;AACtB;;AAEA,iBAAiB;AACjB;IACI,YAAY,EAAE,yBAAyB;IACvC,kBAAkB,EAAE,2CAA2C;IAC/D,oBAAoB;IACpB,gBAAgB;AACpB","sourcesContent":["\\r\\nh1 {\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\nh2 {\\r\\n color: var(--darkGray);\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\nheader {\\r\\n align-items: center;\\r\\n background-color: white;\\r\\n padding: 5px;\\r\\n border-bottom: 1px solid var(--citygreen); \\r\\n /* border: 1px solid var(--citygreen); */\\r\\n height: var(--header-height);\\r\\n /* width: calc(100vw - var(--sidebar-width)); */\\r\\n padding-left: 20px;\\r\\n}\\r\\n\\r\\n/* Logo styling */\\r\\n#logo {\\r\\n height: 50px; /* Or your desired size */\\r\\n margin-right: 20px; /* Optional: space between logo and title */\\r\\n margin-bottom: -50px;\\r\\n margin-top: 20px;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA3LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2hlYWRlci9oZWFkZXIuY3NzPzJmNGMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYFxyXG5oMSB7XHJcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XHJcbn1cclxuXHJcbmgyIHtcclxuICAgIGNvbG9yOiB2YXIoLS1kYXJrR3JheSk7XHJcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XHJcbn1cclxuXHJcbmhlYWRlciB7XHJcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XHJcbiAgICBwYWRkaW5nOiA1cHg7XHJcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tY2l0eWdyZWVuKTsgXHJcbiAgICAvKiBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1jaXR5Z3JlZW4pOyAgKi9cclxuICAgIGhlaWdodDogdmFyKC0taGVhZGVyLWhlaWdodCk7XHJcbiAgICAvKiB3aWR0aDogY2FsYygxMDB2dyAtIHZhcigtLXNpZGViYXItd2lkdGgpKTsgKi9cclxuICAgIHBhZGRpbmctbGVmdDogMjBweDtcclxufVxyXG5cclxuLyogTG9nbyBzdHlsaW5nICovXHJcbiNsb2dvIHtcclxuICAgIGhlaWdodDogNTBweDsgLyogT3IgeW91ciBkZXNpcmVkIHNpemUgKi9cclxuICAgIG1hcmdpbi1yaWdodDogMjBweDsgLyogT3B0aW9uYWw6IHNwYWNlIGJldHdlZW4gbG9nbyBhbmQgdGl0bGUgKi9cclxuICAgIG1hcmdpbi1ib3R0b206IC01MHB4O1xyXG4gICAgbWFyZ2luLXRvcDogMjBweDtcclxufWAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2pzL2NvbXBvbmVudHMvaGVhZGVyL2hlYWRlci5jc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQUNBO0lBQ0ksa0JBQWtCO0FBQ3RCOztBQUVBO0lBQ0ksc0JBQXNCO0lBQ3RCLGtCQUFrQjtBQUN0Qjs7QUFFQTtJQUNJLG1CQUFtQjtJQUNuQix1QkFBdUI7SUFDdkIsWUFBWTtJQUNaLHlDQUF5QztJQUN6Qyx5Q0FBeUM7SUFDekMsNEJBQTRCO0lBQzVCLCtDQUErQztJQUMvQyxrQkFBa0I7QUFDdEI7O0FBRUEsaUJBQWlCO0FBQ2pCO0lBQ0ksWUFBWSxFQUFFLHlCQUF5QjtJQUN2QyxrQkFBa0IsRUFBRSwyQ0FBMkM7SUFDL0Qsb0JBQW9CO0lBQ3BCLGdCQUFnQjtBQUNwQlwiLFwic291cmNlc0NvbnRlbnRcIjpbXCJcXHJcXG5oMSB7XFxyXFxuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcXHJcXG59XFxyXFxuXFxyXFxuaDIge1xcclxcbiAgICBjb2xvcjogdmFyKC0tZGFya0dyYXkpO1xcclxcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxufVxcclxcblxcclxcbmhlYWRlciB7XFxyXFxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xcclxcbiAgICBwYWRkaW5nOiA1cHg7XFxyXFxuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1jaXR5Z3JlZW4pOyBcXHJcXG4gICAgLyogYm9yZGVyOiAxcHggc29saWQgdmFyKC0tY2l0eWdyZWVuKTsgICovXFxyXFxuICAgIGhlaWdodDogdmFyKC0taGVhZGVyLWhlaWdodCk7XFxyXFxuICAgIC8qIHdpZHRoOiBjYWxjKDEwMHZ3IC0gdmFyKC0tc2lkZWJhci13aWR0aCkpOyAqL1xcclxcbiAgICBwYWRkaW5nLWxlZnQ6IDIwcHg7XFxyXFxufVxcclxcblxcclxcbi8qIExvZ28gc3R5bGluZyAqL1xcclxcbiNsb2dvIHtcXHJcXG4gICAgaGVpZ2h0OiA1MHB4OyAvKiBPciB5b3VyIGRlc2lyZWQgc2l6ZSAqL1xcclxcbiAgICBtYXJnaW4tcmlnaHQ6IDIwcHg7IC8qIE9wdGlvbmFsOiBzcGFjZSBiZXR3ZWVuIGxvZ28gYW5kIHRpdGxlICovXFxyXFxuICAgIG1hcmdpbi1ib3R0b206IC01MHB4O1xcclxcbiAgICBtYXJnaW4tdG9wOiAyMHB4O1xcclxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcbi8vIEV4cG9ydHNcbmV4cG9ydCBkZWZhdWx0IF9fX0NTU19MT0FERVJfRVhQT1JUX19fO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///107\n')},95:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, ``, "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvbW9kYWwvbW9kYWwuY3NzPzZhY2QiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYGAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W10sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIlwiLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///95\n')},595:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#nav-btns {\r\n margin: 20px;\r\n text-align: center;\r\n /* margin-top: 100px; */\r\n /* position: absolute; or \'absolute\' depending on use-case */\r\n /* top: 100px; Distance from the top of the viewport or the closest positioned ancestor */\r\n}\r\n\r\n#btn-next, #btn-last {\r\n background-color: var(--darkGray);\r\n}\r\n\r\n#btn-next:hover, #btn-last:hover {\r\n background-color: var(--yellow);\r\n color: var(--darkGray);\r\n}\r\n\r\n/* Add style for when you cannot click the next button */\r\n#btn-next.disabled, #btn-last.disabled,\r\n#btn-next.disabled:hover, #btn-last.disabled:hover {\r\n background-color: gray;\r\n color: white;\r\n pointer-events: none;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/nav_buttons/nav_buttons.css"],"names":[],"mappings":"AAAA;IACI,YAAY;IACZ,kBAAkB;IAClB,uBAAuB;IACvB,4DAA4D;IAC5D,yFAAyF;AAC7F;;AAEA;IACI,iCAAiC;AACrC;;AAEA;IACI,+BAA+B;IAC/B,sBAAsB;AAC1B;;AAEA,wDAAwD;AACxD;;IAEI,sBAAsB;IACtB,YAAY;IACZ,oBAAoB;AACxB","sourcesContent":["#nav-btns {\\r\\n margin: 20px;\\r\\n text-align: center;\\r\\n /* margin-top: 100px; */\\r\\n /* position: absolute; or \'absolute\' depending on use-case */\\r\\n /* top: 100px; Distance from the top of the viewport or the closest positioned ancestor */\\r\\n}\\r\\n\\r\\n#btn-next, #btn-last {\\r\\n background-color: var(--darkGray);\\r\\n}\\r\\n\\r\\n#btn-next:hover, #btn-last:hover {\\r\\n background-color: var(--yellow);\\r\\n color: var(--darkGray);\\r\\n}\\r\\n\\r\\n/* Add style for when you cannot click the next button */\\r\\n#btn-next.disabled, #btn-last.disabled,\\r\\n#btn-next.disabled:hover, #btn-last.disabled:hover {\\r\\n background-color: gray;\\r\\n color: white;\\r\\n pointer-events: none;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTk1LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9uYXZfYnV0dG9ucy9uYXZfYnV0dG9ucy5jc3M/OTA1ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgI25hdi1idG5zIHtcclxuICAgIG1hcmdpbjogMjBweDtcclxuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcclxuICAgIC8qIG1hcmdpbi10b3A6IDEwMHB4OyAqL1xyXG4gICAgLyogcG9zaXRpb246IGFic29sdXRlOyBvciAnYWJzb2x1dGUnIGRlcGVuZGluZyBvbiB1c2UtY2FzZSAqL1xyXG4gICAgLyogdG9wOiAxMDBweDsgRGlzdGFuY2UgZnJvbSB0aGUgdG9wIG9mIHRoZSB2aWV3cG9ydCBvciB0aGUgY2xvc2VzdCBwb3NpdGlvbmVkIGFuY2VzdG9yICovXHJcbn1cclxuXHJcbiNidG4tbmV4dCwgI2J0bi1sYXN0IHtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRhcmtHcmF5KTtcclxufVxyXG5cclxuI2J0bi1uZXh0OmhvdmVyLCAjYnRuLWxhc3Q6aG92ZXIge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0teWVsbG93KTtcclxuICAgIGNvbG9yOiB2YXIoLS1kYXJrR3JheSk7XHJcbn1cclxuXHJcbi8qIEFkZCBzdHlsZSBmb3Igd2hlbiB5b3UgY2Fubm90IGNsaWNrIHRoZSBuZXh0IGJ1dHRvbiAqL1xyXG4jYnRuLW5leHQuZGlzYWJsZWQsICNidG4tbGFzdC5kaXNhYmxlZCxcclxuI2J0bi1uZXh0LmRpc2FibGVkOmhvdmVyLCAjYnRuLWxhc3QuZGlzYWJsZWQ6aG92ZXIge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogZ3JheTtcclxuICAgIGNvbG9yOiB3aGl0ZTtcclxuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xyXG59YCwgXCJcIix7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCJ3ZWJwYWNrOi8vLi9zcmMvanMvY29tcG9uZW50cy9uYXZfYnV0dG9ucy9uYXZfYnV0dG9ucy5jc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7SUFDSSxZQUFZO0lBQ1osa0JBQWtCO0lBQ2xCLHVCQUF1QjtJQUN2Qiw0REFBNEQ7SUFDNUQseUZBQXlGO0FBQzdGOztBQUVBO0lBQ0ksaUNBQWlDO0FBQ3JDOztBQUVBO0lBQ0ksK0JBQStCO0lBQy9CLHNCQUFzQjtBQUMxQjs7QUFFQSx3REFBd0Q7QUFDeEQ7O0lBRUksc0JBQXNCO0lBQ3RCLFlBQVk7SUFDWixvQkFBb0I7QUFDeEJcIixcInNvdXJjZXNDb250ZW50XCI6W1wiI25hdi1idG5zIHtcXHJcXG4gICAgbWFyZ2luOiAyMHB4O1xcclxcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxuICAgIC8qIG1hcmdpbi10b3A6IDEwMHB4OyAqL1xcclxcbiAgICAvKiBwb3NpdGlvbjogYWJzb2x1dGU7IG9yICdhYnNvbHV0ZScgZGVwZW5kaW5nIG9uIHVzZS1jYXNlICovXFxyXFxuICAgIC8qIHRvcDogMTAwcHg7IERpc3RhbmNlIGZyb20gdGhlIHRvcCBvZiB0aGUgdmlld3BvcnQgb3IgdGhlIGNsb3Nlc3QgcG9zaXRpb25lZCBhbmNlc3RvciAqL1xcclxcbn1cXHJcXG5cXHJcXG4jYnRuLW5leHQsICNidG4tbGFzdCB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRhcmtHcmF5KTtcXHJcXG59XFxyXFxuXFxyXFxuI2J0bi1uZXh0OmhvdmVyLCAjYnRuLWxhc3Q6aG92ZXIge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS15ZWxsb3cpO1xcclxcbiAgICBjb2xvcjogdmFyKC0tZGFya0dyYXkpO1xcclxcbn1cXHJcXG5cXHJcXG4vKiBBZGQgc3R5bGUgZm9yIHdoZW4geW91IGNhbm5vdCBjbGljayB0aGUgbmV4dCBidXR0b24gKi9cXHJcXG4jYnRuLW5leHQuZGlzYWJsZWQsICNidG4tbGFzdC5kaXNhYmxlZCxcXHJcXG4jYnRuLW5leHQuZGlzYWJsZWQ6aG92ZXIsICNidG4tbGFzdC5kaXNhYmxlZDpob3ZlciB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IGdyYXk7XFxyXFxuICAgIGNvbG9yOiB3aGl0ZTtcXHJcXG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxyXFxufVwiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuLy8gRXhwb3J0c1xuZXhwb3J0IGRlZmF1bHQgX19fQ1NTX0xPQURFUl9FWFBPUlRfX187XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///595\n')},225:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `div#prompt-div {\r\n display: none;\r\n width: 80%;\r\n margin: auto;\r\n text-align: center;\r\n}\r\n\r\nh3#prompt {\r\n text-align: center;\r\n font-size : 1.2em;\r\n}\r\n\r\n#option1, #option2 { \r\n font-size: 1.5em;\r\n border-color: var(--citygreen); \r\n border-width: 2px;\r\n background-color: var(--white);\r\n color: var(--citygreen);\r\n}\r\n\r\n#option1:hover, #option2:hover { \r\n background-color: var(--spiritgreen);\r\n color: white;\r\n}\r\n\r\n#option2.clicked, #option1.clicked {\r\n font-weight: bold;\r\n background-color: var(--spiritgreen);\r\n color: white;\r\n border-width: 3;\r\n}\r\n\r\n#option1.disabled, #option2.disabled, #option1.disabled:hover, #option2.disabled:hover {\r\n background-color: lightgray;\r\n color: gray;\r\n pointer-events: none;\r\n border-color: gray;\r\n}\r\n\r\n`, "",{"version":3,"sources":["webpack://./src/js/components/prompt/prompt.css"],"names":[],"mappings":"AAAA;IACI,aAAa;IACb,UAAU;IACV,YAAY;IACZ,kBAAkB;AACtB;;AAEA;IACI,kBAAkB;IAClB,iBAAiB;AACrB;;AAEA;IACI,gBAAgB;IAChB,8BAA8B;IAC9B,iBAAiB;IACjB,8BAA8B;IAC9B,uBAAuB;AAC3B;;AAEA;IACI,oCAAoC;IACpC,YAAY;AAChB;;AAEA;IACI,iBAAiB;IACjB,oCAAoC;IACpC,YAAY;IACZ,eAAe;AACnB;;AAEA;IACI,2BAA2B;IAC3B,WAAW;IACX,oBAAoB;IACpB,kBAAkB;AACtB","sourcesContent":["div#prompt-div {\\r\\n display: none;\\r\\n width: 80%;\\r\\n margin: auto;\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\nh3#prompt {\\r\\n text-align: center;\\r\\n font-size : 1.2em;\\r\\n}\\r\\n\\r\\n#option1, #option2 { \\r\\n font-size: 1.5em;\\r\\n border-color: var(--citygreen); \\r\\n border-width: 2px;\\r\\n background-color: var(--white);\\r\\n color: var(--citygreen);\\r\\n}\\r\\n\\r\\n#option1:hover, #option2:hover { \\r\\n background-color: var(--spiritgreen);\\r\\n color: white;\\r\\n}\\r\\n\\r\\n#option2.clicked, #option1.clicked {\\r\\n font-weight: bold;\\r\\n background-color: var(--spiritgreen);\\r\\n color: white;\\r\\n border-width: 3;\\r\\n}\\r\\n\\r\\n#option1.disabled, #option2.disabled, #option1.disabled:hover, #option2.disabled:hover {\\r\\n background-color: lightgray;\\r\\n color: gray;\\r\\n pointer-events: none;\\r\\n border-color: gray;\\r\\n}\\r\\n\\r\\n"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjI1LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3Byb21wdC9wcm9tcHQuY3NzP2U2OTkiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYGRpdiNwcm9tcHQtZGl2IHtcclxuICAgIGRpc3BsYXk6IG5vbmU7XHJcbiAgICB3aWR0aDogODAlO1xyXG4gICAgbWFyZ2luOiBhdXRvO1xyXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG59XHJcblxyXG5oMyNwcm9tcHQge1xyXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG4gICAgZm9udC1zaXplIDogMS4yZW07XHJcbn1cclxuXHJcbiNvcHRpb24xLCAjb3B0aW9uMiB7IFxyXG4gICAgZm9udC1zaXplOiAxLjVlbTtcclxuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tY2l0eWdyZWVuKTsgXHJcbiAgICBib3JkZXItd2lkdGg6IDJweDtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXdoaXRlKTtcclxuICAgIGNvbG9yOiB2YXIoLS1jaXR5Z3JlZW4pO1xyXG59XHJcblxyXG4jb3B0aW9uMTpob3ZlciwgI29wdGlvbjI6aG92ZXIgeyBcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIGNvbG9yOiB3aGl0ZTtcclxufVxyXG5cclxuI29wdGlvbjIuY2xpY2tlZCwgI29wdGlvbjEuY2xpY2tlZCB7XHJcbiAgICBmb250LXdlaWdodDogYm9sZDtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIGNvbG9yOiB3aGl0ZTtcclxuICAgIGJvcmRlci13aWR0aDogMztcclxufVxyXG5cclxuI29wdGlvbjEuZGlzYWJsZWQsICNvcHRpb24yLmRpc2FibGVkLCAjb3B0aW9uMS5kaXNhYmxlZDpob3ZlciwgI29wdGlvbjIuZGlzYWJsZWQ6aG92ZXIge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogbGlnaHRncmF5O1xyXG4gICAgY29sb3I6IGdyYXk7XHJcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcclxuICAgIGJvcmRlci1jb2xvcjogZ3JheTtcclxufVxyXG5cclxuYCwgXCJcIix7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCJ3ZWJwYWNrOi8vLi9zcmMvanMvY29tcG9uZW50cy9wcm9tcHQvcHJvbXB0LmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLGFBQWE7SUFDYixVQUFVO0lBQ1YsWUFBWTtJQUNaLGtCQUFrQjtBQUN0Qjs7QUFFQTtJQUNJLGtCQUFrQjtJQUNsQixpQkFBaUI7QUFDckI7O0FBRUE7SUFDSSxnQkFBZ0I7SUFDaEIsOEJBQThCO0lBQzlCLGlCQUFpQjtJQUNqQiw4QkFBOEI7SUFDOUIsdUJBQXVCO0FBQzNCOztBQUVBO0lBQ0ksb0NBQW9DO0lBQ3BDLFlBQVk7QUFDaEI7O0FBRUE7SUFDSSxpQkFBaUI7SUFDakIsb0NBQW9DO0lBQ3BDLFlBQVk7SUFDWixlQUFlO0FBQ25COztBQUVBO0lBQ0ksMkJBQTJCO0lBQzNCLFdBQVc7SUFDWCxvQkFBb0I7SUFDcEIsa0JBQWtCO0FBQ3RCXCIsXCJzb3VyY2VzQ29udGVudFwiOltcImRpdiNwcm9tcHQtZGl2IHtcXHJcXG4gICAgZGlzcGxheTogbm9uZTtcXHJcXG4gICAgd2lkdGg6IDgwJTtcXHJcXG4gICAgbWFyZ2luOiBhdXRvO1xcclxcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxufVxcclxcblxcclxcbmgzI3Byb21wdCB7XFxyXFxuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcXHJcXG4gICAgZm9udC1zaXplIDogMS4yZW07XFxyXFxufVxcclxcblxcclxcbiNvcHRpb24xLCAjb3B0aW9uMiB7IFxcclxcbiAgICBmb250LXNpemU6IDEuNWVtO1xcclxcbiAgICBib3JkZXItY29sb3I6IHZhcigtLWNpdHlncmVlbik7IFxcclxcbiAgICBib3JkZXItd2lkdGg6IDJweDtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0td2hpdGUpO1xcclxcbiAgICBjb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcXHJcXG59XFxyXFxuXFxyXFxuI29wdGlvbjE6aG92ZXIsICNvcHRpb24yOmhvdmVyIHsgXFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcXHJcXG4gICAgY29sb3I6IHdoaXRlO1xcclxcbn1cXHJcXG5cXHJcXG4jb3B0aW9uMi5jbGlja2VkLCAjb3B0aW9uMS5jbGlja2VkIHtcXHJcXG4gICAgZm9udC13ZWlnaHQ6IGJvbGQ7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcXHJcXG4gICAgY29sb3I6IHdoaXRlO1xcclxcbiAgICBib3JkZXItd2lkdGg6IDM7XFxyXFxufVxcclxcblxcclxcbiNvcHRpb24xLmRpc2FibGVkLCAjb3B0aW9uMi5kaXNhYmxlZCwgI29wdGlvbjEuZGlzYWJsZWQ6aG92ZXIsICNvcHRpb24yLmRpc2FibGVkOmhvdmVyIHtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogbGlnaHRncmF5O1xcclxcbiAgICBjb2xvcjogZ3JheTtcXHJcXG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxyXFxuICAgIGJvcmRlci1jb2xvcjogZ3JheTtcXHJcXG59XFxyXFxuXFxyXFxuXCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///225\n')},263:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#sidebar-panel {\r\n background-color: lightgrey; \r\n /* min-height: 100vh; Full height of viewport */\r\n }\r\n\r\n#supp-total .stat {\r\n color: var(--yellow);\r\n}\r\n\r\n.stat {\r\n font-weight: bold;\r\n}\r\n\r\n#sidebar-panel {\r\n height: 100%; /* Full height of the viewport */\r\n position: fixed; /* Fixed Sidebar (stay in place on scroll) */\r\n z-index: 1; /* Stay on top */\r\n top: 0; /* Stay at the top */\r\n right: 0; /* Sidebar appears on the left */\r\n background-color: #FFFFFF; /* White background color */\r\n overflow-x: hidden; /* Disable horizontal scroll */\r\n padding: 20px;\r\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* Add shadow for some depth */\r\n border-right: 2px solid #DDDDDD; /* Right border */\r\n border-radius: 0px 0px 0px 15px; /* Rounded corners on the left */\r\n /* margin-top: var(--header-height); */\r\n width: var(--sidebar-width);\r\n margin: 0px;\r\n }\r\n \r\n.sidebar a {\r\n padding: 10px 15px;\r\n text-decoration: none;\r\n font-size: 18px;\r\n color: #818181;\r\n display: block;\r\n transition: 0.3s;\r\n}\r\n\r\n#sidebar-title {\r\n color: var(--darkGray);\r\n font-weight: bold;\r\n border-bottom: 1px solid var(--citygreen);\r\n}\r\n\r\nhr {\r\n margin-top: -5px;\r\n margin-bottom: 8px;\r\n}\r\n\r\nh6 {\r\n font-weight: 600;\r\n}\r\n\r\n.section-header {\r\n background-color: var(--mediumGray);\r\n}\r\n\r\n.sidebar-stat-line {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between; /* Distribute space between children */\r\n padding: 2px;\r\n border-bottom: 1px solid #ddd;\r\n}\r\n\r\n.edit-icon, .edit-supp {\r\n color: var(--spiritgreen);\r\n cursor: pointer;\r\n font-size: 16px; /* Adjust the size as needed */\r\n margin-left: 10px;\r\n}\r\n\r\n.edit-icon:hover .edit-supp:hover {\r\n color: var(--citygreen);\r\n}\r\n\r\n.stat-label {\r\n margin-right: auto; /* Push next elements to the right */\r\n}\r\n\r\n.stat {\r\n margin-left: 5px; /* Optional: Add some space between currency and edit icon */\r\n}\r\n\r\n.sidebar-stat-line.fund-total .stat {\r\n margin-right: 05px; /* 25px lines up with lines above (with edit symbol) */\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/sidebar/sidebar.css"],"names":[],"mappings":"AAAA;IACI,2BAA2B;IAC3B,+CAA+C;EACjD;;AAEF;IACI,oBAAoB;AACxB;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,YAAY,EAAE,gCAAgC;IAC9C,eAAe,EAAE,4CAA4C;IAC7D,UAAU,EAAE,gBAAgB;IAC5B,MAAM,EAAE,oBAAoB;IAC5B,QAAQ,EAAE,gCAAgC;IAC1C,yBAAyB,EAAE,2BAA2B;IACtD,kBAAkB,EAAE,8BAA8B;IAClD,aAAa;IACb,wCAAwC,EAAE,8BAA8B;IACxE,+BAA+B,EAAE,iBAAiB;IAClD,+BAA+B,EAAE,gCAAgC;IACjE,sCAAsC;IACtC,2BAA2B;IAC3B,WAAW;EACb;;AAEF;IACI,kBAAkB;IAClB,qBAAqB;IACrB,eAAe;IACf,cAAc;IACd,cAAc;IACd,gBAAgB;AACpB;;AAEA;EACE,sBAAsB;EACtB,iBAAiB;EACjB,yCAAyC;AAC3C;;AAEA;EACE,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,8BAA8B,EAAE,sCAAsC;EACtE,YAAY;EACZ,6BAA6B;AAC/B;;AAEA;EACE,yBAAyB;EACzB,eAAe;EACf,eAAe,EAAE,8BAA8B;EAC/C,iBAAiB;AACnB;;AAEA;EACE,uBAAuB;AACzB;;AAEA;EACE,kBAAkB,EAAE,oCAAoC;AAC1D;;AAEA;EACE,gBAAgB,EAAE,4DAA4D;AAChF;;AAEA;EACE,kBAAkB,EAAE,sDAAsD;AAC5E","sourcesContent":["#sidebar-panel {\\r\\n background-color: lightgrey; \\r\\n /* min-height: 100vh; Full height of viewport */\\r\\n }\\r\\n\\r\\n#supp-total .stat {\\r\\n color: var(--yellow);\\r\\n}\\r\\n\\r\\n.stat {\\r\\n font-weight: bold;\\r\\n}\\r\\n\\r\\n#sidebar-panel {\\r\\n height: 100%; /* Full height of the viewport */\\r\\n position: fixed; /* Fixed Sidebar (stay in place on scroll) */\\r\\n z-index: 1; /* Stay on top */\\r\\n top: 0; /* Stay at the top */\\r\\n right: 0; /* Sidebar appears on the left */\\r\\n background-color: #FFFFFF; /* White background color */\\r\\n overflow-x: hidden; /* Disable horizontal scroll */\\r\\n padding: 20px;\\r\\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* Add shadow for some depth */\\r\\n border-right: 2px solid #DDDDDD; /* Right border */\\r\\n border-radius: 0px 0px 0px 15px; /* Rounded corners on the left */\\r\\n /* margin-top: var(--header-height); */\\r\\n width: var(--sidebar-width);\\r\\n margin: 0px;\\r\\n }\\r\\n \\r\\n.sidebar a {\\r\\n padding: 10px 15px;\\r\\n text-decoration: none;\\r\\n font-size: 18px;\\r\\n color: #818181;\\r\\n display: block;\\r\\n transition: 0.3s;\\r\\n}\\r\\n\\r\\n#sidebar-title {\\r\\n color: var(--darkGray);\\r\\n font-weight: bold;\\r\\n border-bottom: 1px solid var(--citygreen);\\r\\n}\\r\\n\\r\\nhr {\\r\\n margin-top: -5px;\\r\\n margin-bottom: 8px;\\r\\n}\\r\\n\\r\\nh6 {\\r\\n font-weight: 600;\\r\\n}\\r\\n\\r\\n.section-header {\\r\\n background-color: var(--mediumGray);\\r\\n}\\r\\n\\r\\n.sidebar-stat-line {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between; /* Distribute space between children */\\r\\n padding: 2px;\\r\\n border-bottom: 1px solid #ddd;\\r\\n}\\r\\n\\r\\n.edit-icon, .edit-supp {\\r\\n color: var(--spiritgreen);\\r\\n cursor: pointer;\\r\\n font-size: 16px; /* Adjust the size as needed */\\r\\n margin-left: 10px;\\r\\n}\\r\\n\\r\\n.edit-icon:hover .edit-supp:hover {\\r\\n color: var(--citygreen);\\r\\n}\\r\\n\\r\\n.stat-label {\\r\\n margin-right: auto; /* Push next elements to the right */\\r\\n}\\r\\n\\r\\n.stat {\\r\\n margin-left: 5px; /* Optional: Add some space between currency and edit icon */\\r\\n}\\r\\n\\r\\n.sidebar-stat-line.fund-total .stat {\\r\\n margin-right: 05px; /* 25px lines up with lines above (with edit symbol) */\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3NpZGViYXIvc2lkZWJhci5jc3M/M2IwMyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgI3NpZGViYXItcGFuZWwge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogbGlnaHRncmV5OyAgXHJcbiAgICAvKiBtaW4taGVpZ2h0OiAxMDB2aDsgRnVsbCBoZWlnaHQgb2Ygdmlld3BvcnQgKi9cclxuICB9XHJcblxyXG4jc3VwcC10b3RhbCAuc3RhdCB7XHJcbiAgICBjb2xvcjogdmFyKC0teWVsbG93KTtcclxufVxyXG5cclxuLnN0YXQge1xyXG4gICAgZm9udC13ZWlnaHQ6IGJvbGQ7XHJcbn1cclxuXHJcbiNzaWRlYmFyLXBhbmVsIHtcclxuICAgIGhlaWdodDogMTAwJTsgLyogRnVsbCBoZWlnaHQgb2YgdGhlIHZpZXdwb3J0ICovXHJcbiAgICBwb3NpdGlvbjogZml4ZWQ7IC8qIEZpeGVkIFNpZGViYXIgKHN0YXkgaW4gcGxhY2Ugb24gc2Nyb2xsKSAqL1xyXG4gICAgei1pbmRleDogMTsgLyogU3RheSBvbiB0b3AgKi9cclxuICAgIHRvcDogMDsgLyogU3RheSBhdCB0aGUgdG9wICovXHJcbiAgICByaWdodDogMDsgLyogU2lkZWJhciBhcHBlYXJzIG9uIHRoZSBsZWZ0ICovXHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjRkZGRkZGOyAvKiBXaGl0ZSBiYWNrZ3JvdW5kIGNvbG9yICovXHJcbiAgICBvdmVyZmxvdy14OiBoaWRkZW47IC8qIERpc2FibGUgaG9yaXpvbnRhbCBzY3JvbGwgKi9cclxuICAgIHBhZGRpbmc6IDIwcHg7XHJcbiAgICBib3gtc2hhZG93OiAwIDJweCA1cHggcmdiYSgwLCAwLCAwLCAwLjEpOyAvKiBBZGQgc2hhZG93IGZvciBzb21lIGRlcHRoICovXHJcbiAgICBib3JkZXItcmlnaHQ6IDJweCBzb2xpZCAjREREREREOyAvKiBSaWdodCBib3JkZXIgKi9cclxuICAgIGJvcmRlci1yYWRpdXM6IDBweCAwcHggMHB4IDE1cHg7IC8qIFJvdW5kZWQgY29ybmVycyBvbiB0aGUgbGVmdCAqL1xyXG4gICAgLyogbWFyZ2luLXRvcDogdmFyKC0taGVhZGVyLWhlaWdodCk7ICovXHJcbiAgICB3aWR0aDogdmFyKC0tc2lkZWJhci13aWR0aCk7XHJcbiAgICBtYXJnaW46IDBweDtcclxuICB9XHJcbiAgXHJcbi5zaWRlYmFyIGEge1xyXG4gICAgcGFkZGluZzogMTBweCAxNXB4O1xyXG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xyXG4gICAgZm9udC1zaXplOiAxOHB4O1xyXG4gICAgY29sb3I6ICM4MTgxODE7XHJcbiAgICBkaXNwbGF5OiBibG9jaztcclxuICAgIHRyYW5zaXRpb246IDAuM3M7XHJcbn1cclxuXHJcbiNzaWRlYmFyLXRpdGxlIHtcclxuICBjb2xvcjogdmFyKC0tZGFya0dyYXkpO1xyXG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xyXG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1jaXR5Z3JlZW4pO1xyXG59XHJcblxyXG5ociB7XHJcbiAgbWFyZ2luLXRvcDogLTVweDtcclxuICBtYXJnaW4tYm90dG9tOiA4cHg7XHJcbn1cclxuXHJcbmg2IHtcclxuICBmb250LXdlaWdodDogNjAwO1xyXG59XHJcblxyXG4uc2VjdGlvbi1oZWFkZXIge1xyXG4gIGJhY2tncm91bmQtY29sb3I6IHZhcigtLW1lZGl1bUdyYXkpO1xyXG59XHJcblxyXG4uc2lkZWJhci1zdGF0LWxpbmUge1xyXG4gIGRpc3BsYXk6IGZsZXg7XHJcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IC8qIERpc3RyaWJ1dGUgc3BhY2UgYmV0d2VlbiBjaGlsZHJlbiAqL1xyXG4gIHBhZGRpbmc6IDJweDtcclxuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2RkZDtcclxufVxyXG5cclxuLmVkaXQtaWNvbiwgLmVkaXQtc3VwcCB7XHJcbiAgY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICBjdXJzb3I6IHBvaW50ZXI7XHJcbiAgZm9udC1zaXplOiAxNnB4OyAvKiBBZGp1c3QgdGhlIHNpemUgYXMgbmVlZGVkICovXHJcbiAgbWFyZ2luLWxlZnQ6IDEwcHg7XHJcbn1cclxuXHJcbi5lZGl0LWljb246aG92ZXIgLmVkaXQtc3VwcDpob3ZlciB7XHJcbiAgY29sb3I6IHZhcigtLWNpdHlncmVlbik7XHJcbn1cclxuXHJcbi5zdGF0LWxhYmVsIHtcclxuICBtYXJnaW4tcmlnaHQ6IGF1dG87IC8qIFB1c2ggbmV4dCBlbGVtZW50cyB0byB0aGUgcmlnaHQgKi9cclxufVxyXG5cclxuLnN0YXQge1xyXG4gIG1hcmdpbi1sZWZ0OiA1cHg7IC8qIE9wdGlvbmFsOiBBZGQgc29tZSBzcGFjZSBiZXR3ZWVuIGN1cnJlbmN5IGFuZCBlZGl0IGljb24gKi9cclxufVxyXG5cclxuLnNpZGViYXItc3RhdC1saW5lLmZ1bmQtdG90YWwgLnN0YXQge1xyXG4gIG1hcmdpbi1yaWdodDogMDVweDsgLyogMjVweCBsaW5lcyB1cCB3aXRoIGxpbmVzIGFib3ZlICh3aXRoIGVkaXQgc3ltYm9sKSAqL1xyXG59YCwgXCJcIix7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCJ3ZWJwYWNrOi8vLi9zcmMvanMvY29tcG9uZW50cy9zaWRlYmFyL3NpZGViYXIuY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0lBQ0ksMkJBQTJCO0lBQzNCLCtDQUErQztFQUNqRDs7QUFFRjtJQUNJLG9CQUFvQjtBQUN4Qjs7QUFFQTtJQUNJLGlCQUFpQjtBQUNyQjs7QUFFQTtJQUNJLFlBQVksRUFBRSxnQ0FBZ0M7SUFDOUMsZUFBZSxFQUFFLDRDQUE0QztJQUM3RCxVQUFVLEVBQUUsZ0JBQWdCO0lBQzVCLE1BQU0sRUFBRSxvQkFBb0I7SUFDNUIsUUFBUSxFQUFFLGdDQUFnQztJQUMxQyx5QkFBeUIsRUFBRSwyQkFBMkI7SUFDdEQsa0JBQWtCLEVBQUUsOEJBQThCO0lBQ2xELGFBQWE7SUFDYix3Q0FBd0MsRUFBRSw4QkFBOEI7SUFDeEUsK0JBQStCLEVBQUUsaUJBQWlCO0lBQ2xELCtCQUErQixFQUFFLGdDQUFnQztJQUNqRSxzQ0FBc0M7SUFDdEMsMkJBQTJCO0lBQzNCLFdBQVc7RUFDYjs7QUFFRjtJQUNJLGtCQUFrQjtJQUNsQixxQkFBcUI7SUFDckIsZUFBZTtJQUNmLGNBQWM7SUFDZCxjQUFjO0lBQ2QsZ0JBQWdCO0FBQ3BCOztBQUVBO0VBQ0Usc0JBQXNCO0VBQ3RCLGlCQUFpQjtFQUNqQix5Q0FBeUM7QUFDM0M7O0FBRUE7RUFDRSxnQkFBZ0I7RUFDaEIsa0JBQWtCO0FBQ3BCOztBQUVBO0VBQ0UsZ0JBQWdCO0FBQ2xCOztBQUVBO0VBQ0UsbUNBQW1DO0FBQ3JDOztBQUVBO0VBQ0UsYUFBYTtFQUNiLG1CQUFtQjtFQUNuQiw4QkFBOEIsRUFBRSxzQ0FBc0M7RUFDdEUsWUFBWTtFQUNaLDZCQUE2QjtBQUMvQjs7QUFFQTtFQUNFLHlCQUF5QjtFQUN6QixlQUFlO0VBQ2YsZUFBZSxFQUFFLDhCQUE4QjtFQUMvQyxpQkFBaUI7QUFDbkI7O0FBRUE7RUFDRSx1QkFBdUI7QUFDekI7O0FBRUE7RUFDRSxrQkFBa0IsRUFBRSxvQ0FBb0M7QUFDMUQ7O0FBRUE7RUFDRSxnQkFBZ0IsRUFBRSw0REFBNEQ7QUFDaEY7O0FBRUE7RUFDRSxrQkFBa0IsRUFBRSxzREFBc0Q7QUFDNUVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiI3NpZGViYXItcGFuZWwge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiBsaWdodGdyZXk7ICBcXHJcXG4gICAgLyogbWluLWhlaWdodDogMTAwdmg7IEZ1bGwgaGVpZ2h0IG9mIHZpZXdwb3J0ICovXFxyXFxuICB9XFxyXFxuXFxyXFxuI3N1cHAtdG90YWwgLnN0YXQge1xcclxcbiAgICBjb2xvcjogdmFyKC0teWVsbG93KTtcXHJcXG59XFxyXFxuXFxyXFxuLnN0YXQge1xcclxcbiAgICBmb250LXdlaWdodDogYm9sZDtcXHJcXG59XFxyXFxuXFxyXFxuI3NpZGViYXItcGFuZWwge1xcclxcbiAgICBoZWlnaHQ6IDEwMCU7IC8qIEZ1bGwgaGVpZ2h0IG9mIHRoZSB2aWV3cG9ydCAqL1xcclxcbiAgICBwb3NpdGlvbjogZml4ZWQ7IC8qIEZpeGVkIFNpZGViYXIgKHN0YXkgaW4gcGxhY2Ugb24gc2Nyb2xsKSAqL1xcclxcbiAgICB6LWluZGV4OiAxOyAvKiBTdGF5IG9uIHRvcCAqL1xcclxcbiAgICB0b3A6IDA7IC8qIFN0YXkgYXQgdGhlIHRvcCAqL1xcclxcbiAgICByaWdodDogMDsgLyogU2lkZWJhciBhcHBlYXJzIG9uIHRoZSBsZWZ0ICovXFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6ICNGRkZGRkY7IC8qIFdoaXRlIGJhY2tncm91bmQgY29sb3IgKi9cXHJcXG4gICAgb3ZlcmZsb3cteDogaGlkZGVuOyAvKiBEaXNhYmxlIGhvcml6b250YWwgc2Nyb2xsICovXFxyXFxuICAgIHBhZGRpbmc6IDIwcHg7XFxyXFxuICAgIGJveC1zaGFkb3c6IDAgMnB4IDVweCByZ2JhKDAsIDAsIDAsIDAuMSk7IC8qIEFkZCBzaGFkb3cgZm9yIHNvbWUgZGVwdGggKi9cXHJcXG4gICAgYm9yZGVyLXJpZ2h0OiAycHggc29saWQgI0RERERERDsgLyogUmlnaHQgYm9yZGVyICovXFxyXFxuICAgIGJvcmRlci1yYWRpdXM6IDBweCAwcHggMHB4IDE1cHg7IC8qIFJvdW5kZWQgY29ybmVycyBvbiB0aGUgbGVmdCAqL1xcclxcbiAgICAvKiBtYXJnaW4tdG9wOiB2YXIoLS1oZWFkZXItaGVpZ2h0KTsgKi9cXHJcXG4gICAgd2lkdGg6IHZhcigtLXNpZGViYXItd2lkdGgpO1xcclxcbiAgICBtYXJnaW46IDBweDtcXHJcXG4gIH1cXHJcXG4gIFxcclxcbi5zaWRlYmFyIGEge1xcclxcbiAgICBwYWRkaW5nOiAxMHB4IDE1cHg7XFxyXFxuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcXHJcXG4gICAgZm9udC1zaXplOiAxOHB4O1xcclxcbiAgICBjb2xvcjogIzgxODE4MTtcXHJcXG4gICAgZGlzcGxheTogYmxvY2s7XFxyXFxuICAgIHRyYW5zaXRpb246IDAuM3M7XFxyXFxufVxcclxcblxcclxcbiNzaWRlYmFyLXRpdGxlIHtcXHJcXG4gIGNvbG9yOiB2YXIoLS1kYXJrR3JheSk7XFxyXFxuICBmb250LXdlaWdodDogYm9sZDtcXHJcXG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1jaXR5Z3JlZW4pO1xcclxcbn1cXHJcXG5cXHJcXG5ociB7XFxyXFxuICBtYXJnaW4tdG9wOiAtNXB4O1xcclxcbiAgbWFyZ2luLWJvdHRvbTogOHB4O1xcclxcbn1cXHJcXG5cXHJcXG5oNiB7XFxyXFxuICBmb250LXdlaWdodDogNjAwO1xcclxcbn1cXHJcXG5cXHJcXG4uc2VjdGlvbi1oZWFkZXIge1xcclxcbiAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tbWVkaXVtR3JheSk7XFxyXFxufVxcclxcblxcclxcbi5zaWRlYmFyLXN0YXQtbGluZSB7XFxyXFxuICBkaXNwbGF5OiBmbGV4O1xcclxcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcXHJcXG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgLyogRGlzdHJpYnV0ZSBzcGFjZSBiZXR3ZWVuIGNoaWxkcmVuICovXFxyXFxuICBwYWRkaW5nOiAycHg7XFxyXFxuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2RkZDtcXHJcXG59XFxyXFxuXFxyXFxuLmVkaXQtaWNvbiwgLmVkaXQtc3VwcCB7XFxyXFxuICBjb2xvcjogdmFyKC0tc3Bpcml0Z3JlZW4pO1xcclxcbiAgY3Vyc29yOiBwb2ludGVyO1xcclxcbiAgZm9udC1zaXplOiAxNnB4OyAvKiBBZGp1c3QgdGhlIHNpemUgYXMgbmVlZGVkICovXFxyXFxuICBtYXJnaW4tbGVmdDogMTBweDtcXHJcXG59XFxyXFxuXFxyXFxuLmVkaXQtaWNvbjpob3ZlciAuZWRpdC1zdXBwOmhvdmVyIHtcXHJcXG4gIGNvbG9yOiB2YXIoLS1jaXR5Z3JlZW4pO1xcclxcbn1cXHJcXG5cXHJcXG4uc3RhdC1sYWJlbCB7XFxyXFxuICBtYXJnaW4tcmlnaHQ6IGF1dG87IC8qIFB1c2ggbmV4dCBlbGVtZW50cyB0byB0aGUgcmlnaHQgKi9cXHJcXG59XFxyXFxuXFxyXFxuLnN0YXQge1xcclxcbiAgbWFyZ2luLWxlZnQ6IDVweDsgLyogT3B0aW9uYWw6IEFkZCBzb21lIHNwYWNlIGJldHdlZW4gY3VycmVuY3kgYW5kIGVkaXQgaWNvbiAqL1xcclxcbn1cXHJcXG5cXHJcXG4uc2lkZWJhci1zdGF0LWxpbmUuZnVuZC10b3RhbCAuc3RhdCB7XFxyXFxuICBtYXJnaW4tcmlnaHQ6IDA1cHg7IC8qIDI1cHggbGluZXMgdXAgd2l0aCBsaW5lcyBhYm92ZSAod2l0aCBlZGl0IHN5bWJvbCkgKi9cXHJcXG59XCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///263\n')},279:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#main-table {\r\n font-size: 12px;\r\n /* calc(0.5vw + 0.5em); */\r\n margin: auto;\r\n width: 100%;\r\n}\r\n\r\n#main-table thead > tr > th {\r\n text-align: left;\r\n background-color: var(--darkGray);\r\n color: white;\r\n position: -webkit-sticky; /* For Safari */\r\n position: sticky;\r\n top: 0;\r\n}\r\n\r\nth {\r\n background-color: var(--lightGray);\r\n}\r\n\r\ntr {\r\n border-width: 2px;\r\n background-color: white;\r\n}\r\n\r\ntr td {\r\n border-bottom: 1px solid black;\r\n}\r\n\r\n/* Default to hidden columns */\r\n\r\n#main-table tbody > tr > td {\r\n display : none;\r\n}\r\n#main-table thead > tr > th {\r\n display : none;\r\n}\r\n\r\n/* textbox width in table */\r\ninput {\r\n width: 100%;\r\n}\r\n\r\nselect {\r\n max-width: 100px;\r\n}\r\n\r\ndiv.table-container {\r\n overflow-x: auto; \r\n overflow-y: auto;\r\n margin-left: max(65px, 7vh);\r\n margin-right: max(65px, 7vh);\r\n /* max-width: calc(100vw - var(--sidebar-width)); */\r\n /* margin: auto; */\r\n max-height: max(350px, 6vh);\r\n /* min-height: 350px; */\r\n\r\n}\r\n \r\n/* Buttons */\r\n\r\n/* Add new row button */\r\n.btn-add { \r\n background-color: var(--spiritgreen);\r\n margin-top: 20px;\r\n display: none;\r\n}\r\n\r\n.btn-delete {\r\n background-color: var(--orange);\r\n}\r\n\r\n#add-btn-div {\r\n display: flex;\r\n justify-content: center; /* Aligns horizontally */\r\n align-items: center; /* Aligns vertically */\r\n width: 100%;\r\n}\r\n\r\n.btn-edit {\r\n background-color: var(--spiritgreen);\r\n line-height: 1.1;\r\n}\r\n\r\n.active-editing, .selected {\r\n background-color: var(--palegreen);\r\n}\r\n\r\n.selected { \r\n font-weight: bold;\r\n}\r\n\r\n.btn-confirm {\r\n display: none;\r\n}\r\n\r\n.confirm-btn:hover {\r\n background-color: var(--green);\r\n}\r\n\r\n.hover-effect:hover {\r\n cursor: pointer;\r\n background-color: var(--verypalegreen); \r\n}\r\n\r\n/* Fund table */\r\n.fund-name > .viewed-fund {\r\n color: gray;\r\n}\r\n\r\n/* made edit column narrower */\r\nth.edit, td.edit {\r\n width: 20px;\r\n}\r\n\r\n#search-bar-container {\r\n display: flex;\r\n justify-content: flex-end; /* Align the search bar to the right */\r\n align-items: center; /* Vertically center content */\r\n margin-left: max(65px, 7vh);\r\n margin-right: max(80px, 7vh);\r\n margin-bottom: -10px;\r\n}\r\n\r\n#search-bar-container label {\r\n display: flex;\r\n align-items: center; /* Vertically center the label and input */\r\n}\r\n\r\n#search-bar-container input[type="search"] {\r\n width: auto; /* Adjust the width of the search bar as needed */\r\n margin-left: 5px; /* Space between the label and input */\r\n height: 100%; /* Ensure the input height is consistent */\r\n margin-top: 15px;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/table/table.css"],"names":[],"mappings":"AAAA;IACI,eAAe;IACf,yBAAyB;IACzB,YAAY;IACZ,WAAW;AACf;;AAEA;IACI,gBAAgB;IAChB,iCAAiC;IACjC,YAAY;IACZ,wBAAwB,EAAE,eAAe;IACzC,gBAAgB;IAChB,MAAM;AACV;;AAEA;IACI,kCAAkC;AACtC;;AAEA;IACI,iBAAiB;IACjB,uBAAuB;AAC3B;;AAEA;IACI,8BAA8B;AAClC;;AAEA,8BAA8B;;AAE9B;IACI,cAAc;AAClB;AACA;IACI,cAAc;AAClB;;AAEA,2BAA2B;AAC3B;IACI,WAAW;AACf;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,gBAAgB;IAChB,gBAAgB;IAChB,2BAA2B;IAC3B,4BAA4B;IAC5B,oDAAoD;IACpD,kBAAkB;IAClB,2BAA2B;IAC3B,uBAAuB;;AAE3B;;AAEA,YAAY;;AAEZ,uBAAuB;AACvB;IACI,oCAAoC;IACpC,gBAAgB;IAChB,aAAa;AACjB;;AAEA;IACI,+BAA+B;AACnC;;AAEA;IACI,aAAa;IACb,uBAAuB,EAAE,wBAAwB;IACjD,mBAAmB,EAAE,sBAAsB;IAC3C,WAAW;AACf;;AAEA;IACI,oCAAoC;IACpC,gBAAgB;AACpB;;AAEA;IACI,kCAAkC;AACtC;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,8BAA8B;AAClC;;AAEA;IACI,eAAe;IACf,sCAAsC;AAC1C;;AAEA,eAAe;AACf;IACI,WAAW;AACf;;AAEA,8BAA8B;AAC9B;IACI,WAAW;AACf;;AAEA;IACI,aAAa;IACb,yBAAyB,GAAG,sCAAsC;IAClE,mBAAmB,GAAG,8BAA8B;IACpD,2BAA2B;IAC3B,4BAA4B;IAC5B,oBAAoB;AACxB;;AAEA;IACI,aAAa;IACb,mBAAmB,GAAG,0CAA0C;AACpE;;AAEA;IACI,WAAW,GAAG,iDAAiD;IAC/D,gBAAgB,GAAG,sCAAsC;IACzD,YAAY,GAAG,0CAA0C;IACzD,gBAAgB;AACpB","sourcesContent":["#main-table {\\r\\n font-size: 12px;\\r\\n /* calc(0.5vw + 0.5em); */\\r\\n margin: auto;\\r\\n width: 100%;\\r\\n}\\r\\n\\r\\n#main-table thead > tr > th {\\r\\n text-align: left;\\r\\n background-color: var(--darkGray);\\r\\n color: white;\\r\\n position: -webkit-sticky; /* For Safari */\\r\\n position: sticky;\\r\\n top: 0;\\r\\n}\\r\\n\\r\\nth {\\r\\n background-color: var(--lightGray);\\r\\n}\\r\\n\\r\\ntr {\\r\\n border-width: 2px;\\r\\n background-color: white;\\r\\n}\\r\\n\\r\\ntr td {\\r\\n border-bottom: 1px solid black;\\r\\n}\\r\\n\\r\\n/* Default to hidden columns */\\r\\n\\r\\n#main-table tbody > tr > td {\\r\\n display : none;\\r\\n}\\r\\n#main-table thead > tr > th {\\r\\n display : none;\\r\\n}\\r\\n\\r\\n/* textbox width in table */\\r\\ninput {\\r\\n width: 100%;\\r\\n}\\r\\n\\r\\nselect {\\r\\n max-width: 100px;\\r\\n}\\r\\n\\r\\ndiv.table-container {\\r\\n overflow-x: auto; \\r\\n overflow-y: auto;\\r\\n margin-left: max(65px, 7vh);\\r\\n margin-right: max(65px, 7vh);\\r\\n /* max-width: calc(100vw - var(--sidebar-width)); */\\r\\n /* margin: auto; */\\r\\n max-height: max(350px, 6vh);\\r\\n /* min-height: 350px; */\\r\\n\\r\\n}\\r\\n \\r\\n/* Buttons */\\r\\n\\r\\n/* Add new row button */\\r\\n.btn-add { \\r\\n background-color: var(--spiritgreen);\\r\\n margin-top: 20px;\\r\\n display: none;\\r\\n}\\r\\n\\r\\n.btn-delete {\\r\\n background-color: var(--orange);\\r\\n}\\r\\n\\r\\n#add-btn-div {\\r\\n display: flex;\\r\\n justify-content: center; /* Aligns horizontally */\\r\\n align-items: center; /* Aligns vertically */\\r\\n width: 100%;\\r\\n}\\r\\n\\r\\n.btn-edit {\\r\\n background-color: var(--spiritgreen);\\r\\n line-height: 1.1;\\r\\n}\\r\\n\\r\\n.active-editing, .selected {\\r\\n background-color: var(--palegreen);\\r\\n}\\r\\n\\r\\n.selected { \\r\\n font-weight: bold;\\r\\n}\\r\\n\\r\\n.btn-confirm {\\r\\n display: none;\\r\\n}\\r\\n\\r\\n.confirm-btn:hover {\\r\\n background-color: var(--green);\\r\\n}\\r\\n\\r\\n.hover-effect:hover {\\r\\n cursor: pointer;\\r\\n background-color: var(--verypalegreen); \\r\\n}\\r\\n\\r\\n/* Fund table */\\r\\n.fund-name > .viewed-fund {\\r\\n color: gray;\\r\\n}\\r\\n\\r\\n/* made edit column narrower */\\r\\nth.edit, td.edit {\\r\\n width: 20px;\\r\\n}\\r\\n\\r\\n#search-bar-container {\\r\\n display: flex;\\r\\n justify-content: flex-end; /* Align the search bar to the right */\\r\\n align-items: center; /* Vertically center content */\\r\\n margin-left: max(65px, 7vh);\\r\\n margin-right: max(80px, 7vh);\\r\\n margin-bottom: -10px;\\r\\n}\\r\\n\\r\\n#search-bar-container label {\\r\\n display: flex;\\r\\n align-items: center; /* Vertically center the label and input */\\r\\n}\\r\\n\\r\\n#search-bar-container input[type=\\"search\\"] {\\r\\n width: auto; /* Adjust the width of the search bar as needed */\\r\\n margin-left: 5px; /* Space between the label and input */\\r\\n height: 100%; /* Ensure the input height is consistent */\\r\\n margin-top: 15px;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc5LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy90YWJsZS90YWJsZS5jc3M/NTIzNyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgI21haW4tdGFibGUge1xyXG4gICAgZm9udC1zaXplOiAxMnB4O1xyXG4gICAgLyogY2FsYygwLjV2dyArIDAuNWVtKTsgKi9cclxuICAgIG1hcmdpbjogYXV0bztcclxuICAgIHdpZHRoOiAxMDAlO1xyXG59XHJcblxyXG4jbWFpbi10YWJsZSB0aGVhZCA+IHRyID4gdGgge1xyXG4gICAgdGV4dC1hbGlnbjogbGVmdDtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRhcmtHcmF5KTtcclxuICAgIGNvbG9yOiB3aGl0ZTtcclxuICAgIHBvc2l0aW9uOiAtd2Via2l0LXN0aWNreTsgLyogRm9yIFNhZmFyaSAqL1xyXG4gICAgcG9zaXRpb246IHN0aWNreTtcclxuICAgIHRvcDogMDtcclxufVxyXG5cclxudGgge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tbGlnaHRHcmF5KTtcclxufVxyXG5cclxudHIge1xyXG4gICAgYm9yZGVyLXdpZHRoOiAycHg7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTtcclxufVxyXG5cclxudHIgdGQge1xyXG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIGJsYWNrO1xyXG59XHJcblxyXG4vKiBEZWZhdWx0IHRvIGhpZGRlbiBjb2x1bW5zICovXHJcblxyXG4jbWFpbi10YWJsZSB0Ym9keSA+IHRyID4gdGQge1xyXG4gICAgZGlzcGxheSA6IG5vbmU7XHJcbn1cclxuI21haW4tdGFibGUgdGhlYWQgPiB0ciA+IHRoIHtcclxuICAgIGRpc3BsYXkgOiBub25lO1xyXG59XHJcblxyXG4vKiB0ZXh0Ym94IHdpZHRoIGluIHRhYmxlICovXHJcbmlucHV0IHtcclxuICAgIHdpZHRoOiAxMDAlO1xyXG59XHJcblxyXG5zZWxlY3Qge1xyXG4gICAgbWF4LXdpZHRoOiAxMDBweDtcclxufVxyXG5cclxuZGl2LnRhYmxlLWNvbnRhaW5lciB7XHJcbiAgICBvdmVyZmxvdy14OiBhdXRvOyBcclxuICAgIG92ZXJmbG93LXk6IGF1dG87XHJcbiAgICBtYXJnaW4tbGVmdDogbWF4KDY1cHgsIDd2aCk7XHJcbiAgICBtYXJnaW4tcmlnaHQ6IG1heCg2NXB4LCA3dmgpO1xyXG4gICAgLyogbWF4LXdpZHRoOiBjYWxjKDEwMHZ3IC0gdmFyKC0tc2lkZWJhci13aWR0aCkpOyAgKi9cclxuICAgIC8qIG1hcmdpbjogYXV0bzsgKi9cclxuICAgIG1heC1oZWlnaHQ6IG1heCgzNTBweCwgNnZoKTtcclxuICAgIC8qIG1pbi1oZWlnaHQ6IDM1MHB4OyAqL1xyXG5cclxufVxyXG4gIFxyXG4vKiBCdXR0b25zICovXHJcblxyXG4vKiBBZGQgbmV3IHJvdyBidXR0b24gKi9cclxuLmJ0bi1hZGQgeyBcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIG1hcmdpbi10b3A6IDIwcHg7XHJcbiAgICBkaXNwbGF5OiBub25lO1xyXG59XHJcblxyXG4uYnRuLWRlbGV0ZSB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1vcmFuZ2UpO1xyXG59XHJcblxyXG4jYWRkLWJ0bi1kaXYge1xyXG4gICAgZGlzcGxheTogZmxleDtcclxuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOyAvKiBBbGlnbnMgaG9yaXpvbnRhbGx5ICovXHJcbiAgICBhbGlnbi1pdGVtczogY2VudGVyOyAvKiBBbGlnbnMgdmVydGljYWxseSAqL1xyXG4gICAgd2lkdGg6IDEwMCU7XHJcbn1cclxuXHJcbi5idG4tZWRpdCB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XHJcbiAgICBsaW5lLWhlaWdodDogMS4xO1xyXG59XHJcblxyXG4uYWN0aXZlLWVkaXRpbmcsIC5zZWxlY3RlZCB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1wYWxlZ3JlZW4pO1xyXG59XHJcblxyXG4uc2VsZWN0ZWQgeyBcclxuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xyXG59XHJcblxyXG4uYnRuLWNvbmZpcm0ge1xyXG4gICAgZGlzcGxheTogbm9uZTtcclxufVxyXG5cclxuLmNvbmZpcm0tYnRuOmhvdmVyIHtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWdyZWVuKTtcclxufVxyXG5cclxuLmhvdmVyLWVmZmVjdDpob3ZlciB7XHJcbiAgICBjdXJzb3I6IHBvaW50ZXI7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS12ZXJ5cGFsZWdyZWVuKTsgXHJcbn1cclxuXHJcbi8qIEZ1bmQgdGFibGUgKi9cclxuLmZ1bmQtbmFtZSA+IC52aWV3ZWQtZnVuZCB7XHJcbiAgICBjb2xvcjogZ3JheTtcclxufVxyXG5cclxuLyogbWFkZSBlZGl0IGNvbHVtbiBuYXJyb3dlciAqL1xyXG50aC5lZGl0LCB0ZC5lZGl0IHtcclxuICAgIHdpZHRoOiAyMHB4O1xyXG59XHJcblxyXG4jc2VhcmNoLWJhci1jb250YWluZXIge1xyXG4gICAgZGlzcGxheTogZmxleDtcclxuICAgIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7ICAvKiBBbGlnbiB0aGUgc2VhcmNoIGJhciB0byB0aGUgcmlnaHQgKi9cclxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7ICAvKiBWZXJ0aWNhbGx5IGNlbnRlciBjb250ZW50ICovXHJcbiAgICBtYXJnaW4tbGVmdDogbWF4KDY1cHgsIDd2aCk7XHJcbiAgICBtYXJnaW4tcmlnaHQ6IG1heCg4MHB4LCA3dmgpO1xyXG4gICAgbWFyZ2luLWJvdHRvbTogLTEwcHg7XHJcbn1cclxuXHJcbiNzZWFyY2gtYmFyLWNvbnRhaW5lciBsYWJlbCB7XHJcbiAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjsgIC8qIFZlcnRpY2FsbHkgY2VudGVyIHRoZSBsYWJlbCBhbmQgaW5wdXQgKi9cclxufVxyXG5cclxuI3NlYXJjaC1iYXItY29udGFpbmVyIGlucHV0W3R5cGU9XCJzZWFyY2hcIl0ge1xyXG4gICAgd2lkdGg6IGF1dG87ICAvKiBBZGp1c3QgdGhlIHdpZHRoIG9mIHRoZSBzZWFyY2ggYmFyIGFzIG5lZWRlZCAqL1xyXG4gICAgbWFyZ2luLWxlZnQ6IDVweDsgIC8qIFNwYWNlIGJldHdlZW4gdGhlIGxhYmVsIGFuZCBpbnB1dCAqL1xyXG4gICAgaGVpZ2h0OiAxMDAlOyAgLyogRW5zdXJlIHRoZSBpbnB1dCBoZWlnaHQgaXMgY29uc2lzdGVudCAqL1xyXG4gICAgbWFyZ2luLXRvcDogMTVweDtcclxufWAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2pzL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0lBQ0ksZUFBZTtJQUNmLHlCQUF5QjtJQUN6QixZQUFZO0lBQ1osV0FBVztBQUNmOztBQUVBO0lBQ0ksZ0JBQWdCO0lBQ2hCLGlDQUFpQztJQUNqQyxZQUFZO0lBQ1osd0JBQXdCLEVBQUUsZUFBZTtJQUN6QyxnQkFBZ0I7SUFDaEIsTUFBTTtBQUNWOztBQUVBO0lBQ0ksa0NBQWtDO0FBQ3RDOztBQUVBO0lBQ0ksaUJBQWlCO0lBQ2pCLHVCQUF1QjtBQUMzQjs7QUFFQTtJQUNJLDhCQUE4QjtBQUNsQzs7QUFFQSw4QkFBOEI7O0FBRTlCO0lBQ0ksY0FBYztBQUNsQjtBQUNBO0lBQ0ksY0FBYztBQUNsQjs7QUFFQSwyQkFBMkI7QUFDM0I7SUFDSSxXQUFXO0FBQ2Y7O0FBRUE7SUFDSSxnQkFBZ0I7QUFDcEI7O0FBRUE7SUFDSSxnQkFBZ0I7SUFDaEIsZ0JBQWdCO0lBQ2hCLDJCQUEyQjtJQUMzQiw0QkFBNEI7SUFDNUIsb0RBQW9EO0lBQ3BELGtCQUFrQjtJQUNsQiwyQkFBMkI7SUFDM0IsdUJBQXVCOztBQUUzQjs7QUFFQSxZQUFZOztBQUVaLHVCQUF1QjtBQUN2QjtJQUNJLG9DQUFvQztJQUNwQyxnQkFBZ0I7SUFDaEIsYUFBYTtBQUNqQjs7QUFFQTtJQUNJLCtCQUErQjtBQUNuQzs7QUFFQTtJQUNJLGFBQWE7SUFDYix1QkFBdUIsRUFBRSx3QkFBd0I7SUFDakQsbUJBQW1CLEVBQUUsc0JBQXNCO0lBQzNDLFdBQVc7QUFDZjs7QUFFQTtJQUNJLG9DQUFvQztJQUNwQyxnQkFBZ0I7QUFDcEI7O0FBRUE7SUFDSSxrQ0FBa0M7QUFDdEM7O0FBRUE7SUFDSSxpQkFBaUI7QUFDckI7O0FBRUE7SUFDSSxhQUFhO0FBQ2pCOztBQUVBO0lBQ0ksOEJBQThCO0FBQ2xDOztBQUVBO0lBQ0ksZUFBZTtJQUNmLHNDQUFzQztBQUMxQzs7QUFFQSxlQUFlO0FBQ2Y7SUFDSSxXQUFXO0FBQ2Y7O0FBRUEsOEJBQThCO0FBQzlCO0lBQ0ksV0FBVztBQUNmOztBQUVBO0lBQ0ksYUFBYTtJQUNiLHlCQUF5QixHQUFHLHNDQUFzQztJQUNsRSxtQkFBbUIsR0FBRyw4QkFBOEI7SUFDcEQsMkJBQTJCO0lBQzNCLDRCQUE0QjtJQUM1QixvQkFBb0I7QUFDeEI7O0FBRUE7SUFDSSxhQUFhO0lBQ2IsbUJBQW1CLEdBQUcsMENBQTBDO0FBQ3BFOztBQUVBO0lBQ0ksV0FBVyxHQUFHLGlEQUFpRDtJQUMvRCxnQkFBZ0IsR0FBRyxzQ0FBc0M7SUFDekQsWUFBWSxHQUFHLDBDQUEwQztJQUN6RCxnQkFBZ0I7QUFDcEJcIixcInNvdXJjZXNDb250ZW50XCI6W1wiI21haW4tdGFibGUge1xcclxcbiAgICBmb250LXNpemU6IDEycHg7XFxyXFxuICAgIC8qIGNhbGMoMC41dncgKyAwLjVlbSk7ICovXFxyXFxuICAgIG1hcmdpbjogYXV0bztcXHJcXG4gICAgd2lkdGg6IDEwMCU7XFxyXFxufVxcclxcblxcclxcbiNtYWluLXRhYmxlIHRoZWFkID4gdHIgPiB0aCB7XFxyXFxuICAgIHRleHQtYWxpZ246IGxlZnQ7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRhcmtHcmF5KTtcXHJcXG4gICAgY29sb3I6IHdoaXRlO1xcclxcbiAgICBwb3NpdGlvbjogLXdlYmtpdC1zdGlja3k7IC8qIEZvciBTYWZhcmkgKi9cXHJcXG4gICAgcG9zaXRpb246IHN0aWNreTtcXHJcXG4gICAgdG9wOiAwO1xcclxcbn1cXHJcXG5cXHJcXG50aCB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWxpZ2h0R3JheSk7XFxyXFxufVxcclxcblxcclxcbnRyIHtcXHJcXG4gICAgYm9yZGVyLXdpZHRoOiAycHg7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xcclxcbn1cXHJcXG5cXHJcXG50ciB0ZCB7XFxyXFxuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCBibGFjaztcXHJcXG59XFxyXFxuXFxyXFxuLyogRGVmYXVsdCB0byBoaWRkZW4gY29sdW1ucyAqL1xcclxcblxcclxcbiNtYWluLXRhYmxlIHRib2R5ID4gdHIgPiB0ZCB7XFxyXFxuICAgIGRpc3BsYXkgOiBub25lO1xcclxcbn1cXHJcXG4jbWFpbi10YWJsZSB0aGVhZCA+IHRyID4gdGgge1xcclxcbiAgICBkaXNwbGF5IDogbm9uZTtcXHJcXG59XFxyXFxuXFxyXFxuLyogdGV4dGJveCB3aWR0aCBpbiB0YWJsZSAqL1xcclxcbmlucHV0IHtcXHJcXG4gICAgd2lkdGg6IDEwMCU7XFxyXFxufVxcclxcblxcclxcbnNlbGVjdCB7XFxyXFxuICAgIG1heC13aWR0aDogMTAwcHg7XFxyXFxufVxcclxcblxcclxcbmRpdi50YWJsZS1jb250YWluZXIge1xcclxcbiAgICBvdmVyZmxvdy14OiBhdXRvOyBcXHJcXG4gICAgb3ZlcmZsb3cteTogYXV0bztcXHJcXG4gICAgbWFyZ2luLWxlZnQ6IG1heCg2NXB4LCA3dmgpO1xcclxcbiAgICBtYXJnaW4tcmlnaHQ6IG1heCg2NXB4LCA3dmgpO1xcclxcbiAgICAvKiBtYXgtd2lkdGg6IGNhbGMoMTAwdncgLSB2YXIoLS1zaWRlYmFyLXdpZHRoKSk7ICAqL1xcclxcbiAgICAvKiBtYXJnaW46IGF1dG87ICovXFxyXFxuICAgIG1heC1oZWlnaHQ6IG1heCgzNTBweCwgNnZoKTtcXHJcXG4gICAgLyogbWluLWhlaWdodDogMzUwcHg7ICovXFxyXFxuXFxyXFxufVxcclxcbiAgXFxyXFxuLyogQnV0dG9ucyAqL1xcclxcblxcclxcbi8qIEFkZCBuZXcgcm93IGJ1dHRvbiAqL1xcclxcbi5idG4tYWRkIHsgXFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcXHJcXG4gICAgbWFyZ2luLXRvcDogMjBweDtcXHJcXG4gICAgZGlzcGxheTogbm9uZTtcXHJcXG59XFxyXFxuXFxyXFxuLmJ0bi1kZWxldGUge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1vcmFuZ2UpO1xcclxcbn1cXHJcXG5cXHJcXG4jYWRkLWJ0bi1kaXYge1xcclxcbiAgICBkaXNwbGF5OiBmbGV4O1xcclxcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgLyogQWxpZ25zIGhvcml6b250YWxseSAqL1xcclxcbiAgICBhbGlnbi1pdGVtczogY2VudGVyOyAvKiBBbGlnbnMgdmVydGljYWxseSAqL1xcclxcbiAgICB3aWR0aDogMTAwJTtcXHJcXG59XFxyXFxuXFxyXFxuLmJ0bi1lZGl0IHtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tc3Bpcml0Z3JlZW4pO1xcclxcbiAgICBsaW5lLWhlaWdodDogMS4xO1xcclxcbn1cXHJcXG5cXHJcXG4uYWN0aXZlLWVkaXRpbmcsIC5zZWxlY3RlZCB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXBhbGVncmVlbik7XFxyXFxufVxcclxcblxcclxcbi5zZWxlY3RlZCB7IFxcclxcbiAgICBmb250LXdlaWdodDogYm9sZDtcXHJcXG59XFxyXFxuXFxyXFxuLmJ0bi1jb25maXJtIHtcXHJcXG4gICAgZGlzcGxheTogbm9uZTtcXHJcXG59XFxyXFxuXFxyXFxuLmNvbmZpcm0tYnRuOmhvdmVyIHtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tZ3JlZW4pO1xcclxcbn1cXHJcXG5cXHJcXG4uaG92ZXItZWZmZWN0OmhvdmVyIHtcXHJcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS12ZXJ5cGFsZWdyZWVuKTsgXFxyXFxufVxcclxcblxcclxcbi8qIEZ1bmQgdGFibGUgKi9cXHJcXG4uZnVuZC1uYW1lID4gLnZpZXdlZC1mdW5kIHtcXHJcXG4gICAgY29sb3I6IGdyYXk7XFxyXFxufVxcclxcblxcclxcbi8qIG1hZGUgZWRpdCBjb2x1bW4gbmFycm93ZXIgKi9cXHJcXG50aC5lZGl0LCB0ZC5lZGl0IHtcXHJcXG4gICAgd2lkdGg6IDIwcHg7XFxyXFxufVxcclxcblxcclxcbiNzZWFyY2gtYmFyLWNvbnRhaW5lciB7XFxyXFxuICAgIGRpc3BsYXk6IGZsZXg7XFxyXFxuICAgIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7ICAvKiBBbGlnbiB0aGUgc2VhcmNoIGJhciB0byB0aGUgcmlnaHQgKi9cXHJcXG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjsgIC8qIFZlcnRpY2FsbHkgY2VudGVyIGNvbnRlbnQgKi9cXHJcXG4gICAgbWFyZ2luLWxlZnQ6IG1heCg2NXB4LCA3dmgpO1xcclxcbiAgICBtYXJnaW4tcmlnaHQ6IG1heCg4MHB4LCA3dmgpO1xcclxcbiAgICBtYXJnaW4tYm90dG9tOiAtMTBweDtcXHJcXG59XFxyXFxuXFxyXFxuI3NlYXJjaC1iYXItY29udGFpbmVyIGxhYmVsIHtcXHJcXG4gICAgZGlzcGxheTogZmxleDtcXHJcXG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjsgIC8qIFZlcnRpY2FsbHkgY2VudGVyIHRoZSBsYWJlbCBhbmQgaW5wdXQgKi9cXHJcXG59XFxyXFxuXFxyXFxuI3NlYXJjaC1iYXItY29udGFpbmVyIGlucHV0W3R5cGU9XFxcInNlYXJjaFxcXCJdIHtcXHJcXG4gICAgd2lkdGg6IGF1dG87ICAvKiBBZGp1c3QgdGhlIHdpZHRoIG9mIHRoZSBzZWFyY2ggYmFyIGFzIG5lZWRlZCAqL1xcclxcbiAgICBtYXJnaW4tbGVmdDogNXB4OyAgLyogU3BhY2UgYmV0d2VlbiB0aGUgbGFiZWwgYW5kIGlucHV0ICovXFxyXFxuICAgIGhlaWdodDogMTAwJTsgIC8qIEVuc3VyZSB0aGUgaW5wdXQgaGVpZ2h0IGlzIGNvbnNpc3RlbnQgKi9cXHJcXG4gICAgbWFyZ2luLXRvcDogMTVweDtcXHJcXG59XCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///279\n')},843:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#tooltip {\r\n position: absolute;\r\n background-color: black;\r\n color: white;\r\n padding: 5px;\r\n border-radius: 3px;\r\n visibility: hidden;\r\n white-space: nowrap;\r\n font-size: 14px;\r\n z-index: 1000;\r\n max-width: 300px;\r\n word-wrap: break-word;\r\n white-space: normal;\r\n}\r\n\r\n.tooltip-cell {\r\n /* color: blue; */\r\n /* text-decoration: underline; */\r\n cursor: pointer;\r\n}\r\n\r\n.tooltip-cell .info-icon {\r\n margin-left: 5px;\r\n color: var(--spiritgreen);\r\n font-size: 15px;\r\n}\r\n\r\n.tooltip-cell:hover {\r\n background-color: #f0f0f0; /* Change background on hover */\r\n}\r\n\r\n.detail {\r\n color: blue;\r\n color: var(--spiritgreen);\r\n text-decoration: underline;\r\n margin-left: 5px;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/tooltip/tooltip.css"],"names":[],"mappings":"AAAA;IACI,kBAAkB;IAClB,uBAAuB;IACvB,YAAY;IACZ,YAAY;IACZ,kBAAkB;IAClB,kBAAkB;IAClB,mBAAmB;IACnB,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,qBAAqB;IACrB,mBAAmB;AACvB;;AAEA;IACI,iBAAiB;IACjB,gCAAgC;IAChC,eAAe;AACnB;;AAEA;IACI,gBAAgB;IAChB,yBAAyB;IACzB,eAAe;AACnB;;AAEA;IACI,yBAAyB,EAAE,+BAA+B;AAC9D;;AAEA;IACI,WAAW;IACX,yBAAyB;IACzB,0BAA0B;IAC1B,gBAAgB;AACpB","sourcesContent":["#tooltip {\\r\\n position: absolute;\\r\\n background-color: black;\\r\\n color: white;\\r\\n padding: 5px;\\r\\n border-radius: 3px;\\r\\n visibility: hidden;\\r\\n white-space: nowrap;\\r\\n font-size: 14px;\\r\\n z-index: 1000;\\r\\n max-width: 300px;\\r\\n word-wrap: break-word;\\r\\n white-space: normal;\\r\\n}\\r\\n\\r\\n.tooltip-cell {\\r\\n /* color: blue; */\\r\\n /* text-decoration: underline; */\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n.tooltip-cell .info-icon {\\r\\n margin-left: 5px;\\r\\n color: var(--spiritgreen);\\r\\n font-size: 15px;\\r\\n}\\r\\n\\r\\n.tooltip-cell:hover {\\r\\n background-color: #f0f0f0; /* Change background on hover */\\r\\n}\\r\\n\\r\\n.detail {\\r\\n color: blue;\\r\\n color: var(--spiritgreen);\\r\\n text-decoration: underline;\\r\\n margin-left: 5px;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQzLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3Rvb2x0aXAvdG9vbHRpcC5jc3M/N2ZkNiJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgI3Rvb2x0aXAge1xyXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogYmxhY2s7XHJcbiAgICBjb2xvcjogd2hpdGU7XHJcbiAgICBwYWRkaW5nOiA1cHg7XHJcbiAgICBib3JkZXItcmFkaXVzOiAzcHg7XHJcbiAgICB2aXNpYmlsaXR5OiBoaWRkZW47XHJcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xyXG4gICAgZm9udC1zaXplOiAxNHB4O1xyXG4gICAgei1pbmRleDogMTAwMDtcclxuICAgIG1heC13aWR0aDogMzAwcHg7XHJcbiAgICB3b3JkLXdyYXA6IGJyZWFrLXdvcmQ7XHJcbiAgICB3aGl0ZS1zcGFjZTogbm9ybWFsO1xyXG59XHJcblxyXG4udG9vbHRpcC1jZWxsIHtcclxuICAgIC8qIGNvbG9yOiBibHVlOyAqL1xyXG4gICAgLyogdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7ICovXHJcbiAgICBjdXJzb3I6IHBvaW50ZXI7XHJcbn1cclxuXHJcbi50b29sdGlwLWNlbGwgLmluZm8taWNvbiB7XHJcbiAgICBtYXJnaW4tbGVmdDogNXB4O1xyXG4gICAgY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIGZvbnQtc2l6ZTogMTVweDtcclxufVxyXG5cclxuLnRvb2x0aXAtY2VsbDpob3ZlciB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjBmMGYwOyAvKiBDaGFuZ2UgYmFja2dyb3VuZCBvbiBob3ZlciAqL1xyXG59XHJcblxyXG4uZGV0YWlsIHtcclxuICAgIGNvbG9yOiBibHVlO1xyXG4gICAgY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xyXG4gICAgbWFyZ2luLWxlZnQ6IDVweDtcclxufWAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2pzL2NvbXBvbmVudHMvdG9vbHRpcC90b29sdGlwLmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLGtCQUFrQjtJQUNsQix1QkFBdUI7SUFDdkIsWUFBWTtJQUNaLFlBQVk7SUFDWixrQkFBa0I7SUFDbEIsa0JBQWtCO0lBQ2xCLG1CQUFtQjtJQUNuQixlQUFlO0lBQ2YsYUFBYTtJQUNiLGdCQUFnQjtJQUNoQixxQkFBcUI7SUFDckIsbUJBQW1CO0FBQ3ZCOztBQUVBO0lBQ0ksaUJBQWlCO0lBQ2pCLGdDQUFnQztJQUNoQyxlQUFlO0FBQ25COztBQUVBO0lBQ0ksZ0JBQWdCO0lBQ2hCLHlCQUF5QjtJQUN6QixlQUFlO0FBQ25COztBQUVBO0lBQ0kseUJBQXlCLEVBQUUsK0JBQStCO0FBQzlEOztBQUVBO0lBQ0ksV0FBVztJQUNYLHlCQUF5QjtJQUN6QiwwQkFBMEI7SUFDMUIsZ0JBQWdCO0FBQ3BCXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIiN0b29sdGlwIHtcXHJcXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiBibGFjaztcXHJcXG4gICAgY29sb3I6IHdoaXRlO1xcclxcbiAgICBwYWRkaW5nOiA1cHg7XFxyXFxuICAgIGJvcmRlci1yYWRpdXM6IDNweDtcXHJcXG4gICAgdmlzaWJpbGl0eTogaGlkZGVuO1xcclxcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xcclxcbiAgICBmb250LXNpemU6IDE0cHg7XFxyXFxuICAgIHotaW5kZXg6IDEwMDA7XFxyXFxuICAgIG1heC13aWR0aDogMzAwcHg7XFxyXFxuICAgIHdvcmQtd3JhcDogYnJlYWstd29yZDtcXHJcXG4gICAgd2hpdGUtc3BhY2U6IG5vcm1hbDtcXHJcXG59XFxyXFxuXFxyXFxuLnRvb2x0aXAtY2VsbCB7XFxyXFxuICAgIC8qIGNvbG9yOiBibHVlOyAqL1xcclxcbiAgICAvKiB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsgKi9cXHJcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcclxcbn1cXHJcXG5cXHJcXG4udG9vbHRpcC1jZWxsIC5pbmZvLWljb24ge1xcclxcbiAgICBtYXJnaW4tbGVmdDogNXB4O1xcclxcbiAgICBjb2xvcjogdmFyKC0tc3Bpcml0Z3JlZW4pO1xcclxcbiAgICBmb250LXNpemU6IDE1cHg7XFxyXFxufVxcclxcblxcclxcbi50b29sdGlwLWNlbGw6aG92ZXIge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjBmMGYwOyAvKiBDaGFuZ2UgYmFja2dyb3VuZCBvbiBob3ZlciAqL1xcclxcbn1cXHJcXG5cXHJcXG4uZGV0YWlsIHtcXHJcXG4gICAgY29sb3I6IGJsdWU7XFxyXFxuICAgIGNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XFxyXFxuICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xcclxcbiAgICBtYXJnaW4tbGVmdDogNXB4O1xcclxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcbi8vIEV4cG9ydHNcbmV4cG9ydCBkZWZhdWx0IF9fX0NTU19MT0FERVJfRVhQT1JUX19fO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///843\n')},235:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/* Welcome page (index.html) */\r\n\r\n.step {\r\n width: 60%;\r\n height: 80px;\r\n font-size: 1.75em;\r\n margin-bottom: 0px; /* Adds spacing between buttons */\r\n margin-left: 20%;\r\n border-color: var(--citygreen);\r\n border-width: 2;\r\n color: var(--citygreen);\r\n background-color: white;\r\n}\r\n\r\n.step:hover {\r\n color: white;\r\n background-color: var(--spiritgreen);\r\n}\r\n\r\n#welcome-page {\r\n justify-content: center; \r\n align-items: center; \r\n padding-top: 20px;\r\n}\r\n.step.disabled {\r\n opacity: 50%;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/welcome/welcome.css"],"names":[],"mappings":"AAAA,8BAA8B;;AAE9B;IACI,UAAU;IACV,YAAY;IACZ,iBAAiB;IACjB,kBAAkB,EAAE,iCAAiC;IACrD,gBAAgB;IAChB,8BAA8B;IAC9B,eAAe;IACf,uBAAuB;IACvB,uBAAuB;AAC3B;;AAEA;IACI,YAAY;IACZ,oCAAoC;AACxC;;AAEA;IACI,uBAAuB;IACvB,mBAAmB;IACnB,iBAAiB;AACrB;AACA;IACI,YAAY;AAChB","sourcesContent":["/* Welcome page (index.html) */\\r\\n\\r\\n.step {\\r\\n width: 60%;\\r\\n height: 80px;\\r\\n font-size: 1.75em;\\r\\n margin-bottom: 0px; /* Adds spacing between buttons */\\r\\n margin-left: 20%;\\r\\n border-color: var(--citygreen);\\r\\n border-width: 2;\\r\\n color: var(--citygreen);\\r\\n background-color: white;\\r\\n}\\r\\n\\r\\n.step:hover {\\r\\n color: white;\\r\\n background-color: var(--spiritgreen);\\r\\n}\\r\\n\\r\\n#welcome-page {\\r\\n justify-content: center; \\r\\n align-items: center; \\r\\n padding-top: 20px;\\r\\n}\\r\\n.step.disabled {\\r\\n opacity: 50%;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM1LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy93ZWxjb21lL3dlbGNvbWUuY3NzP2IzNDgiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYC8qIFdlbGNvbWUgcGFnZSAoaW5kZXguaHRtbCkgKi9cclxuXHJcbi5zdGVwIHtcclxuICAgIHdpZHRoOiA2MCU7XHJcbiAgICBoZWlnaHQ6IDgwcHg7XHJcbiAgICBmb250LXNpemU6IDEuNzVlbTtcclxuICAgIG1hcmdpbi1ib3R0b206IDBweDsgLyogQWRkcyBzcGFjaW5nIGJldHdlZW4gYnV0dG9ucyAqL1xyXG4gICAgbWFyZ2luLWxlZnQ6IDIwJTtcclxuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcclxuICAgIGJvcmRlci13aWR0aDogMjtcclxuICAgIGNvbG9yOiB2YXIoLS1jaXR5Z3JlZW4pO1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XHJcbn1cclxuXHJcbi5zdGVwOmhvdmVyIHtcclxuICAgIGNvbG9yOiB3aGl0ZTtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxufVxyXG5cclxuI3dlbGNvbWUtcGFnZSB7XHJcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgXHJcbiAgICBhbGlnbi1pdGVtczogY2VudGVyOyBcclxuICAgIHBhZGRpbmctdG9wOiAyMHB4O1xyXG59XHJcbi5zdGVwLmRpc2FibGVkIHtcclxuICAgIG9wYWNpdHk6IDUwJTtcclxufWAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2pzL2NvbXBvbmVudHMvd2VsY29tZS93ZWxjb21lLmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQSw4QkFBOEI7O0FBRTlCO0lBQ0ksVUFBVTtJQUNWLFlBQVk7SUFDWixpQkFBaUI7SUFDakIsa0JBQWtCLEVBQUUsaUNBQWlDO0lBQ3JELGdCQUFnQjtJQUNoQiw4QkFBOEI7SUFDOUIsZUFBZTtJQUNmLHVCQUF1QjtJQUN2Qix1QkFBdUI7QUFDM0I7O0FBRUE7SUFDSSxZQUFZO0lBQ1osb0NBQW9DO0FBQ3hDOztBQUVBO0lBQ0ksdUJBQXVCO0lBQ3ZCLG1CQUFtQjtJQUNuQixpQkFBaUI7QUFDckI7QUFDQTtJQUNJLFlBQVk7QUFDaEJcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLyogV2VsY29tZSBwYWdlIChpbmRleC5odG1sKSAqL1xcclxcblxcclxcbi5zdGVwIHtcXHJcXG4gICAgd2lkdGg6IDYwJTtcXHJcXG4gICAgaGVpZ2h0OiA4MHB4O1xcclxcbiAgICBmb250LXNpemU6IDEuNzVlbTtcXHJcXG4gICAgbWFyZ2luLWJvdHRvbTogMHB4OyAvKiBBZGRzIHNwYWNpbmcgYmV0d2VlbiBidXR0b25zICovXFxyXFxuICAgIG1hcmdpbi1sZWZ0OiAyMCU7XFxyXFxuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcXHJcXG4gICAgYm9yZGVyLXdpZHRoOiAyO1xcclxcbiAgICBjb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XFxyXFxufVxcclxcblxcclxcbi5zdGVwOmhvdmVyIHtcXHJcXG4gICAgY29sb3I6IHdoaXRlO1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XFxyXFxufVxcclxcblxcclxcbiN3ZWxjb21lLXBhZ2Uge1xcclxcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgXFxyXFxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7IFxcclxcbiAgICBwYWRkaW5nLXRvcDogMjBweDtcXHJcXG59XFxyXFxuLnN0ZXAuZGlzYWJsZWQge1xcclxcbiAgICBvcGFjaXR5OiA1MCU7XFxyXFxufVwiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuLy8gRXhwb3J0c1xuZXhwb3J0IGRlZmF1bHQgX19fQ1NTX0xPQURFUl9FWFBPUlRfX187XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///235\n')},314:module=>{eval('\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = "";\n var needLayer = typeof item[5] !== "undefined";\n if (item[4]) {\n content += "@supports (".concat(item[4], ") {");\n }\n if (item[2]) {\n content += "@media ".concat(item[2], " {");\n }\n if (needLayer) {\n content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += "}";\n }\n if (item[2]) {\n content += "}";\n }\n if (item[4]) {\n content += "}";\n }\n return content;\n }).join("");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === "string") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== "undefined") {\n if (typeof item[5] === "undefined") {\n item[5] = layer;\n } else {\n item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = "".concat(supports);\n } else {\n item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzE0LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanM/MjRmYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLypcbiAgTUlUIExpY2Vuc2UgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHBcbiAgQXV0aG9yIFRvYmlhcyBLb3BwZXJzIEBzb2tyYVxuKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGNzc1dpdGhNYXBwaW5nVG9TdHJpbmcpIHtcbiAgdmFyIGxpc3QgPSBbXTtcblxuICAvLyByZXR1cm4gdGhlIGxpc3Qgb2YgbW9kdWxlcyBhcyBjc3Mgc3RyaW5nXG4gIGxpc3QudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHZhciBjb250ZW50ID0gXCJcIjtcbiAgICAgIHZhciBuZWVkTGF5ZXIgPSB0eXBlb2YgaXRlbVs1XSAhPT0gXCJ1bmRlZmluZWRcIjtcbiAgICAgIGlmIChpdGVtWzRdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJAc3VwcG9ydHMgKFwiLmNvbmNhdChpdGVtWzRdLCBcIikge1wiKTtcbiAgICAgIH1cbiAgICAgIGlmIChpdGVtWzJdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJAbWVkaWEgXCIuY29uY2F0KGl0ZW1bMl0sIFwiIHtcIik7XG4gICAgICB9XG4gICAgICBpZiAobmVlZExheWVyKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJAbGF5ZXJcIi5jb25jYXQoaXRlbVs1XS5sZW5ndGggPiAwID8gXCIgXCIuY29uY2F0KGl0ZW1bNV0pIDogXCJcIiwgXCIge1wiKTtcbiAgICAgIH1cbiAgICAgIGNvbnRlbnQgKz0gY3NzV2l0aE1hcHBpbmdUb1N0cmluZyhpdGVtKTtcbiAgICAgIGlmIChuZWVkTGF5ZXIpIHtcbiAgICAgICAgY29udGVudCArPSBcIn1cIjtcbiAgICAgIH1cbiAgICAgIGlmIChpdGVtWzJdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJ9XCI7XG4gICAgICB9XG4gICAgICBpZiAoaXRlbVs0XSkge1xuICAgICAgICBjb250ZW50ICs9IFwifVwiO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvbnRlbnQ7XG4gICAgfSkuam9pbihcIlwiKTtcbiAgfTtcblxuICAvLyBpbXBvcnQgYSBsaXN0IG9mIG1vZHVsZXMgaW50byB0aGUgbGlzdFxuICBsaXN0LmkgPSBmdW5jdGlvbiBpKG1vZHVsZXMsIG1lZGlhLCBkZWR1cGUsIHN1cHBvcnRzLCBsYXllcikge1xuICAgIGlmICh0eXBlb2YgbW9kdWxlcyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgbW9kdWxlcyA9IFtbbnVsbCwgbW9kdWxlcywgdW5kZWZpbmVkXV07XG4gICAgfVxuICAgIHZhciBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzID0ge307XG4gICAgaWYgKGRlZHVwZSkge1xuICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCB0aGlzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgIHZhciBpZCA9IHRoaXNba11bMF07XG4gICAgICAgIGlmIChpZCAhPSBudWxsKSB7XG4gICAgICAgICAgYWxyZWFkeUltcG9ydGVkTW9kdWxlc1tpZF0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAodmFyIF9rID0gMDsgX2sgPCBtb2R1bGVzLmxlbmd0aDsgX2srKykge1xuICAgICAgdmFyIGl0ZW0gPSBbXS5jb25jYXQobW9kdWxlc1tfa10pO1xuICAgICAgaWYgKGRlZHVwZSAmJiBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2l0ZW1bMF1dKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBsYXllciAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBpZiAodHlwZW9mIGl0ZW1bNV0gPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBpdGVtWzVdID0gbGF5ZXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbVsxXSA9IFwiQGxheWVyXCIuY29uY2F0KGl0ZW1bNV0ubGVuZ3RoID4gMCA/IFwiIFwiLmNvbmNhdChpdGVtWzVdKSA6IFwiXCIsIFwiIHtcIikuY29uY2F0KGl0ZW1bMV0sIFwifVwiKTtcbiAgICAgICAgICBpdGVtWzVdID0gbGF5ZXI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZWRpYSkge1xuICAgICAgICBpZiAoIWl0ZW1bMl0pIHtcbiAgICAgICAgICBpdGVtWzJdID0gbWVkaWE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbVsxXSA9IFwiQG1lZGlhIFwiLmNvbmNhdChpdGVtWzJdLCBcIiB7XCIpLmNvbmNhdChpdGVtWzFdLCBcIn1cIik7XG4gICAgICAgICAgaXRlbVsyXSA9IG1lZGlhO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc3VwcG9ydHMpIHtcbiAgICAgICAgaWYgKCFpdGVtWzRdKSB7XG4gICAgICAgICAgaXRlbVs0XSA9IFwiXCIuY29uY2F0KHN1cHBvcnRzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpdGVtWzFdID0gXCJAc3VwcG9ydHMgKFwiLmNvbmNhdChpdGVtWzRdLCBcIikge1wiKS5jb25jYXQoaXRlbVsxXSwgXCJ9XCIpO1xuICAgICAgICAgIGl0ZW1bNF0gPSBzdXBwb3J0cztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGlzdC5wdXNoKGl0ZW0pO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIGxpc3Q7XG59OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///314\n')},354:module=>{eval('\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === "function") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);\n var sourceMapping = "/*# ".concat(data, " */");\n return [content].concat([sourceMapping]).join("\\n");\n }\n return [content].join("\\n");\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzU0LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzP2FmMTIiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgdmFyIGNvbnRlbnQgPSBpdGVtWzFdO1xuICB2YXIgY3NzTWFwcGluZyA9IGl0ZW1bM107XG4gIGlmICghY3NzTWFwcGluZykge1xuICAgIHJldHVybiBjb250ZW50O1xuICB9XG4gIGlmICh0eXBlb2YgYnRvYSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgdmFyIGJhc2U2NCA9IGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KGNzc01hcHBpbmcpKSkpO1xuICAgIHZhciBkYXRhID0gXCJzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxcIi5jb25jYXQoYmFzZTY0KTtcbiAgICB2YXIgc291cmNlTWFwcGluZyA9IFwiLyojIFwiLmNvbmNhdChkYXRhLCBcIiAqL1wiKTtcbiAgICByZXR1cm4gW2NvbnRlbnRdLmNvbmNhdChbc291cmNlTWFwcGluZ10pLmpvaW4oXCJcXG5cIik7XG4gIH1cbiAgcmV0dXJuIFtjb250ZW50XS5qb2luKFwiXFxuXCIpO1xufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///354\n')},72:module=>{eval('\n\nvar stylesInDOM = [];\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n return result;\n}\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = "".concat(id, " ").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n identifiers.push(identifier);\n }\n return identifiers;\n}\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n return updater;\n}\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n var newLastIdentifiers = modulesToDom(newList, options);\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n var _index = getIndexByIdentifier(_identifier);\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n stylesInDOM.splice(_index, 1);\n }\n }\n lastIdentifiers = newLastIdentifiers;\n };\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qcz8yZGJhIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG52YXIgc3R5bGVzSW5ET00gPSBbXTtcbmZ1bmN0aW9uIGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpIHtcbiAgdmFyIHJlc3VsdCA9IC0xO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0eWxlc0luRE9NLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHN0eWxlc0luRE9NW2ldLmlkZW50aWZpZXIgPT09IGlkZW50aWZpZXIpIHtcbiAgICAgIHJlc3VsdCA9IGk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIG1vZHVsZXNUb0RvbShsaXN0LCBvcHRpb25zKSB7XG4gIHZhciBpZENvdW50TWFwID0ge307XG4gIHZhciBpZGVudGlmaWVycyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV07XG4gICAgdmFyIGlkID0gb3B0aW9ucy5iYXNlID8gaXRlbVswXSArIG9wdGlvbnMuYmFzZSA6IGl0ZW1bMF07XG4gICAgdmFyIGNvdW50ID0gaWRDb3VudE1hcFtpZF0gfHwgMDtcbiAgICB2YXIgaWRlbnRpZmllciA9IFwiXCIuY29uY2F0KGlkLCBcIiBcIikuY29uY2F0KGNvdW50KTtcbiAgICBpZENvdW50TWFwW2lkXSA9IGNvdW50ICsgMTtcbiAgICB2YXIgaW5kZXhCeUlkZW50aWZpZXIgPSBnZXRJbmRleEJ5SWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAgICB2YXIgb2JqID0ge1xuICAgICAgY3NzOiBpdGVtWzFdLFxuICAgICAgbWVkaWE6IGl0ZW1bMl0sXG4gICAgICBzb3VyY2VNYXA6IGl0ZW1bM10sXG4gICAgICBzdXBwb3J0czogaXRlbVs0XSxcbiAgICAgIGxheWVyOiBpdGVtWzVdXG4gICAgfTtcbiAgICBpZiAoaW5kZXhCeUlkZW50aWZpZXIgIT09IC0xKSB7XG4gICAgICBzdHlsZXNJbkRPTVtpbmRleEJ5SWRlbnRpZmllcl0ucmVmZXJlbmNlcysrO1xuICAgICAgc3R5bGVzSW5ET01baW5kZXhCeUlkZW50aWZpZXJdLnVwZGF0ZXIob2JqKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHVwZGF0ZXIgPSBhZGRFbGVtZW50U3R5bGUob2JqLCBvcHRpb25zKTtcbiAgICAgIG9wdGlvbnMuYnlJbmRleCA9IGk7XG4gICAgICBzdHlsZXNJbkRPTS5zcGxpY2UoaSwgMCwge1xuICAgICAgICBpZGVudGlmaWVyOiBpZGVudGlmaWVyLFxuICAgICAgICB1cGRhdGVyOiB1cGRhdGVyLFxuICAgICAgICByZWZlcmVuY2VzOiAxXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWRlbnRpZmllcnMucHVzaChpZGVudGlmaWVyKTtcbiAgfVxuICByZXR1cm4gaWRlbnRpZmllcnM7XG59XG5mdW5jdGlvbiBhZGRFbGVtZW50U3R5bGUob2JqLCBvcHRpb25zKSB7XG4gIHZhciBhcGkgPSBvcHRpb25zLmRvbUFQSShvcHRpb25zKTtcbiAgYXBpLnVwZGF0ZShvYmopO1xuICB2YXIgdXBkYXRlciA9IGZ1bmN0aW9uIHVwZGF0ZXIobmV3T2JqKSB7XG4gICAgaWYgKG5ld09iaikge1xuICAgICAgaWYgKG5ld09iai5jc3MgPT09IG9iai5jc3MgJiYgbmV3T2JqLm1lZGlhID09PSBvYmoubWVkaWEgJiYgbmV3T2JqLnNvdXJjZU1hcCA9PT0gb2JqLnNvdXJjZU1hcCAmJiBuZXdPYmouc3VwcG9ydHMgPT09IG9iai5zdXBwb3J0cyAmJiBuZXdPYmoubGF5ZXIgPT09IG9iai5sYXllcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBhcGkudXBkYXRlKG9iaiA9IG5ld09iaik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwaS5yZW1vdmUoKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiB1cGRhdGVyO1xufVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobGlzdCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgbGlzdCA9IGxpc3QgfHwgW107XG4gIHZhciBsYXN0SWRlbnRpZmllcnMgPSBtb2R1bGVzVG9Eb20obGlzdCwgb3B0aW9ucyk7XG4gIHJldHVybiBmdW5jdGlvbiB1cGRhdGUobmV3TGlzdCkge1xuICAgIG5ld0xpc3QgPSBuZXdMaXN0IHx8IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGFzdElkZW50aWZpZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaWRlbnRpZmllciA9IGxhc3RJZGVudGlmaWVyc1tpXTtcbiAgICAgIHZhciBpbmRleCA9IGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpO1xuICAgICAgc3R5bGVzSW5ET01baW5kZXhdLnJlZmVyZW5jZXMtLTtcbiAgICB9XG4gICAgdmFyIG5ld0xhc3RJZGVudGlmaWVycyA9IG1vZHVsZXNUb0RvbShuZXdMaXN0LCBvcHRpb25zKTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgbGFzdElkZW50aWZpZXJzLmxlbmd0aDsgX2krKykge1xuICAgICAgdmFyIF9pZGVudGlmaWVyID0gbGFzdElkZW50aWZpZXJzW19pXTtcbiAgICAgIHZhciBfaW5kZXggPSBnZXRJbmRleEJ5SWRlbnRpZmllcihfaWRlbnRpZmllcik7XG4gICAgICBpZiAoc3R5bGVzSW5ET01bX2luZGV4XS5yZWZlcmVuY2VzID09PSAwKSB7XG4gICAgICAgIHN0eWxlc0luRE9NW19pbmRleF0udXBkYXRlcigpO1xuICAgICAgICBzdHlsZXNJbkRPTS5zcGxpY2UoX2luZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGFzdElkZW50aWZpZXJzID0gbmV3TGFzdElkZW50aWZpZXJzO1xuICB9O1xufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///72\n')},659:module=>{eval('\n\nvar memo = {};\n\n/* istanbul ignore next */\nfunction getTarget(target) {\n if (typeof memo[target] === "undefined") {\n var styleTarget = document.querySelector(target);\n\n // Special case to return head of iframe instead of iframe itself\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n memo[target] = styleTarget;\n }\n return memo[target];\n}\n\n/* istanbul ignore next */\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n if (!target) {\n throw new Error("Couldn\'t find a style target. This probably means that the value for the \'insert\' parameter is invalid.");\n }\n target.appendChild(style);\n}\nmodule.exports = insertBySelector;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjU5LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanM/YjIxNCJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxudmFyIG1lbW8gPSB7fTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBnZXRUYXJnZXQodGFyZ2V0KSB7XG4gIGlmICh0eXBlb2YgbWVtb1t0YXJnZXRdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgdmFyIHN0eWxlVGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0YXJnZXQpO1xuXG4gICAgLy8gU3BlY2lhbCBjYXNlIHRvIHJldHVybiBoZWFkIG9mIGlmcmFtZSBpbnN0ZWFkIG9mIGlmcmFtZSBpdHNlbGZcbiAgICBpZiAod2luZG93LkhUTUxJRnJhbWVFbGVtZW50ICYmIHN0eWxlVGFyZ2V0IGluc3RhbmNlb2Ygd2luZG93LkhUTUxJRnJhbWVFbGVtZW50KSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFjY2VzcyB0byBpZnJhbWUgaXMgYmxvY2tlZFxuICAgICAgICAvLyBkdWUgdG8gY3Jvc3Mtb3JpZ2luIHJlc3RyaWN0aW9uc1xuICAgICAgICBzdHlsZVRhcmdldCA9IHN0eWxlVGFyZ2V0LmNvbnRlbnREb2N1bWVudC5oZWFkO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpc3RhbmJ1bCBpZ25vcmUgbmV4dFxuICAgICAgICBzdHlsZVRhcmdldCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIG1lbW9bdGFyZ2V0XSA9IHN0eWxlVGFyZ2V0O1xuICB9XG4gIHJldHVybiBtZW1vW3RhcmdldF07XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gaW5zZXJ0QnlTZWxlY3RvcihpbnNlcnQsIHN0eWxlKSB7XG4gIHZhciB0YXJnZXQgPSBnZXRUYXJnZXQoaW5zZXJ0KTtcbiAgaWYgKCF0YXJnZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZG4ndCBmaW5kIGEgc3R5bGUgdGFyZ2V0LiBUaGlzIHByb2JhYmx5IG1lYW5zIHRoYXQgdGhlIHZhbHVlIGZvciB0aGUgJ2luc2VydCcgcGFyYW1ldGVyIGlzIGludmFsaWQuXCIpO1xuICB9XG4gIHRhcmdldC5hcHBlbmRDaGlsZChzdHlsZSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGluc2VydEJ5U2VsZWN0b3I7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///659\n')},540:module=>{eval('\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement("style");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\nmodule.exports = insertStyleElement;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQwLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qcz9kZTZjIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zKSB7XG4gIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICBvcHRpb25zLnNldEF0dHJpYnV0ZXMoZWxlbWVudCwgb3B0aW9ucy5hdHRyaWJ1dGVzKTtcbiAgb3B0aW9ucy5pbnNlcnQoZWxlbWVudCwgb3B0aW9ucy5vcHRpb25zKTtcbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGluc2VydFN0eWxlRWxlbWVudDsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///540\n')},56:(module,__unused_webpack_exports,__webpack_require__)=>{eval('\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = true ? __webpack_require__.nc : 0;\n if (nonce) {\n styleElement.setAttribute("nonce", nonce);\n }\n}\nmodule.exports = setAttributesWithoutAttributes;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzP2RkY2UiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzKHN0eWxlRWxlbWVudCkge1xuICB2YXIgbm9uY2UgPSB0eXBlb2YgX193ZWJwYWNrX25vbmNlX18gIT09IFwidW5kZWZpbmVkXCIgPyBfX3dlYnBhY2tfbm9uY2VfXyA6IG51bGw7XG4gIGlmIChub25jZSkge1xuICAgIHN0eWxlRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJub25jZVwiLCBub25jZSk7XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0gc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///56\n')},825:module=>{eval('\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = "";\n if (obj.supports) {\n css += "@supports (".concat(obj.supports, ") {");\n }\n if (obj.media) {\n css += "@media ".concat(obj.media, " {");\n }\n var needLayer = typeof obj.layer !== "undefined";\n if (needLayer) {\n css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");\n }\n css += obj.css;\n if (needLayer) {\n css += "}";\n }\n if (obj.media) {\n css += "}";\n }\n if (obj.supports) {\n css += "}";\n }\n var sourceMap = obj.sourceMap;\n if (sourceMap && typeof btoa !== "undefined") {\n css += "\\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");\n }\n\n // For old IE\n /* istanbul ignore if */\n options.styleTagTransform(css, styleElement, options.options);\n}\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n styleElement.parentNode.removeChild(styleElement);\n}\n\n/* istanbul ignore next */\nfunction domAPI(options) {\n if (typeof document === "undefined") {\n return {\n update: function update() {},\n remove: function remove() {}\n };\n }\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\nmodule.exports = domAPI;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODI1LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzP2U0NzkiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gYXBwbHkoc3R5bGVFbGVtZW50LCBvcHRpb25zLCBvYmopIHtcbiAgdmFyIGNzcyA9IFwiXCI7XG4gIGlmIChvYmouc3VwcG9ydHMpIHtcbiAgICBjc3MgKz0gXCJAc3VwcG9ydHMgKFwiLmNvbmNhdChvYmouc3VwcG9ydHMsIFwiKSB7XCIpO1xuICB9XG4gIGlmIChvYmoubWVkaWEpIHtcbiAgICBjc3MgKz0gXCJAbWVkaWEgXCIuY29uY2F0KG9iai5tZWRpYSwgXCIge1wiKTtcbiAgfVxuICB2YXIgbmVlZExheWVyID0gdHlwZW9mIG9iai5sYXllciAhPT0gXCJ1bmRlZmluZWRcIjtcbiAgaWYgKG5lZWRMYXllcikge1xuICAgIGNzcyArPSBcIkBsYXllclwiLmNvbmNhdChvYmoubGF5ZXIubGVuZ3RoID4gMCA/IFwiIFwiLmNvbmNhdChvYmoubGF5ZXIpIDogXCJcIiwgXCIge1wiKTtcbiAgfVxuICBjc3MgKz0gb2JqLmNzcztcbiAgaWYgKG5lZWRMYXllcikge1xuICAgIGNzcyArPSBcIn1cIjtcbiAgfVxuICBpZiAob2JqLm1lZGlhKSB7XG4gICAgY3NzICs9IFwifVwiO1xuICB9XG4gIGlmIChvYmouc3VwcG9ydHMpIHtcbiAgICBjc3MgKz0gXCJ9XCI7XG4gIH1cbiAgdmFyIHNvdXJjZU1hcCA9IG9iai5zb3VyY2VNYXA7XG4gIGlmIChzb3VyY2VNYXAgJiYgdHlwZW9mIGJ0b2EgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBjc3MgKz0gXCJcXG4vKiMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247YmFzZTY0LFwiLmNvbmNhdChidG9hKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChKU09OLnN0cmluZ2lmeShzb3VyY2VNYXApKSkpLCBcIiAqL1wiKTtcbiAgfVxuXG4gIC8vIEZvciBvbGQgSUVcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICAqL1xuICBvcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtKGNzcywgc3R5bGVFbGVtZW50LCBvcHRpb25zLm9wdGlvbnMpO1xufVxuZnVuY3Rpb24gcmVtb3ZlU3R5bGVFbGVtZW50KHN0eWxlRWxlbWVudCkge1xuICAvLyBpc3RhbmJ1bCBpZ25vcmUgaWZcbiAgaWYgKHN0eWxlRWxlbWVudC5wYXJlbnROb2RlID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHN0eWxlRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudCk7XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gZG9tQVBJKG9wdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgIHJldHVybiB7XG4gICAgICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSgpIHt9LFxuICAgICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoKSB7fVxuICAgIH07XG4gIH1cbiAgdmFyIHN0eWxlRWxlbWVudCA9IG9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50KG9wdGlvbnMpO1xuICByZXR1cm4ge1xuICAgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKG9iaikge1xuICAgICAgYXBwbHkoc3R5bGVFbGVtZW50LCBvcHRpb25zLCBvYmopO1xuICAgIH0sXG4gICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoKSB7XG4gICAgICByZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KTtcbiAgICB9XG4gIH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGRvbUFQSTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///825\n')},113:module=>{eval("\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n styleElement.appendChild(document.createTextNode(css));\n }\n}\nmodule.exports = styleTagTransform;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTEzLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanM/MWRkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBzdHlsZVRhZ1RyYW5zZm9ybShjc3MsIHN0eWxlRWxlbWVudCkge1xuICBpZiAoc3R5bGVFbGVtZW50LnN0eWxlU2hlZXQpIHtcbiAgICBzdHlsZUVsZW1lbnQuc3R5bGVTaGVldC5jc3NUZXh0ID0gY3NzO1xuICB9IGVsc2Uge1xuICAgIHdoaWxlIChzdHlsZUVsZW1lbnQuZmlyc3RDaGlsZCkge1xuICAgICAgc3R5bGVFbGVtZW50LnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudC5maXJzdENoaWxkKTtcbiAgICB9XG4gICAgc3R5bGVFbGVtZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcykpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHN0eWxlVGFnVHJhbnNmb3JtOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///113\n")}},__webpack_module_cache__={};function __webpack_require__(n){var c=__webpack_module_cache__[n];if(void 0!==c)return c.exports;var t=__webpack_module_cache__[n]={id:n,exports:{}};return __webpack_modules__[n](t,t.exports,__webpack_require__),t.exports}__webpack_require__.n=n=>{var c=n&&n.__esModule?()=>n.default:()=>n;return __webpack_require__.d(c,{a:c}),c},__webpack_require__.d=(n,c)=>{for(var t in c)__webpack_require__.o(c,t)&&!__webpack_require__.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:c[t]})},__webpack_require__.o=(n,c)=>Object.prototype.hasOwnProperty.call(n,c),__webpack_require__.nc=void 0;var __webpack_exports__=__webpack_require__(221)})(); \ No newline at end of file +(()=>{"use strict";var __webpack_modules__={254:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{eval("\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\nvar injectStylesIntoStyleTag = __webpack_require__(72);\nvar injectStylesIntoStyleTag_default = /*#__PURE__*/__webpack_require__.n(injectStylesIntoStyleTag);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleDomAPI.js\nvar styleDomAPI = __webpack_require__(825);\nvar styleDomAPI_default = /*#__PURE__*/__webpack_require__.n(styleDomAPI);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertBySelector.js\nvar insertBySelector = __webpack_require__(659);\nvar insertBySelector_default = /*#__PURE__*/__webpack_require__.n(insertBySelector);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\nvar setAttributesWithoutAttributes = __webpack_require__(56);\nvar setAttributesWithoutAttributes_default = /*#__PURE__*/__webpack_require__.n(setAttributesWithoutAttributes);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertStyleElement.js\nvar insertStyleElement = __webpack_require__(540);\nvar insertStyleElement_default = /*#__PURE__*/__webpack_require__.n(insertStyleElement);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleTagTransform.js\nvar styleTagTransform = __webpack_require__(113);\nvar styleTagTransform_default = /*#__PURE__*/__webpack_require__.n(styleTagTransform);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/css/common.css\nvar common = __webpack_require__(404);\n;// CONCATENATED MODULE: ./src/css/common.css\n\n \n \n \n \n \n \n \n \n \n\nvar options = {};\n\noptions.styleTagTransform = (styleTagTransform_default());\noptions.setAttributes = (setAttributesWithoutAttributes_default());\noptions.insert = insertBySelector_default().bind(null, \"head\");\noptions.domAPI = (styleDomAPI_default());\noptions.insertStyleElement = (insertStyleElement_default());\n\nvar update = injectStylesIntoStyleTag_default()(common/* default */.A, options);\n\n\n\n\n /* harmony default export */ const css_common = (common/* default */.A && common/* default */.A.locals ? common/* default */.A.locals : undefined);\n\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/welcome/welcome.css\nvar welcome = __webpack_require__(235);\n;// CONCATENATED MODULE: ./src/js/components/welcome/welcome.css\n\n \n \n \n \n \n \n \n \n \n\nvar welcome_options = {};\n\nwelcome_options.styleTagTransform = (styleTagTransform_default());\nwelcome_options.setAttributes = (setAttributesWithoutAttributes_default());\nwelcome_options.insert = insertBySelector_default().bind(null, \"head\");\nwelcome_options.domAPI = (styleDomAPI_default());\nwelcome_options.insertStyleElement = (insertStyleElement_default());\n\nvar welcome_update = injectStylesIntoStyleTag_default()(welcome/* default */.A, welcome_options);\n\n\n\n\n /* harmony default export */ const welcome_welcome = (welcome/* default */.A && welcome/* default */.A.locals ? welcome/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/welcome/welcome.js\n\n\n// Hide and unhide welcome buttons\nfunction unhideWelcomeButtons() {\n document.getElementById(\"welcome-page\").style.display = \"block\";\n}\nfunction hideWelcomeButtons() {\n document.getElementById(\"welcome-page\").style.display = \"none\";\n}\nconst Welcome = {\n show: unhideWelcomeButtons,\n hide: hideWelcomeButtons\n};\n/* harmony default export */ const components_welcome_welcome = (Welcome);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/prompt/prompt.css\nvar prompt_prompt = __webpack_require__(225);\n;// CONCATENATED MODULE: ./src/js/components/prompt/prompt.css\n\n \n \n \n \n \n \n \n \n \n\nvar prompt_options = {};\n\nprompt_options.styleTagTransform = (styleTagTransform_default());\nprompt_options.setAttributes = (setAttributesWithoutAttributes_default());\nprompt_options.insert = insertBySelector_default().bind(null, \"head\");\nprompt_options.domAPI = (styleDomAPI_default());\nprompt_options.insertStyleElement = (insertStyleElement_default());\n\nvar prompt_update = injectStylesIntoStyleTag_default()(prompt_prompt/* default */.A, prompt_options);\n\n\n\n\n /* harmony default export */ const components_prompt_prompt = (prompt_prompt/* default */.A && prompt_prompt/* default */.A.locals ? prompt_prompt/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/prompt/subcomponents/text.js\nfunction showPrompt() {\n document.getElementById(\"prompt-div\").style.display = \"block\";\n}\nfunction hidePrompt() {\n document.getElementById('prompt-div').style.display = 'none';\n}\nfunction updatePrompt(prompt) {\n document.getElementById('prompt').textContent = prompt;\n showPrompt();\n}\nconst Text = {\n show: showPrompt,\n hide: hidePrompt,\n update: function (text) {\n updatePrompt(text);\n }\n};\n/* harmony default export */ const subcomponents_text = (Text);\n;// CONCATENATED MODULE: ./src/js/components/prompt/subcomponents/buttons.js\nfunction showPromptButton(id) {\n // make buttons visible\n document.getElementById(id).style.display = 'inline';\n}\nfunction updatePromptButton(id, text) {\n document.getElementById(id).textContent = text;\n showPromptButton(id);\n}\nfunction hidePromptButton(id) {\n document.getElementById(id).style.display = 'none';\n}\nfunction unclickAll() {\n document.getElementById('option1').classList.remove('clicked');\n document.getElementById('option2').classList.remove('clicked');\n}\nfunction applyClickedStyle(button) {\n unclickAll();\n button.classList.add('clicked');\n}\nfunction addPromptButtonAction(button_id, action_fn) {\n const buttonElement = document.getElementById(button_id);\n buttonElement.addEventListener('click', action_fn);\n buttonElement.addEventListener('click', function () {\n applyClickedStyle(this);\n });\n}\nfunction removePromptButtonAction(button_id, action_fn) {\n document.getElementById(button_id).removeEventListener('click', action_fn);\n}\nfunction disable(button_id) {\n document.querySelector(`#${button_id}`).classList.add('disabled');\n}\nfunction enable(button_id) {\n document.querySelector(`#${button_id}`).classList.remove('disabled');\n}\nconst Left = {\n show: function () {\n showPromptButton('option1');\n },\n hide: function () {\n hidePromptButton('option1');\n },\n updateText: function (text) {\n updatePromptButton('option1', text);\n },\n addAction: function (action_fn) {\n addPromptButtonAction('option1', action_fn);\n },\n removeAction: function (action_fn) {\n removePromptButtonAction('option1', action_fn);\n },\n disable: function () {\n disable('option1');\n },\n enable: function () {\n enable('option1');\n }\n};\nconst Right = {\n show: function () {\n showPromptButton('option2');\n },\n hide: function () {\n hidePromptButton('option2');\n },\n updateText: function (text) {\n updatePromptButton('option2', text);\n },\n addAction: function (action_fn) {\n addPromptButtonAction('option2', action_fn);\n },\n removeAction: function (action_fn) {\n removePromptButtonAction('option2', action_fn);\n },\n disable: function () {\n disable('option2');\n },\n enable: function () {\n enable('option2');\n }\n};\nconst Buttons = {\n Left: Left,\n Right: Right,\n show: function () {\n showPromptButton('option1');\n showPromptButton('option2');\n },\n hide: function () {\n hidePromptButton('option1');\n hidePromptButton('option2');\n },\n reset: unclickAll\n};\n/* harmony default export */ const buttons = (Buttons);\n;// CONCATENATED MODULE: ./src/js/components/prompt/prompt.js\n\n\n\nconst Prompt = {\n Text: subcomponents_text,\n Buttons: buttons,\n hide: function () {\n subcomponents_text.hide();\n buttons.hide();\n },\n show: function () {\n subcomponents_text.show();\n buttons.show();\n }\n};\n/* harmony default export */ const js_components_prompt_prompt = (Prompt);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/sidebar/sidebar.css\nvar sidebar = __webpack_require__(263);\n;// CONCATENATED MODULE: ./src/js/components/sidebar/sidebar.css\n\n \n \n \n \n \n \n \n \n \n\nvar sidebar_options = {};\n\nsidebar_options.styleTagTransform = (styleTagTransform_default());\nsidebar_options.setAttributes = (setAttributesWithoutAttributes_default());\nsidebar_options.insert = insertBySelector_default().bind(null, \"head\");\nsidebar_options.domAPI = (styleDomAPI_default());\nsidebar_options.insertStyleElement = (insertStyleElement_default());\n\nvar sidebar_update = injectStylesIntoStyleTag_default()(sidebar/* default */.A, sidebar_options);\n\n\n\n\n /* harmony default export */ const sidebar_sidebar = (sidebar/* default */.A && sidebar/* default */.A.locals ? sidebar/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/constants/budget_constants.js\n// Set to equal current fiscal year\nvar FISCAL_YEAR = '26';\n\n// object categories (from obj part of account string)\nconst OBJ_CATEGORIES = {\n list: [\n // 'Salaries & Wages',\n // 'Employee Benefits',\n 'Professional & Contractual Services', 'Operating Supplies', 'Operating Services', 'Equipment Acquisition', 'Capital Outlays', 'Fixed Charges', 'Other Expenses']\n};\n\n// from the drop-down menu\nconst EMPLOYEE_TYPES = ['Regular', 'TASS', 'Seasonal', 'Uniform Fire', 'Uniform Police', 'Appointed', 'Elected', 'Long Term Disability'];\nconst OT_OBJECTS = ['601300 - Salar-Overtime-Gen City', '601305 - Salaries-Overtime-Police Unif', '601310 - Salaries-Overtime-Fire Unif', '602300 - Wages-Overtime-Gen City'];\n;// CONCATENATED MODULE: ./src/js/constants/excel_constants.js\n\n\n// sheets to expect on detail sheet\nconst SHEETS = {\n 'FTE, Salary-Wage, & Benefits': 'personnel',\n 'Overtime & Other Personnel': 'overtime',\n 'Non-Personnel': 'nonpersonnel',\n 'Revenue': 'revenue'\n};\n\n// where to find the general fund target\nconst TARGET_CELL_ADDRESS = 'C14';\nconst TOTAL_COLUMNS = {\n 'personnel': 'Total Sal/Wag & Ben Request',\n 'overtime': `FY${FISCAL_YEAR} Total OT/SP/Hol + FICA Request`,\n 'nonpersonnel': `FY${FISCAL_YEAR} Departmental Request Total`,\n 'revenue': `FY${FISCAL_YEAR} Departmental Estimate`\n};\n;// CONCATENATED MODULE: ./src/js/constants/index.js\n\n\n;// CONCATENATED MODULE: ./src/js/utils/common_utils.js\n// Function to format number as currency\nconst formatCurrency = (amount, return_zero = false) => {\n var amount = Math.round(parseFloat(amount));\n if (amount == NaN) {\n return \"$ -\";\n }\n if (amount < 0) {\n return '($' + amount.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',') + ')';\n } else if (amount == 0) {\n if (return_zero) {\n return '$0';\n }\n return \"$ -\";\n }\n return '$' + amount.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n};\n\n// function to convert formatted number to a float\nconst unformatCurrency = formattedAmount => {\n if (!formattedAmount) {\n return 0;\n }\n ;\n // Remove any currency symbols and commas\n let numericalPart = formattedAmount.replace(/[^0-9.-]+/g, \"\");\n if (numericalPart == '-') {\n return 0;\n }\n return parseFloat(numericalPart);\n};\nfunction displayWithCommas(value) {\n if (value == 0) {\n return 0;\n }\n return formatCurrency(value).replace('$', '');\n}\nfunction cleanString(str) {\n return str.toLowerCase().replaceAll(' ', '-');\n}\nfunction removeNewLines(str) {\n // replace all new lines with spaces\n str = str.replaceAll(/[\\r\\n]+/g, \" \");\n // remove any extra spaces or trailing/leading whitespace\n str = str.replaceAll(' ', ' ');\n str = str.replaceAll(' ', ' ');\n str = str.replace(/^\\s+|\\s+$/g, '');\n return str;\n}\nfunction colSum(table, colName) {\n // fill with zero until there is something saved in storage\n if (!table || table == '') {\n return 0;\n }\n const headers = Object.keys(table[0]);\n if (headers.includes(colName)) {\n let sum = 0;\n for (let i = 0; i < table.length; i++) {\n var value = Math.round(parseFloat(table[i][colName]));\n // treat NaN (non-numerics) as zeroes\n if (value) {\n sum += value;\n }\n }\n return sum;\n } else {\n // console.error(`Could not find expected total column in saved data for ${name}. Returning 0. See StoredTable.totalCol() switch.`);\n return 0;\n }\n}\nfunction getUniqueValues(data, key) {\n const values = data.map(obj => obj[key]);\n return Array.from(new Set(values));\n}\n;// CONCATENATED MODULE: ./src/js/models/fund_lookup_table.js\n\n\nconst FundLookupTable = {\n retrieve: function () {\n return JSON.parse(localStorage.getItem('fund-lookup-table')) || {};\n },\n save: function (fundDict) {\n localStorage.setItem('fund-lookup-table', JSON.stringify(fundDict));\n },\n update: function (fundData) {\n // reset\n this.reset();\n // fill in with data stored in fundDate\n const table = this.retrieve();\n for (let fund of Object.keys(fundData)) {\n // add to lookup table if not in there already\n if (!table[fund]) {\n // get fund name\n const fundName = fundData[fund][0]['Fund Name'];\n // add fund to dictionary\n table[fund] = {};\n table[fund]['name'] = fundName;\n table[fund]['viewed'] = false;\n // build lists of unique cost centers and appropriations\n table[fund]['approp'] = getUniqueValues(fundData[fund], 'Appropriation Name');\n table[fund]['cc'] = getUniqueValues(fundData[fund], 'Cost Center Name');\n }\n }\n // save any updates\n this.save(table);\n },\n getAll: function (key) {\n // function to aggregate all approps or CCs for every fund in one array\n const funds = this.retrieve();\n const ret = [];\n for (const fund in funds) {\n if (funds.hasOwnProperty(fund)) {\n for (let i in funds[fund][key]) {\n ret.push(funds[fund][key][i]);\n }\n }\n }\n return ret;\n },\n getCostCenters: function () {\n // get current fund\n const fund = current_fund.number();\n if (this.retrieve()[fund]) {\n return this.retrieve()[fund]['cc'];\n }\n // if no fund (ie. we're on the new initiative page), return all options\n return this.getAll('cc');\n },\n getApprops: function () {\n // get current fund\n const fund = current_fund.number();\n if (this.retrieve()[fund]) {\n return this.retrieve()[fund]['approp'];\n }\n // if no fund (ie. we're on the new initiative page), return all options\n return this.getAll('approp');\n },\n reset: function () {\n this.save({});\n },\n getName: function (number) {\n if (!number || !this.retrieve()) {\n return '';\n }\n ;\n return this.retrieve()[number]['name'];\n },\n listFunds: function () {\n return Object.keys(this.retrieve());\n },\n listFundNames: function () {\n const funds = this.retrieve();\n // initialize array\n var ret = [];\n Object.keys(funds).forEach(fund_number => {\n var fund_name = funds[fund_number]['name'];\n ret.push(fund_name);\n });\n return ret;\n },\n editFund: function (fund) {\n const table = this.retrieve();\n if (table[fund]) {\n table[fund]['viewed'] = true;\n this.save(table);\n } else {\n console.error('No fund selected.');\n }\n },\n listUneditedFunds: function () {\n const table = this.retrieve();\n const ret = [];\n this.listFunds().forEach(key => {\n if (!table[key]['viewed']) {\n ret.push(key);\n }\n });\n return ret;\n },\n fundsLeft: function () {\n return this.listUneditedFunds().length > 0;\n }\n};\n/* harmony default export */ const fund_lookup_table = (FundLookupTable);\n;// CONCATENATED MODULE: ./src/js/models/current_fund.js\n\nconst CurrentFund = {\n update: function (fund) {\n localStorage.setItem('fund', fund);\n },\n number: function () {\n return localStorage.getItem(\"fund\");\n },\n name: function () {\n return fund_lookup_table.getName(this.number());\n },\n reset: function () {\n this.update('');\n }\n};\n/* harmony default export */ const current_fund = (CurrentFund);\n;// CONCATENATED MODULE: ./src/js/models/account_string.js\n\nconst AccountString = {\n getNumber: function (input) {\n // isolate the numerical part of a appropriation/cost center/object\n const match = input.match(/^\\d+/);\n return match ? match[0] : null;\n },\n build: function (approp, cc, obj = null, fund = null) {\n // put together account string fund-approp-costcenter[-obj] (w optional object)\n if (!fund) {\n fund = current_fund.number();\n }\n ;\n // hits error here\n approp = this.getNumber(approp);\n cc = this.getNumber(cc);\n var string = `${fund}-${approp}-${cc}`;\n string = obj ? `${string}-${this.getNumber(obj)}` : string;\n return string;\n },\n getAccountStringSection: function (account_string, section) {\n const sections = account_string.split(\"-\");\n return sections.length > section ? sections[section] : null;\n },\n fund: function (account_string) {\n return this.getAccountStringSection(account_string, 0);\n },\n approp: function (account_string) {\n return this.getAccountStringSection(account_string, 1);\n },\n costCenter: function (account_string) {\n return this.getAccountStringSection(account_string, 2);\n },\n object: function (account_string) {\n return this.getAccountStringSection(account_string, 3);\n }\n};\n/* harmony default export */ const account_string = (AccountString);\n;// CONCATENATED MODULE: ./src/js/models/fund.js\n\n\n\n// Helper function to create a unique list of appropriations represented in a table\nfunction fetchValueSet(table, key) {\n // IF there's no data, return an empty list\n if (!table) {\n return [];\n }\n\n // Use a Set to store unique values\n const uniqValues = new Set();\n\n // Iterate through each object in the table\n table.forEach(row => {\n if (row[key]) {\n uniqValues.add(row[key]);\n }\n });\n\n // Convert the Set to an array if needed\n return uniqValues;\n}\n\n// Class to hold information on a specific fund and table\nclass StoredTable {\n constructor(page, fund) {\n this.name = `${page}_${fund}`;\n this.page = page;\n this.table = JSON.parse(localStorage.getItem(this.name));\n this.approps = fetchValueSet(this.table, 'Appropriation');\n this.cc = fetchValueSet(this.table, 'Cost Center');\n }\n totalCol() {\n return TOTAL_COLUMNS[this.page];\n }\n getSum() {\n // fill with zero until there is something saved in storage\n return colSum(this.table, this.totalCol(), this.name);\n }\n\n // key is the column to filter on (ie. Cost Center)\n filter(key, value) {\n if (this.table) {\n // reassign underlying data in object if there's data to filter\n this.table = this.table.filter(row => {\n return row[key] && row[key] == value;\n });\n }\n return this;\n }\n}\nclass CostCenter {\n constructor(fund, approp, cc) {\n const AppropObj = new Appropriation(fund, approp);\n this.personnel = AppropObj.personnel.filter('Cost Center', cc);\n this.nonpersonnel = AppropObj.nonpersonnel.filter('Cost Center', cc);\n this.overtime = AppropObj.overtime.filter('Cost Center', cc);\n this.revenue = AppropObj.revenue.filter('Cost Center', cc);\n this.cc = cc;\n this.account_string = `${AppropObj.accountString()}-${cc}`;\n }\n getPersonnelCost() {\n return this.personnel.getSum();\n }\n getOvertimeCost() {\n return this.overtime.getSum();\n }\n getNonPersonnelCost() {\n return this.nonpersonnel.getSum();\n }\n getRevenue() {\n return this.revenue.getSum();\n }\n getTotal() {\n // only sum expenditures, not net of revenue\n return this.getNonPersonnelCost() + this.getOvertimeCost() + this.getPersonnelCost();\n }\n getName() {\n // just grab the value in the cost center name column for the first row\n if (!this.nonpersonnel.table[0]) {\n return '';\n }\n ;\n return 'Cost Center ' + this.nonpersonnel.table[0]['Cost Center Name'];\n }\n accountString() {\n return this.account_string;\n }\n}\nclass Appropriation {\n constructor(fund, approp) {\n const fundObj = new Fund(fund);\n this.personnel = fundObj.personnel.filter('Appropriation', approp);\n this.nonpersonnel = fundObj.nonpersonnel.filter('Appropriation', approp);\n this.overtime = fundObj.overtime.filter('Appropriation', approp);\n this.revenue = fundObj.revenue.filter('Appropriation', approp);\n // own data\n this.approp = approp;\n this.fund = fundObj.fund;\n }\n getCostCenters() {\n // build a set of unique appropriations across all line items for the fund\n const cc = new Set([...this.personnel.cc, ...this.overtime.cc, ...this.nonpersonnel.cc, ...this.revenue.cc]);\n\n // initialize a list placeholder for the appropriations objects\n const ccList = [];\n // build out list\n cc.forEach(num => {\n ccList.push(new CostCenter(this.fund, this.approp, num));\n });\n return ccList;\n }\n total() {\n return this.personnel.getSum() + this.overtime.getSum() + this.nonpersonnel.getSum();\n }\n name() {\n // just grab the value in the approp name column for the first row\n if (!this.nonpersonnel.table[0]) {\n return '';\n }\n ;\n return 'Appropriation ' + this.nonpersonnel.table[0]['Appropriation Name'];\n }\n accountString() {\n return `${this.fund}-${this.approp}`;\n }\n}\n\n// Holds all the detailed data for one fund's budget\nclass Fund {\n constructor(fund) {\n this.fund = fund;\n this.personnel = new StoredTable('personnel', fund);\n this.overtime = new StoredTable('overtime', fund);\n this.nonpersonnel = new StoredTable('nonpersonnel', fund);\n this.revenue = new StoredTable('revenue', fund);\n }\n getAppropriations() {\n // build a set of unique appropriations across all line items for the fund\n const approps = new Set([...this.personnel.approps, ...this.overtime.approps, ...this.nonpersonnel.approps, ...this.revenue.approps]);\n\n // initialize a list placeholder for the appropriations objects\n const appropsList = [];\n // build out list\n approps.forEach(approp => {\n appropsList.push(new Appropriation(this.fund, approp));\n });\n return appropsList;\n }\n getPersonnelCost() {\n return this.personnel.getSum();\n }\n getOvertimeCost() {\n return this.overtime.getSum();\n }\n getNonPersonnelCost() {\n return this.nonpersonnel.getSum();\n }\n getRevenue() {\n return this.revenue.getSum();\n }\n getTotal() {\n // only sum expenditures, not net of revenue\n return this.getNonPersonnelCost() + this.getOvertimeCost() + this.getPersonnelCost();\n }\n}\n/* harmony default export */ const models_fund = (Fund);\n;// CONCATENATED MODULE: ./src/js/models/baseline.js\n\n\nclass Baseline {\n // baseline will just contain a list of funds, each with\n // running tallies for their budgets\n constructor() {\n const allFunds = fund_lookup_table.listFunds();\n this.funds = [];\n allFunds.forEach(fund => {\n this.funds.push(new models_fund(fund));\n });\n }\n static target() {\n return localStorage.getItem('target');\n }\n personnel() {\n let total = 0;\n this.funds.forEach(fund => {\n total += fund.getPersonnelCost();\n });\n return total;\n }\n overtime() {\n let total = 0;\n this.funds.forEach(fund => {\n total += fund.getOvertineCost();\n });\n return total;\n }\n nonpersonnel() {\n let total = 0;\n this.funds.forEach(fund => {\n total += fund.getNonPersonnelCost();\n });\n return total;\n }\n revenue() {\n let total = 0;\n this.funds.forEach(fund => {\n total += fund.getRevenue();\n });\n return total;\n }\n total() {\n return this.nonpersonnel() + this.personnel(); // + this.overtime();\n }\n}\n/* harmony default export */ const models_baseline = (Baseline);\n;// CONCATENATED MODULE: ./src/js/models/services.js\n// data structure to save the possible service options for the department\nconst Services = {\n save: function (services) {\n localStorage.setItem('services-list', JSON.stringify(services));\n },\n list: function () {\n return JSON.parse(localStorage.getItem('services-list')) || {};\n }\n};\n/* harmony default export */ const services = (Services);\n;// CONCATENATED MODULE: ./src/js/models/initiative.js\n// data structure to hold information on new initiatives\n\nclass Initiative {\n constructor(row) {\n this.data = row;\n this.name = row['Initiative Name'];\n }\n expenses() {\n if (this.data['Ballpark Total Expenses']) {\n return this.data['Ballpark Total Expenses'];\n } else {\n return 0;\n }\n }\n revenue() {\n if (this.data['Revenue']) {\n return this.data['Revenue'];\n } else {\n return 0;\n }\n }\n net() {\n return this.expenses();\n }\n}\n/* harmony default export */ const initiative = (Initiative);\n;// CONCATENATED MODULE: ./src/js/models/supplemental.js\n\n\n\n// data structure to hold supplemental requests\nclass Supplemental {\n constructor() {\n this.table = JSON.parse(localStorage.getItem(this.name));\n this.initiatives = [];\n if (this.table) {\n this.table.forEach(row => {\n this.initiatives.push(new initiative(row));\n });\n }\n }\n getInits() {\n return this.table.map(item => {\n return item['Initiative Name'];\n });\n }\n expenses() {\n return colSum(this.table, 'Ballpark Total Expenses');\n }\n revenue() {\n return colSum(this.table, 'Revenue');\n }\n total() {\n return this.expenses() - this.revenue();\n }\n}\n/* harmony default export */ const supplemental = (Supplemental);\n;// CONCATENATED MODULE: ./src/js/models/index.js\n// models/index.js\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./src/js/components/sidebar/subcomponents/baseline_section.js\n\n\n\n\nconst BaselineSection = {\n _data: new models_baseline(),\n _genFund: new models_fund(1000),\n get data() {\n this._data = new models_baseline();\n return this._data;\n },\n set data(newData) {\n this._data = newData;\n },\n get genFund() {\n this._genFund = new models_fund(1000);\n return this._genFund;\n },\n set genFund(newFund) {\n this._genFund = newFund;\n },\n target_html() {\n return `\n \n \n
`;\n },\n fund_html(fund) {\n return `\n
${fund_lookup_table.getName(fund.fund)}
\n
\n \n \n \n \n \n
`;\n },\n linkEditBtns() {\n let btns = document.querySelectorAll('.edit-icon');\n btns.forEach(btn => {\n // Get the fund from the div the button is in\n let fund = btn.closest('.fund-div').id.replace('fund_', '');\n let page = btn.closest('.sidebar-stat-line').classList[1];\n btn.addEventListener('click', function () {\n current_fund.update(fund);\n visitPage(page);\n });\n });\n },\n update() {\n const baselineDiv = document.querySelector('#baseline-stats');\n baselineDiv.innerHTML = this.target_html();\n this.data.funds.forEach(fund => {\n var fundDiv = document.createElement('div');\n fundDiv.id = `fund_${fund.fund}`;\n fundDiv.classList.add('fund-div');\n fundDiv.innerHTML = this.fund_html(fund);\n baselineDiv.appendChild(fundDiv);\n });\n if (this.genFund.getTotal() <= models_baseline.target()) {\n document.querySelector('#GF-total .stat').style.color = \"green\";\n // document.querySelector('#fund_1000 .sidebar-stat-line:last-of-type .stat').style.color = \"green\";\n } else {\n document.querySelector('#GF-total .stat').style.color = \"red\";\n // document.querySelector('#fund_1000 .sidebar-stat-line:last-of-type .stat').style.color = \"red\";\n }\n this.linkEditBtns();\n }\n};\n;// CONCATENATED MODULE: ./src/js/components/sidebar/subcomponents/supp_section.js\n\n\n\nconst SuppSection = {\n html() {\n var supp = new supplemental();\n return `\n \n `;\n },\n linkEditBtns() {\n let btns = document.querySelectorAll('.edit-supp');\n btns.forEach(btn => {\n btn.addEventListener('click', function () {\n visitPage('new-inits');\n });\n });\n },\n update() {\n const suppDiv = document.querySelector('#supp-stats');\n suppDiv.innerHTML = this.html();\n this.linkEditBtns();\n }\n};\n/* harmony default export */ const supp_section = (SuppSection);\n;// CONCATENATED MODULE: ./src/js/components/sidebar/sidebar.js\n\n\n\n\n// fetch CSS variables saved in :root\nconst root = document.documentElement;\nconst sideBarWidth = getComputedStyle(root).getPropertyValue('--sidebar-width').trim();\nfunction hideSidebar() {\n document.getElementById('sidebar-panel').style.display = 'none';\n document.getElementById('main-panel').style.width = '100%';\n document.querySelector('header').style.width = '100%';\n}\nfunction showSidebar() {\n const sidebar = document.getElementById('sidebar-panel');\n const mainPanel = document.getElementById('main-panel');\n const header = document.querySelector('header');\n\n // update values\n updateTotals();\n sidebar.style.display = 'block'; // Show the sidebar\n\n // Calculate the remaining width for the main panel and header\n var contentWidth = document.documentElement.clientWidth;\n mainPanel.style.width = `${contentWidth - parseInt(sideBarWidth, 10)}px`;\n header.style.width = `${contentWidth - parseInt(sideBarWidth, 10)}px`;\n\n // add event listener to resize content if window is adjusted\n window.addEventListener('resize', showSidebar);\n}\nfunction updateSidebarTitle(new_title) {\n document.getElementById('sidebar-title').textContent = new_title;\n}\nfunction updateTotals() {\n supp_section.update();\n BaselineSection.update();\n}\nfunction resetAll() {\n localStorage.clear();\n // reset all stats to 0\n updateTotals();\n}\nconst Sidebar = {\n SuppSection: supp_section,\n BaselineSection: BaselineSection,\n hide: hideSidebar,\n show: showSidebar,\n updateTitle: updateSidebarTitle,\n updateTotals: updateTotals,\n reset: resetAll\n};\n/* harmony default export */ const components_sidebar_sidebar = (Sidebar);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/nav_buttons/nav_buttons.css\nvar nav_buttons = __webpack_require__(595);\n;// CONCATENATED MODULE: ./src/js/components/nav_buttons/nav_buttons.css\n\n \n \n \n \n \n \n \n \n \n\nvar nav_buttons_options = {};\n\nnav_buttons_options.styleTagTransform = (styleTagTransform_default());\nnav_buttons_options.setAttributes = (setAttributesWithoutAttributes_default());\nnav_buttons_options.insert = insertBySelector_default().bind(null, \"head\");\nnav_buttons_options.domAPI = (styleDomAPI_default());\nnav_buttons_options.insertStyleElement = (insertStyleElement_default());\n\nvar nav_buttons_update = injectStylesIntoStyleTag_default()(nav_buttons/* default */.A, nav_buttons_options);\n\n\n\n\n /* harmony default export */ const nav_buttons_nav_buttons = (nav_buttons/* default */.A && nav_buttons/* default */.A.locals ? nav_buttons/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/nav_buttons/nav_buttons.js\n// nav_buttons.js\n\n\nfunction initializeNavButtons() {\n // initialize last button\n const last_btn = document.getElementById('btn-last');\n last_btn.addEventListener('click', lastPage);\n // initialize next button\n const next_btn = document.getElementById('btn-next');\n next_btn.addEventListener('click', nextPage);\n}\nfunction nav_buttons_disable(button_id) {\n const button = document.getElementById(button_id);\n button.classList.add('disabled');\n button.disabled = true; // Also disable it at the DOM level\n}\nfunction nav_buttons_enable(button_id) {\n const button = document.getElementById(button_id);\n button.classList.remove('disabled');\n button.disabled = false; // Enable it at the DOM level\n}\nconst Next = {\n disable: function () {\n nav_buttons_disable('btn-next');\n },\n enable: function () {\n nav_buttons_enable('btn-next');\n },\n addAction: function (fn) {\n document.querySelector(`#btn-next`).addEventListener('click', fn);\n },\n removeAction: function (fn) {\n document.querySelector(`#btn-next`).removeEventListener('click', fn);\n }\n};\nconst Last = {\n disable: function () {\n nav_buttons_disable('btn-last');\n },\n enable: function () {\n nav_buttons_enable('btn-last');\n }\n};\nconst NavButtons = {\n hide: function () {\n document.getElementById('nav-btns').style.display = 'none';\n },\n show: function () {\n document.getElementById('nav-btns').style.display = 'block';\n initializeNavButtons();\n },\n Next: Next,\n Last: Last\n};\n/* harmony default export */ const components_nav_buttons_nav_buttons = (NavButtons);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/body/body.css\nvar body = __webpack_require__(9);\n;// CONCATENATED MODULE: ./src/js/components/body/body.css\n\n \n \n \n \n \n \n \n \n \n\nvar body_options = {};\n\nbody_options.styleTagTransform = (styleTagTransform_default());\nbody_options.setAttributes = (setAttributesWithoutAttributes_default());\nbody_options.insert = insertBySelector_default().bind(null, \"head\");\nbody_options.domAPI = (styleDomAPI_default());\nbody_options.insertStyleElement = (insertStyleElement_default());\n\nvar body_update = injectStylesIntoStyleTag_default()(body/* default */.A, body_options);\n\n\n\n\n /* harmony default export */ const body_body = (body/* default */.A && body/* default */.A.locals ? body/* default */.A.locals : undefined);\n\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/accordion/accordion.css\nvar accordion = __webpack_require__(995);\n;// CONCATENATED MODULE: ./src/js/components/accordion/accordion.css\n\n \n \n \n \n \n \n \n \n \n\nvar accordion_options = {};\n\naccordion_options.styleTagTransform = (styleTagTransform_default());\naccordion_options.setAttributes = (setAttributesWithoutAttributes_default());\naccordion_options.insert = insertBySelector_default().bind(null, \"head\");\naccordion_options.domAPI = (styleDomAPI_default());\naccordion_options.insertStyleElement = (insertStyleElement_default());\n\nvar accordion_update = injectStylesIntoStyleTag_default()(accordion/* default */.A, accordion_options);\n\n\n\n\n /* harmony default export */ const accordion_accordion = (accordion/* default */.A && accordion/* default */.A.locals ? accordion/* default */.A.locals : undefined);\n\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/table/table.css\nvar table = __webpack_require__(279);\n;// CONCATENATED MODULE: ./src/js/components/table/table.css\n\n \n \n \n \n \n \n \n \n \n\nvar table_options = {};\n\ntable_options.styleTagTransform = (styleTagTransform_default());\ntable_options.setAttributes = (setAttributesWithoutAttributes_default());\ntable_options.insert = insertBySelector_default().bind(null, \"head\");\ntable_options.domAPI = (styleDomAPI_default());\ntable_options.insertStyleElement = (insertStyleElement_default());\n\nvar table_update = injectStylesIntoStyleTag_default()(table/* default */.A, table_options);\n\n\n\n\n /* harmony default export */ const table_table = (table/* default */.A && table/* default */.A.locals ? table/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/headers.js\nfunction addTableHeaders(cols) {\n // Get the table element by its ID\n const table = document.getElementById('main-table');\n\n // Create a table header row element\n const headerRow = document.createElement('tr');\n cols.forEach(col => {\n // Create a header cell element\n const headerCell = document.createElement('th');\n headerCell.textContent = col['title'];\n headerCell.classList.add(col['className']);\n\n // Append the header cell to the header row\n headerRow.appendChild(headerCell);\n });\n\n // Append the header row to the table header\n let thead = table.querySelector('thead');\n thead.appendChild(headerRow);\n}\nconst Header = {\n add: function (header_array) {\n addTableHeaders(header_array);\n }\n};\n/* harmony default export */ const headers = (Header);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/rows.js\n\n\nasync function addNewRow(data_dictionary, columns = []) {\n // Get the table element by its ID\n const table = document.getElementById('main-table');\n\n // check if header has already been added\n let header_row = table.querySelector('thead tr');\n if (!header_row) {\n headers.add(columns);\n header_row = table.querySelector('thead tr');\n }\n\n // initialize new row of data\n const new_row = document.createElement('tr');\n\n // go through each header and add the right cell value depending on its class\n let thElements = header_row.querySelectorAll('th');\n thElements.forEach(header_cell => {\n // Create new cell and add it to the row\n const newCell = document.createElement('td');\n new_row.appendChild(newCell);\n // if the data has an appropriate class, add the info to the cell. \n // Otherwise, keep empty cell\n Object.keys(data_dictionary).forEach(className => {\n if (header_cell.classList.contains(className)) {\n newCell.textContent = data_dictionary[className];\n newCell.classList.add(className);\n }\n });\n });\n\n // Append the new row to the table body\n let tbody = table.querySelector('tbody');\n tbody.appendChild(new_row);\n}\nfunction saveRowEdits(row) {\n var cells = row.querySelectorAll('td');\n cells.forEach(cell => {\n // save dropdown values\n if (cell.querySelector('select')) {\n var serviceSelector = cell.querySelector('select');\n cell.textContent = serviceSelector.value;\n } else if (cell.querySelector('input')) {\n // save new entered value in textbox\n var textbox = cell.querySelector('input');\n var enteredValue = textbox.value;\n // update display and format with currency if relevant\n if (cell.classList.contains('cost')) {\n // if cost, remove commas first\n enteredValue = enteredValue.replaceAll(',', '');\n cell.textContent = formatCurrency(enteredValue);\n // set value attribute to the new user input\n cell.setAttribute('value', enteredValue);\n } else {\n cell.textContent = enteredValue;\n }\n } else if (cell.querySelector('textarea')) {\n // save new entered value in textbox\n var enteredValue = cell.querySelector('textarea').value;\n cell.textContent = enteredValue;\n }\n });\n}\nconst Rows = {\n add: function (data_dictionary, cols) {\n addNewRow(data_dictionary, cols);\n },\n saveEdits: function (row) {\n saveRowEdits(row);\n }\n};\n/* harmony default export */ const rows = (Rows);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/buttons.js\n\nfunction hideButton(className) {\n return function () {\n var buttons = document.getElementsByClassName(className);\n for (var i = 0; i < buttons.length; i++) {\n buttons[i].style.display = 'none';\n }\n };\n}\nfunction showButton(className) {\n return function () {\n var buttons = document.getElementsByClassName(className);\n for (var i = 0; i < buttons.length; i++) {\n buttons[i].style.display = 'inline';\n }\n };\n}\nfunction updateButtonText(className, text) {\n document.querySelector(`.${className}`).textContent = text;\n}\nfunction handleRowEdit(actionOnClick, updateCallback = null) {\n // attach an event listener to each edit button in every row\n var editButtons = document.getElementsByClassName('btn-edit');\n for (var i = 0; i < editButtons.length; i++) {\n editButtons[i].addEventListener('click', async function (event) {\n // Determine what was clicked on within the table\n var rowToEdit = event.target.closest('tr');\n // mark row as being edited\n rowToEdit.classList.add('active-editing');\n\n // turn relevant entries into textboxes, usually\n actionOnClick();\n\n // hide edit buttons\n Edit.hide();\n if (updateCallback) {\n initializeConfirmButton(updateCallback);\n }\n });\n }\n ;\n}\nfunction initializeConfirmButton(updateCallback) {\n // get element and add listener for click\n var rowToEdit = document.querySelector('.active-editing');\n const confirm_btn = rowToEdit.querySelector(\".btn-confirm\");\n // show the row's confirm button\n confirm_btn.style.display = 'block';\n confirm_btn.addEventListener('click', function () {\n ;\n // save row edits\n rows.saveEdits(rowToEdit);\n // update values in sidebar\n updateCallback();\n // make row no longer green\n rowToEdit.classList.remove('active-editing');\n // show edit buttons and hide confirm buttons\n Edit.show();\n Confirm.hide();\n });\n}\nconst Edit = {\n html: '',\n hide: hideButton('btn-edit'),\n show: showButton('btn-edit'),\n init: function (actionOnClick, updateCallback) {\n handleRowEdit(actionOnClick, updateCallback);\n }\n};\nconst Delete = {\n html: '',\n hide: hideButton('btn-delete'),\n show: showButton('btn-delete')\n};\nconst Confirm = {\n html: '',\n hide: hideButton('btn-confirm'),\n show: showButton('btn-confirm')\n};\nconst AddRow = {\n hide: hideButton('btn-add'),\n show: showButton('btn-add'),\n updateText: function (text) {\n updateButtonText('btn-add', text);\n }\n};\nconst buttons_Buttons = {\n Delete: Delete,\n Edit: Edit,\n Confirm: Confirm,\n AddRow: AddRow,\n edit_confirm_btns: Edit.html + Confirm.html,\n all_btns: Delete.html + Edit.html + Confirm.html\n};\n/* harmony default export */ const subcomponents_buttons = (buttons_Buttons);\n;// CONCATENATED MODULE: ./src/js/components/form/subcomponents/dropdown.js\nfunction createDropdown(dataArray) {\n // Creating a select element\n const selectElement = document.createElement('select');\n\n // add a default blank option to the dataArray\n dataArray = [''].concat(dataArray);\n\n // Looping through the array and creating an option for each element\n dataArray.forEach(item => {\n const optionElement = document.createElement('option');\n optionElement.value = item;\n optionElement.textContent = item;\n selectElement.appendChild(optionElement); // Appending the option to the select\n });\n\n // Return the select element so it can be appended to the document\n return selectElement;\n}\nconst Dropdown = {\n create: function (dataArray) {\n return createDropdown(dataArray);\n }\n};\n/* harmony default export */ const subcomponents_dropdown = (Dropdown);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/cells.js\n\n\n\n\n// return cell value attribute or 0 if it does not exist\nfunction getCellValue(row, className) {\n var cell = row.querySelector(`.${className}`);\n var cellValue = cell ? cell.getAttribute('value') : null;\n return cellValue ? parseFloat(cellValue) : 0;\n}\n\n// return text in cell\nfunction getCellText(row, className) {\n var cell = row.querySelector(`.${className}`);\n if (cell) {\n return cell.textContent;\n } else {\n //console.log(`Error retrieving cell text for class ${className}`);\n return '';\n }\n}\nfunction updateTableCell(row, col_class, new_value) {\n const cell = row.querySelector(`.${col_class}`);\n cell.setAttribute('value', new_value);\n cell.textContent = formatCurrency(new_value);\n}\nfunction createEditableCell(cellClass, isCost, type = 'input') {\n // get cell\n const cell = document.querySelector(`.active-editing td.${cellClass}`);\n // Create an input element to edit the value\n var textbox = document.createElement(type);\n if (type == 'input') {\n textbox.type = 'text';\n }\n ;\n if (isCost) {\n var value = cell.getAttribute('value');\n textbox.value = displayWithCommas(value);\n } else {\n textbox.value = cell.textContent;\n }\n // Clear the current content and append the textbox to the cell\n cell.innerHTML = '';\n cell.appendChild(textbox);\n}\nfunction cells_createDropdown(cellClass, optionArray) {\n // get cell\n const cell = document.querySelector(`.active-editing td.${cellClass}`);\n // add service dropdown\n const dropdown = subcomponents_dropdown.create(optionArray);\n dropdown.value = cell.textContent;\n // Clear the current content and append the textbox to the cell\n cell.innerHTML = '';\n cell.appendChild(dropdown);\n}\nconst Cell = {\n getValue: function (row, className) {\n return getCellValue(row, className);\n },\n getText: function (row, className) {\n return getCellText(row, className);\n },\n updateValue: function (row, col_class, new_value) {\n updateTableCell(row, col_class, new_value);\n },\n createTextbox: function (className, isCost, type) {\n createEditableCell(className, isCost, type);\n },\n createServiceDropdown: () => {\n cells_createDropdown('service', services.list());\n },\n createDropdown: cells_createDropdown\n};\n/* harmony default export */ const cells = (Cell);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/columns.js\n\n\n// position is index at which new column will be inserted\nfunction addCol(position, htmlContent = '', headerTitle = '') {\n // Get the table element by its ID\n let table = document.getElementById('main-table');\n\n // Validate position\n let maxPosition = table.rows[0].cells.length;\n if (position < 0 || position > maxPosition) {\n console.error(`Position ${position} is out of bounds.`);\n return;\n }\n\n // Insert the header if provided\n let thead = table.tHead;\n if (headerTitle && thead) {\n let th = document.createElement('th');\n th.innerHTML = headerTitle; // Use innerHTML to insert HTML content\n thead.rows[0].insertBefore(th, thead.rows[0].cells[position]);\n }\n\n // Insert new cells into each row of the table body\n let tbody = table.tBodies[0];\n if (tbody) {\n for (let i = 0; i < tbody.rows.length; i++) {\n let row = tbody.rows[i];\n let td = document.createElement('td');\n td.innerHTML = htmlContent; // Use innerHTML to insert HTML content\n row.insertBefore(td, row.cells[position]);\n }\n }\n}\nfunction ncols() {\n const table = document.getElementById('main-table');\n // Ensure that the row exists before counting the columns\n return table.rows[0].cells.length;\n}\nfunction addColToEnd(htmlContents = [], headerTitle = '') {\n // count columns and add new column to the end\n const position = ncols('main-table');\n addCol(position, htmlContents, headerTitle);\n}\nfunction assignClassToColumn(headerName, className) {\n // Get the table element by its ID\n let table = document.getElementById('main-table');\n\n // Find the index of the column by its header name\n const thead = table.tHead;\n let headerCellIndex = -1;\n const headerCells = thead.rows[0].cells; // Assuming the first row contains header cells ()\n for (let i = 0; i < headerCells.length; i++) {\n if (headerCells[i].textContent.trim() === headerName) {\n // assign the class to the header cell\n headerCells[i].classList.add(className);\n headerCellIndex = i;\n break;\n }\n }\n\n // error check\n if (headerCellIndex === -1) {\n console.error(`No header found with name \"${headerName}\"`);\n return;\n }\n\n // Assign the class to each cell in the specified column index within the tbody\n let tbody = table.tBodies[0];\n if (tbody) {\n let bodyRows = tbody.rows;\n for (let row of bodyRows) {\n if (row.cells[headerCellIndex]) {\n row.cells[headerCellIndex].classList.add(className);\n }\n }\n }\n}\nfunction addCostClass(headerName) {\n assignClassToColumn(headerName, 'cost');\n\n // Get all the cells with the specified class name\n const cells = document.querySelectorAll(`td.cost`);\n cells.forEach(cell => {\n // Get the current text content of the cell and assign it to 'value' attribute\n if (!cell.getAttribute('value')) {\n const cellText = cell.textContent.trim();\n const cellValue = isNaN(cellText) || cellText === '' ? 0 : parseFloat(cellText);\n cell.setAttribute('value', cellValue);\n\n // Now format the text content like currency and replace it in the cell\n const formattedCurrency = formatCurrency(parseFloat(cellValue));\n cell.textContent = formattedCurrency;\n }\n });\n}\nfunction assignColumnClasses(columnDefinitions) {\n columnDefinitions.forEach(column => {\n // Assign class to column\n assignClassToColumn(column.title, column.className);\n\n // If the column is a cost column, add the specific cost class\n if (column.isCost) {\n addCostClass(column.title);\n }\n\n // show the column\n if (!column.hide) {\n showColumnByTitle(column.title);\n }\n });\n}\nfunction hideColumn(index) {\n var table = document.getElementById('main-table');\n var rows = table.rows;\n for (var i = 0; i < rows.length; i++) {\n var cells = rows[i].cells;\n if (cells.length > index) {\n cells[index].style.display = 'none';\n }\n }\n}\n\n// Function to show a specific column\nfunction showColumn(index) {\n var table = document.getElementById('main-table');\n var rows = table.rows;\n for (var i = 0; i < rows.length; i++) {\n var cells = rows[i].cells;\n if (cells.length > index) {\n cells[index].style.display = 'table-cell';\n }\n }\n}\n\n// Function to get the column index by title\nfunction getColumnIndexByTitle(table, title) {\n var headers = table.querySelectorAll('th');\n for (var i = 0; i < headers.length; i++) {\n if (headers[i].innerText === title) {\n return i;\n }\n }\n return -1; // Column not found\n}\n\n// Function to hide a column by title\nfunction hideColumnByTitle(title) {\n var table = document.getElementById('main-table');\n var index = getColumnIndexByTitle(table, title);\n if (index !== -1) {\n hideColumn(index);\n } else {\n console.log(`Column with title \"${title}\" not found.`);\n }\n}\n\n// Function to show a column by title\nfunction showColumnByTitle(title) {\n var table = document.getElementById('main-table');\n var index = getColumnIndexByTitle(table, title);\n if (index !== -1) {\n showColumn(index);\n } else {\n console.log(`Column with title \"${title}\" not found.`);\n }\n}\nconst Column = {\n add: function (position, htmlContent, headerTitle) {\n return addCol(position, htmlContent, headerTitle);\n },\n addAtEnd: function (htmlContent, headerTitle) {\n return addColToEnd(htmlContent, headerTitle);\n },\n assignClasses: function (column_definitions) {\n return assignColumnClasses(column_definitions);\n },\n hide: function (colName) {\n hideColumnByTitle(colName);\n },\n show: function (colName) {\n showColumnByTitle(colName);\n }\n};\n/* harmony default export */ const columns = (Column);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/data.js\n\n\n\n\nfunction fillTable(data) {\n try {\n const table = document.getElementById('main-table');\n const thead = table.querySelector('thead');\n const tbody = table.querySelector('tbody');\n\n // clear existing data\n thead.innerHTML = '';\n tbody.innerHTML = '';\n\n // Create table header row\n const headerRow = document.createElement('tr');\n Object.keys(data[0]).forEach(key => {\n const header = document.createElement('th');\n header.textContent = key;\n headerRow.appendChild(header);\n });\n thead.appendChild(headerRow);\n\n // Create table body rows\n data.forEach(item => {\n const row = document.createElement('tr');\n Object.values(item).forEach(val => {\n const cell = document.createElement('td');\n cell.innerHTML = val;\n row.appendChild(cell);\n });\n tbody.appendChild(row);\n });\n } catch (error) {\n console.error('No table saved in localStorage:', error);\n }\n}\nasync function loadFromStorage() {\n // look up table name in storage\n if (current_fund.number()) {\n var key = `${current_page.load()}_${current_fund.number()}`;\n } else {\n var key = current_page.load();\n }\n // load from local storage\n const data = localStorage.getItem(key);\n // if nothing in storage, return a zero\n if (!data) {\n return 0;\n } else {\n // otherwise, fill table in HTML and return success (1)\n components_table_table.show();\n fillTable(await JSON.parse(data));\n return 1;\n }\n}\nfunction loadFunds() {\n // get list of funds from storage\n const fundDict = fund_lookup_table.retrieve();\n // build out data in correct format\n const ret = [];\n Object.keys(fundDict).forEach(key => {\n // determine if the fund has already been edited\n if (fundDict[key]['viewed']) {\n // todo: add a checkmark here\n ret.push({\n 'Fund': ` \n \n ${fundDict[key]['name']}\n `\n });\n } else {\n ret.push({\n 'Fund': ` \n ${fundDict[key]['name']}\n `\n });\n }\n });\n fillTable(ret);\n}\nfunction getColumnIndexByClass(tbody, className) {\n const firstRow = tbody.rows[0];\n if (!firstRow) return -1; // Return -1 if there's no row to examine\n for (let cellIndex = 0; cellIndex < firstRow.cells.length; cellIndex++) {\n if (firstRow.cells[cellIndex].classList.contains(className)) {\n return cellIndex;\n }\n }\n return -1; // Return -1 if class name not found\n}\n\n// function sort(primaryClass, secondaryClass) {\n// const table = document.getElementById('main-table');\n// const tbody = table.tBodies[0];\n// const rows = Array.from(tbody.rows);\n\n// // Get the column indices by class name\n// const primaryColIndex = getColumnIndexByClass(tbody, primaryClass);\n// const secondaryColIndex = getColumnIndexByClass(tbody, secondaryClass);\n\n// // exit if classes don't exist\n// if (primaryColIndex === -1 ) {\n// console.error(`Column class ${classA} not found in table`);\n// return; \n// } else if (secondaryColIndex === -1) {\n// console.error(`Column class ${classB} not found in table`);\n// return; \n// }\n\n// // Sort the rows based on the text content of the cells\n// rows.sort((rowA, rowB) => {\n// // Primary column comparison\n// const primaryA = unformatCurrency(rowA.cells[primaryColIndex].textContent);\n// const primaryB = unformatCurrency(rowB.cells[primaryColIndex].textContent);\n\n// if (primaryA < primaryB) return -1;\n// if (primaryA > primaryB) return 1;\n\n// // Secondary column comparison (if primary is equal)\n// const secondaryA = unformatCurrency(rowA.cells[secondaryColIndex].textContent);\n// const secondaryB = unformatCurrency(rowB.cells[secondaryColIndex].textContent);\n\n// if (secondaryA < secondaryB) return -1;\n// if (secondaryA > secondaryB) return 1;\n\n// // If both columns are equal\n// return 0;\n// });\n\n// // Reattach sorted rows to the table body\n// rows.forEach((row) => tbody.appendChild(row));\n// }\n\nconst Data = {\n load: loadFromStorage,\n loadFunds: loadFunds,\n sort: function (colA, colB) {\n sort(colA, colB);\n }\n};\n/* harmony default export */ const data = (Data);\n;// CONCATENATED MODULE: ./src/js/components/table/subcomponents/filters.js\n// Helper functions & constants\n\n// object to hold all current filter statuses\nconst filterSettings = {\n 'approp-name': '',\n 'cc-name': '',\n 'object-name': '',\n 'object-category': ''\n};\n\n// helper function to filter data based on all filters\nfunction filterData() {\n // Get all rows in the table\n const rows = document.querySelectorAll('#main-table tbody tr');\n\n // Iterate through each row and determine if it should be hidden or shown\n rows.forEach(row => {\n let isVisible = true;\n\n // Check each filter setting against the row's cells\n for (const [filterId, filterValue] of Object.entries(filterSettings)) {\n const cell = row.querySelector(`.${filterId}`);\n\n // only show row if values pass through all filters \n if (filterValue && cell && cell.textContent.trim() !== filterValue) {\n isVisible = false;\n break;\n }\n }\n\n // Show or hide the row based on visibility\n row.classList.toggle('hidden', !isVisible);\n });\n}\nconst Filter = {\n html(filterLabel, filterClass) {\n // basic html with only 'All' option\n return `\n `;\n },\n addOption(filterClass, option) {\n // Add another option to the dropdown for the filter\n const filterObj = document.querySelector(`#filter-${filterClass}`);\n const optionObj = document.createElement('option');\n optionObj.value = option;\n optionObj.textContent = option;\n filterObj.appendChild(optionObj);\n },\n add(filterLabel, filterClass) {\n // create a div to contain the html and insert inside filter-container\n const filterContainer = document.querySelector('#filter-container');\n const filterDiv = document.createElement('div');\n filterDiv.innerHTML = this.html(filterLabel, filterClass);\n filterContainer.appendChild(filterDiv);\n // add all relevant options from that column in the table\n this.addAllOptions(filterClass);\n // Bind change event to the select element\n filterDiv.querySelector('.filter-dropdown').addEventListener('change', event => {\n // Update filter settings\n filterSettings[filterClass] = event.target.value;\n // Apply all filters\n filterData();\n });\n },\n addAllOptions(filterClass) {\n // get matching column from table\n const column = document.querySelectorAll(`#main-table td.${filterClass}`);\n\n // Use a Set to store unique values in the column of interest\n const uniqueValues = new Set();\n\n // Iterate over the NodeList to get the unique values\n column.forEach(td => {\n // Add each textContent to the Set\n uniqueValues.add(td.textContent.trim());\n });\n // add all values as options to the filter dropdown\n uniqueValues.forEach(option => {\n this.addOption(filterClass, option);\n });\n },\n deleteAll() {\n document.querySelector('#filter-container').innerHTML = '';\n }\n};\n/* harmony default export */ const filters = (Filter);\n;// CONCATENATED MODULE: ./src/js/utils/XLSX_handlers.js\n\n\n\n\n\nfunction deleteTopRowsUntilFullData(data) {\n // function to try to find the top of the usable data\n let fullDataRowFound = false;\n while (!fullDataRowFound && data.length > 0) {\n const row = data[0]; // Get the top row\n let hasAllData = true;\n for (const cell of row) {\n if (cell == null || cell === '') {\n hasAllData = false;\n break;\n }\n }\n if (hasAllData && row.length > 1) {\n fullDataRowFound = true;\n } else {\n // delete the top row if it's not the header row\n data.shift();\n }\n }\n return data;\n}\nfunction processWorkbook(arrayBuffer) {\n const workbook = XLSX.read(arrayBuffer, {\n type: 'array'\n });\n workbook.SheetNames.forEach(sheetName => {\n // only convert sheets we need\n if (Object.keys(SHEETS).includes(sheetName)) {\n // read in sheets\n const sheet = workbook.Sheets[sheetName];\n const rawData = XLSX.utils.sheet_to_json(sheet, {\n header: 1,\n defval: ''\n });\n\n // Clean the data by removing top rows with incomplete data\n const dataRows = deleteTopRowsUntilFullData(rawData);\n\n // get new headers\n const headers = dataRows[0];\n\n // isolate Fund column to split data\n const fundIndex = headers.indexOf('Fund');\n if (fundIndex === -1) {\n console.error(`No 'Fund' column found in sheet ${sheetName}`);\n return;\n }\n\n // Save a dictionary of data for each fund for each sheet\n const fundData = {};\n dataRows.forEach(row => {\n const fund = row[fundIndex];\n if (fund && fund != \"Fund\") {\n if (!fundData[fund]) {\n fundData[fund] = [];\n }\n const rowData = {};\n headers.forEach((header, index) => {\n rowData[removeNewLines(header)] = row[index];\n });\n fundData[fund].push(rowData);\n }\n });\n\n // save fund number and name as we go along\n fund_lookup_table.update(fundData);\n console.log('updating fund lookup table');\n Object.keys(fundData).forEach(fund => {\n const key = `${SHEETS[sheetName]}_${fund}`;\n localStorage.setItem(key, JSON.stringify(fundData[fund]));\n });\n }\n\n // But also save the possible services\n else if (sheetName == 'Drop-Down Menus') {\n const sheet = workbook.Sheets[sheetName];\n // Convert the sheet to JSON to easily manipulate data\n const sheetData = XLSX.utils.sheet_to_json(sheet, {\n header: 1\n });\n\n // Locate the \"services\" column header in row 0\n const headerRow = sheetData[0];\n const servicesIndex = headerRow.indexOf('Services');\n if (servicesIndex === -1) {\n console.error('Header \"Services\" not found');\n } else {\n // Extract data from the \"services\" column (excluding the header row)\n const servicesColumn = sheetData.slice(1).map(row => row[servicesIndex]);\n const cleanedServicesColumn = servicesColumn.filter(value => value != null);\n // save the data\n services.save(cleanedServicesColumn);\n }\n } else if (sheetName == 'Dept Summary') {\n const sheet = workbook.Sheets[sheetName];\n // get and save TARGET for general fund\n if (sheet[TARGET_CELL_ADDRESS]) {\n const cellValue = sheet[TARGET_CELL_ADDRESS].v; // Access the cell value\n localStorage.setItem('target', cellValue);\n } else {\n console.error(`Cell ${TARGET_CELL_ADDRESS} not found in sheet ${sheetName}`);\n }\n }\n });\n console.log('all excel data saved');\n}\n\n// Utility function to append a sheet to the workbook if data is present\nfunction appendSheetToWorkbook(workbook, data, sheetName) {\n if (data.length > 0) {\n const sheet = XLSX.utils.json_to_sheet(data);\n XLSX.utils.book_append_sheet(workbook, sheet, sheetName);\n }\n}\nfunction downloadXLSX() {\n const baseline = new models_baseline();\n const workbook = XLSX.utils.book_new(); // Create a new workbook\n\n const dataMap = {\n Personnel: 'personnel',\n Overtime: 'overtime',\n NonPersonnel: 'nonpersonnel',\n Revenue: 'revenue'\n };\n const sheetData = {\n Personnel: [],\n Overtime: [],\n NonPersonnel: [],\n Revenue: []\n };\n baseline.funds.forEach(fund => {\n Object.keys(dataMap).forEach(sheetName => {\n if (fund[dataMap[sheetName]] && fund[dataMap[sheetName]].table) {\n sheetData[sheetName].push(...fund[dataMap[sheetName]].table);\n }\n });\n });\n Object.keys(sheetData).forEach(sheetName => {\n appendSheetToWorkbook(workbook, sheetData[sheetName], sheetName);\n });\n\n // Generate a downloadable file\n const wbout = XLSX.write(workbook, {\n bookType: 'xlsx',\n type: 'array'\n });\n const blob = new Blob([wbout], {\n type: 'application/octet-stream'\n });\n\n // Create a link and trigger the download\n const link = document.createElement(\"a\");\n link.href = URL.createObjectURL(blob);\n link.download = \"Filled_Detail_Sheet.xlsx\";\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n}\nfunction excelSerialDateToJSDate(serial) {\n if (!serial) {\n return null;\n }\n ;\n // Excel considers 1900-01-01 as day 1, but JavaScript's Date considers\n // 1970-01-01 as day 0. Therefore, we calculate the number of milliseconds\n // between 1900-01-01 and 1970-01-01.\n const excelEpoch = new Date(Date.UTC(1899, 11, 30)); // JavaScript Consider December month as '11'\n\n // Calculate the JS date by adding serial days to the epoch date\n const date = new Date(excelEpoch.getTime() + serial * 24 * 60 * 60 * 1000);\n\n // Set the time part to zero (midnight)\n date.setUTCHours(0, 0, 0, 0);\n\n // Return the date part of the ISO string\n return date.toISOString().split('T')[0];\n}\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/tooltip/tooltip.css\nvar tooltip = __webpack_require__(843);\n;// CONCATENATED MODULE: ./src/js/components/tooltip/tooltip.css\n\n \n \n \n \n \n \n \n \n \n\nvar tooltip_options = {};\n\ntooltip_options.styleTagTransform = (styleTagTransform_default());\ntooltip_options.setAttributes = (setAttributesWithoutAttributes_default());\ntooltip_options.insert = insertBySelector_default().bind(null, \"head\");\ntooltip_options.domAPI = (styleDomAPI_default());\ntooltip_options.insertStyleElement = (insertStyleElement_default());\n\nvar tooltip_update = injectStylesIntoStyleTag_default()(tooltip/* default */.A, tooltip_options);\n\n\n\n\n /* harmony default export */ const tooltip_tooltip = (tooltip/* default */.A && tooltip/* default */.A.locals ? tooltip/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/tooltip/tooltip.js\n\n\n\n\n\n\nfunction hideTooltip() {\n document.getElementById('tooltip').style.visibility = 'hidden';\n}\nfunction showTooltip() {\n document.getElementById('tooltip').style.visibility = 'visible';\n}\nfunction editTooltipText(newText) {\n // edit text to display inside tooltip\n const tooltip = document.getElementById('tooltip');\n tooltip.innerHTML = newText;\n}\nfunction showAccountString(row) {\n const approp = cells.getText(row, 'approp-name');\n const cc = cells.getText(row, 'cc-name');\n const obj = cells.getText(row, 'object-name');\n const fund = cells.getText(row, 'fund-name');\n var message = `Fund: ${fund}
\n Appropriation: ${approp}
\n Cost Center: ${cc}`;\n if (obj) {\n message += `
Object: ${obj}`;\n }\n message += `
If you believe this account string is incorrect, please leave a comment \n in the comment column.`;\n editTooltipText(message);\n}\nfunction showSalaryProjection(row) {\n const general_increase = cells.getText(row, 'general-increase-rate');\n const merit_increase = cells.getText(row, 'merit-increase-rate');\n const current_salary = cells.getValue(row, 'current-salary');\n const proj_salary = cells.getValue(row, 'avg-salary');\n if (current_salary) {\n var message = `The average salary/wage for this position was \n ${formatCurrency(current_salary)} as of September 20${FISCAL_YEAR - 2}. \n Given a ${general_increase * 100}% general increase rate and a ${merit_increase * 100}% \n merit increase, the FY${FISCAL_YEAR} projection for this position's average \n annual salary/wage is ${formatCurrency(proj_salary)}. This projection takes into \n account the number of vacant vs. full positions.`;\n } else {\n var message = `The average salary/wage for this position was \n unknown as of September 20${FISCAL_YEAR - 2}, or the position\n did not exist. The FY${FISCAL_YEAR} projection for this position's \n average annual salary/wage is ${formatCurrency(proj_salary)}.`;\n }\n editTooltipText(message);\n}\nfunction showFinalPersonnelCost(row) {\n const proj_salary = cells.getValue(row, 'avg-salary');\n const ftes = cells.getText(row, 'baseline-ftes');\n const fringe = parseFloat(cells.getText(row, 'fringe'));\n const avg_benefits = proj_salary * fringe;\n const message = `The total cost captures ${ftes} position(s) at\n an annual salary/wage of ${formatCurrency(proj_salary)}, \n plus fringe benefits that cost ${formatCurrency(avg_benefits)} \n per position per year, on average.`;\n editTooltipText(message);\n}\nfunction showFICA(row) {\n const fica = parseFloat(cells.getText(row, 'fica'));\n const ficaPercentage = (fica * 100).toFixed(2);\n const message = `This total is overtime / holiday / shift premium pay, plus FICA (payroll tax), \n which is ${ficaPercentage}% for this cost center.`;\n editTooltipText(message);\n}\nfunction showCPA(row) {\n const cpa = parseFloat(cells.getText(row, 'cpa'));\n const description = cells.getText(row, 'cpa-description');\n const vendor = cells.getText(row, 'vendor');\n var contract_end = cells.getText(row, 'contract-end');\n // convert to normal date format from excel \n contract_end = excelSerialDateToJSDate(contract_end);\n const remaining = cells.getValue(row, 'remaining');\n if (cpa) {\n var message = `CPA #${cpa}`;\n } else {\n var message = `No CPA`;\n }\n if (vendor) {\n message += `
Vendor: ${vendor}`;\n }\n ;\n if (description) {\n message += `
Description: ${description}`;\n }\n ;\n if (contract_end) {\n message += `
Contract End Date: ${contract_end}`;\n }\n if (remaining) {\n message += `
Amount Remaining on Contract: ${formatCurrency(remaining)}`;\n }\n editTooltipText(message);\n}\nfunction tooltip_link(element, displayFn) {\n // add class to show cell with an underline, etc\n element.classList.add('tooltip-cell');\n\n // Create and append (detail)\n const detail = document.createElement('span');\n detail.classList.add('detail');\n detail.textContent = '(detail)';\n element.appendChild(detail);\n\n // add event listener to show tooltip on mouseover\n element.addEventListener('click', function (event) {\n const row = event.target.closest('tr');\n displayFn(row);\n showTooltip();\n });\n // and hide when mouse moves off\n element.addEventListener('mouseout', function () {\n hideTooltip();\n });\n // Update tooltip position on mouse move\n element.addEventListener('mousemove', function (event) {\n const tooltip = document.getElementById('tooltip');\n tooltip.style.top = event.clientY + 10 + 'px';\n tooltip.style.left = event.clientX + 10 + 'px';\n });\n}\nfunction linkAccountStringCol() {\n // get all relevant cells\n document.querySelectorAll('td.account-string').forEach(cell => {\n tooltip_link(cell, showAccountString);\n });\n}\nfunction linkSalaryCol() {\n // get all relevant cells\n document.querySelectorAll('td.avg-salary').forEach(cell => {\n tooltip_link(cell, showSalaryProjection);\n });\n}\nfunction linkTotalPersonnelCostCol() {\n // get all relevant cells\n document.querySelectorAll('td.total-baseline').forEach(cell => {\n tooltip_link(cell, showFinalPersonnelCost);\n });\n}\nfunction linkTotalOTCol() {\n // get all relevant cells\n document.querySelectorAll('td.total').forEach(cell => {\n tooltip_link(cell, showFICA);\n });\n}\nfunction linkCPACol() {\n // get all relevant cells\n document.querySelectorAll('td.cpa').forEach(cell => {\n tooltip_link(cell, showCPA);\n });\n}\nconst Tooltip = {\n hide: hideTooltip,\n show: showTooltip,\n linkAll: () => {\n linkAccountStringCol();\n switch (current_page.load()) {\n case 'personnel':\n // linkAccountStringCol();\n linkSalaryCol();\n linkTotalPersonnelCostCol();\n break;\n case 'overtime':\n linkTotalOTCol();\n // linkAccountStringCol();\n break;\n case 'nonpersonnel':\n // linkAccountStringCol();\n linkCPACol();\n break;\n // case 'revenue':\n // linkAccountStringCol();\n // break;\n // case 'new-inits':\n // linkAccountStringCol();\n // break;\n default:\n break;\n }\n },\n unlink: function () {\n let details = document.querySelectorAll('.detail');\n details.forEach(span => {\n span.remove();\n });\n }\n};\n/* harmony default export */ const components_tooltip_tooltip = (Tooltip);\n;// CONCATENATED MODULE: ./src/js/utils/JSON_data_handlers.js\nasync function fetchJSON(jsonFilePath) {\n return fetch(jsonFilePath).then(response => {\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n return response.json();\n });\n}\nfunction convertToJSON(table, colsToRemove = []) {\n const rows = table.rows;\n // Extract headers from the first row\n const headerRow = rows[0].cells;\n const headers = [];\n for (let j = 0; j < headerRow.length; j++) {\n headers.push(headerRow[j].innerText);\n }\n\n // initialize data\n var tableData = [];\n for (var i = 1; i < rows.length; i++) {\n const cols = rows[i].cells;\n const rowData = {};\n headers.forEach((header, index) => {\n if (colsToRemove.includes(header)) {\n return;\n } else if (cols[index].classList.contains('cost')) {\n rowData[header] = cols[index].getAttribute('value');\n } else {\n rowData[header] = cols[index].innerText;\n }\n });\n tableData.push(rowData);\n }\n return JSON.stringify(tableData);\n}\n;// CONCATENATED MODULE: ./src/js/components/table/table.js\n\n\n\n\n\n\n\n\n\n\n\n\n\nfunction adjustTableWidth(width_pct) {\n const table = document.getElementById('main-table');\n table.style.width = width_pct;\n}\nfunction showTable() {\n const tableContainer = document.querySelector('.table-container');\n tableContainer.innerHTML = Table.html;\n const table = document.getElementById('main-table');\n table.style.display = 'table';\n}\nfunction hideTable() {\n // delete table object from table container\n const tableContainer = document.querySelector('.table-container');\n tableContainer.innerHTML = '';\n subcomponents_buttons.AddRow.hide();\n}\nfunction saveTableData() {\n // remove the detail text\n components_tooltip_tooltip.unlink();\n // get table\n var table = document.getElementById('main-table');\n // determine save_as name\n if (current_fund.number()) {\n var save_as = `${current_page.load()}_${current_fund.number()}`;\n } else {\n var save_as = current_page.load();\n }\n localStorage.setItem(save_as, convertToJSON(table, ['Edit']));\n // update sidebar with new data\n components_sidebar_sidebar.updateTotals();\n // relink, depending on page\n components_tooltip_tooltip.linkAll();\n}\nconst Table = {\n html: `\n \n \n \n
`,\n Buttons: subcomponents_buttons,\n Cell: cells,\n Columns: columns,\n Header: headers,\n Rows: rows,\n Data: data,\n Filter: filters,\n // functions\n adjustWidth: function (width_pct) {\n adjustTableWidth(width_pct);\n },\n clear: hideTable,\n hide: hideTable,\n show: showTable,\n save: saveTableData\n};\n/* harmony default export */ const components_table_table = (Table);\n;// CONCATENATED MODULE: ./src/js/components/accordion/accordion.js\n\n\n\n\n\nfunction redirectForEdit() {\n const row = document.querySelector(`.active-editing`);\n const table = row.parentElement;\n const section = table.closest('.summary-container');\n // new initiative edits should all redirect to the new-inits page\n if (section.id == 'supp-accordion') {\n visitPage('new-inits');\n } else {\n // Split the string into parts using '-' as the delimiter; retain fund as 1st numeric segment\n const fund = table.id.split('-')[1];\n current_fund.update(fund);\n const lineItem = row.querySelector('.line-item').textContent;\n // visit the correct page for editing\n switch (lineItem) {\n case 'Personnel Expenditures':\n visitPage('personnel');\n break;\n case 'Non-Personnel Expenditures':\n visitPage('nonpersonnel');\n break;\n case 'Revenues':\n visitPage('revenue');\n break;\n case 'Overtime Expenditures':\n visitPage('overtime');\n break;\n default:\n console.error('Name of line item in table does not match a page destination.');\n }\n }\n}\nconst AppropriationTable = {};\nconst ExpenseTable = {\n table_id: account_string => {\n return `table-${account_string}`;\n },\n init(account_string) {\n // create empty table and put it in the accordion\n var table = document.createElement('table');\n table.id = this.table_id(account_string);\n table.classList.add('accordion-table');\n var parent = document.querySelector(`#string_${account_string}_content .accordion-body`);\n parent.appendChild(table);\n },\n createNewCell(content, row, className) {\n const newCell = document.createElement('td');\n newCell.innerHTML = content;\n newCell.classList.add(className);\n row.appendChild(newCell);\n },\n addRow(account_string, row_name, number) {\n var table = document.getElementById(this.table_id(account_string));\n var new_row = document.createElement('tr');\n table.appendChild(new_row);\n // Create a cell for the line item label\n this.createNewCell(row_name, new_row, 'line-item');\n // create a cell for the amount\n this.createNewCell(formatCurrency(number), new_row, 'cost');\n // create Edit button \n var button = '';\n if (row_name != 'Net Expenditures (Revenues)') {\n button = components_table_table.Buttons.Edit.html;\n }\n this.createNewCell(button, new_row);\n },\n fillFromFund(fund) {\n // use just fund as account string to initialize table inside accordion\n this.init(fund);\n const fundObject = new models_fund(fund);\n\n // Add a row for each appropriation in the fund\n const id = cleanString(fund);\n fundObject.getAppropriations().forEach(appropObj => {\n // if the total for the appropriation is > $0, add an accordion for all the CCs\n if (appropObj.total() != 0) {\n Item.add(appropObj.accountString(), `#string_${id}_content .accordion-body`);\n Item.updateHeader(appropObj.name(), appropObj.accountString(), appropObj.total());\n this.fillFromApprop(appropObj);\n }\n });\n },\n fillFromApprop(appropObj) {\n // initialize the table object\n this.init(appropObj.accountString());\n // add a collapsible row for each cost center\n appropObj.getCostCenters().forEach(ccObj => {\n if (ccObj.getTotal() != 0) {\n Item.add(ccObj.accountString(), `#string_${appropObj.accountString()}_content .accordion-body`);\n Item.updateHeader(ccObj.getName(), ccObj.accountString(), ccObj.getTotal());\n this.fillFromCC(ccObj);\n }\n });\n },\n fillFromCC(ccObj) {\n // initialize a table and summarize the line items\n this.init(ccObj.accountString());\n this.addRow(ccObj.accountString(), 'Personnel Expenditures', ccObj.getPersonnelCost());\n this.addRow(ccObj.accountString(), 'Overtime Expenditures', ccObj.getOvertimeCost());\n this.addRow(ccObj.accountString(), 'Non-Personnel Expenditures', ccObj.getNonPersonnelCost());\n this.addRow(ccObj.accountString(), 'Revenues', ccObj.getRevenue());\n this.addRow(ccObj.accountString(), 'Net Expenditures (Revenues)', ccObj.getTotal());\n },\n fillFromInit(program) {\n this.init(program.name);\n this.addRow(program.name, 'Expenditures', program.expenses());\n this.addRow(program.name, 'Revenues', program.revenue());\n this.addRow(program.name, 'Net Expenditures (Revenues)', program.net());\n }\n};\nconst Item = {\n accountString(fund, approp = '', cc = '') {\n var account_string = cleanString(fund);\n if (approp) {\n account_string += approp;\n }\n ;\n if (cc) {\n account_string += cc;\n }\n ;\n return account_string;\n },\n html(account_string) {\n return `

\n \n

\n
\n
\n
`;\n },\n add: function (account_string, accordion_query) {\n // get accordion and add a new item to it\n const parent = document.querySelector(accordion_query);\n const item_element = document.createElement('div');\n item_element.classList.add('accordion-item');\n item_element.innerHTML = this.html(account_string);\n parent.appendChild(item_element);\n },\n ExpenseTable: ExpenseTable,\n updateHeader: function (title, account_string, new_amount) {\n const header_btn = document.querySelector(`#string_${account_string}_header button`);\n header_btn.querySelector('span.name').textContent = title;\n header_btn.querySelector('span.amount').textContent = formatCurrency(new_amount);\n }\n};\nconst AddInitButton = {\n init() {\n const btn = document.querySelector('.btn-add-init');\n btn.addEventListener('click', function () {\n visitPage('new-inits');\n });\n }\n};\nconst Accordion = {\n Item: Item,\n AddInitButton: AddInitButton,\n hide: function () {\n document.querySelector('#accordion-div').style.display = 'none';\n // reset to delete content\n document.querySelector('#baseline-accordion .summary-accordion').innerHTML = '';\n document.querySelector('#supp-accordion .summary-accordion').innerHTML = '';\n },\n show: function () {\n document.querySelector('#accordion-div').style.display = 'block';\n },\n async createBaseline() {\n var funds = fund_lookup_table.listFunds();\n funds.forEach(fund => {\n Item.add(fund, '#baseline-accordion .summary-accordion');\n Item.ExpenseTable.fillFromFund(fund);\n const fundObject = new models_fund(fund);\n Item.updateHeader(`Fund ${fund_lookup_table.getName(fund)}`, fund, fundObject.getTotal());\n });\n },\n createSupp() {\n const supp = new supplemental();\n supp.initiatives.forEach(program => {\n Item.add(program.name, '#supp-accordion .summary-accordion');\n Item.ExpenseTable.fillFromInit(program);\n Item.updateHeader(program.name, program.name, program.net());\n });\n },\n updateTopLines() {\n // adjuse baseline\n // const baseline = new Baseline;\n const baseline = new models_fund(1000);\n const baselineAmount = document.querySelector('#baseline-title .top-line-amount');\n baselineAmount.textContent = formatCurrency(baseline.getTotal());\n // adjust supplementals\n const supp = new supplemental();\n const suppAmount = document.querySelector('#supp-title .top-line-amount');\n suppAmount.textContent = formatCurrency(supp.total());\n // color-code baseline\n if (baseline.getTotal() <= models_baseline.target()) {\n baselineAmount.style.color = 'green';\n } else {\n baselineAmount.style.color = 'red';\n }\n },\n build() {\n this.createBaseline();\n this.createSupp();\n // initialize edit buttons\n components_table_table.Buttons.Edit.init(redirectForEdit);\n this.AddInitButton.init();\n this.updateTopLines();\n }\n};\n/* harmony default export */ const components_accordion_accordion = (Accordion);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/file_upload/file_upload.css\nvar file_upload = __webpack_require__(39);\n;// CONCATENATED MODULE: ./src/js/components/file_upload/file_upload.css\n\n \n \n \n \n \n \n \n \n \n\nvar file_upload_options = {};\n\nfile_upload_options.styleTagTransform = (styleTagTransform_default());\nfile_upload_options.setAttributes = (setAttributesWithoutAttributes_default());\nfile_upload_options.insert = insertBySelector_default().bind(null, \"head\");\nfile_upload_options.domAPI = (styleDomAPI_default());\nfile_upload_options.insertStyleElement = (insertStyleElement_default());\n\nvar file_upload_update = injectStylesIntoStyleTag_default()(file_upload/* default */.A, file_upload_options);\n\n\n\n\n /* harmony default export */ const file_upload_file_upload = (file_upload/* default */.A && file_upload/* default */.A.locals ? file_upload/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/file_upload/file_upload.js\n// file_upload.js\n\n\n\nconst FileUpload = {\n init: function () {\n components_nav_buttons_nav_buttons.Next.disable();\n const inputObject = document.getElementById('file-input');\n inputObject.addEventListener('change', function (event) {\n readXL(event);\n });\n },\n show: function () {\n const inputObject = document.getElementById('file-input');\n inputObject.style.display = '';\n },\n hide: function () {\n const inputObject = document.getElementById('file-input');\n inputObject.style.display = 'none';\n }\n};\nfunction readXL(event) {\n const file = event.target.files[0]; // read uploaded file\n const spinner = document.getElementById('upload-spinner'); // get the spinner element\n\n if (file) {\n // Show the spinner\n spinner.style.display = 'block';\n\n // read in new data\n const reader = new FileReader();\n reader.onload = function (e) {\n const arrayBuffer = e.target.result;\n try {\n processWorkbook(arrayBuffer);\n\n // Hide the spinner once processing is done\n spinner.style.display = 'none';\n components_nav_buttons_nav_buttons.Next.enable(); // Enable the next button after processing\n } catch (error) {\n console.error('Error processing workbook:', error);\n\n // Hide the spinner in case of an error\n spinner.style.display = 'none';\n components_nav_buttons_nav_buttons.Next.enable(); // Ensure the button is re-enabled in case of an error\n }\n };\n reader.onerror = function (err) {\n console.error('Error reading file:', err);\n\n // Hide the spinner in case of an error\n spinner.style.display = 'none';\n components_nav_buttons_nav_buttons.Next.enable(); // Ensure the button is re-enabled in case of an error\n };\n reader.readAsArrayBuffer(file); // Read the file as an ArrayBuffer\n }\n}\n/* harmony default export */ const components_file_upload_file_upload = (FileUpload);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/modal/modal.css\nvar modal = __webpack_require__(95);\n;// CONCATENATED MODULE: ./src/js/components/modal/modal.css\n\n \n \n \n \n \n \n \n \n \n\nvar modal_options = {};\n\nmodal_options.styleTagTransform = (styleTagTransform_default());\nmodal_options.setAttributes = (setAttributesWithoutAttributes_default());\nmodal_options.insert = insertBySelector_default().bind(null, \"head\");\nmodal_options.domAPI = (styleDomAPI_default());\nmodal_options.insertStyleElement = (insertStyleElement_default());\n\nvar modal_update = injectStylesIntoStyleTag_default()(modal/* default */.A, modal_options);\n\n\n\n\n /* harmony default export */ const modal_modal = (modal/* default */.A && modal/* default */.A.locals ? modal/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/modal/modal.js\n\nfunction clearModal() {\n updateModalTitle('');\n document.getElementById('modal-body').innerHTML = '';\n}\nfunction hideModal() {\n $('#main-modal').modal('hide');\n}\nfunction showModal() {\n $('#main-modal').modal('show');\n}\nfunction showModalHandler() {\n showModal('main-modal');\n}\nconst Submit = {\n handler: null,\n init: function (onSubmit) {\n const modal = document.getElementById('main-modal');\n // add onSubmit function as handler\n this.handler = function (event) {\n event.preventDefault();\n onSubmit(event);\n };\n // Adding the handler reference as the event listener\n modal.addEventListener('submit', this.handler);\n\n // add event listener to enable close x\n const x = modal.querySelector('#modal-close-x');\n x.addEventListener('click', hideModal);\n },\n deinit: function () {\n const modal = document.getElementById('main-modal');\n if (this.handler !== null) {\n // Removing the event listener and clear the handler\n modal.removeEventListener('submit', this.handler);\n this.handler = null;\n }\n // remove event listener to enable close x\n const x = modal.querySelector('#modal-close-x');\n x.removeEventListener('click', hideModal);\n }\n};\nconst Link = {\n add: function (button_id) {\n document.getElementById(button_id).addEventListener('click', showModalHandler);\n },\n remove: function (button_id) {\n document.getElementById(button_id).removeEventListener('click', showModalHandler);\n }\n};\nfunction updateModalTitle(title) {\n document.getElementById('modal-title').textContent = title;\n}\nconst Title = {\n update: function (title) {\n updateModalTitle(title);\n }\n};\nconst Modal = {\n hide: hideModal,\n show: showModal,\n clear: clearModal,\n Title: Title,\n Link: Link,\n Submit: Submit\n};\n/* harmony default export */ const components_modal_modal = (Modal);\n;// CONCATENATED MODULE: ./src/js/components/body/body.js\n\n\n\n\n\n\n\n\n\n\nfunction resetPage() {\n // hide everything in the body\n components_welcome_welcome.hide();\n components_modal_modal.clear();\n components_modal_modal.hide();\n components_nav_buttons_nav_buttons.hide();\n js_components_prompt_prompt.hide();\n components_table_table.hide();\n components_sidebar_sidebar.hide();\n components_accordion_accordion.hide();\n components_file_upload_file_upload.hide();\n components_tooltip_tooltip.hide();\n\n // reset filter dropdowns\n components_table_table.Filter.deleteAll();\n js_components_prompt_prompt.Buttons.reset();\n // disable submit button\n components_modal_modal.Submit.deinit();\n}\nconst Body = {\n reset: resetPage\n};\n/* harmony default export */ const components_body_body = (Body);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/header/header.css\nvar header = __webpack_require__(107);\n;// CONCATENATED MODULE: ./src/js/components/header/header.css\n\n \n \n \n \n \n \n \n \n \n\nvar header_options = {};\n\nheader_options.styleTagTransform = (styleTagTransform_default());\nheader_options.setAttributes = (setAttributesWithoutAttributes_default());\nheader_options.insert = insertBySelector_default().bind(null, \"head\");\nheader_options.domAPI = (styleDomAPI_default());\nheader_options.insertStyleElement = (insertStyleElement_default());\n\nvar header_update = injectStylesIntoStyleTag_default()(header/* default */.A, header_options);\n\n\n\n\n /* harmony default export */ const header_header = (header/* default */.A && header/* default */.A.locals ? header/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/header/header.js\n\n\n\nconst header_Title = {\n update: function (title) {\n document.getElementById(\"title\").textContent = title;\n },\n default() {\n this.update(`FY${FISCAL_YEAR} Budget Request`);\n }\n};\nconst Subtitle = {\n update: function (subtitle) {\n // get current fund\n var fund = current_fund.name();\n if (fund) {\n var subtitle = `${subtitle}: ${fund}`;\n }\n document.getElementById(\"subtitle\").textContent = subtitle;\n }\n};\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./src/js/components/form/form.css\nvar form_form = __webpack_require__(109);\n;// CONCATENATED MODULE: ./src/js/components/form/form.css\n\n \n \n \n \n \n \n \n \n \n\nvar form_options = {};\n\nform_options.styleTagTransform = (styleTagTransform_default());\nform_options.setAttributes = (setAttributesWithoutAttributes_default());\nform_options.insert = insertBySelector_default().bind(null, \"head\");\nform_options.domAPI = (styleDomAPI_default());\nform_options.insertStyleElement = (insertStyleElement_default());\n\nvar form_update = injectStylesIntoStyleTag_default()(form_form/* default */.A, form_options);\n\n\n\n\n /* harmony default export */ const components_form_form = (form_form/* default */.A && form_form/* default */.A.locals ? form_form/* default */.A.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/js/components/form/subcomponents/fields.js\n// function to add questions to forms\n\n\n\n// inputType is for validation ('number' or 'text', etc)\nfunction appendFormElement(label, inputEl, inputId, required) {\n // change if we want forms elsewhere\n const form = document.getElementById('new-form');\n\n // create outer wrapper for element\n const wrapper = document.createElement('div');\n\n // label question\n const labelEl = document.createElement('label');\n labelEl.textContent = label;\n\n // mark as required if applicable\n inputEl.required = required;\n\n // If an ID is provided, set it on the element\n if (inputId) {\n inputEl.id = inputId;\n }\n\n // add elements\n wrapper.appendChild(labelEl);\n wrapper.appendChild(inputEl);\n form.appendChild(wrapper);\n}\nconst NewField = {\n shortText: function (label, inputId, required = false) {\n const inputEl = document.createElement('input');\n inputEl.type = 'text';\n appendFormElement(label, inputEl, inputId, required);\n },\n longText: function (label, inputId, required = false) {\n const inputEl = document.createElement('textarea');\n appendFormElement(label, inputEl, inputId, required);\n },\n numericInput: function (label, inputId, required = false) {\n const inputEl = document.createElement('input');\n inputEl.type = 'number';\n appendFormElement(label, inputEl, inputId, required);\n },\n dropdown: function (label, inputId, optionArray, required = false) {\n var inputEl = subcomponents_dropdown.create(optionArray);\n appendFormElement(label, inputEl, inputId, required);\n }\n};\n/* harmony default export */ const fields = (NewField);\n;// CONCATENATED MODULE: ./src/js/components/form/subcomponents/submit.js\nfunction addSubmitButtonToForm(form_id) {\n // Find the form by its ID\n const form = document.getElementById(form_id);\n\n // Create the container `div` for the button\n const buttonContainer = document.createElement('div');\n buttonContainer.id = 'submit-btn-container';\n\n // Create the submit input\n const submitInput = document.createElement('input');\n submitInput.className = 'btn btn-submit'; // Use appropriate class for your design\n submitInput.type = 'submit';\n submitInput.value = 'Submit';\n\n // Append the submit input to the container\n buttonContainer.appendChild(submitInput);\n\n // Append the container to the form\n form.appendChild(buttonContainer);\n}\nconst SubmitButton = {\n add: function () {\n addSubmitButtonToForm('new-form');\n }\n};\n/* harmony default export */ const subcomponents_submit = (SubmitButton);\n;// CONCATENATED MODULE: ./src/js/components/form/form.js\n\n\n\n\nfunction fetchAllResponses(event) {\n // Assuming `event.target` is the form itself\n const form = event.target;\n\n // Initialize an empty array to hold the input values\n let formData = {};\n\n // Loop through each form element\n for (let i = 0; i < form.elements.length; i++) {\n const element = form.elements[i];\n\n // Exclude elements that aren't inputs, textareas, or select\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA' || element.tagName === 'SELECT') {\n // Exclude input types that are not considered for submission (such as `submit`)\n if (element.type !== 'submit' && element.type !== 'button') {\n formData[element.id] = element.value;\n }\n }\n }\n form.reset();\n return formData;\n}\nfunction addForm(element_id = 'modal-body', form_id = 'new-form') {\n const target_elem = document.getElementById(element_id);\n\n // create form\n const form = document.createElement('form');\n form.setAttribute('id', form_id);\n\n // Append the form to the modal body\n target_elem.appendChild(form);\n}\nconst Form = {\n new: function (parent_elem_id) {\n addForm(parent_elem_id, 'new-form');\n },\n fetchAllResponses: function (event) {\n return fetchAllResponses(event);\n },\n NewField: fields,\n Dropdown: subcomponents_dropdown,\n SubmitButton: subcomponents_submit\n};\n/* harmony default export */ const js_components_form_form = (Form);\n;// CONCATENATED MODULE: ./src/js/views/view_class.js\n\n\n\n\n\n\n\n\n\nclass View {\n constructor() {\n // page state in local storage\n this.page_state = '';\n\n // whether to display\n this.navButtons = true;\n this.sidebar = true;\n\n // text to show in the prompt area\n this.prompt = null;\n\n // subtitle text\n this.subtitle = '';\n\n // table object of class ViewTable or null\n this.table = null;\n }\n visit() {\n // update page state\n current_page.update(this.page_state);\n\n // start with a blank page\n components_body_body.reset();\n\n // add default title\n header_Title.default();\n\n // default to showing navbuttons\n if (this.navButtons) {\n components_nav_buttons_nav_buttons.show();\n }\n ;\n\n // default to showing sidebar\n if (this.sidebar) {\n components_sidebar_sidebar.show();\n }\n ;\n\n // initialize prompt text and buttons\n if (this.prompt) {\n js_components_prompt_prompt.Text.update(this.prompt);\n }\n ;\n\n // initialize table\n if (this.table) {\n this.table.build();\n }\n\n // show page subtitle\n if (this.subtitle) {\n Subtitle.update(this.subtitle);\n }\n ;\n }\n cleanup() {\n return;\n }\n}\nclass ViewTable {\n constructor() {\n // Ensure methods retain the correct `this` context\n this.submitNewRow = this.submitNewRow.bind(this);\n this.columns = [{\n title: 'Account String',\n className: 'account-string'\n }, {\n title: 'Appropriation Name',\n className: 'approp-name',\n hide: true\n }, {\n title: 'Appropriation',\n className: 'approp',\n hide: true\n }, {\n title: 'Cost Center Name',\n className: 'cc-name',\n hide: true\n }, {\n title: 'Cost Center',\n className: 'cc',\n hide: true\n }, {\n title: 'Fund Name',\n className: 'fund-name',\n hide: true\n }, {\n title: 'Fund',\n className: 'fund',\n hide: true\n }, {\n title: 'Edit',\n className: 'edit'\n }];\n\n // whether to add an edit column\n this.addEdit = true;\n\n // message to show if there's no saved data\n this.noDataMessage = null;\n\n // text to show for new row button\n this.addButtonText = null;\n\n // whether to show as a datatable\n this.dataTable = true;\n }\n async build() {\n // build table from local storage and initialize edit buttons\n\n // add the add new row button if needed\n if (this.addButtonText) {\n this.setUpForm();\n }\n\n // fill table with new data from local storage\n if (await components_table_table.Data.load()) {\n // create a datatable object\n if (this.dataTable) {\n this.initDataTable();\n }\n\n // add an edit column if needed\n if (this.addEdit) {\n components_table_table.Columns.addAtEnd(components_table_table.Buttons.edit_confirm_btns, 'Edit');\n // activate edit buttons\n components_table_table.Buttons.Edit.init(this.actionOnEdit, this.updateTable);\n }\n\n // assign the correct classes based on the table columns\n components_table_table.Columns.assignClasses(this.columns);\n\n // Apply any update function to make sure sidebar is up to date\n this.updateTable();\n\n // Add all relevant filters to table\n components_table_table.Filter.add('Appropriation', 'approp-name');\n components_table_table.Filter.add('Cost Center', 'cc-name');\n if (this.columns.some(column => column.className === 'object-name')) {\n components_table_table.Filter.add('Object', 'object-name');\n }\n ;\n if (this.columns.some(column => column.className === 'object-category')) {\n components_table_table.Filter.add('Object Category', 'object-category');\n }\n } else {\n // show a message if there's no saved table data for the selected fund\n if (this.noDataMessage) {\n js_components_prompt_prompt.Text.update(this.noDataMessage);\n }\n }\n }\n initDataTable() {\n components_table_table.adjustWidth('100%');\n // Initialize Datatables\n if (!$.fn.dataTable.isDataTable('#main-table')) {\n $('#main-table').DataTable({\n paging: false,\n // Disable pagination\n info: false,\n // Disable table information display\n searching: false // Disable the search bar\n });\n }\n ;\n }\n\n // placeholder for action on row edit click\n actionOnEdit() {\n return;\n }\n\n // update function for the sidebar; default to just saving the table\n updateTable() {\n components_table_table.save();\n }\n\n // extra questions of the form to add a new row\n addCustomQuestions() {\n return;\n }\n setUpForm() {\n // show add button\n components_table_table.Buttons.AddRow.show();\n components_table_table.Buttons.AddRow.updateText(this.addButtonText);\n\n // set up modal for form when add button is pressed\n components_modal_modal.clear();\n components_modal_modal.Link.add('add-btn');\n components_modal_modal.Title.update(this.addButtonText);\n\n // create form\n js_components_form_form.new('modal-body');\n\n // add custom questions\n this.addCustomQuestions();\n // add submit button\n js_components_form_form.SubmitButton.add();\n\n // Initialize form submission to table data\n components_modal_modal.Submit.init(this.submitNewRow);\n }\n editColumns(responses) {\n // get numbers from account string names\n if (responses['fund-name']) {\n responses['fund'] = account_string.getNumber(responses['fund-name']);\n }\n ;\n if (responses['approp-name']) {\n responses['approp'] = account_string.getNumber(responses['approp-name']);\n }\n ;\n if (responses['cc-name']) {\n responses['cc'] = account_string.getNumber(responses['cc-name']);\n }\n ;\n if (responses['object-name']) {\n responses['object'] = account_string.getNumber(responses['object-name']);\n }\n ;\n responses['account-string'] = account_string.build(responses['approp-name'], responses['cc-name'], responses['object-name'], responses['fund']);\n return responses;\n }\n submitNewRow(event) {\n // get answers from form, hide form, show answers in table\n var responses = js_components_form_form.fetchAllResponses(event);\n\n // edit inputs from modal\n responses = this.editColumns(responses);\n\n // make sure it's not an empty response\n if (Object.values(responses)[0] != '') {\n // change page view\n components_modal_modal.hide();\n\n // add data to table\n components_table_table.Rows.add(responses, this.columns);\n components_table_table.save();\n\n // rebuild table\n this.build();\n }\n }\n}\n;// CONCATENATED MODULE: ./src/js/views/00_welcome.js\n\n\n\nclass WelcomeView extends View {\n constructor() {\n super();\n this.page_state = 'welcome';\n this.subtitle = 'Welcome';\n this.sidebar = false;\n this.navButtons = false;\n }\n visit() {\n super.visit();\n\n // show welcome section\n components_welcome_welcome.show();\n\n // initialize links in buttons\n document.getElementById('step-upload').addEventListener('click', () => visitPage('upload'));\n document.getElementById('step-initiatives').addEventListener('click', () => visitPage('new-inits'));\n document.getElementById('step-revenue').addEventListener('click', () => visitPage('baseline-landing'));\n document.getElementById('step-finish').addEventListener('click', () => visitPage('summary'));\n }\n}\n/* harmony default export */ const _00_welcome = (WelcomeView);\n;// CONCATENATED MODULE: ./src/js/views/01_upload.js\n\n\nclass UploadView extends View {\n constructor() {\n super();\n this.page_state = 'upload';\n this.prompt = `Upload the baseline detail sheet given by your budget analyst.`;\n this.subtitle = 'Excel Upload';\n this.sidebar = false;\n }\n visit() {\n super.visit();\n components_file_upload_file_upload.show();\n components_file_upload_file_upload.init();\n }\n}\n/* harmony default export */ const _01_upload = (UploadView);\n;// CONCATENATED MODULE: ./src/js/views/02_baseline_landing.js\n\n\n\n\nclass FundView extends View {\n constructor() {\n super();\n this.page_state = 'baseline-landing';\n this.prompt = `We will now ask you a series of questions about your BASELINE budget request.\n At the end, we will ask you about any new initiatives (ie. supplemental requests).\n Select one of your funds then click continue.`;\n this.subtitle = 'Baseline Budget Request';\n this.table = new FundTable();\n this.sidebar = false;\n this.dataTable = false;\n }\n visit() {\n // remove fund selection\n localStorage.setItem(\"fund\", '');\n super.visit();\n }\n}\nclass FundTable extends ViewTable {\n constructor() {\n super();\n\n // add additional revenue columns to the table\n this.columns = [{\n title: 'Fund',\n className: 'fund-name'\n }];\n this.noDataMessage = 'No funds found.';\n this.addEdit = false;\n }\n build() {\n // load in fund data\n components_table_table.show();\n components_table_table.Data.loadFunds();\n components_table_table.Columns.assignClasses(this.columns);\n components_table_table.adjustWidth('30%');\n\n // disable next button until a fund is selected\n components_nav_buttons_nav_buttons.Next.disable();\n allowRowSelection();\n }\n}\nfunction allowRowSelection() {\n var tableRows = document.querySelectorAll(\"tbody tr\");\n\n // enable highlight on hover and on select\n tableRows.forEach(function (row) {\n row.addEventListener('mouseover', function () {\n this.classList.add('hover-effect');\n });\n row.addEventListener('mouseout', function () {\n this.classList.remove('hover-effect');\n });\n row.addEventListener('click', function () {\n selectFund(tableRows, this);\n });\n });\n}\nfunction selectFund(tableRows, selected_row) {\n // remove selected class from any other rows\n tableRows.forEach(function (tableRow) {\n tableRow.classList = '';\n });\n\n // add selected class to clicked row\n selected_row.classList.add('selected');\n\n // get fund and save selected fund\n var fund = selected_row.querySelector('.fund-name').textContent;\n var fundNumber = parseInt(fund);\n current_fund.update(fundNumber);\n\n // enable next step\n components_nav_buttons_nav_buttons.Next.enable();\n}\n/* harmony default export */ const _02_baseline_landing = (FundView);\n;// CONCATENATED MODULE: ./src/js/views/03_revenue.js\n\n\nclass RevenueView extends View {\n constructor(fiscal_year) {\n super();\n this.page_state = 'revenue';\n this.prompt = `Review and edit revenue line items. If you change the estimate or \n notice an error in an account string, please note it in the notes column. Click edit \n to change values in a row.`;\n this.subtitle = 'Revenues';\n this.table = new RevenueTable(fiscal_year);\n }\n}\nclass RevenueTable extends ViewTable {\n constructor(fiscal_year) {\n super();\n\n // add additional revenue columns to the table\n this.columns = this.columns.concat([{\n title: 'Recurring or One-Time',\n className: 'recurring'\n }, {\n title: 'Object Category',\n className: 'object-category'\n }, {\n title: `FY${fiscal_year} Departmental Estimate`,\n className: 'request',\n isCost: true\n }, {\n title: 'Departmental Estimate Notes',\n className: 'notes'\n },\n // hidden\n {\n title: 'Object Name',\n className: 'object-name',\n hide: true\n }, {\n title: 'Object',\n className: 'object',\n hide: true\n }]);\n this.noDataMessage = 'No revenues for this fund.';\n }\n\n // action on row edit click: make cells editable\n actionOnEdit() {\n // only allow edits in the notes box\n components_table_table.Cell.createTextbox('notes', false, 'textarea');\n }\n}\n/* harmony default export */ const _03_revenue = (RevenueView);\n;// CONCATENATED MODULE: ./src/js/views/04_personnel.js\n\n\n\n\n\n\nclass PersonnelView extends View {\n constructor(fiscal_year) {\n super();\n this.page_state = 'personnel';\n this.prompt = `\n This table displays the number of FTEs in each job code for in your department's \n current (amended) FY25 budget. To make edits to the number of positions, click the\n \"Edit\" button on the row you would like to edit. The \"Total Cost\" column and the \n summary sidebar will also update to reflect any edits.`;\n this.subtitle = 'Personnel';\n this.table = new PersonnelTable(fiscal_year);\n }\n}\nclass PersonnelTable extends ViewTable {\n constructor(fiscal_year) {\n super();\n this.fiscal_year = fiscal_year;\n // add additional personnel columns to the table\n this.columns = this.columns.concat([{\n title: 'Job Title',\n className: 'job-name'\n }, {\n title: 'Employee Type',\n className: 'employee-type'\n }, {\n title: 'Service',\n className: 'service'\n }, {\n title: `FY${this.fiscal_year} Requested FTE`,\n className: 'baseline-ftes'\n }, {\n title: `FY${this.fiscal_year} Projected Average Salary/Wage`,\n className: 'avg-salary',\n isCost: true\n }, {\n title: 'Total Sal/Wag & Ben Request',\n className: 'total-baseline',\n isCost: true\n }, {\n title: 'Departmental Request Notes',\n className: 'notes'\n },\n // hidden columns\n {\n title: 'Fringe Benefits Rate',\n className: 'fringe',\n hide: true\n }, {\n title: 'General Increase Rate',\n className: 'general-increase-rate',\n hide: true\n }, {\n title: 'Step/Merit Increase Rate',\n className: 'merit-increase-rate',\n hide: true\n }, {\n title: `Average Salary/Wage as of 9/1/20${this.fiscal_year - 2}`,\n className: 'current-salary',\n isCost: true,\n hide: true\n }]);\n this.noDataMessage = 'No personnel expenditures for this fund.';\n this.addButtonText = 'Add new job';\n }\n\n // action on row edit click: make cells editable\n actionOnEdit() {\n components_table_table.Cell.createTextbox('baseline-ftes');\n components_table_table.Cell.createServiceDropdown(services.list());\n components_table_table.Cell.createTextbox('notes', false, 'textarea');\n }\n updateTable() {\n // calculate for each row\n let rows = document.getElementsByTagName('tr');\n for (let i = 1; i < rows.length; i++) {\n // fetch values for calculations\n let avg_salary = components_table_table.Cell.getValue(rows[i], 'avg-salary');\n let fringe = parseFloat(components_table_table.Cell.getText(rows[i], 'fringe'));\n let baseline_ftes = components_table_table.Cell.getText(rows[i], 'baseline-ftes');\n\n // calcuate #FTEs x average salary + COLA adjustments + merit adjustments + fringe\n let total_baseline_cost = avg_salary * baseline_ftes * (1 + fringe);\n\n // update total column\n components_table_table.Cell.updateValue(rows[i], 'total-baseline', total_baseline_cost);\n }\n\n // Save the table after all updates are done\n components_table_table.save();\n }\n addCustomQuestions() {\n // form questions to add a new job\n js_components_form_form.NewField.shortText('Job Title:', 'job-name', true);\n js_components_form_form.NewField.dropdown('Employee Type:', 'employee-type', EMPLOYEE_TYPES, true), js_components_form_form.NewField.dropdown('Appropriation:', 'approp-name', fund_lookup_table.getApprops(), true);\n js_components_form_form.NewField.dropdown('Cost Center:', 'cc-name', fund_lookup_table.getCostCenters(), true);\n js_components_form_form.NewField.dropdown('Service', 'service', services.list(), true);\n js_components_form_form.NewField.shortText('Number of FTEs requested:', 'baseline-ftes', true);\n js_components_form_form.NewField.shortText(`Projected average salary IN FISCAL YEAR ${this.fiscal_year}:`, 'avg-salary', true);\n js_components_form_form.NewField.shortText(`Expected fringe rate (as a percentage)`, 'fringe', true);\n }\n editColumns(responses) {\n responses = super.editColumns(responses);\n // edit inputs from modal\n responses['avg-salary'] = unformatCurrency(responses['avg-salary']);\n responses['fringe'] = parseFloat(responses['fringe']) / 100;\n return responses;\n }\n}\n/* harmony default export */ const _04_personnel = (PersonnelView);\n;// CONCATENATED MODULE: ./src/js/views/05_overtime.js\n\n\n\n\n\n\nclass OvertimeView extends View {\n constructor(fiscal_year) {\n super();\n this.page_state = 'overtime';\n this.prompt = `\n Please see your baseline overtime / holiday pay / shift premiums in the table below.\n Make any edits and continue.`;\n this.subtitle = 'Overtime Estimates';\n this.table = new OvertimeTable(fiscal_year);\n }\n}\nclass OvertimeTable extends ViewTable {\n constructor(fiscal_year) {\n super();\n\n // add additional OT columns to the table\n this.columns = this.columns.concat([{\n title: 'Service',\n className: 'service'\n }, {\n title: 'Recurring or One-Time',\n className: 'recurring'\n }, {\n title: 'Departmental Request OT/SP/Hol',\n className: 'OT-pay',\n isCost: true\n }, {\n title: `FY${fiscal_year} Total OT/SP/Hol + FICA Request`,\n className: 'total',\n isCost: true\n }, {\n title: 'Object Name',\n className: 'object-name'\n }, {\n title: 'Departmental Request Notes',\n className: 'notes'\n },\n // hidden columns\n {\n title: 'FICA Rate',\n className: 'fica',\n hide: true\n }]);\n this.noDataMessage = 'No overtime expenditures for this fund.';\n this.addButtonText = 'Add new cost center';\n }\n\n // action on row edit click: make cells editable\n actionOnEdit() {\n components_table_table.Cell.createTextbox('OT-pay', true);\n components_table_table.Cell.createServiceDropdown(services.list());\n components_table_table.Cell.createDropdown('recurring', ['One-Time', 'Recurring']);\n components_table_table.Cell.createDropdown('object-name', OT_OBJECTS);\n components_table_table.Cell.createTextbox('notes');\n }\n updateTable() {\n // calculate for each row\n let rows = document.getElementsByTagName('tr');\n for (let i = 1; i < rows.length; i++) {\n // fetch values for calculations\n let OT_salary = components_table_table.Cell.getValue(rows[i], 'OT-pay');\n let fica_rate = components_table_table.Cell.getText(rows[i], 'fica');\n\n // add salary and wages and fringe benefits (FICA)\n let row_total = OT_salary * (1 + parseFloat(fica_rate));\n\n // update total\n components_table_table.Cell.updateValue(rows[i], 'total', row_total);\n }\n\n // Save the table after all updates are done\n components_table_table.save();\n }\n addCustomQuestions() {\n // form questions to add a new job\n js_components_form_form.NewField.dropdown('Appropriation:', 'approp-name', fund_lookup_table.getApprops(), true);\n js_components_form_form.NewField.dropdown('Cost Center:', 'cc-name', fund_lookup_table.getCostCenters(), true);\n js_components_form_form.NewField.dropdown('Object (salary or wage):', 'object-name', OT_OBJECTS, true);\n js_components_form_form.NewField.dropdown('Service', 'service', services.list(), true);\n js_components_form_form.NewField.dropdown('Recurring or One-Time', 'recurring', ['Recurring', 'One-Time'], true);\n js_components_form_form.NewField.shortText('Overtime amount requested:', 'OT-pay', true);\n }\n editColumns(responses) {\n responses = super.editColumns(responses);\n // edit inputs from modal\n responses['OT-pay'] = unformatCurrency(responses['OT-pay']);\n responses['fica'] = 0.0765;\n return responses;\n }\n}\n/* harmony default export */ const _05_overtime = (OvertimeView);\n;// CONCATENATED MODULE: ./src/js/views/06_nonpersonnel.js\n\n\n\n\n\n\nclass NonPersonnelView extends View {\n constructor(fiscal_year) {\n super();\n this.page_state = 'nonpersonnel';\n this.prompt = `Review and edit non-personnel line items. The CPA numbers are the \n Contract and Procurement Account numbers. Click on the 'detail' link for a CPA \n to see the contract details. Some line items won't have a CPA number.`;\n this.subtitle = 'Non-Personnel';\n this.table = new NonPersonnelTable(fiscal_year);\n }\n}\nclass NonPersonnelTable extends ViewTable {\n constructor(fiscal_year) {\n super();\n\n // add additional personnel columns to the table\n this.columns = this.columns.concat([{\n title: `FY${fiscal_year} Departmental Request Total`,\n className: 'request',\n isCost: true\n }, {\n title: 'Service',\n className: 'service'\n }, {\n title: 'Recurring or One-Time',\n className: 'recurring'\n }, {\n title: 'Vendor Name',\n className: 'vendor'\n }, {\n title: 'CPA #',\n className: 'cpa'\n },\n // hidden columns\n {\n title: 'End Date',\n className: 'contract-end',\n hide: true\n }, {\n title: 'BPA/CPA Amount Remaining',\n className: 'remaining',\n isCost: true,\n hide: true\n }, {\n title: 'Object Name',\n className: 'object-name',\n hide: true\n }, {\n title: 'Object',\n className: 'object',\n hide: true\n }, {\n title: 'Object Category',\n className: 'object-category',\n hide: true\n }, {\n title: 'BPA/CPA Description',\n className: 'cpa-description',\n hide: true\n }, {\n title: 'Departmental Request Notes',\n className: 'notes'\n }]);\n this.noDataMessage = 'No non-personnel expenditures for this fund.';\n this.addButtonText = 'Add new non-personnel item';\n }\n\n // action on row edit click: make cells editable\n actionOnEdit() {\n components_table_table.Cell.createTextbox('request', true);\n components_table_table.Cell.createServiceDropdown();\n components_table_table.Cell.createDropdown('recurring', ['One-Time', 'Recurring']);\n components_table_table.Cell.createTextbox('notes');\n }\n addCustomQuestions() {\n // form questions to add a new row\n js_components_form_form.NewField.dropdown('Appropriation:', 'approp-name', fund_lookup_table.getApprops(), true);\n js_components_form_form.NewField.dropdown('Cost Center:', 'cc-name', fund_lookup_table.getCostCenters(), true);\n js_components_form_form.NewField.dropdown('Object Category:', 'object-category', OBJ_CATEGORIES.list, true);\n // TODO: maybe give dropdown based on selected obj category\n js_components_form_form.NewField.shortText('Object Number (if known):', 'object', false);\n js_components_form_form.NewField.dropdown('Service', 'service', services.list(), true);\n js_components_form_form.NewField.longText('Describe your new request:', 'cpa-description', true);\n js_components_form_form.NewField.dropdown('Recurring or One-Time', 'recurring', ['Recurring', 'One-Time'], true);\n js_components_form_form.NewField.shortText('Amount requested:', 'request', true);\n }\n editColumns(responses) {\n responses = super.editColumns(responses);\n responses['avg-salary'] = unformatCurrency(responses['avg-salary']);\n responses['fringe'] = parseFloat(responses['fringe']) / 100;\n return responses;\n }\n}\n/* harmony default export */ const _06_nonpersonnel = (NonPersonnelView);\n;// CONCATENATED MODULE: ./src/js/views/07_new_initiatives.js\n\n\n\n\n\nconst dropdownOptions = ['N/A', 'One-Time', 'Recurring'];\n\n// set up page and initialize all buttons\nclass InitiativesView extends View {\n constructor() {\n super();\n this.page_state = 'new-inits';\n this.prompt = `\n This is the place to propose new initiatives for FY${FISCAL_YEAR}.\n New initiative submissions will count as supplemental line items and will be the starting \n point for a conversation with both OB and ODFS, who will help with the details.`;\n this.subtitle = 'New Initiatives';\n this.table = new InitiativesTable();\n }\n visit() {\n // remove fund selection\n localStorage.setItem(\"fund\", '');\n super.visit();\n }\n}\nclass InitiativesTable extends ViewTable {\n constructor() {\n super();\n\n // add additional columns to the table\n this.columns = this.columns.concat([{\n title: 'Initiative Name',\n className: 'init-name'\n }, {\n title: 'Ballpark Total Expenses',\n className: 'total',\n isCost: true\n }, {\n title: 'Personnel Cost',\n className: 'personnel',\n isCost: true\n }, {\n title: 'Non-personnel Cost',\n className: 'nonpersonnel',\n isCost: true\n }, {\n title: 'Revenue',\n className: 'revenue',\n isCost: true\n }, {\n title: 'Revenue Type',\n className: 'rev-type'\n },\n // hide the explanation columns\n {\n title: 'Q1',\n className: 'q1',\n hide: true\n }, {\n title: 'Q2',\n className: 'q2',\n hide: true\n }, {\n title: 'Q3',\n className: 'q3',\n hide: true\n }]);\n this.addButtonText = 'Add new initiative';\n }\n addCustomQuestions() {\n // general questions\n js_components_form_form.NewField.shortText('Initiative Name:', 'init-name', true);\n js_components_form_form.NewField.longText('What is the business case for the Initiative?', 'q1', true);\n js_components_form_form.NewField.longText(`Why is the initiative needed? What is the value-add to residents? \n What is the Department’s plan for implementing the Initiative?`, 'q2', true);\n js_components_form_form.NewField.longText(`Why can’t the Initiative be funded with the Department’s baseline budget?`, 'q3', true);\n\n // TODO: Edit to drop down\n js_components_form_form.NewField.dropdown('Fund:', 'fund-name', fund_lookup_table.listFundNames(), true);\n js_components_form_form.NewField.dropdown('Appropriation (if known):', 'approp-name', fund_lookup_table.getApprops(), true);\n js_components_form_form.NewField.dropdown('Cost Center (if known):', 'cc-name', fund_lookup_table.getCostCenters(), true);\n\n // Numbers\n js_components_form_form.NewField.numericInput('What is your ballpark estimate of TOTAL ADDITONAL expenses associated with this initiative?', 'total', false);\n js_components_form_form.NewField.numericInput('Estimate of ADDITONAL personnel cost?', 'personnel', false);\n js_components_form_form.NewField.numericInput('Estimate of ADDITONAL nonpersonnel cost?', 'nonpersonnel', false);\n js_components_form_form.NewField.numericInput('Estimate of ADDITONAL revenue (if applicable)?', 'revenue', false);\n js_components_form_form.NewField.dropdown(`If there will be revenue, is it one-time or recurring?`, 'rev-type', dropdownOptions);\n }\n\n // action on row edit click: make cells editable\n actionOnEdit() {\n components_table_table.Cell.createTextbox('total', true);\n components_table_table.Cell.createTextbox('revenue', true);\n components_table_table.Cell.createTextbox('personnel', true);\n components_table_table.Cell.createTextbox('nonpersonnel', true);\n components_table_table.Cell.createTextbox('init-name');\n components_table_table.Cell.createDropdown('rev-type', dropdownOptions);\n }\n}\n/* harmony default export */ const _07_new_initiatives = (InitiativesView);\n;// CONCATENATED MODULE: ./src/js/views/08_summary.js\n\n\n\n\n\n\n\n\nfunction compareToTarget() {\n const baseline = new models_baseline();\n if (baseline.total() <= models_baseline.target()) {\n js_components_prompt_prompt.Text.update(`Congrats! Your budget is below your target! \n Edit any line items below or download your completed Excel.`);\n } else {\n js_components_prompt_prompt.Text.update(`Your budget is above your target of ${formatCurrency(models_baseline.target())}. \n Please expand the summary table below and edit line items until you meet your target. \n When you meet the target, you will be able to download the Excel sheet.`);\n js_components_prompt_prompt.Buttons.Right.disable();\n }\n js_components_prompt_prompt.show();\n}\nfunction returnToWelcome() {\n const welcome = new _00_welcome();\n const left = document.getElementById('option1');\n console.log(left.l);\n welcome.visit();\n}\n;\nclass SummaryView extends View {\n constructor() {\n super();\n this.page_state = 'summary';\n this.subtitle = 'Summary';\n this.sidebar = false;\n }\n visit() {\n super.visit();\n\n // reset fund\n current_fund.reset();\n\n // show summary accordion\n Accordion.build();\n Accordion.show();\n\n // add prompt buttons\n js_components_prompt_prompt.Buttons.Right.updateText('Download Excel');\n js_components_prompt_prompt.Buttons.Left.updateText('Start over with new Excel upload');\n // add button links\n js_components_prompt_prompt.Buttons.Left.addAction(returnToWelcome);\n js_components_prompt_prompt.Buttons.Right.addAction(downloadXLSX);\n\n // update prompt text depending on target matching\n compareToTarget();\n }\n cleanup() {\n // delete event listeners\n js_components_prompt_prompt.Buttons.Left.removeAction(returnToWelcome);\n js_components_prompt_prompt.Buttons.Right.removeAction(downloadXLSX);\n js_components_prompt_prompt.Buttons.Right.enable();\n }\n}\n/* harmony default export */ const _08_summary = (SummaryView);\n;// CONCATENATED MODULE: ./src/js/views/view_logic.js\n\n\n\n\n\n\n\n\n\n\n\nfunction initializePages() {\n const PAGES = {\n 'welcome': new _00_welcome(),\n 'upload': new _01_upload(),\n 'baseline-landing': new _02_baseline_landing(),\n 'revenue': new _03_revenue(FISCAL_YEAR),\n 'personnel': new _04_personnel(FISCAL_YEAR),\n 'overtime': new _05_overtime(FISCAL_YEAR),\n 'nonpersonnel': new _06_nonpersonnel(FISCAL_YEAR),\n 'new-inits': new _07_new_initiatives(),\n 'summary': new _08_summary()\n };\n return PAGES;\n}\nfunction visitPage(new_page_key) {\n const PAGES = initializePages();\n\n // clean up from current page\n var page_state = current_page.load();\n PAGES[page_state].cleanup();\n\n // Use the page_state to access and call the corresponding function from PAGES\n if (PAGES[new_page_key]) {\n // Invokes the function if it exists in the PAGES map\n PAGES[new_page_key].visit();\n } else {\n console.error(`No page initializer found for state: ${new_page_key}`);\n }\n}\nfunction nextPage() {\n const PAGES = initializePages();\n var page_state = current_page.load();\n const keys = Object.keys(PAGES);\n\n // Find the index of the current key\n const currentIndex = keys.indexOf(page_state);\n\n // Return to summary if all funds are viewed\n const returnPages = ['revenue', 'nonpersonnel', 'new-inits', 'overtime', 'personnel'];\n if (!fund_lookup_table.fundsLeft() && returnPages.includes(current_page.load())) {\n visitPage('summary');\n return;\n }\n\n // if on non-personnel, circle back to fund selection unless all funds are edited\n if (current_page.load() == 'nonpersonnel') {\n // mark fund as viewed/edited\n fund_lookup_table.editFund(current_fund.number());\n // if any funds left to edit, go back to that page\n if (fund_lookup_table.fundsLeft()) {\n visitPage('baseline-landing');\n return;\n }\n }\n if (currentIndex >= 0 && currentIndex < keys.length - 1) {\n // Check if there is a next key, and get it\n const nextKey = keys[currentIndex + 1];\n // go to that page\n visitPage(nextKey);\n }\n}\nfunction lastPage() {\n const PAGES = initializePages();\n var page_state = current_page.load();\n const keys = Object.keys(PAGES);\n\n // Find the index of the current key\n const currentIndex = keys.indexOf(page_state);\n\n // if on new-inits, circle back to fund selection\n if (current_page.load() == 'new-inits') {\n visitPage('baseline-landing');\n return;\n }\n\n // Check if there is a next key\n if (currentIndex >= 1) {\n // Get the next key\n const lastKey = keys[currentIndex - 1];\n // go to that page\n visitPage(lastKey);\n }\n}\n;// CONCATENATED MODULE: ./src/js/models/current_page.js\n\nconst CurrentPage = {\n update: function (page) {\n localStorage.setItem('page_state', page);\n },\n load: function () {\n const pageState = localStorage.getItem('page_state');\n return pageState !== null ? pageState : 'welcome';\n },\n visit: function () {\n visitPage(this.load());\n }\n};\n/* harmony default export */ const current_page = (CurrentPage);\n;// CONCATENATED MODULE: ./src/js/init.js\n// import styles\n\n\n// import functions\n\ndocument.addEventListener('DOMContentLoaded', function () {\n current_page.visit();\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjU0LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3hCQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDeEJBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFFQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUM5RUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3hCQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVFBOztBQUVBO0FBQ0E7QUFXQTs7QUM5QkE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FDekVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ2pIQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUNsQkE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUN6Q0E7QUFDQTs7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ2pNQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ1RBOztBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUFBO0FBRUE7QUFFQTs7QUM3QkE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7O0FDbENBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUdBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUNwQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7Ozs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3hCQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7OztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4QkE7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUM3QkE7QUFDQTtBQUVBO0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUM3RUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDdkdBO0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFFQTs7QUN6QkE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBRUE7O0FDM0VBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ3JNQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBOztBQy9JQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7O0FDMUxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQzdNQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUM3RUE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFJQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTs7OztBQ2hPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7OztBQzVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdkJBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDN0VBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOzs7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4QkE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4QkE7O0FBRUE7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ3BEQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBRUE7O0FDekJBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUdBO0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBOztBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7O0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFBQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTs7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFLQTtBQUNBO0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDak9BO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFFQTs7QUMvQkE7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUdBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7QUMzRkE7QUFFQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQzNDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBOztBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBR0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUVBO0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkdBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7O0FDZkE7QUFDQTs7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9jc3MvY29tbW9uLmNzcz84ZmY2Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy93ZWxjb21lL3dlbGNvbWUuY3NzP2RlZTEiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3dlbGNvbWUvd2VsY29tZS5qcz81MzVhIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9wcm9tcHQvcHJvbXB0LmNzcz8zMjhiIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9wcm9tcHQvc3ViY29tcG9uZW50cy90ZXh0LmpzP2Y2ZGYiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3Byb21wdC9zdWJjb21wb25lbnRzL2J1dHRvbnMuanM/OGQzYiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvcHJvbXB0L3Byb21wdC5qcz9hNzcxIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9zaWRlYmFyL3NpZGViYXIuY3NzPzNiYzciLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb25zdGFudHMvYnVkZ2V0X2NvbnN0YW50cy5qcz8xNTAyIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29uc3RhbnRzL2V4Y2VsX2NvbnN0YW50cy5qcz9mNjg3Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29uc3RhbnRzL2luZGV4LmpzPzI1YzQiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy91dGlscy9jb21tb25fdXRpbHMuanM/NDRmMiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL21vZGVscy9mdW5kX2xvb2t1cF90YWJsZS5qcz9kYzY2Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvbW9kZWxzL2N1cnJlbnRfZnVuZC5qcz9lNmRiIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvbW9kZWxzL2FjY291bnRfc3RyaW5nLmpzPzZjOGQiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9tb2RlbHMvZnVuZC5qcz82Y2ZhIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvbW9kZWxzL2Jhc2VsaW5lLmpzP2Q0OTQiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9tb2RlbHMvc2VydmljZXMuanM/MTM5ZiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL21vZGVscy9pbml0aWF0aXZlLmpzP2Y5NmEiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9tb2RlbHMvc3VwcGxlbWVudGFsLmpzPzk5Y2UiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9tb2RlbHMvaW5kZXguanM/MDVlMSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvc2lkZWJhci9zdWJjb21wb25lbnRzL2Jhc2VsaW5lX3NlY3Rpb24uanM/MTNiZCIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvc2lkZWJhci9zdWJjb21wb25lbnRzL3N1cHBfc2VjdGlvbi5qcz8wYzRlIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9zaWRlYmFyL3NpZGViYXIuanM/ODBmMCIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvbmF2X2J1dHRvbnMvbmF2X2J1dHRvbnMuY3NzPzcwN2YiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL25hdl9idXR0b25zL25hdl9idXR0b25zLmpzP2FiZDEiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2JvZHkvYm9keS5jc3M/ZDFjNyIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvYWNjb3JkaW9uL2FjY29yZGlvbi5jc3M/NWE2YyIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvdGFibGUvdGFibGUuY3NzPzc4NGMiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3RhYmxlL3N1YmNvbXBvbmVudHMvaGVhZGVycy5qcz8xNjIzIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy90YWJsZS9zdWJjb21wb25lbnRzL3Jvd3MuanM/ZmI3OSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvdGFibGUvc3ViY29tcG9uZW50cy9idXR0b25zLmpzP2M5OTIiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2Zvcm0vc3ViY29tcG9uZW50cy9kcm9wZG93bi5qcz9iYTZiIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy90YWJsZS9zdWJjb21wb25lbnRzL2NlbGxzLmpzPzczY2IiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3RhYmxlL3N1YmNvbXBvbmVudHMvY29sdW1ucy5qcz82NzRhIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy90YWJsZS9zdWJjb21wb25lbnRzL2RhdGEuanM/ZDliNiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvdGFibGUvc3ViY29tcG9uZW50cy9maWx0ZXJzLmpzP2FlY2MiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy91dGlscy9YTFNYX2hhbmRsZXJzLmpzP2JhOGEiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3Rvb2x0aXAvdG9vbHRpcC5jc3M/YmM4YyIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvdG9vbHRpcC90b29sdGlwLmpzP2QyM2MiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy91dGlscy9KU09OX2RhdGFfaGFuZGxlcnMuanM/YzlkMiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvdGFibGUvdGFibGUuanM/MzA3MSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvYWNjb3JkaW9uL2FjY29yZGlvbi5qcz8xZjM3Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9maWxlX3VwbG9hZC9maWxlX3VwbG9hZC5jc3M/ZGIwOSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvZmlsZV91cGxvYWQvZmlsZV91cGxvYWQuanM/NTE4OCIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvbW9kYWwvbW9kYWwuY3NzPzQwZGIiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL21vZGFsL21vZGFsLmpzPzU1MzMiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2JvZHkvYm9keS5qcz9mOWJhIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9oZWFkZXIvaGVhZGVyLmNzcz83MmQ3Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9oZWFkZXIvaGVhZGVyLmpzP2EwYTUiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2Zvcm0vZm9ybS5jc3M/NTQxNSIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvZm9ybS9zdWJjb21wb25lbnRzL2ZpZWxkcy5qcz80NTlmIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9mb3JtL3N1YmNvbXBvbmVudHMvc3VibWl0LmpzP2M1OTYiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2Zvcm0vZm9ybS5qcz9kOTQyIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdmlld3Mvdmlld19jbGFzcy5qcz9hNzllIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdmlld3MvMDBfd2VsY29tZS5qcz8wOGJiIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdmlld3MvMDFfdXBsb2FkLmpzP2M0NDgiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy92aWV3cy8wMl9iYXNlbGluZV9sYW5kaW5nLmpzPzdiOGUiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy92aWV3cy8wM19yZXZlbnVlLmpzP2I4NzgiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy92aWV3cy8wNF9wZXJzb25uZWwuanM/ZmJmZiIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL3ZpZXdzLzA1X292ZXJ0aW1lLmpzP2JmNzAiLCJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy92aWV3cy8wNl9ub25wZXJzb25uZWwuanM/NGQzZCIsIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL3ZpZXdzLzA3X25ld19pbml0aWF0aXZlcy5qcz80MWE3Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdmlld3MvMDhfc3VtbWFyeS5qcz84YjMyIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvdmlld3Mvdmlld19sb2dpYy5qcz80NmM2Iiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvbW9kZWxzL2N1cnJlbnRfcGFnZS5qcz9mZmIwIiwid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvaW5pdC5qcz8xYjJhIl0sInNvdXJjZXNDb250ZW50IjpbIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9jb21tb24uY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vY29tbW9uLmNzc1wiO1xuICAgICAgIGV4cG9ydCBkZWZhdWx0IGNvbnRlbnQgJiYgY29udGVudC5sb2NhbHMgPyBjb250ZW50LmxvY2FscyA6IHVuZGVmaW5lZDtcbiIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi93ZWxjb21lLmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xub3B0aW9ucy5pbnNlcnQgPSBpbnNlcnRGbi5iaW5kKG51bGwsIFwiaGVhZFwiKTtcbm9wdGlvbnMuZG9tQVBJID0gZG9tQVBJO1xub3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQgPSBpbnNlcnRTdHlsZUVsZW1lbnQ7XG5cbnZhciB1cGRhdGUgPSBBUEkoY29udGVudCwgb3B0aW9ucyk7XG5cblxuXG5leHBvcnQgKiBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3dlbGNvbWUuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiaW1wb3J0ICcuL3dlbGNvbWUuY3NzJztcclxuXHJcbi8vIEhpZGUgYW5kIHVuaGlkZSB3ZWxjb21lIGJ1dHRvbnNcclxuZnVuY3Rpb24gdW5oaWRlV2VsY29tZUJ1dHRvbnMoKXtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwid2VsY29tZS1wYWdlXCIpLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XHJcbn1cclxuZnVuY3Rpb24gaGlkZVdlbGNvbWVCdXR0b25zKCl7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIndlbGNvbWUtcGFnZVwiKS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBXZWxjb21lID0ge1xyXG4gICAgc2hvdzogdW5oaWRlV2VsY29tZUJ1dHRvbnMsXHJcbiAgICBoaWRlIDogaGlkZVdlbGNvbWVCdXR0b25zXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFdlbGNvbWU7IiwiXG4gICAgICBpbXBvcnQgQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCI7XG4gICAgICBpbXBvcnQgZG9tQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRGbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanNcIjtcbiAgICAgIGltcG9ydCBzZXRBdHRyaWJ1dGVzIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0U3R5bGVFbGVtZW50IGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzXCI7XG4gICAgICBpbXBvcnQgc3R5bGVUYWdUcmFuc2Zvcm1GbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlVGFnVHJhbnNmb3JtLmpzXCI7XG4gICAgICBpbXBvcnQgY29udGVudCwgKiBhcyBuYW1lZEV4cG9ydCBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3Byb21wdC5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcbm9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9wcm9tcHQuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiZnVuY3Rpb24gc2hvd1Byb21wdCgpe1xyXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwcm9tcHQtZGl2XCIpLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGhpZGVQcm9tcHQoKXtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcm9tcHQtZGl2Jykuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxufVxyXG5cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZVByb21wdChwcm9tcHQpe1xyXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Byb21wdCcpLnRleHRDb250ZW50ID0gcHJvbXB0O1xyXG4gICAgc2hvd1Byb21wdCgpO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgVGV4dCA9IHtcclxuICAgIHNob3cgOiBzaG93UHJvbXB0LFxyXG4gICAgaGlkZSA6IGhpZGVQcm9tcHQsXHJcbiAgICB1cGRhdGUgOiBmdW5jdGlvbih0ZXh0KSB7IHVwZGF0ZVByb21wdCh0ZXh0KSB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFRleHQ7IiwiZnVuY3Rpb24gc2hvd1Byb21wdEJ1dHRvbihpZCl7XHJcbiAgICAvLyBtYWtlIGJ1dHRvbnMgdmlzaWJsZVxyXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lJztcclxufVxyXG5cclxuZnVuY3Rpb24gdXBkYXRlUHJvbXB0QnV0dG9uKGlkLCB0ZXh0KXtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS50ZXh0Q29udGVudCA9IHRleHQ7XHJcbiAgICBzaG93UHJvbXB0QnV0dG9uKGlkKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaGlkZVByb21wdEJ1dHRvbihpZCl7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxufVxyXG5cclxuZnVuY3Rpb24gdW5jbGlja0FsbCgpe1xyXG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ29wdGlvbjEnKS5jbGFzc0xpc3QucmVtb3ZlKCdjbGlja2VkJyk7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnb3B0aW9uMicpLmNsYXNzTGlzdC5yZW1vdmUoJ2NsaWNrZWQnKTtcclxufVxyXG5cclxuZnVuY3Rpb24gYXBwbHlDbGlja2VkU3R5bGUoYnV0dG9uKXtcclxuICAgIHVuY2xpY2tBbGwoKTtcclxuICAgIGJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdjbGlja2VkJyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFkZFByb21wdEJ1dHRvbkFjdGlvbihidXR0b25faWQsIGFjdGlvbl9mbil7XHJcbiAgICBjb25zdCBidXR0b25FbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYnV0dG9uX2lkKTtcclxuICAgIGJ1dHRvbkVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhY3Rpb25fZm4pO1xyXG4gICAgYnV0dG9uRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgYXBwbHlDbGlja2VkU3R5bGUodGhpcyk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlUHJvbXB0QnV0dG9uQWN0aW9uKGJ1dHRvbl9pZCwgYWN0aW9uX2ZuKXtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGJ1dHRvbl9pZCkucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhY3Rpb25fZm4pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBkaXNhYmxlKGJ1dHRvbl9pZCl7XHJcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAjJHtidXR0b25faWR9YCkuY2xhc3NMaXN0LmFkZCgnZGlzYWJsZWQnKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZW5hYmxlKGJ1dHRvbl9pZCl7XHJcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAjJHtidXR0b25faWR9YCkuY2xhc3NMaXN0LnJlbW92ZSgnZGlzYWJsZWQnKTtcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IExlZnQgPSB7XHJcbiAgICBzaG93IDogZnVuY3Rpb24oKSB7IHNob3dQcm9tcHRCdXR0b24oJ29wdGlvbjEnKSB9LFxyXG4gICAgaGlkZSA6IGZ1bmN0aW9uKCkgeyBoaWRlUHJvbXB0QnV0dG9uKCdvcHRpb24xJykgfSxcclxuICAgIHVwZGF0ZVRleHQgOiBmdW5jdGlvbih0ZXh0KSB7IHVwZGF0ZVByb21wdEJ1dHRvbignb3B0aW9uMScsIHRleHQpIH0sXHJcbiAgICBhZGRBY3Rpb24gOiBmdW5jdGlvbihhY3Rpb25fZm4pIHsgYWRkUHJvbXB0QnV0dG9uQWN0aW9uKCdvcHRpb24xJywgYWN0aW9uX2ZuKSB9LFxyXG4gICAgcmVtb3ZlQWN0aW9uIDogZnVuY3Rpb24oYWN0aW9uX2ZuKSB7IHJlbW92ZVByb21wdEJ1dHRvbkFjdGlvbignb3B0aW9uMScsIGFjdGlvbl9mbikgfSxcclxuICAgIGRpc2FibGUgOiBmdW5jdGlvbigpIHsgZGlzYWJsZSgnb3B0aW9uMScpIH0sXHJcbiAgICBlbmFibGUgOiBmdW5jdGlvbigpIHsgZW5hYmxlKCdvcHRpb24xJykgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgUmlnaHQgPSB7XHJcbiAgICBzaG93IDogZnVuY3Rpb24oKSB7IHNob3dQcm9tcHRCdXR0b24oJ29wdGlvbjInKSB9LFxyXG4gICAgaGlkZSA6IGZ1bmN0aW9uKCkgeyBoaWRlUHJvbXB0QnV0dG9uKCdvcHRpb24yJykgfSxcclxuICAgIHVwZGF0ZVRleHQgOiBmdW5jdGlvbih0ZXh0KSB7IHVwZGF0ZVByb21wdEJ1dHRvbignb3B0aW9uMicsIHRleHQpIH0sXHJcbiAgICBhZGRBY3Rpb24gOiBmdW5jdGlvbihhY3Rpb25fZm4pIHsgYWRkUHJvbXB0QnV0dG9uQWN0aW9uKCdvcHRpb24yJywgYWN0aW9uX2ZuKSB9LFxyXG4gICAgcmVtb3ZlQWN0aW9uIDogZnVuY3Rpb24oYWN0aW9uX2ZuKSB7IHJlbW92ZVByb21wdEJ1dHRvbkFjdGlvbignb3B0aW9uMicsIGFjdGlvbl9mbikgfSxcclxuICAgIGRpc2FibGUgOiBmdW5jdGlvbigpIHsgZGlzYWJsZSgnb3B0aW9uMicpIH0sXHJcbiAgICBlbmFibGUgOiBmdW5jdGlvbigpIHsgZW5hYmxlKCdvcHRpb24yJykgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgQnV0dG9ucyA9IHtcclxuICAgIExlZnQgOiBMZWZ0LFxyXG4gICAgUmlnaHQgOiBSaWdodCxcclxuICAgIHNob3cgOiBmdW5jdGlvbigpIHtcclxuICAgICAgICBzaG93UHJvbXB0QnV0dG9uKCdvcHRpb24xJyk7XHJcbiAgICAgICAgc2hvd1Byb21wdEJ1dHRvbignb3B0aW9uMicpO1xyXG4gICAgfSxcclxuICAgIGhpZGUgOiBmdW5jdGlvbigpIHtcclxuICAgICAgICBoaWRlUHJvbXB0QnV0dG9uKCdvcHRpb24xJyk7XHJcbiAgICAgICAgaGlkZVByb21wdEJ1dHRvbignb3B0aW9uMicpO1xyXG4gICAgfSxcclxuICAgIHJlc2V0IDogdW5jbGlja0FsbFxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBCdXR0b25zOyIsImltcG9ydCAnLi9wcm9tcHQuY3NzJztcclxuXHJcbmltcG9ydCBUZXh0IGZyb20gXCIuL3N1YmNvbXBvbmVudHMvdGV4dC5qc1wiO1xyXG5pbXBvcnQgQnV0dG9ucyBmcm9tIFwiLi9zdWJjb21wb25lbnRzL2J1dHRvbnMuanNcIjtcclxuXHJcbmV4cG9ydCBjb25zdCBQcm9tcHQgPSB7XHJcbiAgICBUZXh0IDogVGV4dCxcclxuICAgIEJ1dHRvbnMgOiBCdXR0b25zLFxyXG4gICAgaGlkZSA6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgVGV4dC5oaWRlKCk7XHJcbiAgICAgICAgQnV0dG9ucy5oaWRlKCk7XHJcbiAgICB9LFxyXG4gICAgc2hvdyA6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgVGV4dC5zaG93KCk7XHJcbiAgICAgICAgQnV0dG9ucy5zaG93KCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFByb21wdCIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9zaWRlYmFyLmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xub3B0aW9ucy5pbnNlcnQgPSBpbnNlcnRGbi5iaW5kKG51bGwsIFwiaGVhZFwiKTtcbm9wdGlvbnMuZG9tQVBJID0gZG9tQVBJO1xub3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQgPSBpbnNlcnRTdHlsZUVsZW1lbnQ7XG5cbnZhciB1cGRhdGUgPSBBUEkoY29udGVudCwgb3B0aW9ucyk7XG5cblxuXG5leHBvcnQgKiBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3NpZGViYXIuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiLy8gU2V0IHRvIGVxdWFsIGN1cnJlbnQgZmlzY2FsIHllYXJcclxuZXhwb3J0IHZhciBGSVNDQUxfWUVBUiA9ICcyNic7XHJcblxyXG4vLyBvYmplY3QgY2F0ZWdvcmllcyAoZnJvbSBvYmogcGFydCBvZiBhY2NvdW50IHN0cmluZylcclxuZXhwb3J0IGNvbnN0IE9CSl9DQVRFR09SSUVTID0ge1xyXG4gICAgbGlzdCA6IFtcclxuICAgICAgICAvLyAnU2FsYXJpZXMgJiBXYWdlcycsXHJcbiAgICAgICAgLy8gJ0VtcGxveWVlIEJlbmVmaXRzJyxcclxuICAgICAgICAnUHJvZmVzc2lvbmFsICYgQ29udHJhY3R1YWwgU2VydmljZXMnLFxyXG4gICAgICAgICdPcGVyYXRpbmcgU3VwcGxpZXMnLFxyXG4gICAgICAgICdPcGVyYXRpbmcgU2VydmljZXMnLFxyXG4gICAgICAgICdFcXVpcG1lbnQgQWNxdWlzaXRpb24nLFxyXG4gICAgICAgICdDYXBpdGFsIE91dGxheXMnLFxyXG4gICAgICAgICdGaXhlZCBDaGFyZ2VzJyxcclxuICAgICAgICAnT3RoZXIgRXhwZW5zZXMnXHJcbiAgICBdXHJcbn1cclxuXHJcbi8vIGZyb20gdGhlIGRyb3AtZG93biBtZW51XHJcbmV4cG9ydCBjb25zdCBFTVBMT1lFRV9UWVBFUyA9IFtcclxuICAgICdSZWd1bGFyJyxcclxuICAgICdUQVNTJyxcclxuICAgICdTZWFzb25hbCcsXHJcbiAgICAnVW5pZm9ybSBGaXJlJyxcclxuICAgICdVbmlmb3JtIFBvbGljZScsXHJcbiAgICAnQXBwb2ludGVkJyxcclxuICAgICdFbGVjdGVkJyxcclxuICAgICdMb25nIFRlcm0gRGlzYWJpbGl0eSdcclxuXVxyXG5cclxuZXhwb3J0IGNvbnN0IE9UX09CSkVDVFMgPSBbXHJcbiAgICAnNjAxMzAwIC0gU2FsYXItT3ZlcnRpbWUtR2VuIENpdHknLCBcclxuICAgICc2MDEzMDUgLSBTYWxhcmllcy1PdmVydGltZS1Qb2xpY2UgVW5pZicsXHJcbiAgICAnNjAxMzEwIC0gU2FsYXJpZXMtT3ZlcnRpbWUtRmlyZSBVbmlmJyxcclxuICAgICc2MDIzMDAgLSBXYWdlcy1PdmVydGltZS1HZW4gQ2l0eSdcclxuXSIsImltcG9ydCB7IEZJU0NBTF9ZRUFSIH0gZnJvbSBcIi4vYnVkZ2V0X2NvbnN0YW50c1wiO1xyXG5cclxuLy8gc2hlZXRzIHRvIGV4cGVjdCBvbiBkZXRhaWwgc2hlZXRcclxuZXhwb3J0IGNvbnN0IFNIRUVUUyA9IHtcclxuICAgICdGVEUsIFNhbGFyeS1XYWdlLCAmIEJlbmVmaXRzJyA6ICdwZXJzb25uZWwnICxcclxuICAgICdPdmVydGltZSAmIE90aGVyIFBlcnNvbm5lbCcgOiAnb3ZlcnRpbWUnLFxyXG4gICAgJ05vbi1QZXJzb25uZWwnIDogJ25vbnBlcnNvbm5lbCcsXHJcbiAgICAnUmV2ZW51ZScgOiAncmV2ZW51ZSdcclxufVxyXG5cclxuLy8gd2hlcmUgdG8gZmluZCB0aGUgZ2VuZXJhbCBmdW5kIHRhcmdldFxyXG5leHBvcnQgY29uc3QgVEFSR0VUX0NFTExfQUREUkVTUyA9ICdDMTQnXHJcblxyXG5leHBvcnQgY29uc3QgVE9UQUxfQ09MVU1OUyA9IHtcclxuICAgICdwZXJzb25uZWwnOiAnVG90YWwgU2FsL1dhZyAmIEJlbiBSZXF1ZXN0JyxcclxuICAgICdvdmVydGltZSc6YEZZJHtGSVNDQUxfWUVBUn0gVG90YWwgT1QvU1AvSG9sICsgRklDQSBSZXF1ZXN0YCxcclxuICAgICdub25wZXJzb25uZWwnOiBgRlkke0ZJU0NBTF9ZRUFSfSBEZXBhcnRtZW50YWwgUmVxdWVzdCBUb3RhbGAsXHJcbiAgICAncmV2ZW51ZSc6IGBGWSR7RklTQ0FMX1lFQVJ9IERlcGFydG1lbnRhbCBFc3RpbWF0ZWBcclxufTtcclxuIiwiZXhwb3J0ICogZnJvbSAnLi9idWRnZXRfY29uc3RhbnRzJztcclxuZXhwb3J0ICogZnJvbSAnLi9leGNlbF9jb25zdGFudHMnOyIsIi8vIEZ1bmN0aW9uIHRvIGZvcm1hdCBudW1iZXIgYXMgY3VycmVuY3lcclxuZXhwb3J0IGNvbnN0IGZvcm1hdEN1cnJlbmN5ID0gKGFtb3VudCwgcmV0dXJuX3plcm8gPSBmYWxzZSkgPT4ge1xyXG4gICAgdmFyIGFtb3VudCA9IE1hdGgucm91bmQocGFyc2VGbG9hdChhbW91bnQpKTtcclxuICAgIGlmIChhbW91bnQgPT0gTmFOKXtcclxuICAgICAgICByZXR1cm4gXCIkIC1cIlxyXG4gICAgfVxyXG4gICAgaWYgKGFtb3VudCA8IDApe1xyXG4gICAgICAgIHJldHVybiAnKCQnICsgYW1vdW50LnRvU3RyaW5nKCkucmVwbGFjZSgvXFxCKD89KFxcZHszfSkrKD8hXFxkKSkvZywgJywnKSArICcpJztcclxuICAgIH0gZWxzZSBpZiAoYW1vdW50ID09IDApIHtcclxuICAgICAgICBpZiAocmV0dXJuX3plcm8pe1xyXG4gICAgICAgICAgICByZXR1cm4gJyQwJzsgICAgXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBcIiQgLVwiXHJcbiAgICB9XHJcbiAgICByZXR1cm4gJyQnICsgYW1vdW50LnRvU3RyaW5nKCkucmVwbGFjZSgvXFxCKD89KFxcZHszfSkrKD8hXFxkKSkvZywgJywnKTtcclxufSA7XHJcblxyXG4vLyBmdW5jdGlvbiB0byBjb252ZXJ0IGZvcm1hdHRlZCBudW1iZXIgdG8gYSBmbG9hdFxyXG5leHBvcnQgY29uc3QgdW5mb3JtYXRDdXJyZW5jeSA9IChmb3JtYXR0ZWRBbW91bnQpID0+IHtcclxuICAgIGlmICghZm9ybWF0dGVkQW1vdW50KSB7IHJldHVybiAwIH07XHJcbiAgICAvLyBSZW1vdmUgYW55IGN1cnJlbmN5IHN5bWJvbHMgYW5kIGNvbW1hc1xyXG4gICAgbGV0IG51bWVyaWNhbFBhcnQgPSBmb3JtYXR0ZWRBbW91bnQucmVwbGFjZSgvW14wLTkuLV0rL2csIFwiXCIpO1xyXG4gICAgaWYgKG51bWVyaWNhbFBhcnQgPT0gJy0nKXtcclxuICAgICAgICByZXR1cm4gMDtcclxuICAgIH1cclxuICAgIHJldHVybiBwYXJzZUZsb2F0KG51bWVyaWNhbFBhcnQpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRpc3BsYXlXaXRoQ29tbWFzKHZhbHVlKSB7XHJcbiAgICBpZiAodmFsdWUgPT0gMCl7XHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZm9ybWF0Q3VycmVuY3kodmFsdWUpLnJlcGxhY2UoJyQnLCAnJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjbGVhblN0cmluZyhzdHIpe1xyXG4gICAgcmV0dXJuIHN0ci50b0xvd2VyQ2FzZSgpLnJlcGxhY2VBbGwoJyAnLCAnLScpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlTmV3TGluZXMoc3RyKXtcclxuICAgIC8vIHJlcGxhY2UgYWxsIG5ldyBsaW5lcyB3aXRoIHNwYWNlc1xyXG4gICAgc3RyID0gc3RyLnJlcGxhY2VBbGwoL1tcXHJcXG5dKy9nLCBcIiBcIik7XHJcbiAgICAvLyByZW1vdmUgYW55IGV4dHJhIHNwYWNlcyBvciB0cmFpbGluZy9sZWFkaW5nIHdoaXRlc3BhY2VcclxuICAgIHN0ciA9IHN0ci5yZXBsYWNlQWxsKCcgICcsICcgJyk7XHJcbiAgICBzdHIgPSBzdHIucmVwbGFjZUFsbCgnICAnLCAnICcpO1xyXG4gICAgc3RyID0gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcclxuICAgIHJldHVybiBzdHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjb2xTdW0odGFibGUsIGNvbE5hbWUpIHtcclxuICAgIC8vIGZpbGwgd2l0aCB6ZXJvIHVudGlsIHRoZXJlIGlzIHNvbWV0aGluZyBzYXZlZCBpbiBzdG9yYWdlXHJcbiAgICBpZighdGFibGUgfHwgdGFibGUgPT0gJycpeyBcclxuICAgICAgICByZXR1cm4gMDsgXHJcbiAgICB9XHJcbiAgICBjb25zdCBoZWFkZXJzID0gT2JqZWN0LmtleXModGFibGVbMF0pO1xyXG4gICAgaWYgKGhlYWRlcnMuaW5jbHVkZXMoY29sTmFtZSkpIHtcclxuICAgICAgICBsZXQgc3VtID0gMDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRhYmxlLmxlbmd0aDsgaSsrKXtcclxuICAgICAgICAgICAgdmFyIHZhbHVlID0gTWF0aC5yb3VuZChwYXJzZUZsb2F0KHRhYmxlW2ldW2NvbE5hbWVdKSk7XHJcbiAgICAgICAgICAgIC8vIHRyZWF0IE5hTiAobm9uLW51bWVyaWNzKSBhcyB6ZXJvZXNcclxuICAgICAgICAgICAgaWYgKHZhbHVlKSB7IHN1bSArPSB2YWx1ZTsgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc3VtO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBjb25zb2xlLmVycm9yKGBDb3VsZCBub3QgZmluZCBleHBlY3RlZCB0b3RhbCBjb2x1bW4gaW4gc2F2ZWQgZGF0YSBmb3IgJHtuYW1lfS4gUmV0dXJuaW5nIDAuIFNlZSBTdG9yZWRUYWJsZS50b3RhbENvbCgpIHN3aXRjaC5gKTtcclxuICAgICAgICByZXR1cm4gMDtcclxuICAgIH1cclxuXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRVbmlxdWVWYWx1ZXMoZGF0YSwga2V5KSB7XHJcbiAgICBjb25zdCB2YWx1ZXMgPSBkYXRhLm1hcChvYmogPT4gb2JqW2tleV0pO1xyXG4gICAgcmV0dXJuIEFycmF5LmZyb20obmV3IFNldCh2YWx1ZXMpKTtcclxufVxyXG4iLCJpbXBvcnQgQ3VycmVudEZ1bmQgZnJvbSBcIi4vY3VycmVudF9mdW5kXCI7XHJcbmltcG9ydCB7IGdldFVuaXF1ZVZhbHVlcyB9IGZyb20gXCIuLi91dGlscy9jb21tb25fdXRpbHNcIjtcclxuXHJcbmV4cG9ydCBjb25zdCBGdW5kTG9va3VwVGFibGUgPSB7XHJcbiAgICByZXRyaWV2ZSA6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdmdW5kLWxvb2t1cC10YWJsZScpKSB8fCB7fTtcclxuICAgIH0sXHJcbiAgICBzYXZlIDogZnVuY3Rpb24oZnVuZERpY3Qpe1xyXG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdmdW5kLWxvb2t1cC10YWJsZScsIEpTT04uc3RyaW5naWZ5KGZ1bmREaWN0KSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHVwZGF0ZSA6IGZ1bmN0aW9uKGZ1bmREYXRhKXtcclxuICAgICAgICAvLyByZXNldFxyXG4gICAgICAgIHRoaXMucmVzZXQoKTtcclxuICAgICAgICAvLyBmaWxsIGluIHdpdGggZGF0YSBzdG9yZWQgaW4gZnVuZERhdGVcclxuICAgICAgICBjb25zdCB0YWJsZSA9IHRoaXMucmV0cmlldmUoKTtcclxuICAgICAgICBmb3IgKGxldCBmdW5kIG9mIE9iamVjdC5rZXlzKGZ1bmREYXRhKSl7XHJcblxyXG4gICAgICAgICAgICAvLyBhZGQgdG8gbG9va3VwIHRhYmxlIGlmIG5vdCBpbiB0aGVyZSBhbHJlYWR5XHJcbiAgICAgICAgICAgIGlmICghdGFibGVbZnVuZF0pe1xyXG4gICAgICAgICAgICAgICAgLy8gZ2V0IGZ1bmQgbmFtZVxyXG4gICAgICAgICAgICAgICAgY29uc3QgZnVuZE5hbWUgPSBmdW5kRGF0YVtmdW5kXVswXVsnRnVuZCBOYW1lJ107XHJcbiAgICAgICAgICAgICAgICAvLyBhZGQgZnVuZCB0byBkaWN0aW9uYXJ5XHJcbiAgICAgICAgICAgICAgICB0YWJsZVtmdW5kXSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdGFibGVbZnVuZF1bJ25hbWUnXSA9IGZ1bmROYW1lO1xyXG4gICAgICAgICAgICAgICAgdGFibGVbZnVuZF1bJ3ZpZXdlZCddID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAvLyBidWlsZCBsaXN0cyBvZiB1bmlxdWUgY29zdCBjZW50ZXJzIGFuZCBhcHByb3ByaWF0aW9uc1xyXG4gICAgICAgICAgICAgICAgdGFibGVbZnVuZF1bJ2FwcHJvcCddID0gZ2V0VW5pcXVlVmFsdWVzKGZ1bmREYXRhW2Z1bmRdLCAnQXBwcm9wcmlhdGlvbiBOYW1lJyk7XHJcbiAgICAgICAgICAgICAgICB0YWJsZVtmdW5kXVsnY2MnXSA9IGdldFVuaXF1ZVZhbHVlcyhmdW5kRGF0YVtmdW5kXSwgJ0Nvc3QgQ2VudGVyIE5hbWUnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBzYXZlIGFueSB1cGRhdGVzXHJcbiAgICAgICAgdGhpcy5zYXZlKHRhYmxlKTtcclxuICAgIH0sXHJcblxyXG4gICAgZ2V0QWxsOiBmdW5jdGlvbihrZXkpIHtcclxuICAgICAgICAvLyBmdW5jdGlvbiB0byBhZ2dyZWdhdGUgYWxsIGFwcHJvcHMgb3IgQ0NzIGZvciBldmVyeSBmdW5kIGluIG9uZSBhcnJheVxyXG4gICAgICAgIGNvbnN0IGZ1bmRzID0gdGhpcy5yZXRyaWV2ZSgpO1xyXG4gICAgICAgIGNvbnN0IHJldCA9IFtdO1xyXG4gICAgICAgIGZvciAoY29uc3QgZnVuZCBpbiBmdW5kcykge1xyXG4gICAgICAgICAgICBpZiAoZnVuZHMuaGFzT3duUHJvcGVydHkoZnVuZCkpIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgaW4gZnVuZHNbZnVuZF1ba2V5XSl7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0LnB1c2goZnVuZHNbZnVuZF1ba2V5XVtpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJldDtcclxuICAgIH0sXHJcblxyXG4gICAgZ2V0Q29zdENlbnRlcnMgOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAvLyBnZXQgY3VycmVudCBmdW5kXHJcbiAgICAgICAgY29uc3QgZnVuZCA9IEN1cnJlbnRGdW5kLm51bWJlcigpXHJcbiAgICAgICAgaWYgKHRoaXMucmV0cmlldmUoKVtmdW5kXSl7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJldHJpZXZlKClbZnVuZF1bJ2NjJ107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIG5vIGZ1bmQgKGllLiB3ZSdyZSBvbiB0aGUgbmV3IGluaXRpYXRpdmUgcGFnZSksIHJldHVybiBhbGwgb3B0aW9uc1xyXG4gICAgICAgIHJldHVybiB0aGlzLmdldEFsbCgnY2MnKTtcclxuICAgIH0sXHJcblxyXG4gICAgZ2V0QXBwcm9wcyA6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIC8vIGdldCBjdXJyZW50IGZ1bmRcclxuICAgICAgICBjb25zdCBmdW5kID0gQ3VycmVudEZ1bmQubnVtYmVyKClcclxuICAgICAgICBpZiAodGhpcy5yZXRyaWV2ZSgpW2Z1bmRdKXtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmV0cmlldmUoKVtmdW5kXVsnYXBwcm9wJ107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIG5vIGZ1bmQgKGllLiB3ZSdyZSBvbiB0aGUgbmV3IGluaXRpYXRpdmUgcGFnZSksIHJldHVybiBhbGwgb3B0aW9uc1xyXG4gICAgICAgIHJldHVybiB0aGlzLmdldEFsbCgnYXBwcm9wJyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlc2V0IDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdGhpcy5zYXZlKHt9KTtcclxuICAgIH0sXHJcbiAgICBnZXROYW1lIDogZnVuY3Rpb24obnVtYmVyKXtcclxuICAgICAgICBpZighbnVtYmVyIHx8ICF0aGlzLnJldHJpZXZlKCkpIHsgcmV0dXJuICcnIH07XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmV0cmlldmUoKVtudW1iZXJdWyduYW1lJ107XHJcbiAgICB9LFxyXG4gICAgbGlzdEZ1bmRzIDogZnVuY3Rpb24oKXtcclxuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5yZXRyaWV2ZSgpKTtcclxuICAgIH0sXHJcbiAgICBsaXN0RnVuZE5hbWVzIDogZnVuY3Rpb24oKXtcclxuICAgICAgICBjb25zdCBmdW5kcyA9IHRoaXMucmV0cmlldmUoKTtcclxuICAgICAgICAvLyBpbml0aWFsaXplIGFycmF5XHJcbiAgICAgICAgdmFyIHJldCA9IFtdO1xyXG4gICAgICAgIE9iamVjdC5rZXlzKGZ1bmRzKS5mb3JFYWNoKCAoZnVuZF9udW1iZXIpID0+IHtcclxuICAgICAgICAgICAgdmFyIGZ1bmRfbmFtZSA9IGZ1bmRzW2Z1bmRfbnVtYmVyXVsnbmFtZSddO1xyXG4gICAgICAgICAgICByZXQucHVzaChmdW5kX25hbWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiByZXQ7XHJcbiAgICB9LFxyXG4gICAgZWRpdEZ1bmQgOiBmdW5jdGlvbihmdW5kKXtcclxuICAgICAgICBjb25zdCB0YWJsZSA9IHRoaXMucmV0cmlldmUoKTtcclxuICAgICAgICBpZiAodGFibGVbZnVuZF0pe1xyXG4gICAgICAgICAgICB0YWJsZVtmdW5kXVsndmlld2VkJ10gPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLnNhdmUodGFibGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ05vIGZ1bmQgc2VsZWN0ZWQuJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgfSxcclxuICAgIGxpc3RVbmVkaXRlZEZ1bmRzIDogZnVuY3Rpb24oKXtcclxuICAgICAgICBjb25zdCB0YWJsZSA9IHRoaXMucmV0cmlldmUoKTtcclxuICAgICAgICBjb25zdCByZXQgPSBbXTtcclxuICAgICAgICB0aGlzLmxpc3RGdW5kcygpLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICAgICAgaWYgKCF0YWJsZVtrZXldWyd2aWV3ZWQnXSl7XHJcbiAgICAgICAgICAgICAgICByZXQucHVzaChrZXkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHJldDtcclxuICAgIH0sXHJcbiAgICBmdW5kc0xlZnQgOiBmdW5jdGlvbigpe1xyXG4gICAgICAgIHJldHVybiAodGhpcy5saXN0VW5lZGl0ZWRGdW5kcygpLmxlbmd0aCA+IDApO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBGdW5kTG9va3VwVGFibGUiLCJcclxuaW1wb3J0IEZ1bmRMb29rdXBUYWJsZSBmcm9tIFwiLi9mdW5kX2xvb2t1cF90YWJsZVwiO1xyXG5cclxuZXhwb3J0IGNvbnN0IEN1cnJlbnRGdW5kID0ge1xyXG4gICAgdXBkYXRlIDogZnVuY3Rpb24oZnVuZCl7XHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2Z1bmQnLCBmdW5kKTtcclxuICAgIH0sXHJcbiAgICBudW1iZXIgOiBmdW5jdGlvbigpe1xyXG4gICAgICAgIHJldHVybiBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShcImZ1bmRcIik7XHJcbiAgICB9LFxyXG4gICAgbmFtZSA6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgcmV0dXJuIEZ1bmRMb29rdXBUYWJsZS5nZXROYW1lKCB0aGlzLm51bWJlcigpKTtcclxuICAgIH0sXHJcbiAgICByZXNldCA6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHRoaXMudXBkYXRlKCcnKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ3VycmVudEZ1bmQ7IiwiaW1wb3J0IEN1cnJlbnRGdW5kIGZyb20gXCIuL2N1cnJlbnRfZnVuZFwiO1xyXG5cclxuZXhwb3J0IGNvbnN0IEFjY291bnRTdHJpbmcgPSB7XHJcbiAgICBnZXROdW1iZXI6IGZ1bmN0aW9uKGlucHV0KSB7XHJcbiAgICAgICAgLy8gaXNvbGF0ZSB0aGUgbnVtZXJpY2FsIHBhcnQgb2YgYSBhcHByb3ByaWF0aW9uL2Nvc3QgY2VudGVyL29iamVjdFxyXG4gICAgICAgIGNvbnN0IG1hdGNoID0gaW5wdXQubWF0Y2goL15cXGQrLyk7XHJcbiAgICAgICAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMF0gOiBudWxsO1xyXG4gICAgfSxcclxuXHJcbiAgICBidWlsZCA6IGZ1bmN0aW9uKGFwcHJvcCwgY2MsIG9iaiA9IG51bGwsIGZ1bmQgPSBudWxsKSB7XHJcbiAgICAgICAgLy8gcHV0IHRvZ2V0aGVyIGFjY291bnQgc3RyaW5nIGZ1bmQtYXBwcm9wLWNvc3RjZW50ZXJbLW9ial0gKHcgb3B0aW9uYWwgb2JqZWN0KVxyXG4gICAgICAgIGlmICghZnVuZCkgeyBmdW5kID0gQ3VycmVudEZ1bmQubnVtYmVyKCkgfTtcclxuICAgICAgICAvLyBoaXRzIGVycm9yIGhlcmVcclxuICAgICAgICBhcHByb3AgPSB0aGlzLmdldE51bWJlcihhcHByb3ApO1xyXG4gICAgICAgIGNjID0gdGhpcy5nZXROdW1iZXIoY2MpO1xyXG4gICAgICAgIHZhciBzdHJpbmcgPSBgJHtmdW5kfS0ke2FwcHJvcH0tJHtjY31gO1xyXG4gICAgICAgIHN0cmluZyA9IG9iaiA/IGAke3N0cmluZ30tJHt0aGlzLmdldE51bWJlcihvYmopfWAgOiBzdHJpbmc7XHJcbiAgICAgICAgcmV0dXJuIHN0cmluZztcclxuICAgIH0sXHJcblxyXG4gICAgZ2V0QWNjb3VudFN0cmluZ1NlY3Rpb24gOiBmdW5jdGlvbihhY2NvdW50X3N0cmluZywgc2VjdGlvbikge1xyXG4gICAgICAgIGNvbnN0IHNlY3Rpb25zID0gYWNjb3VudF9zdHJpbmcuc3BsaXQoXCItXCIpO1xyXG4gICAgICAgIHJldHVybiBzZWN0aW9ucy5sZW5ndGggPiBzZWN0aW9uID8gc2VjdGlvbnNbc2VjdGlvbl0gOiBudWxsO1xyXG4gICAgfSxcclxuXHJcbiAgICBmdW5kIDogZnVuY3Rpb24oYWNjb3VudF9zdHJpbmcpIHsgXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QWNjb3VudFN0cmluZ1NlY3Rpb24oYWNjb3VudF9zdHJpbmcsIDApIFxyXG4gICAgfSxcclxuXHJcbiAgICBhcHByb3AgOiBmdW5jdGlvbihhY2NvdW50X3N0cmluZykgeyBcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRBY2NvdW50U3RyaW5nU2VjdGlvbihhY2NvdW50X3N0cmluZywgMSkgXHJcbiAgICB9LFxyXG5cclxuICAgIGNvc3RDZW50ZXIgOiBmdW5jdGlvbihhY2NvdW50X3N0cmluZykgeyBcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRBY2NvdW50U3RyaW5nU2VjdGlvbihhY2NvdW50X3N0cmluZywgMikgXHJcbiAgICB9LFxyXG5cclxuICAgIG9iamVjdCA6IGZ1bmN0aW9uKGFjY291bnRfc3RyaW5nKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QWNjb3VudFN0cmluZ1NlY3Rpb24oYWNjb3VudF9zdHJpbmcsIDMpIFxyXG4gICAgfSxcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgQWNjb3VudFN0cmluZzsiLCJcclxuaW1wb3J0IHsgY29sU3VtIH0gZnJvbSBcIi4uL3V0aWxzL2NvbW1vbl91dGlsc1wiO1xyXG5pbXBvcnQgeyBUT1RBTF9DT0xVTU5TIH0gZnJvbSAnLi4vY29uc3RhbnRzLyc7XHJcblxyXG4vLyBIZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEgdW5pcXVlIGxpc3Qgb2YgYXBwcm9wcmlhdGlvbnMgcmVwcmVzZW50ZWQgaW4gYSB0YWJsZVxyXG5mdW5jdGlvbiBmZXRjaFZhbHVlU2V0KHRhYmxlLCBrZXkpIHtcclxuXHJcbiAgICAvLyBJRiB0aGVyZSdzIG5vIGRhdGEsIHJldHVybiBhbiBlbXB0eSBsaXN0XHJcbiAgICBpZighdGFibGUpe1xyXG4gICAgICAgIHJldHVybiBbXTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBVc2UgYSBTZXQgdG8gc3RvcmUgdW5pcXVlIHZhbHVlc1xyXG4gICAgY29uc3QgdW5pcVZhbHVlcyA9IG5ldyBTZXQoKTtcclxuICBcclxuICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBlYWNoIG9iamVjdCBpbiB0aGUgdGFibGVcclxuICAgIHRhYmxlLmZvckVhY2gocm93ID0+IHtcclxuICAgICAgaWYgKHJvd1trZXldKSB7XHJcbiAgICAgICAgdW5pcVZhbHVlcy5hZGQocm93W2tleV0pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICBcclxuICAgIC8vIENvbnZlcnQgdGhlIFNldCB0byBhbiBhcnJheSBpZiBuZWVkZWRcclxuICAgIHJldHVybiB1bmlxVmFsdWVzO1xyXG4gIH1cclxuXHJcbi8vIENsYXNzIHRvIGhvbGQgaW5mb3JtYXRpb24gb24gYSBzcGVjaWZpYyBmdW5kIGFuZCB0YWJsZVxyXG5jbGFzcyBTdG9yZWRUYWJsZSB7XHJcbiAgICBjb25zdHJ1Y3RvcihwYWdlLCBmdW5kKXtcclxuICAgICAgICB0aGlzLm5hbWUgPSBgJHtwYWdlfV8ke2Z1bmR9YDtcclxuICAgICAgICB0aGlzLnBhZ2UgPSBwYWdlO1xyXG4gICAgICAgIHRoaXMudGFibGUgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMubmFtZSkpO1xyXG4gICAgICAgIHRoaXMuYXBwcm9wcyA9IGZldGNoVmFsdWVTZXQodGhpcy50YWJsZSwgJ0FwcHJvcHJpYXRpb24nKTtcclxuICAgICAgICB0aGlzLmNjID0gZmV0Y2hWYWx1ZVNldCh0aGlzLnRhYmxlLCAnQ29zdCBDZW50ZXInKTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgdG90YWxDb2woKSB7XHJcbiAgICAgICAgcmV0dXJuIFRPVEFMX0NPTFVNTlNbdGhpcy5wYWdlXTtcclxuICAgIH1cclxuICAgIGdldFN1bSgpIHtcclxuICAgICAgICAvLyBmaWxsIHdpdGggemVybyB1bnRpbCB0aGVyZSBpcyBzb21ldGhpbmcgc2F2ZWQgaW4gc3RvcmFnZVxyXG4gICAgICAgIHJldHVybiBjb2xTdW0odGhpcy50YWJsZSwgdGhpcy50b3RhbENvbCgpLCB0aGlzLm5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGtleSBpcyB0aGUgY29sdW1uIHRvIGZpbHRlciBvbiAoaWUuIENvc3QgQ2VudGVyKVxyXG4gICAgZmlsdGVyKGtleSwgdmFsdWUpIHtcclxuICAgICAgICBpZiAodGhpcy50YWJsZSl7XHJcbiAgICAgICAgICAgIC8vIHJlYXNzaWduIHVuZGVybHlpbmcgZGF0YSBpbiBvYmplY3QgaWYgdGhlcmUncyBkYXRhIHRvIGZpbHRlclxyXG4gICAgICAgICAgICB0aGlzLnRhYmxlID0gdGhpcy50YWJsZS5maWx0ZXIocm93ID0+IHsgICBcclxuICAgICAgICAgICAgICAgIHJldHVybiAocm93W2tleV0pICYmIChyb3dba2V5XSA9PSB2YWx1ZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBDb3N0Q2VudGVye1xyXG4gICAgY29uc3RydWN0b3IoZnVuZCwgYXBwcm9wLCBjYyl7XHJcbiAgICAgICAgY29uc3QgQXBwcm9wT2JqID0gbmV3IEFwcHJvcHJpYXRpb24oZnVuZCwgYXBwcm9wKTtcclxuICAgICAgICB0aGlzLnBlcnNvbm5lbCA9IEFwcHJvcE9iai5wZXJzb25uZWwuZmlsdGVyKCdDb3N0IENlbnRlcicsIGNjKTtcclxuICAgICAgICB0aGlzLm5vbnBlcnNvbm5lbCA9IEFwcHJvcE9iai5ub25wZXJzb25uZWwuZmlsdGVyKCdDb3N0IENlbnRlcicsIGNjKTtcclxuICAgICAgICB0aGlzLm92ZXJ0aW1lID0gQXBwcm9wT2JqLm92ZXJ0aW1lLmZpbHRlcignQ29zdCBDZW50ZXInLCBjYyk7XHJcbiAgICAgICAgdGhpcy5yZXZlbnVlID0gQXBwcm9wT2JqLnJldmVudWUuZmlsdGVyKCdDb3N0IENlbnRlcicsIGNjKTtcclxuICAgICAgICB0aGlzLmNjID0gY2M7XHJcbiAgICAgICAgdGhpcy5hY2NvdW50X3N0cmluZyA9IGAke0FwcHJvcE9iai5hY2NvdW50U3RyaW5nKCl9LSR7Y2N9YDtcclxuICAgIH1cclxuXHJcbiAgICBnZXRQZXJzb25uZWxDb3N0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnBlcnNvbm5lbC5nZXRTdW0oKTsgXHJcbiAgICB9XHJcblxyXG4gICAgZ2V0T3ZlcnRpbWVDb3N0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm92ZXJ0aW1lLmdldFN1bSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldE5vblBlcnNvbm5lbENvc3QoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubm9ucGVyc29ubmVsLmdldFN1bSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFJldmVudWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmV2ZW51ZS5nZXRTdW0oKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRUb3RhbCgpIHsgXHJcbiAgICAgICAgLy8gb25seSBzdW0gZXhwZW5kaXR1cmVzLCBub3QgbmV0IG9mIHJldmVudWVcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXROb25QZXJzb25uZWxDb3N0KCkgKyB0aGlzLmdldE92ZXJ0aW1lQ29zdCgpICsgdGhpcy5nZXRQZXJzb25uZWxDb3N0KCk7IFxyXG4gICAgfVxyXG5cclxuICAgIGdldE5hbWUoKSB7XHJcbiAgICAgICAgLy8ganVzdCBncmFiIHRoZSB2YWx1ZSBpbiB0aGUgY29zdCBjZW50ZXIgbmFtZSBjb2x1bW4gZm9yIHRoZSBmaXJzdCByb3dcclxuICAgICAgICBpZiAoIXRoaXMubm9ucGVyc29ubmVsLnRhYmxlWzBdKSB7IHJldHVybiAnJyB9O1xyXG4gICAgICAgIHJldHVybiAnQ29zdCBDZW50ZXIgJyArIHRoaXMubm9ucGVyc29ubmVsLnRhYmxlWzBdWydDb3N0IENlbnRlciBOYW1lJ107XHJcbiAgICB9XHJcblxyXG4gICAgYWNjb3VudFN0cmluZygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5hY2NvdW50X3N0cmluZztcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIEFwcHJvcHJpYXRpb24ge1xyXG4gICAgY29uc3RydWN0b3IoZnVuZCwgYXBwcm9wKXtcclxuICAgICAgICBjb25zdCBmdW5kT2JqID0gbmV3IEZ1bmQoZnVuZCk7XHJcbiAgICAgICAgdGhpcy5wZXJzb25uZWwgPSBmdW5kT2JqLnBlcnNvbm5lbC5maWx0ZXIoJ0FwcHJvcHJpYXRpb24nLCBhcHByb3ApO1xyXG4gICAgICAgIHRoaXMubm9ucGVyc29ubmVsID0gZnVuZE9iai5ub25wZXJzb25uZWwuZmlsdGVyKCdBcHByb3ByaWF0aW9uJywgYXBwcm9wKTtcclxuICAgICAgICB0aGlzLm92ZXJ0aW1lID0gZnVuZE9iai5vdmVydGltZS5maWx0ZXIoJ0FwcHJvcHJpYXRpb24nLCBhcHByb3ApO1xyXG4gICAgICAgIHRoaXMucmV2ZW51ZSA9IGZ1bmRPYmoucmV2ZW51ZS5maWx0ZXIoJ0FwcHJvcHJpYXRpb24nLCBhcHByb3ApO1xyXG4gICAgICAgIC8vIG93biBkYXRhXHJcbiAgICAgICAgdGhpcy5hcHByb3AgPSBhcHByb3A7XHJcbiAgICAgICAgdGhpcy5mdW5kID0gZnVuZE9iai5mdW5kO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBnZXRDb3N0Q2VudGVycygpe1xyXG4gICAgICAgIC8vIGJ1aWxkIGEgc2V0IG9mIHVuaXF1ZSBhcHByb3ByaWF0aW9ucyBhY3Jvc3MgYWxsIGxpbmUgaXRlbXMgZm9yIHRoZSBmdW5kXHJcbiAgICAgICAgY29uc3QgY2MgPSBuZXcgU2V0KFsuLi50aGlzLnBlcnNvbm5lbC5jYyxcclxuICAgICAgICAgICAgLi4udGhpcy5vdmVydGltZS5jYywgXHJcbiAgICAgICAgICAgIC4uLnRoaXMubm9ucGVyc29ubmVsLmNjLCBcclxuICAgICAgICAgICAgLi4udGhpcy5yZXZlbnVlLmNjXSk7XHJcblxyXG4gICAgICAgIC8vIGluaXRpYWxpemUgYSBsaXN0IHBsYWNlaG9sZGVyIGZvciB0aGUgYXBwcm9wcmlhdGlvbnMgb2JqZWN0c1xyXG4gICAgICAgIGNvbnN0IGNjTGlzdCA9IFtdO1xyXG4gICAgICAgIC8vIGJ1aWxkIG91dCBsaXN0XHJcbiAgICAgICAgY2MuZm9yRWFjaChudW0gPT4ge1xyXG4gICAgICAgICAgICBjY0xpc3QucHVzaChuZXcgQ29zdENlbnRlcih0aGlzLmZ1bmQsIHRoaXMuYXBwcm9wLCBudW0pKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gY2NMaXN0O1xyXG4gICAgfVxyXG5cclxuICAgIHRvdGFsKCl7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucGVyc29ubmVsLmdldFN1bSgpICsgdGhpcy5vdmVydGltZS5nZXRTdW0oKSArIHRoaXMubm9ucGVyc29ubmVsLmdldFN1bSgpO1xyXG4gICAgfVxyXG5cclxuICAgIG5hbWUoKXtcclxuICAgICAgICAvLyBqdXN0IGdyYWIgdGhlIHZhbHVlIGluIHRoZSBhcHByb3AgbmFtZSBjb2x1bW4gZm9yIHRoZSBmaXJzdCByb3dcclxuICAgICAgICBpZiAoIXRoaXMubm9ucGVyc29ubmVsLnRhYmxlWzBdKSB7IHJldHVybiAnJyB9O1xyXG4gICAgICAgIHJldHVybiAnQXBwcm9wcmlhdGlvbiAnICsgdGhpcy5ub25wZXJzb25uZWwudGFibGVbMF1bJ0FwcHJvcHJpYXRpb24gTmFtZSddOyAgICB9XHJcblxyXG4gICAgYWNjb3VudFN0cmluZygpe1xyXG4gICAgICAgIHJldHVybiBgJHt0aGlzLmZ1bmR9LSR7dGhpcy5hcHByb3B9YDtcclxuICAgIH1cclxuXHJcbn1cclxuXHJcbi8vIEhvbGRzIGFsbCB0aGUgZGV0YWlsZWQgZGF0YSBmb3Igb25lIGZ1bmQncyBidWRnZXRcclxuZXhwb3J0IGNsYXNzIEZ1bmQge1xyXG4gICAgY29uc3RydWN0b3IoZnVuZCl7XHJcbiAgICAgICAgdGhpcy5mdW5kID0gZnVuZDtcclxuICAgICAgICB0aGlzLnBlcnNvbm5lbCA9IG5ldyBTdG9yZWRUYWJsZSgncGVyc29ubmVsJywgZnVuZCk7XHJcbiAgICAgICAgdGhpcy5vdmVydGltZSA9IG5ldyBTdG9yZWRUYWJsZSgnb3ZlcnRpbWUnLCBmdW5kKTtcclxuICAgICAgICB0aGlzLm5vbnBlcnNvbm5lbCA9IG5ldyBTdG9yZWRUYWJsZSgnbm9ucGVyc29ubmVsJywgZnVuZCk7XHJcbiAgICAgICAgdGhpcy5yZXZlbnVlID0gbmV3IFN0b3JlZFRhYmxlKCdyZXZlbnVlJywgZnVuZCk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0QXBwcm9wcmlhdGlvbnMoKXtcclxuICAgICAgICAvLyBidWlsZCBhIHNldCBvZiB1bmlxdWUgYXBwcm9wcmlhdGlvbnMgYWNyb3NzIGFsbCBsaW5lIGl0ZW1zIGZvciB0aGUgZnVuZFxyXG4gICAgICAgIGNvbnN0IGFwcHJvcHMgPSBuZXcgU2V0KFsuLi50aGlzLnBlcnNvbm5lbC5hcHByb3BzLFxyXG4gICAgICAgICAgICAuLi50aGlzLm92ZXJ0aW1lLmFwcHJvcHMsIFxyXG4gICAgICAgICAgICAuLi50aGlzLm5vbnBlcnNvbm5lbC5hcHByb3BzLCBcclxuICAgICAgICAgICAgLi4udGhpcy5yZXZlbnVlLmFwcHJvcHNdKTtcclxuXHJcbiAgICAgICAgLy8gaW5pdGlhbGl6ZSBhIGxpc3QgcGxhY2Vob2xkZXIgZm9yIHRoZSBhcHByb3ByaWF0aW9ucyBvYmplY3RzXHJcbiAgICAgICAgY29uc3QgYXBwcm9wc0xpc3QgPSBbXTtcclxuICAgICAgICAvLyBidWlsZCBvdXQgbGlzdFxyXG4gICAgICAgIGFwcHJvcHMuZm9yRWFjaChhcHByb3AgPT4ge1xyXG4gICAgICAgICAgICBhcHByb3BzTGlzdC5wdXNoKCBuZXcgQXBwcm9wcmlhdGlvbih0aGlzLmZ1bmQsIGFwcHJvcCkgKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gYXBwcm9wc0xpc3Q7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0UGVyc29ubmVsQ29zdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wZXJzb25uZWwuZ2V0U3VtKCk7IFxyXG4gICAgfVxyXG5cclxuICAgIGdldE92ZXJ0aW1lQ29zdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5vdmVydGltZS5nZXRTdW0oKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXROb25QZXJzb25uZWxDb3N0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm5vbnBlcnNvbm5lbC5nZXRTdW0oKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRSZXZlbnVlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJldmVudWUuZ2V0U3VtKCk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0VG90YWwoKSB7IFxyXG4gICAgICAgIC8vIG9ubHkgc3VtIGV4cGVuZGl0dXJlcywgbm90IG5ldCBvZiByZXZlbnVlXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Tm9uUGVyc29ubmVsQ29zdCgpICsgdGhpcy5nZXRPdmVydGltZUNvc3QoKSArIHRoaXMuZ2V0UGVyc29ubmVsQ29zdCgpOyBcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgRnVuZDsiLCJpbXBvcnQgRnVuZCBmcm9tIFwiLi9mdW5kLmpzXCI7XHJcbmltcG9ydCBGdW5kTG9va3VwVGFibGUgZnJvbSBcIi4vZnVuZF9sb29rdXBfdGFibGUuanNcIjtcclxuXHJcblxyXG5leHBvcnQgY2xhc3MgQmFzZWxpbmUge1xyXG4gICAgLy8gYmFzZWxpbmUgd2lsbCBqdXN0IGNvbnRhaW4gYSBsaXN0IG9mIGZ1bmRzLCBlYWNoIHdpdGhcclxuICAgIC8vIHJ1bm5pbmcgdGFsbGllcyBmb3IgdGhlaXIgYnVkZ2V0c1xyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgY29uc3QgYWxsRnVuZHMgPSBGdW5kTG9va3VwVGFibGUubGlzdEZ1bmRzKCk7XHJcbiAgICAgICAgdGhpcy5mdW5kcyA9IFtdO1xyXG4gICAgICAgIGFsbEZ1bmRzLmZvckVhY2goKGZ1bmQpID0+IHsgXHJcbiAgICAgICAgICAgIHRoaXMuZnVuZHMucHVzaChuZXcgRnVuZChmdW5kKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9IFxyXG5cclxuICAgIHN0YXRpYyB0YXJnZXQoKSB7IHJldHVybiBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgndGFyZ2V0JykgfTtcclxuXHJcbiAgICBwZXJzb25uZWwoKSB7XHJcbiAgICAgICAgbGV0IHRvdGFsID0gMDtcclxuICAgICAgICB0aGlzLmZ1bmRzLmZvckVhY2goZnVuZCA9PiB7XHJcbiAgICAgICAgICAgIHRvdGFsICs9IGZ1bmQuZ2V0UGVyc29ubmVsQ29zdCgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0b3RhbDtcclxuICAgIH1cclxuXHJcbiAgICBvdmVydGltZSgpIHtcclxuICAgICAgICBsZXQgdG90YWwgPSAwO1xyXG4gICAgICAgIHRoaXMuZnVuZHMuZm9yRWFjaChmdW5kID0+IHtcclxuICAgICAgICAgICAgdG90YWwgKz0gZnVuZC5nZXRPdmVydGluZUNvc3QoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdG90YWw7XHJcbiAgICB9XHJcblxyXG4gICAgbm9ucGVyc29ubmVsKCkge1xyXG4gICAgICAgIGxldCB0b3RhbCA9IDA7XHJcbiAgICAgICAgdGhpcy5mdW5kcy5mb3JFYWNoKGZ1bmQgPT4ge1xyXG4gICAgICAgICAgICB0b3RhbCArPSBmdW5kLmdldE5vblBlcnNvbm5lbENvc3QoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdG90YWw7XHJcbiAgICB9XHJcblxyXG4gICAgcmV2ZW51ZSgpIHtcclxuICAgICAgICBsZXQgdG90YWwgPSAwO1xyXG4gICAgICAgIHRoaXMuZnVuZHMuZm9yRWFjaChmdW5kID0+IHtcclxuICAgICAgICAgICAgdG90YWwgKz0gZnVuZC5nZXRSZXZlbnVlKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRvdGFsO1xyXG4gICAgfVxyXG5cclxuICAgIHRvdGFsKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm5vbnBlcnNvbm5lbCgpICsgdGhpcy5wZXJzb25uZWwoKTsgLy8gKyB0aGlzLm92ZXJ0aW1lKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEJhc2VsaW5lOyIsIi8vIGRhdGEgc3RydWN0dXJlIHRvIHNhdmUgdGhlIHBvc3NpYmxlIHNlcnZpY2Ugb3B0aW9ucyBmb3IgdGhlIGRlcGFydG1lbnRcclxuZXhwb3J0IGNvbnN0IFNlcnZpY2VzID0ge1xyXG4gICAgc2F2ZSA6IGZ1bmN0aW9uKHNlcnZpY2VzKXtcclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnc2VydmljZXMtbGlzdCcsIEpTT04uc3RyaW5naWZ5KHNlcnZpY2VzKSk7XHJcbiAgICB9LFxyXG4gICAgbGlzdCA6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3NlcnZpY2VzLWxpc3QnKSkgfHwge307XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFNlcnZpY2VzOyIsIlxyXG4vLyBkYXRhIHN0cnVjdHVyZSB0byBob2xkIGluZm9ybWF0aW9uIG9uIG5ldyBpbml0aWF0aXZlc1xyXG5cclxuZXhwb3J0IGNsYXNzIEluaXRpYXRpdmUge1xyXG4gICAgXHJcbiAgICBjb25zdHJ1Y3Rvcihyb3cpIHtcclxuICAgICAgICB0aGlzLmRhdGEgPSByb3c7XHJcbiAgICAgICAgdGhpcy5uYW1lID0gcm93WydJbml0aWF0aXZlIE5hbWUnXTtcclxuICAgIH1cclxuXHJcbiAgICBleHBlbnNlcygpIHsgXHJcbiAgICAgICAgaWYgKHRoaXMuZGF0YVsnQmFsbHBhcmsgVG90YWwgRXhwZW5zZXMnXSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXRhWydCYWxscGFyayBUb3RhbCBFeHBlbnNlcyddO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXZlbnVlKCkgeyBcclxuICAgICAgICBpZiAodGhpcy5kYXRhWydSZXZlbnVlJ10pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YVsnUmV2ZW51ZSddO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBuZXQoKSB7IHJldHVybiB0aGlzLmV4cGVuc2VzKCkgfVxyXG5cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgSW5pdGlhdGl2ZTsiLCJcclxuaW1wb3J0IEluaXRpYXRpdmUgZnJvbSBcIi4vaW5pdGlhdGl2ZS5qc1wiO1xyXG5pbXBvcnQgeyBjb2xTdW0sIGZvcm1hdEN1cnJlbmN5IH0gZnJvbSBcIi4uL3V0aWxzL2NvbW1vbl91dGlscy5qc1wiO1xyXG5cclxuLy8gZGF0YSBzdHJ1Y3R1cmUgdG8gaG9sZCBzdXBwbGVtZW50YWwgcmVxdWVzdHNcclxuZXhwb3J0IGNsYXNzIFN1cHBsZW1lbnRhbCB7XHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB0aGlzLnRhYmxlID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLm5hbWUpKTtcclxuICAgICAgICB0aGlzLmluaXRpYXRpdmVzID0gW107XHJcbiAgICAgICAgaWYodGhpcy50YWJsZSl7XHJcbiAgICAgICAgICAgIHRoaXMudGFibGUuZm9yRWFjaCgocm93KSA9PiB7IFxyXG4gICAgICAgICAgICAgICAgdGhpcy5pbml0aWF0aXZlcy5wdXNoKG5ldyBJbml0aWF0aXZlKHJvdykpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0SW5pdHMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudGFibGUubWFwKChpdGVtKSA9PiB7IHJldHVybiBpdGVtWydJbml0aWF0aXZlIE5hbWUnXSB9KTtcclxuICAgIH1cclxuXHJcbiAgICBleHBlbnNlcygpIHtcclxuICAgICAgICByZXR1cm4gY29sU3VtKHRoaXMudGFibGUsICdCYWxscGFyayBUb3RhbCBFeHBlbnNlcycpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldmVudWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIGNvbFN1bSh0aGlzLnRhYmxlLCAnUmV2ZW51ZScpO1xyXG4gICAgfVxyXG5cclxuICAgIHRvdGFsKCl7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZXhwZW5zZXMoKSAtIHRoaXMucmV2ZW51ZSgpO1xyXG4gICAgfVxyXG5cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgU3VwcGxlbWVudGFsOyIsIi8vIG1vZGVscy9pbmRleC5qc1xyXG5cclxuZXhwb3J0IHsgZGVmYXVsdCBhcyBBY2NvdW50U3RyaW5nIH0gZnJvbSAnLi9hY2NvdW50X3N0cmluZy5qcyc7XHJcbmV4cG9ydCB7IGRlZmF1bHQgYXMgQmFzZWxpbmUgfSBmcm9tICcuL2Jhc2VsaW5lLmpzJztcclxuZXhwb3J0IHsgZGVmYXVsdCBhcyBDdXJyZW50RnVuZCB9IGZyb20gJy4vY3VycmVudF9mdW5kLmpzJztcclxuZXhwb3J0IHsgZGVmYXVsdCBhcyBDdXJyZW50UGFnZSB9IGZyb20gJy4vY3VycmVudF9wYWdlLmpzJztcclxuZXhwb3J0IHsgZGVmYXVsdCBhcyBGdW5kIH0gZnJvbSAnLi9mdW5kLmpzJztcclxuZXhwb3J0IHsgZGVmYXVsdCBhcyBGdW5kTG9va3VwVGFibGUgfSBmcm9tICcuL2Z1bmRfbG9va3VwX3RhYmxlLmpzJztcclxuZXhwb3J0IHsgZGVmYXVsdCBhcyBJbml0aWF0aXZlIH0gZnJvbSAnLi9pbml0aWF0aXZlLmpzJztcclxuZXhwb3J0IHsgZGVmYXVsdCBhcyBTZXJ2aWNlcyB9IGZyb20gJy4vc2VydmljZXMuanMnO1xyXG5leHBvcnQgeyBkZWZhdWx0IGFzIFN1cHBsZW1lbnRhbCB9IGZyb20gJy4vc3VwcGxlbWVudGFsLmpzJztcclxuIiwiaW1wb3J0IHsgRklTQ0FMX1lFQVIgfSBmcm9tIFwiLi4vLi4vLi4vY29uc3RhbnRzXCI7XHJcbmltcG9ydCB7IEJhc2VsaW5lLCBGdW5kTG9va3VwVGFibGUsIEZ1bmQsIEN1cnJlbnRGdW5kIH0gZnJvbSBcIi4uLy4uLy4uL21vZGVsc1wiO1xyXG5pbXBvcnQgeyBmb3JtYXRDdXJyZW5jeSB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9jb21tb25fdXRpbHNcIjtcclxuaW1wb3J0IHsgdmlzaXRQYWdlIH0gZnJvbSBcIi4uLy4uLy4uL3ZpZXdzL3ZpZXdfbG9naWNcIjtcclxuXHJcbmV4cG9ydCBjb25zdCBCYXNlbGluZVNlY3Rpb24gPSB7XHJcbiAgICBfZGF0YTogbmV3IEJhc2VsaW5lKCksXHJcbiAgICBfZ2VuRnVuZCA6IG5ldyBGdW5kKDEwMDApLFxyXG5cclxuICAgIGdldCBkYXRhKCkge1xyXG4gICAgICAgIHRoaXMuX2RhdGEgPSBuZXcgQmFzZWxpbmUoKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0IGRhdGEobmV3RGF0YSkge1xyXG4gICAgICAgIHRoaXMuX2RhdGEgPSBuZXdEYXRhO1xyXG4gICAgfSxcclxuXHJcbiAgICBnZXQgZ2VuRnVuZCgpIHtcclxuICAgICAgICB0aGlzLl9nZW5GdW5kID0gbmV3IEZ1bmQoMTAwMCk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dlbkZ1bmQ7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldCBnZW5GdW5kKG5ld0Z1bmQpIHtcclxuICAgICAgICB0aGlzLl9nZW5GdW5kID0gbmV3RnVuZDtcclxuICAgIH0sXHJcblxyXG4gICAgdGFyZ2V0X2h0bWwoKSB7XHJcbiAgICAgICAgcmV0dXJuIGBcclxuICAgICAgICAgICAgPGRpdiBjbGFzcz0nc2lkZWJhci1zdGF0LWxpbmUnIGlkPVwidGFyZ2V0XCI+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXQtbGFiZWxcIj5GWSR7RklTQ0FMX1lFQVJ9IEdlbmVyYWwgRnVuZCBiYXNlbGluZSB0YXJnZXQ6PC9zcGFuPiBcclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdFwiPiR7Zm9ybWF0Q3VycmVuY3koQmFzZWxpbmUudGFyZ2V0KCkpfTwvc3Bhbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9J3NpZGViYXItc3RhdC1saW5lJyBpZD1cIkdGLXRvdGFsXCI+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXQtbGFiZWxcIj5DdXJyZW50IEdGIGJhc2VsaW5lOjwvc3Bhbj4gXHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXRcIj4ke2Zvcm1hdEN1cnJlbmN5KHRoaXMuZ2VuRnVuZC5nZXRUb3RhbCgpKX08L3NwYW4+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8YnI+YDtcclxuICAgIH0sXHJcbiAgICBcclxuICAgIGZ1bmRfaHRtbChmdW5kKSB7XHJcbiAgICAgICAgcmV0dXJuIGBcclxuICAgICAgICAgICAgPGg2PiR7RnVuZExvb2t1cFRhYmxlLmdldE5hbWUoZnVuZC5mdW5kKX08L2g2PlxyXG4gICAgICAgICAgICA8aHI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9J3NpZGViYXItc3RhdC1saW5lIHJldmVudWUnPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0LWxhYmVsXCI+UHJvamVjdGVkIHJldmVudWVzOjwvc3Bhbj4gXHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXRcIj4ke2Zvcm1hdEN1cnJlbmN5KGZ1bmQuZ2V0UmV2ZW51ZSgpKX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1lZGl0IGVkaXQtaWNvblwiIHRpdGxlPVwiRWRpdFwiPjwvaT5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9J3NpZGViYXItc3RhdC1saW5lIHBlcnNvbm5lbCc+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXQtbGFiZWxcIj5QZXJzb25uZWwgY29zdDo8L3NwYW4+IFxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0XCI+JHtmb3JtYXRDdXJyZW5jeShmdW5kLmdldFBlcnNvbm5lbENvc3QoKSl9PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtZWRpdCBlZGl0LWljb25cIiB0aXRsZT1cIkVkaXRcIj48L2k+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPSdzaWRlYmFyLXN0YXQtbGluZSBvdmVydGltZSc+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXQtbGFiZWxcIj5PdmVydGltZSBjb3N0Ojwvc3Bhbj4gXHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXRcIj4ke2Zvcm1hdEN1cnJlbmN5KGZ1bmQuZ2V0T3ZlcnRpbWVDb3N0KCkpfTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWVkaXQgZWRpdC1pY29uXCIgdGl0bGU9XCJFZGl0XCI+PC9pPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz0nc2lkZWJhci1zdGF0LWxpbmUgbm9ucGVyc29ubmVsJz5cclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdC1sYWJlbFwiPk5vbi1wZXJzb25uZWwgY29zdDo8L3NwYW4+IFxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0XCI+JHtmb3JtYXRDdXJyZW5jeShmdW5kLmdldE5vblBlcnNvbm5lbENvc3QoKSl9PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtZWRpdCBlZGl0LWljb25cIiB0aXRsZT1cIkVkaXRcIj48L2k+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPSdzaWRlYmFyLXN0YXQtbGluZSBmdW5kLXRvdGFsJz5cclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdC1sYWJlbFwiPlRvdGFsIGV4cGVuZGl0dXJlczo8L3NwYW4+IFxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0XCI+JHtmb3JtYXRDdXJyZW5jeShmdW5kLmdldFRvdGFsKCkpfTwvc3Bhbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxicj5gO1xyXG4gICAgfSxcclxuXHJcbiAgICBsaW5rRWRpdEJ0bnMoKSB7XHJcbiAgICAgICAgbGV0IGJ0bnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZWRpdC1pY29uJyk7XHJcbiAgICAgICAgYnRucy5mb3JFYWNoKChidG4pID0+IHtcclxuICAgICAgICAgICAgLy8gR2V0IHRoZSBmdW5kIGZyb20gdGhlIGRpdiB0aGUgYnV0dG9uIGlzIGluXHJcbiAgICAgICAgICAgIGxldCBmdW5kID0gYnRuLmNsb3Nlc3QoJy5mdW5kLWRpdicpLmlkLnJlcGxhY2UoJ2Z1bmRfJywgJycpO1xyXG4gICAgICAgICAgICBsZXQgcGFnZSA9IGJ0bi5jbG9zZXN0KCcuc2lkZWJhci1zdGF0LWxpbmUnKS5jbGFzc0xpc3RbMV07XHJcbiAgICBcclxuICAgICAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBDdXJyZW50RnVuZC51cGRhdGUoZnVuZCk7XHJcbiAgICAgICAgICAgICAgICB2aXNpdFBhZ2UocGFnZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB1cGRhdGUoKSB7XHJcbiAgICAgICAgY29uc3QgYmFzZWxpbmVEaXYgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmFzZWxpbmUtc3RhdHMnKTtcclxuICAgICAgICBiYXNlbGluZURpdi5pbm5lckhUTUwgPSB0aGlzLnRhcmdldF9odG1sKCk7XHJcblxyXG4gICAgICAgIHRoaXMuZGF0YS5mdW5kcy5mb3JFYWNoKChmdW5kKSA9PiB7XHJcbiAgICAgICAgICAgIHZhciBmdW5kRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgICAgIGZ1bmREaXYuaWQgPSBgZnVuZF8ke2Z1bmQuZnVuZH1gO1xyXG4gICAgICAgICAgICBmdW5kRGl2LmNsYXNzTGlzdC5hZGQoJ2Z1bmQtZGl2Jyk7XHJcbiAgICAgICAgICAgIGZ1bmREaXYuaW5uZXJIVE1MID0gdGhpcy5mdW5kX2h0bWwoZnVuZCk7XHJcbiAgICAgICAgICAgIGJhc2VsaW5lRGl2LmFwcGVuZENoaWxkKGZ1bmREaXYpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZih0aGlzLmdlbkZ1bmQuZ2V0VG90YWwoKSA8PSBCYXNlbGluZS50YXJnZXQoKSl7XHJcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNHRi10b3RhbCAuc3RhdCcpLnN0eWxlLmNvbG9yID0gXCJncmVlblwiO1xyXG4gICAgICAgICAgICAvLyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZnVuZF8xMDAwIC5zaWRlYmFyLXN0YXQtbGluZTpsYXN0LW9mLXR5cGUgLnN0YXQnKS5zdHlsZS5jb2xvciA9IFwiZ3JlZW5cIjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjR0YtdG90YWwgLnN0YXQnKS5zdHlsZS5jb2xvciA9IFwicmVkXCI7XHJcbiAgICAgICAgICAgIC8vIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNmdW5kXzEwMDAgLnNpZGViYXItc3RhdC1saW5lOmxhc3Qtb2YtdHlwZSAuc3RhdCcpLnN0eWxlLmNvbG9yID0gXCJyZWRcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5saW5rRWRpdEJ0bnMoKTtcclxuICAgIH1cclxufTsiLCJpbXBvcnQgeyBTdXBwbGVtZW50YWwgfSBmcm9tIFwiLi4vLi4vLi4vbW9kZWxzXCI7XHJcbmltcG9ydCB7IGZvcm1hdEN1cnJlbmN5IH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL2NvbW1vbl91dGlsc1wiO1xyXG5pbXBvcnQgeyB2aXNpdFBhZ2UgfSBmcm9tIFwiLi4vLi4vLi4vdmlld3Mvdmlld19sb2dpY1wiO1xyXG5cclxuZXhwb3J0IGNvbnN0IFN1cHBTZWN0aW9uID0ge1xyXG4gICAgaHRtbCgpIHtcclxuICAgICAgICB2YXIgc3VwcCA9IG5ldyBTdXBwbGVtZW50YWw7XHJcbiAgICAgICAgcmV0dXJuIGBcclxuICAgICAgICAgICAgPGRpdiBjbGFzcz0nc2lkZWJhci1zdGF0LWxpbmUnIGlkPVwic3VwcC1yZXZlbnVlXCI+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXQtbGFiZWxcIj5Fc3RpbWF0ZWQgcmV2ZW51ZXM6PC9zcGFuPiBcclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdFwiPiR7Zm9ybWF0Q3VycmVuY3koc3VwcC5yZXZlbnVlKCkpfTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWVkaXQgZWRpdC1zdXBwXCIgdGl0bGU9XCJFZGl0XCI+PC9pPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz0nc2lkZWJhci1zdGF0LWxpbmUnIGlkPVwic3VwcC1leHBlbnNlc1wiPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0LWxhYmVsXCI+RXNpbWF0ZWQgZXhwZW5kaXR1cmVzOjwvc3Bhbj4gXHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXRcIj4ke2Zvcm1hdEN1cnJlbmN5KHN1cHAuZXhwZW5zZXMoKSl9PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtZWRpdCBlZGl0LXN1cHBcIiB0aXRsZT1cIkVkaXRcIj48L2k+XHJcbiAgICAgICAgICAgIDwvZGl2PmBcclxuICAgIH0sXHJcblxyXG4gICAgbGlua0VkaXRCdG5zKCkge1xyXG4gICAgICAgIGxldCBidG5zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmVkaXQtc3VwcCcpO1xyXG4gICAgICAgIGJ0bnMuZm9yRWFjaCgoYnRuKSA9PiB7XHJcbiAgICAgICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgdmlzaXRQYWdlKCduZXctaW5pdHMnKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHVwZGF0ZSgpIHtcclxuICAgICAgICBjb25zdCBzdXBwRGl2ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3N1cHAtc3RhdHMnKTtcclxuICAgICAgICBzdXBwRGl2LmlubmVySFRNTCA9IHRoaXMuaHRtbCgpO1xyXG4gICAgICAgIHRoaXMubGlua0VkaXRCdG5zKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFN1cHBTZWN0aW9uOyIsImltcG9ydCAnLi9zaWRlYmFyLmNzcydcclxuaW1wb3J0IHsgQmFzZWxpbmVTZWN0aW9uIH0gZnJvbSAnLi9zdWJjb21wb25lbnRzL2Jhc2VsaW5lX3NlY3Rpb24nO1xyXG5cclxuaW1wb3J0IFN1cHBTZWN0aW9uIGZyb20gJy4vc3ViY29tcG9uZW50cy9zdXBwX3NlY3Rpb24nXHJcblxyXG4vLyBmZXRjaCBDU1MgdmFyaWFibGVzIHNhdmVkIGluIDpyb290XHJcbmNvbnN0IHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XHJcbmNvbnN0IHNpZGVCYXJXaWR0aCA9IGdldENvbXB1dGVkU3R5bGUocm9vdCkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1zaWRlYmFyLXdpZHRoJykudHJpbSgpO1xyXG5cclxuZnVuY3Rpb24gaGlkZVNpZGViYXIoKSB7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZWJhci1wYW5lbCcpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi1wYW5lbCcpLnN0eWxlLndpZHRoID0gJzEwMCUnOyBcclxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2hlYWRlcicpLnN0eWxlLndpZHRoID0gJzEwMCUnXHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNob3dTaWRlYmFyKCkge1xyXG4gICAgY29uc3Qgc2lkZWJhciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaWRlYmFyLXBhbmVsJyk7XHJcbiAgICBjb25zdCBtYWluUGFuZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi1wYW5lbCcpO1xyXG4gICAgY29uc3QgaGVhZGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaGVhZGVyJyk7XHJcblxyXG4gICAgLy8gdXBkYXRlIHZhbHVlc1xyXG4gICAgdXBkYXRlVG90YWxzKCk7XHJcbiAgICBzaWRlYmFyLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOyAvLyBTaG93IHRoZSBzaWRlYmFyXHJcbiAgICBcclxuICAgIC8vIENhbGN1bGF0ZSB0aGUgcmVtYWluaW5nIHdpZHRoIGZvciB0aGUgbWFpbiBwYW5lbCBhbmQgaGVhZGVyXHJcbiAgICB2YXIgY29udGVudFdpZHRoID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xyXG4gICAgbWFpblBhbmVsLnN0eWxlLndpZHRoID0gYCR7Y29udGVudFdpZHRoIC0gcGFyc2VJbnQoc2lkZUJhcldpZHRoLCAxMCl9cHhgOyBcclxuICAgIGhlYWRlci5zdHlsZS53aWR0aCA9IGAke2NvbnRlbnRXaWR0aCAtIHBhcnNlSW50KHNpZGVCYXJXaWR0aCwgMTApfXB4YDsgXHJcblxyXG4gICAgLy8gYWRkIGV2ZW50IGxpc3RlbmVyIHRvIHJlc2l6ZSBjb250ZW50IGlmIHdpbmRvdyBpcyBhZGp1c3RlZFxyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHNob3dTaWRlYmFyKTtcclxufVxyXG5cclxuZnVuY3Rpb24gdXBkYXRlU2lkZWJhclRpdGxlKG5ld190aXRsZSl7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZWJhci10aXRsZScpLnRleHRDb250ZW50ID0gbmV3X3RpdGxlO1xyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVUb3RhbHMoKXtcclxuICAgIFN1cHBTZWN0aW9uLnVwZGF0ZSgpO1xyXG4gICAgQmFzZWxpbmVTZWN0aW9uLnVwZGF0ZSgpO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZXNldEFsbCgpe1xyXG4gICAgbG9jYWxTdG9yYWdlLmNsZWFyKCk7XHJcbiAgICAvLyByZXNldCBhbGwgc3RhdHMgdG8gMFxyXG4gICAgdXBkYXRlVG90YWxzKCk7XHJcbn1cclxuXHJcbmNvbnN0IFNpZGViYXIgPSB7XHJcbiAgICBTdXBwU2VjdGlvbiA6IFN1cHBTZWN0aW9uLFxyXG4gICAgQmFzZWxpbmVTZWN0aW9uIDogQmFzZWxpbmVTZWN0aW9uLFxyXG4gICAgaGlkZTogaGlkZVNpZGViYXIsXHJcbiAgICBzaG93OiBzaG93U2lkZWJhcixcclxuICAgIHVwZGF0ZVRpdGxlOiB1cGRhdGVTaWRlYmFyVGl0bGUsXHJcbiAgICB1cGRhdGVUb3RhbHM6IHVwZGF0ZVRvdGFscyxcclxuICAgIHJlc2V0OiByZXNldEFsbFxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgU2lkZWJhcjsiLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vbmF2X2J1dHRvbnMuY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vbmF2X2J1dHRvbnMuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiLy8gbmF2X2J1dHRvbnMuanNcclxuaW1wb3J0ICcuL25hdl9idXR0b25zLmNzcyc7XHJcbmltcG9ydCB7IG5leHRQYWdlLCBsYXN0UGFnZSB9IGZyb20gJy4uLy4uL3ZpZXdzL3ZpZXdfbG9naWMuanMnO1xyXG5cclxuZnVuY3Rpb24gaW5pdGlhbGl6ZU5hdkJ1dHRvbnMoKSB7XHJcbiAgICAvLyBpbml0aWFsaXplIGxhc3QgYnV0dG9uXHJcbiAgICBjb25zdCBsYXN0X2J0biA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdidG4tbGFzdCcpO1xyXG4gICAgbGFzdF9idG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBsYXN0UGFnZSk7IFxyXG4gICAgLy8gaW5pdGlhbGl6ZSBuZXh0IGJ1dHRvblxyXG4gICAgY29uc3QgbmV4dF9idG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYnRuLW5leHQnKTtcclxuICAgIG5leHRfYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgbmV4dFBhZ2UpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBkaXNhYmxlKGJ1dHRvbl9pZCkge1xyXG4gICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYnV0dG9uX2lkKTtcclxuICAgIGJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdkaXNhYmxlZCcpO1xyXG4gICAgYnV0dG9uLmRpc2FibGVkID0gdHJ1ZTsgLy8gQWxzbyBkaXNhYmxlIGl0IGF0IHRoZSBET00gbGV2ZWxcclxufVxyXG5cclxuZnVuY3Rpb24gZW5hYmxlKGJ1dHRvbl9pZCkge1xyXG4gICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYnV0dG9uX2lkKTtcclxuICAgIGJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdkaXNhYmxlZCcpO1xyXG4gICAgYnV0dG9uLmRpc2FibGVkID0gZmFsc2U7IC8vIEVuYWJsZSBpdCBhdCB0aGUgRE9NIGxldmVsXHJcbn1cclxuXHJcbmNvbnN0IE5leHQgPSB7XHJcbiAgICBkaXNhYmxlOiBmdW5jdGlvbigpIHsgZGlzYWJsZSgnYnRuLW5leHQnKTsgfSxcclxuICAgIGVuYWJsZTogZnVuY3Rpb24oKSB7IGVuYWJsZSgnYnRuLW5leHQnKTsgfSxcclxuICAgIGFkZEFjdGlvbjogZnVuY3Rpb24oZm4pIHtcclxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAjYnRuLW5leHRgKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZuKTtcclxuICAgIH0sXHJcbiAgICByZW1vdmVBY3Rpb246IGZ1bmN0aW9uKGZuKSB7XHJcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgI2J0bi1uZXh0YCkucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmbik7XHJcbiAgICB9LFxyXG59O1xyXG5cclxuY29uc3QgTGFzdCA9IHtcclxuICAgIGRpc2FibGU6IGZ1bmN0aW9uKCkgeyBkaXNhYmxlKCdidG4tbGFzdCcpOyB9LFxyXG4gICAgZW5hYmxlOiBmdW5jdGlvbigpIHsgZW5hYmxlKCdidG4tbGFzdCcpOyB9LFxyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IE5hdkJ1dHRvbnMgPSB7XHJcbiAgICBoaWRlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbmF2LWJ0bnMnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgfSxcclxuICAgIHNob3c6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduYXYtYnRucycpLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgICAgIGluaXRpYWxpemVOYXZCdXR0b25zKCk7XHJcbiAgICB9LFxyXG4gICAgTmV4dDogTmV4dCxcclxuICAgIExhc3Q6IExhc3QsXHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBOYXZCdXR0b25zOyIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9ib2R5LmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xub3B0aW9ucy5pbnNlcnQgPSBpbnNlcnRGbi5iaW5kKG51bGwsIFwiaGVhZFwiKTtcbm9wdGlvbnMuZG9tQVBJID0gZG9tQVBJO1xub3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQgPSBpbnNlcnRTdHlsZUVsZW1lbnQ7XG5cbnZhciB1cGRhdGUgPSBBUEkoY29udGVudCwgb3B0aW9ucyk7XG5cblxuXG5leHBvcnQgKiBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL2JvZHkuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiXG4gICAgICBpbXBvcnQgQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCI7XG4gICAgICBpbXBvcnQgZG9tQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRGbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanNcIjtcbiAgICAgIGltcG9ydCBzZXRBdHRyaWJ1dGVzIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0U3R5bGVFbGVtZW50IGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzXCI7XG4gICAgICBpbXBvcnQgc3R5bGVUYWdUcmFuc2Zvcm1GbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlVGFnVHJhbnNmb3JtLmpzXCI7XG4gICAgICBpbXBvcnQgY29udGVudCwgKiBhcyBuYW1lZEV4cG9ydCBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL2FjY29yZGlvbi5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcbm9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9hY2NvcmRpb24uY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiXG4gICAgICBpbXBvcnQgQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCI7XG4gICAgICBpbXBvcnQgZG9tQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRGbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanNcIjtcbiAgICAgIGltcG9ydCBzZXRBdHRyaWJ1dGVzIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0U3R5bGVFbGVtZW50IGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzXCI7XG4gICAgICBpbXBvcnQgc3R5bGVUYWdUcmFuc2Zvcm1GbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlVGFnVHJhbnNmb3JtLmpzXCI7XG4gICAgICBpbXBvcnQgY29udGVudCwgKiBhcyBuYW1lZEV4cG9ydCBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3RhYmxlLmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xub3B0aW9ucy5pbnNlcnQgPSBpbnNlcnRGbi5iaW5kKG51bGwsIFwiaGVhZFwiKTtcbm9wdGlvbnMuZG9tQVBJID0gZG9tQVBJO1xub3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQgPSBpbnNlcnRTdHlsZUVsZW1lbnQ7XG5cbnZhciB1cGRhdGUgPSBBUEkoY29udGVudCwgb3B0aW9ucyk7XG5cblxuXG5leHBvcnQgKiBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3RhYmxlLmNzc1wiO1xuICAgICAgIGV4cG9ydCBkZWZhdWx0IGNvbnRlbnQgJiYgY29udGVudC5sb2NhbHMgPyBjb250ZW50LmxvY2FscyA6IHVuZGVmaW5lZDtcbiIsImZ1bmN0aW9uIGFkZFRhYmxlSGVhZGVycyhjb2xzKXtcclxuXHJcbiAgICAvLyBHZXQgdGhlIHRhYmxlIGVsZW1lbnQgYnkgaXRzIElEXHJcbiAgICBjb25zdCB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYWluLXRhYmxlJyk7XHJcbiAgICBcclxuICAgIC8vIENyZWF0ZSBhIHRhYmxlIGhlYWRlciByb3cgZWxlbWVudFxyXG4gICAgY29uc3QgaGVhZGVyUm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndHInKTtcclxuXHJcbiAgICBjb2xzLmZvckVhY2goY29sID0+IHtcclxuICAgICAgICAvLyBDcmVhdGUgYSBoZWFkZXIgY2VsbCBlbGVtZW50XHJcbiAgICAgICAgY29uc3QgaGVhZGVyQ2VsbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RoJyk7XHJcbiAgICAgICAgaGVhZGVyQ2VsbC50ZXh0Q29udGVudCA9IGNvbFsndGl0bGUnXTtcclxuICAgICAgICBoZWFkZXJDZWxsLmNsYXNzTGlzdC5hZGQoY29sWydjbGFzc05hbWUnXSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gQXBwZW5kIHRoZSBoZWFkZXIgY2VsbCB0byB0aGUgaGVhZGVyIHJvd1xyXG4gICAgICAgIGhlYWRlclJvdy5hcHBlbmRDaGlsZChoZWFkZXJDZWxsKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEFwcGVuZCB0aGUgaGVhZGVyIHJvdyB0byB0aGUgdGFibGUgaGVhZGVyXHJcbiAgICBsZXQgdGhlYWQgPSB0YWJsZS5xdWVyeVNlbGVjdG9yKCd0aGVhZCcpO1xyXG4gICAgdGhlYWQuYXBwZW5kQ2hpbGQoaGVhZGVyUm93KTtcclxufVxyXG5cclxuY29uc3QgSGVhZGVyID0ge1xyXG4gICAgYWRkOiBmdW5jdGlvbihoZWFkZXJfYXJyYXkpe1xyXG4gICAgICAgIGFkZFRhYmxlSGVhZGVycyhoZWFkZXJfYXJyYXkpXHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBIZWFkZXI7IiwiaW1wb3J0IEhlYWRlciBmcm9tIFwiLi9oZWFkZXJzLmpzXCI7XHJcbmltcG9ydCB7IGZvcm1hdEN1cnJlbmN5IH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL2NvbW1vbl91dGlscy5qc1wiO1xyXG5cclxuYXN5bmMgZnVuY3Rpb24gYWRkTmV3Um93KGRhdGFfZGljdGlvbmFyeSwgY29sdW1ucyA9IFtdKXtcclxuICAgIFxyXG4gICAgLy8gR2V0IHRoZSB0YWJsZSBlbGVtZW50IGJ5IGl0cyBJRFxyXG4gICAgY29uc3QgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi10YWJsZScpO1xyXG5cclxuICAgIC8vIGNoZWNrIGlmIGhlYWRlciBoYXMgYWxyZWFkeSBiZWVuIGFkZGVkXHJcbiAgICBsZXQgaGVhZGVyX3JvdyA9IHRhYmxlLnF1ZXJ5U2VsZWN0b3IoJ3RoZWFkIHRyJyk7XHJcbiAgICBpZiAoIWhlYWRlcl9yb3cpIHtcclxuICAgICAgICBIZWFkZXIuYWRkKGNvbHVtbnMpO1xyXG4gICAgICAgIGhlYWRlcl9yb3cgPSB0YWJsZS5xdWVyeVNlbGVjdG9yKCd0aGVhZCB0cicpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGluaXRpYWxpemUgbmV3IHJvdyBvZiBkYXRhXHJcbiAgICBjb25zdCBuZXdfcm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndHInKTtcclxuXHJcbiAgICAvLyBnbyB0aHJvdWdoIGVhY2ggaGVhZGVyIGFuZCBhZGQgdGhlIHJpZ2h0IGNlbGwgdmFsdWUgZGVwZW5kaW5nIG9uIGl0cyBjbGFzc1xyXG4gICAgbGV0IHRoRWxlbWVudHMgPSBoZWFkZXJfcm93LnF1ZXJ5U2VsZWN0b3JBbGwoJ3RoJyk7XHJcbiAgICB0aEVsZW1lbnRzLmZvckVhY2goIChoZWFkZXJfY2VsbCkgPT4ge1xyXG4gICAgICAgIC8vIENyZWF0ZSBuZXcgY2VsbCBhbmQgYWRkIGl0IHRvIHRoZSByb3dcclxuICAgICAgICBjb25zdCBuZXdDZWxsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGQnKTtcclxuICAgICAgICBuZXdfcm93LmFwcGVuZENoaWxkKG5ld0NlbGwpO1xyXG4gICAgICAgIC8vIGlmIHRoZSBkYXRhIGhhcyBhbiBhcHByb3ByaWF0ZSBjbGFzcywgYWRkIHRoZSBpbmZvIHRvIHRoZSBjZWxsLiBcclxuICAgICAgICAvLyBPdGhlcndpc2UsIGtlZXAgZW1wdHkgY2VsbFxyXG4gICAgICAgIE9iamVjdC5rZXlzKGRhdGFfZGljdGlvbmFyeSkuZm9yRWFjaCggKGNsYXNzTmFtZSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoaGVhZGVyX2NlbGwuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSkgKXtcclxuICAgICAgICAgICAgICAgIG5ld0NlbGwudGV4dENvbnRlbnQgPSBkYXRhX2RpY3Rpb25hcnlbY2xhc3NOYW1lXTtcclxuICAgICAgICAgICAgICAgIG5ld0NlbGwuY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBBcHBlbmQgdGhlIG5ldyByb3cgdG8gdGhlIHRhYmxlIGJvZHlcclxuICAgIGxldCB0Ym9keSA9IHRhYmxlLnF1ZXJ5U2VsZWN0b3IoJ3Rib2R5Jyk7XHJcbiAgICB0Ym9keS5hcHBlbmRDaGlsZChuZXdfcm93KTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2F2ZVJvd0VkaXRzKHJvdyl7XHJcbiAgICB2YXIgY2VsbHMgPSByb3cucXVlcnlTZWxlY3RvckFsbCgndGQnKVxyXG4gICAgY2VsbHMuZm9yRWFjaCggY2VsbCA9PiB7XHJcbiAgICAgICAgLy8gc2F2ZSBkcm9wZG93biB2YWx1ZXNcclxuICAgICAgICBpZiAoY2VsbC5xdWVyeVNlbGVjdG9yKCdzZWxlY3QnKSl7XHJcbiAgICAgICAgICAgIHZhciBzZXJ2aWNlU2VsZWN0b3IgPSBjZWxsLnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdCcpO1xyXG4gICAgICAgICAgICBjZWxsLnRleHRDb250ZW50ID0gc2VydmljZVNlbGVjdG9yLnZhbHVlO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoY2VsbC5xdWVyeVNlbGVjdG9yKCdpbnB1dCcpKSB7XHJcbiAgICAgICAgICAgIC8vIHNhdmUgbmV3IGVudGVyZWQgdmFsdWUgaW4gdGV4dGJveFxyXG4gICAgICAgICAgICB2YXIgdGV4dGJveCA9IGNlbGwucXVlcnlTZWxlY3RvcignaW5wdXQnKTtcclxuICAgICAgICAgICAgdmFyIGVudGVyZWRWYWx1ZSA9IHRleHRib3gudmFsdWU7XHJcbiAgICAgICAgICAgIC8vIHVwZGF0ZSBkaXNwbGF5IGFuZCBmb3JtYXQgd2l0aCBjdXJyZW5jeSBpZiByZWxldmFudFxyXG4gICAgICAgICAgICBpZiAoIGNlbGwuY2xhc3NMaXN0LmNvbnRhaW5zKCdjb3N0JykgKXtcclxuICAgICAgICAgICAgICAgIC8vIGlmIGNvc3QsIHJlbW92ZSBjb21tYXMgZmlyc3RcclxuICAgICAgICAgICAgICAgIGVudGVyZWRWYWx1ZSA9IGVudGVyZWRWYWx1ZS5yZXBsYWNlQWxsKCcsJywgJycpO1xyXG4gICAgICAgICAgICAgICAgY2VsbC50ZXh0Q29udGVudCA9IGZvcm1hdEN1cnJlbmN5KGVudGVyZWRWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAvLyBzZXQgdmFsdWUgYXR0cmlidXRlIHRvIHRoZSBuZXcgdXNlciBpbnB1dFxyXG4gICAgICAgICAgICAgICAgY2VsbC5zZXRBdHRyaWJ1dGUoJ3ZhbHVlJywgZW50ZXJlZFZhbHVlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNlbGwudGV4dENvbnRlbnQgPSBlbnRlcmVkVmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKGNlbGwucXVlcnlTZWxlY3RvcigndGV4dGFyZWEnKSl7XHJcbiAgICAgICAgICAgIC8vIHNhdmUgbmV3IGVudGVyZWQgdmFsdWUgaW4gdGV4dGJveFxyXG4gICAgICAgICAgICB2YXIgZW50ZXJlZFZhbHVlID0gY2VsbC5xdWVyeVNlbGVjdG9yKCd0ZXh0YXJlYScpLnZhbHVlO1xyXG4gICAgICAgICAgICBjZWxsLnRleHRDb250ZW50ID0gZW50ZXJlZFZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH0pXHJcbn1cclxuXHJcbmNvbnN0IFJvd3MgPSB7XHJcbiAgICBhZGQgOiBmdW5jdGlvbihkYXRhX2RpY3Rpb25hcnksIGNvbHMpe1xyXG4gICAgICAgIGFkZE5ld1JvdyhkYXRhX2RpY3Rpb25hcnksIGNvbHMpXHJcbiAgICB9LFxyXG4gICAgc2F2ZUVkaXRzIDogZnVuY3Rpb24ocm93KXtcclxuICAgICAgICBzYXZlUm93RWRpdHMocm93KVxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBSb3dzOyIsImltcG9ydCBSb3dzIGZyb20gJy4vcm93cy5qcydcclxuXHJcbmZ1bmN0aW9uIGhpZGVCdXR0b24oY2xhc3NOYW1lKXtcclxuICAgIHJldHVybiBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgYnV0dG9ucyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoY2xhc3NOYW1lKTtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ1dHRvbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgYnV0dG9uc1tpXS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gc2hvd0J1dHRvbihjbGFzc05hbWUpe1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHZhciBidXR0b25zID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShjbGFzc05hbWUpO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnV0dG9ucy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBidXR0b25zW2ldLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lJztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZUJ1dHRvblRleHQoY2xhc3NOYW1lLCB0ZXh0KXtcclxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYC4ke2NsYXNzTmFtZX1gKS50ZXh0Q29udGVudCA9IHRleHQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGhhbmRsZVJvd0VkaXQoYWN0aW9uT25DbGljaywgdXBkYXRlQ2FsbGJhY2sgPSBudWxsKXtcclxuICAgIC8vIGF0dGFjaCBhbiBldmVudCBsaXN0ZW5lciB0byBlYWNoIGVkaXQgYnV0dG9uIGluIGV2ZXJ5IHJvd1xyXG4gICAgdmFyIGVkaXRCdXR0b25zID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnYnRuLWVkaXQnKTtcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWRpdEJ1dHRvbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBlZGl0QnV0dG9uc1tpXS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIC8vIERldGVybWluZSB3aGF0IHdhcyBjbGlja2VkIG9uIHdpdGhpbiB0aGUgdGFibGVcclxuICAgICAgICAgICAgdmFyIHJvd1RvRWRpdCA9IGV2ZW50LnRhcmdldC5jbG9zZXN0KCd0cicpO1xyXG4gICAgICAgICAgICAvLyBtYXJrIHJvdyBhcyBiZWluZyBlZGl0ZWRcclxuICAgICAgICAgICAgcm93VG9FZGl0LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZS1lZGl0aW5nJyk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyB0dXJuIHJlbGV2YW50IGVudHJpZXMgaW50byB0ZXh0Ym94ZXMsIHVzdWFsbHlcclxuICAgICAgICAgICAgYWN0aW9uT25DbGljaygpO1xyXG5cclxuICAgICAgICAgICAgLy8gaGlkZSBlZGl0IGJ1dHRvbnNcclxuICAgICAgICAgICAgRWRpdC5oaWRlKCk7XHJcbiAgICAgICAgICAgIGlmKHVwZGF0ZUNhbGxiYWNrKXtcclxuICAgICAgICAgICAgICAgIGluaXRpYWxpemVDb25maXJtQnV0dG9uKHVwZGF0ZUNhbGxiYWNrKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxufVxyXG5cclxuZnVuY3Rpb24gaW5pdGlhbGl6ZUNvbmZpcm1CdXR0b24odXBkYXRlQ2FsbGJhY2spe1xyXG4gICAgLy8gZ2V0IGVsZW1lbnQgYW5kIGFkZCBsaXN0ZW5lciBmb3IgY2xpY2tcclxuICAgIHZhciByb3dUb0VkaXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYWN0aXZlLWVkaXRpbmcnKTtcclxuICAgIGNvbnN0IGNvbmZpcm1fYnRuID0gcm93VG9FZGl0LnF1ZXJ5U2VsZWN0b3IoXCIuYnRuLWNvbmZpcm1cIik7XHJcbiAgICAvLyBzaG93IHRoZSByb3cncyBjb25maXJtIGJ1dHRvblxyXG4gICAgY29uZmlybV9idG4uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICBjb25maXJtX2J0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7O1xyXG4gICAgICAgIC8vIHNhdmUgcm93IGVkaXRzXHJcbiAgICAgICAgUm93cy5zYXZlRWRpdHMocm93VG9FZGl0KTtcclxuICAgICAgICAvLyB1cGRhdGUgdmFsdWVzIGluIHNpZGViYXJcclxuICAgICAgICB1cGRhdGVDYWxsYmFjaygpO1xyXG4gICAgICAgIC8vIG1ha2Ugcm93IG5vIGxvbmdlciBncmVlblxyXG4gICAgICAgIHJvd1RvRWRpdC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUtZWRpdGluZycpO1xyXG4gICAgICAgIC8vIHNob3cgZWRpdCBidXR0b25zIGFuZCBoaWRlIGNvbmZpcm0gYnV0dG9uc1xyXG4gICAgICAgIEVkaXQuc2hvdygpO1xyXG4gICAgICAgIENvbmZpcm0uaGlkZSgpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmNvbnN0IEVkaXQgPSB7XHJcbiAgICBodG1sOiAnPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZWRpdFwiPkVkaXQgcm93PC9idXR0b24+JyxcclxuICAgIGhpZGU6IGhpZGVCdXR0b24oJ2J0bi1lZGl0JyksXHJcbiAgICBzaG93OiBzaG93QnV0dG9uKCdidG4tZWRpdCcpLFxyXG4gICAgaW5pdCA6IGZ1bmN0aW9uKGFjdGlvbk9uQ2xpY2ssIHVwZGF0ZUNhbGxiYWNrKXtcclxuICAgICAgICBoYW5kbGVSb3dFZGl0KGFjdGlvbk9uQ2xpY2ssIHVwZGF0ZUNhbGxiYWNrKVxyXG4gICAgfVxyXG59O1xyXG5cclxuY29uc3QgRGVsZXRlID0ge1xyXG4gICAgaHRtbDogJzxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRlbGV0ZVwiPkRlbGV0ZTwvYnV0dG9uPicsXHJcbiAgICBoaWRlOiBoaWRlQnV0dG9uKCdidG4tZGVsZXRlJyksXHJcbiAgICBzaG93OiBzaG93QnV0dG9uKCdidG4tZGVsZXRlJylcclxufTtcclxuXHJcbmNvbnN0IENvbmZpcm0gPSB7XHJcbiAgICBodG1sOiAnPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tY29uZmlybVwiPkNvbmZpcm08L2J1dHRvbj4nLFxyXG4gICAgaGlkZTogaGlkZUJ1dHRvbignYnRuLWNvbmZpcm0nKSxcclxuICAgIHNob3c6IHNob3dCdXR0b24oJ2J0bi1jb25maXJtJylcclxufTtcclxuXHJcbmNvbnN0IEFkZFJvdyA9IHtcclxuICAgIGhpZGU6IGhpZGVCdXR0b24oJ2J0bi1hZGQnKSxcclxuICAgIHNob3c6IHNob3dCdXR0b24oJ2J0bi1hZGQnKSxcclxuICAgIHVwZGF0ZVRleHQ6IGZ1bmN0aW9uKHRleHQpe1xyXG4gICAgICAgIHVwZGF0ZUJ1dHRvblRleHQoJ2J0bi1hZGQnLCB0ZXh0KTtcclxuICAgIH1cclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBCdXR0b25zID0ge1xyXG4gICAgRGVsZXRlOiBEZWxldGUsXHJcbiAgICBFZGl0IDogRWRpdCxcclxuICAgIENvbmZpcm0gOiBDb25maXJtLFxyXG4gICAgQWRkUm93IDogQWRkUm93LFxyXG4gICAgZWRpdF9jb25maXJtX2J0bnMgOiBFZGl0Lmh0bWwgKyBDb25maXJtLmh0bWwgLFxyXG4gICAgYWxsX2J0bnMgOiBEZWxldGUuaHRtbCArIEVkaXQuaHRtbCArIENvbmZpcm0uaHRtbFxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBCdXR0b25zOyIsImZ1bmN0aW9uIGNyZWF0ZURyb3Bkb3duKGRhdGFBcnJheSkge1xyXG5cclxuICAvLyBDcmVhdGluZyBhIHNlbGVjdCBlbGVtZW50XHJcbiAgY29uc3Qgc2VsZWN0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NlbGVjdCcpO1xyXG5cclxuICAvLyBhZGQgYSBkZWZhdWx0IGJsYW5rIG9wdGlvbiB0byB0aGUgZGF0YUFycmF5XHJcbiAgZGF0YUFycmF5ID0gWycnXS5jb25jYXQoZGF0YUFycmF5KTtcclxuXHJcbiAgLy8gTG9vcGluZyB0aHJvdWdoIHRoZSBhcnJheSBhbmQgY3JlYXRpbmcgYW4gb3B0aW9uIGZvciBlYWNoIGVsZW1lbnRcclxuICBkYXRhQXJyYXkuZm9yRWFjaChpdGVtID0+IHtcclxuICAgIGNvbnN0IG9wdGlvbkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKTtcclxuICAgIG9wdGlvbkVsZW1lbnQudmFsdWUgPSBpdGVtO1xyXG4gICAgb3B0aW9uRWxlbWVudC50ZXh0Q29udGVudCA9IGl0ZW07XHJcbiAgICBzZWxlY3RFbGVtZW50LmFwcGVuZENoaWxkKG9wdGlvbkVsZW1lbnQpOyAvLyBBcHBlbmRpbmcgdGhlIG9wdGlvbiB0byB0aGUgc2VsZWN0XHJcbiAgfSk7XHJcblxyXG4gIC8vIFJldHVybiB0aGUgc2VsZWN0IGVsZW1lbnQgc28gaXQgY2FuIGJlIGFwcGVuZGVkIHRvIHRoZSBkb2N1bWVudFxyXG4gIHJldHVybiBzZWxlY3RFbGVtZW50O1xyXG59XHJcblxyXG5cclxuZXhwb3J0IGNvbnN0IERyb3Bkb3duID0ge1xyXG4gICAgY3JlYXRlIDogZnVuY3Rpb24oZGF0YUFycmF5KSB7IHJldHVybiBjcmVhdGVEcm9wZG93bihkYXRhQXJyYXkpIH0sXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IERyb3Bkb3duOyIsImltcG9ydCB7IGZvcm1hdEN1cnJlbmN5LCBkaXNwbGF5V2l0aENvbW1hcyB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9jb21tb25fdXRpbHMuanNcIjtcclxuaW1wb3J0IFNlcnZpY2VzIGZyb20gXCIuLi8uLi8uLi9tb2RlbHMvc2VydmljZXMuanNcIjtcclxuaW1wb3J0IERyb3Bkb3duIGZyb20gXCIuLi8uLi9mb3JtL3N1YmNvbXBvbmVudHMvZHJvcGRvd24uanNcIjtcclxuXHJcbi8vIHJldHVybiBjZWxsIHZhbHVlIGF0dHJpYnV0ZSBvciAwIGlmIGl0IGRvZXMgbm90IGV4aXN0XHJcbmZ1bmN0aW9uIGdldENlbGxWYWx1ZShyb3csIGNsYXNzTmFtZSkge1xyXG4gICAgdmFyIGNlbGwgPSByb3cucXVlcnlTZWxlY3RvcihgLiR7Y2xhc3NOYW1lfWApO1xyXG4gICAgdmFyIGNlbGxWYWx1ZSA9IGNlbGwgPyBjZWxsLmdldEF0dHJpYnV0ZSgndmFsdWUnKSA6IG51bGw7XHJcbiAgICByZXR1cm4gY2VsbFZhbHVlID8gcGFyc2VGbG9hdChjZWxsVmFsdWUpIDogMDtcclxufVxyXG5cclxuLy8gcmV0dXJuIHRleHQgaW4gY2VsbFxyXG5mdW5jdGlvbiBnZXRDZWxsVGV4dChyb3csIGNsYXNzTmFtZSkge1xyXG4gICAgdmFyIGNlbGwgPSByb3cucXVlcnlTZWxlY3RvcihgLiR7Y2xhc3NOYW1lfWApO1xyXG4gICAgaWYgKGNlbGwpIHtcclxuICAgICAgICByZXR1cm4gY2VsbC50ZXh0Q29udGVudDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy9jb25zb2xlLmxvZyhgRXJyb3IgcmV0cmlldmluZyBjZWxsIHRleHQgZm9yIGNsYXNzICR7Y2xhc3NOYW1lfWApO1xyXG4gICAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gdXBkYXRlVGFibGVDZWxsKHJvdywgY29sX2NsYXNzLCBuZXdfdmFsdWUpe1xyXG4gICAgY29uc3QgY2VsbCA9IHJvdy5xdWVyeVNlbGVjdG9yKGAuJHtjb2xfY2xhc3N9YCk7XHJcbiAgICBjZWxsLnNldEF0dHJpYnV0ZSgndmFsdWUnLCBuZXdfdmFsdWUpO1xyXG4gICAgY2VsbC50ZXh0Q29udGVudCA9IGZvcm1hdEN1cnJlbmN5KG5ld192YWx1ZSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUVkaXRhYmxlQ2VsbChjZWxsQ2xhc3MsIGlzQ29zdCwgdHlwZSA9ICdpbnB1dCcpe1xyXG4gICAgLy8gZ2V0IGNlbGxcclxuICAgIGNvbnN0IGNlbGwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAuYWN0aXZlLWVkaXRpbmcgdGQuJHtjZWxsQ2xhc3N9YCk7XHJcbiAgICAvLyBDcmVhdGUgYW4gaW5wdXQgZWxlbWVudCB0byBlZGl0IHRoZSB2YWx1ZVxyXG4gICAgdmFyIHRleHRib3ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHR5cGUpO1xyXG4gICAgaWYgKHR5cGUgPT0gJ2lucHV0Jyl7XHJcbiAgICAgICAgdGV4dGJveC50eXBlID0gJ3RleHQnO1xyXG4gICAgfTtcclxuICAgIGlmIChpc0Nvc3Qpe1xyXG4gICAgICAgIHZhciB2YWx1ZSA9IGNlbGwuZ2V0QXR0cmlidXRlKCd2YWx1ZScpO1xyXG4gICAgICAgIHRleHRib3gudmFsdWUgPSBkaXNwbGF5V2l0aENvbW1hcyh2YWx1ZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRleHRib3gudmFsdWUgPSBjZWxsLnRleHRDb250ZW50O1xyXG4gICAgfVxyXG4gICAgLy8gQ2xlYXIgdGhlIGN1cnJlbnQgY29udGVudCBhbmQgYXBwZW5kIHRoZSB0ZXh0Ym94IHRvIHRoZSBjZWxsXHJcbiAgICBjZWxsLmlubmVySFRNTCA9ICcnO1xyXG4gICAgY2VsbC5hcHBlbmRDaGlsZCh0ZXh0Ym94KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlRHJvcGRvd24oY2VsbENsYXNzLCBvcHRpb25BcnJheSl7XHJcbiAgICAvLyBnZXQgY2VsbFxyXG4gICAgY29uc3QgY2VsbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYC5hY3RpdmUtZWRpdGluZyB0ZC4ke2NlbGxDbGFzc31gKTtcclxuICAgIC8vIGFkZCBzZXJ2aWNlIGRyb3Bkb3duXHJcbiAgICBjb25zdCBkcm9wZG93biA9IERyb3Bkb3duLmNyZWF0ZShvcHRpb25BcnJheSk7XHJcbiAgICBkcm9wZG93bi52YWx1ZSA9IGNlbGwudGV4dENvbnRlbnQ7XHJcbiAgICAvLyBDbGVhciB0aGUgY3VycmVudCBjb250ZW50IGFuZCBhcHBlbmQgdGhlIHRleHRib3ggdG8gdGhlIGNlbGxcclxuICAgIGNlbGwuaW5uZXJIVE1MID0gJyc7XHJcbiAgICBjZWxsLmFwcGVuZENoaWxkKGRyb3Bkb3duKTtcclxufVxyXG5cclxuY29uc3QgQ2VsbCA9IHtcclxuICAgIGdldFZhbHVlOiBmdW5jdGlvbihyb3csIGNsYXNzTmFtZSkge1xyXG4gICAgICAgIHJldHVybiBnZXRDZWxsVmFsdWUocm93LCBjbGFzc05hbWUpOyBcclxuICAgIH0sXHJcbiAgICBnZXRUZXh0OiBmdW5jdGlvbihyb3csIGNsYXNzTmFtZSkge1xyXG4gICAgICAgIHJldHVybiBnZXRDZWxsVGV4dChyb3csIGNsYXNzTmFtZSk7IFxyXG4gICAgfSxcclxuICAgIHVwZGF0ZVZhbHVlOiBmdW5jdGlvbihyb3csIGNvbF9jbGFzcywgbmV3X3ZhbHVlKSB7XHJcbiAgICAgICAgdXBkYXRlVGFibGVDZWxsKHJvdywgY29sX2NsYXNzLCBuZXdfdmFsdWUpOyBcclxuICAgIH0sXHJcbiAgICBjcmVhdGVUZXh0Ym94IDogZnVuY3Rpb24oY2xhc3NOYW1lLCBpc0Nvc3QsIHR5cGUpIHtcclxuICAgICAgICBjcmVhdGVFZGl0YWJsZUNlbGwoY2xhc3NOYW1lLCBpc0Nvc3QsIHR5cGUpXHJcbiAgICB9LFxyXG4gICAgY3JlYXRlU2VydmljZURyb3Bkb3duIDogICgpID0+IHsgY3JlYXRlRHJvcGRvd24oJ3NlcnZpY2UnLCBTZXJ2aWNlcy5saXN0KCkpIH0sXHJcbiAgICBjcmVhdGVEcm9wZG93biA6IGNyZWF0ZURyb3Bkb3duXHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBDZWxsOyIsImltcG9ydCB7IGZvcm1hdEN1cnJlbmN5IH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL2NvbW1vbl91dGlscy5qc1wiO1xyXG5cclxuLy8gcG9zaXRpb24gaXMgaW5kZXggYXQgd2hpY2ggbmV3IGNvbHVtbiB3aWxsIGJlIGluc2VydGVkXHJcbmZ1bmN0aW9uIGFkZENvbChwb3NpdGlvbiwgaHRtbENvbnRlbnQgPSAnJywgaGVhZGVyVGl0bGUgPSAnJykge1xyXG4gICAgLy8gR2V0IHRoZSB0YWJsZSBlbGVtZW50IGJ5IGl0cyBJRFxyXG4gICAgbGV0IHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuXHJcbiAgICAvLyBWYWxpZGF0ZSBwb3NpdGlvblxyXG4gICAgbGV0IG1heFBvc2l0aW9uID0gdGFibGUucm93c1swXS5jZWxscy5sZW5ndGg7XHJcbiAgICBpZiAocG9zaXRpb24gPCAwIHx8IHBvc2l0aW9uID4gbWF4UG9zaXRpb24pIHtcclxuICAgICAgY29uc29sZS5lcnJvcihgUG9zaXRpb24gJHtwb3NpdGlvbn0gaXMgb3V0IG9mIGJvdW5kcy5gKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gIFxyXG4gICAgLy8gSW5zZXJ0IHRoZSBoZWFkZXIgaWYgcHJvdmlkZWRcclxuICAgIGxldCB0aGVhZCA9IHRhYmxlLnRIZWFkO1xyXG4gICAgaWYgKGhlYWRlclRpdGxlICYmIHRoZWFkKSB7XHJcbiAgICAgIGxldCB0aCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RoJyk7XHJcbiAgICAgIHRoLmlubmVySFRNTCA9IGhlYWRlclRpdGxlOyAvLyBVc2UgaW5uZXJIVE1MIHRvIGluc2VydCBIVE1MIGNvbnRlbnRcclxuICAgICAgdGhlYWQucm93c1swXS5pbnNlcnRCZWZvcmUodGgsIHRoZWFkLnJvd3NbMF0uY2VsbHNbcG9zaXRpb25dKTtcclxuICAgIH1cclxuICBcclxuICAgIC8vIEluc2VydCBuZXcgY2VsbHMgaW50byBlYWNoIHJvdyBvZiB0aGUgdGFibGUgYm9keVxyXG4gICAgbGV0IHRib2R5ID0gdGFibGUudEJvZGllc1swXTtcclxuICAgIGlmICh0Ym9keSkge1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRib2R5LnJvd3MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBsZXQgcm93ID0gdGJvZHkucm93c1tpXTtcclxuICAgICAgICBsZXQgdGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZCcpO1xyXG4gICAgICAgIHRkLmlubmVySFRNTCA9IGh0bWxDb250ZW50OyAvLyBVc2UgaW5uZXJIVE1MIHRvIGluc2VydCBIVE1MIGNvbnRlbnRcclxuICAgICAgICByb3cuaW5zZXJ0QmVmb3JlKHRkLCByb3cuY2VsbHNbcG9zaXRpb25dKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBuY29scygpe1xyXG4gICAgY29uc3QgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi10YWJsZScpO1xyXG4gICAgLy8gRW5zdXJlIHRoYXQgdGhlIHJvdyBleGlzdHMgYmVmb3JlIGNvdW50aW5nIHRoZSBjb2x1bW5zXHJcbiAgICByZXR1cm4gdGFibGUucm93c1swXS5jZWxscy5sZW5ndGg7XHJcbn1cclxuICBcclxuZnVuY3Rpb24gYWRkQ29sVG9FbmQoaHRtbENvbnRlbnRzID0gW10sIGhlYWRlclRpdGxlID0gJycpe1xyXG4gICAgLy8gY291bnQgY29sdW1ucyBhbmQgYWRkIG5ldyBjb2x1bW4gdG8gdGhlIGVuZFxyXG4gICAgY29uc3QgcG9zaXRpb24gPSBuY29scygnbWFpbi10YWJsZScpO1xyXG4gICAgYWRkQ29sKHBvc2l0aW9uLCBodG1sQ29udGVudHMsIGhlYWRlclRpdGxlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gYXNzaWduQ2xhc3NUb0NvbHVtbihoZWFkZXJOYW1lLCBjbGFzc05hbWUpIHtcclxuICAgIC8vIEdldCB0aGUgdGFibGUgZWxlbWVudCBieSBpdHMgSURcclxuICAgIGxldCB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYWluLXRhYmxlJyk7XHJcblxyXG4gICAgLy8gRmluZCB0aGUgaW5kZXggb2YgdGhlIGNvbHVtbiBieSBpdHMgaGVhZGVyIG5hbWVcclxuICAgIGNvbnN0IHRoZWFkID0gdGFibGUudEhlYWQ7XHJcbiAgICBsZXQgaGVhZGVyQ2VsbEluZGV4ID0gLTE7XHJcbiAgICBjb25zdCBoZWFkZXJDZWxscyA9IHRoZWFkLnJvd3NbMF0uY2VsbHM7IC8vIEFzc3VtaW5nIHRoZSBmaXJzdCByb3cgY29udGFpbnMgaGVhZGVyIGNlbGxzICg8dGg+KVxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWFkZXJDZWxscy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGlmIChoZWFkZXJDZWxsc1tpXS50ZXh0Q29udGVudC50cmltKCkgPT09IGhlYWRlck5hbWUpIHtcclxuICAgICAgICAgICAgLy8gYXNzaWduIHRoZSBjbGFzcyB0byB0aGUgaGVhZGVyIGNlbGxcclxuICAgICAgICAgICAgaGVhZGVyQ2VsbHNbaV0uY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xyXG4gICAgICAgICAgICBoZWFkZXJDZWxsSW5kZXggPSBpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZXJyb3IgY2hlY2tcclxuICAgIGlmIChoZWFkZXJDZWxsSW5kZXggPT09IC0xKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihgTm8gaGVhZGVyIGZvdW5kIHdpdGggbmFtZSBcIiR7aGVhZGVyTmFtZX1cImApO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICBcclxuICAgIC8vIEFzc2lnbiB0aGUgY2xhc3MgdG8gZWFjaCBjZWxsIGluIHRoZSBzcGVjaWZpZWQgY29sdW1uIGluZGV4IHdpdGhpbiB0aGUgdGJvZHlcclxuICAgIGxldCB0Ym9keSA9IHRhYmxlLnRCb2RpZXNbMF07XHJcbiAgICBpZiAodGJvZHkpIHtcclxuICAgICAgbGV0IGJvZHlSb3dzID0gdGJvZHkucm93cztcclxuICAgICAgZm9yIChsZXQgcm93IG9mIGJvZHlSb3dzKSB7XHJcbiAgICAgICAgaWYgKHJvdy5jZWxsc1toZWFkZXJDZWxsSW5kZXhdKSB7XHJcbiAgICAgICAgICByb3cuY2VsbHNbaGVhZGVyQ2VsbEluZGV4XS5jbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuZnVuY3Rpb24gYWRkQ29zdENsYXNzKGhlYWRlck5hbWUpe1xyXG4gICAgYXNzaWduQ2xhc3NUb0NvbHVtbiggaGVhZGVyTmFtZSwgJ2Nvc3QnKTtcclxuXHJcbiAgICAvLyBHZXQgYWxsIHRoZSBjZWxscyB3aXRoIHRoZSBzcGVjaWZpZWQgY2xhc3MgbmFtZVxyXG4gICAgY29uc3QgY2VsbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGB0ZC5jb3N0YCk7XHJcbiAgICAgIFxyXG4gICAgY2VsbHMuZm9yRWFjaChjZWxsID0+IHtcclxuICAgICAgICAvLyBHZXQgdGhlIGN1cnJlbnQgdGV4dCBjb250ZW50IG9mIHRoZSBjZWxsIGFuZCBhc3NpZ24gaXQgdG8gJ3ZhbHVlJyBhdHRyaWJ1dGVcclxuICAgICAgICBpZiAoIWNlbGwuZ2V0QXR0cmlidXRlKCd2YWx1ZScpKXtcclxuICAgICAgICAgICAgY29uc3QgY2VsbFRleHQgPSBjZWxsLnRleHRDb250ZW50LnRyaW0oKTtcclxuICAgICAgICAgICAgY29uc3QgY2VsbFZhbHVlID0gaXNOYU4oY2VsbFRleHQpIHx8IGNlbGxUZXh0ID09PSAnJyA/IDAgOiBwYXJzZUZsb2F0KGNlbGxUZXh0KTtcclxuICAgICAgICAgICAgY2VsbC5zZXRBdHRyaWJ1dGUoJ3ZhbHVlJywgY2VsbFZhbHVlKTtcclxuXHJcbiAgICAgICAgICAgIC8vIE5vdyBmb3JtYXQgdGhlIHRleHQgY29udGVudCBsaWtlIGN1cnJlbmN5IGFuZCByZXBsYWNlIGl0IGluIHRoZSBjZWxsXHJcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZEN1cnJlbmN5ID0gZm9ybWF0Q3VycmVuY3kocGFyc2VGbG9hdChjZWxsVmFsdWUpKTtcclxuICAgICAgICAgICAgY2VsbC50ZXh0Q29udGVudCA9IGZvcm1hdHRlZEN1cnJlbmN5O1xyXG4gICAgICAgIH1cclxuICAgICAgXHJcbiAgICB9KTtcclxuXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFzc2lnbkNvbHVtbkNsYXNzZXMoY29sdW1uRGVmaW5pdGlvbnMpIHtcclxuICAgIGNvbHVtbkRlZmluaXRpb25zLmZvckVhY2goY29sdW1uID0+IHtcclxuICAgICAgICAvLyBBc3NpZ24gY2xhc3MgdG8gY29sdW1uXHJcbiAgICAgICAgYXNzaWduQ2xhc3NUb0NvbHVtbihjb2x1bW4udGl0bGUsIGNvbHVtbi5jbGFzc05hbWUpO1xyXG5cclxuICAgICAgICAvLyBJZiB0aGUgY29sdW1uIGlzIGEgY29zdCBjb2x1bW4sIGFkZCB0aGUgc3BlY2lmaWMgY29zdCBjbGFzc1xyXG4gICAgICAgIGlmIChjb2x1bW4uaXNDb3N0KSB7XHJcbiAgICAgICAgICAgIGFkZENvc3RDbGFzcyhjb2x1bW4udGl0bGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gc2hvdyB0aGUgY29sdW1uXHJcbiAgICAgICAgaWYgKCFjb2x1bW4uaGlkZSl7XHJcbiAgICAgICAgICAgIHNob3dDb2x1bW5CeVRpdGxlKGNvbHVtbi50aXRsZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGhpZGVDb2x1bW4oaW5kZXgpIHtcclxuICB2YXIgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi10YWJsZScpO1xyXG4gIHZhciByb3dzID0gdGFibGUucm93cztcclxuXHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIHZhciBjZWxscyA9IHJvd3NbaV0uY2VsbHM7XHJcbiAgICAgIGlmIChjZWxscy5sZW5ndGggPiBpbmRleCkge1xyXG4gICAgICAgICAgY2VsbHNbaW5kZXhdLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgIH1cclxuICB9XHJcbn1cclxuXHJcbi8vIEZ1bmN0aW9uIHRvIHNob3cgYSBzcGVjaWZpYyBjb2x1bW5cclxuZnVuY3Rpb24gc2hvd0NvbHVtbihpbmRleCkge1xyXG4gIHZhciB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtYWluLXRhYmxlJyk7XHJcbiAgdmFyIHJvd3MgPSB0YWJsZS5yb3dzO1xyXG5cclxuICBmb3IgKHZhciBpID0gMDsgaSA8IHJvd3MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgdmFyIGNlbGxzID0gcm93c1tpXS5jZWxscztcclxuICAgICAgaWYgKGNlbGxzLmxlbmd0aCA+IGluZGV4KSB7XHJcbiAgICAgICAgICBjZWxsc1tpbmRleF0uc3R5bGUuZGlzcGxheSA9ICd0YWJsZS1jZWxsJztcclxuICAgICAgfVxyXG4gIH1cclxufVxyXG5cclxuLy8gRnVuY3Rpb24gdG8gZ2V0IHRoZSBjb2x1bW4gaW5kZXggYnkgdGl0bGVcclxuZnVuY3Rpb24gZ2V0Q29sdW1uSW5kZXhCeVRpdGxlKHRhYmxlLCB0aXRsZSkge1xyXG4gIHZhciBoZWFkZXJzID0gdGFibGUucXVlcnlTZWxlY3RvckFsbCgndGgnKTtcclxuICBmb3IgKHZhciBpID0gMDsgaSA8IGhlYWRlcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgaWYgKGhlYWRlcnNbaV0uaW5uZXJUZXh0ID09PSB0aXRsZSkge1xyXG4gICAgICAgICAgcmV0dXJuIGk7XHJcbiAgICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIC0xOyAvLyBDb2x1bW4gbm90IGZvdW5kXHJcbn1cclxuXHJcbi8vIEZ1bmN0aW9uIHRvIGhpZGUgYSBjb2x1bW4gYnkgdGl0bGVcclxuZnVuY3Rpb24gaGlkZUNvbHVtbkJ5VGl0bGUodGl0bGUpIHtcclxuICB2YXIgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi10YWJsZScpO1xyXG4gIHZhciBpbmRleCA9IGdldENvbHVtbkluZGV4QnlUaXRsZSh0YWJsZSwgdGl0bGUpO1xyXG4gIGlmIChpbmRleCAhPT0gLTEpIHtcclxuICAgICAgaGlkZUNvbHVtbihpbmRleCk7XHJcbiAgfSBlbHNlIHtcclxuICAgICAgY29uc29sZS5sb2coYENvbHVtbiB3aXRoIHRpdGxlIFwiJHt0aXRsZX1cIiBub3QgZm91bmQuYCk7XHJcbiAgfVxyXG59XHJcblxyXG4vLyBGdW5jdGlvbiB0byBzaG93IGEgY29sdW1uIGJ5IHRpdGxlXHJcbmZ1bmN0aW9uIHNob3dDb2x1bW5CeVRpdGxlKHRpdGxlKSB7XHJcbiAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuICB2YXIgaW5kZXggPSBnZXRDb2x1bW5JbmRleEJ5VGl0bGUodGFibGUsIHRpdGxlKTtcclxuICBpZiAoaW5kZXggIT09IC0xKSB7XHJcbiAgICAgIHNob3dDb2x1bW4oaW5kZXgpO1xyXG4gIH0gZWxzZSB7XHJcbiAgICAgIGNvbnNvbGUubG9nKGBDb2x1bW4gd2l0aCB0aXRsZSBcIiR7dGl0bGV9XCIgbm90IGZvdW5kLmApO1xyXG4gIH1cclxufVxyXG5cclxuXHJcbmNvbnN0IENvbHVtbiA9IHtcclxuICBhZGQ6IGZ1bmN0aW9uKHBvc2l0aW9uLCBodG1sQ29udGVudCwgaGVhZGVyVGl0bGUpIHtcclxuICAgICAgcmV0dXJuIGFkZENvbChwb3NpdGlvbiwgaHRtbENvbnRlbnQsIGhlYWRlclRpdGxlKTtcclxuICB9LFxyXG4gIGFkZEF0RW5kOiBmdW5jdGlvbihodG1sQ29udGVudCwgaGVhZGVyVGl0bGUpIHtcclxuICAgICAgcmV0dXJuIGFkZENvbFRvRW5kKGh0bWxDb250ZW50LCBoZWFkZXJUaXRsZSk7XHJcbiAgfSxcclxuICBhc3NpZ25DbGFzc2VzOiBmdW5jdGlvbihjb2x1bW5fZGVmaW5pdGlvbnMpIHtcclxuICAgICAgcmV0dXJuIGFzc2lnbkNvbHVtbkNsYXNzZXMoY29sdW1uX2RlZmluaXRpb25zKTtcclxuICB9LFxyXG4gIGhpZGUgOiBmdW5jdGlvbihjb2xOYW1lKSB7XHJcbiAgICAgIGhpZGVDb2x1bW5CeVRpdGxlKGNvbE5hbWUpO1xyXG4gIH0sXHJcbiAgc2hvdyA6IGZ1bmN0aW9uKGNvbE5hbWUpIHtcclxuICAgICAgc2hvd0NvbHVtbkJ5VGl0bGUoY29sTmFtZSk7XHJcbiAgfVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ29sdW1uOyIsImltcG9ydCBGdW5kTG9va3VwVGFibGUgZnJvbSAnLi4vLi4vLi4vbW9kZWxzL2Z1bmRfbG9va3VwX3RhYmxlLmpzJztcclxuaW1wb3J0IEN1cnJlbnRGdW5kIGZyb20gJy4uLy4uLy4uL21vZGVscy9jdXJyZW50X2Z1bmQuanMnXHJcbmltcG9ydCBDdXJyZW50UGFnZSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvY3VycmVudF9wYWdlLmpzJ1xyXG5pbXBvcnQgVGFibGUgZnJvbSAnLi4vdGFibGUuanMnO1xyXG5cclxuZnVuY3Rpb24gZmlsbFRhYmxlKGRhdGEpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgY29uc3QgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi10YWJsZScpO1xyXG4gICAgICAgIGNvbnN0IHRoZWFkID0gdGFibGUucXVlcnlTZWxlY3RvcigndGhlYWQnKTtcclxuICAgICAgICBjb25zdCB0Ym9keSA9IHRhYmxlLnF1ZXJ5U2VsZWN0b3IoJ3Rib2R5Jyk7XHJcblxyXG4gICAgICAgIC8vIGNsZWFyIGV4aXN0aW5nIGRhdGFcclxuICAgICAgICB0aGVhZC5pbm5lckhUTUwgPSAnJztcclxuICAgICAgICB0Ym9keS5pbm5lckhUTUwgPSAnJztcclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlIHRhYmxlIGhlYWRlciByb3dcclxuICAgICAgICBjb25zdCBoZWFkZXJSb3cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0cicpO1xyXG4gICAgICAgIE9iamVjdC5rZXlzKGRhdGFbMF0pLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICAgICAgY29uc3QgaGVhZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGgnKTtcclxuICAgICAgICAgICAgaGVhZGVyLnRleHRDb250ZW50ID0ga2V5O1xyXG4gICAgICAgICAgICBoZWFkZXJSb3cuYXBwZW5kQ2hpbGQoaGVhZGVyKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGVhZC5hcHBlbmRDaGlsZChoZWFkZXJSb3cpO1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgdGFibGUgYm9keSByb3dzXHJcbiAgICAgICAgZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xyXG4gICAgICAgICAgICBjb25zdCByb3cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0cicpO1xyXG4gICAgICAgICAgICBPYmplY3QudmFsdWVzKGl0ZW0pLmZvckVhY2godmFsID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNlbGwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZCcpO1xyXG4gICAgICAgICAgICAgICAgY2VsbC5pbm5lckhUTUwgPSB2YWw7XHJcbiAgICAgICAgICAgICAgICByb3cuYXBwZW5kQ2hpbGQoY2VsbCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0Ym9keS5hcHBlbmRDaGlsZChyb3cpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSBjYXRjaChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ05vIHRhYmxlIHNhdmVkIGluIGxvY2FsU3RvcmFnZTonLCBlcnJvcik7XHJcbiAgICB9XHJcbn1cclxuXHJcbmFzeW5jIGZ1bmN0aW9uIGxvYWRGcm9tU3RvcmFnZSgpe1xyXG4gICAgLy8gbG9vayB1cCB0YWJsZSBuYW1lIGluIHN0b3JhZ2VcclxuICAgIGlmIChDdXJyZW50RnVuZC5udW1iZXIoKSl7XHJcbiAgICAgICAgdmFyIGtleSA9IGAke0N1cnJlbnRQYWdlLmxvYWQoKX1fJHtDdXJyZW50RnVuZC5udW1iZXIoKX1gO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB2YXIga2V5ID0gQ3VycmVudFBhZ2UubG9hZCgpO1xyXG4gICAgfVxyXG4gICAgLy8gbG9hZCBmcm9tIGxvY2FsIHN0b3JhZ2VcclxuICAgIGNvbnN0IGRhdGEgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShrZXkpO1xyXG4gICAgLy8gaWYgbm90aGluZyBpbiBzdG9yYWdlLCByZXR1cm4gYSB6ZXJvXHJcbiAgICBpZiAoICFkYXRhICkge1xyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBvdGhlcndpc2UsIGZpbGwgdGFibGUgaW4gSFRNTCBhbmQgcmV0dXJuIHN1Y2Nlc3MgKDEpXHJcbiAgICAgICAgVGFibGUuc2hvdygpO1xyXG4gICAgICAgIGZpbGxUYWJsZShhd2FpdCBKU09OLnBhcnNlKGRhdGEpKTtcclxuICAgICAgICByZXR1cm4gMTtcclxuICAgIH1cclxufVxyXG5cclxuXHJcbmZ1bmN0aW9uIGxvYWRGdW5kcygpe1xyXG4gICAgLy8gZ2V0IGxpc3Qgb2YgZnVuZHMgZnJvbSBzdG9yYWdlXHJcbiAgICBjb25zdCBmdW5kRGljdCA9IEZ1bmRMb29rdXBUYWJsZS5yZXRyaWV2ZSgpO1xyXG4gICAgLy8gYnVpbGQgb3V0IGRhdGEgaW4gY29ycmVjdCBmb3JtYXRcclxuICAgIGNvbnN0IHJldCA9IFtdO1xyXG4gICAgT2JqZWN0LmtleXMoZnVuZERpY3QpLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICAvLyBkZXRlcm1pbmUgaWYgdGhlIGZ1bmQgaGFzIGFscmVhZHkgYmVlbiBlZGl0ZWRcclxuICAgICAgICBpZiAoZnVuZERpY3Rba2V5XVsndmlld2VkJ10pe1xyXG4gICAgICAgICAgICAvLyB0b2RvOiBhZGQgYSBjaGVja21hcmsgaGVyZVxyXG4gICAgICAgICAgICByZXQucHVzaCh7J0Z1bmQnIDogIGA8c3BhbiBjbGFzcyA9ICd2aWV3ZWQtZnVuZCc+IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1jaGVja1wiPjwvaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtmdW5kRGljdFtrZXldWyduYW1lJ119XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPmB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXQucHVzaCh7J0Z1bmQnIDogYDxzcGFuIGNsYXNzID0gJ3Vudmlld2VkLWZ1bmQnPiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtmdW5kRGljdFtrZXldWyduYW1lJ119XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPmB9KTsgICBcclxuICAgICAgICB9XHJcbiAgICB9KTtcclxuICAgIGZpbGxUYWJsZShyZXQpO1xyXG59XHJcblxyXG5cclxuZnVuY3Rpb24gZ2V0Q29sdW1uSW5kZXhCeUNsYXNzKHRib2R5LCBjbGFzc05hbWUpIHtcclxuICBjb25zdCBmaXJzdFJvdyA9IHRib2R5LnJvd3NbMF07XHJcbiAgaWYgKCFmaXJzdFJvdykgcmV0dXJuIC0xOyAvLyBSZXR1cm4gLTEgaWYgdGhlcmUncyBubyByb3cgdG8gZXhhbWluZVxyXG4gIGZvciAobGV0IGNlbGxJbmRleCA9IDA7IGNlbGxJbmRleCA8IGZpcnN0Um93LmNlbGxzLmxlbmd0aDsgY2VsbEluZGV4KyspIHtcclxuICAgICAgaWYgKGZpcnN0Um93LmNlbGxzW2NlbGxJbmRleF0uY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSkpIHtcclxuICAgICAgICAgIHJldHVybiBjZWxsSW5kZXg7XHJcbiAgICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIC0xOyAvLyBSZXR1cm4gLTEgaWYgY2xhc3MgbmFtZSBub3QgZm91bmRcclxufVxyXG5cclxuLy8gZnVuY3Rpb24gc29ydChwcmltYXJ5Q2xhc3MsIHNlY29uZGFyeUNsYXNzKSB7XHJcbi8vICAgY29uc3QgdGFibGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi10YWJsZScpO1xyXG4vLyAgIGNvbnN0IHRib2R5ID0gdGFibGUudEJvZGllc1swXTtcclxuLy8gICBjb25zdCByb3dzID0gQXJyYXkuZnJvbSh0Ym9keS5yb3dzKTtcclxuXHJcbi8vICAgLy8gR2V0IHRoZSBjb2x1bW4gaW5kaWNlcyBieSBjbGFzcyBuYW1lXHJcbi8vICAgY29uc3QgcHJpbWFyeUNvbEluZGV4ID0gZ2V0Q29sdW1uSW5kZXhCeUNsYXNzKHRib2R5LCBwcmltYXJ5Q2xhc3MpO1xyXG4vLyAgIGNvbnN0IHNlY29uZGFyeUNvbEluZGV4ID0gZ2V0Q29sdW1uSW5kZXhCeUNsYXNzKHRib2R5LCBzZWNvbmRhcnlDbGFzcyk7XHJcblxyXG4vLyAgIC8vIGV4aXQgaWYgY2xhc3NlcyBkb24ndCBleGlzdFxyXG4vLyAgIGlmIChwcmltYXJ5Q29sSW5kZXggPT09IC0xICkge1xyXG4vLyAgICAgICBjb25zb2xlLmVycm9yKGBDb2x1bW4gY2xhc3MgJHtjbGFzc0F9IG5vdCBmb3VuZCBpbiB0YWJsZWApO1xyXG4vLyAgICAgICByZXR1cm47IFxyXG4vLyAgIH0gZWxzZSBpZiAoc2Vjb25kYXJ5Q29sSW5kZXggPT09IC0xKSB7XHJcbi8vICAgICAgIGNvbnNvbGUuZXJyb3IoYENvbHVtbiBjbGFzcyAke2NsYXNzQn0gbm90IGZvdW5kIGluIHRhYmxlYCk7XHJcbi8vICAgICAgIHJldHVybjsgXHJcbi8vICAgfVxyXG5cclxuLy8gICAvLyBTb3J0IHRoZSByb3dzIGJhc2VkIG9uIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhlIGNlbGxzXHJcbi8vICAgcm93cy5zb3J0KChyb3dBLCByb3dCKSA9PiB7XHJcbi8vICAgICAgIC8vIFByaW1hcnkgY29sdW1uIGNvbXBhcmlzb25cclxuLy8gICAgICAgY29uc3QgcHJpbWFyeUEgPSB1bmZvcm1hdEN1cnJlbmN5KHJvd0EuY2VsbHNbcHJpbWFyeUNvbEluZGV4XS50ZXh0Q29udGVudCk7XHJcbi8vICAgICAgIGNvbnN0IHByaW1hcnlCID0gdW5mb3JtYXRDdXJyZW5jeShyb3dCLmNlbGxzW3ByaW1hcnlDb2xJbmRleF0udGV4dENvbnRlbnQpO1xyXG5cclxuLy8gICAgICAgaWYgKHByaW1hcnlBIDwgcHJpbWFyeUIpIHJldHVybiAtMTtcclxuLy8gICAgICAgaWYgKHByaW1hcnlBID4gcHJpbWFyeUIpIHJldHVybiAxO1xyXG5cclxuLy8gICAgICAgLy8gU2Vjb25kYXJ5IGNvbHVtbiBjb21wYXJpc29uIChpZiBwcmltYXJ5IGlzIGVxdWFsKVxyXG4vLyAgICAgICBjb25zdCBzZWNvbmRhcnlBID0gdW5mb3JtYXRDdXJyZW5jeShyb3dBLmNlbGxzW3NlY29uZGFyeUNvbEluZGV4XS50ZXh0Q29udGVudCk7XHJcbi8vICAgICAgIGNvbnN0IHNlY29uZGFyeUIgPSB1bmZvcm1hdEN1cnJlbmN5KHJvd0IuY2VsbHNbc2Vjb25kYXJ5Q29sSW5kZXhdLnRleHRDb250ZW50KTtcclxuXHJcbi8vICAgICAgIGlmIChzZWNvbmRhcnlBIDwgc2Vjb25kYXJ5QikgcmV0dXJuIC0xO1xyXG4vLyAgICAgICBpZiAoc2Vjb25kYXJ5QSA+IHNlY29uZGFyeUIpIHJldHVybiAxO1xyXG5cclxuLy8gICAgICAgLy8gSWYgYm90aCBjb2x1bW5zIGFyZSBlcXVhbFxyXG4vLyAgICAgICByZXR1cm4gMDtcclxuLy8gICB9KTtcclxuXHJcbi8vICAgLy8gUmVhdHRhY2ggc29ydGVkIHJvd3MgdG8gdGhlIHRhYmxlIGJvZHlcclxuLy8gICByb3dzLmZvckVhY2goKHJvdykgPT4gdGJvZHkuYXBwZW5kQ2hpbGQocm93KSk7XHJcbi8vIH1cclxuXHJcblxyXG5leHBvcnQgY29uc3QgRGF0YSA9IHtcclxuICAgIGxvYWQgOiBsb2FkRnJvbVN0b3JhZ2UsXHJcbiAgICBsb2FkRnVuZHMgOiBsb2FkRnVuZHMsXHJcbiAgICBzb3J0IDogZnVuY3Rpb24oY29sQSwgY29sQikgeyBzb3J0KGNvbEEsIGNvbEIpIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgRGF0YTsiLCIvLyBIZWxwZXIgZnVuY3Rpb25zICYgY29uc3RhbnRzXHJcblxyXG4vLyBvYmplY3QgdG8gaG9sZCBhbGwgY3VycmVudCBmaWx0ZXIgc3RhdHVzZXNcclxuY29uc3QgZmlsdGVyU2V0dGluZ3MgPSB7XHJcbiAgICAnYXBwcm9wLW5hbWUnOiAnJyxcclxuICAgICdjYy1uYW1lJzogJycsXHJcbiAgICAnb2JqZWN0LW5hbWUnOiAnJyxcclxuICAgICdvYmplY3QtY2F0ZWdvcnknOiAnJ1xyXG59O1xyXG5cclxuLy8gaGVscGVyIGZ1bmN0aW9uIHRvIGZpbHRlciBkYXRhIGJhc2VkIG9uIGFsbCBmaWx0ZXJzXHJcbmZ1bmN0aW9uIGZpbHRlckRhdGEoKSB7XHJcbiAgICAvLyBHZXQgYWxsIHJvd3MgaW4gdGhlIHRhYmxlXHJcbiAgICBjb25zdCByb3dzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI21haW4tdGFibGUgdGJvZHkgdHInKTtcclxuICAgIFxyXG4gICAgLy8gSXRlcmF0ZSB0aHJvdWdoIGVhY2ggcm93IGFuZCBkZXRlcm1pbmUgaWYgaXQgc2hvdWxkIGJlIGhpZGRlbiBvciBzaG93blxyXG4gICAgcm93cy5mb3JFYWNoKHJvdyA9PiB7XHJcbiAgICAgICAgbGV0IGlzVmlzaWJsZSA9IHRydWU7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gQ2hlY2sgZWFjaCBmaWx0ZXIgc2V0dGluZyBhZ2FpbnN0IHRoZSByb3cncyBjZWxsc1xyXG4gICAgICAgIGZvciAoY29uc3QgW2ZpbHRlcklkLCBmaWx0ZXJWYWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZmlsdGVyU2V0dGluZ3MpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNlbGwgPSByb3cucXVlcnlTZWxlY3RvcihgLiR7ZmlsdGVySWR9YCk7XHJcblxyXG4gICAgICAgICAgICAvLyBvbmx5IHNob3cgcm93IGlmIHZhbHVlcyBwYXNzIHRocm91Z2ggYWxsIGZpbHRlcnMgXHJcbiAgICAgICAgICAgIGlmIChmaWx0ZXJWYWx1ZSAmJiBjZWxsICYmIChjZWxsLnRleHRDb250ZW50LnRyaW0oKSAhPT0gZmlsdGVyVmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgICBpc1Zpc2libGUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9IFxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU2hvdyBvciBoaWRlIHRoZSByb3cgYmFzZWQgb24gdmlzaWJpbGl0eVxyXG4gICAgICAgIHJvdy5jbGFzc0xpc3QudG9nZ2xlKCdoaWRkZW4nLCAhaXNWaXNpYmxlKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5jb25zdCBGaWx0ZXIgPSB7XHJcbiAgICBodG1sKGZpbHRlckxhYmVsLCBmaWx0ZXJDbGFzcykge1xyXG4gICAgICAgIC8vIGJhc2ljIGh0bWwgd2l0aCBvbmx5ICdBbGwnIG9wdGlvblxyXG4gICAgICAgIHJldHVybiBgPGxhYmVsIGZvcj1cImZpbHRlci0ke2ZpbHRlckNsYXNzfVwiPkZpbHRlciBieSAke2ZpbHRlckxhYmVsfTo8L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgPHNlbGVjdCBpZD1cImZpbHRlci0ke2ZpbHRlckNsYXNzfVwiIGNsYXNzPVwiZmlsdGVyLWRyb3Bkb3duXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPkFsbDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgPC9zZWxlY3Q+YFxyXG4gICAgfSxcclxuXHJcbiAgICBhZGRPcHRpb24oZmlsdGVyQ2xhc3MsIG9wdGlvbikge1xyXG4gICAgICAgIC8vIEFkZCBhbm90aGVyIG9wdGlvbiB0byB0aGUgZHJvcGRvd24gZm9yIHRoZSBmaWx0ZXJcclxuICAgICAgICBjb25zdCBmaWx0ZXJPYmogPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAjZmlsdGVyLSR7ZmlsdGVyQ2xhc3N9YCk7XHJcbiAgICAgICAgY29uc3Qgb3B0aW9uT2JqID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb3B0aW9uJyk7XHJcbiAgICAgICAgb3B0aW9uT2JqLnZhbHVlID0gb3B0aW9uO1xyXG4gICAgICAgIG9wdGlvbk9iai50ZXh0Q29udGVudCA9IG9wdGlvbjtcclxuICAgICAgICBmaWx0ZXJPYmouYXBwZW5kQ2hpbGQob3B0aW9uT2JqKTtcclxuICAgIH0sXHJcblxyXG4gICAgYWRkKGZpbHRlckxhYmVsLCBmaWx0ZXJDbGFzcykge1xyXG4gICAgICAgIC8vIGNyZWF0ZSBhIGRpdiB0byBjb250YWluIHRoZSBodG1sIGFuZCBpbnNlcnQgaW5zaWRlIGZpbHRlci1jb250YWluZXJcclxuICAgICAgICBjb25zdCBmaWx0ZXJDb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZmlsdGVyLWNvbnRhaW5lcicpO1xyXG4gICAgICAgIGNvbnN0IGZpbHRlckRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG4gICAgICAgIGZpbHRlckRpdi5pbm5lckhUTUwgPSB0aGlzLmh0bWwoZmlsdGVyTGFiZWwsIGZpbHRlckNsYXNzKTtcclxuICAgICAgICBmaWx0ZXJDb250YWluZXIuYXBwZW5kQ2hpbGQoZmlsdGVyRGl2KTtcclxuICAgICAgICAvLyBhZGQgYWxsIHJlbGV2YW50IG9wdGlvbnMgZnJvbSB0aGF0IGNvbHVtbiBpbiB0aGUgdGFibGVcclxuICAgICAgICB0aGlzLmFkZEFsbE9wdGlvbnMoZmlsdGVyQ2xhc3MpO1xyXG4gICAgICAgIC8vIEJpbmQgY2hhbmdlIGV2ZW50IHRvIHRoZSBzZWxlY3QgZWxlbWVudFxyXG4gICAgICAgIGZpbHRlckRpdi5xdWVyeVNlbGVjdG9yKCcuZmlsdGVyLWRyb3Bkb3duJykuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZXZlbnQgPT4ge1xyXG4gICAgICAgICAgICAvLyBVcGRhdGUgZmlsdGVyIHNldHRpbmdzXHJcbiAgICAgICAgICAgIGZpbHRlclNldHRpbmdzW2ZpbHRlckNsYXNzXSA9IGV2ZW50LnRhcmdldC52YWx1ZTtcclxuICAgICAgICAgICAgLy8gQXBwbHkgYWxsIGZpbHRlcnNcclxuICAgICAgICAgICAgZmlsdGVyRGF0YSgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICBhZGRBbGxPcHRpb25zKGZpbHRlckNsYXNzKSB7XHJcbiAgICAgICAgLy8gZ2V0IG1hdGNoaW5nIGNvbHVtbiBmcm9tIHRhYmxlXHJcbiAgICAgICAgY29uc3QgY29sdW1uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgI21haW4tdGFibGUgdGQuJHtmaWx0ZXJDbGFzc31gKTtcclxuXHJcbiAgICAgICAgLy8gVXNlIGEgU2V0IHRvIHN0b3JlIHVuaXF1ZSB2YWx1ZXMgaW4gdGhlIGNvbHVtbiBvZiBpbnRlcmVzdFxyXG4gICAgICAgIGNvbnN0IHVuaXF1ZVZhbHVlcyA9IG5ldyBTZXQoKTtcclxuICAgICAgICBcclxuICAgICAgICAvLyBJdGVyYXRlIG92ZXIgdGhlIE5vZGVMaXN0IHRvIGdldCB0aGUgdW5pcXVlIHZhbHVlc1xyXG4gICAgICAgIGNvbHVtbi5mb3JFYWNoKHRkID0+IHtcclxuICAgICAgICAgICAgLy8gQWRkIGVhY2ggdGV4dENvbnRlbnQgdG8gdGhlIFNldFxyXG4gICAgICAgICAgICB1bmlxdWVWYWx1ZXMuYWRkKHRkLnRleHRDb250ZW50LnRyaW0oKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gYWRkIGFsbCB2YWx1ZXMgYXMgb3B0aW9ucyB0byB0aGUgZmlsdGVyIGRyb3Bkb3duXHJcbiAgICAgICAgdW5pcXVlVmFsdWVzLmZvckVhY2gob3B0aW9uID0+IHtcclxuICAgICAgICAgICAgdGhpcy5hZGRPcHRpb24oZmlsdGVyQ2xhc3MsIG9wdGlvbik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9LFxyXG5cclxuICAgIGRlbGV0ZUFsbCgpe1xyXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNmaWx0ZXItY29udGFpbmVyJykuaW5uZXJIVE1MID0gJyc7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEZpbHRlcjsiLCJcclxuXHJcbmltcG9ydCB7IFNIRUVUUywgVEFSR0VUX0NFTExfQUREUkVTUyB9IGZyb20gJy4uL2NvbnN0YW50cy8nO1xyXG5pbXBvcnQgRnVuZExvb2t1cFRhYmxlIGZyb20gJy4uL21vZGVscy9mdW5kX2xvb2t1cF90YWJsZS5qcyc7XHJcbmltcG9ydCB7IHJlbW92ZU5ld0xpbmVzIH0gZnJvbSAnLi9jb21tb25fdXRpbHMuanMnO1xyXG5pbXBvcnQgQmFzZWxpbmUgZnJvbSAnLi4vbW9kZWxzL2Jhc2VsaW5lLmpzJztcclxuaW1wb3J0IFNlcnZpY2VzIGZyb20gJy4uL21vZGVscy9zZXJ2aWNlcy5qcyc7XHJcblxyXG5mdW5jdGlvbiBkZWxldGVUb3BSb3dzVW50aWxGdWxsRGF0YShkYXRhKSB7XHJcbiAgICAvLyBmdW5jdGlvbiB0byB0cnkgdG8gZmluZCB0aGUgdG9wIG9mIHRoZSB1c2FibGUgZGF0YVxyXG4gICAgbGV0IGZ1bGxEYXRhUm93Rm91bmQgPSBmYWxzZTtcclxuXHJcbiAgICB3aGlsZSAoIWZ1bGxEYXRhUm93Rm91bmQgJiYgZGF0YS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgY29uc3Qgcm93ID0gZGF0YVswXTsgLy8gR2V0IHRoZSB0b3Agcm93XHJcbiAgICAgICAgbGV0IGhhc0FsbERhdGEgPSB0cnVlO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IGNlbGwgb2Ygcm93KSB7XHJcbiAgICAgICAgICAgIGlmIChjZWxsID09IG51bGwgfHwgY2VsbCA9PT0gJycpIHtcclxuICAgICAgICAgICAgICAgIGhhc0FsbERhdGEgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoaGFzQWxsRGF0YSAmJiByb3cubGVuZ3RoID4gMSkge1xyXG4gICAgICAgICAgICBmdWxsRGF0YVJvd0ZvdW5kID0gdHJ1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBkZWxldGUgdGhlIHRvcCByb3cgaWYgaXQncyBub3QgdGhlIGhlYWRlciByb3dcclxuICAgICAgICAgICAgZGF0YS5zaGlmdCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZGF0YTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHByb2Nlc3NXb3JrYm9vayhhcnJheUJ1ZmZlcikge1xyXG4gICAgY29uc3Qgd29ya2Jvb2sgPSBYTFNYLnJlYWQoYXJyYXlCdWZmZXIsIHsgdHlwZTogJ2FycmF5JyB9KTtcclxuICAgIHdvcmtib29rLlNoZWV0TmFtZXMuZm9yRWFjaChzaGVldE5hbWUgPT4ge1xyXG4gICAgICAgIC8vIG9ubHkgY29udmVydCBzaGVldHMgd2UgbmVlZFxyXG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhTSEVFVFMpLmluY2x1ZGVzKHNoZWV0TmFtZSkpIHtcclxuICAgICAgICAgICAgIC8vIHJlYWQgaW4gc2hlZXRzXHJcbiAgICAgICAgICAgIGNvbnN0IHNoZWV0ID0gd29ya2Jvb2suU2hlZXRzW3NoZWV0TmFtZV07XHJcbiAgICAgICAgICAgIGNvbnN0IHJhd0RhdGEgPSBYTFNYLnV0aWxzLnNoZWV0X3RvX2pzb24oc2hlZXQsIHsgaGVhZGVyOiAxLCBkZWZ2YWw6ICcnIH0pO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2xlYW4gdGhlIGRhdGEgYnkgcmVtb3ZpbmcgdG9wIHJvd3Mgd2l0aCBpbmNvbXBsZXRlIGRhdGFcclxuICAgICAgICAgICAgY29uc3QgZGF0YVJvd3MgPSBkZWxldGVUb3BSb3dzVW50aWxGdWxsRGF0YShyYXdEYXRhKTtcclxuXHJcbiAgICAgICAgICAgIC8vIGdldCBuZXcgaGVhZGVyc1xyXG4gICAgICAgICAgICBjb25zdCBoZWFkZXJzID0gZGF0YVJvd3NbMF07XHJcblxyXG4gICAgICAgICAgICAvLyBpc29sYXRlIEZ1bmQgY29sdW1uIHRvIHNwbGl0IGRhdGFcclxuICAgICAgICAgICAgY29uc3QgZnVuZEluZGV4ID0gaGVhZGVycy5pbmRleE9mKCdGdW5kJyk7XHJcbiAgICAgICAgICAgIGlmIChmdW5kSW5kZXggPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBObyAnRnVuZCcgY29sdW1uIGZvdW5kIGluIHNoZWV0ICR7c2hlZXROYW1lfWApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBTYXZlIGEgZGljdGlvbmFyeSBvZiBkYXRhIGZvciBlYWNoIGZ1bmQgZm9yIGVhY2ggc2hlZXRcclxuICAgICAgICAgICAgY29uc3QgZnVuZERhdGEgPSB7fTtcclxuXHJcbiAgICAgICAgICAgIGRhdGFSb3dzLmZvckVhY2gocm93ID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGZ1bmQgPSByb3dbZnVuZEluZGV4XTtcclxuICAgICAgICAgICAgICAgIGlmKGZ1bmQgJiYgZnVuZCAhPSBcIkZ1bmRcIil7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmdW5kRGF0YVtmdW5kXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmdW5kRGF0YVtmdW5kXSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCByb3dEYXRhID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVycy5mb3JFYWNoKChoZWFkZXIsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvd0RhdGFbcmVtb3ZlTmV3TGluZXMoaGVhZGVyKV0gPSByb3dbaW5kZXhdO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmREYXRhW2Z1bmRdLnB1c2gocm93RGF0YSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgLy8gc2F2ZSBmdW5kIG51bWJlciBhbmQgbmFtZSBhcyB3ZSBnbyBhbG9uZ1xyXG4gICAgICAgICAgICBGdW5kTG9va3VwVGFibGUudXBkYXRlKGZ1bmREYXRhKTsgICBcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ3VwZGF0aW5nIGZ1bmQgbG9va3VwIHRhYmxlJyk7ICAgICAgIFxyXG5cclxuICAgICAgICAgICAgT2JqZWN0LmtleXMoZnVuZERhdGEpLmZvckVhY2goZnVuZCA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSBgJHtTSEVFVFNbc2hlZXROYW1lXX1fJHtmdW5kfWA7XHJcbiAgICAgICAgICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShrZXksIEpTT04uc3RyaW5naWZ5KGZ1bmREYXRhW2Z1bmRdKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQnV0IGFsc28gc2F2ZSB0aGUgcG9zc2libGUgc2VydmljZXNcclxuICAgICAgICBlbHNlIGlmIChzaGVldE5hbWUgPT0gJ0Ryb3AtRG93biBNZW51cycpe1xyXG4gICAgICAgICAgICBjb25zdCBzaGVldCA9IHdvcmtib29rLlNoZWV0c1tzaGVldE5hbWVdO1xyXG4gICAgICAgICAgICAvLyBDb252ZXJ0IHRoZSBzaGVldCB0byBKU09OIHRvIGVhc2lseSBtYW5pcHVsYXRlIGRhdGFcclxuICAgICAgICAgICAgY29uc3Qgc2hlZXREYXRhID0gWExTWC51dGlscy5zaGVldF90b19qc29uKHNoZWV0LCB7IGhlYWRlcjogMSB9KTtcclxuXHJcbiAgICAgICAgICAgIC8vIExvY2F0ZSB0aGUgXCJzZXJ2aWNlc1wiIGNvbHVtbiBoZWFkZXIgaW4gcm93IDBcclxuICAgICAgICAgICAgY29uc3QgaGVhZGVyUm93ID0gc2hlZXREYXRhWzBdO1xyXG4gICAgICAgICAgICBjb25zdCBzZXJ2aWNlc0luZGV4ID0gaGVhZGVyUm93LmluZGV4T2YoJ1NlcnZpY2VzJyk7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2VydmljZXNJbmRleCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0hlYWRlciBcIlNlcnZpY2VzXCIgbm90IGZvdW5kJyk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IGRhdGEgZnJvbSB0aGUgXCJzZXJ2aWNlc1wiIGNvbHVtbiAoZXhjbHVkaW5nIHRoZSBoZWFkZXIgcm93KVxyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2VydmljZXNDb2x1bW4gPSBzaGVldERhdGEuc2xpY2UoMSkubWFwKHJvdyA9PiByb3dbc2VydmljZXNJbmRleF0pO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2xlYW5lZFNlcnZpY2VzQ29sdW1uID0gc2VydmljZXNDb2x1bW4uZmlsdGVyKHZhbHVlID0+IHZhbHVlICE9IG51bGwpO1xyXG4gICAgICAgICAgICAgICAgLy8gc2F2ZSB0aGUgZGF0YVxyXG4gICAgICAgICAgICAgICAgU2VydmljZXMuc2F2ZShjbGVhbmVkU2VydmljZXNDb2x1bW4pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBlbHNlIGlmKHNoZWV0TmFtZSA9PSAnRGVwdCBTdW1tYXJ5Jyl7XHJcbiAgICAgICAgICAgIGNvbnN0IHNoZWV0ID0gd29ya2Jvb2suU2hlZXRzW3NoZWV0TmFtZV07XHJcbiAgICAgICAgICAgIC8vIGdldCBhbmQgc2F2ZSBUQVJHRVQgZm9yIGdlbmVyYWwgZnVuZFxyXG4gICAgICAgICAgICBpZihzaGVldFtUQVJHRVRfQ0VMTF9BRERSRVNTXSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2VsbFZhbHVlID0gc2hlZXRbVEFSR0VUX0NFTExfQUREUkVTU10udjsgLy8gQWNjZXNzIHRoZSBjZWxsIHZhbHVlXHJcbiAgICAgICAgICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgndGFyZ2V0JywgY2VsbFZhbHVlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYENlbGwgJHtUQVJHRVRfQ0VMTF9BRERSRVNTfSBub3QgZm91bmQgaW4gc2hlZXQgJHtzaGVldE5hbWV9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb25zb2xlLmxvZygnYWxsIGV4Y2VsIGRhdGEgc2F2ZWQnKTtcclxufVxyXG5cclxuLy8gVXRpbGl0eSBmdW5jdGlvbiB0byBhcHBlbmQgYSBzaGVldCB0byB0aGUgd29ya2Jvb2sgaWYgZGF0YSBpcyBwcmVzZW50XHJcbmZ1bmN0aW9uIGFwcGVuZFNoZWV0VG9Xb3JrYm9vayh3b3JrYm9vaywgZGF0YSwgc2hlZXROYW1lKSB7XHJcbiAgICBpZiAoZGF0YS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgY29uc3Qgc2hlZXQgPSBYTFNYLnV0aWxzLmpzb25fdG9fc2hlZXQoZGF0YSk7XHJcbiAgICAgICAgWExTWC51dGlscy5ib29rX2FwcGVuZF9zaGVldCh3b3JrYm9vaywgc2hlZXQsIHNoZWV0TmFtZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBkb3dubG9hZFhMU1goKSB7XHJcbiAgICBjb25zdCBiYXNlbGluZSA9IG5ldyBCYXNlbGluZSgpO1xyXG4gICAgY29uc3Qgd29ya2Jvb2sgPSBYTFNYLnV0aWxzLmJvb2tfbmV3KCk7IC8vIENyZWF0ZSBhIG5ldyB3b3JrYm9va1xyXG5cclxuICAgIGNvbnN0IGRhdGFNYXAgPSB7XHJcbiAgICAgICAgUGVyc29ubmVsOiAncGVyc29ubmVsJyxcclxuICAgICAgICBPdmVydGltZTogJ292ZXJ0aW1lJyxcclxuICAgICAgICBOb25QZXJzb25uZWw6ICdub25wZXJzb25uZWwnLFxyXG4gICAgICAgIFJldmVudWU6ICdyZXZlbnVlJ1xyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBzaGVldERhdGEgPSB7XHJcbiAgICAgICAgUGVyc29ubmVsOiBbXSxcclxuICAgICAgICBPdmVydGltZTogW10sXHJcbiAgICAgICAgTm9uUGVyc29ubmVsOiBbXSxcclxuICAgICAgICBSZXZlbnVlOiBbXVxyXG4gICAgfTtcclxuXHJcbiAgICBiYXNlbGluZS5mdW5kcy5mb3JFYWNoKGZ1bmQgPT4ge1xyXG4gICAgICAgIE9iamVjdC5rZXlzKGRhdGFNYXApLmZvckVhY2goc2hlZXROYW1lID0+IHtcclxuICAgICAgICAgICAgaWYgKGZ1bmRbZGF0YU1hcFtzaGVldE5hbWVdXSAmJiBmdW5kW2RhdGFNYXBbc2hlZXROYW1lXV0udGFibGUpIHtcclxuICAgICAgICAgICAgICAgIHNoZWV0RGF0YVtzaGVldE5hbWVdLnB1c2goLi4uZnVuZFtkYXRhTWFwW3NoZWV0TmFtZV1dLnRhYmxlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgT2JqZWN0LmtleXMoc2hlZXREYXRhKS5mb3JFYWNoKHNoZWV0TmFtZSA9PiB7XHJcbiAgICAgICAgYXBwZW5kU2hlZXRUb1dvcmtib29rKHdvcmtib29rLCBzaGVldERhdGFbc2hlZXROYW1lXSwgc2hlZXROYW1lKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEdlbmVyYXRlIGEgZG93bmxvYWRhYmxlIGZpbGVcclxuICAgIGNvbnN0IHdib3V0ID0gWExTWC53cml0ZSh3b3JrYm9vaywgeyBib29rVHlwZTogJ3hsc3gnLCB0eXBlOiAnYXJyYXknIH0pO1xyXG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFt3Ym91dF0sIHsgdHlwZTogJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScgfSk7XHJcblxyXG4gICAgLy8gQ3JlYXRlIGEgbGluayBhbmQgdHJpZ2dlciB0aGUgZG93bmxvYWRcclxuICAgIGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcclxuICAgIGxpbmsuaHJlZiA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XHJcbiAgICBsaW5rLmRvd25sb2FkID0gXCJGaWxsZWRfRGV0YWlsX1NoZWV0Lnhsc3hcIjtcclxuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XHJcbiAgICBsaW5rLmNsaWNrKCk7XHJcbiAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGxpbmspO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZXhjZWxTZXJpYWxEYXRlVG9KU0RhdGUoc2VyaWFsKSB7XHJcblxyXG4gICAgaWYgKCFzZXJpYWwpIHsgcmV0dXJuIG51bGwgfTtcclxuICAgIC8vIEV4Y2VsIGNvbnNpZGVycyAxOTAwLTAxLTAxIGFzIGRheSAxLCBidXQgSmF2YVNjcmlwdCdzIERhdGUgY29uc2lkZXJzXHJcbiAgICAvLyAxOTcwLTAxLTAxIGFzIGRheSAwLiBUaGVyZWZvcmUsIHdlIGNhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kc1xyXG4gICAgLy8gYmV0d2VlbiAxOTAwLTAxLTAxIGFuZCAxOTcwLTAxLTAxLlxyXG4gICAgY29uc3QgZXhjZWxFcG9jaCA9IG5ldyBEYXRlKERhdGUuVVRDKDE4OTksIDExLCAzMCkpOyAvLyBKYXZhU2NyaXB0IENvbnNpZGVyIERlY2VtYmVyIG1vbnRoIGFzICcxMSdcclxuICAgIFxyXG4gICAgLy8gQ2FsY3VsYXRlIHRoZSBKUyBkYXRlIGJ5IGFkZGluZyBzZXJpYWwgZGF5cyB0byB0aGUgZXBvY2ggZGF0ZVxyXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKGV4Y2VsRXBvY2guZ2V0VGltZSgpICsgKHNlcmlhbCAqIDI0ICogNjAgKiA2MCAqIDEwMDApKTtcclxuICAgIFxyXG4gICAgLy8gU2V0IHRoZSB0aW1lIHBhcnQgdG8gemVybyAobWlkbmlnaHQpXHJcbiAgICBkYXRlLnNldFVUQ0hvdXJzKDAsIDAsIDAsIDApO1xyXG4gICAgXHJcbiAgICAvLyBSZXR1cm4gdGhlIGRhdGUgcGFydCBvZiB0aGUgSVNPIHN0cmluZ1xyXG4gICAgcmV0dXJuIGRhdGUudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdO1xyXG59XHJcbiIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi90b29sdGlwLmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xub3B0aW9ucy5pbnNlcnQgPSBpbnNlcnRGbi5iaW5kKG51bGwsIFwiaGVhZFwiKTtcbm9wdGlvbnMuZG9tQVBJID0gZG9tQVBJO1xub3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQgPSBpbnNlcnRTdHlsZUVsZW1lbnQ7XG5cbnZhciB1cGRhdGUgPSBBUEkoY29udGVudCwgb3B0aW9ucyk7XG5cblxuXG5leHBvcnQgKiBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3Rvb2x0aXAuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiaW1wb3J0IHsgRklTQ0FMX1lFQVIgfSBmcm9tICcuLi8uLi9jb25zdGFudHMvJztcclxuaW1wb3J0IENlbGwgZnJvbSAnLi4vdGFibGUvc3ViY29tcG9uZW50cy9jZWxscyc7XHJcbmltcG9ydCB7IGZvcm1hdEN1cnJlbmN5IH0gZnJvbSAnLi4vLi4vdXRpbHMvY29tbW9uX3V0aWxzJztcclxuaW1wb3J0IEN1cnJlbnRQYWdlIGZyb20gJy4uLy4uL21vZGVscy9jdXJyZW50X3BhZ2UnO1xyXG5pbXBvcnQgeyBleGNlbFNlcmlhbERhdGVUb0pTRGF0ZSB9IGZyb20gJy4uLy4uL3V0aWxzL1hMU1hfaGFuZGxlcnMnO1xyXG5cclxuaW1wb3J0ICcuL3Rvb2x0aXAuY3NzJ1xyXG5cclxuZnVuY3Rpb24gaGlkZVRvb2x0aXAoKSB7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndG9vbHRpcCcpLnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcclxufVxyXG5cclxuZnVuY3Rpb24gc2hvd1Rvb2x0aXAoKSB7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndG9vbHRpcCcpLnN0eWxlLnZpc2liaWxpdHkgPSAndmlzaWJsZSc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGVkaXRUb29sdGlwVGV4dChuZXdUZXh0KXtcclxuICAgIC8vIGVkaXQgdGV4dCB0byBkaXNwbGF5IGluc2lkZSB0b29sdGlwXHJcbiAgICBjb25zdCB0b29sdGlwID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Rvb2x0aXAnKTtcclxuICAgIHRvb2x0aXAuaW5uZXJIVE1MID0gbmV3VGV4dDtcclxufVxyXG5cclxuZnVuY3Rpb24gc2hvd0FjY291bnRTdHJpbmcocm93KXtcclxuICAgIGNvbnN0IGFwcHJvcCA9IENlbGwuZ2V0VGV4dChyb3csICdhcHByb3AtbmFtZScpO1xyXG4gICAgY29uc3QgY2MgPSAgQ2VsbC5nZXRUZXh0KHJvdywgJ2NjLW5hbWUnKTtcclxuICAgIGNvbnN0IG9iaiA9ICBDZWxsLmdldFRleHQocm93LCAnb2JqZWN0LW5hbWUnKTtcclxuICAgIGNvbnN0IGZ1bmQgPSBDZWxsLmdldFRleHQocm93LCAnZnVuZC1uYW1lJyk7XHJcbiAgICB2YXIgbWVzc2FnZSA9IFxyXG4gICAgICAgIGA8c3Ryb25nPkZ1bmQ8L3N0cm9uZz46ICR7ZnVuZH08YnI+XHJcbiAgICAgICAgPHN0cm9uZz5BcHByb3ByaWF0aW9uPC9zdHJvbmc+OiAke2FwcHJvcH08YnI+XHJcbiAgICAgICAgPHN0cm9uZz5Db3N0IENlbnRlcjwvc3Ryb25nPjogJHtjY31gO1xyXG4gICAgaWYgKG9iaikgeyBtZXNzYWdlICs9IGA8YnI+PHN0cm9uZz5PYmplY3Q8L3N0cm9uZz46ICR7b2JqfWB9XHJcbiAgICBtZXNzYWdlICs9IGA8YnI+IElmIHlvdSBiZWxpZXZlIHRoaXMgYWNjb3VudCBzdHJpbmcgaXMgaW5jb3JyZWN0LCBwbGVhc2UgbGVhdmUgYSBjb21tZW50IFxyXG4gICAgICAgIGluIHRoZSBjb21tZW50IGNvbHVtbi5gXHJcbiAgICBlZGl0VG9vbHRpcFRleHQobWVzc2FnZSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNob3dTYWxhcnlQcm9qZWN0aW9uKHJvdyl7XHJcbiAgICBjb25zdCBnZW5lcmFsX2luY3JlYXNlID0gQ2VsbC5nZXRUZXh0KHJvdywgJ2dlbmVyYWwtaW5jcmVhc2UtcmF0ZScpO1xyXG4gICAgY29uc3QgbWVyaXRfaW5jcmVhc2UgPSAgQ2VsbC5nZXRUZXh0KHJvdywgJ21lcml0LWluY3JlYXNlLXJhdGUnKTtcclxuICAgIGNvbnN0IGN1cnJlbnRfc2FsYXJ5ID0gQ2VsbC5nZXRWYWx1ZShyb3csICdjdXJyZW50LXNhbGFyeScpO1xyXG4gICAgY29uc3QgcHJval9zYWxhcnkgPSBDZWxsLmdldFZhbHVlKHJvdywgJ2F2Zy1zYWxhcnknKTtcclxuICAgIGlmIChjdXJyZW50X3NhbGFyeSl7XHJcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBgVGhlIGF2ZXJhZ2Ugc2FsYXJ5L3dhZ2UgZm9yIHRoaXMgcG9zaXRpb24gd2FzIFxyXG4gICAgICAgICAgICAke2Zvcm1hdEN1cnJlbmN5KGN1cnJlbnRfc2FsYXJ5KX0gYXMgb2YgU2VwdGVtYmVyIDIwJHtGSVNDQUxfWUVBUi0yfS4gXHJcbiAgICAgICAgICAgIEdpdmVuIGEgJHtnZW5lcmFsX2luY3JlYXNlKjEwMH0lIGdlbmVyYWwgaW5jcmVhc2UgcmF0ZSBhbmQgYSAke21lcml0X2luY3JlYXNlKjEwMH0lIFxyXG4gICAgICAgICAgICBtZXJpdCBpbmNyZWFzZSwgdGhlIEZZJHtGSVNDQUxfWUVBUn0gcHJvamVjdGlvbiBmb3IgdGhpcyBwb3NpdGlvbidzIGF2ZXJhZ2UgXHJcbiAgICAgICAgICAgIGFubnVhbCBzYWxhcnkvd2FnZSBpcyAke2Zvcm1hdEN1cnJlbmN5KHByb2pfc2FsYXJ5KX0uIFRoaXMgcHJvamVjdGlvbiB0YWtlcyBpbnRvIFxyXG4gICAgICAgICAgICBhY2NvdW50IHRoZSBudW1iZXIgb2YgdmFjYW50IHZzLiBmdWxsIHBvc2l0aW9ucy5gO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB2YXIgbWVzc2FnZSA9IGBUaGUgYXZlcmFnZSBzYWxhcnkvd2FnZSBmb3IgdGhpcyBwb3NpdGlvbiB3YXMgXHJcbiAgICAgICAgICAgIHVua25vd24gYXMgb2YgU2VwdGVtYmVyIDIwJHtGSVNDQUxfWUVBUi0yfSwgb3IgdGhlIHBvc2l0aW9uXHJcbiAgICAgICAgICAgIGRpZCBub3QgZXhpc3QuIFRoZSBGWSR7RklTQ0FMX1lFQVJ9IHByb2plY3Rpb24gZm9yIHRoaXMgcG9zaXRpb24ncyBcclxuICAgICAgICAgICAgYXZlcmFnZSBhbm51YWwgc2FsYXJ5L3dhZ2UgaXMgJHtmb3JtYXRDdXJyZW5jeShwcm9qX3NhbGFyeSl9LmBcclxuICAgIH1cclxuXHJcbiAgICBlZGl0VG9vbHRpcFRleHQobWVzc2FnZSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNob3dGaW5hbFBlcnNvbm5lbENvc3Qocm93KXtcclxuICAgIGNvbnN0IHByb2pfc2FsYXJ5ID0gQ2VsbC5nZXRWYWx1ZShyb3csICdhdmctc2FsYXJ5Jyk7XHJcbiAgICBjb25zdCBmdGVzID0gQ2VsbC5nZXRUZXh0KHJvdywgJ2Jhc2VsaW5lLWZ0ZXMnKTtcclxuICAgIGNvbnN0IGZyaW5nZSA9IHBhcnNlRmxvYXQoQ2VsbC5nZXRUZXh0KHJvdywgJ2ZyaW5nZScpKTtcclxuICAgIGNvbnN0IGF2Z19iZW5lZml0cyA9IHByb2pfc2FsYXJ5ICogZnJpbmdlO1xyXG4gICAgY29uc3QgbWVzc2FnZSA9IGBUaGUgdG90YWwgY29zdCBjYXB0dXJlcyAke2Z0ZXN9IHBvc2l0aW9uKHMpIGF0XHJcbiAgICAgICAgICAgICAgICAgICAgYW4gYW5udWFsIHNhbGFyeS93YWdlIG9mICR7Zm9ybWF0Q3VycmVuY3kocHJval9zYWxhcnkpfSwgXHJcbiAgICAgICAgICAgICAgICAgICAgcGx1cyBmcmluZ2UgYmVuZWZpdHMgdGhhdCBjb3N0ICR7Zm9ybWF0Q3VycmVuY3koYXZnX2JlbmVmaXRzKX0gXHJcbiAgICAgICAgICAgICAgICAgICAgcGVyIHBvc2l0aW9uIHBlciB5ZWFyLCBvbiBhdmVyYWdlLmBcclxuICAgIGVkaXRUb29sdGlwVGV4dChtZXNzYWdlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2hvd0ZJQ0Eocm93KXtcclxuICAgIGNvbnN0IGZpY2EgPSBwYXJzZUZsb2F0KENlbGwuZ2V0VGV4dChyb3csICdmaWNhJykpO1xyXG4gICAgY29uc3QgZmljYVBlcmNlbnRhZ2UgPSAoZmljYSAqIDEwMCkudG9GaXhlZCgyKTtcclxuICAgIGNvbnN0IG1lc3NhZ2UgPSBgVGhpcyB0b3RhbCBpcyBvdmVydGltZSAvIGhvbGlkYXkgLyBzaGlmdCBwcmVtaXVtIHBheSwgcGx1cyBGSUNBIChwYXlyb2xsIHRheCksIFxyXG4gICAgICAgICAgICAgICAgICAgICB3aGljaCBpcyAke2ZpY2FQZXJjZW50YWdlfSUgZm9yIHRoaXMgY29zdCBjZW50ZXIuYFxyXG4gICAgZWRpdFRvb2x0aXBUZXh0KG1lc3NhZ2UpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzaG93Q1BBKHJvdyl7XHJcbiAgICBjb25zdCBjcGEgPSBwYXJzZUZsb2F0KENlbGwuZ2V0VGV4dChyb3csICdjcGEnKSk7XHJcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9IENlbGwuZ2V0VGV4dChyb3csICdjcGEtZGVzY3JpcHRpb24nKTtcclxuICAgIGNvbnN0IHZlbmRvciA9IENlbGwuZ2V0VGV4dChyb3csICd2ZW5kb3InKTtcclxuICAgIHZhciBjb250cmFjdF9lbmQgPSBDZWxsLmdldFRleHQocm93LCAnY29udHJhY3QtZW5kJyk7XHJcbiAgICAvLyBjb252ZXJ0IHRvIG5vcm1hbCBkYXRlIGZvcm1hdCBmcm9tIGV4Y2VsIFxyXG4gICAgY29udHJhY3RfZW5kID0gZXhjZWxTZXJpYWxEYXRlVG9KU0RhdGUoY29udHJhY3RfZW5kKTtcclxuICAgIGNvbnN0IHJlbWFpbmluZyA9IENlbGwuZ2V0VmFsdWUocm93LCAncmVtYWluaW5nJyk7XHJcbiAgICBpZiAoY3BhKSB7XHJcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBgPHN0cm9uZz5DUEEgIyR7Y3BhfTwvc3Ryb25nPmA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHZhciBtZXNzYWdlID0gYE5vIENQQWA7XHJcbiAgICB9XHJcbiAgICBpZiAodmVuZG9yKSB7bWVzc2FnZSArPSBgPGJyPjxzdHJvbmc+VmVuZG9yPC9zdHJvbmc+OiAke3ZlbmRvcn1gfTtcclxuICAgIGlmIChkZXNjcmlwdGlvbikge21lc3NhZ2UgKz0gYDxicj48c3Ryb25nPkRlc2NyaXB0aW9uPC9zdHJvbmc+OiAke2Rlc2NyaXB0aW9ufWB9O1xyXG4gICAgaWYgKGNvbnRyYWN0X2VuZCkge21lc3NhZ2UgKz0gYDxicj48c3Ryb25nPkNvbnRyYWN0IEVuZCBEYXRlPC9zdHJvbmc+OiAke2NvbnRyYWN0X2VuZH1gfVxyXG4gICAgaWYgKHJlbWFpbmluZykge21lc3NhZ2UgKz0gYDxicj48c3Ryb25nPkFtb3VudCBSZW1haW5pbmcgb24gQ29udHJhY3Q8L3N0cm9uZz46ICR7Zm9ybWF0Q3VycmVuY3kocmVtYWluaW5nKX1gfVxyXG5cclxuICAgIGVkaXRUb29sdGlwVGV4dChtZXNzYWdlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gbGluayhlbGVtZW50LCBkaXNwbGF5Rm4pIHtcclxuXHJcbiAgICAvLyBhZGQgY2xhc3MgdG8gc2hvdyBjZWxsIHdpdGggYW4gdW5kZXJsaW5lLCBldGNcclxuICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgndG9vbHRpcC1jZWxsJyk7XHJcblxyXG4gICAgLy8gQ3JlYXRlIGFuZCBhcHBlbmQgKGRldGFpbClcclxuICAgIGNvbnN0IGRldGFpbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcclxuICAgIGRldGFpbC5jbGFzc0xpc3QuYWRkKCdkZXRhaWwnKTtcclxuICAgIGRldGFpbC50ZXh0Q29udGVudCA9ICcoZGV0YWlsKSc7XHJcbiAgICBlbGVtZW50LmFwcGVuZENoaWxkKGRldGFpbCk7XHJcblxyXG4gICAgLy8gYWRkIGV2ZW50IGxpc3RlbmVyIHRvIHNob3cgdG9vbHRpcCBvbiBtb3VzZW92ZXJcclxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICBjb25zdCByb3cgPSBldmVudC50YXJnZXQuY2xvc2VzdCgndHInKTtcclxuICAgICAgICBkaXNwbGF5Rm4ocm93KTtcclxuICAgICAgICBzaG93VG9vbHRpcCgpO1xyXG4gICAgfSk7XHJcbiAgICAvLyBhbmQgaGlkZSB3aGVuIG1vdXNlIG1vdmVzIG9mZlxyXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBoaWRlVG9vbHRpcCgpO1xyXG4gICAgfSk7XHJcbiAgICAvLyBVcGRhdGUgdG9vbHRpcCBwb3NpdGlvbiBvbiBtb3VzZSBtb3ZlXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIGNvbnN0IHRvb2x0aXAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndG9vbHRpcCcpO1xyXG4gICAgICAgIHRvb2x0aXAuc3R5bGUudG9wID0gKGV2ZW50LmNsaWVudFkgKyAxMCkgKyAncHgnO1xyXG4gICAgICAgIHRvb2x0aXAuc3R5bGUubGVmdCA9IChldmVudC5jbGllbnRYICsgMTApICsgJ3B4JztcclxuICAgIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBsaW5rQWNjb3VudFN0cmluZ0NvbCgpIHtcclxuICAgIC8vIGdldCBhbGwgcmVsZXZhbnQgY2VsbHNcclxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3RkLmFjY291bnQtc3RyaW5nJykuZm9yRWFjaCggKGNlbGwpID0+IHtcclxuICAgICAgICBsaW5rKGNlbGwsIHNob3dBY2NvdW50U3RyaW5nKTtcclxuICAgIH0pXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxpbmtTYWxhcnlDb2woKSB7XHJcbiAgICAvLyBnZXQgYWxsIHJlbGV2YW50IGNlbGxzXHJcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCd0ZC5hdmctc2FsYXJ5JykuZm9yRWFjaCggKGNlbGwpID0+IHtcclxuICAgICAgICBsaW5rKGNlbGwsIHNob3dTYWxhcnlQcm9qZWN0aW9uKTtcclxuICAgIH0pXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxpbmtUb3RhbFBlcnNvbm5lbENvc3RDb2woKSB7XHJcbiAgICAvLyBnZXQgYWxsIHJlbGV2YW50IGNlbGxzXHJcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCd0ZC50b3RhbC1iYXNlbGluZScpLmZvckVhY2goIChjZWxsKSA9PiB7XHJcbiAgICAgICAgbGluayhjZWxsLCBzaG93RmluYWxQZXJzb25uZWxDb3N0KTtcclxuICAgIH0pXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxpbmtUb3RhbE9UQ29sKCkge1xyXG4gICAgLy8gZ2V0IGFsbCByZWxldmFudCBjZWxsc1xyXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgndGQudG90YWwnKS5mb3JFYWNoKCAoY2VsbCkgPT4ge1xyXG4gICAgICAgIGxpbmsoY2VsbCwgc2hvd0ZJQ0EpO1xyXG4gICAgfSlcclxufVxyXG5cclxuZnVuY3Rpb24gbGlua0NQQUNvbCgpIHtcclxuICAgIC8vIGdldCBhbGwgcmVsZXZhbnQgY2VsbHNcclxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3RkLmNwYScpLmZvckVhY2goIChjZWxsKSA9PiB7XHJcbiAgICAgICAgbGluayhjZWxsLCBzaG93Q1BBKTtcclxuICAgIH0pXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBUb29sdGlwID0ge1xyXG5cclxuICAgIGhpZGUgOiBoaWRlVG9vbHRpcCxcclxuICAgIHNob3cgOiBzaG93VG9vbHRpcCxcclxuXHJcbiAgICBsaW5rQWxsIDogKCkgPT4ge1xyXG4gICAgICAgIGxpbmtBY2NvdW50U3RyaW5nQ29sKCk7XHJcbiAgICAgICAgc3dpdGNoKEN1cnJlbnRQYWdlLmxvYWQoKSl7XHJcbiAgICAgICAgICAgIGNhc2UgJ3BlcnNvbm5lbCcgOlxyXG4gICAgICAgICAgICAgICAgLy8gbGlua0FjY291bnRTdHJpbmdDb2woKTtcclxuICAgICAgICAgICAgICAgIGxpbmtTYWxhcnlDb2woKTtcclxuICAgICAgICAgICAgICAgIGxpbmtUb3RhbFBlcnNvbm5lbENvc3RDb2woKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlICdvdmVydGltZSc6XHJcbiAgICAgICAgICAgICAgICBsaW5rVG90YWxPVENvbCgpO1xyXG4gICAgICAgICAgICAgICAgLy8gbGlua0FjY291bnRTdHJpbmdDb2woKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlICdub25wZXJzb25uZWwnOlxyXG4gICAgICAgICAgICAgICAgLy8gbGlua0FjY291bnRTdHJpbmdDb2woKTtcclxuICAgICAgICAgICAgICAgIGxpbmtDUEFDb2woKTsgIFxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIC8vIGNhc2UgJ3JldmVudWUnOlxyXG4gICAgICAgICAgICAvLyAgICAgbGlua0FjY291bnRTdHJpbmdDb2woKTtcclxuICAgICAgICAgICAgLy8gICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAvLyBjYXNlICduZXctaW5pdHMnOlxyXG4gICAgICAgICAgICAvLyAgICAgbGlua0FjY291bnRTdHJpbmdDb2woKTtcclxuICAgICAgICAgICAgLy8gICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgdW5saW5rIDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgbGV0IGRldGFpbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZGV0YWlsJyk7XHJcbiAgICAgICAgZGV0YWlscy5mb3JFYWNoKCAoc3BhbikgPT4ge1xyXG4gICAgICAgICAgICBzcGFuLnJlbW92ZSgpO1xyXG4gICAgICAgIH0pXHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFRvb2x0aXAiLCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gZmV0Y2hKU09OKGpzb25GaWxlUGF0aCkge1xyXG4gIHJldHVybiBmZXRjaChqc29uRmlsZVBhdGgpXHJcbiAgICAudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05ldHdvcmsgcmVzcG9uc2Ugd2FzIG5vdCBvaycpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRUb0pTT04odGFibGUsIGNvbHNUb1JlbW92ZSA9IFtdKXtcclxuICAgIGNvbnN0IHJvd3MgPSB0YWJsZS5yb3dzO1xyXG4gICAgLy8gRXh0cmFjdCBoZWFkZXJzIGZyb20gdGhlIGZpcnN0IHJvd1xyXG4gICAgY29uc3QgaGVhZGVyUm93ID0gcm93c1swXS5jZWxscztcclxuICAgIGNvbnN0IGhlYWRlcnMgPSBbXTtcclxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaGVhZGVyUm93Lmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgaGVhZGVycy5wdXNoKGhlYWRlclJvd1tqXS5pbm5lclRleHQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGluaXRpYWxpemUgZGF0YVxyXG4gICAgdmFyIHRhYmxlRGF0YSA9IFtdO1xyXG5cclxuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgcm93cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IGNvbHMgPSByb3dzW2ldLmNlbGxzO1xyXG4gICAgICAgIGNvbnN0IHJvd0RhdGEgPSB7fTtcclxuICAgICAgICAgICAgaGVhZGVycy5mb3JFYWNoKChoZWFkZXIsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29sc1RvUmVtb3ZlLmluY2x1ZGVzKGhlYWRlcikpe1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbHNbaW5kZXhdLmNsYXNzTGlzdC5jb250YWlucygnY29zdCcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcm93RGF0YVtoZWFkZXJdID0gY29sc1tpbmRleF0uZ2V0QXR0cmlidXRlKCd2YWx1ZScpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByb3dEYXRhW2hlYWRlcl0gPSBjb2xzW2luZGV4XS5pbm5lclRleHQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIHRhYmxlRGF0YS5wdXNoKHJvd0RhdGEpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRhYmxlRGF0YSk7XHJcbn1cclxuXHJcblxyXG4gICIsImltcG9ydCAnLi90YWJsZS5jc3MnO1xyXG5cclxuaW1wb3J0IEJ1dHRvbnMgZnJvbSAnLi9zdWJjb21wb25lbnRzL2J1dHRvbnMuanMnXHJcbmltcG9ydCBDZWxsIGZyb20gJy4vc3ViY29tcG9uZW50cy9jZWxscy5qcydcclxuaW1wb3J0IENvbHVtbnMgZnJvbSAnLi9zdWJjb21wb25lbnRzL2NvbHVtbnMuanMnXHJcbmltcG9ydCBIZWFkZXIgZnJvbSAnLi9zdWJjb21wb25lbnRzL2hlYWRlcnMuanMnXHJcbmltcG9ydCBSb3dzIGZyb20gJy4vc3ViY29tcG9uZW50cy9yb3dzLmpzJ1xyXG5pbXBvcnQgRGF0YSBmcm9tICcuL3N1YmNvbXBvbmVudHMvZGF0YS5qcydcclxuaW1wb3J0IEZpbHRlciBmcm9tICcuL3N1YmNvbXBvbmVudHMvZmlsdGVycy5qcyc7XHJcblxyXG5pbXBvcnQgVG9vbHRpcCBmcm9tICcuLi90b29sdGlwL3Rvb2x0aXAuanMnO1xyXG5pbXBvcnQgeyBjb252ZXJ0VG9KU09OIH0gZnJvbSBcIi4uLy4uL3V0aWxzL0pTT05fZGF0YV9oYW5kbGVycy5qc1wiO1xyXG5pbXBvcnQgU2lkZWJhciBmcm9tICcuLi9zaWRlYmFyL3NpZGViYXIuanMnO1xyXG5pbXBvcnQgQ3VycmVudEZ1bmQgZnJvbSAnLi4vLi4vbW9kZWxzL2N1cnJlbnRfZnVuZC5qcyc7XHJcbmltcG9ydCBDdXJyZW50UGFnZSBmcm9tICcuLi8uLi9tb2RlbHMvY3VycmVudF9wYWdlLmpzJztcclxuXHJcbmZ1bmN0aW9uIGFkanVzdFRhYmxlV2lkdGgod2lkdGhfcGN0KXtcclxuICAgIGNvbnN0IHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuICAgIHRhYmxlLnN0eWxlLndpZHRoID0gd2lkdGhfcGN0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBzaG93VGFibGUoKXtcclxuICAgIGNvbnN0IHRhYmxlQ29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRhYmxlLWNvbnRhaW5lcicpO1xyXG4gICAgdGFibGVDb250YWluZXIuaW5uZXJIVE1MID0gVGFibGUuaHRtbDtcclxuICAgIGNvbnN0IHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuICAgIHRhYmxlLnN0eWxlLmRpc3BsYXkgPSAndGFibGUnO1xyXG59XHJcblxyXG5mdW5jdGlvbiBoaWRlVGFibGUoKXtcclxuXHJcbiAgICAvLyBkZWxldGUgdGFibGUgb2JqZWN0IGZyb20gdGFibGUgY29udGFpbmVyXHJcbiAgICBjb25zdCB0YWJsZUNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50YWJsZS1jb250YWluZXInKTtcclxuICAgIHRhYmxlQ29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xyXG4gICAgQnV0dG9ucy5BZGRSb3cuaGlkZSgpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzYXZlVGFibGVEYXRhKCkge1xyXG4gICAgLy8gcmVtb3ZlIHRoZSBkZXRhaWwgdGV4dFxyXG4gICAgVG9vbHRpcC51bmxpbmsoKTtcclxuICAgIC8vIGdldCB0YWJsZVxyXG4gICAgdmFyIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tdGFibGUnKTtcclxuICAgIC8vIGRldGVybWluZSBzYXZlX2FzIG5hbWVcclxuICAgIGlmIChDdXJyZW50RnVuZC5udW1iZXIoKSkge1xyXG4gICAgICAgIHZhciBzYXZlX2FzID0gYCR7Q3VycmVudFBhZ2UubG9hZCgpfV8ke0N1cnJlbnRGdW5kLm51bWJlcigpfWA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHZhciBzYXZlX2FzID0gQ3VycmVudFBhZ2UubG9hZCgpO1xyXG4gICAgfVxyXG4gICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oc2F2ZV9hcywgY29udmVydFRvSlNPTih0YWJsZSwgWydFZGl0J10pKTtcclxuICAgIC8vIHVwZGF0ZSBzaWRlYmFyIHdpdGggbmV3IGRhdGFcclxuICAgIFNpZGViYXIudXBkYXRlVG90YWxzKCk7XHJcbiAgICAvLyByZWxpbmssIGRlcGVuZGluZyBvbiBwYWdlXHJcbiAgICBUb29sdGlwLmxpbmtBbGwoKTtcclxufVxyXG5cclxuY29uc3QgVGFibGUgPSB7XHJcbiAgICBodG1sIDogYFxyXG4gICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLWJvcmRlcmVkIG10LTMgZGlzcGxheVwiIGlkPVwibWFpbi10YWJsZVwiPlxyXG4gICAgICAgICAgICA8dGhlYWQgY2xhc3M9XCJ0aGVhZC1kYXJrXCI+PC90aGVhZD5cclxuICAgICAgICAgICAgPHRib2R5PjwvdGJvZHk+XHJcbiAgICAgICAgPC90YWJsZT5gLFxyXG4gICAgQnV0dG9ucyA6IEJ1dHRvbnMsXHJcbiAgICBDZWxsIDogQ2VsbCxcclxuICAgIENvbHVtbnMgOiBDb2x1bW5zLFxyXG4gICAgSGVhZGVyIDogSGVhZGVyLFxyXG4gICAgUm93cyA6IFJvd3MsXHJcbiAgICBEYXRhIDogRGF0YSxcclxuICAgIEZpbHRlciA6IEZpbHRlcixcclxuICAgIC8vIGZ1bmN0aW9uc1xyXG4gICAgYWRqdXN0V2lkdGggOiBmdW5jdGlvbih3aWR0aF9wY3Qpe1xyXG4gICAgICAgIGFkanVzdFRhYmxlV2lkdGgod2lkdGhfcGN0KVxyXG4gICAgfSxcclxuICAgIGNsZWFyIDogaGlkZVRhYmxlLFxyXG4gICAgaGlkZSA6IGhpZGVUYWJsZSxcclxuICAgIHNob3cgOiBzaG93VGFibGUsXHJcbiAgICBzYXZlIDogc2F2ZVRhYmxlRGF0YVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBUYWJsZTsiLCJpbXBvcnQgJy4vYWNjb3JkaW9uLmNzcydcclxuXHJcblxyXG5pbXBvcnQge0Jhc2VsaW5lLCBDdXJyZW50RnVuZCwgRnVuZCwgU3VwcGxlbWVudGFsLCBGdW5kTG9va3VwVGFibGV9IGZyb20gJy4uLy4uL21vZGVscydcclxuaW1wb3J0IHsgZm9ybWF0Q3VycmVuY3ksIGNsZWFuU3RyaW5nIH0gZnJvbSBcIi4uLy4uL3V0aWxzL2NvbW1vbl91dGlscy5qc1wiO1xyXG5pbXBvcnQgVGFibGUgZnJvbSBcIi4uL3RhYmxlL3RhYmxlLmpzXCI7XHJcbmltcG9ydCB7IHZpc2l0UGFnZSB9IGZyb20gJy4uLy4uL3ZpZXdzL3ZpZXdfbG9naWMuanMnO1xyXG5cclxuZnVuY3Rpb24gcmVkaXJlY3RGb3JFZGl0KCl7XHJcbiAgICBjb25zdCByb3cgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAuYWN0aXZlLWVkaXRpbmdgKTtcclxuICAgIGNvbnN0IHRhYmxlID0gcm93LnBhcmVudEVsZW1lbnQ7XHJcbiAgICBjb25zdCBzZWN0aW9uID0gdGFibGUuY2xvc2VzdCgnLnN1bW1hcnktY29udGFpbmVyJyk7XHJcbiAgICAvLyBuZXcgaW5pdGlhdGl2ZSBlZGl0cyBzaG91bGQgYWxsIHJlZGlyZWN0IHRvIHRoZSBuZXctaW5pdHMgcGFnZVxyXG4gICAgaWYgKHNlY3Rpb24uaWQgPT0gJ3N1cHAtYWNjb3JkaW9uJyl7XHJcbiAgICAgICAgdmlzaXRQYWdlKCduZXctaW5pdHMnKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vIFNwbGl0IHRoZSBzdHJpbmcgaW50byBwYXJ0cyB1c2luZyAnLScgYXMgdGhlIGRlbGltaXRlcjsgcmV0YWluIGZ1bmQgYXMgMXN0IG51bWVyaWMgc2VnbWVudFxyXG4gICAgICAgIGNvbnN0IGZ1bmQgPSB0YWJsZS5pZC5zcGxpdCgnLScpWzFdXHJcbiAgICAgICAgXHJcbiAgICAgICAgQ3VycmVudEZ1bmQudXBkYXRlKGZ1bmQpO1xyXG4gICAgICAgIGNvbnN0IGxpbmVJdGVtID0gcm93LnF1ZXJ5U2VsZWN0b3IoJy5saW5lLWl0ZW0nKS50ZXh0Q29udGVudDtcclxuICAgICAgICAvLyB2aXNpdCB0aGUgY29ycmVjdCBwYWdlIGZvciBlZGl0aW5nXHJcbiAgICAgICAgc3dpdGNoKGxpbmVJdGVtKXtcclxuICAgICAgICAgICAgY2FzZSAnUGVyc29ubmVsIEV4cGVuZGl0dXJlcyc6XHJcbiAgICAgICAgICAgICAgICB2aXNpdFBhZ2UoJ3BlcnNvbm5lbCcpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgJ05vbi1QZXJzb25uZWwgRXhwZW5kaXR1cmVzJzpcclxuICAgICAgICAgICAgICAgIHZpc2l0UGFnZSgnbm9ucGVyc29ubmVsJyk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAnUmV2ZW51ZXMnOlxyXG4gICAgICAgICAgICAgICAgdmlzaXRQYWdlKCdyZXZlbnVlJyk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAnT3ZlcnRpbWUgRXhwZW5kaXR1cmVzJzpcclxuICAgICAgICAgICAgICAgIHZpc2l0UGFnZSgnb3ZlcnRpbWUnKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTmFtZSBvZiBsaW5lIGl0ZW0gaW4gdGFibGUgZG9lcyBub3QgbWF0Y2ggYSBwYWdlIGRlc3RpbmF0aW9uLicpXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5jb25zdCBBcHByb3ByaWF0aW9uVGFibGUgPSB7XHJcbiAgICBcclxufVxyXG5cclxuY29uc3QgRXhwZW5zZVRhYmxlID0ge1xyXG4gICAgdGFibGVfaWQgOiAoYWNjb3VudF9zdHJpbmcpID0+IHsgcmV0dXJuIGB0YWJsZS0ke2FjY291bnRfc3RyaW5nfWAgfSxcclxuICAgIGluaXQoYWNjb3VudF9zdHJpbmcpIHtcclxuICAgICAgICAvLyBjcmVhdGUgZW1wdHkgdGFibGUgYW5kIHB1dCBpdCBpbiB0aGUgYWNjb3JkaW9uXHJcbiAgICAgICAgdmFyIHRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGFibGUnKTtcclxuICAgICAgICB0YWJsZS5pZCA9IHRoaXMudGFibGVfaWQoYWNjb3VudF9zdHJpbmcpO1xyXG4gICAgICAgIHRhYmxlLmNsYXNzTGlzdC5hZGQoJ2FjY29yZGlvbi10YWJsZScpO1xyXG4gICAgICAgIHZhciBwYXJlbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAjc3RyaW5nXyR7YWNjb3VudF9zdHJpbmd9X2NvbnRlbnQgLmFjY29yZGlvbi1ib2R5YCk7XHJcbiAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKHRhYmxlKTtcclxuICAgIH0sXHJcbiAgICBjcmVhdGVOZXdDZWxsKGNvbnRlbnQsIHJvdywgY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgY29uc3QgbmV3Q2VsbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RkJyk7XHJcbiAgICAgICAgbmV3Q2VsbC5pbm5lckhUTUwgPSBjb250ZW50O1xyXG4gICAgICAgIG5ld0NlbGwuY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xyXG4gICAgICAgIHJvdy5hcHBlbmRDaGlsZChuZXdDZWxsKTtcclxuICAgIH0sXHJcbiAgICBhZGRSb3coYWNjb3VudF9zdHJpbmcsIHJvd19uYW1lLCBudW1iZXIpe1xyXG4gICAgICAgIHZhciB0YWJsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMudGFibGVfaWQoYWNjb3VudF9zdHJpbmcpKTtcclxuICAgICAgICB2YXIgbmV3X3JvdyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RyJyk7XHJcbiAgICAgICAgdGFibGUuYXBwZW5kQ2hpbGQobmV3X3Jvdyk7XHJcbiAgICAgICAgLy8gQ3JlYXRlIGEgY2VsbCBmb3IgdGhlIGxpbmUgaXRlbSBsYWJlbFxyXG4gICAgICAgIHRoaXMuY3JlYXRlTmV3Q2VsbChyb3dfbmFtZSwgbmV3X3JvdywgJ2xpbmUtaXRlbScpO1xyXG4gICAgICAgIC8vIGNyZWF0ZSBhIGNlbGwgZm9yIHRoZSBhbW91bnRcclxuICAgICAgICB0aGlzLmNyZWF0ZU5ld0NlbGwoZm9ybWF0Q3VycmVuY3kobnVtYmVyKSwgbmV3X3JvdywgJ2Nvc3QnKTtcclxuICAgICAgICAvLyBjcmVhdGUgRWRpdCBidXR0b24gXHJcbiAgICAgICAgdmFyIGJ1dHRvbiA9ICcnO1xyXG4gICAgICAgIGlmIChyb3dfbmFtZSAhPSAnTmV0IEV4cGVuZGl0dXJlcyAoUmV2ZW51ZXMpJyl7XHJcbiAgICAgICAgICAgIGJ1dHRvbiA9IFRhYmxlLkJ1dHRvbnMuRWRpdC5odG1sO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNyZWF0ZU5ld0NlbGwoYnV0dG9uLCBuZXdfcm93KTtcclxuICAgIH0sXHJcbiAgICBmaWxsRnJvbUZ1bmQoZnVuZCkge1xyXG4gICAgICAgIC8vIHVzZSBqdXN0IGZ1bmQgYXMgYWNjb3VudCBzdHJpbmcgdG8gaW5pdGlhbGl6ZSB0YWJsZSBpbnNpZGUgYWNjb3JkaW9uXHJcbiAgICAgICAgdGhpcy5pbml0KGZ1bmQpO1xyXG4gICAgICAgIGNvbnN0IGZ1bmRPYmplY3QgPSBuZXcgRnVuZChmdW5kKTtcclxuXHJcbiAgICAgICAgLy8gQWRkIGEgcm93IGZvciBlYWNoIGFwcHJvcHJpYXRpb24gaW4gdGhlIGZ1bmRcclxuICAgICAgICBjb25zdCBpZCA9IGNsZWFuU3RyaW5nKGZ1bmQpO1xyXG5cclxuICAgICAgICBmdW5kT2JqZWN0LmdldEFwcHJvcHJpYXRpb25zKCkuZm9yRWFjaCggYXBwcm9wT2JqID0+IHtcclxuICAgICAgICAgICAgLy8gaWYgdGhlIHRvdGFsIGZvciB0aGUgYXBwcm9wcmlhdGlvbiBpcyA+ICQwLCBhZGQgYW4gYWNjb3JkaW9uIGZvciBhbGwgdGhlIENDc1xyXG4gICAgICAgICAgICBpZiAoIGFwcHJvcE9iai50b3RhbCgpICE9IDAgKXtcclxuICAgICAgICAgICAgICAgIEl0ZW0uYWRkKGFwcHJvcE9iai5hY2NvdW50U3RyaW5nKCksIGAjc3RyaW5nXyR7aWR9X2NvbnRlbnQgLmFjY29yZGlvbi1ib2R5YCk7XHJcbiAgICAgICAgICAgICAgICBJdGVtLnVwZGF0ZUhlYWRlcihhcHByb3BPYmoubmFtZSgpLCBhcHByb3BPYmouYWNjb3VudFN0cmluZygpLCBhcHByb3BPYmoudG90YWwoKSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZpbGxGcm9tQXBwcm9wKGFwcHJvcE9iaik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gICAgfSxcclxuICAgIGZpbGxGcm9tQXBwcm9wKGFwcHJvcE9iail7XHJcbiAgICAgICAgLy8gaW5pdGlhbGl6ZSB0aGUgdGFibGUgb2JqZWN0XHJcbiAgICAgICAgdGhpcy5pbml0KGFwcHJvcE9iai5hY2NvdW50U3RyaW5nKCkpO1xyXG4gICAgICAgIC8vIGFkZCBhIGNvbGxhcHNpYmxlIHJvdyBmb3IgZWFjaCBjb3N0IGNlbnRlclxyXG4gICAgICAgIGFwcHJvcE9iai5nZXRDb3N0Q2VudGVycygpLmZvckVhY2goIGNjT2JqID0+IHtcclxuICAgICAgICAgICAgaWYgKGNjT2JqLmdldFRvdGFsKCkgIT0gMCApe1xyXG4gICAgICAgICAgICAgICAgSXRlbS5hZGQoY2NPYmouYWNjb3VudFN0cmluZygpLCBgI3N0cmluZ18ke2FwcHJvcE9iai5hY2NvdW50U3RyaW5nKCl9X2NvbnRlbnQgLmFjY29yZGlvbi1ib2R5YCk7XHJcbiAgICAgICAgICAgICAgICBJdGVtLnVwZGF0ZUhlYWRlcihjY09iai5nZXROYW1lKCksIGNjT2JqLmFjY291bnRTdHJpbmcoKSwgY2NPYmouZ2V0VG90YWwoKSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZpbGxGcm9tQ0MoY2NPYmopO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgICBcclxuICAgIH0sXHJcbiAgICBmaWxsRnJvbUNDKGNjT2JqKXtcclxuICAgICAgICAvLyBpbml0aWFsaXplIGEgdGFibGUgYW5kIHN1bW1hcml6ZSB0aGUgbGluZSBpdGVtc1xyXG4gICAgICAgIHRoaXMuaW5pdChjY09iai5hY2NvdW50U3RyaW5nKCkpO1xyXG4gICAgICAgIHRoaXMuYWRkUm93KGNjT2JqLmFjY291bnRTdHJpbmcoKSwgJ1BlcnNvbm5lbCBFeHBlbmRpdHVyZXMnLCBjY09iai5nZXRQZXJzb25uZWxDb3N0KCkpO1xyXG4gICAgICAgIHRoaXMuYWRkUm93KGNjT2JqLmFjY291bnRTdHJpbmcoKSwgJ092ZXJ0aW1lIEV4cGVuZGl0dXJlcycsIGNjT2JqLmdldE92ZXJ0aW1lQ29zdCgpKTtcclxuICAgICAgICB0aGlzLmFkZFJvdyhjY09iai5hY2NvdW50U3RyaW5nKCksICdOb24tUGVyc29ubmVsIEV4cGVuZGl0dXJlcycsIGNjT2JqLmdldE5vblBlcnNvbm5lbENvc3QoKSk7XHJcbiAgICAgICAgdGhpcy5hZGRSb3coY2NPYmouYWNjb3VudFN0cmluZygpLCAnUmV2ZW51ZXMnLCBjY09iai5nZXRSZXZlbnVlKCkpO1xyXG4gICAgICAgIHRoaXMuYWRkUm93KGNjT2JqLmFjY291bnRTdHJpbmcoKSwgJ05ldCBFeHBlbmRpdHVyZXMgKFJldmVudWVzKScsIGNjT2JqLmdldFRvdGFsKCkpO1xyXG4gICAgfSxcclxuICAgIGZpbGxGcm9tSW5pdChwcm9ncmFtKSB7XHJcbiAgICAgICAgdGhpcy5pbml0KHByb2dyYW0ubmFtZSk7XHJcbiAgICAgICAgdGhpcy5hZGRSb3cocHJvZ3JhbS5uYW1lLCAnRXhwZW5kaXR1cmVzJywgcHJvZ3JhbS5leHBlbnNlcygpKTtcclxuICAgICAgICB0aGlzLmFkZFJvdyhwcm9ncmFtLm5hbWUsICdSZXZlbnVlcycsIHByb2dyYW0ucmV2ZW51ZSgpKTtcclxuICAgICAgICB0aGlzLmFkZFJvdyhwcm9ncmFtLm5hbWUsICdOZXQgRXhwZW5kaXR1cmVzIChSZXZlbnVlcyknLCBwcm9ncmFtLm5ldCgpKTtcclxuICAgIH1cclxufVxyXG5cclxuY29uc3QgSXRlbSA9IHtcclxuICAgIGFjY291bnRTdHJpbmcoZnVuZCwgYXBwcm9wID0gJycsIGNjID0gJycpIHtcclxuICAgICAgICB2YXIgYWNjb3VudF9zdHJpbmcgPSBjbGVhblN0cmluZyhmdW5kKTtcclxuICAgICAgICBpZiAoYXBwcm9wKSB7IGFjY291bnRfc3RyaW5nICs9IGFwcHJvcCB9O1xyXG4gICAgICAgIGlmIChjYykgeyBhY2NvdW50X3N0cmluZyArPSBjYyB9O1xyXG4gICAgICAgIHJldHVybiBhY2NvdW50X3N0cmluZztcclxuICAgIH0sXHJcbiAgICBodG1sKGFjY291bnRfc3RyaW5nKXtcclxuICAgICAgICByZXR1cm4gYDxoMiBjbGFzcz1cImFjY29yZGlvbi1oZWFkZXJcIiBpZD1cInN0cmluZ18ke2FjY291bnRfc3RyaW5nfV9oZWFkZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYWNjb3JkaW9uLWJ1dHRvbiBjb2xsYXBzZWRcIiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1icy10b2dnbGU9XCJjb2xsYXBzZVwiIGRhdGEtYnMtdGFyZ2V0PVwiI3N0cmluZ18ke2FjY291bnRfc3RyaW5nfV9jb250ZW50XCIgYXJpYS1leHBhbmRlZD1cImZhbHNlXCIgYXJpYS1jb250cm9scz1cInN0cmluZ18ke2FjY291bnRfc3RyaW5nfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5hbWVcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYW1vdW50XCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgPC9oMj5cclxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJzdHJpbmdfJHthY2NvdW50X3N0cmluZ31fY29udGVudFwiIGNsYXNzPVwiYWNjb3JkaW9uLWNvbGxhcHNlIGNvbGxhcHNlXCIgYXJpYS1sYWJlbGxlZGJ5PVwic3RyaW5nXyR7YWNjb3VudF9zdHJpbmd9X2hlYWRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY2NvcmRpb24tYm9keVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+YFxyXG4gICAgfSxcclxuICAgIGFkZCA6IGZ1bmN0aW9uKGFjY291bnRfc3RyaW5nLCBhY2NvcmRpb25fcXVlcnkpIHtcclxuICAgICAgICAvLyBnZXQgYWNjb3JkaW9uIGFuZCBhZGQgYSBuZXcgaXRlbSB0byBpdFxyXG4gICAgICAgIGNvbnN0IHBhcmVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYWNjb3JkaW9uX3F1ZXJ5KTtcclxuICAgICAgICBjb25zdCBpdGVtX2VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgICBpdGVtX2VsZW1lbnQuY2xhc3NMaXN0LmFkZCgnYWNjb3JkaW9uLWl0ZW0nKTtcclxuICAgICAgICBpdGVtX2VsZW1lbnQuaW5uZXJIVE1MID0gdGhpcy5odG1sKGFjY291bnRfc3RyaW5nKTtcclxuICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoaXRlbV9lbGVtZW50KTtcclxuICAgIH0sXHJcbiAgICBFeHBlbnNlVGFibGUgOiBFeHBlbnNlVGFibGUsXHJcbiAgICB1cGRhdGVIZWFkZXIgOiBmdW5jdGlvbih0aXRsZSwgYWNjb3VudF9zdHJpbmcsIG5ld19hbW91bnQpIHtcclxuICAgICAgICBjb25zdCBoZWFkZXJfYnRuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgI3N0cmluZ18ke2FjY291bnRfc3RyaW5nfV9oZWFkZXIgYnV0dG9uYCk7XHJcbiAgICAgICAgaGVhZGVyX2J0bi5xdWVyeVNlbGVjdG9yKCdzcGFuLm5hbWUnKS50ZXh0Q29udGVudCA9IHRpdGxlO1xyXG4gICAgICAgIGhlYWRlcl9idG4ucXVlcnlTZWxlY3Rvcignc3Bhbi5hbW91bnQnKS50ZXh0Q29udGVudCA9IGZvcm1hdEN1cnJlbmN5KG5ld19hbW91bnQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5jb25zdCBBZGRJbml0QnV0dG9uID0ge1xyXG4gICAgaW5pdCgpIHtcclxuICAgICAgICBjb25zdCBidG4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYnRuLWFkZC1pbml0Jyk7XHJcbiAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgdmlzaXRQYWdlKCduZXctaW5pdHMnKTtcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgQWNjb3JkaW9uID0ge1xyXG4gICAgSXRlbSA6IEl0ZW0sXHJcbiAgICBBZGRJbml0QnV0dG9uOiBBZGRJbml0QnV0dG9uLFxyXG4gICAgaGlkZSA6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2FjY29yZGlvbi1kaXYnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgIC8vIHJlc2V0IHRvIGRlbGV0ZSBjb250ZW50XHJcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2Jhc2VsaW5lLWFjY29yZGlvbiAuc3VtbWFyeS1hY2NvcmRpb24nKS5pbm5lckhUTUwgPSAnJztcclxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc3VwcC1hY2NvcmRpb24gLnN1bW1hcnktYWNjb3JkaW9uJykuaW5uZXJIVE1MID0gJyc7XHJcbiAgICB9LFxyXG4gICAgc2hvdyA6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2FjY29yZGlvbi1kaXYnKS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuICAgIH0sXHJcbiAgICBhc3luYyBjcmVhdGVCYXNlbGluZSgpe1xyXG4gICAgICAgIHZhciBmdW5kcyA9IEZ1bmRMb29rdXBUYWJsZS5saXN0RnVuZHMoKTtcclxuICAgICAgICBmdW5kcy5mb3JFYWNoKGZ1bmQgPT4ge1xyXG4gICAgICAgICAgICBJdGVtLmFkZChmdW5kLCAnI2Jhc2VsaW5lLWFjY29yZGlvbiAuc3VtbWFyeS1hY2NvcmRpb24nKTtcclxuICAgICAgICAgICAgSXRlbS5FeHBlbnNlVGFibGUuZmlsbEZyb21GdW5kKGZ1bmQpO1xyXG4gICAgICAgICAgICBjb25zdCBmdW5kT2JqZWN0ID0gbmV3IEZ1bmQoZnVuZCk7XHJcbiAgICAgICAgICAgIEl0ZW0udXBkYXRlSGVhZGVyKGBGdW5kICR7RnVuZExvb2t1cFRhYmxlLmdldE5hbWUoZnVuZCl9YCwgZnVuZCwgZnVuZE9iamVjdC5nZXRUb3RhbCgpKTtcclxuICAgICAgICB9KTtcclxuICAgIH0sXHJcbiAgICBjcmVhdGVTdXBwKCkge1xyXG4gICAgICAgIGNvbnN0IHN1cHAgPSBuZXcgU3VwcGxlbWVudGFsO1xyXG4gICAgICAgIHN1cHAuaW5pdGlhdGl2ZXMuZm9yRWFjaChwcm9ncmFtID0+IHtcclxuICAgICAgICAgICAgSXRlbS5hZGQocHJvZ3JhbS5uYW1lLCAnI3N1cHAtYWNjb3JkaW9uIC5zdW1tYXJ5LWFjY29yZGlvbicpO1xyXG4gICAgICAgICAgICBJdGVtLkV4cGVuc2VUYWJsZS5maWxsRnJvbUluaXQocHJvZ3JhbSk7XHJcbiAgICAgICAgICAgIEl0ZW0udXBkYXRlSGVhZGVyKHByb2dyYW0ubmFtZSwgcHJvZ3JhbS5uYW1lLCBwcm9ncmFtLm5ldCgpKTtcclxuICAgICAgICB9KTtcclxuICAgIH0sXHJcbiAgICB1cGRhdGVUb3BMaW5lcygpIHtcclxuICAgICAgICAvLyBhZGp1c2UgYmFzZWxpbmVcclxuICAgICAgICAvLyBjb25zdCBiYXNlbGluZSA9IG5ldyBCYXNlbGluZTtcclxuICAgICAgICBjb25zdCBiYXNlbGluZSA9IG5ldyBGdW5kKDEwMDApO1xyXG4gICAgICAgIGNvbnN0IGJhc2VsaW5lQW1vdW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2Jhc2VsaW5lLXRpdGxlIC50b3AtbGluZS1hbW91bnQnKVxyXG4gICAgICAgIGJhc2VsaW5lQW1vdW50LnRleHRDb250ZW50ID0gZm9ybWF0Q3VycmVuY3koYmFzZWxpbmUuZ2V0VG90YWwoKSk7XHJcbiAgICAgICAgLy8gYWRqdXN0IHN1cHBsZW1lbnRhbHNcclxuICAgICAgICBjb25zdCBzdXBwID0gbmV3IFN1cHBsZW1lbnRhbDtcclxuICAgICAgICBjb25zdCBzdXBwQW1vdW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3N1cHAtdGl0bGUgLnRvcC1saW5lLWFtb3VudCcpXHJcbiAgICAgICAgc3VwcEFtb3VudC50ZXh0Q29udGVudCA9IGZvcm1hdEN1cnJlbmN5KHN1cHAudG90YWwoKSk7XHJcbiAgICAgICAgLy8gY29sb3ItY29kZSBiYXNlbGluZVxyXG4gICAgICAgIGlmIChiYXNlbGluZS5nZXRUb3RhbCgpIDw9IEJhc2VsaW5lLnRhcmdldCgpKXtcclxuICAgICAgICAgICAgYmFzZWxpbmVBbW91bnQuc3R5bGUuY29sb3IgPSAnZ3JlZW4nO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGJhc2VsaW5lQW1vdW50LnN0eWxlLmNvbG9yID0gJ3JlZCc7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIGJ1aWxkKCkge1xyXG4gICAgICAgIHRoaXMuY3JlYXRlQmFzZWxpbmUoKTtcclxuICAgICAgICB0aGlzLmNyZWF0ZVN1cHAoKTtcclxuICAgICAgICAvLyBpbml0aWFsaXplIGVkaXQgYnV0dG9uc1xyXG4gICAgICAgIFRhYmxlLkJ1dHRvbnMuRWRpdC5pbml0KHJlZGlyZWN0Rm9yRWRpdCk7XHJcbiAgICAgICAgdGhpcy5BZGRJbml0QnV0dG9uLmluaXQoKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZVRvcExpbmVzKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZGVmYXVsdCBBY2NvcmRpb247XHJcbiIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9maWxlX3VwbG9hZC5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcbm9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9maWxlX3VwbG9hZC5jc3NcIjtcbiAgICAgICBleHBvcnQgZGVmYXVsdCBjb250ZW50ICYmIGNvbnRlbnQubG9jYWxzID8gY29udGVudC5sb2NhbHMgOiB1bmRlZmluZWQ7XG4iLCIvLyBmaWxlX3VwbG9hZC5qc1xyXG5pbXBvcnQgJy4vZmlsZV91cGxvYWQuY3NzJztcclxuaW1wb3J0IHsgcHJvY2Vzc1dvcmtib29rIH0gZnJvbSBcIi4uLy4uL3V0aWxzL1hMU1hfaGFuZGxlcnMuanNcIjtcclxuaW1wb3J0IE5hdkJ1dHRvbnMgZnJvbSAnLi4vbmF2X2J1dHRvbnMvbmF2X2J1dHRvbnMuanMnO1xyXG5cclxuZXhwb3J0IGNvbnN0IEZpbGVVcGxvYWQgPSB7XHJcbiAgICBpbml0IDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgTmF2QnV0dG9ucy5OZXh0LmRpc2FibGUoKTtcclxuICAgICAgICBjb25zdCBpbnB1dE9iamVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaWxlLWlucHV0Jyk7XHJcbiAgICAgICAgaW5wdXRPYmplY3QuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24oZXZlbnQpIHsgcmVhZFhMKGV2ZW50KSB9KTtcclxuICAgIH0sXHJcbiAgICBzaG93IDogZnVuY3Rpb24oKXtcclxuICAgICAgICBjb25zdCBpbnB1dE9iamVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaWxlLWlucHV0Jyk7XHJcbiAgICAgICAgaW5wdXRPYmplY3Quc3R5bGUuZGlzcGxheSA9ICcnO1xyXG4gICAgfSxcclxuICAgIGhpZGUgOiBmdW5jdGlvbigpe1xyXG4gICAgICAgIGNvbnN0IGlucHV0T2JqZWN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbGUtaW5wdXQnKTtcclxuICAgICAgICBpbnB1dE9iamVjdC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgfVxyXG59O1xyXG5cclxuZnVuY3Rpb24gcmVhZFhMKGV2ZW50KSB7XHJcbiAgICBjb25zdCBmaWxlID0gZXZlbnQudGFyZ2V0LmZpbGVzWzBdOyAvLyByZWFkIHVwbG9hZGVkIGZpbGVcclxuICAgIGNvbnN0IHNwaW5uZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXBsb2FkLXNwaW5uZXInKTsgLy8gZ2V0IHRoZSBzcGlubmVyIGVsZW1lbnRcclxuXHJcbiAgICBpZiAoZmlsZSkge1xyXG4gICAgICAgIC8vIFNob3cgdGhlIHNwaW5uZXJcclxuICAgICAgICBzcGlubmVyLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG5cclxuICAgICAgICAvLyByZWFkIGluIG5ldyBkYXRhXHJcbiAgICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcclxuICAgICAgICByZWFkZXIub25sb2FkID0gZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IGUudGFyZ2V0LnJlc3VsdDtcclxuXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzV29ya2Jvb2soYXJyYXlCdWZmZXIpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIEhpZGUgdGhlIHNwaW5uZXIgb25jZSBwcm9jZXNzaW5nIGlzIGRvbmVcclxuICAgICAgICAgICAgICAgIHNwaW5uZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgIE5hdkJ1dHRvbnMuTmV4dC5lbmFibGUoKTsgLy8gRW5hYmxlIHRoZSBuZXh0IGJ1dHRvbiBhZnRlciBwcm9jZXNzaW5nXHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBwcm9jZXNzaW5nIHdvcmtib29rOicsIGVycm9yKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBIaWRlIHRoZSBzcGlubmVyIGluIGNhc2Ugb2YgYW4gZXJyb3JcclxuICAgICAgICAgICAgICAgIHNwaW5uZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgIE5hdkJ1dHRvbnMuTmV4dC5lbmFibGUoKTsgLy8gRW5zdXJlIHRoZSBidXR0b24gaXMgcmUtZW5hYmxlZCBpbiBjYXNlIG9mIGFuIGVycm9yXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHJlYWRlci5vbmVycm9yID0gZnVuY3Rpb24oZXJyKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlYWRpbmcgZmlsZTonLCBlcnIpO1xyXG5cclxuICAgICAgICAgICAgLy8gSGlkZSB0aGUgc3Bpbm5lciBpbiBjYXNlIG9mIGFuIGVycm9yXHJcbiAgICAgICAgICAgIHNwaW5uZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgTmF2QnV0dG9ucy5OZXh0LmVuYWJsZSgpOyAvLyBFbnN1cmUgdGhlIGJ1dHRvbiBpcyByZS1lbmFibGVkIGluIGNhc2Ugb2YgYW4gZXJyb3JcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZSk7IC8vIFJlYWQgdGhlIGZpbGUgYXMgYW4gQXJyYXlCdWZmZXJcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgRmlsZVVwbG9hZDsiLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vbW9kYWwuY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vbW9kYWwuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiXHJcbmltcG9ydCAnLi9tb2RhbC5jc3MnO1xyXG5cclxuZnVuY3Rpb24gY2xlYXJNb2RhbCgpe1xyXG4gICAgdXBkYXRlTW9kYWxUaXRsZSgnJyk7XHJcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbW9kYWwtYm9keScpLmlubmVySFRNTCA9ICcnO1xyXG59XHJcblxyXG5mdW5jdGlvbiBoaWRlTW9kYWwoKSB7XHJcbiAgICAkKCcjbWFpbi1tb2RhbCcpLm1vZGFsKCdoaWRlJyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNob3dNb2RhbCgpIHtcclxuICAgICQoJyNtYWluLW1vZGFsJykubW9kYWwoJ3Nob3cnKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2hvd01vZGFsSGFuZGxlcigpIHtcclxuICAgIHNob3dNb2RhbCgnbWFpbi1tb2RhbCcpO1xyXG59XHJcblxyXG5jb25zdCBTdWJtaXQgPSB7XHJcbiAgICBoYW5kbGVyOiBudWxsLCBcclxuXHJcbiAgICBpbml0OiBmdW5jdGlvbihvblN1Ym1pdCkge1xyXG4gICAgICAgIGNvbnN0IG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW4tbW9kYWwnKTtcclxuICAgICAgICAvLyBhZGQgb25TdWJtaXQgZnVuY3Rpb24gYXMgaGFuZGxlclxyXG4gICAgICAgIHRoaXMuaGFuZGxlciA9IGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIG9uU3VibWl0KGV2ZW50KTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIEFkZGluZyB0aGUgaGFuZGxlciByZWZlcmVuY2UgYXMgdGhlIGV2ZW50IGxpc3RlbmVyXHJcbiAgICAgICAgbW9kYWwuYWRkRXZlbnRMaXN0ZW5lcignc3VibWl0JywgdGhpcy5oYW5kbGVyKTtcclxuXHJcbiAgICAgICAgLy8gYWRkIGV2ZW50IGxpc3RlbmVyIHRvIGVuYWJsZSBjbG9zZSB4XHJcbiAgICAgICAgY29uc3QgeCA9IG1vZGFsLnF1ZXJ5U2VsZWN0b3IoJyNtb2RhbC1jbG9zZS14Jyk7XHJcbiAgICAgICAgeC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGhpZGVNb2RhbCk7XHJcbiAgICB9LFxyXG5cclxuICAgIGRlaW5pdDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgY29uc3QgbW9kYWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi1tb2RhbCcpO1xyXG4gICAgICAgIGlmICh0aGlzLmhhbmRsZXIgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgLy8gUmVtb3ZpbmcgdGhlIGV2ZW50IGxpc3RlbmVyIGFuZCBjbGVhciB0aGUgaGFuZGxlclxyXG4gICAgICAgICAgICBtb2RhbC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdWJtaXQnLCB0aGlzLmhhbmRsZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZXIgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyByZW1vdmUgZXZlbnQgbGlzdGVuZXIgdG8gZW5hYmxlIGNsb3NlIHhcclxuICAgICAgICBjb25zdCB4ID0gbW9kYWwucXVlcnlTZWxlY3RvcignI21vZGFsLWNsb3NlLXgnKTtcclxuICAgICAgICB4LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgaGlkZU1vZGFsKTtcclxuICAgIH1cclxufTtcclxuXHJcbmNvbnN0IExpbmsgPSB7XHJcbiAgICBhZGQgOiBmdW5jdGlvbihidXR0b25faWQpe1xyXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGJ1dHRvbl9pZCkuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzaG93TW9kYWxIYW5kbGVyKVxyXG4gICAgfSxcclxuICAgIHJlbW92ZSA6IGZ1bmN0aW9uKGJ1dHRvbl9pZCl7XHJcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYnV0dG9uX2lkKS5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHNob3dNb2RhbEhhbmRsZXIpXHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZU1vZGFsVGl0bGUodGl0bGUpIHtcclxuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb2RhbC10aXRsZScpLnRleHRDb250ZW50ID0gdGl0bGU7XHJcbn1cclxuXHJcbmNvbnN0IFRpdGxlID0ge1xyXG4gICAgdXBkYXRlIDogZnVuY3Rpb24odGl0bGUpIHsgdXBkYXRlTW9kYWxUaXRsZSh0aXRsZSkgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgTW9kYWwgPSB7XHJcbiAgICBoaWRlIDogaGlkZU1vZGFsLFxyXG4gICAgc2hvdyA6IHNob3dNb2RhbCxcclxuICAgIGNsZWFyIDogY2xlYXJNb2RhbCxcclxuICAgIFRpdGxlIDogVGl0bGUsXHJcbiAgICBMaW5rIDogTGluayxcclxuICAgIFN1Ym1pdDogU3VibWl0XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IE1vZGFsOyIsImltcG9ydCAnLi9ib2R5LmNzcyc7XHJcblxyXG5pbXBvcnQgV2VsY29tZSBmcm9tICcuLi8uLi9jb21wb25lbnRzL3dlbGNvbWUvd2VsY29tZS5qcydcclxuaW1wb3J0IEFjY29yZGlvbiBmcm9tICcuLi9hY2NvcmRpb24vYWNjb3JkaW9uLmpzJztcclxuaW1wb3J0IEZpbGVVcGxvYWQgZnJvbSAnLi4vZmlsZV91cGxvYWQvZmlsZV91cGxvYWQuanMnO1xyXG5pbXBvcnQgTW9kYWwgZnJvbSAnLi4vbW9kYWwvbW9kYWwuanMnO1xyXG5pbXBvcnQgTmF2QnV0dG9ucyBmcm9tICcuLi9uYXZfYnV0dG9ucy9uYXZfYnV0dG9ucy5qcyc7XHJcbmltcG9ydCBQcm9tcHQgZnJvbSAnLi4vcHJvbXB0L3Byb21wdC5qcyc7XHJcbmltcG9ydCBTaWRlYmFyIGZyb20gJy4uL3NpZGViYXIvc2lkZWJhci5qcyc7XHJcbmltcG9ydCBUYWJsZSBmcm9tICcuLi90YWJsZS90YWJsZS5qcyc7XHJcbmltcG9ydCBUb29sdGlwIGZyb20gJy4uL3Rvb2x0aXAvdG9vbHRpcC5qcyc7ICBcclxuXHJcbmZ1bmN0aW9uIHJlc2V0UGFnZSgpIHtcclxuICAgIC8vIGhpZGUgZXZlcnl0aGluZyBpbiB0aGUgYm9keVxyXG4gICAgV2VsY29tZS5oaWRlKCk7XHJcbiAgICBNb2RhbC5jbGVhcigpO1xyXG4gICAgTW9kYWwuaGlkZSgpO1xyXG4gICAgTmF2QnV0dG9ucy5oaWRlKCk7XHJcbiAgICBQcm9tcHQuaGlkZSgpO1xyXG4gICAgVGFibGUuaGlkZSgpO1xyXG4gICAgU2lkZWJhci5oaWRlKCk7XHJcbiAgICBBY2NvcmRpb24uaGlkZSgpO1xyXG4gICAgRmlsZVVwbG9hZC5oaWRlKCk7XHJcbiAgICBUb29sdGlwLmhpZGUoKTtcclxuXHJcbiAgICAvLyByZXNldCBmaWx0ZXIgZHJvcGRvd25zXHJcbiAgICBUYWJsZS5GaWx0ZXIuZGVsZXRlQWxsKCk7XHJcblxyXG4gICAgUHJvbXB0LkJ1dHRvbnMucmVzZXQoKTtcclxuICAgIC8vIGRpc2FibGUgc3VibWl0IGJ1dHRvblxyXG4gICAgTW9kYWwuU3VibWl0LmRlaW5pdCgpO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgQm9keSA9IHtcclxuICAgIHJlc2V0IDogcmVzZXRQYWdlXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEJvZHk7IiwiXG4gICAgICBpbXBvcnQgQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCI7XG4gICAgICBpbXBvcnQgZG9tQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRGbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanNcIjtcbiAgICAgIGltcG9ydCBzZXRBdHRyaWJ1dGVzIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0U3R5bGVFbGVtZW50IGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzXCI7XG4gICAgICBpbXBvcnQgc3R5bGVUYWdUcmFuc2Zvcm1GbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlVGFnVHJhbnNmb3JtLmpzXCI7XG4gICAgICBpbXBvcnQgY29udGVudCwgKiBhcyBuYW1lZEV4cG9ydCBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL2hlYWRlci5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcbm9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9oZWFkZXIuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiaW1wb3J0ICcuL2hlYWRlci5jc3MnO1xyXG5cclxuaW1wb3J0IEN1cnJlbnRGdW5kIGZyb20gJy4uLy4uL21vZGVscy9jdXJyZW50X2Z1bmQnO1xyXG5pbXBvcnQgeyBGSVNDQUxfWUVBUiB9IGZyb20gJy4uLy4uL2NvbnN0YW50cyc7XHJcblxyXG5leHBvcnQgY29uc3QgVGl0bGUgPSB7XHJcbiAgICB1cGRhdGUgOiBmdW5jdGlvbih0aXRsZSl7XHJcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ0aXRsZVwiKS50ZXh0Q29udGVudCA9IHRpdGxlO1xyXG4gICAgfSxcclxuICAgIGRlZmF1bHQoKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGUoYEZZJHtGSVNDQUxfWUVBUn0gQnVkZ2V0IFJlcXVlc3RgKVxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgU3VidGl0bGUgPSB7XHJcbiAgICB1cGRhdGUgOiBmdW5jdGlvbihzdWJ0aXRsZSl7XHJcbiAgICAgICAgLy8gZ2V0IGN1cnJlbnQgZnVuZFxyXG4gICAgICAgIHZhciBmdW5kID0gQ3VycmVudEZ1bmQubmFtZSgpO1xyXG4gICAgICAgIGlmIChmdW5kKXtcclxuICAgICAgICAgICAgdmFyIHN1YnRpdGxlID0gYCR7c3VidGl0bGV9OiAke2Z1bmR9YDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzdWJ0aXRsZVwiKS50ZXh0Q29udGVudCA9IHN1YnRpdGxlO1xyXG4gICAgfVxyXG59IiwiXG4gICAgICBpbXBvcnQgQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCI7XG4gICAgICBpbXBvcnQgZG9tQVBJIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRGbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanNcIjtcbiAgICAgIGltcG9ydCBzZXRBdHRyaWJ1dGVzIGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0U3R5bGVFbGVtZW50IGZyb20gXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzXCI7XG4gICAgICBpbXBvcnQgc3R5bGVUYWdUcmFuc2Zvcm1GbiBmcm9tIFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlVGFnVHJhbnNmb3JtLmpzXCI7XG4gICAgICBpbXBvcnQgY29udGVudCwgKiBhcyBuYW1lZEV4cG9ydCBmcm9tIFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL2Zvcm0uY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5vcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vZm9ybS5jc3NcIjtcbiAgICAgICBleHBvcnQgZGVmYXVsdCBjb250ZW50ICYmIGNvbnRlbnQubG9jYWxzID8gY29udGVudC5sb2NhbHMgOiB1bmRlZmluZWQ7XG4iLCIvLyBmdW5jdGlvbiB0byBhZGQgcXVlc3Rpb25zIHRvIGZvcm1zXHJcblxyXG5pbXBvcnQgRHJvcGRvd24gZnJvbSBcIi4vZHJvcGRvd25cIjtcclxuXHJcbi8vIGlucHV0VHlwZSBpcyBmb3IgdmFsaWRhdGlvbiAoJ251bWJlcicgb3IgJ3RleHQnLCBldGMpXHJcbmZ1bmN0aW9uIGFwcGVuZEZvcm1FbGVtZW50KGxhYmVsLCBpbnB1dEVsLCBpbnB1dElkLCByZXF1aXJlZCkge1xyXG5cclxuICAgIC8vIGNoYW5nZSBpZiB3ZSB3YW50IGZvcm1zIGVsc2V3aGVyZVxyXG4gICAgY29uc3QgZm9ybSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduZXctZm9ybScpO1xyXG5cclxuICAgIC8vIGNyZWF0ZSBvdXRlciB3cmFwcGVyIGZvciBlbGVtZW50XHJcbiAgICBjb25zdCB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7ICBcclxuXHJcbiAgICAvLyBsYWJlbCBxdWVzdGlvblxyXG4gICAgY29uc3QgbGFiZWxFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xhYmVsJyk7XHJcbiAgICBsYWJlbEVsLnRleHRDb250ZW50ID0gbGFiZWw7XHJcblxyXG4gICAgLy8gbWFyayBhcyByZXF1aXJlZCBpZiBhcHBsaWNhYmxlXHJcbiAgICBpbnB1dEVsLnJlcXVpcmVkID0gcmVxdWlyZWQ7XHJcblxyXG4gICAgLy8gSWYgYW4gSUQgaXMgcHJvdmlkZWQsIHNldCBpdCBvbiB0aGUgZWxlbWVudFxyXG4gICAgaWYgKGlucHV0SWQpIHtcclxuICAgICAgICBpbnB1dEVsLmlkID0gaW5wdXRJZDtcclxuICAgIH1cclxuICBcclxuICAgIC8vIGFkZCBlbGVtZW50c1xyXG4gICAgd3JhcHBlci5hcHBlbmRDaGlsZChsYWJlbEVsKTtcclxuICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQoaW5wdXRFbCk7XHJcbiAgICBmb3JtLmFwcGVuZENoaWxkKHdyYXBwZXIpO1xyXG59IFxyXG5cclxuZXhwb3J0IGNvbnN0IE5ld0ZpZWxkID0ge1xyXG4gICAgc2hvcnRUZXh0IDogZnVuY3Rpb24obGFiZWwsIGlucHV0SWQsIHJlcXVpcmVkID0gZmFsc2UpIHtcclxuICAgICAgICBjb25zdCBpbnB1dEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcclxuICAgICAgICBpbnB1dEVsLnR5cGUgPSAndGV4dCc7XHJcbiAgICAgICAgYXBwZW5kRm9ybUVsZW1lbnQobGFiZWwsIGlucHV0RWwsIGlucHV0SWQscmVxdWlyZWQpO1xyXG4gICAgfSxcclxuICAgIGxvbmdUZXh0IDogZnVuY3Rpb24obGFiZWwsIGlucHV0SWQsIHJlcXVpcmVkID0gZmFsc2UpIHtcclxuICAgICAgICBjb25zdCBpbnB1dEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcclxuICAgICAgICBhcHBlbmRGb3JtRWxlbWVudChsYWJlbCwgaW5wdXRFbCwgaW5wdXRJZCwgcmVxdWlyZWQpO1xyXG4gICAgfSxcclxuICAgIG51bWVyaWNJbnB1dCA6IGZ1bmN0aW9uKGxhYmVsLCBpbnB1dElkLCByZXF1aXJlZCA9IGZhbHNlKSB7XHJcbiAgICAgICAgY29uc3QgaW5wdXRFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XHJcbiAgICAgICAgaW5wdXRFbC50eXBlID0gJ251bWJlcic7XHJcbiAgICAgICAgYXBwZW5kRm9ybUVsZW1lbnQobGFiZWwsIGlucHV0RWwsIGlucHV0SWQscmVxdWlyZWQpO1xyXG4gICAgfSxcclxuICAgIGRyb3Bkb3duIDogZnVuY3Rpb24obGFiZWwsIGlucHV0SWQsIG9wdGlvbkFycmF5LCByZXF1aXJlZCA9IGZhbHNlKXtcclxuICAgICAgICB2YXIgaW5wdXRFbCA9IERyb3Bkb3duLmNyZWF0ZShvcHRpb25BcnJheSk7XHJcbiAgICAgICAgYXBwZW5kRm9ybUVsZW1lbnQobGFiZWwsIGlucHV0RWwsIGlucHV0SWQsIHJlcXVpcmVkKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgTmV3RmllbGQ7IiwiZnVuY3Rpb24gYWRkU3VibWl0QnV0dG9uVG9Gb3JtKGZvcm1faWQpIHtcclxuICAgIC8vIEZpbmQgdGhlIGZvcm0gYnkgaXRzIElEXHJcbiAgICBjb25zdCBmb3JtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZm9ybV9pZCk7XHJcbiAgXHJcbiAgICAvLyBDcmVhdGUgdGhlIGNvbnRhaW5lciBgZGl2YCBmb3IgdGhlIGJ1dHRvblxyXG4gICAgY29uc3QgYnV0dG9uQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICBidXR0b25Db250YWluZXIuaWQgPSAnc3VibWl0LWJ0bi1jb250YWluZXInO1xyXG4gICAgXHJcbiAgICAvLyBDcmVhdGUgdGhlIHN1Ym1pdCBpbnB1dFxyXG4gICAgY29uc3Qgc3VibWl0SW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xyXG4gICAgc3VibWl0SW5wdXQuY2xhc3NOYW1lID0gJ2J0biBidG4tc3VibWl0JzsgLy8gVXNlIGFwcHJvcHJpYXRlIGNsYXNzIGZvciB5b3VyIGRlc2lnblxyXG4gICAgc3VibWl0SW5wdXQudHlwZSA9ICdzdWJtaXQnO1xyXG4gICAgc3VibWl0SW5wdXQudmFsdWUgPSAnU3VibWl0JztcclxuXHJcbiAgICAvLyBBcHBlbmQgdGhlIHN1Ym1pdCBpbnB1dCB0byB0aGUgY29udGFpbmVyXHJcbiAgICBidXR0b25Db250YWluZXIuYXBwZW5kQ2hpbGQoc3VibWl0SW5wdXQpO1xyXG4gICAgXHJcbiAgICAvLyBBcHBlbmQgdGhlIGNvbnRhaW5lciB0byB0aGUgZm9ybVxyXG4gICAgZm9ybS5hcHBlbmRDaGlsZChidXR0b25Db250YWluZXIpO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgU3VibWl0QnV0dG9uID0ge1xyXG4gICAgYWRkIDogZnVuY3Rpb24oKSB7IGFkZFN1Ym1pdEJ1dHRvblRvRm9ybSgnbmV3LWZvcm0nKSB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFN1Ym1pdEJ1dHRvbjsiLCJpbXBvcnQgJy4vZm9ybS5jc3MnO1xyXG5cclxuaW1wb3J0IERyb3Bkb3duIGZyb20gXCIuL3N1YmNvbXBvbmVudHMvZHJvcGRvd24uanNcIjtcclxuaW1wb3J0IE5ld0ZpZWxkIGZyb20gXCIuL3N1YmNvbXBvbmVudHMvZmllbGRzLmpzXCI7XHJcbmltcG9ydCBTdWJtaXRCdXR0b24gZnJvbSBcIi4vc3ViY29tcG9uZW50cy9zdWJtaXQuanNcIjtcclxuXHJcbmZ1bmN0aW9uIGZldGNoQWxsUmVzcG9uc2VzKGV2ZW50KSB7XHJcblxyXG4gICAgLy8gQXNzdW1pbmcgYGV2ZW50LnRhcmdldGAgaXMgdGhlIGZvcm0gaXRzZWxmXHJcbiAgICBjb25zdCBmb3JtID0gZXZlbnQudGFyZ2V0O1xyXG4gICAgXHJcbiAgICAvLyBJbml0aWFsaXplIGFuIGVtcHR5IGFycmF5IHRvIGhvbGQgdGhlIGlucHV0IHZhbHVlc1xyXG4gICAgbGV0IGZvcm1EYXRhID0ge307XHJcbiAgICBcclxuICAgIC8vIExvb3AgdGhyb3VnaCBlYWNoIGZvcm0gZWxlbWVudFxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmb3JtLmVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBmb3JtLmVsZW1lbnRzW2ldO1xyXG4gICAgICBcclxuICAgICAgLy8gRXhjbHVkZSBlbGVtZW50cyB0aGF0IGFyZW4ndCBpbnB1dHMsIHRleHRhcmVhcywgb3Igc2VsZWN0XHJcbiAgICAgIGlmIChlbGVtZW50LnRhZ05hbWUgPT09ICdJTlBVVCcgfHxcclxuICAgICAgICAgIGVsZW1lbnQudGFnTmFtZSA9PT0gJ1RFWFRBUkVBJyB8fFxyXG4gICAgICAgICAgZWxlbWVudC50YWdOYW1lID09PSAnU0VMRUNUJykge1xyXG4gICAgICAgIC8vIEV4Y2x1ZGUgaW5wdXQgdHlwZXMgdGhhdCBhcmUgbm90IGNvbnNpZGVyZWQgZm9yIHN1Ym1pc3Npb24gKHN1Y2ggYXMgYHN1Ym1pdGApXHJcbiAgICAgICAgaWYgKGVsZW1lbnQudHlwZSAhPT0gJ3N1Ym1pdCcgJiYgZWxlbWVudC50eXBlICE9PSAnYnV0dG9uJykge1xyXG4gICAgICAgICAgZm9ybURhdGFbZWxlbWVudC5pZF0gPSBlbGVtZW50LnZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICBmb3JtLnJlc2V0KCk7XHJcbiAgICByZXR1cm4gZm9ybURhdGE7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFkZEZvcm0oZWxlbWVudF9pZCA9ICdtb2RhbC1ib2R5JywgZm9ybV9pZCA9ICduZXctZm9ybScpIHtcclxuICBcclxuICBjb25zdCB0YXJnZXRfZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRfaWQpO1xyXG5cclxuICAvLyBjcmVhdGUgZm9ybVxyXG4gIGNvbnN0IGZvcm0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdmb3JtJyk7XHJcbiAgZm9ybS5zZXRBdHRyaWJ1dGUoJ2lkJywgZm9ybV9pZCk7XHJcblxyXG4gIC8vIEFwcGVuZCB0aGUgZm9ybSB0byB0aGUgbW9kYWwgYm9keVxyXG4gIHRhcmdldF9lbGVtLmFwcGVuZENoaWxkKGZvcm0pO1xyXG5cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IEZvcm0gPSB7XHJcbiAgbmV3IDogZnVuY3Rpb24ocGFyZW50X2VsZW1faWQpIHsgYWRkRm9ybShwYXJlbnRfZWxlbV9pZCwgJ25ldy1mb3JtJykgfSxcclxuICBmZXRjaEFsbFJlc3BvbnNlcyA6IGZ1bmN0aW9uKGV2ZW50KSB7IHJldHVybiBmZXRjaEFsbFJlc3BvbnNlcyhldmVudCkgfSxcclxuICBOZXdGaWVsZCA6IE5ld0ZpZWxkLFxyXG4gIERyb3Bkb3duIDogRHJvcGRvd24sXHJcbiAgU3VibWl0QnV0dG9uIDogU3VibWl0QnV0dG9uXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEZvcm07IiwiaW1wb3J0IFByb21wdCBmcm9tIFwiLi4vY29tcG9uZW50cy9wcm9tcHQvcHJvbXB0LmpzXCI7XHJcbmltcG9ydCBTaWRlYmFyIGZyb20gXCIuLi9jb21wb25lbnRzL3NpZGViYXIvc2lkZWJhci5qc1wiO1xyXG5pbXBvcnQgTmF2QnV0dG9ucyBmcm9tIFwiLi4vY29tcG9uZW50cy9uYXZfYnV0dG9ucy9uYXZfYnV0dG9ucy5qc1wiO1xyXG5pbXBvcnQgQm9keSBmcm9tIFwiLi4vY29tcG9uZW50cy9ib2R5L2JvZHkuanNcIjtcclxuaW1wb3J0IHsgU3VidGl0bGUsIFRpdGxlIH0gZnJvbSBcIi4uL2NvbXBvbmVudHMvaGVhZGVyL2hlYWRlci5qc1wiO1xyXG5pbXBvcnQgVGFibGUgZnJvbSBcIi4uL2NvbXBvbmVudHMvdGFibGUvdGFibGUuanNcIjtcclxuaW1wb3J0IEZvcm0gZnJvbSBcIi4uL2NvbXBvbmVudHMvZm9ybS9mb3JtLmpzXCI7XHJcbmltcG9ydCBNb2RhbCBmcm9tIFwiLi4vY29tcG9uZW50cy9tb2RhbC9tb2RhbC5qc1wiO1xyXG5cclxuaW1wb3J0IHsgQ3VycmVudFBhZ2UsIEFjY291bnRTdHJpbmcgfSBmcm9tICcuLi9tb2RlbHMvJ1xyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBWaWV3IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICAvLyBwYWdlIHN0YXRlIGluIGxvY2FsIHN0b3JhZ2VcclxuICAgICAgICB0aGlzLnBhZ2Vfc3RhdGUgPSAnJztcclxuXHJcbiAgICAgICAgLy8gd2hldGhlciB0byBkaXNwbGF5XHJcbiAgICAgICAgdGhpcy5uYXZCdXR0b25zID0gdHJ1ZTsgXHJcbiAgICAgICAgdGhpcy5zaWRlYmFyID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgLy8gdGV4dCB0byBzaG93IGluIHRoZSBwcm9tcHQgYXJlYVxyXG4gICAgICAgIHRoaXMucHJvbXB0ID0gbnVsbDtcclxuXHJcbiAgICAgICAgLy8gc3VidGl0bGUgdGV4dFxyXG4gICAgICAgIHRoaXMuc3VidGl0bGUgPSAnJztcclxuXHJcbiAgICAgICAgLy8gdGFibGUgb2JqZWN0IG9mIGNsYXNzIFZpZXdUYWJsZSBvciBudWxsXHJcbiAgICAgICAgdGhpcy50YWJsZSA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgdmlzaXQoKSB7XHJcbiAgICAgICAgLy8gdXBkYXRlIHBhZ2Ugc3RhdGVcclxuICAgICAgICBDdXJyZW50UGFnZS51cGRhdGUodGhpcy5wYWdlX3N0YXRlKTtcclxuXHJcbiAgICAgICAgLy8gc3RhcnQgd2l0aCBhIGJsYW5rIHBhZ2VcclxuICAgICAgICBCb2R5LnJlc2V0KCk7XHJcblxyXG4gICAgICAgIC8vIGFkZCBkZWZhdWx0IHRpdGxlXHJcbiAgICAgICAgVGl0bGUuZGVmYXVsdCgpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIGRlZmF1bHQgdG8gc2hvd2luZyBuYXZidXR0b25zXHJcbiAgICAgICAgaWYgKHRoaXMubmF2QnV0dG9ucykgeyBOYXZCdXR0b25zLnNob3coKTsgfTtcclxuICAgICAgICBcclxuICAgICAgICAvLyBkZWZhdWx0IHRvIHNob3dpbmcgc2lkZWJhclxyXG4gICAgICAgIGlmICh0aGlzLnNpZGViYXIpIHsgU2lkZWJhci5zaG93KCkgfTtcclxuXHJcbiAgICAgICAgLy8gaW5pdGlhbGl6ZSBwcm9tcHQgdGV4dCBhbmQgYnV0dG9uc1xyXG4gICAgICAgIGlmICh0aGlzLnByb21wdCkgeyBQcm9tcHQuVGV4dC51cGRhdGUodGhpcy5wcm9tcHQpIH07XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gaW5pdGlhbGl6ZSB0YWJsZVxyXG4gICAgICAgIGlmICh0aGlzLnRhYmxlKSB7IHRoaXMudGFibGUuYnVpbGQoKTsgfVxyXG5cclxuICAgICAgICAvLyBzaG93IHBhZ2Ugc3VidGl0bGVcclxuICAgICAgICBpZiAodGhpcy5zdWJ0aXRsZSkgeyBTdWJ0aXRsZS51cGRhdGUodGhpcy5zdWJ0aXRsZSkgfTtcclxuICAgIH1cclxuXHJcbiAgICBjbGVhbnVwKCkgeyByZXR1cm47IH1cclxuXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBWaWV3VGFibGUge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKCl7XHJcbiAgICAgICAgLy8gRW5zdXJlIG1ldGhvZHMgcmV0YWluIHRoZSBjb3JyZWN0IGB0aGlzYCBjb250ZXh0XHJcbiAgICAgICAgdGhpcy5zdWJtaXROZXdSb3cgPSB0aGlzLnN1Ym1pdE5ld1Jvdy5iaW5kKHRoaXMpO1xyXG5cclxuICAgICAgICB0aGlzLmNvbHVtbnMgPSBbXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdBY2NvdW50IFN0cmluZycsIGNsYXNzTmFtZTogJ2FjY291bnQtc3RyaW5nJyB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnQXBwcm9wcmlhdGlvbiBOYW1lJywgY2xhc3NOYW1lOiAnYXBwcm9wLW5hbWUnLCBoaWRlOiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdBcHByb3ByaWF0aW9uJywgY2xhc3NOYW1lOiAnYXBwcm9wJywgaGlkZTogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnQ29zdCBDZW50ZXIgTmFtZScsIGNsYXNzTmFtZTogJ2NjLW5hbWUnLCAgaGlkZTogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnQ29zdCBDZW50ZXInLCBjbGFzc05hbWU6ICdjYycsICBoaWRlOiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdGdW5kIE5hbWUnLCBjbGFzc05hbWU6ICdmdW5kLW5hbWUnLCAgaGlkZTogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnRnVuZCcsIGNsYXNzTmFtZTogJ2Z1bmQnLCAgaGlkZTogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnRWRpdCcsIGNsYXNzTmFtZTogJ2VkaXQnIH0sXHJcbiAgICAgICAgXTtcclxuICAgICAgICBcclxuICAgICAgICAvLyB3aGV0aGVyIHRvIGFkZCBhbiBlZGl0IGNvbHVtblxyXG4gICAgICAgIHRoaXMuYWRkRWRpdCA9IHRydWUgO1xyXG5cclxuICAgICAgICAvLyBtZXNzYWdlIHRvIHNob3cgaWYgdGhlcmUncyBubyBzYXZlZCBkYXRhXHJcbiAgICAgICAgdGhpcy5ub0RhdGFNZXNzYWdlID0gbnVsbDtcclxuICAgXHJcbiAgICAgICAgLy8gdGV4dCB0byBzaG93IGZvciBuZXcgcm93IGJ1dHRvblxyXG4gICAgICAgIHRoaXMuYWRkQnV0dG9uVGV4dCA9IG51bGwgO1xyXG5cclxuICAgICAgICAvLyB3aGV0aGVyIHRvIHNob3cgYXMgYSBkYXRhdGFibGVcclxuICAgICAgICB0aGlzLmRhdGFUYWJsZSA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgYnVpbGQoKSB7XHJcbiAgICAvLyBidWlsZCB0YWJsZSBmcm9tIGxvY2FsIHN0b3JhZ2UgYW5kIGluaXRpYWxpemUgZWRpdCBidXR0b25zXHJcblxyXG4gICAgICAgIC8vIGFkZCB0aGUgYWRkIG5ldyByb3cgYnV0dG9uIGlmIG5lZWRlZFxyXG4gICAgICAgIGlmICh0aGlzLmFkZEJ1dHRvblRleHQpIHsgXHJcbiAgICAgICAgICAgIHRoaXMuc2V0VXBGb3JtKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBmaWxsIHRhYmxlIHdpdGggbmV3IGRhdGEgZnJvbSBsb2NhbCBzdG9yYWdlXHJcbiAgICAgICAgaWYoYXdhaXQgVGFibGUuRGF0YS5sb2FkKCkpIHsgICAgICBcclxuXHJcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIGRhdGF0YWJsZSBvYmplY3RcclxuICAgICAgICAgICAgaWYodGhpcy5kYXRhVGFibGUpe3RoaXMuaW5pdERhdGFUYWJsZSgpfVxyXG5cclxuICAgICAgICAgICAgLy8gYWRkIGFuIGVkaXQgY29sdW1uIGlmIG5lZWRlZFxyXG4gICAgICAgICAgICBpZiAodGhpcy5hZGRFZGl0KSB7IFxyXG4gICAgICAgICAgICAgICAgVGFibGUuQ29sdW1ucy5hZGRBdEVuZChUYWJsZS5CdXR0b25zLmVkaXRfY29uZmlybV9idG5zLCAnRWRpdCcpOyBcclxuICAgICAgICAgICAgICAgIC8vIGFjdGl2YXRlIGVkaXQgYnV0dG9uc1xyXG4gICAgICAgICAgICAgICAgVGFibGUuQnV0dG9ucy5FZGl0LmluaXQodGhpcy5hY3Rpb25PbkVkaXQsIHRoaXMudXBkYXRlVGFibGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyBhc3NpZ24gdGhlIGNvcnJlY3QgY2xhc3NlcyBiYXNlZCBvbiB0aGUgdGFibGUgY29sdW1uc1xyXG4gICAgICAgICAgICBUYWJsZS5Db2x1bW5zLmFzc2lnbkNsYXNzZXModGhpcy5jb2x1bW5zKTtcclxuXHJcbiAgICAgICAgICAgIC8vIEFwcGx5IGFueSB1cGRhdGUgZnVuY3Rpb24gdG8gbWFrZSBzdXJlIHNpZGViYXIgaXMgdXAgdG8gZGF0ZVxyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVRhYmxlKCk7XHJcblxyXG4gICAgICAgICAgICAvLyBBZGQgYWxsIHJlbGV2YW50IGZpbHRlcnMgdG8gdGFibGVcclxuICAgICAgICAgICAgVGFibGUuRmlsdGVyLmFkZCgnQXBwcm9wcmlhdGlvbicsICdhcHByb3AtbmFtZScpO1xyXG4gICAgICAgICAgICBUYWJsZS5GaWx0ZXIuYWRkKCdDb3N0IENlbnRlcicsICdjYy1uYW1lJyk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbHVtbnMuc29tZShjb2x1bW4gPT4gY29sdW1uLmNsYXNzTmFtZSA9PT0gJ29iamVjdC1uYW1lJykpe1xyXG4gICAgICAgICAgICAgICAgVGFibGUuRmlsdGVyLmFkZCgnT2JqZWN0JywgJ29iamVjdC1uYW1lJyk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbHVtbnMuc29tZShjb2x1bW4gPT4gY29sdW1uLmNsYXNzTmFtZSA9PT0gJ29iamVjdC1jYXRlZ29yeScpKXtcclxuICAgICAgICAgICAgICAgIFRhYmxlLkZpbHRlci5hZGQoJ09iamVjdCBDYXRlZ29yeScsICdvYmplY3QtY2F0ZWdvcnknKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgICAgICAgLy8gc2hvdyBhIG1lc3NhZ2UgaWYgdGhlcmUncyBubyBzYXZlZCB0YWJsZSBkYXRhIGZvciB0aGUgc2VsZWN0ZWQgZnVuZFxyXG4gICAgICAgICAgICBpZiAodGhpcy5ub0RhdGFNZXNzYWdlKSB7XHJcbiAgICAgICAgICAgICAgICBQcm9tcHQuVGV4dC51cGRhdGUodGhpcy5ub0RhdGFNZXNzYWdlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgaW5pdERhdGFUYWJsZSgpIHtcclxuICAgICAgICBUYWJsZS5hZGp1c3RXaWR0aCgnMTAwJScpO1xyXG4gICAgICAgIC8vIEluaXRpYWxpemUgRGF0YXRhYmxlc1xyXG4gICAgICAgIGlmICggISQuZm4uZGF0YVRhYmxlLmlzRGF0YVRhYmxlKCcjbWFpbi10YWJsZScpICkge1xyXG4gICAgICAgICAgICAkKCcjbWFpbi10YWJsZScpLkRhdGFUYWJsZSh7XHJcbiAgICAgICAgICAgICAgICBwYWdpbmc6IGZhbHNlLCAvLyBEaXNhYmxlIHBhZ2luYXRpb25cclxuICAgICAgICAgICAgICAgIGluZm86IGZhbHNlLCAvLyBEaXNhYmxlIHRhYmxlIGluZm9ybWF0aW9uIGRpc3BsYXlcclxuICAgICAgICAgICAgICAgIHNlYXJjaGluZzogZmFsc2UgLy8gRGlzYWJsZSB0aGUgc2VhcmNoIGJhclxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHBsYWNlaG9sZGVyIGZvciBhY3Rpb24gb24gcm93IGVkaXQgY2xpY2tcclxuICAgIGFjdGlvbk9uRWRpdCgpIHsgcmV0dXJuIH1cclxuXHJcbiAgICAvLyB1cGRhdGUgZnVuY3Rpb24gZm9yIHRoZSBzaWRlYmFyOyBkZWZhdWx0IHRvIGp1c3Qgc2F2aW5nIHRoZSB0YWJsZVxyXG4gICAgdXBkYXRlVGFibGUoKSB7IFRhYmxlLnNhdmUoKSB9XHJcblxyXG4gICAgLy8gZXh0cmEgcXVlc3Rpb25zIG9mIHRoZSBmb3JtIHRvIGFkZCBhIG5ldyByb3dcclxuICAgIGFkZEN1c3RvbVF1ZXN0aW9ucygpIHsgcmV0dXJuIH07XHJcblxyXG4gICAgc2V0VXBGb3JtKCkge1xyXG4gICAgICAgIC8vIHNob3cgYWRkIGJ1dHRvblxyXG4gICAgICAgIFRhYmxlLkJ1dHRvbnMuQWRkUm93LnNob3coKTtcclxuICAgICAgICBUYWJsZS5CdXR0b25zLkFkZFJvdy51cGRhdGVUZXh0KHRoaXMuYWRkQnV0dG9uVGV4dCk7XHJcblxyXG4gICAgICAgIC8vIHNldCB1cCBtb2RhbCBmb3IgZm9ybSB3aGVuIGFkZCBidXR0b24gaXMgcHJlc3NlZFxyXG4gICAgICAgIE1vZGFsLmNsZWFyKCk7XHJcbiAgICAgICAgTW9kYWwuTGluay5hZGQoJ2FkZC1idG4nKTtcclxuICAgICAgICBNb2RhbC5UaXRsZS51cGRhdGUodGhpcy5hZGRCdXR0b25UZXh0KTtcclxuXHJcbiAgICAgICAgLy8gY3JlYXRlIGZvcm1cclxuICAgICAgICBGb3JtLm5ldygnbW9kYWwtYm9keScpO1xyXG5cclxuICAgICAgICAvLyBhZGQgY3VzdG9tIHF1ZXN0aW9uc1xyXG4gICAgICAgIHRoaXMuYWRkQ3VzdG9tUXVlc3Rpb25zKCk7XHJcbiAgICAgICAgLy8gYWRkIHN1Ym1pdCBidXR0b25cclxuICAgICAgICBGb3JtLlN1Ym1pdEJ1dHRvbi5hZGQoKTtcclxuXHJcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBmb3JtIHN1Ym1pc3Npb24gdG8gdGFibGUgZGF0YVxyXG4gICAgICAgIE1vZGFsLlN1Ym1pdC5pbml0KHRoaXMuc3VibWl0TmV3Um93KTtcclxuICAgIH1cclxuXHJcbiAgICBlZGl0Q29sdW1ucyhyZXNwb25zZXMpIHsgXHJcbiAgICAgICAgLy8gZ2V0IG51bWJlcnMgZnJvbSBhY2NvdW50IHN0cmluZyBuYW1lc1xyXG4gICAgICAgIGlmKHJlc3BvbnNlc1snZnVuZC1uYW1lJ10pe1xyXG4gICAgICAgICAgICByZXNwb25zZXNbJ2Z1bmQnXSA9IEFjY291bnRTdHJpbmcuZ2V0TnVtYmVyKHJlc3BvbnNlc1snZnVuZC1uYW1lJ10pO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgaWYocmVzcG9uc2VzWydhcHByb3AtbmFtZSddKXtcclxuICAgICAgICAgICAgcmVzcG9uc2VzWydhcHByb3AnXSA9IEFjY291bnRTdHJpbmcuZ2V0TnVtYmVyKHJlc3BvbnNlc1snYXBwcm9wLW5hbWUnXSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBpZihyZXNwb25zZXNbJ2NjLW5hbWUnXSl7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlc1snY2MnXSA9IEFjY291bnRTdHJpbmcuZ2V0TnVtYmVyKHJlc3BvbnNlc1snY2MtbmFtZSddKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmKHJlc3BvbnNlc1snb2JqZWN0LW5hbWUnXSl7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlc1snb2JqZWN0J10gPSBBY2NvdW50U3RyaW5nLmdldE51bWJlcihyZXNwb25zZXNbJ29iamVjdC1uYW1lJ10pO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmVzcG9uc2VzWydhY2NvdW50LXN0cmluZyddID0gXHJcbiAgICAgICAgICAgIEFjY291bnRTdHJpbmcuYnVpbGQocmVzcG9uc2VzWydhcHByb3AtbmFtZSddLCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZXNbJ2NjLW5hbWUnXSwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VzWydvYmplY3QtbmFtZSddLCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZXNbJ2Z1bmQnXSk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlcztcclxuICAgIH1cclxuXHJcbiAgICBzdWJtaXROZXdSb3coZXZlbnQpIHtcclxuICAgICAgICAvLyBnZXQgYW5zd2VycyBmcm9tIGZvcm0sIGhpZGUgZm9ybSwgc2hvdyBhbnN3ZXJzIGluIHRhYmxlXHJcbiAgICAgICAgdmFyIHJlc3BvbnNlcyA9IEZvcm0uZmV0Y2hBbGxSZXNwb25zZXMoZXZlbnQpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIGVkaXQgaW5wdXRzIGZyb20gbW9kYWxcclxuICAgICAgICByZXNwb25zZXMgPSB0aGlzLmVkaXRDb2x1bW5zKHJlc3BvbnNlcyk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gbWFrZSBzdXJlIGl0J3Mgbm90IGFuIGVtcHR5IHJlc3BvbnNlXHJcbiAgICAgICAgaWYgKE9iamVjdC52YWx1ZXMocmVzcG9uc2VzKVswXSAhPSAnJyl7XHJcblxyXG4gICAgICAgICAgICAvLyBjaGFuZ2UgcGFnZSB2aWV3XHJcbiAgICAgICAgICAgIE1vZGFsLmhpZGUoKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIC8vIGFkZCBkYXRhIHRvIHRhYmxlXHJcbiAgICAgICAgICAgIFRhYmxlLlJvd3MuYWRkKHJlc3BvbnNlcywgdGhpcy5jb2x1bW5zKTtcclxuICAgICAgICAgICAgVGFibGUuc2F2ZSgpO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gcmVidWlsZCB0YWJsZVxyXG4gICAgICAgICAgICB0aGlzLmJ1aWxkKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxufSIsIlxyXG5pbXBvcnQgV2VsY29tZSBmcm9tICcuLi9jb21wb25lbnRzL3dlbGNvbWUvd2VsY29tZS5qcyc7XHJcbmltcG9ydCB7IFZpZXcgfSBmcm9tICcuL3ZpZXdfY2xhc3MuanMnO1xyXG5pbXBvcnQgeyB2aXNpdFBhZ2UgfSBmcm9tICcuL3ZpZXdfbG9naWMuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFdlbGNvbWVWaWV3IGV4dGVuZHMgVmlldyB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLnBhZ2Vfc3RhdGUgPSAnd2VsY29tZSc7XHJcbiAgICAgICAgdGhpcy5zdWJ0aXRsZSA9ICdXZWxjb21lJztcclxuICAgICAgICB0aGlzLnNpZGViYXIgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLm5hdkJ1dHRvbnMgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICB2aXNpdCgpIHtcclxuICAgICAgICBzdXBlci52aXNpdCgpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIHNob3cgd2VsY29tZSBzZWN0aW9uXHJcbiAgICAgICAgV2VsY29tZS5zaG93KCk7XHJcblxyXG4gICAgICAgIC8vIGluaXRpYWxpemUgbGlua3MgaW4gYnV0dG9uc1xyXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGVwLXVwbG9hZCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gdmlzaXRQYWdlKCd1cGxvYWQnKSk7XHJcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0ZXAtaW5pdGlhdGl2ZXMnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHZpc2l0UGFnZSgnbmV3LWluaXRzJykpO1xyXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGVwLXJldmVudWUnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHZpc2l0UGFnZSgnYmFzZWxpbmUtbGFuZGluZycpKTtcclxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RlcC1maW5pc2gnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHZpc2l0UGFnZSgnc3VtbWFyeScpKTtcclxuXHJcbiAgICB9XHJcblxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBXZWxjb21lVmlldztcclxuIiwiaW1wb3J0IHsgVmlldyB9IGZyb20gJy4vdmlld19jbGFzcy5qcydcclxuXHJcbmltcG9ydCBGaWxlVXBsb2FkIGZyb20gXCIuLi9jb21wb25lbnRzL2ZpbGVfdXBsb2FkL2ZpbGVfdXBsb2FkLmpzXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgVXBsb2FkVmlldyBleHRlbmRzIFZpZXcge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy5wYWdlX3N0YXRlID0gJ3VwbG9hZCc7XHJcbiAgICAgICAgdGhpcy5wcm9tcHQgPSBgVXBsb2FkIHRoZSBiYXNlbGluZSBkZXRhaWwgc2hlZXQgZ2l2ZW4gYnkgeW91ciBidWRnZXQgYW5hbHlzdC5gO1xyXG4gICAgICAgIHRoaXMuc3VidGl0bGUgPSAnRXhjZWwgVXBsb2FkJztcclxuICAgICAgICB0aGlzLnNpZGViYXIgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICB2aXNpdCgpIHtcclxuICAgICAgICBzdXBlci52aXNpdCgpO1xyXG4gICAgICAgIEZpbGVVcGxvYWQuc2hvdygpO1xyXG4gICAgICAgIEZpbGVVcGxvYWQuaW5pdCgpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBVcGxvYWRWaWV3OyIsImltcG9ydCBOYXZCdXR0b25zIGZyb20gXCIuLi9jb21wb25lbnRzL25hdl9idXR0b25zL25hdl9idXR0b25zLmpzXCI7XHJcbmltcG9ydCBUYWJsZSBmcm9tIFwiLi4vY29tcG9uZW50cy90YWJsZS90YWJsZS5qc1wiO1xyXG5pbXBvcnQgeyBWaWV3LCBWaWV3VGFibGUgfSBmcm9tICcuL3ZpZXdfY2xhc3MuanMnXHJcbmltcG9ydCBDdXJyZW50RnVuZCBmcm9tIFwiLi4vbW9kZWxzL2N1cnJlbnRfZnVuZC5qc1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEZ1bmRWaWV3IGV4dGVuZHMgVmlldyB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLnBhZ2Vfc3RhdGUgPSAnYmFzZWxpbmUtbGFuZGluZyc7XHJcbiAgICAgICAgdGhpcy5wcm9tcHQgPSBgV2Ugd2lsbCBub3cgYXNrIHlvdSBhIHNlcmllcyBvZiBxdWVzdGlvbnMgYWJvdXQgeW91ciBCQVNFTElORSBidWRnZXQgcmVxdWVzdC5cclxuICAgICAgICAgICAgQXQgdGhlIGVuZCwgd2Ugd2lsbCBhc2sgeW91IGFib3V0IGFueSBuZXcgaW5pdGlhdGl2ZXMgKGllLiBzdXBwbGVtZW50YWwgcmVxdWVzdHMpLlxyXG4gICAgICAgICAgICBTZWxlY3Qgb25lIG9mIHlvdXIgZnVuZHMgdGhlbiBjbGljayBjb250aW51ZS5gO1xyXG4gICAgICAgIHRoaXMuc3VidGl0bGUgPSAnQmFzZWxpbmUgQnVkZ2V0IFJlcXVlc3QnO1xyXG4gICAgICAgIHRoaXMudGFibGUgPSBuZXcgRnVuZFRhYmxlKCk7XHJcbiAgICAgICAgdGhpcy5zaWRlYmFyID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5kYXRhVGFibGUgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICB2aXNpdCgpIHtcclxuICAgICAgICAvLyByZW1vdmUgZnVuZCBzZWxlY3Rpb25cclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShcImZ1bmRcIiwgJycpO1xyXG4gICAgICAgIHN1cGVyLnZpc2l0KCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmNsYXNzIEZ1bmRUYWJsZSBleHRlbmRzIFZpZXdUYWJsZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuXHJcbiAgICAgICAgLy8gYWRkIGFkZGl0aW9uYWwgcmV2ZW51ZSBjb2x1bW5zIHRvIHRoZSB0YWJsZVxyXG4gICAgICAgIHRoaXMuY29sdW1ucyA9IFtcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0Z1bmQnLCBjbGFzc05hbWU6ICdmdW5kLW5hbWUnIH1cclxuICAgICAgICBdO1xyXG5cclxuICAgICAgICB0aGlzLm5vRGF0YU1lc3NhZ2UgPSAnTm8gZnVuZHMgZm91bmQuJ1xyXG4gICAgICAgIHRoaXMuYWRkRWRpdCA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGJ1aWxkKCl7XHJcbiAgICAgICAgLy8gbG9hZCBpbiBmdW5kIGRhdGFcclxuICAgICAgICBUYWJsZS5zaG93KCk7XHJcbiAgICAgICAgVGFibGUuRGF0YS5sb2FkRnVuZHMoKTtcclxuICAgICAgICBUYWJsZS5Db2x1bW5zLmFzc2lnbkNsYXNzZXModGhpcy5jb2x1bW5zKTtcclxuICAgICAgICBUYWJsZS5hZGp1c3RXaWR0aCgnMzAlJyk7XHJcblxyXG4gICAgICAgIC8vIGRpc2FibGUgbmV4dCBidXR0b24gdW50aWwgYSBmdW5kIGlzIHNlbGVjdGVkXHJcbiAgICAgICAgTmF2QnV0dG9ucy5OZXh0LmRpc2FibGUoKTtcclxuICAgICAgICBhbGxvd1Jvd1NlbGVjdGlvbigpO1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuZnVuY3Rpb24gYWxsb3dSb3dTZWxlY3Rpb24oKXtcclxuICAgIFxyXG4gICAgdmFyIHRhYmxlUm93cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJ0Ym9keSB0clwiKTtcclxuICAgIFxyXG4gICAgLy8gZW5hYmxlIGhpZ2hsaWdodCBvbiBob3ZlciBhbmQgb24gc2VsZWN0XHJcbiAgICB0YWJsZVJvd3MuZm9yRWFjaChmdW5jdGlvbihyb3cpIHtcclxuICAgICAgICByb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnaG92ZXItZWZmZWN0Jyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3V0JywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2xhc3NMaXN0LnJlbW92ZSgnaG92ZXItZWZmZWN0Jyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHNlbGVjdEZ1bmQodGFibGVSb3dzLCB0aGlzKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZWxlY3RGdW5kKHRhYmxlUm93cywgc2VsZWN0ZWRfcm93KXtcclxuXHJcbiAgICAvLyByZW1vdmUgc2VsZWN0ZWQgY2xhc3MgZnJvbSBhbnkgb3RoZXIgcm93c1xyXG4gICAgdGFibGVSb3dzLmZvckVhY2goZnVuY3Rpb24odGFibGVSb3cpIHtcclxuICAgICAgICB0YWJsZVJvdy5jbGFzc0xpc3QgPSAnJztcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIGFkZCBzZWxlY3RlZCBjbGFzcyB0byBjbGlja2VkIHJvd1xyXG4gICAgc2VsZWN0ZWRfcm93LmNsYXNzTGlzdC5hZGQoJ3NlbGVjdGVkJyk7XHJcblxyXG4gICAgLy8gZ2V0IGZ1bmQgYW5kIHNhdmUgc2VsZWN0ZWQgZnVuZFxyXG4gICAgdmFyIGZ1bmQgPSBzZWxlY3RlZF9yb3cucXVlcnlTZWxlY3RvcignLmZ1bmQtbmFtZScpLnRleHRDb250ZW50O1xyXG4gICAgdmFyIGZ1bmROdW1iZXIgPSBwYXJzZUludChmdW5kKTtcclxuICAgIEN1cnJlbnRGdW5kLnVwZGF0ZShmdW5kTnVtYmVyKTtcclxuXHJcbiAgICAvLyBlbmFibGUgbmV4dCBzdGVwXHJcbiAgICBOYXZCdXR0b25zLk5leHQuZW5hYmxlKCk7XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEZ1bmRWaWV3OyIsImltcG9ydCB7IFZpZXcsIFZpZXdUYWJsZSB9IGZyb20gJy4vdmlld19jbGFzcy5qcydcclxuXHJcbmltcG9ydCBUYWJsZSBmcm9tICcuLi9jb21wb25lbnRzL3RhYmxlL3RhYmxlLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBSZXZlbnVlVmlldyBleHRlbmRzIFZpZXcge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGZpc2NhbF95ZWFyKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLnBhZ2Vfc3RhdGUgPSAncmV2ZW51ZSc7XHJcbiAgICAgICAgdGhpcy5wcm9tcHQgPSBgUmV2aWV3IGFuZCBlZGl0IHJldmVudWUgbGluZSBpdGVtcy4gSWYgeW91IGNoYW5nZSB0aGUgZXN0aW1hdGUgb3IgXHJcbiAgICAgICAgICAgIG5vdGljZSBhbiBlcnJvciBpbiBhbiBhY2NvdW50IHN0cmluZywgcGxlYXNlIG5vdGUgaXQgaW4gdGhlIG5vdGVzIGNvbHVtbi4gQ2xpY2sgZWRpdCBcclxuICAgICAgICAgICAgdG8gY2hhbmdlIHZhbHVlcyBpbiBhIHJvdy5gO1xyXG4gICAgICAgIHRoaXMuc3VidGl0bGUgPSAnUmV2ZW51ZXMnO1xyXG4gICAgICAgIHRoaXMudGFibGUgPSBuZXcgUmV2ZW51ZVRhYmxlKGZpc2NhbF95ZWFyKTtcclxuICAgIH1cclxufVxyXG5cclxuY2xhc3MgUmV2ZW51ZVRhYmxlIGV4dGVuZHMgVmlld1RhYmxlIHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihmaXNjYWxfeWVhcikge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcblxyXG4gICAgICAgIC8vIGFkZCBhZGRpdGlvbmFsIHJldmVudWUgY29sdW1ucyB0byB0aGUgdGFibGVcclxuICAgICAgICB0aGlzLmNvbHVtbnMgPSB0aGlzLmNvbHVtbnMuY29uY2F0KFtcclxuICAgICAgICAgICAgeyB0aXRsZTogJ1JlY3VycmluZyBvciBPbmUtVGltZScsIGNsYXNzTmFtZTogJ3JlY3VycmluZyd9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnT2JqZWN0IENhdGVnb3J5JywgY2xhc3NOYW1lOiAnb2JqZWN0LWNhdGVnb3J5J30sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6IGBGWSR7ZmlzY2FsX3llYXJ9IERlcGFydG1lbnRhbCBFc3RpbWF0ZWAsIGNsYXNzTmFtZTogJ3JlcXVlc3QnLCBpc0Nvc3Q6IHRydWV9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnRGVwYXJ0bWVudGFsIEVzdGltYXRlIE5vdGVzJywgY2xhc3NOYW1lOiAnbm90ZXMnfSxcclxuICAgICAgICAgICAgLy8gaGlkZGVuXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdPYmplY3QgTmFtZScsIGNsYXNzTmFtZTogJ29iamVjdC1uYW1lJywgaGlkZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdPYmplY3QnLCBjbGFzc05hbWU6ICdvYmplY3QnLCBoaWRlOiB0cnVlfSxcclxuICAgICAgICBdKTtcclxuXHJcbiAgICAgICAgdGhpcy5ub0RhdGFNZXNzYWdlID0gJ05vIHJldmVudWVzIGZvciB0aGlzIGZ1bmQuJ1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGFjdGlvbiBvbiByb3cgZWRpdCBjbGljazogbWFrZSBjZWxscyBlZGl0YWJsZVxyXG4gICAgYWN0aW9uT25FZGl0KCkgeyBcclxuICAgICAgICAvLyBvbmx5IGFsbG93IGVkaXRzIGluIHRoZSBub3RlcyBib3hcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVRleHRib3goJ25vdGVzJywgZmFsc2UsICd0ZXh0YXJlYScpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBSZXZlbnVlVmlldzsiLCJpbXBvcnQgeyBWaWV3LCBWaWV3VGFibGUgfSBmcm9tICcuL3ZpZXdfY2xhc3MuanMnXHJcblxyXG5pbXBvcnQgVGFibGUgZnJvbSBcIi4uL2NvbXBvbmVudHMvdGFibGUvdGFibGUuanNcIjtcclxuaW1wb3J0IEZvcm0gZnJvbSBcIi4uL2NvbXBvbmVudHMvZm9ybS9mb3JtLmpzXCI7XHJcblxyXG5pbXBvcnQgeyBTZXJ2aWNlcywgRnVuZExvb2t1cFRhYmxlIH0gZnJvbSAnLi4vbW9kZWxzLyc7XHJcbmltcG9ydCB7IHVuZm9ybWF0Q3VycmVuY3kgfSBmcm9tIFwiLi4vdXRpbHMvY29tbW9uX3V0aWxzLmpzXCI7XHJcbmltcG9ydCB7IEVNUExPWUVFX1RZUEVTIH0gZnJvbSAnLi4vY29uc3RhbnRzL2J1ZGdldF9jb25zdGFudHMuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFBlcnNvbm5lbFZpZXcgZXh0ZW5kcyBWaWV3IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihmaXNjYWxfeWVhcikge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy5wYWdlX3N0YXRlID0gJ3BlcnNvbm5lbCc7XHJcbiAgICAgICAgdGhpcy5wcm9tcHQgPSBgXHJcbiAgICAgICAgICAgIFRoaXMgdGFibGUgZGlzcGxheXMgdGhlIG51bWJlciBvZiBGVEVzIGluIGVhY2ggam9iIGNvZGUgZm9yIGluIHlvdXIgZGVwYXJ0bWVudCdzIFxyXG4gICAgICAgICAgICBjdXJyZW50IChhbWVuZGVkKSBGWTI1IGJ1ZGdldC4gVG8gbWFrZSBlZGl0cyB0byB0aGUgbnVtYmVyIG9mIHBvc2l0aW9ucywgY2xpY2sgdGhlXHJcbiAgICAgICAgICAgIFwiRWRpdFwiIGJ1dHRvbiBvbiB0aGUgcm93IHlvdSB3b3VsZCBsaWtlIHRvIGVkaXQuIFRoZSBcIlRvdGFsIENvc3RcIiBjb2x1bW4gYW5kIHRoZSBcclxuICAgICAgICAgICAgc3VtbWFyeSBzaWRlYmFyIHdpbGwgYWxzbyB1cGRhdGUgdG8gcmVmbGVjdCBhbnkgZWRpdHMuYDtcclxuICAgICAgICB0aGlzLnN1YnRpdGxlID0gJ1BlcnNvbm5lbCc7XHJcbiAgICAgICAgdGhpcy50YWJsZSA9IG5ldyBQZXJzb25uZWxUYWJsZShmaXNjYWxfeWVhcik7XHJcbiAgICB9XHJcbn1cclxuXHJcblxyXG5jbGFzcyBQZXJzb25uZWxUYWJsZSBleHRlbmRzIFZpZXdUYWJsZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZmlzY2FsX3llYXIpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIHRoaXMuZmlzY2FsX3llYXIgPSBmaXNjYWxfeWVhcjtcclxuICAgICAgICAvLyBhZGQgYWRkaXRpb25hbCBwZXJzb25uZWwgY29sdW1ucyB0byB0aGUgdGFibGVcclxuICAgICAgICB0aGlzLmNvbHVtbnMgPSB0aGlzLmNvbHVtbnMuY29uY2F0KFtcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0pvYiBUaXRsZScsIGNsYXNzTmFtZTogJ2pvYi1uYW1lJyB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnRW1wbG95ZWUgVHlwZScsIGNsYXNzTmFtZTogJ2VtcGxveWVlLXR5cGUnfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ1NlcnZpY2UnLCBjbGFzc05hbWU6ICdzZXJ2aWNlJyB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiBgRlkke3RoaXMuZmlzY2FsX3llYXJ9IFJlcXVlc3RlZCBGVEVgLCBjbGFzc05hbWU6ICdiYXNlbGluZS1mdGVzJyB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiBgRlkke3RoaXMuZmlzY2FsX3llYXJ9IFByb2plY3RlZCBBdmVyYWdlIFNhbGFyeS9XYWdlYCwgY2xhc3NOYW1lOiAnYXZnLXNhbGFyeScsIGlzQ29zdDogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnVG90YWwgU2FsL1dhZyAmIEJlbiBSZXF1ZXN0JywgY2xhc3NOYW1lOiAndG90YWwtYmFzZWxpbmUnLCBpc0Nvc3Q6IHRydWUgfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0RlcGFydG1lbnRhbCBSZXF1ZXN0IE5vdGVzJywgY2xhc3NOYW1lOiAnbm90ZXMnfSxcclxuICAgICAgICAgICAgLy8gaGlkZGVuIGNvbHVtbnNcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0ZyaW5nZSBCZW5lZml0cyBSYXRlJywgY2xhc3NOYW1lOiAnZnJpbmdlJywgaGlkZTogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnR2VuZXJhbCBJbmNyZWFzZSBSYXRlJywgY2xhc3NOYW1lOiAnZ2VuZXJhbC1pbmNyZWFzZS1yYXRlJywgaGlkZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdTdGVwL01lcml0IEluY3JlYXNlIFJhdGUnLCBjbGFzc05hbWU6ICdtZXJpdC1pbmNyZWFzZS1yYXRlJywgaGlkZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6IGBBdmVyYWdlIFNhbGFyeS9XYWdlIGFzIG9mIDkvMS8yMCR7dGhpcy5maXNjYWxfeWVhci0yfWAsIGNsYXNzTmFtZTogJ2N1cnJlbnQtc2FsYXJ5JywgaXNDb3N0OiB0cnVlLCBoaWRlOiB0cnVlfVxyXG4gICAgICAgIF0pO1xyXG5cclxuICAgICAgICB0aGlzLm5vRGF0YU1lc3NhZ2UgPSAnTm8gcGVyc29ubmVsIGV4cGVuZGl0dXJlcyBmb3IgdGhpcyBmdW5kLidcclxuICAgICAgICB0aGlzLmFkZEJ1dHRvblRleHQgPSAnQWRkIG5ldyBqb2InIDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBhY3Rpb24gb24gcm93IGVkaXQgY2xpY2s6IG1ha2UgY2VsbHMgZWRpdGFibGVcclxuICAgIGFjdGlvbk9uRWRpdCgpIHsgXHJcbiAgICAgICAgVGFibGUuQ2VsbC5jcmVhdGVUZXh0Ym94KCdiYXNlbGluZS1mdGVzJyk7XHJcbiAgICAgICAgVGFibGUuQ2VsbC5jcmVhdGVTZXJ2aWNlRHJvcGRvd24oU2VydmljZXMubGlzdCgpKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVRleHRib3goJ25vdGVzJywgZmFsc2UsICd0ZXh0YXJlYScpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZVRhYmxlKCl7XHJcbiAgICAgICAgLy8gY2FsY3VsYXRlIGZvciBlYWNoIHJvd1xyXG4gICAgICAgIGxldCByb3dzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RyJyk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCByb3dzLmxlbmd0aDsgaSsrKXtcclxuICAgICAgICAgICAgLy8gZmV0Y2ggdmFsdWVzIGZvciBjYWxjdWxhdGlvbnNcclxuICAgICAgICAgICAgbGV0IGF2Z19zYWxhcnkgPSBUYWJsZS5DZWxsLmdldFZhbHVlKHJvd3NbaV0sICdhdmctc2FsYXJ5Jyk7XHJcbiAgICAgICAgICAgIGxldCBmcmluZ2UgPSBwYXJzZUZsb2F0KFRhYmxlLkNlbGwuZ2V0VGV4dChyb3dzW2ldLCAnZnJpbmdlJykpO1xyXG4gICAgICAgICAgICBsZXQgYmFzZWxpbmVfZnRlcyA9IFRhYmxlLkNlbGwuZ2V0VGV4dChyb3dzW2ldLCAnYmFzZWxpbmUtZnRlcycpO1xyXG5cclxuICAgICAgICAgICAgLy8gY2FsY3VhdGUgI0ZURXMgeCBhdmVyYWdlIHNhbGFyeSArIENPTEEgYWRqdXN0bWVudHMgKyBtZXJpdCBhZGp1c3RtZW50cyArIGZyaW5nZVxyXG4gICAgICAgICAgICBsZXQgdG90YWxfYmFzZWxpbmVfY29zdCA9IGF2Z19zYWxhcnkgKiBiYXNlbGluZV9mdGVzICogKDEgKyBmcmluZ2UpO1xyXG5cclxuICAgICAgICAgICAgLy8gdXBkYXRlIHRvdGFsIGNvbHVtblxyXG4gICAgICAgICAgICBUYWJsZS5DZWxsLnVwZGF0ZVZhbHVlKHJvd3NbaV0sICd0b3RhbC1iYXNlbGluZScsIHRvdGFsX2Jhc2VsaW5lX2Nvc3QpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU2F2ZSB0aGUgdGFibGUgYWZ0ZXIgYWxsIHVwZGF0ZXMgYXJlIGRvbmVcclxuICAgICAgICBUYWJsZS5zYXZlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkQ3VzdG9tUXVlc3Rpb25zKCl7XHJcbiAgICAgICAgLy8gZm9ybSBxdWVzdGlvbnMgdG8gYWRkIGEgbmV3IGpvYlxyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuc2hvcnRUZXh0KCdKb2IgVGl0bGU6JywgJ2pvYi1uYW1lJywgdHJ1ZSk7IFxyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oJ0VtcGxveWVlIFR5cGU6JywgJ2VtcGxveWVlLXR5cGUnLCBFTVBMT1lFRV9UWVBFUywgdHJ1ZSksXHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignQXBwcm9wcmlhdGlvbjonLCAnYXBwcm9wLW5hbWUnLCBGdW5kTG9va3VwVGFibGUuZ2V0QXBwcm9wcygpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdDb3N0IENlbnRlcjonLCAnY2MtbmFtZScsIEZ1bmRMb29rdXBUYWJsZS5nZXRDb3N0Q2VudGVycygpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdTZXJ2aWNlJywgJ3NlcnZpY2UnLCBTZXJ2aWNlcy5saXN0KCksIHRydWUpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuc2hvcnRUZXh0KCdOdW1iZXIgb2YgRlRFcyByZXF1ZXN0ZWQ6JywgJ2Jhc2VsaW5lLWZ0ZXMnLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLnNob3J0VGV4dChgUHJvamVjdGVkIGF2ZXJhZ2Ugc2FsYXJ5IElOIEZJU0NBTCBZRUFSICR7dGhpcy5maXNjYWxfeWVhcn06YCwgJ2F2Zy1zYWxhcnknLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLnNob3J0VGV4dChgRXhwZWN0ZWQgZnJpbmdlIHJhdGUgKGFzIGEgcGVyY2VudGFnZSlgLCAnZnJpbmdlJywgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWRpdENvbHVtbnMocmVzcG9uc2VzKXtcclxuICAgICAgICByZXNwb25zZXMgPSBzdXBlci5lZGl0Q29sdW1ucyhyZXNwb25zZXMpO1xyXG4gICAgICAgIC8vIGVkaXQgaW5wdXRzIGZyb20gbW9kYWxcclxuICAgICAgICByZXNwb25zZXNbJ2F2Zy1zYWxhcnknXSA9IHVuZm9ybWF0Q3VycmVuY3kocmVzcG9uc2VzWydhdmctc2FsYXJ5J10pO1xyXG4gICAgICAgIHJlc3BvbnNlc1snZnJpbmdlJ10gPSBwYXJzZUZsb2F0KHJlc3BvbnNlc1snZnJpbmdlJ10pIC8gMTAwO1xyXG4gICAgICAgIHJldHVybiByZXNwb25zZXM7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IFBlcnNvbm5lbFZpZXc7IiwiXHJcblxyXG5pbXBvcnQgeyBWaWV3LCBWaWV3VGFibGUgfSBmcm9tICcuL3ZpZXdfY2xhc3MuanMnXHJcbmltcG9ydCBUYWJsZSBmcm9tICcuLi9jb21wb25lbnRzL3RhYmxlL3RhYmxlLmpzJztcclxuaW1wb3J0IEZvcm0gZnJvbSAnLi4vY29tcG9uZW50cy9mb3JtL2Zvcm0uanMnO1xyXG5pbXBvcnQgeyBGdW5kTG9va3VwVGFibGUsIFNlcnZpY2VzIH0gZnJvbSAnLi4vbW9kZWxzLyc7XHJcbmltcG9ydCB7IHVuZm9ybWF0Q3VycmVuY3kgfSBmcm9tICcuLi91dGlscy9jb21tb25fdXRpbHMuanMnO1xyXG5pbXBvcnQgeyBPVF9PQkpFQ1RTIH0gZnJvbSAnLi4vY29uc3RhbnRzLyc7XHJcblxyXG5leHBvcnQgY2xhc3MgT3ZlcnRpbWVWaWV3IGV4dGVuZHMgVmlldyB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZmlzY2FsX3llYXIpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIHRoaXMucGFnZV9zdGF0ZSA9ICdvdmVydGltZSc7XHJcbiAgICAgICAgdGhpcy5wcm9tcHQgPSBgXHJcbiAgICAgICAgICAgIFBsZWFzZSBzZWUgeW91ciBiYXNlbGluZSBvdmVydGltZSAvIGhvbGlkYXkgcGF5IC8gc2hpZnQgcHJlbWl1bXMgaW4gdGhlIHRhYmxlIGJlbG93LlxyXG4gICAgICAgICAgICBNYWtlIGFueSBlZGl0cyBhbmQgY29udGludWUuYDtcclxuICAgICAgICB0aGlzLnN1YnRpdGxlID0gJ092ZXJ0aW1lIEVzdGltYXRlcyc7XHJcbiAgICAgICAgdGhpcy50YWJsZSA9IG5ldyBPdmVydGltZVRhYmxlKGZpc2NhbF95ZWFyKTtcclxuICAgIH1cclxufVxyXG5cclxuY2xhc3MgT3ZlcnRpbWVUYWJsZSBleHRlbmRzIFZpZXdUYWJsZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZmlzY2FsX3llYXIpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG5cclxuICAgICAgICAvLyBhZGQgYWRkaXRpb25hbCBPVCBjb2x1bW5zIHRvIHRoZSB0YWJsZVxyXG4gICAgICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuY29sdW1ucy5jb25jYXQoW1xyXG4gICAgICAgICAgICB7IHRpdGxlOiAnU2VydmljZScsIGNsYXNzTmFtZTogJ3NlcnZpY2UnIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdSZWN1cnJpbmcgb3IgT25lLVRpbWUnLCBjbGFzc05hbWU6ICdyZWN1cnJpbmcnfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ0RlcGFydG1lbnRhbCBSZXF1ZXN0IE9UL1NQL0hvbCcsIGNsYXNzTmFtZTogJ09ULXBheScsIGlzQ29zdDogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiBgRlkke2Zpc2NhbF95ZWFyfSBUb3RhbCBPVC9TUC9Ib2wgKyBGSUNBIFJlcXVlc3RgLCBjbGFzc05hbWUgOiAndG90YWwnLCBpc0Nvc3Q6IHRydWV9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnT2JqZWN0IE5hbWUnLCBjbGFzc05hbWU6ICdvYmplY3QtbmFtZSd9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnRGVwYXJ0bWVudGFsIFJlcXVlc3QgTm90ZXMnLCBjbGFzc05hbWU6ICdub3Rlcyd9LFxyXG4gICAgICAgICAgICAvLyBoaWRkZW4gY29sdW1uc1xyXG4gICAgICAgICAgICB7IHRpdGxlOiAnRklDQSBSYXRlJywgY2xhc3NOYW1lOiAnZmljYScsIGhpZGU6IHRydWV9LFxyXG4gICAgICAgIF0pO1xyXG5cclxuICAgICAgICB0aGlzLm5vRGF0YU1lc3NhZ2UgPSAnTm8gb3ZlcnRpbWUgZXhwZW5kaXR1cmVzIGZvciB0aGlzIGZ1bmQuJ1xyXG4gICAgICAgIHRoaXMuYWRkQnV0dG9uVGV4dCA9ICdBZGQgbmV3IGNvc3QgY2VudGVyJyA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYWN0aW9uIG9uIHJvdyBlZGl0IGNsaWNrOiBtYWtlIGNlbGxzIGVkaXRhYmxlXHJcbiAgICBhY3Rpb25PbkVkaXQoKSB7IFxyXG4gICAgICAgIFRhYmxlLkNlbGwuY3JlYXRlVGV4dGJveCgnT1QtcGF5JywgdHJ1ZSk7XHJcbiAgICAgICAgVGFibGUuQ2VsbC5jcmVhdGVTZXJ2aWNlRHJvcGRvd24oU2VydmljZXMubGlzdCgpKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZURyb3Bkb3duKCdyZWN1cnJpbmcnLCBbJ09uZS1UaW1lJywgJ1JlY3VycmluZyddKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZURyb3Bkb3duKCdvYmplY3QtbmFtZScsIE9UX09CSkVDVFMpO1xyXG4gICAgICAgIFRhYmxlLkNlbGwuY3JlYXRlVGV4dGJveCgnbm90ZXMnKTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVUYWJsZSgpe1xyXG5cclxuICAgICAgICAvLyBjYWxjdWxhdGUgZm9yIGVhY2ggcm93XHJcbiAgICAgICAgbGV0IHJvd3MgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgndHInKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJvd3MubGVuZ3RoOyBpKyspe1xyXG4gICAgICAgICAgICAvLyBmZXRjaCB2YWx1ZXMgZm9yIGNhbGN1bGF0aW9uc1xyXG4gICAgICAgICAgICBsZXQgT1Rfc2FsYXJ5ID0gVGFibGUuQ2VsbC5nZXRWYWx1ZShyb3dzW2ldLCAnT1QtcGF5Jyk7XHJcbiAgICAgICAgICAgIGxldCBmaWNhX3JhdGUgPSBUYWJsZS5DZWxsLmdldFRleHQocm93c1tpXSwgJ2ZpY2EnKTtcclxuXHJcbiAgICAgICAgICAgIC8vIGFkZCBzYWxhcnkgYW5kIHdhZ2VzIGFuZCBmcmluZ2UgYmVuZWZpdHMgKEZJQ0EpXHJcbiAgICAgICAgICAgIGxldCByb3dfdG90YWwgPSBPVF9zYWxhcnkgKiAoMSArIHBhcnNlRmxvYXQoZmljYV9yYXRlKSk7XHJcblxyXG4gICAgICAgICAgICAvLyB1cGRhdGUgdG90YWxcclxuICAgICAgICAgICAgVGFibGUuQ2VsbC51cGRhdGVWYWx1ZShyb3dzW2ldLCAndG90YWwnLCByb3dfdG90YWwpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU2F2ZSB0aGUgdGFibGUgYWZ0ZXIgYWxsIHVwZGF0ZXMgYXJlIGRvbmVcclxuICAgICAgICBUYWJsZS5zYXZlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkQ3VzdG9tUXVlc3Rpb25zKCl7XHJcbiAgICAgICAgLy8gZm9ybSBxdWVzdGlvbnMgdG8gYWRkIGEgbmV3IGpvYlxyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oJ0FwcHJvcHJpYXRpb246JywgJ2FwcHJvcC1uYW1lJywgRnVuZExvb2t1cFRhYmxlLmdldEFwcHJvcHMoKSwgdHJ1ZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignQ29zdCBDZW50ZXI6JywgJ2NjLW5hbWUnLCBGdW5kTG9va3VwVGFibGUuZ2V0Q29zdENlbnRlcnMoKSwgdHJ1ZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignT2JqZWN0IChzYWxhcnkgb3Igd2FnZSk6JywgJ29iamVjdC1uYW1lJywgT1RfT0JKRUNUUywgdHJ1ZSk7IFxyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oJ1NlcnZpY2UnLCAnc2VydmljZScsIFNlcnZpY2VzLmxpc3QoKSwgdHJ1ZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignUmVjdXJyaW5nIG9yIE9uZS1UaW1lJywgJ3JlY3VycmluZycsIFsnUmVjdXJyaW5nJywgJ09uZS1UaW1lJ10sIHRydWUpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuc2hvcnRUZXh0KCdPdmVydGltZSBhbW91bnQgcmVxdWVzdGVkOicsICdPVC1wYXknLCB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICBlZGl0Q29sdW1ucyhyZXNwb25zZXMpe1xyXG4gICAgICAgIHJlc3BvbnNlcyA9IHN1cGVyLmVkaXRDb2x1bW5zKHJlc3BvbnNlcyk7XHJcbiAgICAgICAgLy8gZWRpdCBpbnB1dHMgZnJvbSBtb2RhbFxyXG4gICAgICAgIHJlc3BvbnNlc1snT1QtcGF5J10gPSB1bmZvcm1hdEN1cnJlbmN5KHJlc3BvbnNlc1snT1QtcGF5J10pO1xyXG4gICAgICAgIHJlc3BvbnNlc1snZmljYSddID0gMC4wNzY1O1xyXG4gICAgICAgIHJldHVybiByZXNwb25zZXM7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IE92ZXJ0aW1lVmlldzsiLCJpbXBvcnQgeyBWaWV3LCBWaWV3VGFibGUgfSBmcm9tICcuL3ZpZXdfY2xhc3MuanMnXHJcbmltcG9ydCBGb3JtIGZyb20gJy4uL2NvbXBvbmVudHMvZm9ybS9mb3JtLmpzJztcclxuaW1wb3J0IFRhYmxlIGZyb20gJy4uL2NvbXBvbmVudHMvdGFibGUvdGFibGUuanMnO1xyXG5pbXBvcnQgeyBGdW5kTG9va3VwVGFibGUsIFNlcnZpY2VzIH0gZnJvbSAnLi4vbW9kZWxzLyc7XHJcbmltcG9ydCB7IHVuZm9ybWF0Q3VycmVuY3kgfSBmcm9tICcuLi91dGlscy9jb21tb25fdXRpbHMuanMnO1xyXG5pbXBvcnQgeyBPQkpfQ0FURUdPUklFUyB9IGZyb20gJy4uL2NvbnN0YW50cy8nO1xyXG5cclxuZXhwb3J0IGNsYXNzIE5vblBlcnNvbm5lbFZpZXcgZXh0ZW5kcyBWaWV3IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihmaXNjYWxfeWVhcikge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy5wYWdlX3N0YXRlID0gJ25vbnBlcnNvbm5lbCc7XHJcbiAgICAgICAgdGhpcy5wcm9tcHQgPSBgUmV2aWV3IGFuZCBlZGl0IG5vbi1wZXJzb25uZWwgbGluZSBpdGVtcy4gVGhlIENQQSBudW1iZXJzIGFyZSB0aGUgXHJcbiAgICAgICAgICAgIENvbnRyYWN0IGFuZCBQcm9jdXJlbWVudCBBY2NvdW50IG51bWJlcnMuIENsaWNrIG9uIHRoZSAnZGV0YWlsJyBsaW5rIGZvciBhIENQQSBcclxuICAgICAgICAgICAgdG8gc2VlIHRoZSBjb250cmFjdCBkZXRhaWxzLiBTb21lIGxpbmUgaXRlbXMgd29uJ3QgaGF2ZSBhIENQQSBudW1iZXIuYDtcclxuICAgICAgICB0aGlzLnN1YnRpdGxlID0gJ05vbi1QZXJzb25uZWwnO1xyXG4gICAgICAgIHRoaXMudGFibGUgPSBuZXcgTm9uUGVyc29ubmVsVGFibGUoZmlzY2FsX3llYXIpO1xyXG4gICAgfVxyXG59XHJcblxyXG5jbGFzcyBOb25QZXJzb25uZWxUYWJsZSBleHRlbmRzIFZpZXdUYWJsZSB7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZmlzY2FsX3llYXIpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG5cclxuICAgICAgICAvLyBhZGQgYWRkaXRpb25hbCBwZXJzb25uZWwgY29sdW1ucyB0byB0aGUgdGFibGVcclxuICAgICAgICB0aGlzLmNvbHVtbnMgPSB0aGlzLmNvbHVtbnMuY29uY2F0KFtcclxuICAgICAgICAgICAgeyB0aXRsZTogYEZZJHtmaXNjYWxfeWVhcn0gRGVwYXJ0bWVudGFsIFJlcXVlc3QgVG90YWxgLCBjbGFzc05hbWU6ICdyZXF1ZXN0JywgaXNDb3N0OiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdTZXJ2aWNlJywgY2xhc3NOYW1lIDogJ3NlcnZpY2UnIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdSZWN1cnJpbmcgb3IgT25lLVRpbWUnLCBjbGFzc05hbWU6ICdyZWN1cnJpbmcnfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ1ZlbmRvciBOYW1lJywgY2xhc3NOYW1lOiAndmVuZG9yJ30sXHJcbiAgICAgICAgICAgIHsgdGl0bGUgOiAnQ1BBICMnLCBjbGFzc05hbWUgOiAnY3BhJ30sXHJcbiAgICAgICAgICAgIC8vIGhpZGRlbiBjb2x1bW5zXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdFbmQgRGF0ZScsIGNsYXNzTmFtZTogJ2NvbnRyYWN0LWVuZCcsIGhpZGU6IHRydWV9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnQlBBL0NQQSBBbW91bnQgUmVtYWluaW5nJywgY2xhc3NOYW1lOiAncmVtYWluaW5nJywgaXNDb3N0OiB0cnVlICwgaGlkZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdPYmplY3QgTmFtZScsIGNsYXNzTmFtZTogJ29iamVjdC1uYW1lJywgaGlkZTogdHJ1ZX0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdPYmplY3QnLCBjbGFzc05hbWU6ICdvYmplY3QnLCBoaWRlOiB0cnVlfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ09iamVjdCBDYXRlZ29yeScsIGNsYXNzTmFtZTogJ29iamVjdC1jYXRlZ29yeScsIGhpZGU6IHRydWV9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnQlBBL0NQQSBEZXNjcmlwdGlvbicsIGNsYXNzTmFtZTogJ2NwYS1kZXNjcmlwdGlvbicsIGhpZGU6IHRydWV9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnRGVwYXJ0bWVudGFsIFJlcXVlc3QgTm90ZXMnLCBjbGFzc05hbWU6ICdub3Rlcyd9LCBcclxuICAgICAgICBdKTtcclxuXHJcbiAgICAgICAgdGhpcy5ub0RhdGFNZXNzYWdlID0gJ05vIG5vbi1wZXJzb25uZWwgZXhwZW5kaXR1cmVzIGZvciB0aGlzIGZ1bmQuJ1xyXG4gICAgICAgIHRoaXMuYWRkQnV0dG9uVGV4dCA9ICdBZGQgbmV3IG5vbi1wZXJzb25uZWwgaXRlbScgO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGFjdGlvbiBvbiByb3cgZWRpdCBjbGljazogbWFrZSBjZWxscyBlZGl0YWJsZVxyXG4gICAgYWN0aW9uT25FZGl0KCkgeyBcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVRleHRib3goJ3JlcXVlc3QnLCB0cnVlKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVNlcnZpY2VEcm9wZG93bigpO1xyXG4gICAgICAgIFRhYmxlLkNlbGwuY3JlYXRlRHJvcGRvd24oJ3JlY3VycmluZycsIFsnT25lLVRpbWUnLCAnUmVjdXJyaW5nJ10pO1xyXG4gICAgICAgIFRhYmxlLkNlbGwuY3JlYXRlVGV4dGJveCgnbm90ZXMnKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRDdXN0b21RdWVzdGlvbnMoKXtcclxuICAgICAgICAvLyBmb3JtIHF1ZXN0aW9ucyB0byBhZGQgYSBuZXcgcm93XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignQXBwcm9wcmlhdGlvbjonLCAnYXBwcm9wLW5hbWUnLCBGdW5kTG9va3VwVGFibGUuZ2V0QXBwcm9wcygpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdDb3N0IENlbnRlcjonLCAnY2MtbmFtZScsIEZ1bmRMb29rdXBUYWJsZS5nZXRDb3N0Q2VudGVycygpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdPYmplY3QgQ2F0ZWdvcnk6JywgJ29iamVjdC1jYXRlZ29yeScsIE9CSl9DQVRFR09SSUVTLmxpc3QsIHRydWUpO1xyXG4gICAgICAgIC8vIFRPRE86IG1heWJlIGdpdmUgZHJvcGRvd24gYmFzZWQgb24gc2VsZWN0ZWQgb2JqIGNhdGVnb3J5XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5zaG9ydFRleHQoJ09iamVjdCBOdW1iZXIgKGlmIGtub3duKTonLCAnb2JqZWN0JywgZmFsc2UpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oJ1NlcnZpY2UnLCAnc2VydmljZScsIFNlcnZpY2VzLmxpc3QoKSwgdHJ1ZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5sb25nVGV4dCgnRGVzY3JpYmUgeW91ciBuZXcgcmVxdWVzdDonLCAnY3BhLWRlc2NyaXB0aW9uJywgdHJ1ZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5kcm9wZG93bignUmVjdXJyaW5nIG9yIE9uZS1UaW1lJywgJ3JlY3VycmluZycsIFsnUmVjdXJyaW5nJywgJ09uZS1UaW1lJ10sIHRydWUpOyBcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLnNob3J0VGV4dCgnQW1vdW50IHJlcXVlc3RlZDonLCAncmVxdWVzdCcsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGVkaXRDb2x1bW5zKHJlc3BvbnNlcyl7XHJcbiAgICAgICAgcmVzcG9uc2VzID0gc3VwZXIuZWRpdENvbHVtbnMocmVzcG9uc2VzKTtcclxuICAgICAgICByZXNwb25zZXNbJ2F2Zy1zYWxhcnknXSA9IHVuZm9ybWF0Q3VycmVuY3kocmVzcG9uc2VzWydhdmctc2FsYXJ5J10pO1xyXG4gICAgICAgIHJlc3BvbnNlc1snZnJpbmdlJ10gPSBwYXJzZUZsb2F0KHJlc3BvbnNlc1snZnJpbmdlJ10pIC8gMTAwO1xyXG4gICAgICAgIHJldHVybiByZXNwb25zZXM7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IE5vblBlcnNvbm5lbFZpZXc7IiwiXHJcbmltcG9ydCB7IFZpZXcsIFZpZXdUYWJsZSB9IGZyb20gJy4vdmlld19jbGFzcy5qcydcclxuaW1wb3J0IFRhYmxlIGZyb20gXCIuLi9jb21wb25lbnRzL3RhYmxlL3RhYmxlLmpzXCI7XHJcbmltcG9ydCBGb3JtIGZyb20gXCIuLi9jb21wb25lbnRzL2Zvcm0vZm9ybS5qc1wiO1xyXG5pbXBvcnQgRnVuZExvb2t1cFRhYmxlIGZyb20gJy4uL21vZGVscy9mdW5kX2xvb2t1cF90YWJsZS5qcyc7XHJcbmltcG9ydCB7IEZJU0NBTF9ZRUFSIH0gZnJvbSAnLi4vY29uc3RhbnRzLyc7XHJcblxyXG5cclxuY29uc3QgZHJvcGRvd25PcHRpb25zID0gWydOL0EnLCAnT25lLVRpbWUnLCAnUmVjdXJyaW5nJ11cclxuXHJcbi8vIHNldCB1cCBwYWdlIGFuZCBpbml0aWFsaXplIGFsbCBidXR0b25zXHJcbmV4cG9ydCBjbGFzcyBJbml0aWF0aXZlc1ZpZXcgZXh0ZW5kcyBWaWV3IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIHRoaXMucGFnZV9zdGF0ZSA9ICduZXctaW5pdHMnO1xyXG4gICAgICAgIHRoaXMucHJvbXB0ID0gYFxyXG4gICAgICAgICAgICBUaGlzIGlzIHRoZSBwbGFjZSB0byBwcm9wb3NlIG5ldyBpbml0aWF0aXZlcyBmb3IgRlkke0ZJU0NBTF9ZRUFSfS5cclxuICAgICAgICAgICAgTmV3IGluaXRpYXRpdmUgc3VibWlzc2lvbnMgd2lsbCBjb3VudCBhcyBzdXBwbGVtZW50YWwgbGluZSBpdGVtcyBhbmQgd2lsbCBiZSB0aGUgc3RhcnRpbmcgXHJcbiAgICAgICAgICAgIHBvaW50IGZvciBhIGNvbnZlcnNhdGlvbiB3aXRoIGJvdGggT0IgYW5kIE9ERlMsIHdobyB3aWxsIGhlbHAgd2l0aCB0aGUgZGV0YWlscy5gO1xyXG4gICAgICAgIHRoaXMuc3VidGl0bGUgPSAnTmV3IEluaXRpYXRpdmVzJztcclxuICAgICAgICB0aGlzLnRhYmxlID0gbmV3IEluaXRpYXRpdmVzVGFibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICB2aXNpdCgpIHtcclxuICAgICAgICAvLyByZW1vdmUgZnVuZCBzZWxlY3Rpb25cclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShcImZ1bmRcIiwgJycpO1xyXG4gICAgICAgIHN1cGVyLnZpc2l0KCk7XHJcbiAgICB9XHJcblxyXG59XHJcblxyXG5jbGFzcyBJbml0aWF0aXZlc1RhYmxlIGV4dGVuZHMgVmlld1RhYmxlIHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG5cclxuICAgICAgICAvLyBhZGQgYWRkaXRpb25hbCBjb2x1bW5zIHRvIHRoZSB0YWJsZVxyXG4gICAgICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuY29sdW1ucy5jb25jYXQoW1xyXG4gICAgICAgICAgICB7IHRpdGxlOiAnSW5pdGlhdGl2ZSBOYW1lJywgY2xhc3NOYW1lOiAnaW5pdC1uYW1lJyB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnQmFsbHBhcmsgVG90YWwgRXhwZW5zZXMnLCBjbGFzc05hbWU6ICd0b3RhbCcsIGlzQ29zdDogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnUGVyc29ubmVsIENvc3QnLCBjbGFzc05hbWU6ICdwZXJzb25uZWwnLCBpc0Nvc3Q6IHRydWUgfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ05vbi1wZXJzb25uZWwgQ29zdCcsIGNsYXNzTmFtZTogJ25vbnBlcnNvbm5lbCcsIGlzQ29zdDogdHJ1ZSB9LFxyXG4gICAgICAgICAgICB7IHRpdGxlOiAnUmV2ZW51ZScsIGNsYXNzTmFtZTogJ3JldmVudWUnLCBpc0Nvc3Q6IHRydWUgfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ1JldmVudWUgVHlwZScsIGNsYXNzTmFtZTogJ3Jldi10eXBlJyB9LFxyXG5cclxuICAgICAgICAgICAgLy8gaGlkZSB0aGUgZXhwbGFuYXRpb24gY29sdW1uc1xyXG4gICAgICAgICAgICB7IHRpdGxlOiAnUTEnLCBjbGFzc05hbWU6ICdxMScsIGhpZGU6IHRydWUgfSxcclxuICAgICAgICAgICAgeyB0aXRsZTogJ1EyJywgY2xhc3NOYW1lOiAncTInLCBoaWRlOiB0cnVlIH0sXHJcbiAgICAgICAgICAgIHsgdGl0bGU6ICdRMycsIGNsYXNzTmFtZTogJ3EzJywgaGlkZTogdHJ1ZSB9XHJcbiAgICAgICAgXSk7XHJcblxyXG4gICAgICAgIHRoaXMuYWRkQnV0dG9uVGV4dCA9ICdBZGQgbmV3IGluaXRpYXRpdmUnIDtcclxuICAgIH1cclxuXHJcbiAgICBhZGRDdXN0b21RdWVzdGlvbnMoKXtcclxuXHJcbiAgICAgICAgLy8gZ2VuZXJhbCBxdWVzdGlvbnNcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLnNob3J0VGV4dCgnSW5pdGlhdGl2ZSBOYW1lOicsICdpbml0LW5hbWUnLCB0cnVlKTsgXHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5sb25nVGV4dCgnV2hhdCBpcyB0aGUgYnVzaW5lc3MgY2FzZSBmb3IgdGhlIEluaXRpYXRpdmU/JywgJ3ExJywgdHJ1ZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5sb25nVGV4dChgV2h5IGlzIHRoZSBpbml0aWF0aXZlIG5lZWRlZD8gV2hhdCBpcyB0aGUgdmFsdWUtYWRkIHRvIHJlc2lkZW50cz8gXHJcbiAgICAgICAgICAgIFdoYXQgaXMgdGhlIERlcGFydG1lbnTigJlzIHBsYW4gZm9yIGltcGxlbWVudGluZyB0aGUgSW5pdGlhdGl2ZT9gLCAncTInLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmxvbmdUZXh0KGBXaHkgY2Fu4oCZdCB0aGUgSW5pdGlhdGl2ZSBiZSBmdW5kZWQgd2l0aCB0aGUgRGVwYXJ0bWVudOKAmXMgYmFzZWxpbmUgYnVkZ2V0P2AsICdxMycsIHRydWUpO1xyXG5cclxuICAgICAgICAvLyBUT0RPOiBFZGl0IHRvIGRyb3AgZG93blxyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oJ0Z1bmQ6JywgJ2Z1bmQtbmFtZScsIEZ1bmRMb29rdXBUYWJsZS5saXN0RnVuZE5hbWVzKCksIHRydWUpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQuZHJvcGRvd24oJ0FwcHJvcHJpYXRpb24gKGlmIGtub3duKTonLCAnYXBwcm9wLW5hbWUnLCBGdW5kTG9va3VwVGFibGUuZ2V0QXBwcm9wcygpLCB0cnVlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKCdDb3N0IENlbnRlciAoaWYga25vd24pOicsICdjYy1uYW1lJywgRnVuZExvb2t1cFRhYmxlLmdldENvc3RDZW50ZXJzKCksIHRydWUpO1xyXG5cclxuICAgICAgICAvLyBOdW1iZXJzXHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5udW1lcmljSW5wdXQoJ1doYXQgaXMgeW91ciBiYWxscGFyayBlc3RpbWF0ZSBvZiBUT1RBTCBBRERJVE9OQUwgZXhwZW5zZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgaW5pdGlhdGl2ZT8nLCBcclxuICAgICAgICAgICAgJ3RvdGFsJywgZmFsc2UpO1xyXG4gICAgICAgIEZvcm0uTmV3RmllbGQubnVtZXJpY0lucHV0KCdFc3RpbWF0ZSBvZiBBRERJVE9OQUwgcGVyc29ubmVsIGNvc3Q/JywgJ3BlcnNvbm5lbCcsIGZhbHNlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLm51bWVyaWNJbnB1dCgnRXN0aW1hdGUgb2YgQURESVRPTkFMIG5vbnBlcnNvbm5lbCBjb3N0PycsICdub25wZXJzb25uZWwnLCBmYWxzZSk7XHJcbiAgICAgICAgRm9ybS5OZXdGaWVsZC5udW1lcmljSW5wdXQoJ0VzdGltYXRlIG9mIEFERElUT05BTCByZXZlbnVlIChpZiBhcHBsaWNhYmxlKT8nLCAncmV2ZW51ZScsIGZhbHNlKTtcclxuICAgICAgICBGb3JtLk5ld0ZpZWxkLmRyb3Bkb3duKGBJZiB0aGVyZSB3aWxsIGJlIHJldmVudWUsIGlzIGl0IG9uZS10aW1lIG9yIHJlY3VycmluZz9gLCBcclxuICAgICAgICAgICAgJ3Jldi10eXBlJywgZHJvcGRvd25PcHRpb25zKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBhY3Rpb24gb24gcm93IGVkaXQgY2xpY2s6IG1ha2UgY2VsbHMgZWRpdGFibGVcclxuICAgIGFjdGlvbk9uRWRpdCgpIHsgXHJcbiAgICAgICAgVGFibGUuQ2VsbC5jcmVhdGVUZXh0Ym94KCd0b3RhbCcsIHRydWUpO1xyXG4gICAgICAgIFRhYmxlLkNlbGwuY3JlYXRlVGV4dGJveCgncmV2ZW51ZScsIHRydWUpO1xyXG4gICAgICAgIFRhYmxlLkNlbGwuY3JlYXRlVGV4dGJveCgncGVyc29ubmVsJywgdHJ1ZSk7XHJcbiAgICAgICAgVGFibGUuQ2VsbC5jcmVhdGVUZXh0Ym94KCdub25wZXJzb25uZWwnLCB0cnVlKTtcclxuICAgICAgICBUYWJsZS5DZWxsLmNyZWF0ZVRleHRib3goJ2luaXQtbmFtZScpO1xyXG4gICAgICAgIFRhYmxlLkNlbGwuY3JlYXRlRHJvcGRvd24oJ3Jldi10eXBlJywgZHJvcGRvd25PcHRpb25zKTtcclxuICAgIH1cclxuXHJcbn1cclxuXHJcbmV4cG9ydCBkZWZhdWx0IEluaXRpYXRpdmVzVmlldzsiLCJpbXBvcnQgQ3VycmVudEZ1bmQgZnJvbSAnLi4vbW9kZWxzL2N1cnJlbnRfZnVuZC5qcyc7XHJcbmltcG9ydCBCYXNlbGluZSBmcm9tICcuLi9tb2RlbHMvYmFzZWxpbmUuanMnO1xyXG5pbXBvcnQgeyBBY2NvcmRpb24gfSBmcm9tIFwiLi4vY29tcG9uZW50cy9hY2NvcmRpb24vYWNjb3JkaW9uLmpzXCI7XHJcbmltcG9ydCB7IGZvcm1hdEN1cnJlbmN5IH0gZnJvbSAnLi4vdXRpbHMvY29tbW9uX3V0aWxzLmpzJztcclxuaW1wb3J0IHsgVmlldyB9IGZyb20gXCIuL3ZpZXdfY2xhc3MuanNcIjtcclxuaW1wb3J0IFByb21wdCBmcm9tIFwiLi4vY29tcG9uZW50cy9wcm9tcHQvcHJvbXB0LmpzXCI7XHJcbmltcG9ydCB7IGRvd25sb2FkWExTWCB9IGZyb20gXCIuLi91dGlscy9YTFNYX2hhbmRsZXJzLmpzXCI7XHJcbmltcG9ydCBXZWxjb21lVmlldyBmcm9tICcuLzAwX3dlbGNvbWUuanMnO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNvbXBhcmVUb1RhcmdldCgpe1xyXG4gICAgY29uc3QgYmFzZWxpbmUgPSBuZXcgQmFzZWxpbmU7XHJcbiAgICBpZiAoYmFzZWxpbmUudG90YWwoKSA8PSBCYXNlbGluZS50YXJnZXQoKSl7XHJcbiAgICAgICAgUHJvbXB0LlRleHQudXBkYXRlKGBDb25ncmF0cyEgWW91ciBidWRnZXQgaXMgYmVsb3cgeW91ciB0YXJnZXQhIFxyXG4gICAgICAgICAgICBFZGl0IGFueSBsaW5lIGl0ZW1zIGJlbG93IG9yIGRvd25sb2FkIHlvdXIgY29tcGxldGVkIEV4Y2VsLmApO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBQcm9tcHQuVGV4dC51cGRhdGUoYFlvdXIgYnVkZ2V0IGlzIGFib3ZlIHlvdXIgdGFyZ2V0IG9mICR7Zm9ybWF0Q3VycmVuY3koQmFzZWxpbmUudGFyZ2V0KCkpfS4gXHJcbiAgICAgICAgICAgIFBsZWFzZSBleHBhbmQgdGhlIHN1bW1hcnkgdGFibGUgYmVsb3cgYW5kIGVkaXQgbGluZSBpdGVtcyB1bnRpbCB5b3UgbWVldCB5b3VyIHRhcmdldC4gXHJcbiAgICAgICAgICAgIFdoZW4geW91IG1lZXQgdGhlIHRhcmdldCwgeW91IHdpbGwgYmUgYWJsZSB0byBkb3dubG9hZCB0aGUgRXhjZWwgc2hlZXQuYCk7XHJcbiAgICAgICAgUHJvbXB0LkJ1dHRvbnMuUmlnaHQuZGlzYWJsZSgpO1xyXG4gICAgfVxyXG4gICAgUHJvbXB0LnNob3coKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmV0dXJuVG9XZWxjb21lKCkge1xyXG4gICAgY29uc3Qgd2VsY29tZSA9IG5ldyBXZWxjb21lVmlldygpO1xyXG4gICAgY29uc3QgbGVmdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvcHRpb24xJyk7XHJcbiAgICBjb25zb2xlLmxvZyhsZWZ0LmwpXHJcbiAgICB3ZWxjb21lLnZpc2l0KCk7XHJcbn07XHJcblxyXG5leHBvcnQgY2xhc3MgU3VtbWFyeVZpZXcgZXh0ZW5kcyBWaWV3IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIHRoaXMucGFnZV9zdGF0ZSA9ICdzdW1tYXJ5JztcclxuICAgICAgICB0aGlzLnN1YnRpdGxlID0gJ1N1bW1hcnknO1xyXG4gICAgICAgIHRoaXMuc2lkZWJhciA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHZpc2l0KCkge1xyXG4gICAgICAgIHN1cGVyLnZpc2l0KCk7XHJcblxyXG4gICAgICAgIC8vIHJlc2V0IGZ1bmRcclxuICAgICAgICBDdXJyZW50RnVuZC5yZXNldCgpO1xyXG5cclxuICAgICAgICAvLyBzaG93IHN1bW1hcnkgYWNjb3JkaW9uXHJcbiAgICAgICAgQWNjb3JkaW9uLmJ1aWxkKCk7XHJcbiAgICAgICAgQWNjb3JkaW9uLnNob3coKTtcclxuXHJcbiAgICAgICAgLy8gYWRkIHByb21wdCBidXR0b25zXHJcbiAgICAgICAgUHJvbXB0LkJ1dHRvbnMuUmlnaHQudXBkYXRlVGV4dCgnRG93bmxvYWQgRXhjZWwnKTtcclxuICAgICAgICBQcm9tcHQuQnV0dG9ucy5MZWZ0LnVwZGF0ZVRleHQoJ1N0YXJ0IG92ZXIgd2l0aCBuZXcgRXhjZWwgdXBsb2FkJyk7XHJcbiAgICAgICAgLy8gYWRkIGJ1dHRvbiBsaW5rc1xyXG4gICAgICAgIFByb21wdC5CdXR0b25zLkxlZnQuYWRkQWN0aW9uKHJldHVyblRvV2VsY29tZSk7XHJcbiAgICAgICAgUHJvbXB0LkJ1dHRvbnMuUmlnaHQuYWRkQWN0aW9uKGRvd25sb2FkWExTWCk7XHJcblxyXG4gICAgICAgIC8vIHVwZGF0ZSBwcm9tcHQgdGV4dCBkZXBlbmRpbmcgb24gdGFyZ2V0IG1hdGNoaW5nXHJcbiAgICAgICAgY29tcGFyZVRvVGFyZ2V0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgY2xlYW51cCgpIHtcclxuICAgICAgICAvLyBkZWxldGUgZXZlbnQgbGlzdGVuZXJzXHJcbiAgICAgICAgUHJvbXB0LkJ1dHRvbnMuTGVmdC5yZW1vdmVBY3Rpb24ocmV0dXJuVG9XZWxjb21lKTtcclxuICAgICAgICBQcm9tcHQuQnV0dG9ucy5SaWdodC5yZW1vdmVBY3Rpb24oZG93bmxvYWRYTFNYKTtcclxuICAgICAgICBQcm9tcHQuQnV0dG9ucy5SaWdodC5lbmFibGUoKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgU3VtbWFyeVZpZXc7IiwiaW1wb3J0IFdlbGNvbWVWaWV3IGZyb20gJy4vMDBfd2VsY29tZS5qcyc7XHJcbmltcG9ydCBVcGxvYWRWaWV3IGZyb20gJy4vMDFfdXBsb2FkLmpzJztcclxuaW1wb3J0IEZ1bmRWaWV3IGZyb20gJy4vMDJfYmFzZWxpbmVfbGFuZGluZy5qcyc7XHJcbmltcG9ydCBSZXZlbnVlVmlldyBmcm9tICcuLzAzX3JldmVudWUuanMnO1xyXG5pbXBvcnQgUGVyc29ubmVsVmlldyBmcm9tICcuLzA0X3BlcnNvbm5lbC5qcyc7XHJcbmltcG9ydCBPdmVydGltZVZpZXcgZnJvbSAnLi8wNV9vdmVydGltZS5qcyc7XHJcbmltcG9ydCBOb25QZXJzb25uZWxWaWV3IGZyb20gJy4vMDZfbm9ucGVyc29ubmVsLmpzJztcclxuaW1wb3J0IEluaXRpYXRpdmVzVmlldyBmcm9tICcuLzA3X25ld19pbml0aWF0aXZlcy5qcyc7XHJcbmltcG9ydCBTdW1tYXJ5VmlldyBmcm9tICcuLzA4X3N1bW1hcnkuanMnO1xyXG5cclxuaW1wb3J0IHsgRnVuZExvb2t1cFRhYmxlLCBDdXJyZW50RnVuZCwgQ3VycmVudFBhZ2UgfSBmcm9tICcuLi9tb2RlbHMvJztcclxuaW1wb3J0IHsgRklTQ0FMX1lFQVIgfSBmcm9tICcuLi9jb25zdGFudHMvJztcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpbml0aWFsaXplUGFnZXMoKSB7XHJcbiAgICBjb25zdCBQQUdFUyA9IHtcclxuICAgICAgICAnd2VsY29tZSc6IG5ldyBXZWxjb21lVmlldygpLFxyXG4gICAgICAgICd1cGxvYWQnOiBuZXcgVXBsb2FkVmlldygpLFxyXG4gICAgICAgICdiYXNlbGluZS1sYW5kaW5nJzogbmV3IEZ1bmRWaWV3KCksXHJcbiAgICAgICAgJ3JldmVudWUnOiBuZXcgUmV2ZW51ZVZpZXcoRklTQ0FMX1lFQVIpLFxyXG4gICAgICAgICdwZXJzb25uZWwnOiBuZXcgUGVyc29ubmVsVmlldyhGSVNDQUxfWUVBUiksXHJcbiAgICAgICAgJ292ZXJ0aW1lJzogbmV3IE92ZXJ0aW1lVmlldyhGSVNDQUxfWUVBUiksXHJcbiAgICAgICAgJ25vbnBlcnNvbm5lbCc6IG5ldyBOb25QZXJzb25uZWxWaWV3KEZJU0NBTF9ZRUFSKSxcclxuICAgICAgICAnbmV3LWluaXRzJzogbmV3IEluaXRpYXRpdmVzVmlldygpLFxyXG4gICAgICAgICdzdW1tYXJ5JzogbmV3IFN1bW1hcnlWaWV3KCksXHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFBBR0VTO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdmlzaXRQYWdlKG5ld19wYWdlX2tleSl7XHJcblxyXG4gICAgY29uc3QgUEFHRVMgPSBpbml0aWFsaXplUGFnZXMoKTtcclxuXHJcbiAgICAvLyBjbGVhbiB1cCBmcm9tIGN1cnJlbnQgcGFnZVxyXG4gICAgdmFyIHBhZ2Vfc3RhdGUgPSBDdXJyZW50UGFnZS5sb2FkKCk7XHJcbiAgICBQQUdFU1twYWdlX3N0YXRlXS5jbGVhbnVwKCk7XHJcbiAgICBcclxuICAgIC8vIFVzZSB0aGUgcGFnZV9zdGF0ZSB0byBhY2Nlc3MgYW5kIGNhbGwgdGhlIGNvcnJlc3BvbmRpbmcgZnVuY3Rpb24gZnJvbSBQQUdFU1xyXG4gICAgaWYgKFBBR0VTW25ld19wYWdlX2tleV0pIHtcclxuICAgICAgICAvLyBJbnZva2VzIHRoZSBmdW5jdGlvbiBpZiBpdCBleGlzdHMgaW4gdGhlIFBBR0VTIG1hcFxyXG4gICAgICAgIFBBR0VTW25ld19wYWdlX2tleV0udmlzaXQoKTsgXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYE5vIHBhZ2UgaW5pdGlhbGl6ZXIgZm91bmQgZm9yIHN0YXRlOiAke25ld19wYWdlX2tleX1gKTtcclxuICAgIH19XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV4dFBhZ2UoKXtcclxuXHJcbiAgICBjb25zdCBQQUdFUyA9IGluaXRpYWxpemVQYWdlcygpO1xyXG5cclxuICAgIHZhciBwYWdlX3N0YXRlID0gQ3VycmVudFBhZ2UubG9hZCgpO1xyXG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKFBBR0VTKTtcclxuICBcclxuICAgIC8vIEZpbmQgdGhlIGluZGV4IG9mIHRoZSBjdXJyZW50IGtleVxyXG4gICAgY29uc3QgY3VycmVudEluZGV4ID0ga2V5cy5pbmRleE9mKHBhZ2Vfc3RhdGUpO1xyXG5cclxuICAgIC8vIFJldHVybiB0byBzdW1tYXJ5IGlmIGFsbCBmdW5kcyBhcmUgdmlld2VkXHJcbiAgICBjb25zdCByZXR1cm5QYWdlcyA9IFsncmV2ZW51ZScsICdub25wZXJzb25uZWwnLCAnbmV3LWluaXRzJywgJ292ZXJ0aW1lJywgJ3BlcnNvbm5lbCddO1xyXG4gICAgaWYgKCFGdW5kTG9va3VwVGFibGUuZnVuZHNMZWZ0KCkgJiYgcmV0dXJuUGFnZXMuaW5jbHVkZXMoQ3VycmVudFBhZ2UubG9hZCgpKSkge1xyXG4gICAgICAgIHZpc2l0UGFnZSgnc3VtbWFyeScpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBpZiBvbiBub24tcGVyc29ubmVsLCBjaXJjbGUgYmFjayB0byBmdW5kIHNlbGVjdGlvbiB1bmxlc3MgYWxsIGZ1bmRzIGFyZSBlZGl0ZWRcclxuICAgIGlmIChDdXJyZW50UGFnZS5sb2FkKCkgPT0gJ25vbnBlcnNvbm5lbCcpe1xyXG4gICAgICAgIC8vIG1hcmsgZnVuZCBhcyB2aWV3ZWQvZWRpdGVkXHJcbiAgICAgICAgRnVuZExvb2t1cFRhYmxlLmVkaXRGdW5kKEN1cnJlbnRGdW5kLm51bWJlcigpKTtcclxuICAgICAgICAvLyBpZiBhbnkgZnVuZHMgbGVmdCB0byBlZGl0LCBnbyBiYWNrIHRvIHRoYXQgcGFnZVxyXG4gICAgICAgIGlmICggRnVuZExvb2t1cFRhYmxlLmZ1bmRzTGVmdCgpICl7XHJcbiAgICAgICAgICAgIHZpc2l0UGFnZSgnYmFzZWxpbmUtbGFuZGluZycpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChjdXJyZW50SW5kZXggPj0gMCAmJiBjdXJyZW50SW5kZXggPCBrZXlzLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAvLyBDaGVjayBpZiB0aGVyZSBpcyBhIG5leHQga2V5LCBhbmQgZ2V0IGl0XHJcbiAgICAgICAgY29uc3QgbmV4dEtleSA9IGtleXNbY3VycmVudEluZGV4ICsgMV07XHJcbiAgICAgICAgLy8gZ28gdG8gdGhhdCBwYWdlXHJcbiAgICAgICAgdmlzaXRQYWdlKG5leHRLZXkpO1xyXG4gICAgfSBcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGxhc3RQYWdlKCl7XHJcblxyXG4gICAgY29uc3QgUEFHRVMgPSBpbml0aWFsaXplUGFnZXMoKTtcclxuXHJcbiAgICB2YXIgcGFnZV9zdGF0ZSA9IEN1cnJlbnRQYWdlLmxvYWQoKTtcclxuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhQQUdFUyk7XHJcbiAgXHJcbiAgICAvLyBGaW5kIHRoZSBpbmRleCBvZiB0aGUgY3VycmVudCBrZXlcclxuICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IGtleXMuaW5kZXhPZihwYWdlX3N0YXRlKTtcclxuXHJcbiAgICAvLyBpZiBvbiBuZXctaW5pdHMsIGNpcmNsZSBiYWNrIHRvIGZ1bmQgc2VsZWN0aW9uXHJcbiAgICBpZiAoQ3VycmVudFBhZ2UubG9hZCgpID09ICduZXctaW5pdHMnKXtcclxuICAgICAgICB2aXNpdFBhZ2UoJ2Jhc2VsaW5lLWxhbmRpbmcnKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8vIENoZWNrIGlmIHRoZXJlIGlzIGEgbmV4dCBrZXlcclxuICAgIGlmIChjdXJyZW50SW5kZXggPj0gMSkge1xyXG4gICAgICAgIC8vIEdldCB0aGUgbmV4dCBrZXlcclxuICAgICAgICBjb25zdCBsYXN0S2V5ID0ga2V5c1tjdXJyZW50SW5kZXggLSAxXTtcclxuICAgICAgICAvLyBnbyB0byB0aGF0IHBhZ2VcclxuICAgICAgICB2aXNpdFBhZ2UobGFzdEtleSk7XHJcbiAgICB9IFxyXG59IiwiaW1wb3J0IHsgdmlzaXRQYWdlIH0gZnJvbSBcIi4uL3ZpZXdzL3ZpZXdfbG9naWNcIjtcclxuXHJcbmV4cG9ydCBjb25zdCBDdXJyZW50UGFnZSA9IHtcclxuICAgIHVwZGF0ZSA6IGZ1bmN0aW9uKHBhZ2Upe1xyXG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdwYWdlX3N0YXRlJywgcGFnZSk7XHJcbiAgICB9LFxyXG4gICAgbG9hZCA6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgY29uc3QgcGFnZVN0YXRlID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3BhZ2Vfc3RhdGUnKTtcclxuICAgICAgICByZXR1cm4gcGFnZVN0YXRlICE9PSBudWxsID8gcGFnZVN0YXRlIDogJ3dlbGNvbWUnO1xyXG4gICAgfSxcclxuICAgIHZpc2l0IDogZnVuY3Rpb24oKXtcclxuICAgICAgICB2aXNpdFBhZ2UodGhpcy5sb2FkKCkpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCBDdXJyZW50UGFnZTsiLCIvLyBpbXBvcnQgc3R5bGVzXHJcbmltcG9ydCAnLi4vY3NzL2NvbW1vbi5jc3MnO1xyXG5cclxuLy8gaW1wb3J0IGZ1bmN0aW9uc1xyXG5pbXBvcnQgQ3VycmVudFBhZ2UgZnJvbSAnLi9tb2RlbHMvY3VycmVudF9wYWdlLmpzJztcclxuXHJcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICBDdXJyZW50UGFnZS52aXNpdCgpO1xyXG59KTtcclxuXHJcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///254\n")},404:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `:root {\r\n /* colors */\r\n --orange: #FB6523;\r\n --yellow: #D99733;\r\n --blue: #43748E;\r\n --lightBlue: #b7c9e2;\r\n --darkGray: #373A37;\r\n --mediumGray: #D0D0D0;\r\n --lightGray: #F2F2F2;\r\n --white: #FBFDFB;\r\n --black: #212121;\r\n --green: #71BC78;\r\n --citygreen: #004445;\r\n --spiritgreen: #279989;\r\n --palegreen: #9FD5B3;\r\n --verypalegreen: #DFF5E3;\r\n --accentyellow: #feb70d;\r\n --nearblack: #18252a;\r\n /* fonts */\r\n font-family: \'Nunito\', sans-serif;\r\n font-size: 14px;\r\n /* spacing */\r\n --header-height : 105px;\r\n --sidebar-width: 300px;\r\n}\r\n\r\n/* Button styling */\r\n\r\n.btn {\r\n cursor: pointer;\r\n padding: 6px;\r\n margin-top: 5px;\r\n margin-right : 2px;\r\n margin-left: 2px;\r\n border-radius: 10px;\r\n background-color: gray;\r\n color: white; \r\n}\r\n\r\n/* Font application for all text */\r\nbody, button, input, textarea, select, .sidebar, table {\r\n font-family: var(--font-family), sans-serif;\r\n }\r\n\r\n#main-panel {\r\n /* display: flex; */\r\n /* flex-direction: column; */\r\n justify-content: center; /* This will center content vertically */\r\n min-height: calc(100vh - var(--header-height)) ; \r\n /* max-width: calc(100vw - var(--sidebar-width)); */\r\n padding-top: 25px;\r\n padding-bottom: 25px;\r\n margin: 0;\r\n}\r\n\r\n/* Font awesome */\r\n\r\ni.fas.fa-check { \r\n font-size: 1.5em;\r\n color: var(--spiritgreen);\r\n margin-right: 10px;\r\n}\r\n`, "",{"version":3,"sources":["webpack://./src/css/common.css"],"names":[],"mappings":"AAAA;IACI,WAAW;IACX,iBAAiB;IACjB,iBAAiB;IACjB,eAAe;IACf,oBAAoB;IACpB,mBAAmB;IACnB,qBAAqB;IACrB,oBAAoB;IACpB,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,oBAAoB;IACpB,sBAAsB;IACtB,oBAAoB;IACpB,wBAAwB;IACxB,uBAAuB;IACvB,oBAAoB;IACpB,UAAU;IACV,iCAAiC;IACjC,eAAe;IACf,YAAY;IACZ,uBAAuB;IACvB,sBAAsB;AAC1B;;AAEA,mBAAmB;;AAEnB;IACI,eAAe;IACf,YAAY;IACZ,eAAe;IACf,kBAAkB;IAClB,gBAAgB;IAChB,mBAAmB;IACnB,sBAAsB;IACtB,YAAY;AAChB;;AAEA,mCAAmC;AACnC;IACI,2CAA2C;EAC7C;;AAEF;IACI,mBAAmB;IACnB,4BAA4B;IAC5B,uBAAuB,EAAE,wCAAwC;IACjE,+CAA+C;IAC/C,oDAAoD;IACpD,iBAAiB;IACjB,oBAAoB;IACpB,SAAS;AACb;;AAEA,iBAAiB;;AAEjB;IACI,gBAAgB;IAChB,yBAAyB;IACzB,kBAAkB;AACtB","sourcesContent":[":root {\\r\\n /* colors */\\r\\n --orange: #FB6523;\\r\\n --yellow: #D99733;\\r\\n --blue: #43748E;\\r\\n --lightBlue: #b7c9e2;\\r\\n --darkGray: #373A37;\\r\\n --mediumGray: #D0D0D0;\\r\\n --lightGray: #F2F2F2;\\r\\n --white: #FBFDFB;\\r\\n --black: #212121;\\r\\n --green: #71BC78;\\r\\n --citygreen: #004445;\\r\\n --spiritgreen: #279989;\\r\\n --palegreen: #9FD5B3;\\r\\n --verypalegreen: #DFF5E3;\\r\\n --accentyellow: #feb70d;\\r\\n --nearblack: #18252a;\\r\\n /* fonts */\\r\\n font-family: \'Nunito\', sans-serif;\\r\\n font-size: 14px;\\r\\n /* spacing */\\r\\n --header-height : 105px;\\r\\n --sidebar-width: 300px;\\r\\n}\\r\\n\\r\\n/* Button styling */\\r\\n\\r\\n.btn {\\r\\n cursor: pointer;\\r\\n padding: 6px;\\r\\n margin-top: 5px;\\r\\n margin-right : 2px;\\r\\n margin-left: 2px;\\r\\n border-radius: 10px;\\r\\n background-color: gray;\\r\\n color: white; \\r\\n}\\r\\n\\r\\n/* Font application for all text */\\r\\nbody, button, input, textarea, select, .sidebar, table {\\r\\n font-family: var(--font-family), sans-serif;\\r\\n }\\r\\n\\r\\n#main-panel {\\r\\n /* display: flex; */\\r\\n /* flex-direction: column; */\\r\\n justify-content: center; /* This will center content vertically */\\r\\n min-height: calc(100vh - var(--header-height)) ; \\r\\n /* max-width: calc(100vw - var(--sidebar-width)); */\\r\\n padding-top: 25px;\\r\\n padding-bottom: 25px;\\r\\n margin: 0;\\r\\n}\\r\\n\\r\\n/* Font awesome */\\r\\n\\r\\ni.fas.fa-check { \\r\\n font-size: 1.5em;\\r\\n color: var(--spiritgreen);\\r\\n margin-right: 10px;\\r\\n}\\r\\n"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDA0LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvY3NzL2NvbW1vbi5jc3M/ZjdjYSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgOnJvb3Qge1xyXG4gICAgLyogY29sb3JzICovXHJcbiAgICAtLW9yYW5nZTogI0ZCNjUyMztcclxuICAgIC0teWVsbG93OiAjRDk5NzMzO1xyXG4gICAgLS1ibHVlOiAjNDM3NDhFO1xyXG4gICAgLS1saWdodEJsdWU6ICNiN2M5ZTI7XHJcbiAgICAtLWRhcmtHcmF5OiAjMzczQTM3O1xyXG4gICAgLS1tZWRpdW1HcmF5OiAjRDBEMEQwO1xyXG4gICAgLS1saWdodEdyYXk6ICNGMkYyRjI7XHJcbiAgICAtLXdoaXRlOiAjRkJGREZCO1xyXG4gICAgLS1ibGFjazogIzIxMjEyMTtcclxuICAgIC0tZ3JlZW46ICM3MUJDNzg7XHJcbiAgICAtLWNpdHlncmVlbjogIzAwNDQ0NTtcclxuICAgIC0tc3Bpcml0Z3JlZW46ICMyNzk5ODk7XHJcbiAgICAtLXBhbGVncmVlbjogIzlGRDVCMztcclxuICAgIC0tdmVyeXBhbGVncmVlbjogI0RGRjVFMztcclxuICAgIC0tYWNjZW50eWVsbG93OiAjZmViNzBkO1xyXG4gICAgLS1uZWFyYmxhY2s6ICMxODI1MmE7XHJcbiAgICAvKiBmb250cyAqL1xyXG4gICAgZm9udC1mYW1pbHk6ICdOdW5pdG8nLCBzYW5zLXNlcmlmO1xyXG4gICAgZm9udC1zaXplOiAxNHB4O1xyXG4gICAgLyogc3BhY2luZyAqL1xyXG4gICAgLS1oZWFkZXItaGVpZ2h0IDogMTA1cHg7XHJcbiAgICAtLXNpZGViYXItd2lkdGg6IDMwMHB4O1xyXG59XHJcblxyXG4vKiBCdXR0b24gc3R5bGluZyAqL1xyXG5cclxuLmJ0biB7XHJcbiAgICBjdXJzb3I6IHBvaW50ZXI7XHJcbiAgICBwYWRkaW5nOiA2cHg7XHJcbiAgICBtYXJnaW4tdG9wOiA1cHg7XHJcbiAgICBtYXJnaW4tcmlnaHQgOiAycHg7XHJcbiAgICBtYXJnaW4tbGVmdDogMnB4O1xyXG4gICAgYm9yZGVyLXJhZGl1czogMTBweDtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IGdyYXk7XHJcbiAgICBjb2xvcjogd2hpdGU7IFxyXG59XHJcblxyXG4vKiBGb250IGFwcGxpY2F0aW9uIGZvciBhbGwgdGV4dCAgKi9cclxuYm9keSwgYnV0dG9uLCBpbnB1dCwgdGV4dGFyZWEsIHNlbGVjdCwgLnNpZGViYXIsIHRhYmxlIHtcclxuICAgIGZvbnQtZmFtaWx5OiB2YXIoLS1mb250LWZhbWlseSksIHNhbnMtc2VyaWY7XHJcbiAgfVxyXG5cclxuI21haW4tcGFuZWwge1xyXG4gICAgLyogZGlzcGxheTogZmxleDsgKi9cclxuICAgIC8qIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47ICovXHJcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgLyogVGhpcyB3aWxsIGNlbnRlciBjb250ZW50IHZlcnRpY2FsbHkgKi9cclxuICAgIG1pbi1oZWlnaHQ6IGNhbGMoMTAwdmggLSB2YXIoLS1oZWFkZXItaGVpZ2h0KSkgOyBcclxuICAgIC8qIG1heC13aWR0aDogY2FsYygxMDB2dyAtIHZhcigtLXNpZGViYXItd2lkdGgpKTsgICovXHJcbiAgICBwYWRkaW5nLXRvcDogMjVweDtcclxuICAgIHBhZGRpbmctYm90dG9tOiAyNXB4O1xyXG4gICAgbWFyZ2luOiAwO1xyXG59XHJcblxyXG4vKiBGb250IGF3ZXNvbWUgKi9cclxuXHJcbmkuZmFzLmZhLWNoZWNrIHsgXHJcbiAgICBmb250LXNpemU6IDEuNWVtO1xyXG4gICAgY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIG1hcmdpbi1yaWdodDogMTBweDtcclxufVxyXG5gLCBcIlwiLHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIndlYnBhY2s6Ly8uL3NyYy9jc3MvY29tbW9uLmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLFdBQVc7SUFDWCxpQkFBaUI7SUFDakIsaUJBQWlCO0lBQ2pCLGVBQWU7SUFDZixvQkFBb0I7SUFDcEIsbUJBQW1CO0lBQ25CLHFCQUFxQjtJQUNyQixvQkFBb0I7SUFDcEIsZ0JBQWdCO0lBQ2hCLGdCQUFnQjtJQUNoQixnQkFBZ0I7SUFDaEIsb0JBQW9CO0lBQ3BCLHNCQUFzQjtJQUN0QixvQkFBb0I7SUFDcEIsd0JBQXdCO0lBQ3hCLHVCQUF1QjtJQUN2QixvQkFBb0I7SUFDcEIsVUFBVTtJQUNWLGlDQUFpQztJQUNqQyxlQUFlO0lBQ2YsWUFBWTtJQUNaLHVCQUF1QjtJQUN2QixzQkFBc0I7QUFDMUI7O0FBRUEsbUJBQW1COztBQUVuQjtJQUNJLGVBQWU7SUFDZixZQUFZO0lBQ1osZUFBZTtJQUNmLGtCQUFrQjtJQUNsQixnQkFBZ0I7SUFDaEIsbUJBQW1CO0lBQ25CLHNCQUFzQjtJQUN0QixZQUFZO0FBQ2hCOztBQUVBLG1DQUFtQztBQUNuQztJQUNJLDJDQUEyQztFQUM3Qzs7QUFFRjtJQUNJLG1CQUFtQjtJQUNuQiw0QkFBNEI7SUFDNUIsdUJBQXVCLEVBQUUsd0NBQXdDO0lBQ2pFLCtDQUErQztJQUMvQyxvREFBb0Q7SUFDcEQsaUJBQWlCO0lBQ2pCLG9CQUFvQjtJQUNwQixTQUFTO0FBQ2I7O0FBRUEsaUJBQWlCOztBQUVqQjtJQUNJLGdCQUFnQjtJQUNoQix5QkFBeUI7SUFDekIsa0JBQWtCO0FBQ3RCXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjpyb290IHtcXHJcXG4gICAgLyogY29sb3JzICovXFxyXFxuICAgIC0tb3JhbmdlOiAjRkI2NTIzO1xcclxcbiAgICAtLXllbGxvdzogI0Q5OTczMztcXHJcXG4gICAgLS1ibHVlOiAjNDM3NDhFO1xcclxcbiAgICAtLWxpZ2h0Qmx1ZTogI2I3YzllMjtcXHJcXG4gICAgLS1kYXJrR3JheTogIzM3M0EzNztcXHJcXG4gICAgLS1tZWRpdW1HcmF5OiAjRDBEMEQwO1xcclxcbiAgICAtLWxpZ2h0R3JheTogI0YyRjJGMjtcXHJcXG4gICAgLS13aGl0ZTogI0ZCRkRGQjtcXHJcXG4gICAgLS1ibGFjazogIzIxMjEyMTtcXHJcXG4gICAgLS1ncmVlbjogIzcxQkM3ODtcXHJcXG4gICAgLS1jaXR5Z3JlZW46ICMwMDQ0NDU7XFxyXFxuICAgIC0tc3Bpcml0Z3JlZW46ICMyNzk5ODk7XFxyXFxuICAgIC0tcGFsZWdyZWVuOiAjOUZENUIzO1xcclxcbiAgICAtLXZlcnlwYWxlZ3JlZW46ICNERkY1RTM7XFxyXFxuICAgIC0tYWNjZW50eWVsbG93OiAjZmViNzBkO1xcclxcbiAgICAtLW5lYXJibGFjazogIzE4MjUyYTtcXHJcXG4gICAgLyogZm9udHMgKi9cXHJcXG4gICAgZm9udC1mYW1pbHk6ICdOdW5pdG8nLCBzYW5zLXNlcmlmO1xcclxcbiAgICBmb250LXNpemU6IDE0cHg7XFxyXFxuICAgIC8qIHNwYWNpbmcgKi9cXHJcXG4gICAgLS1oZWFkZXItaGVpZ2h0IDogMTA1cHg7XFxyXFxuICAgIC0tc2lkZWJhci13aWR0aDogMzAwcHg7XFxyXFxufVxcclxcblxcclxcbi8qIEJ1dHRvbiBzdHlsaW5nICovXFxyXFxuXFxyXFxuLmJ0biB7XFxyXFxuICAgIGN1cnNvcjogcG9pbnRlcjtcXHJcXG4gICAgcGFkZGluZzogNnB4O1xcclxcbiAgICBtYXJnaW4tdG9wOiA1cHg7XFxyXFxuICAgIG1hcmdpbi1yaWdodCA6IDJweDtcXHJcXG4gICAgbWFyZ2luLWxlZnQ6IDJweDtcXHJcXG4gICAgYm9yZGVyLXJhZGl1czogMTBweDtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogZ3JheTtcXHJcXG4gICAgY29sb3I6IHdoaXRlOyBcXHJcXG59XFxyXFxuXFxyXFxuLyogRm9udCBhcHBsaWNhdGlvbiBmb3IgYWxsIHRleHQgICovXFxyXFxuYm9keSwgYnV0dG9uLCBpbnB1dCwgdGV4dGFyZWEsIHNlbGVjdCwgLnNpZGViYXIsIHRhYmxlIHtcXHJcXG4gICAgZm9udC1mYW1pbHk6IHZhcigtLWZvbnQtZmFtaWx5KSwgc2Fucy1zZXJpZjtcXHJcXG4gIH1cXHJcXG5cXHJcXG4jbWFpbi1wYW5lbCB7XFxyXFxuICAgIC8qIGRpc3BsYXk6IGZsZXg7ICovXFxyXFxuICAgIC8qIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47ICovXFxyXFxuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOyAvKiBUaGlzIHdpbGwgY2VudGVyIGNvbnRlbnQgdmVydGljYWxseSAqL1xcclxcbiAgICBtaW4taGVpZ2h0OiBjYWxjKDEwMHZoIC0gdmFyKC0taGVhZGVyLWhlaWdodCkpIDsgXFxyXFxuICAgIC8qIG1heC13aWR0aDogY2FsYygxMDB2dyAtIHZhcigtLXNpZGViYXItd2lkdGgpKTsgICovXFxyXFxuICAgIHBhZGRpbmctdG9wOiAyNXB4O1xcclxcbiAgICBwYWRkaW5nLWJvdHRvbTogMjVweDtcXHJcXG4gICAgbWFyZ2luOiAwO1xcclxcbn1cXHJcXG5cXHJcXG4vKiBGb250IGF3ZXNvbWUgKi9cXHJcXG5cXHJcXG5pLmZhcy5mYS1jaGVjayB7IFxcclxcbiAgICBmb250LXNpemU6IDEuNWVtO1xcclxcbiAgICBjb2xvcjogdmFyKC0tc3Bpcml0Z3JlZW4pO1xcclxcbiAgICBtYXJnaW4tcmlnaHQ6IDEwcHg7XFxyXFxufVxcclxcblwiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuLy8gRXhwb3J0c1xuZXhwb3J0IGRlZmF1bHQgX19fQ1NTX0xPQURFUl9FWFBPUlRfX187XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///404\n')},995:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.summary-accordion {\r\n width: 60%;\r\n margin: auto;\r\n}\r\n\r\n.accordion-title {\r\n margin-left: 20%;\r\n font-weight: bold;\r\n /* font-size: 20px; */\r\n padding-bottom: 10px;\r\n padding-left: 15px;\r\n padding-top: 30px;\r\n}\r\n\r\n.accordion-button:active, .accordion-button:not(.collapsed) {\r\n background-color: var(--palegreen);\r\n color: var(--citygreen);\r\n /* font-size: 20px; */\r\n}\r\n\r\n.accordion-table { \r\n width: 100%;\r\n font-size: 1.2em;\r\n /* border-collapse: separate; This is required for rounded corners */\r\n}\r\n\r\n.accordion-table td:last-child {\r\n text-align: right;\r\n padding-right: 15px;\r\n padding-bottom: 5px\r\n}\r\n\r\n.accordion-table tr {\r\n border-bottom: 1px solid black;\r\n border-top: none;\r\n border-right: none;\r\n border-left: none;\r\n}\r\n\r\n.accordion-table tr:last-child {\r\n border-bottom: none;\r\n background-color: var(--mediumGray);\r\n height : 50px;\r\n}\r\n\r\nspan.amount {\r\n font-weight: bold;\r\n position: absolute;\r\n right: 0;\r\n margin-right: 60px;\r\n}\r\n\r\n.accordion-header button {\r\n font-size: 0.8em;\r\n}\r\n\r\n.btn-add-init {\r\n background-color: var(--spiritgreen);\r\n border-color: var(--citygreen);\r\n /* position: absolute; */\r\n right: 0;\r\n /* margin-left: 20px; */\r\n /* margin-right: calc(20vw + 15px); */\r\n margin-top: 15px;\r\n}\r\n\r\n#supp-title {\r\n margin-top: 20px;\r\n}\r\n\r\n.btn-add-init:hover {\r\n background-color: var(--palegreen);\r\n}\r\n.add-init-btn-div{\r\n text-align: center;\r\n}\r\n\r\nspan.top-line-amount {\r\n font-weight: bold;\r\n position: absolute;\r\n right: 0;\r\n margin-right: calc(20vw + 20px);\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/accordion/accordion.css"],"names":[],"mappings":"AAAA;IACI,UAAU;IACV,YAAY;AAChB;;AAEA;IACI,gBAAgB;IAChB,iBAAiB;IACjB,qBAAqB;IACrB,oBAAoB;IACpB,kBAAkB;IAClB,iBAAiB;AACrB;;AAEA;IACI,kCAAkC;IAClC,uBAAuB;IACvB,qBAAqB;AACzB;;AAEA;IACI,WAAW;IACX,gBAAgB;IAChB,oEAAoE;AACxE;;AAEA;IACI,iBAAiB;IACjB,mBAAmB;IACnB;AACJ;;AAEA;IACI,8BAA8B;IAC9B,gBAAgB;IAChB,kBAAkB;IAClB,iBAAiB;AACrB;;AAEA;IACI,mBAAmB;IACnB,mCAAmC;IACnC,aAAa;AACjB;;AAEA;IACI,iBAAiB;IACjB,kBAAkB;IAClB,QAAQ;IACR,kBAAkB;AACtB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,oCAAoC;IACpC,8BAA8B;IAC9B,wBAAwB;IACxB,QAAQ;IACR,uBAAuB;IACvB,qCAAqC;IACrC,gBAAgB;AACpB;;AAEA;GACG,gBAAgB;AACnB;;AAEA;IACI,kCAAkC;AACtC;AACA;IACI,kBAAkB;AACtB;;AAEA;IACI,iBAAiB;IACjB,kBAAkB;IAClB,QAAQ;IACR,+BAA+B;AACnC","sourcesContent":[".summary-accordion {\\r\\n width: 60%;\\r\\n margin: auto;\\r\\n}\\r\\n\\r\\n.accordion-title {\\r\\n margin-left: 20%;\\r\\n font-weight: bold;\\r\\n /* font-size: 20px; */\\r\\n padding-bottom: 10px;\\r\\n padding-left: 15px;\\r\\n padding-top: 30px;\\r\\n}\\r\\n\\r\\n.accordion-button:active, .accordion-button:not(.collapsed) {\\r\\n background-color: var(--palegreen);\\r\\n color: var(--citygreen);\\r\\n /* font-size: 20px; */\\r\\n}\\r\\n\\r\\n.accordion-table { \\r\\n width: 100%;\\r\\n font-size: 1.2em;\\r\\n /* border-collapse: separate; This is required for rounded corners */\\r\\n}\\r\\n\\r\\n.accordion-table td:last-child {\\r\\n text-align: right;\\r\\n padding-right: 15px;\\r\\n padding-bottom: 5px\\r\\n}\\r\\n\\r\\n.accordion-table tr {\\r\\n border-bottom: 1px solid black;\\r\\n border-top: none;\\r\\n border-right: none;\\r\\n border-left: none;\\r\\n}\\r\\n\\r\\n.accordion-table tr:last-child {\\r\\n border-bottom: none;\\r\\n background-color: var(--mediumGray);\\r\\n height : 50px;\\r\\n}\\r\\n\\r\\nspan.amount {\\r\\n font-weight: bold;\\r\\n position: absolute;\\r\\n right: 0;\\r\\n margin-right: 60px;\\r\\n}\\r\\n\\r\\n.accordion-header button {\\r\\n font-size: 0.8em;\\r\\n}\\r\\n\\r\\n.btn-add-init {\\r\\n background-color: var(--spiritgreen);\\r\\n border-color: var(--citygreen);\\r\\n /* position: absolute; */\\r\\n right: 0;\\r\\n /* margin-left: 20px; */\\r\\n /* margin-right: calc(20vw + 15px); */\\r\\n margin-top: 15px;\\r\\n}\\r\\n\\r\\n#supp-title {\\r\\n margin-top: 20px;\\r\\n}\\r\\n\\r\\n.btn-add-init:hover {\\r\\n background-color: var(--palegreen);\\r\\n}\\r\\n.add-init-btn-div{\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\nspan.top-line-amount {\\r\\n font-weight: bold;\\r\\n position: absolute;\\r\\n right: 0;\\r\\n margin-right: calc(20vw + 20px);\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTk1LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvYWNjb3JkaW9uL2FjY29yZGlvbi5jc3M/ZjBmOCJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgLnN1bW1hcnktYWNjb3JkaW9uIHtcclxuICAgIHdpZHRoOiA2MCU7XHJcbiAgICBtYXJnaW46IGF1dG87XHJcbn1cclxuXHJcbi5hY2NvcmRpb24tdGl0bGUge1xyXG4gICAgbWFyZ2luLWxlZnQ6IDIwJTtcclxuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xyXG4gICAgLyogZm9udC1zaXplOiAyMHB4OyAqL1xyXG4gICAgcGFkZGluZy1ib3R0b206IDEwcHg7XHJcbiAgICBwYWRkaW5nLWxlZnQ6IDE1cHg7XHJcbiAgICBwYWRkaW5nLXRvcDogMzBweDtcclxufVxyXG5cclxuLmFjY29yZGlvbi1idXR0b246YWN0aXZlLCAuYWNjb3JkaW9uLWJ1dHRvbjpub3QoLmNvbGxhcHNlZCkge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tcGFsZWdyZWVuKTtcclxuICAgIGNvbG9yOiB2YXIoLS1jaXR5Z3JlZW4pO1xyXG4gICAgLyogZm9udC1zaXplOiAyMHB4OyAqL1xyXG59XHJcblxyXG4uYWNjb3JkaW9uLXRhYmxlIHsgXHJcbiAgICB3aWR0aDogMTAwJTtcclxuICAgIGZvbnQtc2l6ZTogMS4yZW07XHJcbiAgICAvKiBib3JkZXItY29sbGFwc2U6IHNlcGFyYXRlOyBUaGlzIGlzIHJlcXVpcmVkIGZvciByb3VuZGVkIGNvcm5lcnMgKi9cclxufVxyXG5cclxuLmFjY29yZGlvbi10YWJsZSB0ZDpsYXN0LWNoaWxkIHtcclxuICAgIHRleHQtYWxpZ246IHJpZ2h0O1xyXG4gICAgcGFkZGluZy1yaWdodDogMTVweDtcclxuICAgIHBhZGRpbmctYm90dG9tOiA1cHhcclxufVxyXG5cclxuLmFjY29yZGlvbi10YWJsZSB0ciB7XHJcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgYmxhY2s7XHJcbiAgICBib3JkZXItdG9wOiBub25lO1xyXG4gICAgYm9yZGVyLXJpZ2h0OiBub25lO1xyXG4gICAgYm9yZGVyLWxlZnQ6IG5vbmU7XHJcbn1cclxuXHJcbi5hY2NvcmRpb24tdGFibGUgdHI6bGFzdC1jaGlsZCB7XHJcbiAgICBib3JkZXItYm90dG9tOiBub25lO1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tbWVkaXVtR3JheSk7XHJcbiAgICBoZWlnaHQgOiA1MHB4O1xyXG59XHJcblxyXG5zcGFuLmFtb3VudCB7XHJcbiAgICBmb250LXdlaWdodDogYm9sZDtcclxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgIHJpZ2h0OiAwO1xyXG4gICAgbWFyZ2luLXJpZ2h0OiA2MHB4O1xyXG59XHJcblxyXG4uYWNjb3JkaW9uLWhlYWRlciBidXR0b24ge1xyXG4gICAgZm9udC1zaXplOiAwLjhlbTtcclxufVxyXG5cclxuLmJ0bi1hZGQtaW5pdCB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XHJcbiAgICBib3JkZXItY29sb3I6IHZhcigtLWNpdHlncmVlbik7XHJcbiAgICAvKiBwb3NpdGlvbjogYWJzb2x1dGU7ICovXHJcbiAgICByaWdodDogMDtcclxuICAgIC8qIG1hcmdpbi1sZWZ0OiAyMHB4OyAqL1xyXG4gICAgLyogbWFyZ2luLXJpZ2h0OiBjYWxjKDIwdncgKyAxNXB4KTsgKi9cclxuICAgIG1hcmdpbi10b3A6IDE1cHg7XHJcbn1cclxuXHJcbiNzdXBwLXRpdGxlIHtcclxuICAgbWFyZ2luLXRvcDogMjBweDtcclxufVxyXG5cclxuLmJ0bi1hZGQtaW5pdDpob3ZlciB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1wYWxlZ3JlZW4pO1xyXG59XHJcbi5hZGQtaW5pdC1idG4tZGl2e1xyXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG59XHJcblxyXG5zcGFuLnRvcC1saW5lLWFtb3VudCB7XHJcbiAgICBmb250LXdlaWdodDogYm9sZDtcclxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgIHJpZ2h0OiAwO1xyXG4gICAgbWFyZ2luLXJpZ2h0OiBjYWxjKDIwdncgKyAyMHB4KTtcclxufWAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2pzL2NvbXBvbmVudHMvYWNjb3JkaW9uL2FjY29yZGlvbi5jc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7SUFDSSxVQUFVO0lBQ1YsWUFBWTtBQUNoQjs7QUFFQTtJQUNJLGdCQUFnQjtJQUNoQixpQkFBaUI7SUFDakIscUJBQXFCO0lBQ3JCLG9CQUFvQjtJQUNwQixrQkFBa0I7SUFDbEIsaUJBQWlCO0FBQ3JCOztBQUVBO0lBQ0ksa0NBQWtDO0lBQ2xDLHVCQUF1QjtJQUN2QixxQkFBcUI7QUFDekI7O0FBRUE7SUFDSSxXQUFXO0lBQ1gsZ0JBQWdCO0lBQ2hCLG9FQUFvRTtBQUN4RTs7QUFFQTtJQUNJLGlCQUFpQjtJQUNqQixtQkFBbUI7SUFDbkI7QUFDSjs7QUFFQTtJQUNJLDhCQUE4QjtJQUM5QixnQkFBZ0I7SUFDaEIsa0JBQWtCO0lBQ2xCLGlCQUFpQjtBQUNyQjs7QUFFQTtJQUNJLG1CQUFtQjtJQUNuQixtQ0FBbUM7SUFDbkMsYUFBYTtBQUNqQjs7QUFFQTtJQUNJLGlCQUFpQjtJQUNqQixrQkFBa0I7SUFDbEIsUUFBUTtJQUNSLGtCQUFrQjtBQUN0Qjs7QUFFQTtJQUNJLGdCQUFnQjtBQUNwQjs7QUFFQTtJQUNJLG9DQUFvQztJQUNwQyw4QkFBOEI7SUFDOUIsd0JBQXdCO0lBQ3hCLFFBQVE7SUFDUix1QkFBdUI7SUFDdkIscUNBQXFDO0lBQ3JDLGdCQUFnQjtBQUNwQjs7QUFFQTtHQUNHLGdCQUFnQjtBQUNuQjs7QUFFQTtJQUNJLGtDQUFrQztBQUN0QztBQUNBO0lBQ0ksa0JBQWtCO0FBQ3RCOztBQUVBO0lBQ0ksaUJBQWlCO0lBQ2pCLGtCQUFrQjtJQUNsQixRQUFRO0lBQ1IsK0JBQStCO0FBQ25DXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi5zdW1tYXJ5LWFjY29yZGlvbiB7XFxyXFxuICAgIHdpZHRoOiA2MCU7XFxyXFxuICAgIG1hcmdpbjogYXV0bztcXHJcXG59XFxyXFxuXFxyXFxuLmFjY29yZGlvbi10aXRsZSB7XFxyXFxuICAgIG1hcmdpbi1sZWZ0OiAyMCU7XFxyXFxuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xcclxcbiAgICAvKiBmb250LXNpemU6IDIwcHg7ICovXFxyXFxuICAgIHBhZGRpbmctYm90dG9tOiAxMHB4O1xcclxcbiAgICBwYWRkaW5nLWxlZnQ6IDE1cHg7XFxyXFxuICAgIHBhZGRpbmctdG9wOiAzMHB4O1xcclxcbn1cXHJcXG5cXHJcXG4uYWNjb3JkaW9uLWJ1dHRvbjphY3RpdmUsIC5hY2NvcmRpb24tYnV0dG9uOm5vdCguY29sbGFwc2VkKSB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXBhbGVncmVlbik7XFxyXFxuICAgIGNvbG9yOiB2YXIoLS1jaXR5Z3JlZW4pO1xcclxcbiAgICAvKiBmb250LXNpemU6IDIwcHg7ICovXFxyXFxufVxcclxcblxcclxcbi5hY2NvcmRpb24tdGFibGUgeyBcXHJcXG4gICAgd2lkdGg6IDEwMCU7XFxyXFxuICAgIGZvbnQtc2l6ZTogMS4yZW07XFxyXFxuICAgIC8qIGJvcmRlci1jb2xsYXBzZTogc2VwYXJhdGU7IFRoaXMgaXMgcmVxdWlyZWQgZm9yIHJvdW5kZWQgY29ybmVycyAqL1xcclxcbn1cXHJcXG5cXHJcXG4uYWNjb3JkaW9uLXRhYmxlIHRkOmxhc3QtY2hpbGQge1xcclxcbiAgICB0ZXh0LWFsaWduOiByaWdodDtcXHJcXG4gICAgcGFkZGluZy1yaWdodDogMTVweDtcXHJcXG4gICAgcGFkZGluZy1ib3R0b206IDVweFxcclxcbn1cXHJcXG5cXHJcXG4uYWNjb3JkaW9uLXRhYmxlIHRyIHtcXHJcXG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIGJsYWNrO1xcclxcbiAgICBib3JkZXItdG9wOiBub25lO1xcclxcbiAgICBib3JkZXItcmlnaHQ6IG5vbmU7XFxyXFxuICAgIGJvcmRlci1sZWZ0OiBub25lO1xcclxcbn1cXHJcXG5cXHJcXG4uYWNjb3JkaW9uLXRhYmxlIHRyOmxhc3QtY2hpbGQge1xcclxcbiAgICBib3JkZXItYm90dG9tOiBub25lO1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1tZWRpdW1HcmF5KTtcXHJcXG4gICAgaGVpZ2h0IDogNTBweDtcXHJcXG59XFxyXFxuXFxyXFxuc3Bhbi5hbW91bnQge1xcclxcbiAgICBmb250LXdlaWdodDogYm9sZDtcXHJcXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbiAgICByaWdodDogMDtcXHJcXG4gICAgbWFyZ2luLXJpZ2h0OiA2MHB4O1xcclxcbn1cXHJcXG5cXHJcXG4uYWNjb3JkaW9uLWhlYWRlciBidXR0b24ge1xcclxcbiAgICBmb250LXNpemU6IDAuOGVtO1xcclxcbn1cXHJcXG5cXHJcXG4uYnRuLWFkZC1pbml0IHtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tc3Bpcml0Z3JlZW4pO1xcclxcbiAgICBib3JkZXItY29sb3I6IHZhcigtLWNpdHlncmVlbik7XFxyXFxuICAgIC8qIHBvc2l0aW9uOiBhYnNvbHV0ZTsgKi9cXHJcXG4gICAgcmlnaHQ6IDA7XFxyXFxuICAgIC8qIG1hcmdpbi1sZWZ0OiAyMHB4OyAqL1xcclxcbiAgICAvKiBtYXJnaW4tcmlnaHQ6IGNhbGMoMjB2dyArIDE1cHgpOyAqL1xcclxcbiAgICBtYXJnaW4tdG9wOiAxNXB4O1xcclxcbn1cXHJcXG5cXHJcXG4jc3VwcC10aXRsZSB7XFxyXFxuICAgbWFyZ2luLXRvcDogMjBweDtcXHJcXG59XFxyXFxuXFxyXFxuLmJ0bi1hZGQtaW5pdDpob3ZlciB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXBhbGVncmVlbik7XFxyXFxufVxcclxcbi5hZGQtaW5pdC1idG4tZGl2e1xcclxcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxufVxcclxcblxcclxcbnNwYW4udG9wLWxpbmUtYW1vdW50IHtcXHJcXG4gICAgZm9udC13ZWlnaHQ6IGJvbGQ7XFxyXFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gICAgcmlnaHQ6IDA7XFxyXFxuICAgIG1hcmdpbi1yaWdodDogY2FsYygyMHZ3ICsgMjBweCk7XFxyXFxufVwiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuLy8gRXhwb3J0c1xuZXhwb3J0IGRlZmF1bHQgX19fQ1NTX0xPQURFUl9FWFBPUlRfX187XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///995\n')},9:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `body {\r\n background-color: var(--lightGray);\r\n margin: 0;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/body/body.css"],"names":[],"mappings":"AAAA;IACI,kCAAkC;IAClC,SAAS;AACb","sourcesContent":["body {\\r\\n background-color: var(--lightGray);\\r\\n margin: 0;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOS5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9ib2R5L2JvZHkuY3NzPzM2ZTAiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYGJvZHkge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tbGlnaHRHcmF5KTtcclxuICAgIG1hcmdpbjogMDtcclxufWAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2pzL2NvbXBvbmVudHMvYm9keS9ib2R5LmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLGtDQUFrQztJQUNsQyxTQUFTO0FBQ2JcIixcInNvdXJjZXNDb250ZW50XCI6W1wiYm9keSB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWxpZ2h0R3JheSk7XFxyXFxuICAgIG1hcmdpbjogMDtcXHJcXG59XCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9\n')},39:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#file-input {\r\n margin-left: 40%;\r\n}\r\n\r\n/* Spinner Styles */\r\n.spinner {\r\n display: inline-block;\r\n width: 150px;\r\n height: 150px;\r\n border: 20px solid rgba(0, 0, 0, 0.1);\r\n border-radius: 50%;\r\n border-top-color: var(--spiritgreen);\r\n animation: spin 1s ease-in-out infinite;\r\n position: fixed; /* Ensures it stays fixed relative to the viewport */\r\n top: 20%; /* Center vertically */\r\n left: 43%; /* Center horizontally */\r\n transform: translate(-50%, -50%); /* Centralize the spinner exactly */\r\n z-index: 9999; /* Ensures it appears in front of other elements */\r\n background-color: rgba(255, 255, 255, 0.8); /* Optional: light background */\r\n padding: 20px; /* Optional: extra padding for better visibility */\r\n }\r\n \r\n @keyframes spin {\r\n 0% {\r\n transform: rotate(0deg);\r\n }\r\n 100% {\r\n transform: rotate(360deg);\r\n }\r\n }`, "",{"version":3,"sources":["webpack://./src/js/components/file_upload/file_upload.css"],"names":[],"mappings":"AAAA;IACI,gBAAgB;AACpB;;AAEA,mBAAmB;AACnB;IACI,qBAAqB;IACrB,YAAY;IACZ,aAAa;IACb,qCAAqC;IACrC,kBAAkB;IAClB,oCAAoC;IACpC,uCAAuC;IACvC,eAAe,EAAE,oDAAoD;IACrE,QAAQ,EAAE,sBAAsB;IAChC,SAAS,EAAE,wBAAwB;IACnC,gCAAgC,EAAE,mCAAmC;IACrE,aAAa,EAAE,kDAAkD;IACjE,0CAA0C,EAAE,+BAA+B;IAC3E,aAAa,EAAE,kDAAkD;EACnE;;EAEA;IACE;MACE,uBAAuB;IACzB;IACA;MACE,yBAAyB;IAC3B;EACF","sourcesContent":["#file-input {\\r\\n margin-left: 40%;\\r\\n}\\r\\n\\r\\n/* Spinner Styles */\\r\\n.spinner {\\r\\n display: inline-block;\\r\\n width: 150px;\\r\\n height: 150px;\\r\\n border: 20px solid rgba(0, 0, 0, 0.1);\\r\\n border-radius: 50%;\\r\\n border-top-color: var(--spiritgreen);\\r\\n animation: spin 1s ease-in-out infinite;\\r\\n position: fixed; /* Ensures it stays fixed relative to the viewport */\\r\\n top: 20%; /* Center vertically */\\r\\n left: 43%; /* Center horizontally */\\r\\n transform: translate(-50%, -50%); /* Centralize the spinner exactly */\\r\\n z-index: 9999; /* Ensures it appears in front of other elements */\\r\\n background-color: rgba(255, 255, 255, 0.8); /* Optional: light background */\\r\\n padding: 20px; /* Optional: extra padding for better visibility */\\r\\n }\\r\\n \\r\\n @keyframes spin {\\r\\n 0% {\\r\\n transform: rotate(0deg);\\r\\n }\\r\\n 100% {\\r\\n transform: rotate(360deg);\\r\\n }\\r\\n }"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2ZpbGVfdXBsb2FkL2ZpbGVfdXBsb2FkLmNzcz9jNTU4Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIEltcG9ydHNcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvc291cmNlTWFwcy5qc1wiO1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL2FwaS5qc1wiO1xudmFyIF9fX0NTU19MT0FERVJfRVhQT1JUX19fID0gX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fKF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18pO1xuLy8gTW9kdWxlXG5fX19DU1NfTE9BREVSX0VYUE9SVF9fXy5wdXNoKFttb2R1bGUuaWQsIGAjZmlsZS1pbnB1dCB7XHJcbiAgICBtYXJnaW4tbGVmdDogNDAlO1xyXG59XHJcblxyXG4vKiBTcGlubmVyIFN0eWxlcyAqL1xyXG4uc3Bpbm5lciB7XHJcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XHJcbiAgICB3aWR0aDogMTUwcHg7XHJcbiAgICBoZWlnaHQ6IDE1MHB4O1xyXG4gICAgYm9yZGVyOiAyMHB4IHNvbGlkIHJnYmEoMCwgMCwgMCwgMC4xKTtcclxuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcclxuICAgIGJvcmRlci10b3AtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIGFuaW1hdGlvbjogc3BpbiAxcyBlYXNlLWluLW91dCBpbmZpbml0ZTtcclxuICAgIHBvc2l0aW9uOiBmaXhlZDsgLyogRW5zdXJlcyBpdCBzdGF5cyBmaXhlZCByZWxhdGl2ZSB0byB0aGUgdmlld3BvcnQgKi9cclxuICAgIHRvcDogMjAlOyAvKiBDZW50ZXIgdmVydGljYWxseSAqL1xyXG4gICAgbGVmdDogNDMlOyAvKiBDZW50ZXIgaG9yaXpvbnRhbGx5ICovXHJcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtNTAlKTsgLyogQ2VudHJhbGl6ZSB0aGUgc3Bpbm5lciBleGFjdGx5ICovXHJcbiAgICB6LWluZGV4OiA5OTk5OyAvKiBFbnN1cmVzIGl0IGFwcGVhcnMgaW4gZnJvbnQgb2Ygb3RoZXIgZWxlbWVudHMgKi9cclxuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC44KTsgLyogT3B0aW9uYWw6IGxpZ2h0IGJhY2tncm91bmQgKi9cclxuICAgIHBhZGRpbmc6IDIwcHg7IC8qIE9wdGlvbmFsOiBleHRyYSBwYWRkaW5nIGZvciBiZXR0ZXIgdmlzaWJpbGl0eSAqL1xyXG4gIH1cclxuICBcclxuICBAa2V5ZnJhbWVzIHNwaW4ge1xyXG4gICAgMCUge1xyXG4gICAgICB0cmFuc2Zvcm06IHJvdGF0ZSgwZGVnKTtcclxuICAgIH1cclxuICAgIDEwMCUge1xyXG4gICAgICB0cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpO1xyXG4gICAgfVxyXG4gIH1gLCBcIlwiLHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIndlYnBhY2s6Ly8uL3NyYy9qcy9jb21wb25lbnRzL2ZpbGVfdXBsb2FkL2ZpbGVfdXBsb2FkLmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLGdCQUFnQjtBQUNwQjs7QUFFQSxtQkFBbUI7QUFDbkI7SUFDSSxxQkFBcUI7SUFDckIsWUFBWTtJQUNaLGFBQWE7SUFDYixxQ0FBcUM7SUFDckMsa0JBQWtCO0lBQ2xCLG9DQUFvQztJQUNwQyx1Q0FBdUM7SUFDdkMsZUFBZSxFQUFFLG9EQUFvRDtJQUNyRSxRQUFRLEVBQUUsc0JBQXNCO0lBQ2hDLFNBQVMsRUFBRSx3QkFBd0I7SUFDbkMsZ0NBQWdDLEVBQUUsbUNBQW1DO0lBQ3JFLGFBQWEsRUFBRSxrREFBa0Q7SUFDakUsMENBQTBDLEVBQUUsK0JBQStCO0lBQzNFLGFBQWEsRUFBRSxrREFBa0Q7RUFDbkU7O0VBRUE7SUFDRTtNQUNFLHVCQUF1QjtJQUN6QjtJQUNBO01BQ0UseUJBQXlCO0lBQzNCO0VBQ0ZcIixcInNvdXJjZXNDb250ZW50XCI6W1wiI2ZpbGUtaW5wdXQge1xcclxcbiAgICBtYXJnaW4tbGVmdDogNDAlO1xcclxcbn1cXHJcXG5cXHJcXG4vKiBTcGlubmVyIFN0eWxlcyAqL1xcclxcbi5zcGlubmVyIHtcXHJcXG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xcclxcbiAgICB3aWR0aDogMTUwcHg7XFxyXFxuICAgIGhlaWdodDogMTUwcHg7XFxyXFxuICAgIGJvcmRlcjogMjBweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMSk7XFxyXFxuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcXHJcXG4gICAgYm9yZGVyLXRvcC1jb2xvcjogdmFyKC0tc3Bpcml0Z3JlZW4pO1xcclxcbiAgICBhbmltYXRpb246IHNwaW4gMXMgZWFzZS1pbi1vdXQgaW5maW5pdGU7XFxyXFxuICAgIHBvc2l0aW9uOiBmaXhlZDsgLyogRW5zdXJlcyBpdCBzdGF5cyBmaXhlZCByZWxhdGl2ZSB0byB0aGUgdmlld3BvcnQgKi9cXHJcXG4gICAgdG9wOiAyMCU7IC8qIENlbnRlciB2ZXJ0aWNhbGx5ICovXFxyXFxuICAgIGxlZnQ6IDQzJTsgLyogQ2VudGVyIGhvcml6b250YWxseSAqL1xcclxcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtNTAlKTsgLyogQ2VudHJhbGl6ZSB0aGUgc3Bpbm5lciBleGFjdGx5ICovXFxyXFxuICAgIHotaW5kZXg6IDk5OTk7IC8qIEVuc3VyZXMgaXQgYXBwZWFycyBpbiBmcm9udCBvZiBvdGhlciBlbGVtZW50cyAqL1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuOCk7IC8qIE9wdGlvbmFsOiBsaWdodCBiYWNrZ3JvdW5kICovXFxyXFxuICAgIHBhZGRpbmc6IDIwcHg7IC8qIE9wdGlvbmFsOiBleHRyYSBwYWRkaW5nIGZvciBiZXR0ZXIgdmlzaWJpbGl0eSAqL1xcclxcbiAgfVxcclxcbiAgXFxyXFxuICBAa2V5ZnJhbWVzIHNwaW4ge1xcclxcbiAgICAwJSB7XFxyXFxuICAgICAgdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7XFxyXFxuICAgIH1cXHJcXG4gICAgMTAwJSB7XFxyXFxuICAgICAgdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTtcXHJcXG4gICAgfVxcclxcbiAgfVwiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuLy8gRXhwb3J0c1xuZXhwb3J0IGRlZmF1bHQgX19fQ1NTX0xPQURFUl9FWFBPUlRfX187XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///39\n')},109:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `textarea {height: 100px; width: 100%;}\r\n\r\ntextarea, input {\r\n margin-bottom: 20px;\r\n}\r\n\r\n.btn-submit {\r\n margin-top: 20px;\r\n width: 60%;\r\n margin-left: 20%;\r\n background-color: var(--spiritgreen);\r\n}\r\n\r\n#new-form label {\r\n display: block; /* Ensure label is on its own line */\r\n margin-bottom: 0.25em; \r\n}\r\n\r\n#new-form select {\r\n min-width: 300px;\r\n margin-bottom: 1.25em;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/form/form.css"],"names":[],"mappings":"AAAA,UAAU,aAAa,EAAE,WAAW,CAAC;;AAErC;IACI,mBAAmB;AACvB;;AAEA;IACI,gBAAgB;IAChB,UAAU;IACV,gBAAgB;IAChB,oCAAoC;AACxC;;AAEA;IACI,cAAc,EAAE,oCAAoC;IACpD,qBAAqB;AACzB;;AAEA;IACI,gBAAgB;IAChB,qBAAqB;AACzB","sourcesContent":["textarea {height: 100px; width: 100%;}\\r\\n\\r\\ntextarea, input {\\r\\n margin-bottom: 20px;\\r\\n}\\r\\n\\r\\n.btn-submit {\\r\\n margin-top: 20px;\\r\\n width: 60%;\\r\\n margin-left: 20%;\\r\\n background-color: var(--spiritgreen);\\r\\n}\\r\\n\\r\\n#new-form label {\\r\\n display: block; /* Ensure label is on its own line */\\r\\n margin-bottom: 0.25em; \\r\\n}\\r\\n\\r\\n#new-form select {\\r\\n min-width: 300px;\\r\\n margin-bottom: 1.25em;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA5LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL2Zvcm0vZm9ybS5jc3M/ZTM4YSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgdGV4dGFyZWEge2hlaWdodDogMTAwcHg7IHdpZHRoOiAxMDAlO31cclxuXHJcbnRleHRhcmVhLCBpbnB1dCB7XHJcbiAgICBtYXJnaW4tYm90dG9tOiAyMHB4O1xyXG59XHJcblxyXG4uYnRuLXN1Ym1pdCB7XHJcbiAgICBtYXJnaW4tdG9wOiAyMHB4O1xyXG4gICAgd2lkdGg6IDYwJTtcclxuICAgIG1hcmdpbi1sZWZ0OiAyMCU7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XHJcbn1cclxuXHJcbiNuZXctZm9ybSBsYWJlbCB7XHJcbiAgICBkaXNwbGF5OiBibG9jazsgLyogRW5zdXJlIGxhYmVsIGlzIG9uIGl0cyBvd24gbGluZSAqL1xyXG4gICAgbWFyZ2luLWJvdHRvbTogMC4yNWVtOyBcclxufVxyXG5cclxuI25ldy1mb3JtIHNlbGVjdCB7XHJcbiAgICBtaW4td2lkdGg6IDMwMHB4O1xyXG4gICAgbWFyZ2luLWJvdHRvbTogMS4yNWVtO1xyXG59YCwgXCJcIix7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCJ3ZWJwYWNrOi8vLi9zcmMvanMvY29tcG9uZW50cy9mb3JtL2Zvcm0uY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBLFVBQVUsYUFBYSxFQUFFLFdBQVcsQ0FBQzs7QUFFckM7SUFDSSxtQkFBbUI7QUFDdkI7O0FBRUE7SUFDSSxnQkFBZ0I7SUFDaEIsVUFBVTtJQUNWLGdCQUFnQjtJQUNoQixvQ0FBb0M7QUFDeEM7O0FBRUE7SUFDSSxjQUFjLEVBQUUsb0NBQW9DO0lBQ3BELHFCQUFxQjtBQUN6Qjs7QUFFQTtJQUNJLGdCQUFnQjtJQUNoQixxQkFBcUI7QUFDekJcIixcInNvdXJjZXNDb250ZW50XCI6W1widGV4dGFyZWEge2hlaWdodDogMTAwcHg7IHdpZHRoOiAxMDAlO31cXHJcXG5cXHJcXG50ZXh0YXJlYSwgaW5wdXQge1xcclxcbiAgICBtYXJnaW4tYm90dG9tOiAyMHB4O1xcclxcbn1cXHJcXG5cXHJcXG4uYnRuLXN1Ym1pdCB7XFxyXFxuICAgIG1hcmdpbi10b3A6IDIwcHg7XFxyXFxuICAgIHdpZHRoOiA2MCU7XFxyXFxuICAgIG1hcmdpbi1sZWZ0OiAyMCU7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcXHJcXG59XFxyXFxuXFxyXFxuI25ldy1mb3JtIGxhYmVsIHtcXHJcXG4gICAgZGlzcGxheTogYmxvY2s7IC8qIEVuc3VyZSBsYWJlbCBpcyBvbiBpdHMgb3duIGxpbmUgKi9cXHJcXG4gICAgbWFyZ2luLWJvdHRvbTogMC4yNWVtOyBcXHJcXG59XFxyXFxuXFxyXFxuI25ldy1mb3JtIHNlbGVjdCB7XFxyXFxuICAgIG1pbi13aWR0aDogMzAwcHg7XFxyXFxuICAgIG1hcmdpbi1ib3R0b206IDEuMjVlbTtcXHJcXG59XCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///109\n')},107:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `\r\nh1 {\r\n text-align: center;\r\n font-size: 30px;\r\n}\r\n\r\nh2 {\r\n color: var(--darkGray);\r\n text-align: center;\r\n font-size: 20px;\r\n}\r\n\r\nheader {\r\n align-items: center;\r\n background-color: white;\r\n padding: 5px;\r\n border-bottom: 1px solid var(--citygreen); \r\n /* border: 1px solid var(--citygreen); */\r\n height: var(--header-height);\r\n /* width: calc(100vw - var(--sidebar-width)); */\r\n padding-left: 20px;\r\n}\r\n\r\n/* Logo styling */\r\n#logo {\r\n height: 50px; /* Or your desired size */\r\n margin-right: 20px; /* Optional: space between logo and title */\r\n margin-bottom: -50px;\r\n margin-top: 10px;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/header/header.css"],"names":[],"mappings":";AACA;IACI,kBAAkB;IAClB,eAAe;AACnB;;AAEA;IACI,sBAAsB;IACtB,kBAAkB;IAClB,eAAe;AACnB;;AAEA;IACI,mBAAmB;IACnB,uBAAuB;IACvB,YAAY;IACZ,yCAAyC;IACzC,yCAAyC;IACzC,4BAA4B;IAC5B,+CAA+C;IAC/C,kBAAkB;AACtB;;AAEA,iBAAiB;AACjB;IACI,YAAY,EAAE,yBAAyB;IACvC,kBAAkB,EAAE,2CAA2C;IAC/D,oBAAoB;IACpB,gBAAgB;AACpB","sourcesContent":["\\r\\nh1 {\\r\\n text-align: center;\\r\\n font-size: 30px;\\r\\n}\\r\\n\\r\\nh2 {\\r\\n color: var(--darkGray);\\r\\n text-align: center;\\r\\n font-size: 20px;\\r\\n}\\r\\n\\r\\nheader {\\r\\n align-items: center;\\r\\n background-color: white;\\r\\n padding: 5px;\\r\\n border-bottom: 1px solid var(--citygreen); \\r\\n /* border: 1px solid var(--citygreen); */\\r\\n height: var(--header-height);\\r\\n /* width: calc(100vw - var(--sidebar-width)); */\\r\\n padding-left: 20px;\\r\\n}\\r\\n\\r\\n/* Logo styling */\\r\\n#logo {\\r\\n height: 50px; /* Or your desired size */\\r\\n margin-right: 20px; /* Optional: space between logo and title */\\r\\n margin-bottom: -50px;\\r\\n margin-top: 10px;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA3LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy9oZWFkZXIvaGVhZGVyLmNzcz8yZjRjIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEltcG9ydHNcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvc291cmNlTWFwcy5qc1wiO1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL2FwaS5qc1wiO1xudmFyIF9fX0NTU19MT0FERVJfRVhQT1JUX19fID0gX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fKF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18pO1xuLy8gTW9kdWxlXG5fX19DU1NfTE9BREVSX0VYUE9SVF9fXy5wdXNoKFttb2R1bGUuaWQsIGBcclxuaDEge1xyXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG4gICAgZm9udC1zaXplOiAzMHB4O1xyXG59XHJcblxyXG5oMiB7XHJcbiAgICBjb2xvcjogdmFyKC0tZGFya0dyYXkpO1xyXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG4gICAgZm9udC1zaXplOiAyMHB4O1xyXG59XHJcblxyXG5oZWFkZXIge1xyXG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xyXG4gICAgcGFkZGluZzogNXB4O1xyXG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWNpdHlncmVlbik7IFxyXG4gICAgLyogYm9yZGVyOiAxcHggc29saWQgdmFyKC0tY2l0eWdyZWVuKTsgICovXHJcbiAgICBoZWlnaHQ6IHZhcigtLWhlYWRlci1oZWlnaHQpO1xyXG4gICAgLyogd2lkdGg6IGNhbGMoMTAwdncgLSB2YXIoLS1zaWRlYmFyLXdpZHRoKSk7ICovXHJcbiAgICBwYWRkaW5nLWxlZnQ6IDIwcHg7XHJcbn1cclxuXHJcbi8qIExvZ28gc3R5bGluZyAqL1xyXG4jbG9nbyB7XHJcbiAgICBoZWlnaHQ6IDUwcHg7IC8qIE9yIHlvdXIgZGVzaXJlZCBzaXplICovXHJcbiAgICBtYXJnaW4tcmlnaHQ6IDIwcHg7IC8qIE9wdGlvbmFsOiBzcGFjZSBiZXR3ZWVuIGxvZ28gYW5kIHRpdGxlICovXHJcbiAgICBtYXJnaW4tYm90dG9tOiAtNTBweDtcclxuICAgIG1hcmdpbi10b3A6IDEwcHg7XHJcbn1gLCBcIlwiLHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIndlYnBhY2s6Ly8uL3NyYy9qcy9jb21wb25lbnRzL2hlYWRlci9oZWFkZXIuY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFDQTtJQUNJLGtCQUFrQjtJQUNsQixlQUFlO0FBQ25COztBQUVBO0lBQ0ksc0JBQXNCO0lBQ3RCLGtCQUFrQjtJQUNsQixlQUFlO0FBQ25COztBQUVBO0lBQ0ksbUJBQW1CO0lBQ25CLHVCQUF1QjtJQUN2QixZQUFZO0lBQ1oseUNBQXlDO0lBQ3pDLHlDQUF5QztJQUN6Qyw0QkFBNEI7SUFDNUIsK0NBQStDO0lBQy9DLGtCQUFrQjtBQUN0Qjs7QUFFQSxpQkFBaUI7QUFDakI7SUFDSSxZQUFZLEVBQUUseUJBQXlCO0lBQ3ZDLGtCQUFrQixFQUFFLDJDQUEyQztJQUMvRCxvQkFBb0I7SUFDcEIsZ0JBQWdCO0FBQ3BCXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIlxcclxcbmgxIHtcXHJcXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xcclxcbiAgICBmb250LXNpemU6IDMwcHg7XFxyXFxufVxcclxcblxcclxcbmgyIHtcXHJcXG4gICAgY29sb3I6IHZhcigtLWRhcmtHcmF5KTtcXHJcXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xcclxcbiAgICBmb250LXNpemU6IDIwcHg7XFxyXFxufVxcclxcblxcclxcbmhlYWRlciB7XFxyXFxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xcclxcbiAgICBwYWRkaW5nOiA1cHg7XFxyXFxuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1jaXR5Z3JlZW4pOyBcXHJcXG4gICAgLyogYm9yZGVyOiAxcHggc29saWQgdmFyKC0tY2l0eWdyZWVuKTsgICovXFxyXFxuICAgIGhlaWdodDogdmFyKC0taGVhZGVyLWhlaWdodCk7XFxyXFxuICAgIC8qIHdpZHRoOiBjYWxjKDEwMHZ3IC0gdmFyKC0tc2lkZWJhci13aWR0aCkpOyAqL1xcclxcbiAgICBwYWRkaW5nLWxlZnQ6IDIwcHg7XFxyXFxufVxcclxcblxcclxcbi8qIExvZ28gc3R5bGluZyAqL1xcclxcbiNsb2dvIHtcXHJcXG4gICAgaGVpZ2h0OiA1MHB4OyAvKiBPciB5b3VyIGRlc2lyZWQgc2l6ZSAqL1xcclxcbiAgICBtYXJnaW4tcmlnaHQ6IDIwcHg7IC8qIE9wdGlvbmFsOiBzcGFjZSBiZXR3ZWVuIGxvZ28gYW5kIHRpdGxlICovXFxyXFxuICAgIG1hcmdpbi1ib3R0b206IC01MHB4O1xcclxcbiAgICBtYXJnaW4tdG9wOiAxMHB4O1xcclxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcbi8vIEV4cG9ydHNcbmV4cG9ydCBkZWZhdWx0IF9fX0NTU19MT0FERVJfRVhQT1JUX19fO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///107\n')},95:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, ``, "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvbW9kYWwvbW9kYWwuY3NzPzZhY2QiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYGAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W10sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIlwiLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///95\n')},595:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#nav-btns {\r\n margin: 20px;\r\n text-align: center;\r\n margin-top: 5px;\r\n margin-bottom: 5px;\r\n /* position: absolute; or \'absolute\' depending on use-case */\r\n /* top: 100px; Distance from the top of the viewport or the closest positioned ancestor */\r\n}\r\n\r\n#btn-next, #btn-last {\r\n background-color: var(--darkGray);\r\n}\r\n\r\n#btn-next:hover, #btn-last:hover {\r\n background-color: var(--yellow);\r\n color: var(--darkGray);\r\n}\r\n\r\n/* Add style for when you cannot click the next button */\r\n#btn-next.disabled, #btn-last.disabled,\r\n#btn-next.disabled:hover, #btn-last.disabled:hover {\r\n background-color: gray;\r\n color: white;\r\n pointer-events: none;\r\n \r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/nav_buttons/nav_buttons.css"],"names":[],"mappings":"AAAA;IACI,YAAY;IACZ,kBAAkB;IAClB,eAAe;IACf,kBAAkB;IAClB,4DAA4D;IAC5D,yFAAyF;AAC7F;;AAEA;IACI,iCAAiC;AACrC;;AAEA;IACI,+BAA+B;IAC/B,sBAAsB;AAC1B;;AAEA,wDAAwD;AACxD;;IAEI,sBAAsB;IACtB,YAAY;IACZ,oBAAoB;;AAExB","sourcesContent":["#nav-btns {\\r\\n margin: 20px;\\r\\n text-align: center;\\r\\n margin-top: 5px;\\r\\n margin-bottom: 5px;\\r\\n /* position: absolute; or \'absolute\' depending on use-case */\\r\\n /* top: 100px; Distance from the top of the viewport or the closest positioned ancestor */\\r\\n}\\r\\n\\r\\n#btn-next, #btn-last {\\r\\n background-color: var(--darkGray);\\r\\n}\\r\\n\\r\\n#btn-next:hover, #btn-last:hover {\\r\\n background-color: var(--yellow);\\r\\n color: var(--darkGray);\\r\\n}\\r\\n\\r\\n/* Add style for when you cannot click the next button */\\r\\n#btn-next.disabled, #btn-last.disabled,\\r\\n#btn-next.disabled:hover, #btn-last.disabled:hover {\\r\\n background-color: gray;\\r\\n color: white;\\r\\n pointer-events: none;\\r\\n \\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTk1LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vc3JjL2pzL2NvbXBvbmVudHMvbmF2X2J1dHRvbnMvbmF2X2J1dHRvbnMuY3NzPzkwNWQiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYCNuYXYtYnRucyB7XHJcbiAgICBtYXJnaW46IDIwcHg7XHJcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XHJcbiAgICBtYXJnaW4tdG9wOiA1cHg7XHJcbiAgICBtYXJnaW4tYm90dG9tOiA1cHg7XHJcbiAgICAvKiBwb3NpdGlvbjogYWJzb2x1dGU7IG9yICdhYnNvbHV0ZScgZGVwZW5kaW5nIG9uIHVzZS1jYXNlICovXHJcbiAgICAvKiB0b3A6IDEwMHB4OyBEaXN0YW5jZSBmcm9tIHRoZSB0b3Agb2YgdGhlIHZpZXdwb3J0IG9yIHRoZSBjbG9zZXN0IHBvc2l0aW9uZWQgYW5jZXN0b3IgKi9cclxufVxyXG5cclxuI2J0bi1uZXh0LCAjYnRuLWxhc3Qge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tZGFya0dyYXkpO1xyXG59XHJcblxyXG4jYnRuLW5leHQ6aG92ZXIsICNidG4tbGFzdDpob3ZlciB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS15ZWxsb3cpO1xyXG4gICAgY29sb3I6IHZhcigtLWRhcmtHcmF5KTtcclxufVxyXG5cclxuLyogQWRkIHN0eWxlIGZvciB3aGVuIHlvdSBjYW5ub3QgY2xpY2sgdGhlIG5leHQgYnV0dG9uICovXHJcbiNidG4tbmV4dC5kaXNhYmxlZCwgI2J0bi1sYXN0LmRpc2FibGVkLFxyXG4jYnRuLW5leHQuZGlzYWJsZWQ6aG92ZXIsICNidG4tbGFzdC5kaXNhYmxlZDpob3ZlciB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiBncmF5O1xyXG4gICAgY29sb3I6IHdoaXRlO1xyXG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XHJcbiAgICBcclxufWAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2pzL2NvbXBvbmVudHMvbmF2X2J1dHRvbnMvbmF2X2J1dHRvbnMuY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0lBQ0ksWUFBWTtJQUNaLGtCQUFrQjtJQUNsQixlQUFlO0lBQ2Ysa0JBQWtCO0lBQ2xCLDREQUE0RDtJQUM1RCx5RkFBeUY7QUFDN0Y7O0FBRUE7SUFDSSxpQ0FBaUM7QUFDckM7O0FBRUE7SUFDSSwrQkFBK0I7SUFDL0Isc0JBQXNCO0FBQzFCOztBQUVBLHdEQUF3RDtBQUN4RDs7SUFFSSxzQkFBc0I7SUFDdEIsWUFBWTtJQUNaLG9CQUFvQjs7QUFFeEJcIixcInNvdXJjZXNDb250ZW50XCI6W1wiI25hdi1idG5zIHtcXHJcXG4gICAgbWFyZ2luOiAyMHB4O1xcclxcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxuICAgIG1hcmdpbi10b3A6IDVweDtcXHJcXG4gICAgbWFyZ2luLWJvdHRvbTogNXB4O1xcclxcbiAgICAvKiBwb3NpdGlvbjogYWJzb2x1dGU7IG9yICdhYnNvbHV0ZScgZGVwZW5kaW5nIG9uIHVzZS1jYXNlICovXFxyXFxuICAgIC8qIHRvcDogMTAwcHg7IERpc3RhbmNlIGZyb20gdGhlIHRvcCBvZiB0aGUgdmlld3BvcnQgb3IgdGhlIGNsb3Nlc3QgcG9zaXRpb25lZCBhbmNlc3RvciAqL1xcclxcbn1cXHJcXG5cXHJcXG4jYnRuLW5leHQsICNidG4tbGFzdCB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRhcmtHcmF5KTtcXHJcXG59XFxyXFxuXFxyXFxuI2J0bi1uZXh0OmhvdmVyLCAjYnRuLWxhc3Q6aG92ZXIge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS15ZWxsb3cpO1xcclxcbiAgICBjb2xvcjogdmFyKC0tZGFya0dyYXkpO1xcclxcbn1cXHJcXG5cXHJcXG4vKiBBZGQgc3R5bGUgZm9yIHdoZW4geW91IGNhbm5vdCBjbGljayB0aGUgbmV4dCBidXR0b24gKi9cXHJcXG4jYnRuLW5leHQuZGlzYWJsZWQsICNidG4tbGFzdC5kaXNhYmxlZCxcXHJcXG4jYnRuLW5leHQuZGlzYWJsZWQ6aG92ZXIsICNidG4tbGFzdC5kaXNhYmxlZDpob3ZlciB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IGdyYXk7XFxyXFxuICAgIGNvbG9yOiB3aGl0ZTtcXHJcXG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxyXFxuICAgIFxcclxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcbi8vIEV4cG9ydHNcbmV4cG9ydCBkZWZhdWx0IF9fX0NTU19MT0FERVJfRVhQT1JUX19fO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///595\n')},225:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `div#prompt-div {\r\n display: none;\r\n width: 80%;\r\n margin: auto;\r\n text-align: center;\r\n}\r\n\r\nh3#prompt {\r\n text-align: center;\r\n font-size : 1.2em;\r\n}\r\n\r\n#option1, #option2 { \r\n font-size: 1.5em;\r\n border-color: var(--citygreen); \r\n border-width: 2px;\r\n background-color: var(--white);\r\n color: var(--citygreen);\r\n}\r\n\r\n#option1:hover, #option2:hover { \r\n background-color: var(--spiritgreen);\r\n color: white;\r\n}\r\n\r\n#option2.clicked, #option1.clicked {\r\n font-weight: bold;\r\n background-color: var(--spiritgreen);\r\n color: white;\r\n border-width: 3;\r\n}\r\n\r\n#option1.disabled, #option2.disabled, #option1.disabled:hover, #option2.disabled:hover {\r\n background-color: lightgray;\r\n color: gray;\r\n pointer-events: none;\r\n border-color: gray;\r\n}\r\n\r\n`, "",{"version":3,"sources":["webpack://./src/js/components/prompt/prompt.css"],"names":[],"mappings":"AAAA;IACI,aAAa;IACb,UAAU;IACV,YAAY;IACZ,kBAAkB;AACtB;;AAEA;IACI,kBAAkB;IAClB,iBAAiB;AACrB;;AAEA;IACI,gBAAgB;IAChB,8BAA8B;IAC9B,iBAAiB;IACjB,8BAA8B;IAC9B,uBAAuB;AAC3B;;AAEA;IACI,oCAAoC;IACpC,YAAY;AAChB;;AAEA;IACI,iBAAiB;IACjB,oCAAoC;IACpC,YAAY;IACZ,eAAe;AACnB;;AAEA;IACI,2BAA2B;IAC3B,WAAW;IACX,oBAAoB;IACpB,kBAAkB;AACtB","sourcesContent":["div#prompt-div {\\r\\n display: none;\\r\\n width: 80%;\\r\\n margin: auto;\\r\\n text-align: center;\\r\\n}\\r\\n\\r\\nh3#prompt {\\r\\n text-align: center;\\r\\n font-size : 1.2em;\\r\\n}\\r\\n\\r\\n#option1, #option2 { \\r\\n font-size: 1.5em;\\r\\n border-color: var(--citygreen); \\r\\n border-width: 2px;\\r\\n background-color: var(--white);\\r\\n color: var(--citygreen);\\r\\n}\\r\\n\\r\\n#option1:hover, #option2:hover { \\r\\n background-color: var(--spiritgreen);\\r\\n color: white;\\r\\n}\\r\\n\\r\\n#option2.clicked, #option1.clicked {\\r\\n font-weight: bold;\\r\\n background-color: var(--spiritgreen);\\r\\n color: white;\\r\\n border-width: 3;\\r\\n}\\r\\n\\r\\n#option1.disabled, #option2.disabled, #option1.disabled:hover, #option2.disabled:hover {\\r\\n background-color: lightgray;\\r\\n color: gray;\\r\\n pointer-events: none;\\r\\n border-color: gray;\\r\\n}\\r\\n\\r\\n"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjI1LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3Byb21wdC9wcm9tcHQuY3NzP2U2OTkiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYGRpdiNwcm9tcHQtZGl2IHtcclxuICAgIGRpc3BsYXk6IG5vbmU7XHJcbiAgICB3aWR0aDogODAlO1xyXG4gICAgbWFyZ2luOiBhdXRvO1xyXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG59XHJcblxyXG5oMyNwcm9tcHQge1xyXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG4gICAgZm9udC1zaXplIDogMS4yZW07XHJcbn1cclxuXHJcbiNvcHRpb24xLCAjb3B0aW9uMiB7IFxyXG4gICAgZm9udC1zaXplOiAxLjVlbTtcclxuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tY2l0eWdyZWVuKTsgXHJcbiAgICBib3JkZXItd2lkdGg6IDJweDtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXdoaXRlKTtcclxuICAgIGNvbG9yOiB2YXIoLS1jaXR5Z3JlZW4pO1xyXG59XHJcblxyXG4jb3B0aW9uMTpob3ZlciwgI29wdGlvbjI6aG92ZXIgeyBcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIGNvbG9yOiB3aGl0ZTtcclxufVxyXG5cclxuI29wdGlvbjIuY2xpY2tlZCwgI29wdGlvbjEuY2xpY2tlZCB7XHJcbiAgICBmb250LXdlaWdodDogYm9sZDtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIGNvbG9yOiB3aGl0ZTtcclxuICAgIGJvcmRlci13aWR0aDogMztcclxufVxyXG5cclxuI29wdGlvbjEuZGlzYWJsZWQsICNvcHRpb24yLmRpc2FibGVkLCAjb3B0aW9uMS5kaXNhYmxlZDpob3ZlciwgI29wdGlvbjIuZGlzYWJsZWQ6aG92ZXIge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogbGlnaHRncmF5O1xyXG4gICAgY29sb3I6IGdyYXk7XHJcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcclxuICAgIGJvcmRlci1jb2xvcjogZ3JheTtcclxufVxyXG5cclxuYCwgXCJcIix7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCJ3ZWJwYWNrOi8vLi9zcmMvanMvY29tcG9uZW50cy9wcm9tcHQvcHJvbXB0LmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLGFBQWE7SUFDYixVQUFVO0lBQ1YsWUFBWTtJQUNaLGtCQUFrQjtBQUN0Qjs7QUFFQTtJQUNJLGtCQUFrQjtJQUNsQixpQkFBaUI7QUFDckI7O0FBRUE7SUFDSSxnQkFBZ0I7SUFDaEIsOEJBQThCO0lBQzlCLGlCQUFpQjtJQUNqQiw4QkFBOEI7SUFDOUIsdUJBQXVCO0FBQzNCOztBQUVBO0lBQ0ksb0NBQW9DO0lBQ3BDLFlBQVk7QUFDaEI7O0FBRUE7SUFDSSxpQkFBaUI7SUFDakIsb0NBQW9DO0lBQ3BDLFlBQVk7SUFDWixlQUFlO0FBQ25COztBQUVBO0lBQ0ksMkJBQTJCO0lBQzNCLFdBQVc7SUFDWCxvQkFBb0I7SUFDcEIsa0JBQWtCO0FBQ3RCXCIsXCJzb3VyY2VzQ29udGVudFwiOltcImRpdiNwcm9tcHQtZGl2IHtcXHJcXG4gICAgZGlzcGxheTogbm9uZTtcXHJcXG4gICAgd2lkdGg6IDgwJTtcXHJcXG4gICAgbWFyZ2luOiBhdXRvO1xcclxcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxufVxcclxcblxcclxcbmgzI3Byb21wdCB7XFxyXFxuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcXHJcXG4gICAgZm9udC1zaXplIDogMS4yZW07XFxyXFxufVxcclxcblxcclxcbiNvcHRpb24xLCAjb3B0aW9uMiB7IFxcclxcbiAgICBmb250LXNpemU6IDEuNWVtO1xcclxcbiAgICBib3JkZXItY29sb3I6IHZhcigtLWNpdHlncmVlbik7IFxcclxcbiAgICBib3JkZXItd2lkdGg6IDJweDtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0td2hpdGUpO1xcclxcbiAgICBjb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcXHJcXG59XFxyXFxuXFxyXFxuI29wdGlvbjE6aG92ZXIsICNvcHRpb24yOmhvdmVyIHsgXFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcXHJcXG4gICAgY29sb3I6IHdoaXRlO1xcclxcbn1cXHJcXG5cXHJcXG4jb3B0aW9uMi5jbGlja2VkLCAjb3B0aW9uMS5jbGlja2VkIHtcXHJcXG4gICAgZm9udC13ZWlnaHQ6IGJvbGQ7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcXHJcXG4gICAgY29sb3I6IHdoaXRlO1xcclxcbiAgICBib3JkZXItd2lkdGg6IDM7XFxyXFxufVxcclxcblxcclxcbiNvcHRpb24xLmRpc2FibGVkLCAjb3B0aW9uMi5kaXNhYmxlZCwgI29wdGlvbjEuZGlzYWJsZWQ6aG92ZXIsICNvcHRpb24yLmRpc2FibGVkOmhvdmVyIHtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogbGlnaHRncmF5O1xcclxcbiAgICBjb2xvcjogZ3JheTtcXHJcXG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxyXFxuICAgIGJvcmRlci1jb2xvcjogZ3JheTtcXHJcXG59XFxyXFxuXFxyXFxuXCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///225\n')},263:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#sidebar-panel {\r\n background-color: lightgrey; \r\n /* min-height: 100vh; Full height of viewport */\r\n }\r\n\r\n#supp-total .stat {\r\n color: var(--yellow);\r\n}\r\n\r\n.stat {\r\n font-weight: bold;\r\n}\r\n\r\n#sidebar-panel {\r\n height: 100%; /* Full height of the viewport */\r\n position: fixed; /* Fixed Sidebar (stay in place on scroll) */\r\n z-index: 1; /* Stay on top */\r\n top: 0; /* Stay at the top */\r\n right: 0; /* Sidebar appears on the left */\r\n background-color: #FFFFFF; /* White background color */\r\n overflow-x: hidden; /* Disable horizontal scroll */\r\n padding: 20px;\r\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* Add shadow for some depth */\r\n border-right: 2px solid #DDDDDD; /* Right border */\r\n border-radius: 0px 0px 0px 15px; /* Rounded corners on the left */\r\n /* margin-top: var(--header-height); */\r\n width: var(--sidebar-width);\r\n margin: 0px;\r\n }\r\n \r\n.sidebar a {\r\n padding: 10px 15px;\r\n text-decoration: none;\r\n font-size: 18px;\r\n color: #818181;\r\n display: block;\r\n transition: 0.3s;\r\n}\r\n\r\n#sidebar-title {\r\n color: var(--darkGray);\r\n font-weight: bold;\r\n border-bottom: 1px solid var(--citygreen);\r\n}\r\n\r\nhr {\r\n margin-top: -5px;\r\n margin-bottom: 8px;\r\n}\r\n\r\nh6 {\r\n font-weight: 600;\r\n}\r\n\r\n.section-header {\r\n background-color: var(--mediumGray);\r\n}\r\n\r\n.sidebar-stat-line {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between; /* Distribute space between children */\r\n padding: 2px;\r\n border-bottom: 1px solid #ddd;\r\n}\r\n\r\n.edit-icon, .edit-supp {\r\n color: var(--spiritgreen);\r\n cursor: pointer;\r\n font-size: 16px; /* Adjust the size as needed */\r\n margin-left: 10px;\r\n}\r\n\r\n.edit-icon:hover .edit-supp:hover {\r\n color: var(--citygreen);\r\n}\r\n\r\n.stat-label {\r\n margin-right: auto; /* Push next elements to the right */\r\n}\r\n\r\n.stat {\r\n margin-left: 5px; /* Optional: Add some space between currency and edit icon */\r\n}\r\n\r\n.sidebar-stat-line.fund-total .stat {\r\n margin-right: 05px; /* 25px lines up with lines above (with edit symbol) */\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/sidebar/sidebar.css"],"names":[],"mappings":"AAAA;IACI,2BAA2B;IAC3B,+CAA+C;EACjD;;AAEF;IACI,oBAAoB;AACxB;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,YAAY,EAAE,gCAAgC;IAC9C,eAAe,EAAE,4CAA4C;IAC7D,UAAU,EAAE,gBAAgB;IAC5B,MAAM,EAAE,oBAAoB;IAC5B,QAAQ,EAAE,gCAAgC;IAC1C,yBAAyB,EAAE,2BAA2B;IACtD,kBAAkB,EAAE,8BAA8B;IAClD,aAAa;IACb,wCAAwC,EAAE,8BAA8B;IACxE,+BAA+B,EAAE,iBAAiB;IAClD,+BAA+B,EAAE,gCAAgC;IACjE,sCAAsC;IACtC,2BAA2B;IAC3B,WAAW;EACb;;AAEF;IACI,kBAAkB;IAClB,qBAAqB;IACrB,eAAe;IACf,cAAc;IACd,cAAc;IACd,gBAAgB;AACpB;;AAEA;EACE,sBAAsB;EACtB,iBAAiB;EACjB,yCAAyC;AAC3C;;AAEA;EACE,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,8BAA8B,EAAE,sCAAsC;EACtE,YAAY;EACZ,6BAA6B;AAC/B;;AAEA;EACE,yBAAyB;EACzB,eAAe;EACf,eAAe,EAAE,8BAA8B;EAC/C,iBAAiB;AACnB;;AAEA;EACE,uBAAuB;AACzB;;AAEA;EACE,kBAAkB,EAAE,oCAAoC;AAC1D;;AAEA;EACE,gBAAgB,EAAE,4DAA4D;AAChF;;AAEA;EACE,kBAAkB,EAAE,sDAAsD;AAC5E","sourcesContent":["#sidebar-panel {\\r\\n background-color: lightgrey; \\r\\n /* min-height: 100vh; Full height of viewport */\\r\\n }\\r\\n\\r\\n#supp-total .stat {\\r\\n color: var(--yellow);\\r\\n}\\r\\n\\r\\n.stat {\\r\\n font-weight: bold;\\r\\n}\\r\\n\\r\\n#sidebar-panel {\\r\\n height: 100%; /* Full height of the viewport */\\r\\n position: fixed; /* Fixed Sidebar (stay in place on scroll) */\\r\\n z-index: 1; /* Stay on top */\\r\\n top: 0; /* Stay at the top */\\r\\n right: 0; /* Sidebar appears on the left */\\r\\n background-color: #FFFFFF; /* White background color */\\r\\n overflow-x: hidden; /* Disable horizontal scroll */\\r\\n padding: 20px;\\r\\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* Add shadow for some depth */\\r\\n border-right: 2px solid #DDDDDD; /* Right border */\\r\\n border-radius: 0px 0px 0px 15px; /* Rounded corners on the left */\\r\\n /* margin-top: var(--header-height); */\\r\\n width: var(--sidebar-width);\\r\\n margin: 0px;\\r\\n }\\r\\n \\r\\n.sidebar a {\\r\\n padding: 10px 15px;\\r\\n text-decoration: none;\\r\\n font-size: 18px;\\r\\n color: #818181;\\r\\n display: block;\\r\\n transition: 0.3s;\\r\\n}\\r\\n\\r\\n#sidebar-title {\\r\\n color: var(--darkGray);\\r\\n font-weight: bold;\\r\\n border-bottom: 1px solid var(--citygreen);\\r\\n}\\r\\n\\r\\nhr {\\r\\n margin-top: -5px;\\r\\n margin-bottom: 8px;\\r\\n}\\r\\n\\r\\nh6 {\\r\\n font-weight: 600;\\r\\n}\\r\\n\\r\\n.section-header {\\r\\n background-color: var(--mediumGray);\\r\\n}\\r\\n\\r\\n.sidebar-stat-line {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between; /* Distribute space between children */\\r\\n padding: 2px;\\r\\n border-bottom: 1px solid #ddd;\\r\\n}\\r\\n\\r\\n.edit-icon, .edit-supp {\\r\\n color: var(--spiritgreen);\\r\\n cursor: pointer;\\r\\n font-size: 16px; /* Adjust the size as needed */\\r\\n margin-left: 10px;\\r\\n}\\r\\n\\r\\n.edit-icon:hover .edit-supp:hover {\\r\\n color: var(--citygreen);\\r\\n}\\r\\n\\r\\n.stat-label {\\r\\n margin-right: auto; /* Push next elements to the right */\\r\\n}\\r\\n\\r\\n.stat {\\r\\n margin-left: 5px; /* Optional: Add some space between currency and edit icon */\\r\\n}\\r\\n\\r\\n.sidebar-stat-line.fund-total .stat {\\r\\n margin-right: 05px; /* 25px lines up with lines above (with edit symbol) */\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjYzLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3NpZGViYXIvc2lkZWJhci5jc3M/M2IwMyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgI3NpZGViYXItcGFuZWwge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogbGlnaHRncmV5OyAgXHJcbiAgICAvKiBtaW4taGVpZ2h0OiAxMDB2aDsgRnVsbCBoZWlnaHQgb2Ygdmlld3BvcnQgKi9cclxuICB9XHJcblxyXG4jc3VwcC10b3RhbCAuc3RhdCB7XHJcbiAgICBjb2xvcjogdmFyKC0teWVsbG93KTtcclxufVxyXG5cclxuLnN0YXQge1xyXG4gICAgZm9udC13ZWlnaHQ6IGJvbGQ7XHJcbn1cclxuXHJcbiNzaWRlYmFyLXBhbmVsIHtcclxuICAgIGhlaWdodDogMTAwJTsgLyogRnVsbCBoZWlnaHQgb2YgdGhlIHZpZXdwb3J0ICovXHJcbiAgICBwb3NpdGlvbjogZml4ZWQ7IC8qIEZpeGVkIFNpZGViYXIgKHN0YXkgaW4gcGxhY2Ugb24gc2Nyb2xsKSAqL1xyXG4gICAgei1pbmRleDogMTsgLyogU3RheSBvbiB0b3AgKi9cclxuICAgIHRvcDogMDsgLyogU3RheSBhdCB0aGUgdG9wICovXHJcbiAgICByaWdodDogMDsgLyogU2lkZWJhciBhcHBlYXJzIG9uIHRoZSBsZWZ0ICovXHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjRkZGRkZGOyAvKiBXaGl0ZSBiYWNrZ3JvdW5kIGNvbG9yICovXHJcbiAgICBvdmVyZmxvdy14OiBoaWRkZW47IC8qIERpc2FibGUgaG9yaXpvbnRhbCBzY3JvbGwgKi9cclxuICAgIHBhZGRpbmc6IDIwcHg7XHJcbiAgICBib3gtc2hhZG93OiAwIDJweCA1cHggcmdiYSgwLCAwLCAwLCAwLjEpOyAvKiBBZGQgc2hhZG93IGZvciBzb21lIGRlcHRoICovXHJcbiAgICBib3JkZXItcmlnaHQ6IDJweCBzb2xpZCAjREREREREOyAvKiBSaWdodCBib3JkZXIgKi9cclxuICAgIGJvcmRlci1yYWRpdXM6IDBweCAwcHggMHB4IDE1cHg7IC8qIFJvdW5kZWQgY29ybmVycyBvbiB0aGUgbGVmdCAqL1xyXG4gICAgLyogbWFyZ2luLXRvcDogdmFyKC0taGVhZGVyLWhlaWdodCk7ICovXHJcbiAgICB3aWR0aDogdmFyKC0tc2lkZWJhci13aWR0aCk7XHJcbiAgICBtYXJnaW46IDBweDtcclxuICB9XHJcbiAgXHJcbi5zaWRlYmFyIGEge1xyXG4gICAgcGFkZGluZzogMTBweCAxNXB4O1xyXG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xyXG4gICAgZm9udC1zaXplOiAxOHB4O1xyXG4gICAgY29sb3I6ICM4MTgxODE7XHJcbiAgICBkaXNwbGF5OiBibG9jaztcclxuICAgIHRyYW5zaXRpb246IDAuM3M7XHJcbn1cclxuXHJcbiNzaWRlYmFyLXRpdGxlIHtcclxuICBjb2xvcjogdmFyKC0tZGFya0dyYXkpO1xyXG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xyXG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1jaXR5Z3JlZW4pO1xyXG59XHJcblxyXG5ociB7XHJcbiAgbWFyZ2luLXRvcDogLTVweDtcclxuICBtYXJnaW4tYm90dG9tOiA4cHg7XHJcbn1cclxuXHJcbmg2IHtcclxuICBmb250LXdlaWdodDogNjAwO1xyXG59XHJcblxyXG4uc2VjdGlvbi1oZWFkZXIge1xyXG4gIGJhY2tncm91bmQtY29sb3I6IHZhcigtLW1lZGl1bUdyYXkpO1xyXG59XHJcblxyXG4uc2lkZWJhci1zdGF0LWxpbmUge1xyXG4gIGRpc3BsYXk6IGZsZXg7XHJcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IC8qIERpc3RyaWJ1dGUgc3BhY2UgYmV0d2VlbiBjaGlsZHJlbiAqL1xyXG4gIHBhZGRpbmc6IDJweDtcclxuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2RkZDtcclxufVxyXG5cclxuLmVkaXQtaWNvbiwgLmVkaXQtc3VwcCB7XHJcbiAgY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICBjdXJzb3I6IHBvaW50ZXI7XHJcbiAgZm9udC1zaXplOiAxNnB4OyAvKiBBZGp1c3QgdGhlIHNpemUgYXMgbmVlZGVkICovXHJcbiAgbWFyZ2luLWxlZnQ6IDEwcHg7XHJcbn1cclxuXHJcbi5lZGl0LWljb246aG92ZXIgLmVkaXQtc3VwcDpob3ZlciB7XHJcbiAgY29sb3I6IHZhcigtLWNpdHlncmVlbik7XHJcbn1cclxuXHJcbi5zdGF0LWxhYmVsIHtcclxuICBtYXJnaW4tcmlnaHQ6IGF1dG87IC8qIFB1c2ggbmV4dCBlbGVtZW50cyB0byB0aGUgcmlnaHQgKi9cclxufVxyXG5cclxuLnN0YXQge1xyXG4gIG1hcmdpbi1sZWZ0OiA1cHg7IC8qIE9wdGlvbmFsOiBBZGQgc29tZSBzcGFjZSBiZXR3ZWVuIGN1cnJlbmN5IGFuZCBlZGl0IGljb24gKi9cclxufVxyXG5cclxuLnNpZGViYXItc3RhdC1saW5lLmZ1bmQtdG90YWwgLnN0YXQge1xyXG4gIG1hcmdpbi1yaWdodDogMDVweDsgLyogMjVweCBsaW5lcyB1cCB3aXRoIGxpbmVzIGFib3ZlICh3aXRoIGVkaXQgc3ltYm9sKSAqL1xyXG59YCwgXCJcIix7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCJ3ZWJwYWNrOi8vLi9zcmMvanMvY29tcG9uZW50cy9zaWRlYmFyL3NpZGViYXIuY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0lBQ0ksMkJBQTJCO0lBQzNCLCtDQUErQztFQUNqRDs7QUFFRjtJQUNJLG9CQUFvQjtBQUN4Qjs7QUFFQTtJQUNJLGlCQUFpQjtBQUNyQjs7QUFFQTtJQUNJLFlBQVksRUFBRSxnQ0FBZ0M7SUFDOUMsZUFBZSxFQUFFLDRDQUE0QztJQUM3RCxVQUFVLEVBQUUsZ0JBQWdCO0lBQzVCLE1BQU0sRUFBRSxvQkFBb0I7SUFDNUIsUUFBUSxFQUFFLGdDQUFnQztJQUMxQyx5QkFBeUIsRUFBRSwyQkFBMkI7SUFDdEQsa0JBQWtCLEVBQUUsOEJBQThCO0lBQ2xELGFBQWE7SUFDYix3Q0FBd0MsRUFBRSw4QkFBOEI7SUFDeEUsK0JBQStCLEVBQUUsaUJBQWlCO0lBQ2xELCtCQUErQixFQUFFLGdDQUFnQztJQUNqRSxzQ0FBc0M7SUFDdEMsMkJBQTJCO0lBQzNCLFdBQVc7RUFDYjs7QUFFRjtJQUNJLGtCQUFrQjtJQUNsQixxQkFBcUI7SUFDckIsZUFBZTtJQUNmLGNBQWM7SUFDZCxjQUFjO0lBQ2QsZ0JBQWdCO0FBQ3BCOztBQUVBO0VBQ0Usc0JBQXNCO0VBQ3RCLGlCQUFpQjtFQUNqQix5Q0FBeUM7QUFDM0M7O0FBRUE7RUFDRSxnQkFBZ0I7RUFDaEIsa0JBQWtCO0FBQ3BCOztBQUVBO0VBQ0UsZ0JBQWdCO0FBQ2xCOztBQUVBO0VBQ0UsbUNBQW1DO0FBQ3JDOztBQUVBO0VBQ0UsYUFBYTtFQUNiLG1CQUFtQjtFQUNuQiw4QkFBOEIsRUFBRSxzQ0FBc0M7RUFDdEUsWUFBWTtFQUNaLDZCQUE2QjtBQUMvQjs7QUFFQTtFQUNFLHlCQUF5QjtFQUN6QixlQUFlO0VBQ2YsZUFBZSxFQUFFLDhCQUE4QjtFQUMvQyxpQkFBaUI7QUFDbkI7O0FBRUE7RUFDRSx1QkFBdUI7QUFDekI7O0FBRUE7RUFDRSxrQkFBa0IsRUFBRSxvQ0FBb0M7QUFDMUQ7O0FBRUE7RUFDRSxnQkFBZ0IsRUFBRSw0REFBNEQ7QUFDaEY7O0FBRUE7RUFDRSxrQkFBa0IsRUFBRSxzREFBc0Q7QUFDNUVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiI3NpZGViYXItcGFuZWwge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiBsaWdodGdyZXk7ICBcXHJcXG4gICAgLyogbWluLWhlaWdodDogMTAwdmg7IEZ1bGwgaGVpZ2h0IG9mIHZpZXdwb3J0ICovXFxyXFxuICB9XFxyXFxuXFxyXFxuI3N1cHAtdG90YWwgLnN0YXQge1xcclxcbiAgICBjb2xvcjogdmFyKC0teWVsbG93KTtcXHJcXG59XFxyXFxuXFxyXFxuLnN0YXQge1xcclxcbiAgICBmb250LXdlaWdodDogYm9sZDtcXHJcXG59XFxyXFxuXFxyXFxuI3NpZGViYXItcGFuZWwge1xcclxcbiAgICBoZWlnaHQ6IDEwMCU7IC8qIEZ1bGwgaGVpZ2h0IG9mIHRoZSB2aWV3cG9ydCAqL1xcclxcbiAgICBwb3NpdGlvbjogZml4ZWQ7IC8qIEZpeGVkIFNpZGViYXIgKHN0YXkgaW4gcGxhY2Ugb24gc2Nyb2xsKSAqL1xcclxcbiAgICB6LWluZGV4OiAxOyAvKiBTdGF5IG9uIHRvcCAqL1xcclxcbiAgICB0b3A6IDA7IC8qIFN0YXkgYXQgdGhlIHRvcCAqL1xcclxcbiAgICByaWdodDogMDsgLyogU2lkZWJhciBhcHBlYXJzIG9uIHRoZSBsZWZ0ICovXFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6ICNGRkZGRkY7IC8qIFdoaXRlIGJhY2tncm91bmQgY29sb3IgKi9cXHJcXG4gICAgb3ZlcmZsb3cteDogaGlkZGVuOyAvKiBEaXNhYmxlIGhvcml6b250YWwgc2Nyb2xsICovXFxyXFxuICAgIHBhZGRpbmc6IDIwcHg7XFxyXFxuICAgIGJveC1zaGFkb3c6IDAgMnB4IDVweCByZ2JhKDAsIDAsIDAsIDAuMSk7IC8qIEFkZCBzaGFkb3cgZm9yIHNvbWUgZGVwdGggKi9cXHJcXG4gICAgYm9yZGVyLXJpZ2h0OiAycHggc29saWQgI0RERERERDsgLyogUmlnaHQgYm9yZGVyICovXFxyXFxuICAgIGJvcmRlci1yYWRpdXM6IDBweCAwcHggMHB4IDE1cHg7IC8qIFJvdW5kZWQgY29ybmVycyBvbiB0aGUgbGVmdCAqL1xcclxcbiAgICAvKiBtYXJnaW4tdG9wOiB2YXIoLS1oZWFkZXItaGVpZ2h0KTsgKi9cXHJcXG4gICAgd2lkdGg6IHZhcigtLXNpZGViYXItd2lkdGgpO1xcclxcbiAgICBtYXJnaW46IDBweDtcXHJcXG4gIH1cXHJcXG4gIFxcclxcbi5zaWRlYmFyIGEge1xcclxcbiAgICBwYWRkaW5nOiAxMHB4IDE1cHg7XFxyXFxuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcXHJcXG4gICAgZm9udC1zaXplOiAxOHB4O1xcclxcbiAgICBjb2xvcjogIzgxODE4MTtcXHJcXG4gICAgZGlzcGxheTogYmxvY2s7XFxyXFxuICAgIHRyYW5zaXRpb246IDAuM3M7XFxyXFxufVxcclxcblxcclxcbiNzaWRlYmFyLXRpdGxlIHtcXHJcXG4gIGNvbG9yOiB2YXIoLS1kYXJrR3JheSk7XFxyXFxuICBmb250LXdlaWdodDogYm9sZDtcXHJcXG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1jaXR5Z3JlZW4pO1xcclxcbn1cXHJcXG5cXHJcXG5ociB7XFxyXFxuICBtYXJnaW4tdG9wOiAtNXB4O1xcclxcbiAgbWFyZ2luLWJvdHRvbTogOHB4O1xcclxcbn1cXHJcXG5cXHJcXG5oNiB7XFxyXFxuICBmb250LXdlaWdodDogNjAwO1xcclxcbn1cXHJcXG5cXHJcXG4uc2VjdGlvbi1oZWFkZXIge1xcclxcbiAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tbWVkaXVtR3JheSk7XFxyXFxufVxcclxcblxcclxcbi5zaWRlYmFyLXN0YXQtbGluZSB7XFxyXFxuICBkaXNwbGF5OiBmbGV4O1xcclxcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcXHJcXG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgLyogRGlzdHJpYnV0ZSBzcGFjZSBiZXR3ZWVuIGNoaWxkcmVuICovXFxyXFxuICBwYWRkaW5nOiAycHg7XFxyXFxuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2RkZDtcXHJcXG59XFxyXFxuXFxyXFxuLmVkaXQtaWNvbiwgLmVkaXQtc3VwcCB7XFxyXFxuICBjb2xvcjogdmFyKC0tc3Bpcml0Z3JlZW4pO1xcclxcbiAgY3Vyc29yOiBwb2ludGVyO1xcclxcbiAgZm9udC1zaXplOiAxNnB4OyAvKiBBZGp1c3QgdGhlIHNpemUgYXMgbmVlZGVkICovXFxyXFxuICBtYXJnaW4tbGVmdDogMTBweDtcXHJcXG59XFxyXFxuXFxyXFxuLmVkaXQtaWNvbjpob3ZlciAuZWRpdC1zdXBwOmhvdmVyIHtcXHJcXG4gIGNvbG9yOiB2YXIoLS1jaXR5Z3JlZW4pO1xcclxcbn1cXHJcXG5cXHJcXG4uc3RhdC1sYWJlbCB7XFxyXFxuICBtYXJnaW4tcmlnaHQ6IGF1dG87IC8qIFB1c2ggbmV4dCBlbGVtZW50cyB0byB0aGUgcmlnaHQgKi9cXHJcXG59XFxyXFxuXFxyXFxuLnN0YXQge1xcclxcbiAgbWFyZ2luLWxlZnQ6IDVweDsgLyogT3B0aW9uYWw6IEFkZCBzb21lIHNwYWNlIGJldHdlZW4gY3VycmVuY3kgYW5kIGVkaXQgaWNvbiAqL1xcclxcbn1cXHJcXG5cXHJcXG4uc2lkZWJhci1zdGF0LWxpbmUuZnVuZC10b3RhbCAuc3RhdCB7XFxyXFxuICBtYXJnaW4tcmlnaHQ6IDA1cHg7IC8qIDI1cHggbGluZXMgdXAgd2l0aCBsaW5lcyBhYm92ZSAod2l0aCBlZGl0IHN5bWJvbCkgKi9cXHJcXG59XCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///263\n')},279:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#main-table {\r\n font-size: 12px;\r\n /* calc(0.5vw + 0.5em); */\r\n margin: auto;\r\n width: 100%;\r\n}\r\n\r\n#main-table thead > tr > th {\r\n text-align: left;\r\n background-color: var(--darkGray);\r\n color: white;\r\n position: -webkit-sticky; /* For Safari */\r\n position: sticky;\r\n top: 0;\r\n padding-top: 5px;\r\n padding-bottom: 5px;\r\n}\r\n\r\nth {\r\n background-color: var(--lightGray);\r\n}\r\n\r\ntr {\r\n border-width: 2px;\r\n background-color: white;\r\n}\r\n\r\ntr td {\r\n border-bottom: 1px solid black;\r\n}\r\n\r\n/* Default to hidden columns */\r\n\r\n#main-table tbody > tr > td {\r\n display : none;\r\n}\r\n#main-table thead > tr > th {\r\n display : none;\r\n}\r\n\r\n/* textbox width in table */\r\ninput {\r\n width: 100%;\r\n}\r\n\r\nselect {\r\n max-width: 100px;\r\n}\r\n\r\ndiv.table-container {\r\n overflow-x: auto; \r\n overflow-y: auto;\r\n margin-left: max(65px, 7vh);\r\n margin-right: max(65px, 7vh);\r\n /* max-width: calc(100vw - var(--sidebar-width)); */\r\n /* margin: auto; */\r\n max-height: max(350px, 6vh);\r\n /* min-height: 350px; */\r\n\r\n}\r\n \r\n/* Buttons */\r\n\r\n/* Add new row button */\r\n.btn-add { \r\n background-color: var(--spiritgreen);\r\n margin-top: 20px;\r\n display: none;\r\n}\r\n\r\n.btn-delete {\r\n background-color: var(--orange);\r\n}\r\n\r\n#add-btn-div {\r\n display: flex;\r\n justify-content: center; /* Aligns horizontally */\r\n align-items: center; /* Aligns vertically */\r\n width: 100%;\r\n}\r\n\r\n.btn-edit {\r\n background-color: var(--spiritgreen);\r\n line-height: 1.1;\r\n}\r\n\r\n.active-editing, .selected {\r\n background-color: var(--palegreen);\r\n}\r\n\r\n.selected { \r\n font-weight: bold;\r\n}\r\n\r\n.btn-confirm {\r\n display: none;\r\n}\r\n\r\n.confirm-btn:hover {\r\n background-color: var(--green);\r\n}\r\n\r\n.hover-effect:hover {\r\n cursor: pointer;\r\n background-color: var(--verypalegreen); \r\n}\r\n\r\n/* Fund table */\r\n.fund-name > .viewed-fund {\r\n color: gray;\r\n}\r\n\r\n/* made edit column narrower */\r\nth.edit, td.edit {\r\n width: 20px;\r\n}\r\n\r\n/* Class for hidden rows on filter */\r\n.hidden {\r\n display: none;\r\n}\r\n\r\n/* Filter styling for the dropdown options */\r\n#filter-container {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 2px; /* Adjust the gap as needed */\r\n font-size: 11px;\r\n margin-left: 10%;\r\n margin-right: 10%;\r\n margin-bottom: 5px;\r\n}\r\n\r\n#filter-container div {\r\n display: flex;\r\n align-items: center;\r\n width: calc(50% - 10px); /* Adjust width to fit two items per row with gap */\r\n}\r\n\r\n#filter-container label {\r\n width: 200px; /* Adjust the width as needed */\r\n text-align: right;\r\n margin-right: 10px; /* Spacing between label and select */\r\n}\r\n\r\n/* Ensure all select boxes are wide enough to show text */\r\n.filter-dropdown {\r\n flex: 1;\r\n min-width: 200px; /* Adjust the min-width as needed */\r\n}\r\n\r\n/* Optional styling to make the select dropdown look better */\r\n.filter-dropdown {\r\n padding: 5px;\r\n border: 1px solid #ccc;\r\n border-radius: 4px;\r\n}\r\n\r\n/* Responsive adjustment: On smaller screens, stack elements vertically */\r\n@media (max-width: 800px) {\r\n #filter-container div {\r\n width: 100%;\r\n }\r\n\r\n #filter-container label {\r\n text-align: left;\r\n width: auto;\r\n margin-right: 0;\r\n margin-bottom: 5px;\r\n }\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/table/table.css"],"names":[],"mappings":"AAAA;IACI,eAAe;IACf,yBAAyB;IACzB,YAAY;IACZ,WAAW;AACf;;AAEA;IACI,gBAAgB;IAChB,iCAAiC;IACjC,YAAY;IACZ,wBAAwB,EAAE,eAAe;IACzC,gBAAgB;IAChB,MAAM;IACN,gBAAgB;IAChB,mBAAmB;AACvB;;AAEA;IACI,kCAAkC;AACtC;;AAEA;IACI,iBAAiB;IACjB,uBAAuB;AAC3B;;AAEA;IACI,8BAA8B;AAClC;;AAEA,8BAA8B;;AAE9B;IACI,cAAc;AAClB;AACA;IACI,cAAc;AAClB;;AAEA,2BAA2B;AAC3B;IACI,WAAW;AACf;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,gBAAgB;IAChB,gBAAgB;IAChB,2BAA2B;IAC3B,4BAA4B;IAC5B,oDAAoD;IACpD,kBAAkB;IAClB,2BAA2B;IAC3B,uBAAuB;;AAE3B;;AAEA,YAAY;;AAEZ,uBAAuB;AACvB;IACI,oCAAoC;IACpC,gBAAgB;IAChB,aAAa;AACjB;;AAEA;IACI,+BAA+B;AACnC;;AAEA;IACI,aAAa;IACb,uBAAuB,EAAE,wBAAwB;IACjD,mBAAmB,EAAE,sBAAsB;IAC3C,WAAW;AACf;;AAEA;IACI,oCAAoC;IACpC,gBAAgB;AACpB;;AAEA;IACI,kCAAkC;AACtC;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,8BAA8B;AAClC;;AAEA;IACI,eAAe;IACf,sCAAsC;AAC1C;;AAEA,eAAe;AACf;IACI,WAAW;AACf;;AAEA,8BAA8B;AAC9B;IACI,WAAW;AACf;;AAEA,oCAAoC;AACpC;IACI,aAAa;AACjB;;AAEA,4CAA4C;AAC5C;IACI,aAAa;IACb,eAAe;IACf,QAAQ,EAAE,6BAA6B;IACvC,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,kBAAkB;AACtB;;AAEA;IACI,aAAa;IACb,mBAAmB;IACnB,uBAAuB,EAAE,mDAAmD;AAChF;;AAEA;IACI,YAAY,EAAE,+BAA+B;IAC7C,iBAAiB;IACjB,kBAAkB,EAAE,qCAAqC;AAC7D;;AAEA,yDAAyD;AACzD;IACI,OAAO;IACP,gBAAgB,EAAE,mCAAmC;AACzD;;AAEA,6DAA6D;AAC7D;IACI,YAAY;IACZ,sBAAsB;IACtB,kBAAkB;AACtB;;AAEA,yEAAyE;AACzE;IACI;QACI,WAAW;IACf;;IAEA;QACI,gBAAgB;QAChB,WAAW;QACX,eAAe;QACf,kBAAkB;IACtB;AACJ","sourcesContent":["#main-table {\\r\\n font-size: 12px;\\r\\n /* calc(0.5vw + 0.5em); */\\r\\n margin: auto;\\r\\n width: 100%;\\r\\n}\\r\\n\\r\\n#main-table thead > tr > th {\\r\\n text-align: left;\\r\\n background-color: var(--darkGray);\\r\\n color: white;\\r\\n position: -webkit-sticky; /* For Safari */\\r\\n position: sticky;\\r\\n top: 0;\\r\\n padding-top: 5px;\\r\\n padding-bottom: 5px;\\r\\n}\\r\\n\\r\\nth {\\r\\n background-color: var(--lightGray);\\r\\n}\\r\\n\\r\\ntr {\\r\\n border-width: 2px;\\r\\n background-color: white;\\r\\n}\\r\\n\\r\\ntr td {\\r\\n border-bottom: 1px solid black;\\r\\n}\\r\\n\\r\\n/* Default to hidden columns */\\r\\n\\r\\n#main-table tbody > tr > td {\\r\\n display : none;\\r\\n}\\r\\n#main-table thead > tr > th {\\r\\n display : none;\\r\\n}\\r\\n\\r\\n/* textbox width in table */\\r\\ninput {\\r\\n width: 100%;\\r\\n}\\r\\n\\r\\nselect {\\r\\n max-width: 100px;\\r\\n}\\r\\n\\r\\ndiv.table-container {\\r\\n overflow-x: auto; \\r\\n overflow-y: auto;\\r\\n margin-left: max(65px, 7vh);\\r\\n margin-right: max(65px, 7vh);\\r\\n /* max-width: calc(100vw - var(--sidebar-width)); */\\r\\n /* margin: auto; */\\r\\n max-height: max(350px, 6vh);\\r\\n /* min-height: 350px; */\\r\\n\\r\\n}\\r\\n \\r\\n/* Buttons */\\r\\n\\r\\n/* Add new row button */\\r\\n.btn-add { \\r\\n background-color: var(--spiritgreen);\\r\\n margin-top: 20px;\\r\\n display: none;\\r\\n}\\r\\n\\r\\n.btn-delete {\\r\\n background-color: var(--orange);\\r\\n}\\r\\n\\r\\n#add-btn-div {\\r\\n display: flex;\\r\\n justify-content: center; /* Aligns horizontally */\\r\\n align-items: center; /* Aligns vertically */\\r\\n width: 100%;\\r\\n}\\r\\n\\r\\n.btn-edit {\\r\\n background-color: var(--spiritgreen);\\r\\n line-height: 1.1;\\r\\n}\\r\\n\\r\\n.active-editing, .selected {\\r\\n background-color: var(--palegreen);\\r\\n}\\r\\n\\r\\n.selected { \\r\\n font-weight: bold;\\r\\n}\\r\\n\\r\\n.btn-confirm {\\r\\n display: none;\\r\\n}\\r\\n\\r\\n.confirm-btn:hover {\\r\\n background-color: var(--green);\\r\\n}\\r\\n\\r\\n.hover-effect:hover {\\r\\n cursor: pointer;\\r\\n background-color: var(--verypalegreen); \\r\\n}\\r\\n\\r\\n/* Fund table */\\r\\n.fund-name > .viewed-fund {\\r\\n color: gray;\\r\\n}\\r\\n\\r\\n/* made edit column narrower */\\r\\nth.edit, td.edit {\\r\\n width: 20px;\\r\\n}\\r\\n\\r\\n/* Class for hidden rows on filter */\\r\\n.hidden {\\r\\n display: none;\\r\\n}\\r\\n\\r\\n/* Filter styling for the dropdown options */\\r\\n#filter-container {\\r\\n display: flex;\\r\\n flex-wrap: wrap;\\r\\n gap: 2px; /* Adjust the gap as needed */\\r\\n font-size: 11px;\\r\\n margin-left: 10%;\\r\\n margin-right: 10%;\\r\\n margin-bottom: 5px;\\r\\n}\\r\\n\\r\\n#filter-container div {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n width: calc(50% - 10px); /* Adjust width to fit two items per row with gap */\\r\\n}\\r\\n\\r\\n#filter-container label {\\r\\n width: 200px; /* Adjust the width as needed */\\r\\n text-align: right;\\r\\n margin-right: 10px; /* Spacing between label and select */\\r\\n}\\r\\n\\r\\n/* Ensure all select boxes are wide enough to show text */\\r\\n.filter-dropdown {\\r\\n flex: 1;\\r\\n min-width: 200px; /* Adjust the min-width as needed */\\r\\n}\\r\\n\\r\\n/* Optional styling to make the select dropdown look better */\\r\\n.filter-dropdown {\\r\\n padding: 5px;\\r\\n border: 1px solid #ccc;\\r\\n border-radius: 4px;\\r\\n}\\r\\n\\r\\n/* Responsive adjustment: On smaller screens, stack elements vertically */\\r\\n@media (max-width: 800px) {\\r\\n #filter-container div {\\r\\n width: 100%;\\r\\n }\\r\\n\\r\\n #filter-container label {\\r\\n text-align: left;\\r\\n width: auto;\\r\\n margin-right: 0;\\r\\n margin-bottom: 5px;\\r\\n }\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjc5LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy90YWJsZS90YWJsZS5jc3M/NTIzNyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgI21haW4tdGFibGUge1xyXG4gICAgZm9udC1zaXplOiAxMnB4O1xyXG4gICAgLyogY2FsYygwLjV2dyArIDAuNWVtKTsgKi9cclxuICAgIG1hcmdpbjogYXV0bztcclxuICAgIHdpZHRoOiAxMDAlO1xyXG59XHJcblxyXG4jbWFpbi10YWJsZSB0aGVhZCA+IHRyID4gdGgge1xyXG4gICAgdGV4dC1hbGlnbjogbGVmdDtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWRhcmtHcmF5KTtcclxuICAgIGNvbG9yOiB3aGl0ZTtcclxuICAgIHBvc2l0aW9uOiAtd2Via2l0LXN0aWNreTsgLyogRm9yIFNhZmFyaSAqL1xyXG4gICAgcG9zaXRpb246IHN0aWNreTtcclxuICAgIHRvcDogMDtcclxuICAgIHBhZGRpbmctdG9wOiA1cHg7XHJcbiAgICBwYWRkaW5nLWJvdHRvbTogNXB4O1xyXG59XHJcblxyXG50aCB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1saWdodEdyYXkpO1xyXG59XHJcblxyXG50ciB7XHJcbiAgICBib3JkZXItd2lkdGg6IDJweDtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xyXG59XHJcblxyXG50ciB0ZCB7XHJcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgYmxhY2s7XHJcbn1cclxuXHJcbi8qIERlZmF1bHQgdG8gaGlkZGVuIGNvbHVtbnMgKi9cclxuXHJcbiNtYWluLXRhYmxlIHRib2R5ID4gdHIgPiB0ZCB7XHJcbiAgICBkaXNwbGF5IDogbm9uZTtcclxufVxyXG4jbWFpbi10YWJsZSB0aGVhZCA+IHRyID4gdGgge1xyXG4gICAgZGlzcGxheSA6IG5vbmU7XHJcbn1cclxuXHJcbi8qIHRleHRib3ggd2lkdGggaW4gdGFibGUgKi9cclxuaW5wdXQge1xyXG4gICAgd2lkdGg6IDEwMCU7XHJcbn1cclxuXHJcbnNlbGVjdCB7XHJcbiAgICBtYXgtd2lkdGg6IDEwMHB4O1xyXG59XHJcblxyXG5kaXYudGFibGUtY29udGFpbmVyIHtcclxuICAgIG92ZXJmbG93LXg6IGF1dG87IFxyXG4gICAgb3ZlcmZsb3cteTogYXV0bztcclxuICAgIG1hcmdpbi1sZWZ0OiBtYXgoNjVweCwgN3ZoKTtcclxuICAgIG1hcmdpbi1yaWdodDogbWF4KDY1cHgsIDd2aCk7XHJcbiAgICAvKiBtYXgtd2lkdGg6IGNhbGMoMTAwdncgLSB2YXIoLS1zaWRlYmFyLXdpZHRoKSk7ICAqL1xyXG4gICAgLyogbWFyZ2luOiBhdXRvOyAqL1xyXG4gICAgbWF4LWhlaWdodDogbWF4KDM1MHB4LCA2dmgpO1xyXG4gICAgLyogbWluLWhlaWdodDogMzUwcHg7ICovXHJcblxyXG59XHJcbiAgXHJcbi8qIEJ1dHRvbnMgKi9cclxuXHJcbi8qIEFkZCBuZXcgcm93IGJ1dHRvbiAqL1xyXG4uYnRuLWFkZCB7IFxyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tc3Bpcml0Z3JlZW4pO1xyXG4gICAgbWFyZ2luLXRvcDogMjBweDtcclxuICAgIGRpc3BsYXk6IG5vbmU7XHJcbn1cclxuXHJcbi5idG4tZGVsZXRlIHtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLW9yYW5nZSk7XHJcbn1cclxuXHJcbiNhZGQtYnRuLWRpdiB7XHJcbiAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7IC8qIEFsaWducyBob3Jpem9udGFsbHkgKi9cclxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7IC8qIEFsaWducyB2ZXJ0aWNhbGx5ICovXHJcbiAgICB3aWR0aDogMTAwJTtcclxufVxyXG5cclxuLmJ0bi1lZGl0IHtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIGxpbmUtaGVpZ2h0OiAxLjE7XHJcbn1cclxuXHJcbi5hY3RpdmUtZWRpdGluZywgLnNlbGVjdGVkIHtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXBhbGVncmVlbik7XHJcbn1cclxuXHJcbi5zZWxlY3RlZCB7IFxyXG4gICAgZm9udC13ZWlnaHQ6IGJvbGQ7XHJcbn1cclxuXHJcbi5idG4tY29uZmlybSB7XHJcbiAgICBkaXNwbGF5OiBub25lO1xyXG59XHJcblxyXG4uY29uZmlybS1idG46aG92ZXIge1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tZ3JlZW4pO1xyXG59XHJcblxyXG4uaG92ZXItZWZmZWN0OmhvdmVyIHtcclxuICAgIGN1cnNvcjogcG9pbnRlcjtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXZlcnlwYWxlZ3JlZW4pOyBcclxufVxyXG5cclxuLyogRnVuZCB0YWJsZSAqL1xyXG4uZnVuZC1uYW1lID4gLnZpZXdlZC1mdW5kIHtcclxuICAgIGNvbG9yOiBncmF5O1xyXG59XHJcblxyXG4vKiBtYWRlIGVkaXQgY29sdW1uIG5hcnJvd2VyICovXHJcbnRoLmVkaXQsIHRkLmVkaXQge1xyXG4gICAgd2lkdGg6IDIwcHg7XHJcbn1cclxuXHJcbi8qIENsYXNzIGZvciBoaWRkZW4gcm93cyBvbiBmaWx0ZXIgKi9cclxuLmhpZGRlbiB7XHJcbiAgICBkaXNwbGF5OiBub25lO1xyXG59XHJcblxyXG4vKiBGaWx0ZXIgc3R5bGluZyBmb3IgdGhlIGRyb3Bkb3duIG9wdGlvbnMgKi9cclxuI2ZpbHRlci1jb250YWluZXIge1xyXG4gICAgZGlzcGxheTogZmxleDtcclxuICAgIGZsZXgtd3JhcDogd3JhcDtcclxuICAgIGdhcDogMnB4OyAvKiBBZGp1c3QgdGhlIGdhcCBhcyBuZWVkZWQgKi9cclxuICAgIGZvbnQtc2l6ZTogMTFweDtcclxuICAgIG1hcmdpbi1sZWZ0OiAxMCU7XHJcbiAgICBtYXJnaW4tcmlnaHQ6IDEwJTtcclxuICAgIG1hcmdpbi1ib3R0b206IDVweDtcclxufVxyXG5cclxuI2ZpbHRlci1jb250YWluZXIgZGl2IHtcclxuICAgIGRpc3BsYXk6IGZsZXg7XHJcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xyXG4gICAgd2lkdGg6IGNhbGMoNTAlIC0gMTBweCk7IC8qIEFkanVzdCB3aWR0aCB0byBmaXQgdHdvIGl0ZW1zIHBlciByb3cgd2l0aCBnYXAgKi9cclxufVxyXG5cclxuI2ZpbHRlci1jb250YWluZXIgbGFiZWwge1xyXG4gICAgd2lkdGg6IDIwMHB4OyAvKiBBZGp1c3QgdGhlIHdpZHRoIGFzIG5lZWRlZCAqL1xyXG4gICAgdGV4dC1hbGlnbjogcmlnaHQ7XHJcbiAgICBtYXJnaW4tcmlnaHQ6IDEwcHg7IC8qIFNwYWNpbmcgYmV0d2VlbiBsYWJlbCBhbmQgc2VsZWN0ICovXHJcbn1cclxuXHJcbi8qIEVuc3VyZSBhbGwgc2VsZWN0IGJveGVzIGFyZSB3aWRlIGVub3VnaCB0byBzaG93IHRleHQgKi9cclxuLmZpbHRlci1kcm9wZG93biB7XHJcbiAgICBmbGV4OiAxO1xyXG4gICAgbWluLXdpZHRoOiAyMDBweDsgLyogQWRqdXN0IHRoZSBtaW4td2lkdGggYXMgbmVlZGVkICovXHJcbn1cclxuXHJcbi8qIE9wdGlvbmFsIHN0eWxpbmcgdG8gbWFrZSB0aGUgc2VsZWN0IGRyb3Bkb3duIGxvb2sgYmV0dGVyICovXHJcbi5maWx0ZXItZHJvcGRvd24ge1xyXG4gICAgcGFkZGluZzogNXB4O1xyXG4gICAgYm9yZGVyOiAxcHggc29saWQgI2NjYztcclxuICAgIGJvcmRlci1yYWRpdXM6IDRweDtcclxufVxyXG5cclxuLyogUmVzcG9uc2l2ZSBhZGp1c3RtZW50OiBPbiBzbWFsbGVyIHNjcmVlbnMsIHN0YWNrIGVsZW1lbnRzIHZlcnRpY2FsbHkgKi9cclxuQG1lZGlhIChtYXgtd2lkdGg6IDgwMHB4KSB7XHJcbiAgICAjZmlsdGVyLWNvbnRhaW5lciBkaXYge1xyXG4gICAgICAgIHdpZHRoOiAxMDAlO1xyXG4gICAgfVxyXG5cclxuICAgICNmaWx0ZXItY29udGFpbmVyIGxhYmVsIHtcclxuICAgICAgICB0ZXh0LWFsaWduOiBsZWZ0O1xyXG4gICAgICAgIHdpZHRoOiBhdXRvO1xyXG4gICAgICAgIG1hcmdpbi1yaWdodDogMDtcclxuICAgICAgICBtYXJnaW4tYm90dG9tOiA1cHg7XHJcbiAgICB9XHJcbn1gLCBcIlwiLHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIndlYnBhY2s6Ly8uL3NyYy9qcy9jb21wb25lbnRzL3RhYmxlL3RhYmxlLmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLGVBQWU7SUFDZix5QkFBeUI7SUFDekIsWUFBWTtJQUNaLFdBQVc7QUFDZjs7QUFFQTtJQUNJLGdCQUFnQjtJQUNoQixpQ0FBaUM7SUFDakMsWUFBWTtJQUNaLHdCQUF3QixFQUFFLGVBQWU7SUFDekMsZ0JBQWdCO0lBQ2hCLE1BQU07SUFDTixnQkFBZ0I7SUFDaEIsbUJBQW1CO0FBQ3ZCOztBQUVBO0lBQ0ksa0NBQWtDO0FBQ3RDOztBQUVBO0lBQ0ksaUJBQWlCO0lBQ2pCLHVCQUF1QjtBQUMzQjs7QUFFQTtJQUNJLDhCQUE4QjtBQUNsQzs7QUFFQSw4QkFBOEI7O0FBRTlCO0lBQ0ksY0FBYztBQUNsQjtBQUNBO0lBQ0ksY0FBYztBQUNsQjs7QUFFQSwyQkFBMkI7QUFDM0I7SUFDSSxXQUFXO0FBQ2Y7O0FBRUE7SUFDSSxnQkFBZ0I7QUFDcEI7O0FBRUE7SUFDSSxnQkFBZ0I7SUFDaEIsZ0JBQWdCO0lBQ2hCLDJCQUEyQjtJQUMzQiw0QkFBNEI7SUFDNUIsb0RBQW9EO0lBQ3BELGtCQUFrQjtJQUNsQiwyQkFBMkI7SUFDM0IsdUJBQXVCOztBQUUzQjs7QUFFQSxZQUFZOztBQUVaLHVCQUF1QjtBQUN2QjtJQUNJLG9DQUFvQztJQUNwQyxnQkFBZ0I7SUFDaEIsYUFBYTtBQUNqQjs7QUFFQTtJQUNJLCtCQUErQjtBQUNuQzs7QUFFQTtJQUNJLGFBQWE7SUFDYix1QkFBdUIsRUFBRSx3QkFBd0I7SUFDakQsbUJBQW1CLEVBQUUsc0JBQXNCO0lBQzNDLFdBQVc7QUFDZjs7QUFFQTtJQUNJLG9DQUFvQztJQUNwQyxnQkFBZ0I7QUFDcEI7O0FBRUE7SUFDSSxrQ0FBa0M7QUFDdEM7O0FBRUE7SUFDSSxpQkFBaUI7QUFDckI7O0FBRUE7SUFDSSxhQUFhO0FBQ2pCOztBQUVBO0lBQ0ksOEJBQThCO0FBQ2xDOztBQUVBO0lBQ0ksZUFBZTtJQUNmLHNDQUFzQztBQUMxQzs7QUFFQSxlQUFlO0FBQ2Y7SUFDSSxXQUFXO0FBQ2Y7O0FBRUEsOEJBQThCO0FBQzlCO0lBQ0ksV0FBVztBQUNmOztBQUVBLG9DQUFvQztBQUNwQztJQUNJLGFBQWE7QUFDakI7O0FBRUEsNENBQTRDO0FBQzVDO0lBQ0ksYUFBYTtJQUNiLGVBQWU7SUFDZixRQUFRLEVBQUUsNkJBQTZCO0lBQ3ZDLGVBQWU7SUFDZixnQkFBZ0I7SUFDaEIsaUJBQWlCO0lBQ2pCLGtCQUFrQjtBQUN0Qjs7QUFFQTtJQUNJLGFBQWE7SUFDYixtQkFBbUI7SUFDbkIsdUJBQXVCLEVBQUUsbURBQW1EO0FBQ2hGOztBQUVBO0lBQ0ksWUFBWSxFQUFFLCtCQUErQjtJQUM3QyxpQkFBaUI7SUFDakIsa0JBQWtCLEVBQUUscUNBQXFDO0FBQzdEOztBQUVBLHlEQUF5RDtBQUN6RDtJQUNJLE9BQU87SUFDUCxnQkFBZ0IsRUFBRSxtQ0FBbUM7QUFDekQ7O0FBRUEsNkRBQTZEO0FBQzdEO0lBQ0ksWUFBWTtJQUNaLHNCQUFzQjtJQUN0QixrQkFBa0I7QUFDdEI7O0FBRUEseUVBQXlFO0FBQ3pFO0lBQ0k7UUFDSSxXQUFXO0lBQ2Y7O0lBRUE7UUFDSSxnQkFBZ0I7UUFDaEIsV0FBVztRQUNYLGVBQWU7UUFDZixrQkFBa0I7SUFDdEI7QUFDSlwiLFwic291cmNlc0NvbnRlbnRcIjpbXCIjbWFpbi10YWJsZSB7XFxyXFxuICAgIGZvbnQtc2l6ZTogMTJweDtcXHJcXG4gICAgLyogY2FsYygwLjV2dyArIDAuNWVtKTsgKi9cXHJcXG4gICAgbWFyZ2luOiBhdXRvO1xcclxcbiAgICB3aWR0aDogMTAwJTtcXHJcXG59XFxyXFxuXFxyXFxuI21haW4tdGFibGUgdGhlYWQgPiB0ciA+IHRoIHtcXHJcXG4gICAgdGV4dC1hbGlnbjogbGVmdDtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tZGFya0dyYXkpO1xcclxcbiAgICBjb2xvcjogd2hpdGU7XFxyXFxuICAgIHBvc2l0aW9uOiAtd2Via2l0LXN0aWNreTsgLyogRm9yIFNhZmFyaSAqL1xcclxcbiAgICBwb3NpdGlvbjogc3RpY2t5O1xcclxcbiAgICB0b3A6IDA7XFxyXFxuICAgIHBhZGRpbmctdG9wOiA1cHg7XFxyXFxuICAgIHBhZGRpbmctYm90dG9tOiA1cHg7XFxyXFxufVxcclxcblxcclxcbnRoIHtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tbGlnaHRHcmF5KTtcXHJcXG59XFxyXFxuXFxyXFxudHIge1xcclxcbiAgICBib3JkZXItd2lkdGg6IDJweDtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XFxyXFxufVxcclxcblxcclxcbnRyIHRkIHtcXHJcXG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIGJsYWNrO1xcclxcbn1cXHJcXG5cXHJcXG4vKiBEZWZhdWx0IHRvIGhpZGRlbiBjb2x1bW5zICovXFxyXFxuXFxyXFxuI21haW4tdGFibGUgdGJvZHkgPiB0ciA+IHRkIHtcXHJcXG4gICAgZGlzcGxheSA6IG5vbmU7XFxyXFxufVxcclxcbiNtYWluLXRhYmxlIHRoZWFkID4gdHIgPiB0aCB7XFxyXFxuICAgIGRpc3BsYXkgOiBub25lO1xcclxcbn1cXHJcXG5cXHJcXG4vKiB0ZXh0Ym94IHdpZHRoIGluIHRhYmxlICovXFxyXFxuaW5wdXQge1xcclxcbiAgICB3aWR0aDogMTAwJTtcXHJcXG59XFxyXFxuXFxyXFxuc2VsZWN0IHtcXHJcXG4gICAgbWF4LXdpZHRoOiAxMDBweDtcXHJcXG59XFxyXFxuXFxyXFxuZGl2LnRhYmxlLWNvbnRhaW5lciB7XFxyXFxuICAgIG92ZXJmbG93LXg6IGF1dG87IFxcclxcbiAgICBvdmVyZmxvdy15OiBhdXRvO1xcclxcbiAgICBtYXJnaW4tbGVmdDogbWF4KDY1cHgsIDd2aCk7XFxyXFxuICAgIG1hcmdpbi1yaWdodDogbWF4KDY1cHgsIDd2aCk7XFxyXFxuICAgIC8qIG1heC13aWR0aDogY2FsYygxMDB2dyAtIHZhcigtLXNpZGViYXItd2lkdGgpKTsgICovXFxyXFxuICAgIC8qIG1hcmdpbjogYXV0bzsgKi9cXHJcXG4gICAgbWF4LWhlaWdodDogbWF4KDM1MHB4LCA2dmgpO1xcclxcbiAgICAvKiBtaW4taGVpZ2h0OiAzNTBweDsgKi9cXHJcXG5cXHJcXG59XFxyXFxuICBcXHJcXG4vKiBCdXR0b25zICovXFxyXFxuXFxyXFxuLyogQWRkIG5ldyByb3cgYnV0dG9uICovXFxyXFxuLmJ0bi1hZGQgeyBcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tc3Bpcml0Z3JlZW4pO1xcclxcbiAgICBtYXJnaW4tdG9wOiAyMHB4O1xcclxcbiAgICBkaXNwbGF5OiBub25lO1xcclxcbn1cXHJcXG5cXHJcXG4uYnRuLWRlbGV0ZSB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLW9yYW5nZSk7XFxyXFxufVxcclxcblxcclxcbiNhZGQtYnRuLWRpdiB7XFxyXFxuICAgIGRpc3BsYXk6IGZsZXg7XFxyXFxuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOyAvKiBBbGlnbnMgaG9yaXpvbnRhbGx5ICovXFxyXFxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7IC8qIEFsaWducyB2ZXJ0aWNhbGx5ICovXFxyXFxuICAgIHdpZHRoOiAxMDAlO1xcclxcbn1cXHJcXG5cXHJcXG4uYnRuLWVkaXQge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XFxyXFxuICAgIGxpbmUtaGVpZ2h0OiAxLjE7XFxyXFxufVxcclxcblxcclxcbi5hY3RpdmUtZWRpdGluZywgLnNlbGVjdGVkIHtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tcGFsZWdyZWVuKTtcXHJcXG59XFxyXFxuXFxyXFxuLnNlbGVjdGVkIHsgXFxyXFxuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xcclxcbn1cXHJcXG5cXHJcXG4uYnRuLWNvbmZpcm0ge1xcclxcbiAgICBkaXNwbGF5OiBub25lO1xcclxcbn1cXHJcXG5cXHJcXG4uY29uZmlybS1idG46aG92ZXIge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1ncmVlbik7XFxyXFxufVxcclxcblxcclxcbi5ob3Zlci1lZmZlY3Q6aG92ZXIge1xcclxcbiAgICBjdXJzb3I6IHBvaW50ZXI7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXZlcnlwYWxlZ3JlZW4pOyBcXHJcXG59XFxyXFxuXFxyXFxuLyogRnVuZCB0YWJsZSAqL1xcclxcbi5mdW5kLW5hbWUgPiAudmlld2VkLWZ1bmQge1xcclxcbiAgICBjb2xvcjogZ3JheTtcXHJcXG59XFxyXFxuXFxyXFxuLyogbWFkZSBlZGl0IGNvbHVtbiBuYXJyb3dlciAqL1xcclxcbnRoLmVkaXQsIHRkLmVkaXQge1xcclxcbiAgICB3aWR0aDogMjBweDtcXHJcXG59XFxyXFxuXFxyXFxuLyogQ2xhc3MgZm9yIGhpZGRlbiByb3dzIG9uIGZpbHRlciAqL1xcclxcbi5oaWRkZW4ge1xcclxcbiAgICBkaXNwbGF5OiBub25lO1xcclxcbn1cXHJcXG5cXHJcXG4vKiBGaWx0ZXIgc3R5bGluZyBmb3IgdGhlIGRyb3Bkb3duIG9wdGlvbnMgKi9cXHJcXG4jZmlsdGVyLWNvbnRhaW5lciB7XFxyXFxuICAgIGRpc3BsYXk6IGZsZXg7XFxyXFxuICAgIGZsZXgtd3JhcDogd3JhcDtcXHJcXG4gICAgZ2FwOiAycHg7IC8qIEFkanVzdCB0aGUgZ2FwIGFzIG5lZWRlZCAqL1xcclxcbiAgICBmb250LXNpemU6IDExcHg7XFxyXFxuICAgIG1hcmdpbi1sZWZ0OiAxMCU7XFxyXFxuICAgIG1hcmdpbi1yaWdodDogMTAlO1xcclxcbiAgICBtYXJnaW4tYm90dG9tOiA1cHg7XFxyXFxufVxcclxcblxcclxcbiNmaWx0ZXItY29udGFpbmVyIGRpdiB7XFxyXFxuICAgIGRpc3BsYXk6IGZsZXg7XFxyXFxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxyXFxuICAgIHdpZHRoOiBjYWxjKDUwJSAtIDEwcHgpOyAvKiBBZGp1c3Qgd2lkdGggdG8gZml0IHR3byBpdGVtcyBwZXIgcm93IHdpdGggZ2FwICovXFxyXFxufVxcclxcblxcclxcbiNmaWx0ZXItY29udGFpbmVyIGxhYmVsIHtcXHJcXG4gICAgd2lkdGg6IDIwMHB4OyAvKiBBZGp1c3QgdGhlIHdpZHRoIGFzIG5lZWRlZCAqL1xcclxcbiAgICB0ZXh0LWFsaWduOiByaWdodDtcXHJcXG4gICAgbWFyZ2luLXJpZ2h0OiAxMHB4OyAvKiBTcGFjaW5nIGJldHdlZW4gbGFiZWwgYW5kIHNlbGVjdCAqL1xcclxcbn1cXHJcXG5cXHJcXG4vKiBFbnN1cmUgYWxsIHNlbGVjdCBib3hlcyBhcmUgd2lkZSBlbm91Z2ggdG8gc2hvdyB0ZXh0ICovXFxyXFxuLmZpbHRlci1kcm9wZG93biB7XFxyXFxuICAgIGZsZXg6IDE7XFxyXFxuICAgIG1pbi13aWR0aDogMjAwcHg7IC8qIEFkanVzdCB0aGUgbWluLXdpZHRoIGFzIG5lZWRlZCAqL1xcclxcbn1cXHJcXG5cXHJcXG4vKiBPcHRpb25hbCBzdHlsaW5nIHRvIG1ha2UgdGhlIHNlbGVjdCBkcm9wZG93biBsb29rIGJldHRlciAqL1xcclxcbi5maWx0ZXItZHJvcGRvd24ge1xcclxcbiAgICBwYWRkaW5nOiA1cHg7XFxyXFxuICAgIGJvcmRlcjogMXB4IHNvbGlkICNjY2M7XFxyXFxuICAgIGJvcmRlci1yYWRpdXM6IDRweDtcXHJcXG59XFxyXFxuXFxyXFxuLyogUmVzcG9uc2l2ZSBhZGp1c3RtZW50OiBPbiBzbWFsbGVyIHNjcmVlbnMsIHN0YWNrIGVsZW1lbnRzIHZlcnRpY2FsbHkgKi9cXHJcXG5AbWVkaWEgKG1heC13aWR0aDogODAwcHgpIHtcXHJcXG4gICAgI2ZpbHRlci1jb250YWluZXIgZGl2IHtcXHJcXG4gICAgICAgIHdpZHRoOiAxMDAlO1xcclxcbiAgICB9XFxyXFxuXFxyXFxuICAgICNmaWx0ZXItY29udGFpbmVyIGxhYmVsIHtcXHJcXG4gICAgICAgIHRleHQtYWxpZ246IGxlZnQ7XFxyXFxuICAgICAgICB3aWR0aDogYXV0bztcXHJcXG4gICAgICAgIG1hcmdpbi1yaWdodDogMDtcXHJcXG4gICAgICAgIG1hcmdpbi1ib3R0b206IDVweDtcXHJcXG4gICAgfVxcclxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcbi8vIEV4cG9ydHNcbmV4cG9ydCBkZWZhdWx0IF9fX0NTU19MT0FERVJfRVhQT1JUX19fO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///279\n')},843:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#tooltip {\r\n position: absolute;\r\n background-color: black;\r\n color: white;\r\n padding: 5px;\r\n border-radius: 3px;\r\n visibility: hidden;\r\n white-space: nowrap;\r\n font-size: 14px;\r\n z-index: 1000;\r\n max-width: 300px;\r\n word-wrap: break-word;\r\n white-space: normal;\r\n}\r\n\r\n.tooltip-cell {\r\n /* color: blue; */\r\n /* text-decoration: underline; */\r\n cursor: pointer;\r\n}\r\n\r\n.tooltip-cell .info-icon {\r\n margin-left: 5px;\r\n color: var(--spiritgreen);\r\n font-size: 15px;\r\n}\r\n\r\n.tooltip-cell:hover {\r\n background-color: #f0f0f0; /* Change background on hover */\r\n}\r\n\r\n.detail {\r\n color: blue;\r\n color: var(--spiritgreen);\r\n text-decoration: underline;\r\n margin-left: 5px;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/tooltip/tooltip.css"],"names":[],"mappings":"AAAA;IACI,kBAAkB;IAClB,uBAAuB;IACvB,YAAY;IACZ,YAAY;IACZ,kBAAkB;IAClB,kBAAkB;IAClB,mBAAmB;IACnB,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,qBAAqB;IACrB,mBAAmB;AACvB;;AAEA;IACI,iBAAiB;IACjB,gCAAgC;IAChC,eAAe;AACnB;;AAEA;IACI,gBAAgB;IAChB,yBAAyB;IACzB,eAAe;AACnB;;AAEA;IACI,yBAAyB,EAAE,+BAA+B;AAC9D;;AAEA;IACI,WAAW;IACX,yBAAyB;IACzB,0BAA0B;IAC1B,gBAAgB;AACpB","sourcesContent":["#tooltip {\\r\\n position: absolute;\\r\\n background-color: black;\\r\\n color: white;\\r\\n padding: 5px;\\r\\n border-radius: 3px;\\r\\n visibility: hidden;\\r\\n white-space: nowrap;\\r\\n font-size: 14px;\\r\\n z-index: 1000;\\r\\n max-width: 300px;\\r\\n word-wrap: break-word;\\r\\n white-space: normal;\\r\\n}\\r\\n\\r\\n.tooltip-cell {\\r\\n /* color: blue; */\\r\\n /* text-decoration: underline; */\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n.tooltip-cell .info-icon {\\r\\n margin-left: 5px;\\r\\n color: var(--spiritgreen);\\r\\n font-size: 15px;\\r\\n}\\r\\n\\r\\n.tooltip-cell:hover {\\r\\n background-color: #f0f0f0; /* Change background on hover */\\r\\n}\\r\\n\\r\\n.detail {\\r\\n color: blue;\\r\\n color: var(--spiritgreen);\\r\\n text-decoration: underline;\\r\\n margin-left: 5px;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQzLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL3NyYy9qcy9jb21wb25lbnRzL3Rvb2x0aXAvdG9vbHRpcC5jc3M/N2ZkNiJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanNcIjtcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBgI3Rvb2x0aXAge1xyXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogYmxhY2s7XHJcbiAgICBjb2xvcjogd2hpdGU7XHJcbiAgICBwYWRkaW5nOiA1cHg7XHJcbiAgICBib3JkZXItcmFkaXVzOiAzcHg7XHJcbiAgICB2aXNpYmlsaXR5OiBoaWRkZW47XHJcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xyXG4gICAgZm9udC1zaXplOiAxNHB4O1xyXG4gICAgei1pbmRleDogMTAwMDtcclxuICAgIG1heC13aWR0aDogMzAwcHg7XHJcbiAgICB3b3JkLXdyYXA6IGJyZWFrLXdvcmQ7XHJcbiAgICB3aGl0ZS1zcGFjZTogbm9ybWFsO1xyXG59XHJcblxyXG4udG9vbHRpcC1jZWxsIHtcclxuICAgIC8qIGNvbG9yOiBibHVlOyAqL1xyXG4gICAgLyogdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7ICovXHJcbiAgICBjdXJzb3I6IHBvaW50ZXI7XHJcbn1cclxuXHJcbi50b29sdGlwLWNlbGwgLmluZm8taWNvbiB7XHJcbiAgICBtYXJnaW4tbGVmdDogNXB4O1xyXG4gICAgY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIGZvbnQtc2l6ZTogMTVweDtcclxufVxyXG5cclxuLnRvb2x0aXAtY2VsbDpob3ZlciB7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjBmMGYwOyAvKiBDaGFuZ2UgYmFja2dyb3VuZCBvbiBob3ZlciAqL1xyXG59XHJcblxyXG4uZGV0YWlsIHtcclxuICAgIGNvbG9yOiBibHVlO1xyXG4gICAgY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxuICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xyXG4gICAgbWFyZ2luLWxlZnQ6IDVweDtcclxufWAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2pzL2NvbXBvbmVudHMvdG9vbHRpcC90b29sdGlwLmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtJQUNJLGtCQUFrQjtJQUNsQix1QkFBdUI7SUFDdkIsWUFBWTtJQUNaLFlBQVk7SUFDWixrQkFBa0I7SUFDbEIsa0JBQWtCO0lBQ2xCLG1CQUFtQjtJQUNuQixlQUFlO0lBQ2YsYUFBYTtJQUNiLGdCQUFnQjtJQUNoQixxQkFBcUI7SUFDckIsbUJBQW1CO0FBQ3ZCOztBQUVBO0lBQ0ksaUJBQWlCO0lBQ2pCLGdDQUFnQztJQUNoQyxlQUFlO0FBQ25COztBQUVBO0lBQ0ksZ0JBQWdCO0lBQ2hCLHlCQUF5QjtJQUN6QixlQUFlO0FBQ25COztBQUVBO0lBQ0kseUJBQXlCLEVBQUUsK0JBQStCO0FBQzlEOztBQUVBO0lBQ0ksV0FBVztJQUNYLHlCQUF5QjtJQUN6QiwwQkFBMEI7SUFDMUIsZ0JBQWdCO0FBQ3BCXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIiN0b29sdGlwIHtcXHJcXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiBibGFjaztcXHJcXG4gICAgY29sb3I6IHdoaXRlO1xcclxcbiAgICBwYWRkaW5nOiA1cHg7XFxyXFxuICAgIGJvcmRlci1yYWRpdXM6IDNweDtcXHJcXG4gICAgdmlzaWJpbGl0eTogaGlkZGVuO1xcclxcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xcclxcbiAgICBmb250LXNpemU6IDE0cHg7XFxyXFxuICAgIHotaW5kZXg6IDEwMDA7XFxyXFxuICAgIG1heC13aWR0aDogMzAwcHg7XFxyXFxuICAgIHdvcmQtd3JhcDogYnJlYWstd29yZDtcXHJcXG4gICAgd2hpdGUtc3BhY2U6IG5vcm1hbDtcXHJcXG59XFxyXFxuXFxyXFxuLnRvb2x0aXAtY2VsbCB7XFxyXFxuICAgIC8qIGNvbG9yOiBibHVlOyAqL1xcclxcbiAgICAvKiB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsgKi9cXHJcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcclxcbn1cXHJcXG5cXHJcXG4udG9vbHRpcC1jZWxsIC5pbmZvLWljb24ge1xcclxcbiAgICBtYXJnaW4tbGVmdDogNXB4O1xcclxcbiAgICBjb2xvcjogdmFyKC0tc3Bpcml0Z3JlZW4pO1xcclxcbiAgICBmb250LXNpemU6IDE1cHg7XFxyXFxufVxcclxcblxcclxcbi50b29sdGlwLWNlbGw6aG92ZXIge1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjBmMGYwOyAvKiBDaGFuZ2UgYmFja2dyb3VuZCBvbiBob3ZlciAqL1xcclxcbn1cXHJcXG5cXHJcXG4uZGV0YWlsIHtcXHJcXG4gICAgY29sb3I6IGJsdWU7XFxyXFxuICAgIGNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XFxyXFxuICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xcclxcbiAgICBtYXJnaW4tbGVmdDogNXB4O1xcclxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcbi8vIEV4cG9ydHNcbmV4cG9ydCBkZWZhdWx0IF9fX0NTU19MT0FERVJfRVhQT1JUX19fO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///843\n')},235:(module,__webpack_exports__,__webpack_require__)=>{eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(354);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(314);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/* Welcome page (index.html) */\r\n\r\n.step {\r\n width: 60%;\r\n height: 80px;\r\n font-size: 1.75em;\r\n margin-bottom: 0px; /* Adds spacing between buttons */\r\n margin-left: 20%;\r\n border-color: var(--citygreen);\r\n border-width: 2;\r\n color: var(--citygreen);\r\n background-color: white;\r\n}\r\n\r\n.step:hover {\r\n color: white;\r\n background-color: var(--spiritgreen);\r\n}\r\n\r\n#welcome-page {\r\n justify-content: center; \r\n align-items: center; \r\n padding-top: 20px;\r\n}\r\n.step.disabled {\r\n opacity: 50%;\r\n}`, "",{"version":3,"sources":["webpack://./src/js/components/welcome/welcome.css"],"names":[],"mappings":"AAAA,8BAA8B;;AAE9B;IACI,UAAU;IACV,YAAY;IACZ,iBAAiB;IACjB,kBAAkB,EAAE,iCAAiC;IACrD,gBAAgB;IAChB,8BAA8B;IAC9B,eAAe;IACf,uBAAuB;IACvB,uBAAuB;AAC3B;;AAEA;IACI,YAAY;IACZ,oCAAoC;AACxC;;AAEA;IACI,uBAAuB;IACvB,mBAAmB;IACnB,iBAAiB;AACrB;AACA;IACI,YAAY;AAChB","sourcesContent":["/* Welcome page (index.html) */\\r\\n\\r\\n.step {\\r\\n width: 60%;\\r\\n height: 80px;\\r\\n font-size: 1.75em;\\r\\n margin-bottom: 0px; /* Adds spacing between buttons */\\r\\n margin-left: 20%;\\r\\n border-color: var(--citygreen);\\r\\n border-width: 2;\\r\\n color: var(--citygreen);\\r\\n background-color: white;\\r\\n}\\r\\n\\r\\n.step:hover {\\r\\n color: white;\\r\\n background-color: var(--spiritgreen);\\r\\n}\\r\\n\\r\\n#welcome-page {\\r\\n justify-content: center; \\r\\n align-items: center; \\r\\n padding-top: 20px;\\r\\n}\\r\\n.step.disabled {\\r\\n opacity: 50%;\\r\\n}"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjM1LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL2J1ZGdldC1yZXF1ZXN0LWZvcm0vLi9zcmMvanMvY29tcG9uZW50cy93ZWxjb21lL3dlbGNvbWUuY3NzP2IzNDgiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgYC8qIFdlbGNvbWUgcGFnZSAoaW5kZXguaHRtbCkgKi9cclxuXHJcbi5zdGVwIHtcclxuICAgIHdpZHRoOiA2MCU7XHJcbiAgICBoZWlnaHQ6IDgwcHg7XHJcbiAgICBmb250LXNpemU6IDEuNzVlbTtcclxuICAgIG1hcmdpbi1ib3R0b206IDBweDsgLyogQWRkcyBzcGFjaW5nIGJldHdlZW4gYnV0dG9ucyAqL1xyXG4gICAgbWFyZ2luLWxlZnQ6IDIwJTtcclxuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcclxuICAgIGJvcmRlci13aWR0aDogMjtcclxuICAgIGNvbG9yOiB2YXIoLS1jaXR5Z3JlZW4pO1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XHJcbn1cclxuXHJcbi5zdGVwOmhvdmVyIHtcclxuICAgIGNvbG9yOiB3aGl0ZTtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNwaXJpdGdyZWVuKTtcclxufVxyXG5cclxuI3dlbGNvbWUtcGFnZSB7XHJcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgXHJcbiAgICBhbGlnbi1pdGVtczogY2VudGVyOyBcclxuICAgIHBhZGRpbmctdG9wOiAyMHB4O1xyXG59XHJcbi5zdGVwLmRpc2FibGVkIHtcclxuICAgIG9wYWNpdHk6IDUwJTtcclxufWAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2pzL2NvbXBvbmVudHMvd2VsY29tZS93ZWxjb21lLmNzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQSw4QkFBOEI7O0FBRTlCO0lBQ0ksVUFBVTtJQUNWLFlBQVk7SUFDWixpQkFBaUI7SUFDakIsa0JBQWtCLEVBQUUsaUNBQWlDO0lBQ3JELGdCQUFnQjtJQUNoQiw4QkFBOEI7SUFDOUIsZUFBZTtJQUNmLHVCQUF1QjtJQUN2Qix1QkFBdUI7QUFDM0I7O0FBRUE7SUFDSSxZQUFZO0lBQ1osb0NBQW9DO0FBQ3hDOztBQUVBO0lBQ0ksdUJBQXVCO0lBQ3ZCLG1CQUFtQjtJQUNuQixpQkFBaUI7QUFDckI7QUFDQTtJQUNJLFlBQVk7QUFDaEJcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLyogV2VsY29tZSBwYWdlIChpbmRleC5odG1sKSAqL1xcclxcblxcclxcbi5zdGVwIHtcXHJcXG4gICAgd2lkdGg6IDYwJTtcXHJcXG4gICAgaGVpZ2h0OiA4MHB4O1xcclxcbiAgICBmb250LXNpemU6IDEuNzVlbTtcXHJcXG4gICAgbWFyZ2luLWJvdHRvbTogMHB4OyAvKiBBZGRzIHNwYWNpbmcgYmV0d2VlbiBidXR0b25zICovXFxyXFxuICAgIG1hcmdpbi1sZWZ0OiAyMCU7XFxyXFxuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcXHJcXG4gICAgYm9yZGVyLXdpZHRoOiAyO1xcclxcbiAgICBjb2xvcjogdmFyKC0tY2l0eWdyZWVuKTtcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XFxyXFxufVxcclxcblxcclxcbi5zdGVwOmhvdmVyIHtcXHJcXG4gICAgY29sb3I6IHdoaXRlO1xcclxcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1zcGlyaXRncmVlbik7XFxyXFxufVxcclxcblxcclxcbiN3ZWxjb21lLXBhZ2Uge1xcclxcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgXFxyXFxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7IFxcclxcbiAgICBwYWRkaW5nLXRvcDogMjBweDtcXHJcXG59XFxyXFxuLnN0ZXAuZGlzYWJsZWQge1xcclxcbiAgICBvcGFjaXR5OiA1MCU7XFxyXFxufVwiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuLy8gRXhwb3J0c1xuZXhwb3J0IGRlZmF1bHQgX19fQ1NTX0xPQURFUl9FWFBPUlRfX187XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///235\n')},314:module=>{eval('\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = "";\n var needLayer = typeof item[5] !== "undefined";\n if (item[4]) {\n content += "@supports (".concat(item[4], ") {");\n }\n if (item[2]) {\n content += "@media ".concat(item[2], " {");\n }\n if (needLayer) {\n content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += "}";\n }\n if (item[2]) {\n content += "}";\n }\n if (item[4]) {\n content += "}";\n }\n return content;\n }).join("");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === "string") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== "undefined") {\n if (typeof item[5] === "undefined") {\n item[5] = layer;\n } else {\n item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = "".concat(supports);\n } else {\n item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzE0LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanM/MjRmYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLypcbiAgTUlUIExpY2Vuc2UgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHBcbiAgQXV0aG9yIFRvYmlhcyBLb3BwZXJzIEBzb2tyYVxuKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGNzc1dpdGhNYXBwaW5nVG9TdHJpbmcpIHtcbiAgdmFyIGxpc3QgPSBbXTtcblxuICAvLyByZXR1cm4gdGhlIGxpc3Qgb2YgbW9kdWxlcyBhcyBjc3Mgc3RyaW5nXG4gIGxpc3QudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHZhciBjb250ZW50ID0gXCJcIjtcbiAgICAgIHZhciBuZWVkTGF5ZXIgPSB0eXBlb2YgaXRlbVs1XSAhPT0gXCJ1bmRlZmluZWRcIjtcbiAgICAgIGlmIChpdGVtWzRdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJAc3VwcG9ydHMgKFwiLmNvbmNhdChpdGVtWzRdLCBcIikge1wiKTtcbiAgICAgIH1cbiAgICAgIGlmIChpdGVtWzJdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJAbWVkaWEgXCIuY29uY2F0KGl0ZW1bMl0sIFwiIHtcIik7XG4gICAgICB9XG4gICAgICBpZiAobmVlZExheWVyKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJAbGF5ZXJcIi5jb25jYXQoaXRlbVs1XS5sZW5ndGggPiAwID8gXCIgXCIuY29uY2F0KGl0ZW1bNV0pIDogXCJcIiwgXCIge1wiKTtcbiAgICAgIH1cbiAgICAgIGNvbnRlbnQgKz0gY3NzV2l0aE1hcHBpbmdUb1N0cmluZyhpdGVtKTtcbiAgICAgIGlmIChuZWVkTGF5ZXIpIHtcbiAgICAgICAgY29udGVudCArPSBcIn1cIjtcbiAgICAgIH1cbiAgICAgIGlmIChpdGVtWzJdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJ9XCI7XG4gICAgICB9XG4gICAgICBpZiAoaXRlbVs0XSkge1xuICAgICAgICBjb250ZW50ICs9IFwifVwiO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvbnRlbnQ7XG4gICAgfSkuam9pbihcIlwiKTtcbiAgfTtcblxuICAvLyBpbXBvcnQgYSBsaXN0IG9mIG1vZHVsZXMgaW50byB0aGUgbGlzdFxuICBsaXN0LmkgPSBmdW5jdGlvbiBpKG1vZHVsZXMsIG1lZGlhLCBkZWR1cGUsIHN1cHBvcnRzLCBsYXllcikge1xuICAgIGlmICh0eXBlb2YgbW9kdWxlcyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgbW9kdWxlcyA9IFtbbnVsbCwgbW9kdWxlcywgdW5kZWZpbmVkXV07XG4gICAgfVxuICAgIHZhciBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzID0ge307XG4gICAgaWYgKGRlZHVwZSkge1xuICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCB0aGlzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgIHZhciBpZCA9IHRoaXNba11bMF07XG4gICAgICAgIGlmIChpZCAhPSBudWxsKSB7XG4gICAgICAgICAgYWxyZWFkeUltcG9ydGVkTW9kdWxlc1tpZF0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAodmFyIF9rID0gMDsgX2sgPCBtb2R1bGVzLmxlbmd0aDsgX2srKykge1xuICAgICAgdmFyIGl0ZW0gPSBbXS5jb25jYXQobW9kdWxlc1tfa10pO1xuICAgICAgaWYgKGRlZHVwZSAmJiBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2l0ZW1bMF1dKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBsYXllciAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBpZiAodHlwZW9mIGl0ZW1bNV0gPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBpdGVtWzVdID0gbGF5ZXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbVsxXSA9IFwiQGxheWVyXCIuY29uY2F0KGl0ZW1bNV0ubGVuZ3RoID4gMCA/IFwiIFwiLmNvbmNhdChpdGVtWzVdKSA6IFwiXCIsIFwiIHtcIikuY29uY2F0KGl0ZW1bMV0sIFwifVwiKTtcbiAgICAgICAgICBpdGVtWzVdID0gbGF5ZXI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZWRpYSkge1xuICAgICAgICBpZiAoIWl0ZW1bMl0pIHtcbiAgICAgICAgICBpdGVtWzJdID0gbWVkaWE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbVsxXSA9IFwiQG1lZGlhIFwiLmNvbmNhdChpdGVtWzJdLCBcIiB7XCIpLmNvbmNhdChpdGVtWzFdLCBcIn1cIik7XG4gICAgICAgICAgaXRlbVsyXSA9IG1lZGlhO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc3VwcG9ydHMpIHtcbiAgICAgICAgaWYgKCFpdGVtWzRdKSB7XG4gICAgICAgICAgaXRlbVs0XSA9IFwiXCIuY29uY2F0KHN1cHBvcnRzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpdGVtWzFdID0gXCJAc3VwcG9ydHMgKFwiLmNvbmNhdChpdGVtWzRdLCBcIikge1wiKS5jb25jYXQoaXRlbVsxXSwgXCJ9XCIpO1xuICAgICAgICAgIGl0ZW1bNF0gPSBzdXBwb3J0cztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGlzdC5wdXNoKGl0ZW0pO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIGxpc3Q7XG59OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///314\n')},354:module=>{eval('\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === "function") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);\n var sourceMapping = "/*# ".concat(data, " */");\n return [content].concat([sourceMapping]).join("\\n");\n }\n return [content].join("\\n");\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzU0LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzP2FmMTIiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgdmFyIGNvbnRlbnQgPSBpdGVtWzFdO1xuICB2YXIgY3NzTWFwcGluZyA9IGl0ZW1bM107XG4gIGlmICghY3NzTWFwcGluZykge1xuICAgIHJldHVybiBjb250ZW50O1xuICB9XG4gIGlmICh0eXBlb2YgYnRvYSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgdmFyIGJhc2U2NCA9IGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KGNzc01hcHBpbmcpKSkpO1xuICAgIHZhciBkYXRhID0gXCJzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxcIi5jb25jYXQoYmFzZTY0KTtcbiAgICB2YXIgc291cmNlTWFwcGluZyA9IFwiLyojIFwiLmNvbmNhdChkYXRhLCBcIiAqL1wiKTtcbiAgICByZXR1cm4gW2NvbnRlbnRdLmNvbmNhdChbc291cmNlTWFwcGluZ10pLmpvaW4oXCJcXG5cIik7XG4gIH1cbiAgcmV0dXJuIFtjb250ZW50XS5qb2luKFwiXFxuXCIpO1xufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///354\n')},72:module=>{eval('\n\nvar stylesInDOM = [];\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n return result;\n}\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = "".concat(id, " ").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n identifiers.push(identifier);\n }\n return identifiers;\n}\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n return updater;\n}\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n var newLastIdentifiers = modulesToDom(newList, options);\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n var _index = getIndexByIdentifier(_identifier);\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n stylesInDOM.splice(_index, 1);\n }\n }\n lastIdentifiers = newLastIdentifiers;\n };\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qcz8yZGJhIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG52YXIgc3R5bGVzSW5ET00gPSBbXTtcbmZ1bmN0aW9uIGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpIHtcbiAgdmFyIHJlc3VsdCA9IC0xO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0eWxlc0luRE9NLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHN0eWxlc0luRE9NW2ldLmlkZW50aWZpZXIgPT09IGlkZW50aWZpZXIpIHtcbiAgICAgIHJlc3VsdCA9IGk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIG1vZHVsZXNUb0RvbShsaXN0LCBvcHRpb25zKSB7XG4gIHZhciBpZENvdW50TWFwID0ge307XG4gIHZhciBpZGVudGlmaWVycyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV07XG4gICAgdmFyIGlkID0gb3B0aW9ucy5iYXNlID8gaXRlbVswXSArIG9wdGlvbnMuYmFzZSA6IGl0ZW1bMF07XG4gICAgdmFyIGNvdW50ID0gaWRDb3VudE1hcFtpZF0gfHwgMDtcbiAgICB2YXIgaWRlbnRpZmllciA9IFwiXCIuY29uY2F0KGlkLCBcIiBcIikuY29uY2F0KGNvdW50KTtcbiAgICBpZENvdW50TWFwW2lkXSA9IGNvdW50ICsgMTtcbiAgICB2YXIgaW5kZXhCeUlkZW50aWZpZXIgPSBnZXRJbmRleEJ5SWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAgICB2YXIgb2JqID0ge1xuICAgICAgY3NzOiBpdGVtWzFdLFxuICAgICAgbWVkaWE6IGl0ZW1bMl0sXG4gICAgICBzb3VyY2VNYXA6IGl0ZW1bM10sXG4gICAgICBzdXBwb3J0czogaXRlbVs0XSxcbiAgICAgIGxheWVyOiBpdGVtWzVdXG4gICAgfTtcbiAgICBpZiAoaW5kZXhCeUlkZW50aWZpZXIgIT09IC0xKSB7XG4gICAgICBzdHlsZXNJbkRPTVtpbmRleEJ5SWRlbnRpZmllcl0ucmVmZXJlbmNlcysrO1xuICAgICAgc3R5bGVzSW5ET01baW5kZXhCeUlkZW50aWZpZXJdLnVwZGF0ZXIob2JqKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHVwZGF0ZXIgPSBhZGRFbGVtZW50U3R5bGUob2JqLCBvcHRpb25zKTtcbiAgICAgIG9wdGlvbnMuYnlJbmRleCA9IGk7XG4gICAgICBzdHlsZXNJbkRPTS5zcGxpY2UoaSwgMCwge1xuICAgICAgICBpZGVudGlmaWVyOiBpZGVudGlmaWVyLFxuICAgICAgICB1cGRhdGVyOiB1cGRhdGVyLFxuICAgICAgICByZWZlcmVuY2VzOiAxXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWRlbnRpZmllcnMucHVzaChpZGVudGlmaWVyKTtcbiAgfVxuICByZXR1cm4gaWRlbnRpZmllcnM7XG59XG5mdW5jdGlvbiBhZGRFbGVtZW50U3R5bGUob2JqLCBvcHRpb25zKSB7XG4gIHZhciBhcGkgPSBvcHRpb25zLmRvbUFQSShvcHRpb25zKTtcbiAgYXBpLnVwZGF0ZShvYmopO1xuICB2YXIgdXBkYXRlciA9IGZ1bmN0aW9uIHVwZGF0ZXIobmV3T2JqKSB7XG4gICAgaWYgKG5ld09iaikge1xuICAgICAgaWYgKG5ld09iai5jc3MgPT09IG9iai5jc3MgJiYgbmV3T2JqLm1lZGlhID09PSBvYmoubWVkaWEgJiYgbmV3T2JqLnNvdXJjZU1hcCA9PT0gb2JqLnNvdXJjZU1hcCAmJiBuZXdPYmouc3VwcG9ydHMgPT09IG9iai5zdXBwb3J0cyAmJiBuZXdPYmoubGF5ZXIgPT09IG9iai5sYXllcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBhcGkudXBkYXRlKG9iaiA9IG5ld09iaik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwaS5yZW1vdmUoKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiB1cGRhdGVyO1xufVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobGlzdCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgbGlzdCA9IGxpc3QgfHwgW107XG4gIHZhciBsYXN0SWRlbnRpZmllcnMgPSBtb2R1bGVzVG9Eb20obGlzdCwgb3B0aW9ucyk7XG4gIHJldHVybiBmdW5jdGlvbiB1cGRhdGUobmV3TGlzdCkge1xuICAgIG5ld0xpc3QgPSBuZXdMaXN0IHx8IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGFzdElkZW50aWZpZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaWRlbnRpZmllciA9IGxhc3RJZGVudGlmaWVyc1tpXTtcbiAgICAgIHZhciBpbmRleCA9IGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpO1xuICAgICAgc3R5bGVzSW5ET01baW5kZXhdLnJlZmVyZW5jZXMtLTtcbiAgICB9XG4gICAgdmFyIG5ld0xhc3RJZGVudGlmaWVycyA9IG1vZHVsZXNUb0RvbShuZXdMaXN0LCBvcHRpb25zKTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgbGFzdElkZW50aWZpZXJzLmxlbmd0aDsgX2krKykge1xuICAgICAgdmFyIF9pZGVudGlmaWVyID0gbGFzdElkZW50aWZpZXJzW19pXTtcbiAgICAgIHZhciBfaW5kZXggPSBnZXRJbmRleEJ5SWRlbnRpZmllcihfaWRlbnRpZmllcik7XG4gICAgICBpZiAoc3R5bGVzSW5ET01bX2luZGV4XS5yZWZlcmVuY2VzID09PSAwKSB7XG4gICAgICAgIHN0eWxlc0luRE9NW19pbmRleF0udXBkYXRlcigpO1xuICAgICAgICBzdHlsZXNJbkRPTS5zcGxpY2UoX2luZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGFzdElkZW50aWZpZXJzID0gbmV3TGFzdElkZW50aWZpZXJzO1xuICB9O1xufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///72\n')},659:module=>{eval('\n\nvar memo = {};\n\n/* istanbul ignore next */\nfunction getTarget(target) {\n if (typeof memo[target] === "undefined") {\n var styleTarget = document.querySelector(target);\n\n // Special case to return head of iframe instead of iframe itself\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n memo[target] = styleTarget;\n }\n return memo[target];\n}\n\n/* istanbul ignore next */\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n if (!target) {\n throw new Error("Couldn\'t find a style target. This probably means that the value for the \'insert\' parameter is invalid.");\n }\n target.appendChild(style);\n}\nmodule.exports = insertBySelector;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjU5LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanM/YjIxNCJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxudmFyIG1lbW8gPSB7fTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBnZXRUYXJnZXQodGFyZ2V0KSB7XG4gIGlmICh0eXBlb2YgbWVtb1t0YXJnZXRdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgdmFyIHN0eWxlVGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0YXJnZXQpO1xuXG4gICAgLy8gU3BlY2lhbCBjYXNlIHRvIHJldHVybiBoZWFkIG9mIGlmcmFtZSBpbnN0ZWFkIG9mIGlmcmFtZSBpdHNlbGZcbiAgICBpZiAod2luZG93LkhUTUxJRnJhbWVFbGVtZW50ICYmIHN0eWxlVGFyZ2V0IGluc3RhbmNlb2Ygd2luZG93LkhUTUxJRnJhbWVFbGVtZW50KSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFjY2VzcyB0byBpZnJhbWUgaXMgYmxvY2tlZFxuICAgICAgICAvLyBkdWUgdG8gY3Jvc3Mtb3JpZ2luIHJlc3RyaWN0aW9uc1xuICAgICAgICBzdHlsZVRhcmdldCA9IHN0eWxlVGFyZ2V0LmNvbnRlbnREb2N1bWVudC5oZWFkO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpc3RhbmJ1bCBpZ25vcmUgbmV4dFxuICAgICAgICBzdHlsZVRhcmdldCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIG1lbW9bdGFyZ2V0XSA9IHN0eWxlVGFyZ2V0O1xuICB9XG4gIHJldHVybiBtZW1vW3RhcmdldF07XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gaW5zZXJ0QnlTZWxlY3RvcihpbnNlcnQsIHN0eWxlKSB7XG4gIHZhciB0YXJnZXQgPSBnZXRUYXJnZXQoaW5zZXJ0KTtcbiAgaWYgKCF0YXJnZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZG4ndCBmaW5kIGEgc3R5bGUgdGFyZ2V0LiBUaGlzIHByb2JhYmx5IG1lYW5zIHRoYXQgdGhlIHZhbHVlIGZvciB0aGUgJ2luc2VydCcgcGFyYW1ldGVyIGlzIGludmFsaWQuXCIpO1xuICB9XG4gIHRhcmdldC5hcHBlbmRDaGlsZChzdHlsZSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGluc2VydEJ5U2VsZWN0b3I7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///659\n')},540:module=>{eval('\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement("style");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\nmodule.exports = insertStyleElement;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQwLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qcz9kZTZjIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zKSB7XG4gIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICBvcHRpb25zLnNldEF0dHJpYnV0ZXMoZWxlbWVudCwgb3B0aW9ucy5hdHRyaWJ1dGVzKTtcbiAgb3B0aW9ucy5pbnNlcnQoZWxlbWVudCwgb3B0aW9ucy5vcHRpb25zKTtcbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGluc2VydFN0eWxlRWxlbWVudDsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///540\n')},56:(module,__unused_webpack_exports,__webpack_require__)=>{eval('\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = true ? __webpack_require__.nc : 0;\n if (nonce) {\n styleElement.setAttribute("nonce", nonce);\n }\n}\nmodule.exports = setAttributesWithoutAttributes;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTYuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzP2RkY2UiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzKHN0eWxlRWxlbWVudCkge1xuICB2YXIgbm9uY2UgPSB0eXBlb2YgX193ZWJwYWNrX25vbmNlX18gIT09IFwidW5kZWZpbmVkXCIgPyBfX3dlYnBhY2tfbm9uY2VfXyA6IG51bGw7XG4gIGlmIChub25jZSkge1xuICAgIHN0eWxlRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJub25jZVwiLCBub25jZSk7XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0gc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///56\n')},825:module=>{eval('\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = "";\n if (obj.supports) {\n css += "@supports (".concat(obj.supports, ") {");\n }\n if (obj.media) {\n css += "@media ".concat(obj.media, " {");\n }\n var needLayer = typeof obj.layer !== "undefined";\n if (needLayer) {\n css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");\n }\n css += obj.css;\n if (needLayer) {\n css += "}";\n }\n if (obj.media) {\n css += "}";\n }\n if (obj.supports) {\n css += "}";\n }\n var sourceMap = obj.sourceMap;\n if (sourceMap && typeof btoa !== "undefined") {\n css += "\\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");\n }\n\n // For old IE\n /* istanbul ignore if */\n options.styleTagTransform(css, styleElement, options.options);\n}\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n styleElement.parentNode.removeChild(styleElement);\n}\n\n/* istanbul ignore next */\nfunction domAPI(options) {\n if (typeof document === "undefined") {\n return {\n update: function update() {},\n remove: function remove() {}\n };\n }\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\nmodule.exports = domAPI;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODI1LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYnVkZ2V0LXJlcXVlc3QtZm9ybS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzP2U0NzkiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gYXBwbHkoc3R5bGVFbGVtZW50LCBvcHRpb25zLCBvYmopIHtcbiAgdmFyIGNzcyA9IFwiXCI7XG4gIGlmIChvYmouc3VwcG9ydHMpIHtcbiAgICBjc3MgKz0gXCJAc3VwcG9ydHMgKFwiLmNvbmNhdChvYmouc3VwcG9ydHMsIFwiKSB7XCIpO1xuICB9XG4gIGlmIChvYmoubWVkaWEpIHtcbiAgICBjc3MgKz0gXCJAbWVkaWEgXCIuY29uY2F0KG9iai5tZWRpYSwgXCIge1wiKTtcbiAgfVxuICB2YXIgbmVlZExheWVyID0gdHlwZW9mIG9iai5sYXllciAhPT0gXCJ1bmRlZmluZWRcIjtcbiAgaWYgKG5lZWRMYXllcikge1xuICAgIGNzcyArPSBcIkBsYXllclwiLmNvbmNhdChvYmoubGF5ZXIubGVuZ3RoID4gMCA/IFwiIFwiLmNvbmNhdChvYmoubGF5ZXIpIDogXCJcIiwgXCIge1wiKTtcbiAgfVxuICBjc3MgKz0gb2JqLmNzcztcbiAgaWYgKG5lZWRMYXllcikge1xuICAgIGNzcyArPSBcIn1cIjtcbiAgfVxuICBpZiAob2JqLm1lZGlhKSB7XG4gICAgY3NzICs9IFwifVwiO1xuICB9XG4gIGlmIChvYmouc3VwcG9ydHMpIHtcbiAgICBjc3MgKz0gXCJ9XCI7XG4gIH1cbiAgdmFyIHNvdXJjZU1hcCA9IG9iai5zb3VyY2VNYXA7XG4gIGlmIChzb3VyY2VNYXAgJiYgdHlwZW9mIGJ0b2EgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBjc3MgKz0gXCJcXG4vKiMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247YmFzZTY0LFwiLmNvbmNhdChidG9hKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChKU09OLnN0cmluZ2lmeShzb3VyY2VNYXApKSkpLCBcIiAqL1wiKTtcbiAgfVxuXG4gIC8vIEZvciBvbGQgSUVcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICAqL1xuICBvcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtKGNzcywgc3R5bGVFbGVtZW50LCBvcHRpb25zLm9wdGlvbnMpO1xufVxuZnVuY3Rpb24gcmVtb3ZlU3R5bGVFbGVtZW50KHN0eWxlRWxlbWVudCkge1xuICAvLyBpc3RhbmJ1bCBpZ25vcmUgaWZcbiAgaWYgKHN0eWxlRWxlbWVudC5wYXJlbnROb2RlID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHN0eWxlRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudCk7XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gZG9tQVBJKG9wdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgIHJldHVybiB7XG4gICAgICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSgpIHt9LFxuICAgICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoKSB7fVxuICAgIH07XG4gIH1cbiAgdmFyIHN0eWxlRWxlbWVudCA9IG9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50KG9wdGlvbnMpO1xuICByZXR1cm4ge1xuICAgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKG9iaikge1xuICAgICAgYXBwbHkoc3R5bGVFbGVtZW50LCBvcHRpb25zLCBvYmopO1xuICAgIH0sXG4gICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoKSB7XG4gICAgICByZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KTtcbiAgICB9XG4gIH07XG59XG5tb2R1bGUuZXhwb3J0cyA9IGRvbUFQSTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///825\n')},113:module=>{eval("\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n styleElement.appendChild(document.createTextNode(css));\n }\n}\nmodule.exports = styleTagTransform;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTEzLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9idWRnZXQtcmVxdWVzdC1mb3JtLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanM/MWRkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBzdHlsZVRhZ1RyYW5zZm9ybShjc3MsIHN0eWxlRWxlbWVudCkge1xuICBpZiAoc3R5bGVFbGVtZW50LnN0eWxlU2hlZXQpIHtcbiAgICBzdHlsZUVsZW1lbnQuc3R5bGVTaGVldC5jc3NUZXh0ID0gY3NzO1xuICB9IGVsc2Uge1xuICAgIHdoaWxlIChzdHlsZUVsZW1lbnQuZmlyc3RDaGlsZCkge1xuICAgICAgc3R5bGVFbGVtZW50LnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudC5maXJzdENoaWxkKTtcbiAgICB9XG4gICAgc3R5bGVFbGVtZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcykpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHN0eWxlVGFnVHJhbnNmb3JtOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///113\n")}},__webpack_module_cache__={};function __webpack_require__(n){var c=__webpack_module_cache__[n];if(void 0!==c)return c.exports;var t=__webpack_module_cache__[n]={id:n,exports:{}};return __webpack_modules__[n](t,t.exports,__webpack_require__),t.exports}__webpack_require__.n=n=>{var c=n&&n.__esModule?()=>n.default:()=>n;return __webpack_require__.d(c,{a:c}),c},__webpack_require__.d=(n,c)=>{for(var t in c)__webpack_require__.o(c,t)&&!__webpack_require__.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:c[t]})},__webpack_require__.o=(n,c)=>Object.prototype.hasOwnProperty.call(n,c),__webpack_require__.nc=void 0;var __webpack_exports__=__webpack_require__(254)})(); \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 252677a..0fcd675 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1 +1 @@ -Demo Budget Form

FY2026 Budget Form


Baseline

Suplemental

\ No newline at end of file +Budget Request Form


Baseline

Suplemental

\ No newline at end of file diff --git a/src/assets/city-of-detroit-logo.png b/src/assets/city-of-detroit-logo.png new file mode 100644 index 0000000..856d278 Binary files /dev/null and b/src/assets/city-of-detroit-logo.png differ diff --git a/src/css/common.css b/src/css/common.css new file mode 100644 index 0000000..6d9a9df --- /dev/null +++ b/src/css/common.css @@ -0,0 +1,62 @@ +:root { + /* colors */ + --orange: #FB6523; + --yellow: #D99733; + --blue: #43748E; + --lightBlue: #b7c9e2; + --darkGray: #373A37; + --mediumGray: #D0D0D0; + --lightGray: #F2F2F2; + --white: #FBFDFB; + --black: #212121; + --green: #71BC78; + --citygreen: #004445; + --spiritgreen: #279989; + --palegreen: #9FD5B3; + --verypalegreen: #DFF5E3; + --accentyellow: #feb70d; + --nearblack: #18252a; + /* fonts */ + font-family: 'Nunito', sans-serif; + font-size: 14px; + /* spacing */ + --header-height : 105px; + --sidebar-width: 300px; +} + +/* Button styling */ + +.btn { + cursor: pointer; + padding: 6px; + margin-top: 5px; + margin-right : 2px; + margin-left: 2px; + border-radius: 10px; + background-color: gray; + color: white; +} + +/* Font application for all text */ +body, button, input, textarea, select, .sidebar, table { + font-family: var(--font-family), sans-serif; + } + +#main-panel { + /* display: flex; */ + /* flex-direction: column; */ + justify-content: center; /* This will center content vertically */ + min-height: calc(100vh - var(--header-height)) ; + /* max-width: calc(100vw - var(--sidebar-width)); */ + padding-top: 25px; + padding-bottom: 25px; + margin: 0; +} + +/* Font awesome */ + +i.fas.fa-check { + font-size: 1.5em; + color: var(--spiritgreen); + margin-right: 10px; +} diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..b94547e --- /dev/null +++ b/src/index.html @@ -0,0 +1,157 @@ + + + + + +Budget Request Form + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

+

+
+ + +
+ + +
+ + + + +
+ + +
+

+
+ + + + + +
+ + + + +
+ + +
+
+ + +
+ + +
+
+ +
+
+ + +
+
+

+ Baseline + +

+
+
+
+

+ Suplemental + +

+
+
+
+ +
+
+ + +
+
+ +
+
+ + + + +
+ + + + + + + + + \ No newline at end of file diff --git a/src/js/components/accordion/accordion.css b/src/js/components/accordion/accordion.css new file mode 100644 index 0000000..55c8e99 --- /dev/null +++ b/src/js/components/accordion/accordion.css @@ -0,0 +1,83 @@ +.summary-accordion { + width: 60%; + margin: auto; +} + +.accordion-title { + margin-left: 20%; + font-weight: bold; + /* font-size: 20px; */ + padding-bottom: 10px; + padding-left: 15px; + padding-top: 30px; +} + +.accordion-button:active, .accordion-button:not(.collapsed) { + background-color: var(--palegreen); + color: var(--citygreen); + /* font-size: 20px; */ +} + +.accordion-table { + width: 100%; + font-size: 1.2em; + /* border-collapse: separate; This is required for rounded corners */ +} + +.accordion-table td:last-child { + text-align: right; + padding-right: 15px; + padding-bottom: 5px +} + +.accordion-table tr { + border-bottom: 1px solid black; + border-top: none; + border-right: none; + border-left: none; +} + +.accordion-table tr:last-child { + border-bottom: none; + background-color: var(--mediumGray); + height : 50px; +} + +span.amount { + font-weight: bold; + position: absolute; + right: 0; + margin-right: 60px; +} + +.accordion-header button { + font-size: 0.8em; +} + +.btn-add-init { + background-color: var(--spiritgreen); + border-color: var(--citygreen); + /* position: absolute; */ + right: 0; + /* margin-left: 20px; */ + /* margin-right: calc(20vw + 15px); */ + margin-top: 15px; +} + +#supp-title { + margin-top: 20px; +} + +.btn-add-init:hover { + background-color: var(--palegreen); +} +.add-init-btn-div{ + text-align: center; +} + +span.top-line-amount { + font-weight: bold; + position: absolute; + right: 0; + margin-right: calc(20vw + 20px); +} \ No newline at end of file diff --git a/src/js/components/accordion/accordion.js b/src/js/components/accordion/accordion.js new file mode 100644 index 0000000..b34efd9 --- /dev/null +++ b/src/js/components/accordion/accordion.js @@ -0,0 +1,225 @@ +import './accordion.css' + + +import {Baseline, CurrentFund, Fund, Supplemental, FundLookupTable} from '../../models' +import { formatCurrency, cleanString } from "../../utils/common_utils.js"; +import Table from "../table/table.js"; +import { visitPage } from '../../views/view_logic.js'; + +function redirectForEdit(){ + const row = document.querySelector(`.active-editing`); + const table = row.parentElement; + const section = table.closest('.summary-container'); + // new initiative edits should all redirect to the new-inits page + if (section.id == 'supp-accordion'){ + visitPage('new-inits'); + } + else { + // Split the string into parts using '-' as the delimiter; retain fund as 1st numeric segment + const fund = table.id.split('-')[1] + + CurrentFund.update(fund); + const lineItem = row.querySelector('.line-item').textContent; + // visit the correct page for editing + switch(lineItem){ + case 'Personnel Expenditures': + visitPage('personnel'); + break; + case 'Non-Personnel Expenditures': + visitPage('nonpersonnel'); + break; + case 'Revenues': + visitPage('revenue'); + break; + case 'Overtime Expenditures': + visitPage('overtime'); + break; + default: + console.error('Name of line item in table does not match a page destination.') + } + } +} + +const AppropriationTable = { + +} + +const ExpenseTable = { + table_id : (account_string) => { return `table-${account_string}` }, + init(account_string) { + // create empty table and put it in the accordion + var table = document.createElement('table'); + table.id = this.table_id(account_string); + table.classList.add('accordion-table'); + var parent = document.querySelector(`#string_${account_string}_content .accordion-body`); + parent.appendChild(table); + }, + createNewCell(content, row, className) { + const newCell = document.createElement('td'); + newCell.innerHTML = content; + newCell.classList.add(className); + row.appendChild(newCell); + }, + addRow(account_string, row_name, number){ + var table = document.getElementById(this.table_id(account_string)); + var new_row = document.createElement('tr'); + table.appendChild(new_row); + // Create a cell for the line item label + this.createNewCell(row_name, new_row, 'line-item'); + // create a cell for the amount + this.createNewCell(formatCurrency(number), new_row, 'cost'); + // create Edit button + var button = ''; + if (row_name != 'Net Expenditures (Revenues)'){ + button = Table.Buttons.Edit.html; + } + this.createNewCell(button, new_row); + }, + fillFromFund(fund) { + // use just fund as account string to initialize table inside accordion + this.init(fund); + const fundObject = new Fund(fund); + + // Add a row for each appropriation in the fund + const id = cleanString(fund); + + fundObject.getAppropriations().forEach( appropObj => { + // if the total for the appropriation is > $0, add an accordion for all the CCs + if ( appropObj.total() != 0 ){ + Item.add(appropObj.accountString(), `#string_${id}_content .accordion-body`); + Item.updateHeader(appropObj.name(), appropObj.accountString(), appropObj.total()); + this.fillFromApprop(appropObj); + } + }) + }, + fillFromApprop(appropObj){ + // initialize the table object + this.init(appropObj.accountString()); + // add a collapsible row for each cost center + appropObj.getCostCenters().forEach( ccObj => { + if (ccObj.getTotal() != 0 ){ + Item.add(ccObj.accountString(), `#string_${appropObj.accountString()}_content .accordion-body`); + Item.updateHeader(ccObj.getName(), ccObj.accountString(), ccObj.getTotal()); + this.fillFromCC(ccObj); + } + }) + + }, + fillFromCC(ccObj){ + // initialize a table and summarize the line items + this.init(ccObj.accountString()); + this.addRow(ccObj.accountString(), 'Personnel Expenditures', ccObj.getPersonnelCost()); + this.addRow(ccObj.accountString(), 'Overtime Expenditures', ccObj.getOvertimeCost()); + this.addRow(ccObj.accountString(), 'Non-Personnel Expenditures', ccObj.getNonPersonnelCost()); + this.addRow(ccObj.accountString(), 'Revenues', ccObj.getRevenue()); + this.addRow(ccObj.accountString(), 'Net Expenditures (Revenues)', ccObj.getTotal()); + }, + fillFromInit(program) { + this.init(program.name); + this.addRow(program.name, 'Expenditures', program.expenses()); + this.addRow(program.name, 'Revenues', program.revenue()); + this.addRow(program.name, 'Net Expenditures (Revenues)', program.net()); + } +} + +const Item = { + accountString(fund, approp = '', cc = '') { + var account_string = cleanString(fund); + if (approp) { account_string += approp }; + if (cc) { account_string += cc }; + return account_string; + }, + html(account_string){ + return `

+ +

+
+
+
` + }, + add : function(account_string, accordion_query) { + // get accordion and add a new item to it + const parent = document.querySelector(accordion_query); + const item_element = document.createElement('div'); + item_element.classList.add('accordion-item'); + item_element.innerHTML = this.html(account_string); + parent.appendChild(item_element); + }, + ExpenseTable : ExpenseTable, + updateHeader : function(title, account_string, new_amount) { + const header_btn = document.querySelector(`#string_${account_string}_header button`); + header_btn.querySelector('span.name').textContent = title; + header_btn.querySelector('span.amount').textContent = formatCurrency(new_amount); + } +} + +const AddInitButton = { + init() { + const btn = document.querySelector('.btn-add-init'); + btn.addEventListener('click', function(){ + visitPage('new-inits'); + }) + } +} + +export const Accordion = { + Item : Item, + AddInitButton: AddInitButton, + hide : function(){ + document.querySelector('#accordion-div').style.display = 'none'; + // reset to delete content + document.querySelector('#baseline-accordion .summary-accordion').innerHTML = ''; + document.querySelector('#supp-accordion .summary-accordion').innerHTML = ''; + }, + show : function(){ + document.querySelector('#accordion-div').style.display = 'block'; + }, + async createBaseline(){ + var funds = FundLookupTable.listFunds(); + funds.forEach(fund => { + Item.add(fund, '#baseline-accordion .summary-accordion'); + Item.ExpenseTable.fillFromFund(fund); + const fundObject = new Fund(fund); + Item.updateHeader(`Fund ${FundLookupTable.getName(fund)}`, fund, fundObject.getTotal()); + }); + }, + createSupp() { + const supp = new Supplemental; + supp.initiatives.forEach(program => { + Item.add(program.name, '#supp-accordion .summary-accordion'); + Item.ExpenseTable.fillFromInit(program); + Item.updateHeader(program.name, program.name, program.net()); + }); + }, + updateTopLines() { + // adjuse baseline + // const baseline = new Baseline; + const baseline = new Fund(1000); + const baselineAmount = document.querySelector('#baseline-title .top-line-amount') + baselineAmount.textContent = formatCurrency(baseline.getTotal()); + // adjust supplementals + const supp = new Supplemental; + const suppAmount = document.querySelector('#supp-title .top-line-amount') + suppAmount.textContent = formatCurrency(supp.total()); + // color-code baseline + if (baseline.getTotal() <= Baseline.target()){ + baselineAmount.style.color = 'green'; + } else { + baselineAmount.style.color = 'red'; + } + }, + build() { + this.createBaseline(); + this.createSupp(); + // initialize edit buttons + Table.Buttons.Edit.init(redirectForEdit); + this.AddInitButton.init(); + this.updateTopLines(); + } +} + + +export default Accordion; diff --git a/src/js/components/body/body.css b/src/js/components/body/body.css new file mode 100644 index 0000000..c669b50 --- /dev/null +++ b/src/js/components/body/body.css @@ -0,0 +1,4 @@ +body { + background-color: var(--lightGray); + margin: 0; +} \ No newline at end of file diff --git a/src/js/components/body/body.js b/src/js/components/body/body.js new file mode 100644 index 0000000..baea720 --- /dev/null +++ b/src/js/components/body/body.js @@ -0,0 +1,38 @@ +import './body.css'; + +import Welcome from '../../components/welcome/welcome.js' +import Accordion from '../accordion/accordion.js'; +import FileUpload from '../file_upload/file_upload.js'; +import Modal from '../modal/modal.js'; +import NavButtons from '../nav_buttons/nav_buttons.js'; +import Prompt from '../prompt/prompt.js'; +import Sidebar from '../sidebar/sidebar.js'; +import Table from '../table/table.js'; +import Tooltip from '../tooltip/tooltip.js'; + +function resetPage() { + // hide everything in the body + Welcome.hide(); + Modal.clear(); + Modal.hide(); + NavButtons.hide(); + Prompt.hide(); + Table.hide(); + Sidebar.hide(); + Accordion.hide(); + FileUpload.hide(); + Tooltip.hide(); + + // reset filter dropdowns + Table.Filter.deleteAll(); + + Prompt.Buttons.reset(); + // disable submit button + Modal.Submit.deinit(); +} + +export const Body = { + reset : resetPage +} + +export default Body; \ No newline at end of file diff --git a/src/js/components/file_upload/file_upload.css b/src/js/components/file_upload/file_upload.css new file mode 100644 index 0000000..5bb2461 --- /dev/null +++ b/src/js/components/file_upload/file_upload.css @@ -0,0 +1,30 @@ +#file-input { + margin-left: 40%; +} + +/* Spinner Styles */ +.spinner { + display: inline-block; + width: 150px; + height: 150px; + border: 20px solid rgba(0, 0, 0, 0.1); + border-radius: 50%; + border-top-color: var(--spiritgreen); + animation: spin 1s ease-in-out infinite; + position: fixed; /* Ensures it stays fixed relative to the viewport */ + top: 20%; /* Center vertically */ + left: 43%; /* Center horizontally */ + transform: translate(-50%, -50%); /* Centralize the spinner exactly */ + z-index: 9999; /* Ensures it appears in front of other elements */ + background-color: rgba(255, 255, 255, 0.8); /* Optional: light background */ + padding: 20px; /* Optional: extra padding for better visibility */ + } + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } \ No newline at end of file diff --git a/src/js/components/file_upload/file_upload.js b/src/js/components/file_upload/file_upload.js new file mode 100644 index 0000000..12994c1 --- /dev/null +++ b/src/js/components/file_upload/file_upload.js @@ -0,0 +1,61 @@ +// file_upload.js +import './file_upload.css'; +import { processWorkbook } from "../../utils/XLSX_handlers.js"; +import NavButtons from '../nav_buttons/nav_buttons.js'; + +export const FileUpload = { + init : function() { + NavButtons.Next.disable(); + const inputObject = document.getElementById('file-input'); + inputObject.addEventListener('change', function(event) { readXL(event) }); + }, + show : function(){ + const inputObject = document.getElementById('file-input'); + inputObject.style.display = ''; + }, + hide : function(){ + const inputObject = document.getElementById('file-input'); + inputObject.style.display = 'none'; + } +}; + +function readXL(event) { + const file = event.target.files[0]; // read uploaded file + const spinner = document.getElementById('upload-spinner'); // get the spinner element + + if (file) { + // Show the spinner + spinner.style.display = 'block'; + + // read in new data + const reader = new FileReader(); + reader.onload = function(e) { + const arrayBuffer = e.target.result; + + try { + processWorkbook(arrayBuffer); + + // Hide the spinner once processing is done + spinner.style.display = 'none'; + NavButtons.Next.enable(); // Enable the next button after processing + } catch (error) { + console.error('Error processing workbook:', error); + + // Hide the spinner in case of an error + spinner.style.display = 'none'; + NavButtons.Next.enable(); // Ensure the button is re-enabled in case of an error + } + }; + reader.onerror = function(err) { + console.error('Error reading file:', err); + + // Hide the spinner in case of an error + spinner.style.display = 'none'; + NavButtons.Next.enable(); // Ensure the button is re-enabled in case of an error + }; + + reader.readAsArrayBuffer(file); // Read the file as an ArrayBuffer + } +} + +export default FileUpload; \ No newline at end of file diff --git a/src/js/components/form/form.css b/src/js/components/form/form.css new file mode 100644 index 0000000..eeecba2 --- /dev/null +++ b/src/js/components/form/form.css @@ -0,0 +1,22 @@ +textarea {height: 100px; width: 100%;} + +textarea, input { + margin-bottom: 20px; +} + +.btn-submit { + margin-top: 20px; + width: 60%; + margin-left: 20%; + background-color: var(--spiritgreen); +} + +#new-form label { + display: block; /* Ensure label is on its own line */ + margin-bottom: 0.25em; +} + +#new-form select { + min-width: 300px; + margin-bottom: 1.25em; +} \ No newline at end of file diff --git a/src/js/components/form/form.js b/src/js/components/form/form.js new file mode 100644 index 0000000..74b64eb --- /dev/null +++ b/src/js/components/form/form.js @@ -0,0 +1,55 @@ +import './form.css'; + +import Dropdown from "./subcomponents/dropdown.js"; +import NewField from "./subcomponents/fields.js"; +import SubmitButton from "./subcomponents/submit.js"; + +function fetchAllResponses(event) { + + // Assuming `event.target` is the form itself + const form = event.target; + + // Initialize an empty array to hold the input values + let formData = {}; + + // Loop through each form element + for (let i = 0; i < form.elements.length; i++) { + const element = form.elements[i]; + + // Exclude elements that aren't inputs, textareas, or select + if (element.tagName === 'INPUT' || + element.tagName === 'TEXTAREA' || + element.tagName === 'SELECT') { + // Exclude input types that are not considered for submission (such as `submit`) + if (element.type !== 'submit' && element.type !== 'button') { + formData[element.id] = element.value; + } + } + } + + form.reset(); + return formData; +} + +function addForm(element_id = 'modal-body', form_id = 'new-form') { + + const target_elem = document.getElementById(element_id); + + // create form + const form = document.createElement('form'); + form.setAttribute('id', form_id); + + // Append the form to the modal body + target_elem.appendChild(form); + +} + +export const Form = { + new : function(parent_elem_id) { addForm(parent_elem_id, 'new-form') }, + fetchAllResponses : function(event) { return fetchAllResponses(event) }, + NewField : NewField, + Dropdown : Dropdown, + SubmitButton : SubmitButton +} + +export default Form; \ No newline at end of file diff --git a/src/js/components/form/subcomponents/dropdown.js b/src/js/components/form/subcomponents/dropdown.js new file mode 100644 index 0000000..ad611b6 --- /dev/null +++ b/src/js/components/form/subcomponents/dropdown.js @@ -0,0 +1,26 @@ +function createDropdown(dataArray) { + + // Creating a select element + const selectElement = document.createElement('select'); + + // add a default blank option to the dataArray + dataArray = [''].concat(dataArray); + + // Looping through the array and creating an option for each element + dataArray.forEach(item => { + const optionElement = document.createElement('option'); + optionElement.value = item; + optionElement.textContent = item; + selectElement.appendChild(optionElement); // Appending the option to the select + }); + + // Return the select element so it can be appended to the document + return selectElement; +} + + +export const Dropdown = { + create : function(dataArray) { return createDropdown(dataArray) }, +} + +export default Dropdown; \ No newline at end of file diff --git a/src/js/components/form/subcomponents/fields.js b/src/js/components/form/subcomponents/fields.js new file mode 100644 index 0000000..ce3d12b --- /dev/null +++ b/src/js/components/form/subcomponents/fields.js @@ -0,0 +1,53 @@ +// function to add questions to forms + +import Dropdown from "./dropdown"; + +// inputType is for validation ('number' or 'text', etc) +function appendFormElement(label, inputEl, inputId, required) { + + // change if we want forms elsewhere + const form = document.getElementById('new-form'); + + // create outer wrapper for element + const wrapper = document.createElement('div'); + + // label question + const labelEl = document.createElement('label'); + labelEl.textContent = label; + + // mark as required if applicable + inputEl.required = required; + + // If an ID is provided, set it on the element + if (inputId) { + inputEl.id = inputId; + } + + // add elements + wrapper.appendChild(labelEl); + wrapper.appendChild(inputEl); + form.appendChild(wrapper); +} + +export const NewField = { + shortText : function(label, inputId, required = false) { + const inputEl = document.createElement('input'); + inputEl.type = 'text'; + appendFormElement(label, inputEl, inputId,required); + }, + longText : function(label, inputId, required = false) { + const inputEl = document.createElement('textarea'); + appendFormElement(label, inputEl, inputId, required); + }, + numericInput : function(label, inputId, required = false) { + const inputEl = document.createElement('input'); + inputEl.type = 'number'; + appendFormElement(label, inputEl, inputId,required); + }, + dropdown : function(label, inputId, optionArray, required = false){ + var inputEl = Dropdown.create(optionArray); + appendFormElement(label, inputEl, inputId, required); + } +} + +export default NewField; \ No newline at end of file diff --git a/src/js/components/form/subcomponents/submit.js b/src/js/components/form/subcomponents/submit.js new file mode 100644 index 0000000..3a47d55 --- /dev/null +++ b/src/js/components/form/subcomponents/submit.js @@ -0,0 +1,26 @@ +function addSubmitButtonToForm(form_id) { + // Find the form by its ID + const form = document.getElementById(form_id); + + // Create the container `div` for the button + const buttonContainer = document.createElement('div'); + buttonContainer.id = 'submit-btn-container'; + + // Create the submit input + const submitInput = document.createElement('input'); + submitInput.className = 'btn btn-submit'; // Use appropriate class for your design + submitInput.type = 'submit'; + submitInput.value = 'Submit'; + + // Append the submit input to the container + buttonContainer.appendChild(submitInput); + + // Append the container to the form + form.appendChild(buttonContainer); +} + +export const SubmitButton = { + add : function() { addSubmitButtonToForm('new-form') } +} + +export default SubmitButton; \ No newline at end of file diff --git a/src/js/components/header/header.css b/src/js/components/header/header.css new file mode 100644 index 0000000..01365ce --- /dev/null +++ b/src/js/components/header/header.css @@ -0,0 +1,30 @@ + +h1 { + text-align: center; + font-size: 30px; +} + +h2 { + color: var(--darkGray); + text-align: center; + font-size: 20px; +} + +header { + align-items: center; + background-color: white; + padding: 5px; + border-bottom: 1px solid var(--citygreen); + /* border: 1px solid var(--citygreen); */ + height: var(--header-height); + /* width: calc(100vw - var(--sidebar-width)); */ + padding-left: 20px; +} + +/* Logo styling */ +#logo { + height: 50px; /* Or your desired size */ + margin-right: 20px; /* Optional: space between logo and title */ + margin-bottom: -50px; + margin-top: 10px; +} \ No newline at end of file diff --git a/src/js/components/header/header.js b/src/js/components/header/header.js new file mode 100644 index 0000000..70fcce7 --- /dev/null +++ b/src/js/components/header/header.js @@ -0,0 +1,24 @@ +import './header.css'; + +import CurrentFund from '../../models/current_fund'; +import { FISCAL_YEAR } from '../../constants'; + +export const Title = { + update : function(title){ + document.getElementById("title").textContent = title; + }, + default() { + this.update(`FY${FISCAL_YEAR} Budget Request`) + } +} + +export const Subtitle = { + update : function(subtitle){ + // get current fund + var fund = CurrentFund.name(); + if (fund){ + var subtitle = `${subtitle}: ${fund}`; + } + document.getElementById("subtitle").textContent = subtitle; + } +} \ No newline at end of file diff --git a/src/js/components/modal/modal.css b/src/js/components/modal/modal.css new file mode 100644 index 0000000..e69de29 diff --git a/src/js/components/modal/modal.js b/src/js/components/modal/modal.js new file mode 100644 index 0000000..460e17c --- /dev/null +++ b/src/js/components/modal/modal.js @@ -0,0 +1,78 @@ + +import './modal.css'; + +function clearModal(){ + updateModalTitle(''); + document.getElementById('modal-body').innerHTML = ''; +} + +function hideModal() { + $('#main-modal').modal('hide'); +} + +function showModal() { + $('#main-modal').modal('show'); +} + +function showModalHandler() { + showModal('main-modal'); +} + +const Submit = { + handler: null, + + init: function(onSubmit) { + const modal = document.getElementById('main-modal'); + // add onSubmit function as handler + this.handler = function(event) { + event.preventDefault(); + onSubmit(event); + }; + // Adding the handler reference as the event listener + modal.addEventListener('submit', this.handler); + + // add event listener to enable close x + const x = modal.querySelector('#modal-close-x'); + x.addEventListener('click', hideModal); + }, + + deinit: function() { + const modal = document.getElementById('main-modal'); + if (this.handler !== null) { + // Removing the event listener and clear the handler + modal.removeEventListener('submit', this.handler); + this.handler = null; + } + // remove event listener to enable close x + const x = modal.querySelector('#modal-close-x'); + x.removeEventListener('click', hideModal); + } +}; + +const Link = { + add : function(button_id){ + document.getElementById(button_id).addEventListener('click', showModalHandler) + }, + remove : function(button_id){ + document.getElementById(button_id).removeEventListener('click', showModalHandler) + } +} + +function updateModalTitle(title) { + document.getElementById('modal-title').textContent = title; +} + +const Title = { + update : function(title) { updateModalTitle(title) } +} + +export const Modal = { + hide : hideModal, + show : showModal, + clear : clearModal, + Title : Title, + Link : Link, + Submit: Submit +} + +export default Modal; \ No newline at end of file diff --git a/src/js/components/nav_buttons/nav_buttons.css b/src/js/components/nav_buttons/nav_buttons.css new file mode 100644 index 0000000..43e7771 --- /dev/null +++ b/src/js/components/nav_buttons/nav_buttons.css @@ -0,0 +1,26 @@ +#nav-btns { + margin: 20px; + text-align: center; + margin-top: 5px; + margin-bottom: 5px; + /* position: absolute; or 'absolute' depending on use-case */ + /* top: 100px; Distance from the top of the viewport or the closest positioned ancestor */ +} + +#btn-next, #btn-last { + background-color: var(--darkGray); +} + +#btn-next:hover, #btn-last:hover { + background-color: var(--yellow); + color: var(--darkGray); +} + +/* Add style for when you cannot click the next button */ +#btn-next.disabled, #btn-last.disabled, +#btn-next.disabled:hover, #btn-last.disabled:hover { + background-color: gray; + color: white; + pointer-events: none; + +} \ No newline at end of file diff --git a/src/js/components/nav_buttons/nav_buttons.js b/src/js/components/nav_buttons/nav_buttons.js new file mode 100644 index 0000000..0d38c75 --- /dev/null +++ b/src/js/components/nav_buttons/nav_buttons.js @@ -0,0 +1,54 @@ +// nav_buttons.js +import './nav_buttons.css'; +import { nextPage, lastPage } from '../../views/view_logic.js'; + +function initializeNavButtons() { + // initialize last button + const last_btn = document.getElementById('btn-last'); + last_btn.addEventListener('click', lastPage); + // initialize next button + const next_btn = document.getElementById('btn-next'); + next_btn.addEventListener('click', nextPage); +} + +function disable(button_id) { + const button = document.getElementById(button_id); + button.classList.add('disabled'); + button.disabled = true; // Also disable it at the DOM level +} + +function enable(button_id) { + const button = document.getElementById(button_id); + button.classList.remove('disabled'); + button.disabled = false; // Enable it at the DOM level +} + +const Next = { + disable: function() { disable('btn-next'); }, + enable: function() { enable('btn-next'); }, + addAction: function(fn) { + document.querySelector(`#btn-next`).addEventListener('click', fn); + }, + removeAction: function(fn) { + document.querySelector(`#btn-next`).removeEventListener('click', fn); + }, +}; + +const Last = { + disable: function() { disable('btn-last'); }, + enable: function() { enable('btn-last'); }, +}; + +export const NavButtons = { + hide: function() { + document.getElementById('nav-btns').style.display = 'none'; + }, + show: function() { + document.getElementById('nav-btns').style.display = 'block'; + initializeNavButtons(); + }, + Next: Next, + Last: Last, +}; + +export default NavButtons; \ No newline at end of file diff --git a/src/js/components/prompt/prompt.css b/src/js/components/prompt/prompt.css new file mode 100644 index 0000000..7f4d617 --- /dev/null +++ b/src/js/components/prompt/prompt.css @@ -0,0 +1,39 @@ +div#prompt-div { + display: none; + width: 80%; + margin: auto; + text-align: center; +} + +h3#prompt { + text-align: center; + font-size : 1.2em; +} + +#option1, #option2 { + font-size: 1.5em; + border-color: var(--citygreen); + border-width: 2px; + background-color: var(--white); + color: var(--citygreen); +} + +#option1:hover, #option2:hover { + background-color: var(--spiritgreen); + color: white; +} + +#option2.clicked, #option1.clicked { + font-weight: bold; + background-color: var(--spiritgreen); + color: white; + border-width: 3; +} + +#option1.disabled, #option2.disabled, #option1.disabled:hover, #option2.disabled:hover { + background-color: lightgray; + color: gray; + pointer-events: none; + border-color: gray; +} + diff --git a/src/js/components/prompt/prompt.js b/src/js/components/prompt/prompt.js new file mode 100644 index 0000000..576e454 --- /dev/null +++ b/src/js/components/prompt/prompt.js @@ -0,0 +1,19 @@ +import './prompt.css'; + +import Text from "./subcomponents/text.js"; +import Buttons from "./subcomponents/buttons.js"; + +export const Prompt = { + Text : Text, + Buttons : Buttons, + hide : function(){ + Text.hide(); + Buttons.hide(); + }, + show : function(){ + Text.show(); + Buttons.show(); + } +} + +export default Prompt \ No newline at end of file diff --git a/src/js/components/prompt/subcomponents/buttons.js b/src/js/components/prompt/subcomponents/buttons.js new file mode 100644 index 0000000..a9bbac3 --- /dev/null +++ b/src/js/components/prompt/subcomponents/buttons.js @@ -0,0 +1,79 @@ +function showPromptButton(id){ + // make buttons visible + document.getElementById(id).style.display = 'inline'; +} + +function updatePromptButton(id, text){ + document.getElementById(id).textContent = text; + showPromptButton(id); +} + +function hidePromptButton(id){ + document.getElementById(id).style.display = 'none'; +} + +function unclickAll(){ + document.getElementById('option1').classList.remove('clicked'); + document.getElementById('option2').classList.remove('clicked'); +} + +function applyClickedStyle(button){ + unclickAll(); + button.classList.add('clicked'); +} + +function addPromptButtonAction(button_id, action_fn){ + const buttonElement = document.getElementById(button_id); + buttonElement.addEventListener('click', action_fn); + buttonElement.addEventListener('click', function(){ + applyClickedStyle(this); + }); +} + +function removePromptButtonAction(button_id, action_fn){ + document.getElementById(button_id).removeEventListener('click', action_fn); +} + +function disable(button_id){ + document.querySelector(`#${button_id}`).classList.add('disabled'); +} + +function enable(button_id){ + document.querySelector(`#${button_id}`).classList.remove('disabled'); +} + +export const Left = { + show : function() { showPromptButton('option1') }, + hide : function() { hidePromptButton('option1') }, + updateText : function(text) { updatePromptButton('option1', text) }, + addAction : function(action_fn) { addPromptButtonAction('option1', action_fn) }, + removeAction : function(action_fn) { removePromptButtonAction('option1', action_fn) }, + disable : function() { disable('option1') }, + enable : function() { enable('option1') } +} + +export const Right = { + show : function() { showPromptButton('option2') }, + hide : function() { hidePromptButton('option2') }, + updateText : function(text) { updatePromptButton('option2', text) }, + addAction : function(action_fn) { addPromptButtonAction('option2', action_fn) }, + removeAction : function(action_fn) { removePromptButtonAction('option2', action_fn) }, + disable : function() { disable('option2') }, + enable : function() { enable('option2') } +} + +export const Buttons = { + Left : Left, + Right : Right, + show : function() { + showPromptButton('option1'); + showPromptButton('option2'); + }, + hide : function() { + hidePromptButton('option1'); + hidePromptButton('option2'); + }, + reset : unclickAll +} + +export default Buttons; \ No newline at end of file diff --git a/src/js/components/prompt/subcomponents/text.js b/src/js/components/prompt/subcomponents/text.js new file mode 100644 index 0000000..b693ad8 --- /dev/null +++ b/src/js/components/prompt/subcomponents/text.js @@ -0,0 +1,21 @@ +function showPrompt(){ + document.getElementById("prompt-div").style.display = "block"; +} + +function hidePrompt(){ + document.getElementById('prompt-div').style.display = 'none'; +} + + +function updatePrompt(prompt){ + document.getElementById('prompt').textContent = prompt; + showPrompt(); +} + +export const Text = { + show : showPrompt, + hide : hidePrompt, + update : function(text) { updatePrompt(text) } +} + +export default Text; \ No newline at end of file diff --git a/src/js/components/sidebar/sidebar.css b/src/js/components/sidebar/sidebar.css new file mode 100644 index 0000000..a839895 --- /dev/null +++ b/src/js/components/sidebar/sidebar.css @@ -0,0 +1,88 @@ +#sidebar-panel { + background-color: lightgrey; + /* min-height: 100vh; Full height of viewport */ + } + +#supp-total .stat { + color: var(--yellow); +} + +.stat { + font-weight: bold; +} + +#sidebar-panel { + height: 100%; /* Full height of the viewport */ + position: fixed; /* Fixed Sidebar (stay in place on scroll) */ + z-index: 1; /* Stay on top */ + top: 0; /* Stay at the top */ + right: 0; /* Sidebar appears on the left */ + background-color: #FFFFFF; /* White background color */ + overflow-x: hidden; /* Disable horizontal scroll */ + padding: 20px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* Add shadow for some depth */ + border-right: 2px solid #DDDDDD; /* Right border */ + border-radius: 0px 0px 0px 15px; /* Rounded corners on the left */ + /* margin-top: var(--header-height); */ + width: var(--sidebar-width); + margin: 0px; + } + +.sidebar a { + padding: 10px 15px; + text-decoration: none; + font-size: 18px; + color: #818181; + display: block; + transition: 0.3s; +} + +#sidebar-title { + color: var(--darkGray); + font-weight: bold; + border-bottom: 1px solid var(--citygreen); +} + +hr { + margin-top: -5px; + margin-bottom: 8px; +} + +h6 { + font-weight: 600; +} + +.section-header { + background-color: var(--mediumGray); +} + +.sidebar-stat-line { + display: flex; + align-items: center; + justify-content: space-between; /* Distribute space between children */ + padding: 2px; + border-bottom: 1px solid #ddd; +} + +.edit-icon, .edit-supp { + color: var(--spiritgreen); + cursor: pointer; + font-size: 16px; /* Adjust the size as needed */ + margin-left: 10px; +} + +.edit-icon:hover .edit-supp:hover { + color: var(--citygreen); +} + +.stat-label { + margin-right: auto; /* Push next elements to the right */ +} + +.stat { + margin-left: 5px; /* Optional: Add some space between currency and edit icon */ +} + +.sidebar-stat-line.fund-total .stat { + margin-right: 05px; /* 25px lines up with lines above (with edit symbol) */ +} \ No newline at end of file diff --git a/src/js/components/sidebar/sidebar.js b/src/js/components/sidebar/sidebar.js new file mode 100644 index 0000000..7cbfa9f --- /dev/null +++ b/src/js/components/sidebar/sidebar.js @@ -0,0 +1,59 @@ +import './sidebar.css' +import { BaselineSection } from './subcomponents/baseline_section'; + +import SuppSection from './subcomponents/supp_section' + +// fetch CSS variables saved in :root +const root = document.documentElement; +const sideBarWidth = getComputedStyle(root).getPropertyValue('--sidebar-width').trim(); + +function hideSidebar() { + document.getElementById('sidebar-panel').style.display = 'none'; + document.getElementById('main-panel').style.width = '100%'; + document.querySelector('header').style.width = '100%' +} + +function showSidebar() { + const sidebar = document.getElementById('sidebar-panel'); + const mainPanel = document.getElementById('main-panel'); + const header = document.querySelector('header'); + + // update values + updateTotals(); + sidebar.style.display = 'block'; // Show the sidebar + + // Calculate the remaining width for the main panel and header + var contentWidth = document.documentElement.clientWidth; + mainPanel.style.width = `${contentWidth - parseInt(sideBarWidth, 10)}px`; + header.style.width = `${contentWidth - parseInt(sideBarWidth, 10)}px`; + + // add event listener to resize content if window is adjusted + window.addEventListener('resize', showSidebar); +} + +function updateSidebarTitle(new_title){ + document.getElementById('sidebar-title').textContent = new_title; +} + +function updateTotals(){ + SuppSection.update(); + BaselineSection.update(); +} + +function resetAll(){ + localStorage.clear(); + // reset all stats to 0 + updateTotals(); +} + +const Sidebar = { + SuppSection : SuppSection, + BaselineSection : BaselineSection, + hide: hideSidebar, + show: showSidebar, + updateTitle: updateSidebarTitle, + updateTotals: updateTotals, + reset: resetAll +}; + +export default Sidebar; \ No newline at end of file diff --git a/src/js/components/sidebar/subcomponents/baseline_section.js b/src/js/components/sidebar/subcomponents/baseline_section.js new file mode 100644 index 0000000..8e54181 --- /dev/null +++ b/src/js/components/sidebar/subcomponents/baseline_section.js @@ -0,0 +1,107 @@ +import { FISCAL_YEAR } from "../../../constants"; +import { Baseline, FundLookupTable, Fund, CurrentFund } from "../../../models"; +import { formatCurrency } from "../../../utils/common_utils"; +import { visitPage } from "../../../views/view_logic"; + +export const BaselineSection = { + _data: new Baseline(), + _genFund : new Fund(1000), + + get data() { + this._data = new Baseline(); + return this._data; + }, + + set data(newData) { + this._data = newData; + }, + + get genFund() { + this._genFund = new Fund(1000); + return this._genFund; + }, + + set genFund(newFund) { + this._genFund = newFund; + }, + + target_html() { + return ` + + +
`; + }, + + fund_html(fund) { + return ` +
${FundLookupTable.getName(fund.fund)}
+
+ + + + + +
`; + }, + + linkEditBtns() { + let btns = document.querySelectorAll('.edit-icon'); + btns.forEach((btn) => { + // Get the fund from the div the button is in + let fund = btn.closest('.fund-div').id.replace('fund_', ''); + let page = btn.closest('.sidebar-stat-line').classList[1]; + + btn.addEventListener('click', function() { + CurrentFund.update(fund); + visitPage(page); + }); + }); + }, + + update() { + const baselineDiv = document.querySelector('#baseline-stats'); + baselineDiv.innerHTML = this.target_html(); + + this.data.funds.forEach((fund) => { + var fundDiv = document.createElement('div'); + fundDiv.id = `fund_${fund.fund}`; + fundDiv.classList.add('fund-div'); + fundDiv.innerHTML = this.fund_html(fund); + baselineDiv.appendChild(fundDiv); + }); + + if(this.genFund.getTotal() <= Baseline.target()){ + document.querySelector('#GF-total .stat').style.color = "green"; + // document.querySelector('#fund_1000 .sidebar-stat-line:last-of-type .stat').style.color = "green"; + } else { + document.querySelector('#GF-total .stat').style.color = "red"; + // document.querySelector('#fund_1000 .sidebar-stat-line:last-of-type .stat').style.color = "red"; + } + this.linkEditBtns(); + } +}; \ No newline at end of file diff --git a/src/js/components/sidebar/subcomponents/supp_section.js b/src/js/components/sidebar/subcomponents/supp_section.js new file mode 100644 index 0000000..62d87ac --- /dev/null +++ b/src/js/components/sidebar/subcomponents/supp_section.js @@ -0,0 +1,37 @@ +import { Supplemental } from "../../../models"; +import { formatCurrency } from "../../../utils/common_utils"; +import { visitPage } from "../../../views/view_logic"; + +export const SuppSection = { + html() { + var supp = new Supplemental; + return ` + + ` + }, + + linkEditBtns() { + let btns = document.querySelectorAll('.edit-supp'); + btns.forEach((btn) => { + btn.addEventListener('click', function() { + visitPage('new-inits'); + }); + }); + }, + + update() { + const suppDiv = document.querySelector('#supp-stats'); + suppDiv.innerHTML = this.html(); + this.linkEditBtns(); + } +} + +export default SuppSection; \ No newline at end of file diff --git a/src/js/components/table/subcomponents/buttons.js b/src/js/components/table/subcomponents/buttons.js new file mode 100644 index 0000000..3102f2f --- /dev/null +++ b/src/js/components/table/subcomponents/buttons.js @@ -0,0 +1,104 @@ +import Rows from './rows.js' + +function hideButton(className){ + return function() { + var buttons = document.getElementsByClassName(className); + for (var i = 0; i < buttons.length; i++) { + buttons[i].style.display = 'none'; + } + } +} + +function showButton(className){ + return function() { + var buttons = document.getElementsByClassName(className); + for (var i = 0; i < buttons.length; i++) { + buttons[i].style.display = 'inline'; + } + } +} + +function updateButtonText(className, text){ + document.querySelector(`.${className}`).textContent = text; +} + +function handleRowEdit(actionOnClick, updateCallback = null){ + // attach an event listener to each edit button in every row + var editButtons = document.getElementsByClassName('btn-edit'); + for (var i = 0; i < editButtons.length; i++) { + editButtons[i].addEventListener('click', async function(event) { + // Determine what was clicked on within the table + var rowToEdit = event.target.closest('tr'); + // mark row as being edited + rowToEdit.classList.add('active-editing'); + + // turn relevant entries into textboxes, usually + actionOnClick(); + + // hide edit buttons + Edit.hide(); + if(updateCallback){ + initializeConfirmButton(updateCallback); + } + }); + }; +} + +function initializeConfirmButton(updateCallback){ + // get element and add listener for click + var rowToEdit = document.querySelector('.active-editing'); + const confirm_btn = rowToEdit.querySelector(".btn-confirm"); + // show the row's confirm button + confirm_btn.style.display = 'block'; + confirm_btn.addEventListener('click', function(){; + // save row edits + Rows.saveEdits(rowToEdit); + // update values in sidebar + updateCallback(); + // make row no longer green + rowToEdit.classList.remove('active-editing'); + // show edit buttons and hide confirm buttons + Edit.show(); + Confirm.hide(); + }); +} + +const Edit = { + html: '', + hide: hideButton('btn-edit'), + show: showButton('btn-edit'), + init : function(actionOnClick, updateCallback){ + handleRowEdit(actionOnClick, updateCallback) + } +}; + +const Delete = { + html: '', + hide: hideButton('btn-delete'), + show: showButton('btn-delete') +}; + +const Confirm = { + html: '', + hide: hideButton('btn-confirm'), + show: showButton('btn-confirm') +}; + +const AddRow = { + hide: hideButton('btn-add'), + show: showButton('btn-add'), + updateText: function(text){ + updateButtonText('btn-add', text); + } +}; + +export const Buttons = { + Delete: Delete, + Edit : Edit, + Confirm : Confirm, + AddRow : AddRow, + edit_confirm_btns : Edit.html + Confirm.html , + all_btns : Delete.html + Edit.html + Confirm.html +} + +export default Buttons; \ No newline at end of file diff --git a/src/js/components/table/subcomponents/cells.js b/src/js/components/table/subcomponents/cells.js new file mode 100644 index 0000000..d80f26c --- /dev/null +++ b/src/js/components/table/subcomponents/cells.js @@ -0,0 +1,76 @@ +import { formatCurrency, displayWithCommas } from "../../../utils/common_utils.js"; +import Services from "../../../models/services.js"; +import Dropdown from "../../form/subcomponents/dropdown.js"; + +// return cell value attribute or 0 if it does not exist +function getCellValue(row, className) { + var cell = row.querySelector(`.${className}`); + var cellValue = cell ? cell.getAttribute('value') : null; + return cellValue ? parseFloat(cellValue) : 0; +} + +// return text in cell +function getCellText(row, className) { + var cell = row.querySelector(`.${className}`); + if (cell) { + return cell.textContent; + } else { + //console.log(`Error retrieving cell text for class ${className}`); + return ''; + } +} + +function updateTableCell(row, col_class, new_value){ + const cell = row.querySelector(`.${col_class}`); + cell.setAttribute('value', new_value); + cell.textContent = formatCurrency(new_value); +} + +function createEditableCell(cellClass, isCost, type = 'input'){ + // get cell + const cell = document.querySelector(`.active-editing td.${cellClass}`); + // Create an input element to edit the value + var textbox = document.createElement(type); + if (type == 'input'){ + textbox.type = 'text'; + }; + if (isCost){ + var value = cell.getAttribute('value'); + textbox.value = displayWithCommas(value); + } else { + textbox.value = cell.textContent; + } + // Clear the current content and append the textbox to the cell + cell.innerHTML = ''; + cell.appendChild(textbox); +} + +function createDropdown(cellClass, optionArray){ + // get cell + const cell = document.querySelector(`.active-editing td.${cellClass}`); + // add service dropdown + const dropdown = Dropdown.create(optionArray); + dropdown.value = cell.textContent; + // Clear the current content and append the textbox to the cell + cell.innerHTML = ''; + cell.appendChild(dropdown); +} + +const Cell = { + getValue: function(row, className) { + return getCellValue(row, className); + }, + getText: function(row, className) { + return getCellText(row, className); + }, + updateValue: function(row, col_class, new_value) { + updateTableCell(row, col_class, new_value); + }, + createTextbox : function(className, isCost, type) { + createEditableCell(className, isCost, type) + }, + createServiceDropdown : () => { createDropdown('service', Services.list()) }, + createDropdown : createDropdown +}; + +export default Cell; \ No newline at end of file diff --git a/src/js/components/table/subcomponents/columns.js b/src/js/components/table/subcomponents/columns.js new file mode 100644 index 0000000..f641642 --- /dev/null +++ b/src/js/components/table/subcomponents/columns.js @@ -0,0 +1,198 @@ +import { formatCurrency } from "../../../utils/common_utils.js"; + +// position is index at which new column will be inserted +function addCol(position, htmlContent = '', headerTitle = '') { + // Get the table element by its ID + let table = document.getElementById('main-table'); + + // Validate position + let maxPosition = table.rows[0].cells.length; + if (position < 0 || position > maxPosition) { + console.error(`Position ${position} is out of bounds.`); + return; + } + + // Insert the header if provided + let thead = table.tHead; + if (headerTitle && thead) { + let th = document.createElement('th'); + th.innerHTML = headerTitle; // Use innerHTML to insert HTML content + thead.rows[0].insertBefore(th, thead.rows[0].cells[position]); + } + + // Insert new cells into each row of the table body + let tbody = table.tBodies[0]; + if (tbody) { + for (let i = 0; i < tbody.rows.length; i++) { + let row = tbody.rows[i]; + let td = document.createElement('td'); + td.innerHTML = htmlContent; // Use innerHTML to insert HTML content + row.insertBefore(td, row.cells[position]); + } + } +} + +function ncols(){ + const table = document.getElementById('main-table'); + // Ensure that the row exists before counting the columns + return table.rows[0].cells.length; +} + +function addColToEnd(htmlContents = [], headerTitle = ''){ + // count columns and add new column to the end + const position = ncols('main-table'); + addCol(position, htmlContents, headerTitle); +} + +function assignClassToColumn(headerName, className) { + // Get the table element by its ID + let table = document.getElementById('main-table'); + + // Find the index of the column by its header name + const thead = table.tHead; + let headerCellIndex = -1; + const headerCells = thead.rows[0].cells; // Assuming the first row contains header cells () + for (let i = 0; i < headerCells.length; i++) { + if (headerCells[i].textContent.trim() === headerName) { + // assign the class to the header cell + headerCells[i].classList.add(className); + headerCellIndex = i; + break; + } + } + + // error check + if (headerCellIndex === -1) { + console.error(`No header found with name "${headerName}"`); + return; + } + + // Assign the class to each cell in the specified column index within the tbody + let tbody = table.tBodies[0]; + if (tbody) { + let bodyRows = tbody.rows; + for (let row of bodyRows) { + if (row.cells[headerCellIndex]) { + row.cells[headerCellIndex].classList.add(className); + } + } + } + } + +function addCostClass(headerName){ + assignClassToColumn( headerName, 'cost'); + + // Get all the cells with the specified class name + const cells = document.querySelectorAll(`td.cost`); + + cells.forEach(cell => { + // Get the current text content of the cell and assign it to 'value' attribute + if (!cell.getAttribute('value')){ + const cellText = cell.textContent.trim(); + const cellValue = isNaN(cellText) || cellText === '' ? 0 : parseFloat(cellText); + cell.setAttribute('value', cellValue); + + // Now format the text content like currency and replace it in the cell + const formattedCurrency = formatCurrency(parseFloat(cellValue)); + cell.textContent = formattedCurrency; + } + + }); + +} + +function assignColumnClasses(columnDefinitions) { + columnDefinitions.forEach(column => { + // Assign class to column + assignClassToColumn(column.title, column.className); + + // If the column is a cost column, add the specific cost class + if (column.isCost) { + addCostClass(column.title); + } + + // show the column + if (!column.hide){ + showColumnByTitle(column.title); + } + }); +} + +function hideColumn(index) { + var table = document.getElementById('main-table'); + var rows = table.rows; + + for (var i = 0; i < rows.length; i++) { + var cells = rows[i].cells; + if (cells.length > index) { + cells[index].style.display = 'none'; + } + } +} + +// Function to show a specific column +function showColumn(index) { + var table = document.getElementById('main-table'); + var rows = table.rows; + + for (var i = 0; i < rows.length; i++) { + var cells = rows[i].cells; + if (cells.length > index) { + cells[index].style.display = 'table-cell'; + } + } +} + +// Function to get the column index by title +function getColumnIndexByTitle(table, title) { + var headers = table.querySelectorAll('th'); + for (var i = 0; i < headers.length; i++) { + if (headers[i].innerText === title) { + return i; + } + } + return -1; // Column not found +} + +// Function to hide a column by title +function hideColumnByTitle(title) { + var table = document.getElementById('main-table'); + var index = getColumnIndexByTitle(table, title); + if (index !== -1) { + hideColumn(index); + } else { + console.log(`Column with title "${title}" not found.`); + } +} + +// Function to show a column by title +function showColumnByTitle(title) { + var table = document.getElementById('main-table'); + var index = getColumnIndexByTitle(table, title); + if (index !== -1) { + showColumn(index); + } else { + console.log(`Column with title "${title}" not found.`); + } +} + + +const Column = { + add: function(position, htmlContent, headerTitle) { + return addCol(position, htmlContent, headerTitle); + }, + addAtEnd: function(htmlContent, headerTitle) { + return addColToEnd(htmlContent, headerTitle); + }, + assignClasses: function(column_definitions) { + return assignColumnClasses(column_definitions); + }, + hide : function(colName) { + hideColumnByTitle(colName); + }, + show : function(colName) { + showColumnByTitle(colName); + } +}; + +export default Column; \ No newline at end of file diff --git a/src/js/components/table/subcomponents/data.js b/src/js/components/table/subcomponents/data.js new file mode 100644 index 0000000..3da560d --- /dev/null +++ b/src/js/components/table/subcomponents/data.js @@ -0,0 +1,144 @@ +import FundLookupTable from '../../../models/fund_lookup_table.js'; +import CurrentFund from '../../../models/current_fund.js' +import CurrentPage from '../../../models/current_page.js' +import Table from '../table.js'; + +function fillTable(data) { + try { + const table = document.getElementById('main-table'); + const thead = table.querySelector('thead'); + const tbody = table.querySelector('tbody'); + + // clear existing data + thead.innerHTML = ''; + tbody.innerHTML = ''; + + // Create table header row + const headerRow = document.createElement('tr'); + Object.keys(data[0]).forEach(key => { + const header = document.createElement('th'); + header.textContent = key; + headerRow.appendChild(header); + }); + thead.appendChild(headerRow); + + // Create table body rows + data.forEach(item => { + const row = document.createElement('tr'); + Object.values(item).forEach(val => { + const cell = document.createElement('td'); + cell.innerHTML = val; + row.appendChild(cell); + }); + tbody.appendChild(row); + }); + } catch(error) { + console.error('No table saved in localStorage:', error); + } +} + +async function loadFromStorage(){ + // look up table name in storage + if (CurrentFund.number()){ + var key = `${CurrentPage.load()}_${CurrentFund.number()}`; + } else { + var key = CurrentPage.load(); + } + // load from local storage + const data = localStorage.getItem(key); + // if nothing in storage, return a zero + if ( !data ) { + return 0; + } else { + // otherwise, fill table in HTML and return success (1) + Table.show(); + fillTable(await JSON.parse(data)); + return 1; + } +} + + +function loadFunds(){ + // get list of funds from storage + const fundDict = FundLookupTable.retrieve(); + // build out data in correct format + const ret = []; + Object.keys(fundDict).forEach(key => { + // determine if the fund has already been edited + if (fundDict[key]['viewed']){ + // todo: add a checkmark here + ret.push({'Fund' : ` + + ${fundDict[key]['name']} + `}); + } else { + ret.push({'Fund' : ` + ${fundDict[key]['name']} + `}); + } + }); + fillTable(ret); +} + + +function getColumnIndexByClass(tbody, className) { + const firstRow = tbody.rows[0]; + if (!firstRow) return -1; // Return -1 if there's no row to examine + for (let cellIndex = 0; cellIndex < firstRow.cells.length; cellIndex++) { + if (firstRow.cells[cellIndex].classList.contains(className)) { + return cellIndex; + } + } + return -1; // Return -1 if class name not found +} + +// function sort(primaryClass, secondaryClass) { +// const table = document.getElementById('main-table'); +// const tbody = table.tBodies[0]; +// const rows = Array.from(tbody.rows); + +// // Get the column indices by class name +// const primaryColIndex = getColumnIndexByClass(tbody, primaryClass); +// const secondaryColIndex = getColumnIndexByClass(tbody, secondaryClass); + +// // exit if classes don't exist +// if (primaryColIndex === -1 ) { +// console.error(`Column class ${classA} not found in table`); +// return; +// } else if (secondaryColIndex === -1) { +// console.error(`Column class ${classB} not found in table`); +// return; +// } + +// // Sort the rows based on the text content of the cells +// rows.sort((rowA, rowB) => { +// // Primary column comparison +// const primaryA = unformatCurrency(rowA.cells[primaryColIndex].textContent); +// const primaryB = unformatCurrency(rowB.cells[primaryColIndex].textContent); + +// if (primaryA < primaryB) return -1; +// if (primaryA > primaryB) return 1; + +// // Secondary column comparison (if primary is equal) +// const secondaryA = unformatCurrency(rowA.cells[secondaryColIndex].textContent); +// const secondaryB = unformatCurrency(rowB.cells[secondaryColIndex].textContent); + +// if (secondaryA < secondaryB) return -1; +// if (secondaryA > secondaryB) return 1; + +// // If both columns are equal +// return 0; +// }); + +// // Reattach sorted rows to the table body +// rows.forEach((row) => tbody.appendChild(row)); +// } + + +export const Data = { + load : loadFromStorage, + loadFunds : loadFunds, + sort : function(colA, colB) { sort(colA, colB) } +} + +export default Data; \ No newline at end of file diff --git a/src/js/components/table/subcomponents/filters.js b/src/js/components/table/subcomponents/filters.js new file mode 100644 index 0000000..40f735c --- /dev/null +++ b/src/js/components/table/subcomponents/filters.js @@ -0,0 +1,94 @@ +// Helper functions & constants + +// object to hold all current filter statuses +const filterSettings = { + 'approp-name': '', + 'cc-name': '', + 'object-name': '', + 'object-category': '' +}; + +// helper function to filter data based on all filters +function filterData() { + // Get all rows in the table + const rows = document.querySelectorAll('#main-table tbody tr'); + + // Iterate through each row and determine if it should be hidden or shown + rows.forEach(row => { + let isVisible = true; + + // Check each filter setting against the row's cells + for (const [filterId, filterValue] of Object.entries(filterSettings)) { + const cell = row.querySelector(`.${filterId}`); + + // only show row if values pass through all filters + if (filterValue && cell && (cell.textContent.trim() !== filterValue)) { + isVisible = false; + break; + } + } + + // Show or hide the row based on visibility + row.classList.toggle('hidden', !isVisible); + }); +} + +const Filter = { + html(filterLabel, filterClass) { + // basic html with only 'All' option + return ` + ` + }, + + addOption(filterClass, option) { + // Add another option to the dropdown for the filter + const filterObj = document.querySelector(`#filter-${filterClass}`); + const optionObj = document.createElement('option'); + optionObj.value = option; + optionObj.textContent = option; + filterObj.appendChild(optionObj); + }, + + add(filterLabel, filterClass) { + // create a div to contain the html and insert inside filter-container + const filterContainer = document.querySelector('#filter-container'); + const filterDiv = document.createElement('div'); + filterDiv.innerHTML = this.html(filterLabel, filterClass); + filterContainer.appendChild(filterDiv); + // add all relevant options from that column in the table + this.addAllOptions(filterClass); + // Bind change event to the select element + filterDiv.querySelector('.filter-dropdown').addEventListener('change', event => { + // Update filter settings + filterSettings[filterClass] = event.target.value; + // Apply all filters + filterData(); + }); + }, + + addAllOptions(filterClass) { + // get matching column from table + const column = document.querySelectorAll(`#main-table td.${filterClass}`); + + // Use a Set to store unique values in the column of interest + const uniqueValues = new Set(); + + // Iterate over the NodeList to get the unique values + column.forEach(td => { + // Add each textContent to the Set + uniqueValues.add(td.textContent.trim()); + }); + // add all values as options to the filter dropdown + uniqueValues.forEach(option => { + this.addOption(filterClass, option); + }); + }, + + deleteAll(){ + document.querySelector('#filter-container').innerHTML = ''; + } +} + +export default Filter; \ No newline at end of file diff --git a/src/js/components/table/subcomponents/headers.js b/src/js/components/table/subcomponents/headers.js new file mode 100644 index 0000000..233f0af --- /dev/null +++ b/src/js/components/table/subcomponents/headers.js @@ -0,0 +1,30 @@ +function addTableHeaders(cols){ + + // Get the table element by its ID + const table = document.getElementById('main-table'); + + // Create a table header row element + const headerRow = document.createElement('tr'); + + cols.forEach(col => { + // Create a header cell element + const headerCell = document.createElement('th'); + headerCell.textContent = col['title']; + headerCell.classList.add(col['className']); + + // Append the header cell to the header row + headerRow.appendChild(headerCell); + }); + + // Append the header row to the table header + let thead = table.querySelector('thead'); + thead.appendChild(headerRow); +} + +const Header = { + add: function(header_array){ + addTableHeaders(header_array) + } +}; + +export default Header; \ No newline at end of file diff --git a/src/js/components/table/subcomponents/rows.js b/src/js/components/table/subcomponents/rows.js new file mode 100644 index 0000000..d89031a --- /dev/null +++ b/src/js/components/table/subcomponents/rows.js @@ -0,0 +1,78 @@ +import Header from "./headers.js"; +import { formatCurrency } from "../../../utils/common_utils.js"; + +async function addNewRow(data_dictionary, columns = []){ + + // Get the table element by its ID + const table = document.getElementById('main-table'); + + // check if header has already been added + let header_row = table.querySelector('thead tr'); + if (!header_row) { + Header.add(columns); + header_row = table.querySelector('thead tr'); + } + + // initialize new row of data + const new_row = document.createElement('tr'); + + // go through each header and add the right cell value depending on its class + let thElements = header_row.querySelectorAll('th'); + thElements.forEach( (header_cell) => { + // Create new cell and add it to the row + const newCell = document.createElement('td'); + new_row.appendChild(newCell); + // if the data has an appropriate class, add the info to the cell. + // Otherwise, keep empty cell + Object.keys(data_dictionary).forEach( (className) => { + if (header_cell.classList.contains(className) ){ + newCell.textContent = data_dictionary[className]; + newCell.classList.add(className); + } + }); + }); + + // Append the new row to the table body + let tbody = table.querySelector('tbody'); + tbody.appendChild(new_row); +} + +function saveRowEdits(row){ + var cells = row.querySelectorAll('td') + cells.forEach( cell => { + // save dropdown values + if (cell.querySelector('select')){ + var serviceSelector = cell.querySelector('select'); + cell.textContent = serviceSelector.value; + } else if (cell.querySelector('input')) { + // save new entered value in textbox + var textbox = cell.querySelector('input'); + var enteredValue = textbox.value; + // update display and format with currency if relevant + if ( cell.classList.contains('cost') ){ + // if cost, remove commas first + enteredValue = enteredValue.replaceAll(',', ''); + cell.textContent = formatCurrency(enteredValue); + // set value attribute to the new user input + cell.setAttribute('value', enteredValue); + } else { + cell.textContent = enteredValue; + } + } else if (cell.querySelector('textarea')){ + // save new entered value in textbox + var enteredValue = cell.querySelector('textarea').value; + cell.textContent = enteredValue; + } + }) +} + +const Rows = { + add : function(data_dictionary, cols){ + addNewRow(data_dictionary, cols) + }, + saveEdits : function(row){ + saveRowEdits(row) + } +} + +export default Rows; \ No newline at end of file diff --git a/src/js/components/table/table.css b/src/js/components/table/table.css new file mode 100644 index 0000000..e1ee918 --- /dev/null +++ b/src/js/components/table/table.css @@ -0,0 +1,171 @@ +#main-table { + font-size: 12px; + /* calc(0.5vw + 0.5em); */ + margin: auto; + width: 100%; +} + +#main-table thead > tr > th { + text-align: left; + background-color: var(--darkGray); + color: white; + position: -webkit-sticky; /* For Safari */ + position: sticky; + top: 0; + padding-top: 5px; + padding-bottom: 5px; +} + +th { + background-color: var(--lightGray); +} + +tr { + border-width: 2px; + background-color: white; +} + +tr td { + border-bottom: 1px solid black; +} + +/* Default to hidden columns */ + +#main-table tbody > tr > td { + display : none; +} +#main-table thead > tr > th { + display : none; +} + +/* textbox width in table */ +input { + width: 100%; +} + +select { + max-width: 100px; +} + +div.table-container { + overflow-x: auto; + overflow-y: auto; + margin-left: max(65px, 7vh); + margin-right: max(65px, 7vh); + /* max-width: calc(100vw - var(--sidebar-width)); */ + /* margin: auto; */ + max-height: max(350px, 6vh); + /* min-height: 350px; */ + +} + +/* Buttons */ + +/* Add new row button */ +.btn-add { + background-color: var(--spiritgreen); + margin-top: 20px; + display: none; +} + +.btn-delete { + background-color: var(--orange); +} + +#add-btn-div { + display: flex; + justify-content: center; /* Aligns horizontally */ + align-items: center; /* Aligns vertically */ + width: 100%; +} + +.btn-edit { + background-color: var(--spiritgreen); + line-height: 1.1; +} + +.active-editing, .selected { + background-color: var(--palegreen); +} + +.selected { + font-weight: bold; +} + +.btn-confirm { + display: none; +} + +.confirm-btn:hover { + background-color: var(--green); +} + +.hover-effect:hover { + cursor: pointer; + background-color: var(--verypalegreen); +} + +/* Fund table */ +.fund-name > .viewed-fund { + color: gray; +} + +/* made edit column narrower */ +th.edit, td.edit { + width: 20px; +} + +/* Class for hidden rows on filter */ +.hidden { + display: none; +} + +/* Filter styling for the dropdown options */ +#filter-container { + display: flex; + flex-wrap: wrap; + gap: 2px; /* Adjust the gap as needed */ + font-size: 11px; + margin-left: 10%; + margin-right: 10%; + margin-bottom: 5px; +} + +#filter-container div { + display: flex; + align-items: center; + width: calc(50% - 10px); /* Adjust width to fit two items per row with gap */ +} + +#filter-container label { + width: 200px; /* Adjust the width as needed */ + text-align: right; + margin-right: 10px; /* Spacing between label and select */ +} + +/* Ensure all select boxes are wide enough to show text */ +.filter-dropdown { + flex: 1; + min-width: 200px; /* Adjust the min-width as needed */ +} + +/* Optional styling to make the select dropdown look better */ +.filter-dropdown { + padding: 5px; + border: 1px solid #ccc; + border-radius: 4px; +} + +/* Responsive adjustment: On smaller screens, stack elements vertically */ +@media (max-width: 800px) { + #filter-container div { + width: 100%; + } + + #filter-container label { + text-align: left; + width: auto; + margin-right: 0; + margin-bottom: 5px; + } +} \ No newline at end of file diff --git a/src/js/components/table/table.js b/src/js/components/table/table.js new file mode 100644 index 0000000..9ae870b --- /dev/null +++ b/src/js/components/table/table.js @@ -0,0 +1,78 @@ +import './table.css'; + +import Buttons from './subcomponents/buttons.js' +import Cell from './subcomponents/cells.js' +import Columns from './subcomponents/columns.js' +import Header from './subcomponents/headers.js' +import Rows from './subcomponents/rows.js' +import Data from './subcomponents/data.js' +import Filter from './subcomponents/filters.js'; + +import Tooltip from '../tooltip/tooltip.js'; +import { convertToJSON } from "../../utils/JSON_data_handlers.js"; +import Sidebar from '../sidebar/sidebar.js'; +import CurrentFund from '../../models/current_fund.js'; +import CurrentPage from '../../models/current_page.js'; + +function adjustTableWidth(width_pct){ + const table = document.getElementById('main-table'); + table.style.width = width_pct; +} + +function showTable(){ + const tableContainer = document.querySelector('.table-container'); + tableContainer.innerHTML = Table.html; + const table = document.getElementById('main-table'); + table.style.display = 'table'; +} + +function hideTable(){ + + // delete table object from table container + const tableContainer = document.querySelector('.table-container'); + tableContainer.innerHTML = ''; + Buttons.AddRow.hide(); +} + +function saveTableData() { + // remove the detail text + Tooltip.unlink(); + // get table + var table = document.getElementById('main-table'); + // determine save_as name + if (CurrentFund.number()) { + var save_as = `${CurrentPage.load()}_${CurrentFund.number()}`; + } else { + var save_as = CurrentPage.load(); + } + localStorage.setItem(save_as, convertToJSON(table, ['Edit'])); + // update sidebar with new data + Sidebar.updateTotals(); + // relink, depending on page + Tooltip.linkAll(); +} + +const Table = { + html : ` + + + +
`, + Buttons : Buttons, + Cell : Cell, + Columns : Columns, + Header : Header, + Rows : Rows, + Data : Data, + Filter : Filter, + // functions + adjustWidth : function(width_pct){ + adjustTableWidth(width_pct) + }, + clear : hideTable, + hide : hideTable, + show : showTable, + save : saveTableData +} + +export default Table; \ No newline at end of file diff --git a/src/js/components/tooltip/tooltip.css b/src/js/components/tooltip/tooltip.css new file mode 100644 index 0000000..78a4ad8 --- /dev/null +++ b/src/js/components/tooltip/tooltip.css @@ -0,0 +1,37 @@ +#tooltip { + position: absolute; + background-color: black; + color: white; + padding: 5px; + border-radius: 3px; + visibility: hidden; + white-space: nowrap; + font-size: 14px; + z-index: 1000; + max-width: 300px; + word-wrap: break-word; + white-space: normal; +} + +.tooltip-cell { + /* color: blue; */ + /* text-decoration: underline; */ + cursor: pointer; +} + +.tooltip-cell .info-icon { + margin-left: 5px; + color: var(--spiritgreen); + font-size: 15px; +} + +.tooltip-cell:hover { + background-color: #f0f0f0; /* Change background on hover */ +} + +.detail { + color: blue; + color: var(--spiritgreen); + text-decoration: underline; + margin-left: 5px; +} \ No newline at end of file diff --git a/src/js/components/tooltip/tooltip.js b/src/js/components/tooltip/tooltip.js new file mode 100644 index 0000000..287d0b5 --- /dev/null +++ b/src/js/components/tooltip/tooltip.js @@ -0,0 +1,206 @@ +import { FISCAL_YEAR } from '../../constants/'; +import Cell from '../table/subcomponents/cells'; +import { formatCurrency } from '../../utils/common_utils'; +import CurrentPage from '../../models/current_page'; +import { excelSerialDateToJSDate } from '../../utils/XLSX_handlers'; + +import './tooltip.css' + +function hideTooltip() { + document.getElementById('tooltip').style.visibility = 'hidden'; +} + +function showTooltip() { + document.getElementById('tooltip').style.visibility = 'visible'; +} + +function editTooltipText(newText){ + // edit text to display inside tooltip + const tooltip = document.getElementById('tooltip'); + tooltip.innerHTML = newText; +} + +function showAccountString(row){ + const approp = Cell.getText(row, 'approp-name'); + const cc = Cell.getText(row, 'cc-name'); + const obj = Cell.getText(row, 'object-name'); + const fund = Cell.getText(row, 'fund-name'); + var message = + `Fund: ${fund}
+ Appropriation: ${approp}
+ Cost Center: ${cc}`; + if (obj) { message += `
Object: ${obj}`} + message += `
If you believe this account string is incorrect, please leave a comment + in the comment column.` + editTooltipText(message); +} + +function showSalaryProjection(row){ + const general_increase = Cell.getText(row, 'general-increase-rate'); + const merit_increase = Cell.getText(row, 'merit-increase-rate'); + const current_salary = Cell.getValue(row, 'current-salary'); + const proj_salary = Cell.getValue(row, 'avg-salary'); + if (current_salary){ + var message = `The average salary/wage for this position was + ${formatCurrency(current_salary)} as of September 20${FISCAL_YEAR-2}. + Given a ${general_increase*100}% general increase rate and a ${merit_increase*100}% + merit increase, the FY${FISCAL_YEAR} projection for this position's average + annual salary/wage is ${formatCurrency(proj_salary)}. This projection takes into + account the number of vacant vs. full positions.`; + } else { + var message = `The average salary/wage for this position was + unknown as of September 20${FISCAL_YEAR-2}, or the position + did not exist. The FY${FISCAL_YEAR} projection for this position's + average annual salary/wage is ${formatCurrency(proj_salary)}.` + } + + editTooltipText(message); +} + +function showFinalPersonnelCost(row){ + const proj_salary = Cell.getValue(row, 'avg-salary'); + const ftes = Cell.getText(row, 'baseline-ftes'); + const fringe = parseFloat(Cell.getText(row, 'fringe')); + const avg_benefits = proj_salary * fringe; + const message = `The total cost captures ${ftes} position(s) at + an annual salary/wage of ${formatCurrency(proj_salary)}, + plus fringe benefits that cost ${formatCurrency(avg_benefits)} + per position per year, on average.` + editTooltipText(message); +} + +function showFICA(row){ + const fica = parseFloat(Cell.getText(row, 'fica')); + const ficaPercentage = (fica * 100).toFixed(2); + const message = `This total is overtime / holiday / shift premium pay, plus FICA (payroll tax), + which is ${ficaPercentage}% for this cost center.` + editTooltipText(message); +} + +function showCPA(row){ + const cpa = parseFloat(Cell.getText(row, 'cpa')); + const description = Cell.getText(row, 'cpa-description'); + const vendor = Cell.getText(row, 'vendor'); + var contract_end = Cell.getText(row, 'contract-end'); + // convert to normal date format from excel + contract_end = excelSerialDateToJSDate(contract_end); + const remaining = Cell.getValue(row, 'remaining'); + if (cpa) { + var message = `CPA #${cpa}`; + } else { + var message = `No CPA`; + } + if (vendor) {message += `
Vendor: ${vendor}`}; + if (description) {message += `
Description: ${description}`}; + if (contract_end) {message += `
Contract End Date: ${contract_end}`} + if (remaining) {message += `
Amount Remaining on Contract: ${formatCurrency(remaining)}`} + + editTooltipText(message); +} + +function link(element, displayFn) { + + // add class to show cell with an underline, etc + element.classList.add('tooltip-cell'); + + // Create and append (detail) + const detail = document.createElement('span'); + detail.classList.add('detail'); + detail.textContent = '(detail)'; + element.appendChild(detail); + + // add event listener to show tooltip on mouseover + element.addEventListener('click', function (event) { + const row = event.target.closest('tr'); + displayFn(row); + showTooltip(); + }); + // and hide when mouse moves off + element.addEventListener('mouseout', function () { + hideTooltip(); + }); + // Update tooltip position on mouse move + element.addEventListener('mousemove', function (event) { + const tooltip = document.getElementById('tooltip'); + tooltip.style.top = (event.clientY + 10) + 'px'; + tooltip.style.left = (event.clientX + 10) + 'px'; + }); +} + +function linkAccountStringCol() { + // get all relevant cells + document.querySelectorAll('td.account-string').forEach( (cell) => { + link(cell, showAccountString); + }) +} + +function linkSalaryCol() { + // get all relevant cells + document.querySelectorAll('td.avg-salary').forEach( (cell) => { + link(cell, showSalaryProjection); + }) +} + +function linkTotalPersonnelCostCol() { + // get all relevant cells + document.querySelectorAll('td.total-baseline').forEach( (cell) => { + link(cell, showFinalPersonnelCost); + }) +} + +function linkTotalOTCol() { + // get all relevant cells + document.querySelectorAll('td.total').forEach( (cell) => { + link(cell, showFICA); + }) +} + +function linkCPACol() { + // get all relevant cells + document.querySelectorAll('td.cpa').forEach( (cell) => { + link(cell, showCPA); + }) +} + +export const Tooltip = { + + hide : hideTooltip, + show : showTooltip, + + linkAll : () => { + linkAccountStringCol(); + switch(CurrentPage.load()){ + case 'personnel' : + // linkAccountStringCol(); + linkSalaryCol(); + linkTotalPersonnelCostCol(); + break; + case 'overtime': + linkTotalOTCol(); + // linkAccountStringCol(); + break; + case 'nonpersonnel': + // linkAccountStringCol(); + linkCPACol(); + break; + // case 'revenue': + // linkAccountStringCol(); + // break; + // case 'new-inits': + // linkAccountStringCol(); + // break; + default: + break; + + } + }, + + unlink : function() { + let details = document.querySelectorAll('.detail'); + details.forEach( (span) => { + span.remove(); + }) + } +} + +export default Tooltip \ No newline at end of file diff --git a/src/js/components/welcome/welcome.css b/src/js/components/welcome/welcome.css new file mode 100644 index 0000000..7237dd6 --- /dev/null +++ b/src/js/components/welcome/welcome.css @@ -0,0 +1,27 @@ +/* Welcome page (index.html) */ + +.step { + width: 60%; + height: 80px; + font-size: 1.75em; + margin-bottom: 0px; /* Adds spacing between buttons */ + margin-left: 20%; + border-color: var(--citygreen); + border-width: 2; + color: var(--citygreen); + background-color: white; +} + +.step:hover { + color: white; + background-color: var(--spiritgreen); +} + +#welcome-page { + justify-content: center; + align-items: center; + padding-top: 20px; +} +.step.disabled { + opacity: 50%; +} \ No newline at end of file diff --git a/src/js/components/welcome/welcome.js b/src/js/components/welcome/welcome.js new file mode 100644 index 0000000..d6e3749 --- /dev/null +++ b/src/js/components/welcome/welcome.js @@ -0,0 +1,16 @@ +import './welcome.css'; + +// Hide and unhide welcome buttons +function unhideWelcomeButtons(){ + document.getElementById("welcome-page").style.display = "block"; +} +function hideWelcomeButtons(){ + document.getElementById("welcome-page").style.display = "none"; +} + +export const Welcome = { + show: unhideWelcomeButtons, + hide : hideWelcomeButtons +} + +export default Welcome; \ No newline at end of file diff --git a/src/js/constants/budget_constants.js b/src/js/constants/budget_constants.js new file mode 100644 index 0000000..6a4838d --- /dev/null +++ b/src/js/constants/budget_constants.js @@ -0,0 +1,36 @@ +// Set to equal current fiscal year +export var FISCAL_YEAR = '26'; + +// object categories (from obj part of account string) +export const OBJ_CATEGORIES = { + list : [ + // 'Salaries & Wages', + // 'Employee Benefits', + 'Professional & Contractual Services', + 'Operating Supplies', + 'Operating Services', + 'Equipment Acquisition', + 'Capital Outlays', + 'Fixed Charges', + 'Other Expenses' + ] +} + +// from the drop-down menu +export const EMPLOYEE_TYPES = [ + 'Regular', + 'TASS', + 'Seasonal', + 'Uniform Fire', + 'Uniform Police', + 'Appointed', + 'Elected', + 'Long Term Disability' +] + +export const OT_OBJECTS = [ + '601300 - Salar-Overtime-Gen City', + '601305 - Salaries-Overtime-Police Unif', + '601310 - Salaries-Overtime-Fire Unif', + '602300 - Wages-Overtime-Gen City' +] \ No newline at end of file diff --git a/src/js/constants/excel_constants.js b/src/js/constants/excel_constants.js new file mode 100644 index 0000000..e49a456 --- /dev/null +++ b/src/js/constants/excel_constants.js @@ -0,0 +1,19 @@ +import { FISCAL_YEAR } from "./budget_constants"; + +// sheets to expect on detail sheet +export const SHEETS = { + 'FTE, Salary-Wage, & Benefits' : 'personnel' , + 'Overtime & Other Personnel' : 'overtime', + 'Non-Personnel' : 'nonpersonnel', + 'Revenue' : 'revenue' +} + +// where to find the general fund target +export const TARGET_CELL_ADDRESS = 'C14' + +export const TOTAL_COLUMNS = { + 'personnel': 'Total Sal/Wag & Ben Request', + 'overtime':`FY${FISCAL_YEAR} Total OT/SP/Hol + FICA Request`, + 'nonpersonnel': `FY${FISCAL_YEAR} Departmental Request Total`, + 'revenue': `FY${FISCAL_YEAR} Departmental Estimate` +}; diff --git a/src/js/constants/index.js b/src/js/constants/index.js new file mode 100644 index 0000000..4a580ca --- /dev/null +++ b/src/js/constants/index.js @@ -0,0 +1,2 @@ +export * from './budget_constants'; +export * from './excel_constants'; \ No newline at end of file diff --git a/src/js/init.js b/src/js/init.js new file mode 100644 index 0000000..9e4153f --- /dev/null +++ b/src/js/init.js @@ -0,0 +1,10 @@ +// import styles +import '../css/common.css'; + +// import functions +import CurrentPage from './models/current_page.js'; + +document.addEventListener('DOMContentLoaded', function () { + CurrentPage.visit(); +}); + diff --git a/src/js/models/account_string.js b/src/js/models/account_string.js new file mode 100644 index 0000000..b7f7e55 --- /dev/null +++ b/src/js/models/account_string.js @@ -0,0 +1,43 @@ +import CurrentFund from "./current_fund"; + +export const AccountString = { + getNumber: function(input) { + // isolate the numerical part of a appropriation/cost center/object + const match = input.match(/^\d+/); + return match ? match[0] : null; + }, + + build : function(approp, cc, obj = null, fund = null) { + // put together account string fund-approp-costcenter[-obj] (w optional object) + if (!fund) { fund = CurrentFund.number() }; + // hits error here + approp = this.getNumber(approp); + cc = this.getNumber(cc); + var string = `${fund}-${approp}-${cc}`; + string = obj ? `${string}-${this.getNumber(obj)}` : string; + return string; + }, + + getAccountStringSection : function(account_string, section) { + const sections = account_string.split("-"); + return sections.length > section ? sections[section] : null; + }, + + fund : function(account_string) { + return this.getAccountStringSection(account_string, 0) + }, + + approp : function(account_string) { + return this.getAccountStringSection(account_string, 1) + }, + + costCenter : function(account_string) { + return this.getAccountStringSection(account_string, 2) + }, + + object : function(account_string) { + return this.getAccountStringSection(account_string, 3) + }, +} + +export default AccountString; \ No newline at end of file diff --git a/src/js/models/baseline.js b/src/js/models/baseline.js new file mode 100644 index 0000000..f7f3bf0 --- /dev/null +++ b/src/js/models/baseline.js @@ -0,0 +1,55 @@ +import Fund from "./fund.js"; +import FundLookupTable from "./fund_lookup_table.js"; + + +export class Baseline { + // baseline will just contain a list of funds, each with + // running tallies for their budgets + constructor() { + const allFunds = FundLookupTable.listFunds(); + this.funds = []; + allFunds.forEach((fund) => { + this.funds.push(new Fund(fund)); + }); + } + + static target() { return localStorage.getItem('target') }; + + personnel() { + let total = 0; + this.funds.forEach(fund => { + total += fund.getPersonnelCost(); + }); + return total; + } + + overtime() { + let total = 0; + this.funds.forEach(fund => { + total += fund.getOvertineCost(); + }); + return total; + } + + nonpersonnel() { + let total = 0; + this.funds.forEach(fund => { + total += fund.getNonPersonnelCost(); + }); + return total; + } + + revenue() { + let total = 0; + this.funds.forEach(fund => { + total += fund.getRevenue(); + }); + return total; + } + + total() { + return this.nonpersonnel() + this.personnel(); // + this.overtime(); + } +} + +export default Baseline; \ No newline at end of file diff --git a/src/js/models/current_fund.js b/src/js/models/current_fund.js new file mode 100644 index 0000000..b040e90 --- /dev/null +++ b/src/js/models/current_fund.js @@ -0,0 +1,19 @@ + +import FundLookupTable from "./fund_lookup_table"; + +export const CurrentFund = { + update : function(fund){ + localStorage.setItem('fund', fund); + }, + number : function(){ + return localStorage.getItem("fund"); + }, + name : function(){ + return FundLookupTable.getName( this.number()); + }, + reset : function() { + this.update(''); + } +} + +export default CurrentFund; \ No newline at end of file diff --git a/src/js/models/current_page.js b/src/js/models/current_page.js new file mode 100644 index 0000000..b3a5144 --- /dev/null +++ b/src/js/models/current_page.js @@ -0,0 +1,16 @@ +import { visitPage } from "../views/view_logic"; + +export const CurrentPage = { + update : function(page){ + localStorage.setItem('page_state', page); + }, + load : function(){ + const pageState = localStorage.getItem('page_state'); + return pageState !== null ? pageState : 'welcome'; + }, + visit : function(){ + visitPage(this.load()); + } +} + +export default CurrentPage; \ No newline at end of file diff --git a/src/js/models/fund.js b/src/js/models/fund.js new file mode 100644 index 0000000..0f96838 --- /dev/null +++ b/src/js/models/fund.js @@ -0,0 +1,194 @@ + +import { colSum } from "../utils/common_utils"; +import { TOTAL_COLUMNS } from '../constants/'; + +// Helper function to create a unique list of appropriations represented in a table +function fetchValueSet(table, key) { + + // IF there's no data, return an empty list + if(!table){ + return []; + } + + // Use a Set to store unique values + const uniqValues = new Set(); + + // Iterate through each object in the table + table.forEach(row => { + if (row[key]) { + uniqValues.add(row[key]); + } + }); + + // Convert the Set to an array if needed + return uniqValues; + } + +// Class to hold information on a specific fund and table +class StoredTable { + constructor(page, fund){ + this.name = `${page}_${fund}`; + this.page = page; + this.table = JSON.parse(localStorage.getItem(this.name)); + this.approps = fetchValueSet(this.table, 'Appropriation'); + this.cc = fetchValueSet(this.table, 'Cost Center'); + + } + + totalCol() { + return TOTAL_COLUMNS[this.page]; + } + getSum() { + // fill with zero until there is something saved in storage + return colSum(this.table, this.totalCol(), this.name); + } + + // key is the column to filter on (ie. Cost Center) + filter(key, value) { + if (this.table){ + // reassign underlying data in object if there's data to filter + this.table = this.table.filter(row => { + return (row[key]) && (row[key] == value); + }); + } + return this; + } + +} + +export class CostCenter{ + constructor(fund, approp, cc){ + const AppropObj = new Appropriation(fund, approp); + this.personnel = AppropObj.personnel.filter('Cost Center', cc); + this.nonpersonnel = AppropObj.nonpersonnel.filter('Cost Center', cc); + this.overtime = AppropObj.overtime.filter('Cost Center', cc); + this.revenue = AppropObj.revenue.filter('Cost Center', cc); + this.cc = cc; + this.account_string = `${AppropObj.accountString()}-${cc}`; + } + + getPersonnelCost() { + return this.personnel.getSum(); + } + + getOvertimeCost() { + return this.overtime.getSum(); + } + + getNonPersonnelCost() { + return this.nonpersonnel.getSum(); + } + + getRevenue() { + return this.revenue.getSum(); + } + + getTotal() { + // only sum expenditures, not net of revenue + return this.getNonPersonnelCost() + this.getOvertimeCost() + this.getPersonnelCost(); + } + + getName() { + // just grab the value in the cost center name column for the first row + if (!this.nonpersonnel.table[0]) { return '' }; + return 'Cost Center ' + this.nonpersonnel.table[0]['Cost Center Name']; + } + + accountString() { + return this.account_string; + } +} + +export class Appropriation { + constructor(fund, approp){ + const fundObj = new Fund(fund); + this.personnel = fundObj.personnel.filter('Appropriation', approp); + this.nonpersonnel = fundObj.nonpersonnel.filter('Appropriation', approp); + this.overtime = fundObj.overtime.filter('Appropriation', approp); + this.revenue = fundObj.revenue.filter('Appropriation', approp); + // own data + this.approp = approp; + this.fund = fundObj.fund; + + } + + getCostCenters(){ + // build a set of unique appropriations across all line items for the fund + const cc = new Set([...this.personnel.cc, + ...this.overtime.cc, + ...this.nonpersonnel.cc, + ...this.revenue.cc]); + + // initialize a list placeholder for the appropriations objects + const ccList = []; + // build out list + cc.forEach(num => { + ccList.push(new CostCenter(this.fund, this.approp, num)); + }); + return ccList; + } + + total(){ + return this.personnel.getSum() + this.overtime.getSum() + this.nonpersonnel.getSum(); + } + + name(){ + // just grab the value in the approp name column for the first row + if (!this.nonpersonnel.table[0]) { return '' }; + return 'Appropriation ' + this.nonpersonnel.table[0]['Appropriation Name']; } + + accountString(){ + return `${this.fund}-${this.approp}`; + } + +} + +// Holds all the detailed data for one fund's budget +export class Fund { + constructor(fund){ + this.fund = fund; + this.personnel = new StoredTable('personnel', fund); + this.overtime = new StoredTable('overtime', fund); + this.nonpersonnel = new StoredTable('nonpersonnel', fund); + this.revenue = new StoredTable('revenue', fund); + } + + getAppropriations(){ + // build a set of unique appropriations across all line items for the fund + const approps = new Set([...this.personnel.approps, + ...this.overtime.approps, + ...this.nonpersonnel.approps, + ...this.revenue.approps]); + + // initialize a list placeholder for the appropriations objects + const appropsList = []; + // build out list + approps.forEach(approp => { + appropsList.push( new Appropriation(this.fund, approp) ); + }); + return appropsList; + } + + getPersonnelCost() { + return this.personnel.getSum(); + } + + getOvertimeCost() { + return this.overtime.getSum(); + } + + getNonPersonnelCost() { + return this.nonpersonnel.getSum(); + } + + getRevenue() { + return this.revenue.getSum(); + } + + getTotal() { + // only sum expenditures, not net of revenue + return this.getNonPersonnelCost() + this.getOvertimeCost() + this.getPersonnelCost(); + } +} + +export default Fund; \ No newline at end of file diff --git a/src/js/models/fund_lookup_table.js b/src/js/models/fund_lookup_table.js new file mode 100644 index 0000000..dc2bc4f --- /dev/null +++ b/src/js/models/fund_lookup_table.js @@ -0,0 +1,115 @@ +import CurrentFund from "./current_fund"; +import { getUniqueValues } from "../utils/common_utils"; + +export const FundLookupTable = { + retrieve : function() { + return JSON.parse(localStorage.getItem('fund-lookup-table')) || {}; + }, + save : function(fundDict){ + localStorage.setItem('fund-lookup-table', JSON.stringify(fundDict)); + }, + + update : function(fundData){ + // reset + this.reset(); + // fill in with data stored in fundDate + const table = this.retrieve(); + for (let fund of Object.keys(fundData)){ + + // add to lookup table if not in there already + if (!table[fund]){ + // get fund name + const fundName = fundData[fund][0]['Fund Name']; + // add fund to dictionary + table[fund] = {}; + table[fund]['name'] = fundName; + table[fund]['viewed'] = false; + // build lists of unique cost centers and appropriations + table[fund]['approp'] = getUniqueValues(fundData[fund], 'Appropriation Name'); + table[fund]['cc'] = getUniqueValues(fundData[fund], 'Cost Center Name'); + } + } + // save any updates + this.save(table); + }, + + getAll: function(key) { + // function to aggregate all approps or CCs for every fund in one array + const funds = this.retrieve(); + const ret = []; + for (const fund in funds) { + if (funds.hasOwnProperty(fund)) { + for (let i in funds[fund][key]){ + ret.push(funds[fund][key][i]); + } + } + } + return ret; + }, + + getCostCenters : function() { + // get current fund + const fund = CurrentFund.number() + if (this.retrieve()[fund]){ + return this.retrieve()[fund]['cc']; + } + // if no fund (ie. we're on the new initiative page), return all options + return this.getAll('cc'); + }, + + getApprops : function() { + // get current fund + const fund = CurrentFund.number() + if (this.retrieve()[fund]){ + return this.retrieve()[fund]['approp']; + } + // if no fund (ie. we're on the new initiative page), return all options + return this.getAll('approp'); + }, + + reset : function() { + this.save({}); + }, + getName : function(number){ + if(!number || !this.retrieve()) { return '' }; + return this.retrieve()[number]['name']; + }, + listFunds : function(){ + return Object.keys(this.retrieve()); + }, + listFundNames : function(){ + const funds = this.retrieve(); + // initialize array + var ret = []; + Object.keys(funds).forEach( (fund_number) => { + var fund_name = funds[fund_number]['name']; + ret.push(fund_name); + }); + return ret; + }, + editFund : function(fund){ + const table = this.retrieve(); + if (table[fund]){ + table[fund]['viewed'] = true; + this.save(table); + } else { + console.error('No fund selected.'); + } + + }, + listUneditedFunds : function(){ + const table = this.retrieve(); + const ret = []; + this.listFunds().forEach(key => { + if (!table[key]['viewed']){ + ret.push(key); + } + }); + return ret; + }, + fundsLeft : function(){ + return (this.listUneditedFunds().length > 0); + } +} + +export default FundLookupTable \ No newline at end of file diff --git a/src/js/models/index.js b/src/js/models/index.js new file mode 100644 index 0000000..f2025bf --- /dev/null +++ b/src/js/models/index.js @@ -0,0 +1,11 @@ +// models/index.js + +export { default as AccountString } from './account_string.js'; +export { default as Baseline } from './baseline.js'; +export { default as CurrentFund } from './current_fund.js'; +export { default as CurrentPage } from './current_page.js'; +export { default as Fund } from './fund.js'; +export { default as FundLookupTable } from './fund_lookup_table.js'; +export { default as Initiative } from './initiative.js'; +export { default as Services } from './services.js'; +export { default as Supplemental } from './supplemental.js'; diff --git a/src/js/models/initiative.js b/src/js/models/initiative.js new file mode 100644 index 0000000..b4cb836 --- /dev/null +++ b/src/js/models/initiative.js @@ -0,0 +1,31 @@ + +// data structure to hold information on new initiatives + +export class Initiative { + + constructor(row) { + this.data = row; + this.name = row['Initiative Name']; + } + + expenses() { + if (this.data['Ballpark Total Expenses']) { + return this.data['Ballpark Total Expenses']; + } else { + return 0; + } + } + + revenue() { + if (this.data['Revenue']) { + return this.data['Revenue']; + } else { + return 0; + } + } + + net() { return this.expenses() } + +} + +export default Initiative; \ No newline at end of file diff --git a/src/js/models/services.js b/src/js/models/services.js new file mode 100644 index 0000000..9cf60e0 --- /dev/null +++ b/src/js/models/services.js @@ -0,0 +1,11 @@ +// data structure to save the possible service options for the department +export const Services = { + save : function(services){ + localStorage.setItem('services-list', JSON.stringify(services)); + }, + list : function(){ + return JSON.parse(localStorage.getItem('services-list')) || {}; + } +} + +export default Services; \ No newline at end of file diff --git a/src/js/models/supplemental.js b/src/js/models/supplemental.js new file mode 100644 index 0000000..d25add9 --- /dev/null +++ b/src/js/models/supplemental.js @@ -0,0 +1,35 @@ + +import Initiative from "./initiative.js"; +import { colSum, formatCurrency } from "../utils/common_utils.js"; + +// data structure to hold supplemental requests +export class Supplemental { + constructor() { + this.table = JSON.parse(localStorage.getItem(this.name)); + this.initiatives = []; + if(this.table){ + this.table.forEach((row) => { + this.initiatives.push(new Initiative(row)); + }); + } + } + + getInits() { + return this.table.map((item) => { return item['Initiative Name'] }); + } + + expenses() { + return colSum(this.table, 'Ballpark Total Expenses'); + } + + revenue() { + return colSum(this.table, 'Revenue'); + } + + total(){ + return this.expenses() - this.revenue(); + } + +} + +export default Supplemental; \ No newline at end of file diff --git a/src/js/utils/JSON_data_handlers.js b/src/js/utils/JSON_data_handlers.js new file mode 100644 index 0000000..f488001 --- /dev/null +++ b/src/js/utils/JSON_data_handlers.js @@ -0,0 +1,42 @@ +export async function fetchJSON(jsonFilePath) { + return fetch(jsonFilePath) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }); +} + +export function convertToJSON(table, colsToRemove = []){ + const rows = table.rows; + // Extract headers from the first row + const headerRow = rows[0].cells; + const headers = []; + for (let j = 0; j < headerRow.length; j++) { + headers.push(headerRow[j].innerText); + } + + // initialize data + var tableData = []; + + for (var i = 1; i < rows.length; i++) { + const cols = rows[i].cells; + const rowData = {}; + headers.forEach((header, index) => { + if (colsToRemove.includes(header)){ + return; + } + else if (cols[index].classList.contains('cost')) { + rowData[header] = cols[index].getAttribute('value'); + } else { + rowData[header] = cols[index].innerText; + } + }); + tableData.push(rowData); + } + return JSON.stringify(tableData); +} + + + \ No newline at end of file diff --git a/src/js/utils/XLSX_handlers.js b/src/js/utils/XLSX_handlers.js new file mode 100644 index 0000000..da0c8ce --- /dev/null +++ b/src/js/utils/XLSX_handlers.js @@ -0,0 +1,187 @@ + + +import { SHEETS, TARGET_CELL_ADDRESS } from '../constants/'; +import FundLookupTable from '../models/fund_lookup_table.js'; +import { removeNewLines } from './common_utils.js'; +import Baseline from '../models/baseline.js'; +import Services from '../models/services.js'; + +function deleteTopRowsUntilFullData(data) { + // function to try to find the top of the usable data + let fullDataRowFound = false; + + while (!fullDataRowFound && data.length > 0) { + const row = data[0]; // Get the top row + let hasAllData = true; + + for (const cell of row) { + if (cell == null || cell === '') { + hasAllData = false; + break; + } + } + + if (hasAllData && row.length > 1) { + fullDataRowFound = true; + } else { + // delete the top row if it's not the header row + data.shift(); + } + } + + return data; +} + +export function processWorkbook(arrayBuffer) { + const workbook = XLSX.read(arrayBuffer, { type: 'array' }); + workbook.SheetNames.forEach(sheetName => { + // only convert sheets we need + if (Object.keys(SHEETS).includes(sheetName)) { + // read in sheets + const sheet = workbook.Sheets[sheetName]; + const rawData = XLSX.utils.sheet_to_json(sheet, { header: 1, defval: '' }); + + // Clean the data by removing top rows with incomplete data + const dataRows = deleteTopRowsUntilFullData(rawData); + + // get new headers + const headers = dataRows[0]; + + // isolate Fund column to split data + const fundIndex = headers.indexOf('Fund'); + if (fundIndex === -1) { + console.error(`No 'Fund' column found in sheet ${sheetName}`); + return; + } + + // Save a dictionary of data for each fund for each sheet + const fundData = {}; + + dataRows.forEach(row => { + const fund = row[fundIndex]; + if(fund && fund != "Fund"){ + if (!fundData[fund]) { + fundData[fund] = []; + } + const rowData = {}; + headers.forEach((header, index) => { + rowData[removeNewLines(header)] = row[index]; + }); + fundData[fund].push(rowData); + } + }); + + // save fund number and name as we go along + FundLookupTable.update(fundData); + console.log('updating fund lookup table'); + + Object.keys(fundData).forEach(fund => { + const key = `${SHEETS[sheetName]}_${fund}`; + localStorage.setItem(key, JSON.stringify(fundData[fund])); + }); + } + + // But also save the possible services + else if (sheetName == 'Drop-Down Menus'){ + const sheet = workbook.Sheets[sheetName]; + // Convert the sheet to JSON to easily manipulate data + const sheetData = XLSX.utils.sheet_to_json(sheet, { header: 1 }); + + // Locate the "services" column header in row 0 + const headerRow = sheetData[0]; + const servicesIndex = headerRow.indexOf('Services'); + + if (servicesIndex === -1) { + console.error('Header "Services" not found'); + } else { + // Extract data from the "services" column (excluding the header row) + const servicesColumn = sheetData.slice(1).map(row => row[servicesIndex]); + const cleanedServicesColumn = servicesColumn.filter(value => value != null); + // save the data + Services.save(cleanedServicesColumn); + } + } + + else if(sheetName == 'Dept Summary'){ + const sheet = workbook.Sheets[sheetName]; + // get and save TARGET for general fund + if(sheet[TARGET_CELL_ADDRESS]) { + const cellValue = sheet[TARGET_CELL_ADDRESS].v; // Access the cell value + localStorage.setItem('target', cellValue); + } else { + console.error(`Cell ${TARGET_CELL_ADDRESS} not found in sheet ${sheetName}`); + } + } + }); + + console.log('all excel data saved'); +} + +// Utility function to append a sheet to the workbook if data is present +function appendSheetToWorkbook(workbook, data, sheetName) { + if (data.length > 0) { + const sheet = XLSX.utils.json_to_sheet(data); + XLSX.utils.book_append_sheet(workbook, sheet, sheetName); + } +} + +export function downloadXLSX() { + const baseline = new Baseline(); + const workbook = XLSX.utils.book_new(); // Create a new workbook + + const dataMap = { + Personnel: 'personnel', + Overtime: 'overtime', + NonPersonnel: 'nonpersonnel', + Revenue: 'revenue' + }; + + const sheetData = { + Personnel: [], + Overtime: [], + NonPersonnel: [], + Revenue: [] + }; + + baseline.funds.forEach(fund => { + Object.keys(dataMap).forEach(sheetName => { + if (fund[dataMap[sheetName]] && fund[dataMap[sheetName]].table) { + sheetData[sheetName].push(...fund[dataMap[sheetName]].table); + } + }); + }); + + Object.keys(sheetData).forEach(sheetName => { + appendSheetToWorkbook(workbook, sheetData[sheetName], sheetName); + }); + + // Generate a downloadable file + const wbout = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); + const blob = new Blob([wbout], { type: 'application/octet-stream' }); + + // Create a link and trigger the download + const link = document.createElement("a"); + link.href = URL.createObjectURL(blob); + link.download = "Filled_Detail_Sheet.xlsx"; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); +} + +export function excelSerialDateToJSDate(serial) { + + if (!serial) { return null }; + // Excel considers 1900-01-01 as day 1, but JavaScript's Date considers + // 1970-01-01 as day 0. Therefore, we calculate the number of milliseconds + // between 1900-01-01 and 1970-01-01. + const excelEpoch = new Date(Date.UTC(1899, 11, 30)); // JavaScript Consider December month as '11' + + // Calculate the JS date by adding serial days to the epoch date + const date = new Date(excelEpoch.getTime() + (serial * 24 * 60 * 60 * 1000)); + + // Set the time part to zero (midnight) + date.setUTCHours(0, 0, 0, 0); + + // Return the date part of the ISO string + return date.toISOString().split('T')[0]; +} diff --git a/src/js/utils/common_utils.js b/src/js/utils/common_utils.js new file mode 100644 index 0000000..78c908e --- /dev/null +++ b/src/js/utils/common_utils.js @@ -0,0 +1,74 @@ +// Function to format number as currency +export const formatCurrency = (amount, return_zero = false) => { + var amount = Math.round(parseFloat(amount)); + if (amount == NaN){ + return "$ -" + } + if (amount < 0){ + return '($' + amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + ')'; + } else if (amount == 0) { + if (return_zero){ + return '$0'; + } + return "$ -" + } + return '$' + amount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); +} ; + +// function to convert formatted number to a float +export const unformatCurrency = (formattedAmount) => { + if (!formattedAmount) { return 0 }; + // Remove any currency symbols and commas + let numericalPart = formattedAmount.replace(/[^0-9.-]+/g, ""); + if (numericalPart == '-'){ + return 0; + } + return parseFloat(numericalPart); +}; + +export function displayWithCommas(value) { + if (value == 0){ + return 0; + } + return formatCurrency(value).replace('$', ''); +} + +export function cleanString(str){ + return str.toLowerCase().replaceAll(' ', '-'); +} + +export function removeNewLines(str){ + // replace all new lines with spaces + str = str.replaceAll(/[\r\n]+/g, " "); + // remove any extra spaces or trailing/leading whitespace + str = str.replaceAll(' ', ' '); + str = str.replaceAll(' ', ' '); + str = str.replace(/^\s+|\s+$/g, ''); + return str; +} + +export function colSum(table, colName) { + // fill with zero until there is something saved in storage + if(!table || table == ''){ + return 0; + } + const headers = Object.keys(table[0]); + if (headers.includes(colName)) { + let sum = 0; + for (let i = 0; i < table.length; i++){ + var value = Math.round(parseFloat(table[i][colName])); + // treat NaN (non-numerics) as zeroes + if (value) { sum += value; } + } + return sum; + } else { + // console.error(`Could not find expected total column in saved data for ${name}. Returning 0. See StoredTable.totalCol() switch.`); + return 0; + } + +} + +export function getUniqueValues(data, key) { + const values = data.map(obj => obj[key]); + return Array.from(new Set(values)); +} diff --git a/src/js/views/00_welcome.js b/src/js/views/00_welcome.js new file mode 100644 index 0000000..eb6b5ae --- /dev/null +++ b/src/js/views/00_welcome.js @@ -0,0 +1,32 @@ + +import Welcome from '../components/welcome/welcome.js'; +import { View } from './view_class.js'; +import { visitPage } from './view_logic.js'; + +export class WelcomeView extends View { + + constructor() { + super(); + this.page_state = 'welcome'; + this.subtitle = 'Welcome'; + this.sidebar = false; + this.navButtons = false; + } + + visit() { + super.visit(); + + // show welcome section + Welcome.show(); + + // initialize links in buttons + document.getElementById('step-upload').addEventListener('click', () => visitPage('upload')); + document.getElementById('step-initiatives').addEventListener('click', () => visitPage('new-inits')); + document.getElementById('step-revenue').addEventListener('click', () => visitPage('baseline-landing')); + document.getElementById('step-finish').addEventListener('click', () => visitPage('summary')); + + } + +} + +export default WelcomeView; diff --git a/src/js/views/01_upload.js b/src/js/views/01_upload.js new file mode 100644 index 0000000..42fd9eb --- /dev/null +++ b/src/js/views/01_upload.js @@ -0,0 +1,22 @@ +import { View } from './view_class.js' + +import FileUpload from "../components/file_upload/file_upload.js"; + +export class UploadView extends View { + + constructor() { + super(); + this.page_state = 'upload'; + this.prompt = `Upload the baseline detail sheet given by your budget analyst.`; + this.subtitle = 'Excel Upload'; + this.sidebar = false; + } + + visit() { + super.visit(); + FileUpload.show(); + FileUpload.init(); + } +} + +export default UploadView; \ No newline at end of file diff --git a/src/js/views/02_baseline_landing.js b/src/js/views/02_baseline_landing.js new file mode 100644 index 0000000..c611273 --- /dev/null +++ b/src/js/views/02_baseline_landing.js @@ -0,0 +1,92 @@ +import NavButtons from "../components/nav_buttons/nav_buttons.js"; +import Table from "../components/table/table.js"; +import { View, ViewTable } from './view_class.js' +import CurrentFund from "../models/current_fund.js"; + +export class FundView extends View { + + constructor() { + super(); + this.page_state = 'baseline-landing'; + this.prompt = `We will now ask you a series of questions about your BASELINE budget request. + At the end, we will ask you about any new initiatives (ie. supplemental requests). + Select one of your funds then click continue.`; + this.subtitle = 'Baseline Budget Request'; + this.table = new FundTable(); + this.sidebar = false; + this.dataTable = false; + } + + visit() { + // remove fund selection + localStorage.setItem("fund", ''); + super.visit(); + } +} + +class FundTable extends ViewTable { + + constructor() { + super(); + + // add additional revenue columns to the table + this.columns = [ + { title: 'Fund', className: 'fund-name' } + ]; + + this.noDataMessage = 'No funds found.' + this.addEdit = false; + } + + build(){ + // load in fund data + Table.show(); + Table.Data.loadFunds(); + Table.Columns.assignClasses(this.columns); + Table.adjustWidth('30%'); + + // disable next button until a fund is selected + NavButtons.Next.disable(); + allowRowSelection(); + } +} + + +function allowRowSelection(){ + + var tableRows = document.querySelectorAll("tbody tr"); + + // enable highlight on hover and on select + tableRows.forEach(function(row) { + row.addEventListener('mouseover', function() { + this.classList.add('hover-effect'); + }); + row.addEventListener('mouseout', function() { + this.classList.remove('hover-effect'); + }); + row.addEventListener('click', function() { + selectFund(tableRows, this); + }); + }); +} + +function selectFund(tableRows, selected_row){ + + // remove selected class from any other rows + tableRows.forEach(function(tableRow) { + tableRow.classList = ''; + }); + + // add selected class to clicked row + selected_row.classList.add('selected'); + + // get fund and save selected fund + var fund = selected_row.querySelector('.fund-name').textContent; + var fundNumber = parseInt(fund); + CurrentFund.update(fundNumber); + + // enable next step + NavButtons.Next.enable(); +} + +export default FundView; \ No newline at end of file diff --git a/src/js/views/03_revenue.js b/src/js/views/03_revenue.js new file mode 100644 index 0000000..37946ce --- /dev/null +++ b/src/js/views/03_revenue.js @@ -0,0 +1,44 @@ +import { View, ViewTable } from './view_class.js' + +import Table from '../components/table/table.js'; + +export class RevenueView extends View { + + constructor(fiscal_year) { + super(); + this.page_state = 'revenue'; + this.prompt = `Review and edit revenue line items. If you change the estimate or + notice an error in an account string, please note it in the notes column. Click edit + to change values in a row.`; + this.subtitle = 'Revenues'; + this.table = new RevenueTable(fiscal_year); + } +} + +class RevenueTable extends ViewTable { + + constructor(fiscal_year) { + super(); + + // add additional revenue columns to the table + this.columns = this.columns.concat([ + { title: 'Recurring or One-Time', className: 'recurring'}, + { title: 'Object Category', className: 'object-category'}, + { title: `FY${fiscal_year} Departmental Estimate`, className: 'request', isCost: true}, + { title: 'Departmental Estimate Notes', className: 'notes'}, + // hidden + { title: 'Object Name', className: 'object-name', hide: true}, + { title: 'Object', className: 'object', hide: true}, + ]); + + this.noDataMessage = 'No revenues for this fund.' + } + + // action on row edit click: make cells editable + actionOnEdit() { + // only allow edits in the notes box + Table.Cell.createTextbox('notes', false, 'textarea'); + } +} + +export default RevenueView; \ No newline at end of file diff --git a/src/js/views/04_personnel.js b/src/js/views/04_personnel.js new file mode 100644 index 0000000..5c9344d --- /dev/null +++ b/src/js/views/04_personnel.js @@ -0,0 +1,99 @@ +import { View, ViewTable } from './view_class.js' + +import Table from "../components/table/table.js"; +import Form from "../components/form/form.js"; + +import { Services, FundLookupTable } from '../models/'; +import { unformatCurrency } from "../utils/common_utils.js"; +import { EMPLOYEE_TYPES } from '../constants/budget_constants.js'; + +export class PersonnelView extends View { + + constructor(fiscal_year) { + super(); + this.page_state = 'personnel'; + this.prompt = ` + This table displays the number of FTEs in each job code for in your department's + current (amended) FY25 budget. To make edits to the number of positions, click the + "Edit" button on the row you would like to edit. The "Total Cost" column and the + summary sidebar will also update to reflect any edits.`; + this.subtitle = 'Personnel'; + this.table = new PersonnelTable(fiscal_year); + } +} + + +class PersonnelTable extends ViewTable { + + constructor(fiscal_year) { + super(); + this.fiscal_year = fiscal_year; + // add additional personnel columns to the table + this.columns = this.columns.concat([ + { title: 'Job Title', className: 'job-name' }, + { title: 'Employee Type', className: 'employee-type'}, + { title: 'Service', className: 'service' }, + { title: `FY${this.fiscal_year} Requested FTE`, className: 'baseline-ftes' }, + { title: `FY${this.fiscal_year} Projected Average Salary/Wage`, className: 'avg-salary', isCost: true }, + { title: 'Total Sal/Wag & Ben Request', className: 'total-baseline', isCost: true }, + { title: 'Departmental Request Notes', className: 'notes'}, + // hidden columns + { title: 'Fringe Benefits Rate', className: 'fringe', hide: true }, + { title: 'General Increase Rate', className: 'general-increase-rate', hide: true}, + { title: 'Step/Merit Increase Rate', className: 'merit-increase-rate', hide: true}, + { title: `Average Salary/Wage as of 9/1/20${this.fiscal_year-2}`, className: 'current-salary', isCost: true, hide: true} + ]); + + this.noDataMessage = 'No personnel expenditures for this fund.' + this.addButtonText = 'Add new job' ; + } + + // action on row edit click: make cells editable + actionOnEdit() { + Table.Cell.createTextbox('baseline-ftes'); + Table.Cell.createServiceDropdown(Services.list()); + Table.Cell.createTextbox('notes', false, 'textarea'); + } + + updateTable(){ + // calculate for each row + let rows = document.getElementsByTagName('tr'); + for (let i = 1; i < rows.length; i++){ + // fetch values for calculations + let avg_salary = Table.Cell.getValue(rows[i], 'avg-salary'); + let fringe = parseFloat(Table.Cell.getText(rows[i], 'fringe')); + let baseline_ftes = Table.Cell.getText(rows[i], 'baseline-ftes'); + + // calcuate #FTEs x average salary + COLA adjustments + merit adjustments + fringe + let total_baseline_cost = avg_salary * baseline_ftes * (1 + fringe); + + // update total column + Table.Cell.updateValue(rows[i], 'total-baseline', total_baseline_cost); + } + + // Save the table after all updates are done + Table.save(); + } + + addCustomQuestions(){ + // form questions to add a new job + Form.NewField.shortText('Job Title:', 'job-name', true); + Form.NewField.dropdown('Employee Type:', 'employee-type', EMPLOYEE_TYPES, true), + Form.NewField.dropdown('Appropriation:', 'approp-name', FundLookupTable.getApprops(), true); + Form.NewField.dropdown('Cost Center:', 'cc-name', FundLookupTable.getCostCenters(), true); + Form.NewField.dropdown('Service', 'service', Services.list(), true); + Form.NewField.shortText('Number of FTEs requested:', 'baseline-ftes', true); + Form.NewField.shortText(`Projected average salary IN FISCAL YEAR ${this.fiscal_year}:`, 'avg-salary', true); + Form.NewField.shortText(`Expected fringe rate (as a percentage)`, 'fringe', true); + } + + editColumns(responses){ + responses = super.editColumns(responses); + // edit inputs from modal + responses['avg-salary'] = unformatCurrency(responses['avg-salary']); + responses['fringe'] = parseFloat(responses['fringe']) / 100; + return responses; + } +} + +export default PersonnelView; \ No newline at end of file diff --git a/src/js/views/05_overtime.js b/src/js/views/05_overtime.js new file mode 100644 index 0000000..292ebd3 --- /dev/null +++ b/src/js/views/05_overtime.js @@ -0,0 +1,92 @@ + + +import { View, ViewTable } from './view_class.js' +import Table from '../components/table/table.js'; +import Form from '../components/form/form.js'; +import { FundLookupTable, Services } from '../models/'; +import { unformatCurrency } from '../utils/common_utils.js'; +import { OT_OBJECTS } from '../constants/'; + +export class OvertimeView extends View { + + constructor(fiscal_year) { + super(); + this.page_state = 'overtime'; + this.prompt = ` + Please see your baseline overtime / holiday pay / shift premiums in the table below. + Make any edits and continue.`; + this.subtitle = 'Overtime Estimates'; + this.table = new OvertimeTable(fiscal_year); + } +} + +class OvertimeTable extends ViewTable { + + constructor(fiscal_year) { + super(); + + // add additional OT columns to the table + this.columns = this.columns.concat([ + { title: 'Service', className: 'service' }, + { title: 'Recurring or One-Time', className: 'recurring'}, + { title: 'Departmental Request OT/SP/Hol', className: 'OT-pay', isCost: true }, + { title: `FY${fiscal_year} Total OT/SP/Hol + FICA Request`, className : 'total', isCost: true}, + { title: 'Object Name', className: 'object-name'}, + { title: 'Departmental Request Notes', className: 'notes'}, + // hidden columns + { title: 'FICA Rate', className: 'fica', hide: true}, + ]); + + this.noDataMessage = 'No overtime expenditures for this fund.' + this.addButtonText = 'Add new cost center' ; + } + + // action on row edit click: make cells editable + actionOnEdit() { + Table.Cell.createTextbox('OT-pay', true); + Table.Cell.createServiceDropdown(Services.list()); + Table.Cell.createDropdown('recurring', ['One-Time', 'Recurring']); + Table.Cell.createDropdown('object-name', OT_OBJECTS); + Table.Cell.createTextbox('notes'); + } + + updateTable(){ + + // calculate for each row + let rows = document.getElementsByTagName('tr'); + for (let i = 1; i < rows.length; i++){ + // fetch values for calculations + let OT_salary = Table.Cell.getValue(rows[i], 'OT-pay'); + let fica_rate = Table.Cell.getText(rows[i], 'fica'); + + // add salary and wages and fringe benefits (FICA) + let row_total = OT_salary * (1 + parseFloat(fica_rate)); + + // update total + Table.Cell.updateValue(rows[i], 'total', row_total); + } + + // Save the table after all updates are done + Table.save(); + } + + addCustomQuestions(){ + // form questions to add a new job + Form.NewField.dropdown('Appropriation:', 'approp-name', FundLookupTable.getApprops(), true); + Form.NewField.dropdown('Cost Center:', 'cc-name', FundLookupTable.getCostCenters(), true); + Form.NewField.dropdown('Object (salary or wage):', 'object-name', OT_OBJECTS, true); + Form.NewField.dropdown('Service', 'service', Services.list(), true); + Form.NewField.dropdown('Recurring or One-Time', 'recurring', ['Recurring', 'One-Time'], true); + Form.NewField.shortText('Overtime amount requested:', 'OT-pay', true); + } + + editColumns(responses){ + responses = super.editColumns(responses); + // edit inputs from modal + responses['OT-pay'] = unformatCurrency(responses['OT-pay']); + responses['fica'] = 0.0765; + return responses; + } +} + +export default OvertimeView; \ No newline at end of file diff --git a/src/js/views/06_nonpersonnel.js b/src/js/views/06_nonpersonnel.js new file mode 100644 index 0000000..5bab8d3 --- /dev/null +++ b/src/js/views/06_nonpersonnel.js @@ -0,0 +1,76 @@ +import { View, ViewTable } from './view_class.js' +import Form from '../components/form/form.js'; +import Table from '../components/table/table.js'; +import { FundLookupTable, Services } from '../models/'; +import { unformatCurrency } from '../utils/common_utils.js'; +import { OBJ_CATEGORIES } from '../constants/'; + +export class NonPersonnelView extends View { + + constructor(fiscal_year) { + super(); + this.page_state = 'nonpersonnel'; + this.prompt = `Review and edit non-personnel line items. The CPA numbers are the + Contract and Procurement Account numbers. Click on the 'detail' link for a CPA + to see the contract details. Some line items won't have a CPA number.`; + this.subtitle = 'Non-Personnel'; + this.table = new NonPersonnelTable(fiscal_year); + } +} + +class NonPersonnelTable extends ViewTable { + + constructor(fiscal_year) { + super(); + + // add additional personnel columns to the table + this.columns = this.columns.concat([ + { title: `FY${fiscal_year} Departmental Request Total`, className: 'request', isCost: true }, + { title: 'Service', className : 'service' }, + { title: 'Recurring or One-Time', className: 'recurring'}, + { title: 'Vendor Name', className: 'vendor'}, + { title : 'CPA #', className : 'cpa'}, + // hidden columns + { title: 'End Date', className: 'contract-end', hide: true}, + { title: 'BPA/CPA Amount Remaining', className: 'remaining', isCost: true , hide: true}, + { title: 'Object Name', className: 'object-name', hide: true}, + { title: 'Object', className: 'object', hide: true}, + { title: 'Object Category', className: 'object-category', hide: true}, + { title: 'BPA/CPA Description', className: 'cpa-description', hide: true}, + { title: 'Departmental Request Notes', className: 'notes'}, + ]); + + this.noDataMessage = 'No non-personnel expenditures for this fund.' + this.addButtonText = 'Add new non-personnel item' ; + } + + // action on row edit click: make cells editable + actionOnEdit() { + Table.Cell.createTextbox('request', true); + Table.Cell.createServiceDropdown(); + Table.Cell.createDropdown('recurring', ['One-Time', 'Recurring']); + Table.Cell.createTextbox('notes'); + } + + addCustomQuestions(){ + // form questions to add a new row + Form.NewField.dropdown('Appropriation:', 'approp-name', FundLookupTable.getApprops(), true); + Form.NewField.dropdown('Cost Center:', 'cc-name', FundLookupTable.getCostCenters(), true); + Form.NewField.dropdown('Object Category:', 'object-category', OBJ_CATEGORIES.list, true); + // TODO: maybe give dropdown based on selected obj category + Form.NewField.shortText('Object Number (if known):', 'object', false); + Form.NewField.dropdown('Service', 'service', Services.list(), true); + Form.NewField.longText('Describe your new request:', 'cpa-description', true); + Form.NewField.dropdown('Recurring or One-Time', 'recurring', ['Recurring', 'One-Time'], true); + Form.NewField.shortText('Amount requested:', 'request', true); + } + + editColumns(responses){ + responses = super.editColumns(responses); + responses['avg-salary'] = unformatCurrency(responses['avg-salary']); + responses['fringe'] = parseFloat(responses['fringe']) / 100; + return responses; + } +} + +export default NonPersonnelView; \ No newline at end of file diff --git a/src/js/views/07_new_initiatives.js b/src/js/views/07_new_initiatives.js new file mode 100644 index 0000000..dcf6bac --- /dev/null +++ b/src/js/views/07_new_initiatives.js @@ -0,0 +1,92 @@ + +import { View, ViewTable } from './view_class.js' +import Table from "../components/table/table.js"; +import Form from "../components/form/form.js"; +import FundLookupTable from '../models/fund_lookup_table.js'; +import { FISCAL_YEAR } from '../constants/'; + + +const dropdownOptions = ['N/A', 'One-Time', 'Recurring'] + +// set up page and initialize all buttons +export class InitiativesView extends View { + + constructor() { + super(); + this.page_state = 'new-inits'; + this.prompt = ` + This is the place to propose new initiatives for FY${FISCAL_YEAR}. + New initiative submissions will count as supplemental line items and will be the starting + point for a conversation with both OB and ODFS, who will help with the details.`; + this.subtitle = 'New Initiatives'; + this.table = new InitiativesTable(); + } + + visit() { + // remove fund selection + localStorage.setItem("fund", ''); + super.visit(); + } + +} + +class InitiativesTable extends ViewTable { + + constructor() { + super(); + + // add additional columns to the table + this.columns = this.columns.concat([ + { title: 'Initiative Name', className: 'init-name' }, + { title: 'Ballpark Total Expenses', className: 'total', isCost: true }, + { title: 'Personnel Cost', className: 'personnel', isCost: true }, + { title: 'Non-personnel Cost', className: 'nonpersonnel', isCost: true }, + { title: 'Revenue', className: 'revenue', isCost: true }, + { title: 'Revenue Type', className: 'rev-type' }, + + // hide the explanation columns + { title: 'Q1', className: 'q1', hide: true }, + { title: 'Q2', className: 'q2', hide: true }, + { title: 'Q3', className: 'q3', hide: true } + ]); + + this.addButtonText = 'Add new initiative' ; + } + + addCustomQuestions(){ + + // general questions + Form.NewField.shortText('Initiative Name:', 'init-name', true); + Form.NewField.longText('What is the business case for the Initiative?', 'q1', true); + Form.NewField.longText(`Why is the initiative needed? What is the value-add to residents? + What is the Department’s plan for implementing the Initiative?`, 'q2', true); + Form.NewField.longText(`Why can’t the Initiative be funded with the Department’s baseline budget?`, 'q3', true); + + // TODO: Edit to drop down + Form.NewField.dropdown('Fund:', 'fund-name', FundLookupTable.listFundNames(), true); + Form.NewField.dropdown('Appropriation (if known):', 'approp-name', FundLookupTable.getApprops(), true); + Form.NewField.dropdown('Cost Center (if known):', 'cc-name', FundLookupTable.getCostCenters(), true); + + // Numbers + Form.NewField.numericInput('What is your ballpark estimate of TOTAL ADDITONAL expenses associated with this initiative?', + 'total', false); + Form.NewField.numericInput('Estimate of ADDITONAL personnel cost?', 'personnel', false); + Form.NewField.numericInput('Estimate of ADDITONAL nonpersonnel cost?', 'nonpersonnel', false); + Form.NewField.numericInput('Estimate of ADDITONAL revenue (if applicable)?', 'revenue', false); + Form.NewField.dropdown(`If there will be revenue, is it one-time or recurring?`, + 'rev-type', dropdownOptions); + } + + // action on row edit click: make cells editable + actionOnEdit() { + Table.Cell.createTextbox('total', true); + Table.Cell.createTextbox('revenue', true); + Table.Cell.createTextbox('personnel', true); + Table.Cell.createTextbox('nonpersonnel', true); + Table.Cell.createTextbox('init-name'); + Table.Cell.createDropdown('rev-type', dropdownOptions); + } + +} + +export default InitiativesView; \ No newline at end of file diff --git a/src/js/views/08_summary.js b/src/js/views/08_summary.js new file mode 100644 index 0000000..21f0df3 --- /dev/null +++ b/src/js/views/08_summary.js @@ -0,0 +1,69 @@ +import CurrentFund from '../models/current_fund.js'; +import Baseline from '../models/baseline.js'; +import { Accordion } from "../components/accordion/accordion.js"; +import { formatCurrency } from '../utils/common_utils.js'; +import { View } from "./view_class.js"; +import Prompt from "../components/prompt/prompt.js"; +import { downloadXLSX } from "../utils/XLSX_handlers.js"; +import WelcomeView from './00_welcome.js'; + +export function compareToTarget(){ + const baseline = new Baseline; + if (baseline.total() <= Baseline.target()){ + Prompt.Text.update(`Congrats! Your budget is below your target! + Edit any line items below or download your completed Excel.`); + } else { + Prompt.Text.update(`Your budget is above your target of ${formatCurrency(Baseline.target())}. + Please expand the summary table below and edit line items until you meet your target. + When you meet the target, you will be able to download the Excel sheet.`); + Prompt.Buttons.Right.disable(); + } + Prompt.show(); +} + +function returnToWelcome() { + const welcome = new WelcomeView(); + const left = document.getElementById('option1'); + console.log(left.l) + welcome.visit(); +}; + +export class SummaryView extends View { + + constructor() { + super(); + this.page_state = 'summary'; + this.subtitle = 'Summary'; + this.sidebar = false; + } + + visit() { + super.visit(); + + // reset fund + CurrentFund.reset(); + + // show summary accordion + Accordion.build(); + Accordion.show(); + + // add prompt buttons + Prompt.Buttons.Right.updateText('Download Excel'); + Prompt.Buttons.Left.updateText('Start over with new Excel upload'); + // add button links + Prompt.Buttons.Left.addAction(returnToWelcome); + Prompt.Buttons.Right.addAction(downloadXLSX); + + // update prompt text depending on target matching + compareToTarget(); + } + + cleanup() { + // delete event listeners + Prompt.Buttons.Left.removeAction(returnToWelcome); + Prompt.Buttons.Right.removeAction(downloadXLSX); + Prompt.Buttons.Right.enable(); + } +} + +export default SummaryView; \ No newline at end of file diff --git a/src/js/views/view_class.js b/src/js/views/view_class.js new file mode 100644 index 0000000..8ecdf52 --- /dev/null +++ b/src/js/views/view_class.js @@ -0,0 +1,227 @@ +import Prompt from "../components/prompt/prompt.js"; +import Sidebar from "../components/sidebar/sidebar.js"; +import NavButtons from "../components/nav_buttons/nav_buttons.js"; +import Body from "../components/body/body.js"; +import { Subtitle, Title } from "../components/header/header.js"; +import Table from "../components/table/table.js"; +import Form from "../components/form/form.js"; +import Modal from "../components/modal/modal.js"; + +import { CurrentPage, AccountString } from '../models/' + + +export class View { + + constructor() { + // page state in local storage + this.page_state = ''; + + // whether to display + this.navButtons = true; + this.sidebar = true; + + // text to show in the prompt area + this.prompt = null; + + // subtitle text + this.subtitle = ''; + + // table object of class ViewTable or null + this.table = null; + } + + visit() { + // update page state + CurrentPage.update(this.page_state); + + // start with a blank page + Body.reset(); + + // add default title + Title.default(); + + // default to showing navbuttons + if (this.navButtons) { NavButtons.show(); }; + + // default to showing sidebar + if (this.sidebar) { Sidebar.show() }; + + // initialize prompt text and buttons + if (this.prompt) { Prompt.Text.update(this.prompt) }; + + // initialize table + if (this.table) { this.table.build(); } + + // show page subtitle + if (this.subtitle) { Subtitle.update(this.subtitle) }; + } + + cleanup() { return; } + +} + +export class ViewTable { + + constructor(){ + // Ensure methods retain the correct `this` context + this.submitNewRow = this.submitNewRow.bind(this); + + this.columns = [ + { title: 'Account String', className: 'account-string' }, + { title: 'Appropriation Name', className: 'approp-name', hide: true }, + { title: 'Appropriation', className: 'approp', hide: true }, + { title: 'Cost Center Name', className: 'cc-name', hide: true }, + { title: 'Cost Center', className: 'cc', hide: true }, + { title: 'Fund Name', className: 'fund-name', hide: true }, + { title: 'Fund', className: 'fund', hide: true }, + { title: 'Edit', className: 'edit' }, + ]; + + // whether to add an edit column + this.addEdit = true ; + + // message to show if there's no saved data + this.noDataMessage = null; + + // text to show for new row button + this.addButtonText = null ; + + // whether to show as a datatable + this.dataTable = true; + } + + async build() { + // build table from local storage and initialize edit buttons + + // add the add new row button if needed + if (this.addButtonText) { + this.setUpForm(); + } + + // fill table with new data from local storage + if(await Table.Data.load()) { + + // create a datatable object + if(this.dataTable){this.initDataTable()} + + // add an edit column if needed + if (this.addEdit) { + Table.Columns.addAtEnd(Table.Buttons.edit_confirm_btns, 'Edit'); + // activate edit buttons + Table.Buttons.Edit.init(this.actionOnEdit, this.updateTable); + } + + // assign the correct classes based on the table columns + Table.Columns.assignClasses(this.columns); + + // Apply any update function to make sure sidebar is up to date + this.updateTable(); + + // Add all relevant filters to table + Table.Filter.add('Appropriation', 'approp-name'); + Table.Filter.add('Cost Center', 'cc-name'); + if (this.columns.some(column => column.className === 'object-name')){ + Table.Filter.add('Object', 'object-name'); + }; + if (this.columns.some(column => column.className === 'object-category')){ + Table.Filter.add('Object Category', 'object-category'); + } + + } else { + + // show a message if there's no saved table data for the selected fund + if (this.noDataMessage) { + Prompt.Text.update(this.noDataMessage); + } + } + + } + + initDataTable() { + Table.adjustWidth('100%'); + // Initialize Datatables + if ( !$.fn.dataTable.isDataTable('#main-table') ) { + $('#main-table').DataTable({ + paging: false, // Disable pagination + info: false, // Disable table information display + searching: false // Disable the search bar + }); + }; + } + + // placeholder for action on row edit click + actionOnEdit() { return } + + // update function for the sidebar; default to just saving the table + updateTable() { Table.save() } + + // extra questions of the form to add a new row + addCustomQuestions() { return }; + + setUpForm() { + // show add button + Table.Buttons.AddRow.show(); + Table.Buttons.AddRow.updateText(this.addButtonText); + + // set up modal for form when add button is pressed + Modal.clear(); + Modal.Link.add('add-btn'); + Modal.Title.update(this.addButtonText); + + // create form + Form.new('modal-body'); + + // add custom questions + this.addCustomQuestions(); + // add submit button + Form.SubmitButton.add(); + + // Initialize form submission to table data + Modal.Submit.init(this.submitNewRow); + } + + editColumns(responses) { + // get numbers from account string names + if(responses['fund-name']){ + responses['fund'] = AccountString.getNumber(responses['fund-name']); + }; + if(responses['approp-name']){ + responses['approp'] = AccountString.getNumber(responses['approp-name']); + }; + if(responses['cc-name']){ + responses['cc'] = AccountString.getNumber(responses['cc-name']); + }; + if(responses['object-name']){ + responses['object'] = AccountString.getNumber(responses['object-name']); + }; + responses['account-string'] = + AccountString.build(responses['approp-name'], + responses['cc-name'], + responses['object-name'], + responses['fund']); + return responses; + } + + submitNewRow(event) { + // get answers from form, hide form, show answers in table + var responses = Form.fetchAllResponses(event); + + // edit inputs from modal + responses = this.editColumns(responses); + + // make sure it's not an empty response + if (Object.values(responses)[0] != ''){ + + // change page view + Modal.hide(); + + // add data to table + Table.Rows.add(responses, this.columns); + Table.save(); + + // rebuild table + this.build(); + } + } + +} \ No newline at end of file diff --git a/src/js/views/view_logic.js b/src/js/views/view_logic.js new file mode 100644 index 0000000..bcff6d1 --- /dev/null +++ b/src/js/views/view_logic.js @@ -0,0 +1,104 @@ +import WelcomeView from './00_welcome.js'; +import UploadView from './01_upload.js'; +import FundView from './02_baseline_landing.js'; +import RevenueView from './03_revenue.js'; +import PersonnelView from './04_personnel.js'; +import OvertimeView from './05_overtime.js'; +import NonPersonnelView from './06_nonpersonnel.js'; +import InitiativesView from './07_new_initiatives.js'; +import SummaryView from './08_summary.js'; + +import { FundLookupTable, CurrentFund, CurrentPage } from '../models/'; +import { FISCAL_YEAR } from '../constants/'; + +export function initializePages() { + const PAGES = { + 'welcome': new WelcomeView(), + 'upload': new UploadView(), + 'baseline-landing': new FundView(), + 'revenue': new RevenueView(FISCAL_YEAR), + 'personnel': new PersonnelView(FISCAL_YEAR), + 'overtime': new OvertimeView(FISCAL_YEAR), + 'nonpersonnel': new NonPersonnelView(FISCAL_YEAR), + 'new-inits': new InitiativesView(), + 'summary': new SummaryView(), + }; + return PAGES; +} + +export function visitPage(new_page_key){ + + const PAGES = initializePages(); + + // clean up from current page + var page_state = CurrentPage.load(); + PAGES[page_state].cleanup(); + + // Use the page_state to access and call the corresponding function from PAGES + if (PAGES[new_page_key]) { + // Invokes the function if it exists in the PAGES map + PAGES[new_page_key].visit(); + } else { + console.error(`No page initializer found for state: ${new_page_key}`); + }} + +export function nextPage(){ + + const PAGES = initializePages(); + + var page_state = CurrentPage.load(); + const keys = Object.keys(PAGES); + + // Find the index of the current key + const currentIndex = keys.indexOf(page_state); + + // Return to summary if all funds are viewed + const returnPages = ['revenue', 'nonpersonnel', 'new-inits', 'overtime', 'personnel']; + if (!FundLookupTable.fundsLeft() && returnPages.includes(CurrentPage.load())) { + visitPage('summary'); + return; + } + + // if on non-personnel, circle back to fund selection unless all funds are edited + if (CurrentPage.load() == 'nonpersonnel'){ + // mark fund as viewed/edited + FundLookupTable.editFund(CurrentFund.number()); + // if any funds left to edit, go back to that page + if ( FundLookupTable.fundsLeft() ){ + visitPage('baseline-landing'); + return; + } + } + + if (currentIndex >= 0 && currentIndex < keys.length - 1) { + // Check if there is a next key, and get it + const nextKey = keys[currentIndex + 1]; + // go to that page + visitPage(nextKey); + } +} + +export function lastPage(){ + + const PAGES = initializePages(); + + var page_state = CurrentPage.load(); + const keys = Object.keys(PAGES); + + // Find the index of the current key + const currentIndex = keys.indexOf(page_state); + + // if on new-inits, circle back to fund selection + if (CurrentPage.load() == 'new-inits'){ + visitPage('baseline-landing'); + return; + } + + // Check if there is a next key + if (currentIndex >= 1) { + // Get the next key + const lastKey = keys[currentIndex - 1]; + // go to that page + visitPage(lastKey); + } +} \ No newline at end of file