{"id":201,"date":"2026-04-27T15:07:19","date_gmt":"2026-04-27T15:07:19","guid":{"rendered":"https:\/\/incometaxbill.com\/wp\/capital-gains-tax-calculator\/"},"modified":"2026-04-27T15:12:30","modified_gmt":"2026-04-27T15:12:30","slug":"capital-gains-tax-calculator","status":"publish","type":"page","link":"https:\/\/incometaxbill.com\/wp\/capital-gains-tax-calculator\/","title":{"rendered":"2026 Capital Gains Tax Calculator"},"content":{"rendered":"\n<style>\n.itb-capgains-calculator * {\n  box-sizing: border-box;\n}\n\n.itb-capgains-calculator {\n  --itb-bg: #0b0f14;\n  --itb-card: #161b22;\n  --itb-panel: #0d1117;\n  --itb-line: #2d333b;\n  --itb-text: #e6edf3;\n  --itb-muted: #a7b3c2;\n  --itb-accent: #ffb020;\n  --itb-good: #52d273;\n  --itb-bad: #ff7b72;\n  width: min(1160px, calc(100% - 32px));\n  margin: 0 auto;\n  padding: 36px 0 54px;\n  color: var(--itb-text);\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n  line-height: 1.55;\n}\n\nbody.itb-capgains-standalone {\n  margin: 0;\n  background: var(--itb-bg, #0b0f14);\n}\n\n.itb-capgains-calculator a {\n  color: var(--itb-accent);\n}\n\n.itb-capgains-kicker {\n  margin: 0 0 8px;\n  color: var(--itb-accent);\n  font-size: .78rem;\n  font-weight: 800;\n  letter-spacing: .08em;\n  text-transform: uppercase;\n}\n\n.itb-capgains-calculator h1 {\n  max-width: 920px;\n  margin: 0;\n  color: #f4f7fa;\n  font-size: clamp(2.05rem, 5vw, 3.35rem);\n  line-height: 1.05;\n}\n\n.itb-capgains-lede {\n  max-width: 930px;\n  margin: 14px 0 24px;\n  color: var(--itb-muted);\n  font-size: 1rem;\n}\n\n.itb-capgains-layout {\n  display: grid;\n  grid-template-columns: minmax(0, 1fr) 390px;\n  gap: 20px;\n  align-items: start;\n}\n\n.itb-capgains-card,\n.itb-calculator-results,\n.itb-sponsor-box,\n.itb-capgains-ad-placeholder {\n  background: var(--itb-card);\n  border: 1px solid rgba(255, 255, 255, .08);\n  border-radius: 8px;\n  box-shadow: 0 12px 30px rgba(0, 0, 0, .22);\n  padding: 22px;\n  margin-bottom: 18px;\n}\n\n.itb-capgains-card h2,\n.itb-calculator-results h2 {\n  margin: 0 0 16px;\n  padding-bottom: 10px;\n  border-bottom: 2px solid var(--itb-line);\n  color: var(--itb-muted);\n  font-size: .9rem;\n  letter-spacing: .07em;\n  text-transform: uppercase;\n}\n\n.itb-capgains-grid {\n  display: grid;\n  grid-template-columns: repeat(2, minmax(0, 1fr));\n  gap: 14px;\n}\n\n.itb-capgains-grid.itb-capgains-grid-3 {\n  grid-template-columns: repeat(3, minmax(0, 1fr));\n}\n\n.itb-capgains-field {\n  display: flex;\n  flex-direction: column;\n  min-width: 0;\n}\n\n.itb-capgains-field label,\n.itb-capgains-field-label {\n  margin-bottom: 6px;\n  color: var(--itb-muted);\n  font-size: .84rem;\n  font-weight: 700;\n}\n\n.itb-capgains-field input,\n.itb-capgains-field select {\n  width: 100%;\n  min-height: 44px;\n  border: 1.5px solid var(--itb-line);\n  border-radius: 8px;\n  background: var(--itb-panel);\n  color: var(--itb-text);\n  padding: 9px 10px;\n  font: inherit;\n}\n\n.itb-capgains-helper,\n.itb-capgains-note {\n  margin: 8px 0 0;\n  color: var(--itb-muted);\n  font-size: .82rem;\n}\n\n.itb-capgains-warning,\n.itb-capgains-error {\n  padding: 12px 14px;\n  border-left: 3px solid var(--itb-accent);\n  background: rgba(255, 176, 32, .08);\n  border-radius: 8px;\n  color: #d6dee8;\n  font-size: .86rem;\n  margin: 12px 0;\n}\n\n.itb-capgains-error {\n  border-left-color: var(--itb-bad);\n  background: rgba(255, 123, 114, .09);\n}\n\n.itb-capgains-checkbox-line {\n  display: flex;\n  align-items: flex-start;\n  gap: 8px;\n  color: var(--itb-muted);\n  font-size: .9rem;\n}\n\n.itb-capgains-checkbox-line input {\n  margin-top: 4px;\n}\n\n.itb-capgains-actions {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 10px;\n  margin-top: 16px;\n}\n\n.itb-capgains-calculator button,\n.itb-capgains-calculator .itb-capgains-button {\n  min-height: 42px;\n  border: 0;\n  border-radius: 8px;\n  background: var(--itb-accent);\n  color: #111 !important;\n  cursor: pointer;\n  font-weight: 850;\n  padding: 10px 14px;\n  text-decoration: none;\n}\n\n.itb-capgains-calculator button.itb-capgains-secondary {\n  background: var(--itb-panel);\n  color: var(--itb-text) !important;\n  border: 1px solid var(--itb-line);\n}\n\n.itb-calculator-results {\n  position: sticky;\n  top: 18px;\n}\n\n.itb-capgains-headline {\n  padding: 16px;\n  background: var(--itb-panel);\n  border: 1px solid var(--itb-line);\n  border-radius: 8px;\n  margin-bottom: 12px;\n}\n\n.itb-capgains-headline span {\n  display: block;\n  color: var(--itb-muted);\n  font-size: .78rem;\n  font-weight: 800;\n  letter-spacing: .05em;\n  text-transform: uppercase;\n}\n\n.itb-capgains-headline strong {\n  display: block;\n  color: #f4f7fa;\n  font-size: 1.45rem;\n  line-height: 1.2;\n  margin-top: 4px;\n  overflow-wrap: anywhere;\n}\n\n.itb-capgains-row {\n  display: flex;\n  justify-content: space-between;\n  gap: 14px;\n  padding: 9px 0;\n  border-bottom: 1px solid var(--itb-line);\n  color: var(--itb-muted);\n  font-size: .88rem;\n}\n\n.itb-capgains-row strong {\n  color: var(--itb-text);\n  text-align: right;\n}\n\n.itb-capgains-ad-placeholder {\n  width: 100%;\n  max-width: 100%;\n  min-height: 90px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  overflow: hidden;\n  text-align: center;\n  color: var(--itb-muted);\n  font-size: .78rem;\n  letter-spacing: .08em;\n  text-transform: uppercase;\n}\n\n.itb-capgains-ad-placeholder ins,\n.itb-capgains-ad-placeholder iframe,\n.itb-result-ad-slot ins,\n.itb-result-ad-slot iframe {\n  max-width: 100% !important;\n}\n\n.itb-result-ad-slot {\n  width: 100%;\n  max-width: 100%;\n  min-height: 76px;\n  margin: 18px 0;\n  padding: 18px;\n  box-shadow: none;\n}\n\n.itb-capgains-tool-list,\n.itb-calculator-menu-list {\n  display: grid;\n  gap: 10px;\n  margin: 12px 0 0 !important;\n  padding: 0 !important;\n  list-style: none !important;\n}\n\n.itb-capgains-tool-list li,\n.itb-calculator-menu-list li {\n  margin: 0 !important;\n  padding: 0 !important;\n}\n\n.itb-capgains-tool-list a,\n.itb-calculator-menu-list a {\n  display: block;\n  padding: 10px 12px;\n  border: 1px solid var(--itb-line);\n  border-radius: 8px;\n  background: var(--itb-panel);\n  color: var(--itb-text);\n  text-decoration: none;\n  font-weight: 750;\n}\n\n.itb-calculator-menu[data-no-auto-ads] ins,\n.itb-calculator-menu[data-no-auto-ads] iframe,\n.itb-calculator-menu[data-no-auto-ads] .adsbygoogle,\n.itb-calculator-menu[data-no-auto-ads] .google-auto-placed,\n.itb-calculator-menu[data-no-auto-ads] [id^=\"google_ads\"],\n.itb-calculator-menu[data-no-auto-ads] [id^=\"aswift\"],\n.itb-calculator-menu[data-no-auto-ads] > :has(ins),\n.itb-calculator-menu[data-no-auto-ads] > :has(iframe),\n.itb-calculator-menu[data-no-auto-ads] > :has(.adsbygoogle),\n.itb-calculator-menu[data-no-auto-ads] > :has(.google-auto-placed),\n.itb-calculator-menu[data-no-auto-ads] .itb-calculator-menu-list > :has(ins),\n.itb-calculator-menu[data-no-auto-ads] .itb-calculator-menu-list > :has(iframe),\n.itb-calculator-menu[data-no-auto-ads] .itb-calculator-menu-list > :has(.adsbygoogle),\n.itb-calculator-menu[data-no-auto-ads] .itb-calculator-menu-list > :has(.google-auto-placed) {\n  display: none !important;\n  min-height: 0 !important;\n  height: 0 !important;\n  margin: 0 !important;\n  padding: 0 !important;\n}\n\n.itb-capgains-faq-item {\n  margin-bottom: 14px;\n}\n\n.itb-capgains-faq-item h3 {\n  margin: 0 0 4px;\n  color: #f4f7fa;\n  font-size: 1rem;\n}\n\n.itb-capgains-faq-item p,\n.itb-capgains-card p,\n.itb-capgains-card li {\n  color: var(--itb-muted);\n}\n\n.itb-capgains-hidden {\n  display: none !important;\n}\n\n@media (max-width: 920px) {\n  .itb-capgains-layout,\n  .itb-capgains-grid,\n  .itb-capgains-grid.itb-capgains-grid-3 {\n    grid-template-columns: 1fr;\n  }\n  .itb-calculator-results {\n    position: static;\n  }\n}\n\n@media (max-width: 560px) {\n  .itb-capgains-calculator {\n    width: calc(100% - 20px);\n    padding-top: 22px;\n  }\n  .itb-capgains-card,\n  .itb-calculator-results,\n  .itb-sponsor-box,\n  .itb-capgains-ad-placeholder {\n    padding: 16px;\n  }\n  .itb-capgains-ad-placeholder {\n    min-height: 100px;\n  }\n  .itb-result-ad-slot {\n    margin: 20px 0;\n    padding: 14px;\n  }\n  .itb-capgains-actions button {\n    width: 100%;\n  }\n}\n\n@media print {\n  body * {\n    visibility: hidden !important;\n  }\n  .itb-capgains-calculator,\n  .itb-capgains-calculator h1,\n  .itb-calculator-results,\n  .itb-calculator-results *,\n  .itb-capgains-print-keep,\n  .itb-capgains-print-keep * {\n    visibility: visible !important;\n  }\n  .itb-capgains-calculator {\n    width: 100% !important;\n    padding: 0 !important;\n    color: #111 !important;\n  }\n  .itb-capgains-layout {\n    display: block !important;\n  }\n  .itb-capgains-form,\n  .itb-capgains-ad-placeholder,\n  .itb-result-ad-slot,\n  .itb-sponsor-box,\n  .itb-capgains-actions,\n  .itb-capgains-tools,\n  .itb-capgains-faqs,\n  nav,\n  header,\n  footer,\n  .adsbygoogle,\n  .google-auto-placed {\n    display: none !important;\n  }\n  .itb-calculator-results,\n  .itb-capgains-print-keep {\n    display: block !important;\n    position: static !important;\n    box-shadow: none !important;\n    border: 1px solid #999 !important;\n    color: #111 !important;\n    background: #fff !important;\n  }\n}\n\n<\/style>\n<main class=\"itb-capgains-calculator\" data-itb-capgains-calculator>\n    <p class=\"itb-capgains-kicker\">Investment tax planning<\/p>\n    <h1>2026 Capital Gains Tax Calculator<\/h1>\n    <p class=\"itb-capgains-lede\">Estimate capital gains tax on stocks, ETFs, mutual funds, crypto, real estate, collectibles, and other assets. This calculator estimates federal capital gains tax, Net Investment Income Tax, state tax, local tax where applicable, total estimated tax, and after-tax proceeds.<\/p>\n    <section class=\"itb-capgains-card itb-capgains-quickstart\" aria-label=\"How to use this calculator\">\n      <h2>How to use this calculator<\/h2>\n      <p>Start with the asset type, sale price, cost basis, dates, filing status, other taxable income for the year, and state of residence. Then calculate the estimate. Some choices, such as crypto, real estate, primary residence, or collectibles, will show extra notes or fields when they matter.<\/p>\n    <\/section>\n\n    <div class=\"itb-capgains-layout\">\n      <form class=\"itb-capgains-form\" data-capgains-form aria-label=\"2026 capital gains tax calculator inputs\">\n        <section class=\"itb-capgains-card\">\n          <h2>Sale details<\/h2>\n          <div class=\"itb-capgains-grid\">\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-asset-type\">Asset type<\/label>\n              <select id=\"itb-asset-type\" data-field=\"assetType\">\n                <option value=\"stock\">Stock, ETF, or mutual fund<\/option>\n                <option value=\"crypto\">Crypto<\/option>\n                <option value=\"real_estate\">Real estate<\/option>\n                <option value=\"primary_residence\">Primary residence<\/option>\n                <option value=\"collectible\">Collectible<\/option>\n                <option value=\"other\">Other investment asset<\/option>\n              <\/select>\n              <p class=\"itb-capgains-helper\">Use the asset type that best matches the sale. Real estate and primary residence calculations are simplified planning estimates.<\/p>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-basis\">Purchase price or cost basis<\/label>\n              <input id=\"itb-basis\" type=\"number\" min=\"0\" step=\"1\" data-field=\"purchasePrice\" value=\"50000\" aria-describedby=\"itb-basis-help\">\n              <p id=\"itb-basis-help\" class=\"itb-capgains-helper\">Use what you paid, plus basis adjustments you know. This may come from brokerage, exchange, or closing records.<\/p>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-sale-price\">Sale price<\/label>\n              <input id=\"itb-sale-price\" type=\"number\" min=\"0\" step=\"1\" data-field=\"salePrice\" value=\"100000\" aria-describedby=\"itb-sale-help\">\n              <p id=\"itb-sale-help\" class=\"itb-capgains-helper\">Use the gross sale amount before subtracting selling expenses.<\/p>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-selling-expenses\">Selling expenses<\/label>\n              <input id=\"itb-selling-expenses\" type=\"number\" min=\"0\" step=\"1\" data-field=\"sellingExpenses\" value=\"0\" aria-describedby=\"itb-expenses-help\">\n              <p id=\"itb-expenses-help\" class=\"itb-capgains-helper\">Include commissions, transaction fees, broker fees, real estate agent commissions, transfer fees, and other selling costs if known.<\/p>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-purchase-date\">Purchase date<\/label>\n              <input id=\"itb-purchase-date\" type=\"date\" data-field=\"purchaseDate\" value=\"2024-01-15\" aria-describedby=\"itb-date-help\">\n              <p id=\"itb-date-help\" class=\"itb-capgains-helper\">Assets held for more than one year are generally treated as long-term.<\/p>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-sale-date\">Sale date<\/label>\n              <input id=\"itb-sale-date\" type=\"date\" data-field=\"saleDate\" value=\"2026-02-01\">\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-holding-override\">Holding period override<\/label>\n              <select id=\"itb-holding-override\" data-field=\"holdingPeriodOverride\" aria-describedby=\"itb-holding-override-help\">\n                <option value=\"\">Use dates<\/option>\n                <option value=\"long_term\">Long-term<\/option>\n                <option value=\"short_term\">Short-term<\/option>\n              <\/select>\n              <p id=\"itb-holding-override-help\" class=\"itb-capgains-helper\">Leave this on \u201cUse dates\u201d for the normal estimate. Choose long-term or short-term to test a what-if scenario or override the date-based result.<\/p>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-losses\">Capital losses available to offset gain<\/label>\n              <input id=\"itb-losses\" type=\"number\" min=\"0\" step=\"1\" data-field=\"capitalLosses\" value=\"0\" aria-describedby=\"itb-losses-help\">\n              <p id=\"itb-losses-help\" class=\"itb-capgains-helper\">Enter capital losses you expect to use against this gain. If you are not sure, leave this blank.<\/p>\n            <\/div>\n          <\/div>\n          <div class=\"itb-capgains-warning itb-capgains-hidden\" data-real-estate-warning>This calculator can estimate a basic real estate sale using sale price, basis, selling expenses, holding period, and optional depreciation recapture. It does not handle installment sales, 1031 exchanges, full depreciation schedules, passive activity rules, or Form 4797-level treatment.<\/div>\n          <div class=\"itb-capgains-warning itb-capgains-hidden\" data-crypto-warning>This calculator handles a simplified single crypto sale. It does not import exchange records, reconcile wallets, calculate FIFO\/LIFO\/specific-identification lots, handle staking rewards, mining income, airdrops, DeFi transactions, NFTs, stablecoin transactions, wallet transfers, crypto-to-crypto swaps, or full Form 8949 reporting.<\/div>\n        <\/section>\n\n        <section class=\"itb-capgains-card\">\n          <h2>Tax profile<\/h2>\n          <div class=\"itb-capgains-grid\">\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-tax-year\">Tax year<\/label>\n              <select id=\"itb-tax-year\" data-field=\"taxYear\">\n                <option value=\"2026\" selected>2026<\/option>\n              <\/select>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-filing-status\">Filing status<\/label>\n              <select id=\"itb-filing-status\" data-field=\"filingStatus\" required>\n                <option value=\"single\">Single<\/option>\n                <option value=\"married_filing_jointly\">Married Filing Jointly<\/option>\n                <option value=\"married_filing_separately\">Married Filing Separately<\/option>\n                <option value=\"head_of_household\">Head of Household<\/option>\n              <\/select>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-taxable-income\">Other taxable income for the year<\/label>\n              <input id=\"itb-taxable-income\" type=\"number\" min=\"0\" step=\"1\" data-field=\"taxableIncomeBeforeGain\" value=\"100000\" aria-describedby=\"itb-taxable-income-help\">\n              <p id=\"itb-taxable-income-help\" class=\"itb-capgains-helper\">Enter estimated 2026 taxable income not including this sale&#8217;s taxable gain. This is used to stack the gain into the federal capital gains brackets.<\/p>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-magi\">Modified AGI without this sale&#8217;s gain<\/label>\n              <input id=\"itb-magi\" type=\"number\" min=\"0\" step=\"1\" data-field=\"magiBeforeGain\" aria-describedby=\"itb-magi-help\">\n              <p id=\"itb-magi-help\" class=\"itb-capgains-helper\">Used for NIIT. If blank, the calculator estimates MAGI from taxable income plus this sale&#8217;s taxable gain and labels the NIIT result as simplified.<\/p>\n            <\/div>\n          <\/div>\n        <\/section>\n\n        <section class=\"itb-capgains-card\">\n          <h2>State and local tax<\/h2>\n          <div class=\"itb-capgains-grid\">\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-state\">State of residence<\/label>\n              <select id=\"itb-state\" data-field=\"stateOfResidence\" aria-describedby=\"itb-state-help\"><\/select>\n              <p id=\"itb-state-help\" class=\"itb-capgains-helper\">Many states tax capital gains as regular income, while some states have no broad individual income tax or special rules.<\/p>\n            <\/div>\n            <div class=\"itb-capgains-field itb-capgains-hidden\" data-nyc-resident-field>\n              <label for=\"itb-nyc-resident\">Did you live in New York City?<\/label>\n              <select id=\"itb-nyc-resident\" data-field=\"isNYCResident\">\n                <option value=\"no\">No<\/option>\n                <option value=\"yes\">Yes<\/option>\n              <\/select>\n            <\/div>\n          <\/div>\n        <\/section>\n\n        <section class=\"itb-capgains-card\">\n          <button type=\"button\" class=\"itb-capgains-secondary\" data-advanced-toggle aria-expanded=\"false\" aria-controls=\"itb-advanced-options\">Advanced options<\/button>\n          <div id=\"itb-advanced-options\" class=\"itb-capgains-hidden\" data-advanced-panel>\n            <p class=\"itb-capgains-note\">Most users can leave this section closed. Use these fields only if you have more detailed tax information.<\/p>\n            <div class=\"itb-capgains-grid\">\n              <div class=\"itb-capgains-field\">\n                <label for=\"itb-adjusted-basis\">Manually enter adjusted basis<\/label>\n                <input id=\"itb-adjusted-basis\" type=\"number\" min=\"0\" step=\"1\" data-field=\"adjustedBasis\">\n                <p class=\"itb-capgains-helper\">Use this if basis differs because of improvements, return of capital, depreciation, inheritance, gifts, stock splits, or reinvestments.<\/p>\n              <\/div>\n              <div class=\"itb-capgains-field\">\n                <label for=\"itb-depreciation\">Rental or business property depreciation recapture<\/label>\n                <input id=\"itb-depreciation\" type=\"number\" min=\"0\" step=\"1\" data-field=\"depreciationRecapture\" value=\"0\">\n                <p class=\"itb-capgains-helper\">Most stock, crypto, and personal-use home sales can leave this at zero. Use it only if you sold rental real estate or business property and know the recapture amount from your records or tax preparer.<\/p>\n              <\/div>\n              <div class=\"itb-capgains-field\">\n                <label for=\"itb-state-income-override\">State taxable income override<\/label>\n                <input id=\"itb-state-income-override\" type=\"number\" min=\"0\" step=\"1\" data-field=\"stateTaxableIncomeOverride\">\n              <\/div>\n              <div class=\"itb-capgains-field\">\n                <label for=\"itb-state-tax-override\">State capital gain tax override<\/label>\n                <input id=\"itb-state-tax-override\" type=\"number\" min=\"0\" step=\"1\" data-field=\"stateTaxOverride\">\n              <\/div>\n              <div class=\"itb-capgains-field\">\n                <label for=\"itb-niit-override\">NIIT override<\/label>\n                <input id=\"itb-niit-override\" type=\"number\" min=\"0\" step=\"1\" data-field=\"niitOverride\">\n              <\/div>\n            <\/div>\n          <\/div>\n        <\/section>\n\n        <section class=\"itb-capgains-card itb-capgains-hidden\" data-primary-residence-section>\n          <h2>Primary residence exclusion<\/h2>\n          <div class=\"itb-capgains-grid\">\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-home-eligible\">Did you own and use the home as your main home for at least 2 of the last 5 years?<\/label>\n              <select id=\"itb-home-eligible\" data-field=\"homeOwnedUsedTwoYears\">\n                <option value=\"yes\">Yes<\/option>\n                <option value=\"no\">No<\/option>\n                <option value=\"not_sure\">Not sure<\/option>\n              <\/select>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-home-recent\">Have you used the home sale exclusion in the last 2 years?<\/label>\n              <select id=\"itb-home-recent\" data-field=\"homeExclusionUsedRecently\">\n                <option value=\"no\">No<\/option>\n                <option value=\"yes\">Yes<\/option>\n                <option value=\"not_sure\">Not sure<\/option>\n              <\/select>\n            <\/div>\n            <div class=\"itb-capgains-field\">\n              <label for=\"itb-home-exclusion\">Section 121 primary home exclusion amount<\/label>\n              <input id=\"itb-home-exclusion\" type=\"number\" min=\"0\" step=\"1\" data-field=\"manualHomeExclusion\">\n            <\/div>\n          <\/div>\n          <p class=\"itb-capgains-note\">The home sale exclusion has eligibility rules. This calculator uses a simplified estimate and does not determine full eligibility.<\/p>\n        <\/section>\n\n        <section class=\"itb-capgains-card\">\n          <div class=\"itb-capgains-actions\">\n            <button type=\"submit\">Calculate<\/button>\n            <button type=\"reset\" class=\"itb-capgains-secondary\">Reset<\/button>\n          <\/div>\n        <\/section>\n      <\/form>\n\n      <aside class=\"itb-calculator-results\" data-calculator-results aria-live=\"polite\">\n        <h2>Results<\/h2>\n        <p class=\"itb-capgains-note\">Your entries are calculated in your browser. IncomeTaxBill.com does not save the numbers you enter.<\/p>\n        <div data-validation-messages><\/div>\n        <div data-empty-results>Enter your sale details and calculate your result.<\/div>\n        <div data-result-content class=\"itb-capgains-hidden\">\n          <div class=\"itb-copyable-results\" data-copyable-results><\/div>\n          <div class=\"itb-capgains-ad-placeholder itb-result-ad-slot\">Advertisement<\/div>\n        <\/div>\n        <div class=\"itb-capgains-actions\">\n          <button type=\"button\" class=\"itb-capgains-secondary\" data-copy-results>Copy Results<\/button>\n          <button type=\"button\" class=\"itb-capgains-secondary\" data-print-results>Print or Save Results<\/button>\n        <\/div>\n        <p class=\"itb-capgains-note\" data-copy-status><\/p>\n        <div class=\"itb-sponsor-box\">Interested in sponsoring this tax calculator? Contact us to discuss relevant advertising or partnership opportunities.<\/div>\n      <\/aside>\n    <\/div>\n\n    <section class=\"itb-capgains-card itb-capgains-print-keep\">\n      <h2>Disclaimer<\/h2>\n      <p>This calculator is a simplified planning tool. It does not prepare a tax return and does not handle every federal, state, local, or asset-specific rule. Capital gains taxes can depend on exact taxable income, holding period, basis, losses, depreciation, exclusions, state law, local tax rules, and other facts. Confirm your tax obligations before relying on the result.<\/p>\n    <\/section>\n\n    <div class=\"itb-capgains-ad-placeholder\">Advertisement<\/div>\n\n    <section class=\"itb-capgains-card itb-capgains-tools itb-calculator-menu\" data-no-auto-ads>\n      <h2>Related Tax Tools<\/h2>\n      <ul class=\"itb-calculator-menu-list\" data-related-tools><\/ul>\n    <\/section>\n\n    <section class=\"itb-capgains-card itb-capgains-print-keep\">\n      <h2>What This Calculator Does Not Handle<\/h2>\n      <ul>\n        <li>Full 1031 exchange calculations<\/li>\n        <li>Installment sales, QSBS exclusions, AMT, wash sales, or full depreciation schedules<\/li>\n        <li>Partnership K-1 capital gains, trusts, estates, or nonresident alien rules<\/li>\n        <li>State part-year residency, every state credit or deduction, or every local tax rule<\/li>\n        <li>Crypto exchange imports, wallet imports, multiple lots, FIFO, LIFO, specific identification, DeFi, NFTs, or full Form 8949 reporting<\/li>\n      <\/ul>\n    <\/section>\n\n    <section class=\"itb-capgains-card itb-capgains-faqs\">\n      <h2>FAQs<\/h2>\n      <div class=\"itb-capgains-faq-item\"><h3>What is capital gains tax?<\/h3><p>Capital gains tax is tax on profit from selling an asset for more than its tax basis. Stocks, ETFs, mutual funds, crypto, real estate, collectibles, and other investments may create capital gains when sold.<\/p><\/div>\n      <div class=\"itb-capgains-faq-item\"><h3>What is the difference between short-term and long-term capital gains?<\/h3><p>Short-term capital gains generally apply to assets held for one year or less and are usually taxed like ordinary income. Long-term capital gains generally apply to assets held for more than one year and may qualify for lower federal tax rates.<\/p><\/div>\n      <div class=\"itb-capgains-faq-item\"><h3>Does this calculator include state capital gains tax?<\/h3><p>Yes, where state data is available. Many states tax capital gains as ordinary income, some states have no broad individual income tax, and some states have special capital gains rules. State results are labeled as simplified when appropriate.<\/p><\/div>\n      <div class=\"itb-capgains-faq-item\"><h3>Does New York tax capital gains?<\/h3><p>New York generally taxes capital gains through its regular income tax system. New York City residents may also owe New York City resident income tax.<\/p><\/div>\n      <div class=\"itb-capgains-faq-item\"><h3>Do states without income tax have capital gains tax?<\/h3><p>States without a broad individual income tax generally do not tax capital gains through a regular state income tax in this simplified model. Other taxes or special rules may still apply.<\/p><\/div>\n      <div class=\"itb-capgains-faq-item\"><h3>Does this calculator include Net Investment Income Tax?<\/h3><p>Yes. The calculator estimates the 3.8% Net Investment Income Tax when income appears to exceed the applicable threshold. If modified adjusted gross income is not entered, the NIIT result is simplified.<\/p><\/div>\n      <div class=\"itb-capgains-faq-item\"><h3>Does this calculator handle home sale exclusions?<\/h3><p>It includes a simplified primary residence exclusion estimate for users who indicate they may qualify. The full home sale exclusion has detailed eligibility rules, so the result should not be treated as a tax return calculation.<\/p><\/div>\n      <div class=\"itb-capgains-faq-item\"><h3>Does this calculator handle crypto gains?<\/h3><p>Yes, basic crypto sales can be entered like other investment sales. The calculator estimates gain based on sale price, basis, expenses, holding period, and tax profile. It does not import exchange records or prepare Form 8949.<\/p><\/div>\n      <div class=\"itb-capgains-faq-item\"><h3>Does this calculator handle collectibles?<\/h3><p>It includes a simplified collectibles estimate. Collectibles may be taxed differently from ordinary long-term capital gains, so users should confirm treatment before relying on the result.<\/p><\/div>\n      <div class=\"itb-capgains-faq-item\"><h3>Why is this only an estimate?<\/h3><p>Capital gains tax can depend on exact income, basis, holding period, losses, asset type, depreciation, exclusions, state law, local tax rules, and other facts. This calculator is a planning tool, not a tax return.<\/p><\/div>\n    <\/section>\n  <\/main>\n<script>new Function(atob(\"KGZ1bmN0aW9uICgpIHsKICAidXNlIHN0cmljdCI7CgogIHdpbmRvdy5JVEJDYXBpdGFsR2FpbnNGZWRlcmFsTFRDRzIwMjYgPSB7CiAgICBqdXJpc2RpY3Rpb246ICJVbml0ZWQgU3RhdGVzIiwKICAgIHRheFllYXI6IDIwMjYsCiAgICBkYXRhVmludGFnZTogIjIwMjYgSVJTIGluZmxhdGlvbi1hZGp1c3RlZCB0aHJlc2hvbGRzIiwKICAgIGxhc3RVcGRhdGVkOiAiMjAyNi0wNC0yNyIsCiAgICBzb3VyY2VOYW1lOiAiSVJTIFJldi4gUHJvYy4gMjAyNS0zMiwgU2VjdGlvbiA0LjAzIiwKICAgIHNvdXJjZVVybDogImh0dHBzOi8vd3d3Lmlycy5nb3YvcHViL2lycy1kcm9wL3JwLTI1LTMyLnBkZiIsCiAgICBzb3VyY2VUeXBlOiAib2ZmaWNpYWxfaXJzX3JldmVudWVfcHJvY2VkdXJlIiwKICAgIHJldHJpZXZlZERhdGU6ICIyMDI2LTA0LTI3IiwKICAgIHZlcmlmaWVkQnk6ICJyZXF1aXJlc19odW1hbl9yZXZpZXciLAogICAgYWNjdXJhY3lTdGF0dXM6ICJvZmZpY2lhbF8yMDI2IiwKICAgIG5vdGVzOiAiTWF4aW11bSB6ZXJvLXJhdGUgYW5kIG1heGltdW0gMTUtcGVyY2VudC1yYXRlIGFtb3VudHMgZm9yIDIwMjYgbG9uZy10ZXJtIGNhcGl0YWwgZ2FpbnMuIiwKICAgIHRocmVzaG9sZHM6IHsKICAgICAgc2luZ2xlOiB7IG1heGltdW1aZXJvUmF0ZUFtb3VudDogNDk0NTAsIG1heGltdW0xNVJhdGVBbW91bnQ6IDU0NTUwMCB9LAogICAgICBtYXJyaWVkX2ZpbGluZ19qb2ludGx5OiB7IG1heGltdW1aZXJvUmF0ZUFtb3VudDogOTg5MDAsIG1heGltdW0xNVJhdGVBbW91bnQ6IDYxMzcwMCB9LAogICAgICBtYXJyaWVkX2ZpbGluZ19zZXBhcmF0ZWx5OiB7IG1heGltdW1aZXJvUmF0ZUFtb3VudDogNDk0NTAsIG1heGltdW0xNVJhdGVBbW91bnQ6IDMwNjg1MCB9LAogICAgICBoZWFkX29mX2hvdXNlaG9sZDogeyBtYXhpbXVtWmVyb1JhdGVBbW91bnQ6IDY2MjAwLCBtYXhpbXVtMTVSYXRlQW1vdW50OiA1Nzk2MDAgfQogICAgfQogIH07Cn0pKCk7CgoKKGZ1bmN0aW9uICgpIHsKICAidXNlIHN0cmljdCI7CgogIHdpbmRvdy5JVEJGZWRlcmFsT3JkaW5hcnlJbmNvbWUyMDI2ID0gewogICAganVyaXNkaWN0aW9uOiAiVW5pdGVkIFN0YXRlcyIsCiAgICB0YXhZZWFyOiAyMDI2LAogICAgZGF0YVZpbnRhZ2U6ICIyMDI2IElSUyBpbmZsYXRpb24tYWRqdXN0ZWQgdGF4IHJhdGUgdGFibGVzIiwKICAgIGxhc3RVcGRhdGVkOiAiMjAyNi0wNC0yNyIsCiAgICBzb3VyY2VOYW1lOiAiSVJTIFJldi4gUHJvYy4gMjAyNS0zMiwgU2VjdGlvbiA0LjAxIiwKICAgIHNvdXJjZVVybDogImh0dHBzOi8vd3d3Lmlycy5nb3YvcHViL2lycy1kcm9wL3JwLTI1LTMyLnBkZiIsCiAgICBzb3VyY2VUeXBlOiAib2ZmaWNpYWxfaXJzX3JldmVudWVfcHJvY2VkdXJlIiwKICAgIHJldHJpZXZlZERhdGU6ICIyMDI2LTA0LTI3IiwKICAgIHZlcmlmaWVkQnk6ICJyZXF1aXJlc19odW1hbl9yZXZpZXciLAogICAgYWNjdXJhY3lTdGF0dXM6ICJvZmZpY2lhbF8yMDI2IiwKICAgIG5vdGVzOiAiT3JkaW5hcnkgaW5jb21lIGJyYWNrZXRzIHVzZWQgZm9yIHNob3J0LXRlcm0gY2FwaXRhbCBnYWluIGluY3JlbWVudGFsIHRheCBlc3RpbWF0ZXMuIiwKICAgIGJyYWNrZXRzOiB7CiAgICAgIG1hcnJpZWRfZmlsaW5nX2pvaW50bHk6IFsKICAgICAgICB7IHVwVG86IDI0ODAwLCByYXRlOiAwLjEwLCBiYXNlVGF4OiAwLCBvdmVyOiAwIH0sCiAgICAgICAgeyB1cFRvOiAxMDA4MDAsIHJhdGU6IDAuMTIsIGJhc2VUYXg6IDI0ODAsIG92ZXI6IDI0ODAwIH0sCiAgICAgICAgeyB1cFRvOiAyMTE0MDAsIHJhdGU6IDAuMjIsIGJhc2VUYXg6IDExNjAwLCBvdmVyOiAxMDA4MDAgfSwKICAgICAgICB7IHVwVG86IDQwMzU1MCwgcmF0ZTogMC4yNCwgYmFzZVRheDogMzU5MzIsIG92ZXI6IDIxMTQwMCB9LAogICAgICAgIHsgdXBUbzogNTEyNDUwLCByYXRlOiAwLjMyLCBiYXNlVGF4OiA4MjA0OCwgb3ZlcjogNDAzNTUwIH0sCiAgICAgICAgeyB1cFRvOiA3Njg3MDAsIHJhdGU6IDAuMzUsIGJhc2VUYXg6IDExNjg5Niwgb3ZlcjogNTEyNDUwIH0sCiAgICAgICAgeyB1cFRvOiBudWxsLCByYXRlOiAwLjM3LCBiYXNlVGF4OiAyMDY1ODMuNTAsIG92ZXI6IDc2ODcwMCB9CiAgICAgIF0sCiAgICAgIGhlYWRfb2ZfaG91c2Vob2xkOiBbCiAgICAgICAgeyB1cFRvOiAxNzcwMCwgcmF0ZTogMC4xMCwgYmFzZVRheDogMCwgb3ZlcjogMCB9LAogICAgICAgIHsgdXBUbzogNjc0NTAsIHJhdGU6IDAuMTIsIGJhc2VUYXg6IDE3NzAsIG92ZXI6IDE3NzAwIH0sCiAgICAgICAgeyB1cFRvOiAxMDU3MDAsIHJhdGU6IDAuMjIsIGJhc2VUYXg6IDc3NDAsIG92ZXI6IDY3NDUwIH0sCiAgICAgICAgeyB1cFRvOiAyMDE3NTAsIHJhdGU6IDAuMjQsIGJhc2VUYXg6IDE2MTU1LCBvdmVyOiAxMDU3MDAgfSwKICAgICAgICB7IHVwVG86IDI1NjIwMCwgcmF0ZTogMC4zMiwgYmFzZVRheDogMzkyMDcsIG92ZXI6IDIwMTc1MCB9LAogICAgICAgIHsgdXBUbzogNjQwNjAwLCByYXRlOiAwLjM1LCBiYXNlVGF4OiA1NjYzMSwgb3ZlcjogMjU2MjAwIH0sCiAgICAgICAgeyB1cFRvOiBudWxsLCByYXRlOiAwLjM3LCBiYXNlVGF4OiAxOTExNzEsIG92ZXI6IDY0MDYwMCB9CiAgICAgIF0sCiAgICAgIHNpbmdsZTogWwogICAgICAgIHsgdXBUbzogMTI0MDAsIHJhdGU6IDAuMTAsIGJhc2VUYXg6IDAsIG92ZXI6IDAgfSwKICAgICAgICB7IHVwVG86IDUwNDAwLCByYXRlOiAwLjEyLCBiYXNlVGF4OiAxMjQwLCBvdmVyOiAxMjQwMCB9LAogICAgICAgIHsgdXBUbzogMTA1NzAwLCByYXRlOiAwLjIyLCBiYXNlVGF4OiA1ODAwLCBvdmVyOiA1MDQwMCB9LAogICAgICAgIHsgdXBUbzogMjAxNzc1LCByYXRlOiAwLjI0LCBiYXNlVGF4OiAxNzk2Niwgb3ZlcjogMTA1NzAwIH0sCiAgICAgICAgeyB1cFRvOiAyNTYyMjUsIHJhdGU6IDAuMzIsIGJhc2VUYXg6IDQxMDI0LCBvdmVyOiAyMDE3NzUgfSwKICAgICAgICB7IHVwVG86IDY0MDYwMCwgcmF0ZTogMC4zNSwgYmFzZVRheDogNTg0NDgsIG92ZXI6IDI1NjIyNSB9LAogICAgICAgIHsgdXBUbzogbnVsbCwgcmF0ZTogMC4zNywgYmFzZVRheDogMTkyOTc5LjI1LCBvdmVyOiA2NDA2MDAgfQogICAgICBdLAogICAgICBtYXJyaWVkX2ZpbGluZ19zZXBhcmF0ZWx5OiBbCiAgICAgICAgeyB1cFRvOiAxMjQwMCwgcmF0ZTogMC4xMCwgYmFzZVRheDogMCwgb3ZlcjogMCB9LAogICAgICAgIHsgdXBUbzogNTA0MDAsIHJhdGU6IDAuMTIsIGJhc2VUYXg6IDEyNDAsIG92ZXI6IDEyNDAwIH0sCiAgICAgICAgeyB1cFRvOiAxMDU3MDAsIHJhdGU6IDAuMjIsIGJhc2VUYXg6IDU4MDAsIG92ZXI6IDUwNDAwIH0sCiAgICAgICAgeyB1cFRvOiAyMDE3NzUsIHJhdGU6IDAuMjQsIGJhc2VUYXg6IDE3OTY2LCBvdmVyOiAxMDU3MDAgfSwKICAgICAgICB7IHVwVG86IDI1NjIyNSwgcmF0ZTogMC4zMiwgYmFzZVRheDogNDEwMjQsIG92ZXI6IDIwMTc3NSB9LAogICAgICAgIHsgdXBUbzogMzg0MzUwLCByYXRlOiAwLjM1LCBiYXNlVGF4OiA1ODQ0OCwgb3ZlcjogMjU2MjI1IH0sCiAgICAgICAgeyB1cFRvOiBudWxsLCByYXRlOiAwLjM3LCBiYXNlVGF4OiAxMDMyOTEuNzUsIG92ZXI6IDM4NDM1MCB9CiAgICAgIF0KICAgIH0KICB9Owp9KSgpOwoKCihmdW5jdGlvbiAoKSB7CiAgInVzZSBzdHJpY3QiOwoKICB3aW5kb3cuSVRCRmVkZXJhbE5JSVREYXRhID0gewogICAganVyaXNkaWN0aW9uOiAiVW5pdGVkIFN0YXRlcyIsCiAgICB0YXhZZWFyOiAibGF0ZXN0X2F2YWlsYWJsZSIsCiAgICBkYXRhVmludGFnZTogIklSUyBOSUlUIHN0YXR1dG9yeSB0aHJlc2hvbGQgZ3VpZGFuY2UiLAogICAgbGFzdFVwZGF0ZWQ6ICIyMDI2LTA0LTI3IiwKICAgIHNvdXJjZU5hbWU6ICJJUlMgTmV0IEludmVzdG1lbnQgSW5jb21lIFRheCBndWlkYW5jZSIsCiAgICBzb3VyY2VVcmw6ICJodHRwczovL3d3dy5pcnMuZ292L2luZGl2aWR1YWxzL25ldC1pbnZlc3RtZW50LWluY29tZS10YXgiLAogICAgc291cmNlVHlwZTogIm9mZmljaWFsX2lyc190b3BpYyIsCiAgICByZXRyaWV2ZWREYXRlOiAiMjAyNi0wNC0yNyIsCiAgICB2ZXJpZmllZEJ5OiAicmVxdWlyZXNfaHVtYW5fcmV2aWV3IiwKICAgIGFjY3VyYWN5U3RhdHVzOiAib2ZmaWNpYWxfbGF0ZXN0X2F2YWlsYWJsZSIsCiAgICBub3RlczogIk5JSVQgYXBwbGllcyBhdCAzLjglIHRvIHRoZSBsZXNzZXIgb2YgbmV0IGludmVzdG1lbnQgaW5jb21lIG9yIE1BR0kgYWJvdmUgdGhlIGZpbGluZyBzdGF0dXMgdGhyZXNob2xkLiIsCiAgICByYXRlOiAwLjAzOCwKICAgIHRocmVzaG9sZHM6IHsKICAgICAgc2luZ2xlOiAyMDAwMDAsCiAgICAgIGhlYWRfb2ZfaG91c2Vob2xkOiAyMDAwMDAsCiAgICAgIG1hcnJpZWRfZmlsaW5nX2pvaW50bHk6IDI1MDAwMCwKICAgICAgbWFycmllZF9maWxpbmdfc2VwYXJhdGVseTogMTI1MDAwCiAgICB9CiAgfTsKfSkoKTsKCgooZnVuY3Rpb24gKCkgewogICJ1c2Ugc3RyaWN0IjsKCiAgY29uc3QgdW5zdXBwb3J0ZWQgPSB7CiAgICBicm9hZEluZGl2aWR1YWxJbmNvbWVUYXg6IHRydWUsCiAgICBkZWZhdWx0Q2FwaXRhbEdhaW5zVHJlYXRtZW50OiAibm90X2ltcGxlbWVudGVkIiwKICAgIHN1cHBvcnRlZDogZmFsc2UsCiAgICBsb2NhbFRheE1heUFwcGx5OiBmYWxzZSwKICAgIGFjY3VyYWN5U3RhdHVzOiAibm90X2ltcGxlbWVudGVkIiwKICAgIHZlcmlmaWVkQnk6ICJyZXF1aXJlc19odW1hbl9yZXZpZXciLAogICAgc291cmNlVHlwZTogInVuc3VwcG9ydGVkIiwKICAgIHNvdXJjZU5hbWU6ICJTdGF0ZSBjYXBpdGFsIGdhaW5zIHRyZWF0bWVudCBub3QgaW1wbGVtZW50ZWQgaW4gVmVyc2lvbiAxIiwKICAgIHNvdXJjZVVybDogIiIsCiAgICBkYXRhVmludGFnZTogIm5vdCBpbXBsZW1lbnRlZCIsCiAgICBsYXN0VXBkYXRlZDogIjIwMjYtMDQtMjciLAogICAgcmV0cmlldmVkRGF0ZTogIjIwMjYtMDQtMjciLAogICAgbm90ZXM6ICJTdGF0ZSBjYXBpdGFsIGdhaW5zIGVzdGltYXRlIGlzIG5vdCB5ZXQgYXZhaWxhYmxlIGZvciB0aGlzIHN0YXRlLiIKICB9OwoKICBmdW5jdGlvbiBzdGF0ZShuYW1lLCBhYmJyZXZpYXRpb24sIG92ZXJyaWRlcykgewogICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHVuc3VwcG9ydGVkLCB7IG5hbWUsIGFiYnJldmlhdGlvbiwganVyaXNkaWN0aW9uOiBuYW1lLCB0YXhZZWFyOiAyMDI2IH0sIG92ZXJyaWRlcyB8fCB7fSk7CiAgfQoKICBmdW5jdGlvbiBub0Jyb2FkSW5jb21lVGF4KG5hbWUsIGFiYnJldmlhdGlvbiwgc291cmNlVXJsKSB7CiAgICByZXR1cm4gc3RhdGUobmFtZSwgYWJicmV2aWF0aW9uLCB7CiAgICAgIGJyb2FkSW5kaXZpZHVhbEluY29tZVRheDogZmFsc2UsCiAgICAgIGRlZmF1bHRDYXBpdGFsR2FpbnNUcmVhdG1lbnQ6ICJub19icm9hZF9pbmRpdmlkdWFsX2luY29tZV90YXgiLAogICAgICBzdXBwb3J0ZWQ6IHRydWUsCiAgICAgIGFjY3VyYWN5U3RhdHVzOiAic2ltcGxpZmllZF9yZXF1aXJlc19yZXZpZXciLAogICAgICBzb3VyY2VUeXBlOiAib2ZmaWNpYWxfc3RhdGVfdGF4X2FnZW5jeSIsCiAgICAgIHNvdXJjZU5hbWU6IG5hbWUgKyAiIHRheCBhZ2VuY3kgaW5kaXZpZHVhbCBpbmNvbWUgdGF4IGd1aWRhbmNlIiwKICAgICAgc291cmNlVXJsLAogICAgICBkYXRhVmludGFnZTogImxhdGVzdCBhdmFpbGFibGUgc3RhdGUgZ3VpZGFuY2UiLAogICAgICBub3RlczogIlRoaXMgc3RhdGUgZG9lcyBub3QgaGF2ZSBhIGJyb2FkIGluZGl2aWR1YWwgaW5jb21lIHRheCBpbiB0aGlzIHNpbXBsaWZpZWQgbW9kZWwuIE90aGVyIHRheGVzIG9yIHNwZWNpYWwgcnVsZXMgbWF5IHN0aWxsIGFwcGx5LiIKICAgIH0pOwogIH0KCiAgd2luZG93LklUQlN0YXRlQ2FwaXRhbEdhaW5zRGF0YSA9IHsKICAgIHRheFllYXI6IDIwMjYsCiAgICBsYXN0VXBkYXRlZDogIjIwMjYtMDQtMjciLAogICAgdmVyaWZpZWRCeTogInJlcXVpcmVzX2h1bWFuX3JldmlldyIsCiAgICBub3RlczogIkFsbCBzdGF0ZSBlbnRyaWVzIHJlcXVpcmUgaHVtYW4gcmV2aWV3IGJlZm9yZSBwdWJsaWNhdGlvbi4gVW5zdXBwb3J0ZWQgc3RhdGVzIGludGVudGlvbmFsbHkgZG8gbm90IGZhYnJpY2F0ZSBwcmVjaXNlIGVzdGltYXRlcy4iLAogICAgc3RhdGVzOiB7CiAgICAgIEFMOiBzdGF0ZSgiQWxhYmFtYSIsICJBTCIpLCBBSzogbm9Ccm9hZEluY29tZVRheCgiQWxhc2thIiwgIkFLIiwgImh0dHBzOi8vdGF4LmFsYXNrYS5nb3YvIiksCiAgICAgIEFaOiBzdGF0ZSgiQXJpem9uYSIsICJBWiIpLCBBUjogc3RhdGUoIkFya2Fuc2FzIiwgIkFSIiksCiAgICAgIENBOiBzdGF0ZSgiQ2FsaWZvcm5pYSIsICJDQSIsIHsKICAgICAgICBkZWZhdWx0Q2FwaXRhbEdhaW5zVHJlYXRtZW50OiAidGF4ZWRfYXNfb3JkaW5hcnlfaW5jb21lIiwKICAgICAgICBzdXBwb3J0ZWQ6IGZhbHNlLAogICAgICAgIGFjY3VyYWN5U3RhdHVzOiAibm90X2ltcGxlbWVudGVkIiwKICAgICAgICBzb3VyY2VUeXBlOiAib2ZmaWNpYWxfc3RhdGVfdGF4X2FnZW5jeSIsCiAgICAgICAgc291cmNlTmFtZTogIkNhbGlmb3JuaWEgRnJhbmNoaXNlIFRheCBCb2FyZCBjYXBpdGFsIGdhaW5zIGd1aWRhbmNlIiwKICAgICAgICBzb3VyY2VVcmw6ICJodHRwczovL3d3dy5mdGIuY2EuZ292L2ZpbGUvcGVyc29uYWwvaW5jb21lLXR5cGVzL2NhcGl0YWwtZ2FpbnMtYW5kLWxvc3Nlcy5odG1sIiwKICAgICAgICBub3RlczogIkNhbGlmb3JuaWEgY2FwaXRhbCBnYWlucyBlc3RpbWF0ZSBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LiBGZWRlcmFsIHRheCBpcyBzdGlsbCBlc3RpbWF0ZWQuIgogICAgICB9KSwKICAgICAgQ086IHN0YXRlKCJDb2xvcmFkbyIsICJDTyIpLCBDVDogc3RhdGUoIkNvbm5lY3RpY3V0IiwgIkNUIiksCiAgICAgIERDOiBzdGF0ZSgiRGlzdHJpY3Qgb2YgQ29sdW1iaWEiLCAiREMiKSwgREU6IHN0YXRlKCJEZWxhd2FyZSIsICJERSIpLAogICAgICBGTDogbm9Ccm9hZEluY29tZVRheCgiRmxvcmlkYSIsICJGTCIsICJodHRwczovL2Zsb3JpZGFyZXZlbnVlLmNvbS8iKSwKICAgICAgR0E6IHN0YXRlKCJHZW9yZ2lhIiwgIkdBIiksIEhJOiBzdGF0ZSgiSGF3YWlpIiwgIkhJIiksIElEOiBzdGF0ZSgiSWRhaG8iLCAiSUQiKSwKICAgICAgSUw6IHN0YXRlKCJJbGxpbm9pcyIsICJJTCIpLCBJTjogc3RhdGUoIkluZGlhbmEiLCAiSU4iKSwgSUE6IHN0YXRlKCJJb3dhIiwgIklBIiksCiAgICAgIEtTOiBzdGF0ZSgiS2Fuc2FzIiwgIktTIiksIEtZOiBzdGF0ZSgiS2VudHVja3kiLCAiS1kiKSwgTEE6IHN0YXRlKCJMb3Vpc2lhbmEiLCAiTEEiKSwKICAgICAgTUU6IHN0YXRlKCJNYWluZSIsICJNRSIpLCBNRDogc3RhdGUoIk1hcnlsYW5kIiwgIk1EIiwgeyBsb2NhbFRheE1heUFwcGx5OiB0cnVlIH0pLAogICAgICBNQTogc3RhdGUoIk1hc3NhY2h1c2V0dHMiLCAiTUEiLCB7CiAgICAgICAgZGVmYXVsdENhcGl0YWxHYWluc1RyZWF0bWVudDogInByZWZlcmVudGlhbF9vcl9zcGVjaWFsX3J1bGVzIiwKICAgICAgICBzdXBwb3J0ZWQ6IGZhbHNlLAogICAgICAgIGFjY3VyYWN5U3RhdHVzOiAibm90X2ltcGxlbWVudGVkIiwKICAgICAgICBzb3VyY2VUeXBlOiAib2ZmaWNpYWxfc3RhdGVfdGF4X2FnZW5jeSIsCiAgICAgICAgc291cmNlTmFtZTogIk1hc3NhY2h1c2V0dHMgRGVwYXJ0bWVudCBvZiBSZXZlbnVlIGNhcGl0YWwgZ2FpbnMgZ3VpZGFuY2UiLAogICAgICAgIHNvdXJjZVVybDogImh0dHBzOi8vd3d3Lm1hc3MuZ292L2luZm8tZGV0YWlscy9tYXNzYWNodXNldHRzLXRheC1yYXRlcyIsCiAgICAgICAgbm90ZXM6ICJNYXNzYWNodXNldHRzIGhhcyBzcGVjaWFsIGNhcGl0YWwgZ2FpbnMgdHJlYXRtZW50LiBTdGF0ZSBlc3RpbWF0ZSBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LiIKICAgICAgfSksCiAgICAgIE1JOiBzdGF0ZSgiTWljaGlnYW4iLCAiTUkiKSwgTU46IHN0YXRlKCJNaW5uZXNvdGEiLCAiTU4iKSwgTVM6IHN0YXRlKCJNaXNzaXNzaXBwaSIsICJNUyIpLAogICAgICBNTzogc3RhdGUoIk1pc3NvdXJpIiwgIk1PIiksIE1UOiBzdGF0ZSgiTW9udGFuYSIsICJNVCIpLCBORTogc3RhdGUoIk5lYnJhc2thIiwgIk5FIiksCiAgICAgIE5WOiBub0Jyb2FkSW5jb21lVGF4KCJOZXZhZGEiLCAiTlYiLCAiaHR0cHM6Ly90YXgubnYuZ292LyIpLAogICAgICBOSDogbm9Ccm9hZEluY29tZVRheCgiTmV3IEhhbXBzaGlyZSIsICJOSCIsICJodHRwczovL3d3dy5yZXZlbnVlLm5oLmdvdi8iKSwKICAgICAgTko6IHN0YXRlKCJOZXcgSmVyc2V5IiwgIk5KIiwgewogICAgICAgIGRlZmF1bHRDYXBpdGFsR2FpbnNUcmVhdG1lbnQ6ICJ0YXhlZF9hc19vcmRpbmFyeV9pbmNvbWUiLAogICAgICAgIHN1cHBvcnRlZDogZmFsc2UsCiAgICAgICAgYWNjdXJhY3lTdGF0dXM6ICJub3RfaW1wbGVtZW50ZWQiLAogICAgICAgIHNvdXJjZVR5cGU6ICJvZmZpY2lhbF9zdGF0ZV90YXhfYWdlbmN5IiwKICAgICAgICBzb3VyY2VOYW1lOiAiTmV3IEplcnNleSBEaXZpc2lvbiBvZiBUYXhhdGlvbiBjYXBpdGFsIGdhaW5zIGd1aWRhbmNlIiwKICAgICAgICBzb3VyY2VVcmw6ICJodHRwczovL3d3dy5uai5nb3YvdHJlYXN1cnkvdGF4YXRpb24vIiwKICAgICAgICBub3RlczogIk5ldyBKZXJzZXkgc3RhdGUgY2FwaXRhbCBnYWlucyBlc3RpbWF0ZSBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LiIKICAgICAgfSksCiAgICAgIE5NOiBzdGF0ZSgiTmV3IE1leGljbyIsICJOTSIpLAogICAgICBOWTogc3RhdGUoIk5ldyBZb3JrIiwgIk5ZIiwgewogICAgICAgIGRlZmF1bHRDYXBpdGFsR2FpbnNUcmVhdG1lbnQ6ICJ0YXhlZF9hc19vcmRpbmFyeV9pbmNvbWUiLAogICAgICAgIHN1cHBvcnRlZDogdHJ1ZSwKICAgICAgICBsb2NhbFRheE1heUFwcGx5OiB0cnVlLAogICAgICAgIGFjY3VyYWN5U3RhdHVzOiAic2ltcGxpZmllZF9yZXF1aXJlc19yZXZpZXciLAogICAgICAgIHNvdXJjZVR5cGU6ICJvZmZpY2lhbF9zdGF0ZV90YXhfYWdlbmN5IiwKICAgICAgICBzb3VyY2VOYW1lOiAiTmV3IFlvcmsgU3RhdGUgcGVyc29uYWwgaW5jb21lIHRheCBmb3JtcyBhbmQgaW5zdHJ1Y3Rpb25zIiwKICAgICAgICBzb3VyY2VVcmw6ICJodHRwczovL3d3dy50YXgubnkuZ292L2Zvcm1zL2N1cnJlbnQtZm9ybXMvaXQvaXQyMDFpLmh0bSIsCiAgICAgICAgZGF0YVZpbnRhZ2U6ICJsYXRlc3QgYXZhaWxhYmxlIE5ldyBZb3JrIHJhdGUgYXNzdW1wdGlvbnMiLAogICAgICAgIG5vdGVzOiAiU2ltcGxpZmllZCBpbmNyZW1lbnRhbCBOZXcgWW9yayBTdGF0ZSBvcmRpbmFyeSBpbmNvbWUgdGF4IGVzdGltYXRlLiBSZXF1aXJlcyBodW1hbiByZXZpZXcgYmVmb3JlIHB1YmxpY2F0aW9uLiIsCiAgICAgICAgc3RhbmRhcmREZWR1Y3Rpb246IHsKICAgICAgICAgIHNpbmdsZTogODAwMCwKICAgICAgICAgIG1hcnJpZWRfZmlsaW5nX2pvaW50bHk6IDE2MDUwLAogICAgICAgICAgbWFycmllZF9maWxpbmdfc2VwYXJhdGVseTogODAwMCwKICAgICAgICAgIGhlYWRfb2ZfaG91c2Vob2xkOiAxMTIwMAogICAgICAgIH0sCiAgICAgICAgYnJhY2tldHM6IHsKICAgICAgICAgIHNpbmdsZTogWwogICAgICAgICAgICB7IHVwVG86IDg1MDAsIHJhdGU6IDAuMDQgfSwgeyB1cFRvOiAxMTcwMCwgcmF0ZTogMC4wNDUgfSwKICAgICAgICAgICAgeyB1cFRvOiAxMzkwMCwgcmF0ZTogMC4wNTI1IH0sIHsgdXBUbzogODA2NTAsIHJhdGU6IDAuMDU1IH0sCiAgICAgICAgICAgIHsgdXBUbzogMjE1NDAwLCByYXRlOiAwLjA2IH0sIHsgdXBUbzogMTA3NzU1MCwgcmF0ZTogMC4wNjg1IH0sCiAgICAgICAgICAgIHsgdXBUbzogNTAwMDAwMCwgcmF0ZTogMC4wOTY1IH0sIHsgdXBUbzogMjUwMDAwMDAsIHJhdGU6IDAuMTAzIH0sCiAgICAgICAgICAgIHsgdXBUbzogbnVsbCwgcmF0ZTogMC4xMDkgfQogICAgICAgICAgXSwKICAgICAgICAgIG1hcnJpZWRfZmlsaW5nX2pvaW50bHk6IFsKICAgICAgICAgICAgeyB1cFRvOiAxNzE1MCwgcmF0ZTogMC4wNCB9LCB7IHVwVG86IDIzNjAwLCByYXRlOiAwLjA0NSB9LAogICAgICAgICAgICB7IHVwVG86IDI3OTAwLCByYXRlOiAwLjA1MjUgfSwgeyB1cFRvOiAxNjE1NTAsIHJhdGU6IDAuMDU1IH0sCiAgICAgICAgICAgIHsgdXBUbzogMzIzMjAwLCByYXRlOiAwLjA2IH0sIHsgdXBUbzogMjE1NTM1MCwgcmF0ZTogMC4wNjg1IH0sCiAgICAgICAgICAgIHsgdXBUbzogNTAwMDAwMCwgcmF0ZTogMC4wOTY1IH0sIHsgdXBUbzogMjUwMDAwMDAsIHJhdGU6IDAuMTAzIH0sCiAgICAgICAgICAgIHsgdXBUbzogbnVsbCwgcmF0ZTogMC4xMDkgfQogICAgICAgICAgXSwKICAgICAgICAgIG1hcnJpZWRfZmlsaW5nX3NlcGFyYXRlbHk6IFsKICAgICAgICAgICAgeyB1cFRvOiA4NTAwLCByYXRlOiAwLjA0IH0sIHsgdXBUbzogMTE3MDAsIHJhdGU6IDAuMDQ1IH0sCiAgICAgICAgICAgIHsgdXBUbzogMTM5MDAsIHJhdGU6IDAuMDUyNSB9LCB7IHVwVG86IDgwNjUwLCByYXRlOiAwLjA1NSB9LAogICAgICAgICAgICB7IHVwVG86IDIxNTQwMCwgcmF0ZTogMC4wNiB9LCB7IHVwVG86IDEwNzc1NTAsIHJhdGU6IDAuMDY4NSB9LAogICAgICAgICAgICB7IHVwVG86IDUwMDAwMDAsIHJhdGU6IDAuMDk2NSB9LCB7IHVwVG86IDI1MDAwMDAwLCByYXRlOiAwLjEwMyB9LAogICAgICAgICAgICB7IHVwVG86IG51bGwsIHJhdGU6IDAuMTA5IH0KICAgICAgICAgIF0sCiAgICAgICAgICBoZWFkX29mX2hvdXNlaG9sZDogWwogICAgICAgICAgICB7IHVwVG86IDEyODAwLCByYXRlOiAwLjA0IH0sIHsgdXBUbzogMTc2NTAsIHJhdGU6IDAuMDQ1IH0sCiAgICAgICAgICAgIHsgdXBUbzogMjA5MDAsIHJhdGU6IDAuMDUyNSB9LCB7IHVwVG86IDEwNzY1MCwgcmF0ZTogMC4wNTUgfSwKICAgICAgICAgICAgeyB1cFRvOiAyNjkzMDAsIHJhdGU6IDAuMDYgfSwgeyB1cFRvOiAxNjE2NDUwLCByYXRlOiAwLjA2ODUgfSwKICAgICAgICAgICAgeyB1cFRvOiA1MDAwMDAwLCByYXRlOiAwLjA5NjUgfSwgeyB1cFRvOiAyNTAwMDAwMCwgcmF0ZTogMC4xMDMgfSwKICAgICAgICAgICAgeyB1cFRvOiBudWxsLCByYXRlOiAwLjEwOSB9CiAgICAgICAgICBdCiAgICAgICAgfQogICAgICB9KSwKICAgICAgTkM6IHN0YXRlKCJOb3J0aCBDYXJvbGluYSIsICJOQyIpLCBORDogc3RhdGUoIk5vcnRoIERha290YSIsICJORCIpLCBPSDogc3RhdGUoIk9oaW8iLCAiT0giLCB7IGxvY2FsVGF4TWF5QXBwbHk6IHRydWUgfSksCiAgICAgIE9LOiBzdGF0ZSgiT2tsYWhvbWEiLCAiT0siKSwgT1I6IHN0YXRlKCJPcmVnb24iLCAiT1IiKSwKICAgICAgUEE6IHN0YXRlKCJQZW5uc3lsdmFuaWEiLCAiUEEiLCB7CiAgICAgICAgZGVmYXVsdENhcGl0YWxHYWluc1RyZWF0bWVudDogInRheGVkX2FzX29yZGluYXJ5X2luY29tZSIsCiAgICAgICAgc3VwcG9ydGVkOiB0cnVlLAogICAgICAgIGxvY2FsVGF4TWF5QXBwbHk6IHRydWUsCiAgICAgICAgYWNjdXJhY3lTdGF0dXM6ICJzaW1wbGlmaWVkX3JlcXVpcmVzX3JldmlldyIsCiAgICAgICAgc291cmNlVHlwZTogIm9mZmljaWFsX3N0YXRlX3RheF9hZ2VuY3kiLAogICAgICAgIHNvdXJjZU5hbWU6ICJQZW5uc3lsdmFuaWEgRGVwYXJ0bWVudCBvZiBSZXZlbnVlIHBlcnNvbmFsIGluY29tZSB0YXggZ3VpZGFuY2UiLAogICAgICAgIHNvdXJjZVVybDogImh0dHBzOi8vd3d3LnBhLmdvdi9hZ2VuY2llcy9yZXZlbnVlLmh0bWwiLAogICAgICAgIGRhdGFWaW50YWdlOiAibGF0ZXN0IGF2YWlsYWJsZSBQZW5uc3lsdmFuaWEgZmxhdCBQSVQgcmF0ZSBhc3N1bXB0aW9uIiwKICAgICAgICBub3RlczogIlNpbXBsaWZpZWQgUGVubnN5bHZhbmlhIGZsYXQgcGVyc29uYWwgaW5jb21lIHRheCBlc3RpbWF0ZS4gUEEgbG9jYWwgdGF4ZXMgYXJlIG5vdCBpbmNsdWRlZC4iLAogICAgICAgIGZsYXRSYXRlOiAwLjAzMDcKICAgICAgfSksCiAgICAgIFJJOiBzdGF0ZSgiUmhvZGUgSXNsYW5kIiwgIlJJIiksIFNDOiBzdGF0ZSgiU291dGggQ2Fyb2xpbmEiLCAiU0MiKSwKICAgICAgU0Q6IG5vQnJvYWRJbmNvbWVUYXgoIlNvdXRoIERha290YSIsICJTRCIsICJodHRwczovL2Rvci5zZC5nb3YvIiksCiAgICAgIFROOiBub0Jyb2FkSW5jb21lVGF4KCJUZW5uZXNzZWUiLCAiVE4iLCAiaHR0cHM6Ly93d3cudG4uZ292L3JldmVudWUuaHRtbCIpLAogICAgICBUWDogbm9Ccm9hZEluY29tZVRheCgiVGV4YXMiLCAiVFgiLCAiaHR0cHM6Ly9jb21wdHJvbGxlci50ZXhhcy5nb3YvdGF4ZXMvIiksCiAgICAgIFVUOiBzdGF0ZSgiVXRhaCIsICJVVCIpLCBWVDogc3RhdGUoIlZlcm1vbnQiLCAiVlQiKSwgVkE6IHN0YXRlKCJWaXJnaW5pYSIsICJWQSIpLAogICAgICBXQTogc3RhdGUoIldhc2hpbmd0b24iLCAiV0EiLCB7CiAgICAgICAgYnJvYWRJbmRpdmlkdWFsSW5jb21lVGF4OiBmYWxzZSwKICAgICAgICBkZWZhdWx0Q2FwaXRhbEdhaW5zVHJlYXRtZW50OiAicHJlZmVyZW50aWFsX29yX3NwZWNpYWxfcnVsZXMiLAogICAgICAgIHN1cHBvcnRlZDogZmFsc2UsCiAgICAgICAgYWNjdXJhY3lTdGF0dXM6ICJub3RfaW1wbGVtZW50ZWQiLAogICAgICAgIHNvdXJjZVR5cGU6ICJvZmZpY2lhbF9zdGF0ZV90YXhfYWdlbmN5IiwKICAgICAgICBzb3VyY2VOYW1lOiAiV2FzaGluZ3RvbiBEZXBhcnRtZW50IG9mIFJldmVudWUgY2FwaXRhbCBnYWlucyB0YXggZ3VpZGFuY2UiLAogICAgICAgIHNvdXJjZVVybDogImh0dHBzOi8vZG9yLndhLmdvdi90YXhlcy1yYXRlcy9vdGhlci10YXhlcy9jYXBpdGFsLWdhaW5zLXRheCIsCiAgICAgICAgbm90ZXM6ICJXYXNoaW5ndG9uIGhhcyBhIHNlcGFyYXRlIGNhcGl0YWwgZ2FpbnMgdGF4IHJlZ2ltZS4gVmVyc2lvbiAxIGRvZXMgbm90IGVzdGltYXRlIGl0LiIKICAgICAgfSksCiAgICAgIFdWOiBzdGF0ZSgiV2VzdCBWaXJnaW5pYSIsICJXViIpLCBXSTogc3RhdGUoIldpc2NvbnNpbiIsICJXSSIpLAogICAgICBXWTogbm9Ccm9hZEluY29tZVRheCgiV3lvbWluZyIsICJXWSIsICJodHRwczovL3JldmVudWUud3lvLmdvdi8iKQogICAgfQogIH07Cn0pKCk7CgoKKGZ1bmN0aW9uICgpIHsKICAidXNlIHN0cmljdCI7CgogIHdpbmRvdy5JVEJMb2NhbFRheERhdGEgPSB7CiAgICBqdXJpc2RpY3Rpb25zOiB7CiAgICAgIE5ZQzogewogICAgICAgIGp1cmlzZGljdGlvbjogIk5ldyBZb3JrIENpdHkiLAogICAgICAgIHRheFllYXI6IDIwMjYsCiAgICAgICAgZGF0YVZpbnRhZ2U6ICJMYXRlc3QgYXZhaWxhYmxlIE5ZQyByZXNpZGVudCBpbmNvbWUgdGF4IHJhdGUgYXNzdW1wdGlvbnMiLAogICAgICAgIGxhc3RVcGRhdGVkOiAiMjAyNi0wNC0yNyIsCiAgICAgICAgc291cmNlTmFtZTogIk5ldyBZb3JrIFN0YXRlIHBlcnNvbmFsIGluY29tZSB0YXggZm9ybXMgYW5kIGNpdHkgcmVzaWRlbnQgdGF4IGluc3RydWN0aW9ucyIsCiAgICAgICAgc291cmNlVXJsOiAiaHR0cHM6Ly93d3cudGF4Lm55Lmdvdi9mb3Jtcy9jdXJyZW50LWZvcm1zL2l0L2l0MjAxaS5odG0iLAogICAgICAgIHNvdXJjZVR5cGU6ICJvZmZpY2lhbF9jaXR5X3RheF9hZ2VuY3kiLAogICAgICAgIHJldHJpZXZlZERhdGU6ICIyMDI2LTA0LTI3IiwKICAgICAgICB2ZXJpZmllZEJ5OiAicmVxdWlyZXNfaHVtYW5fcmV2aWV3IiwKICAgICAgICBhY2N1cmFjeVN0YXR1czogInNpbXBsaWZpZWRfcmVxdWlyZXNfcmV2aWV3IiwKICAgICAgICBub3RlczogIlNpbXBsaWZpZWQgTllDIHJlc2lkZW50IHRheCBpbXBhY3QgZXN0aW1hdGUuIEFwcGxpZXMgb25seSB3aGVuIHRoZSB1c2VyIHNlbGVjdHMgTmV3IFlvcmsgYW5kIE5ZQyByZXNpZGVudC4iLAogICAgICAgIHN1cHBvcnRlZDogdHJ1ZSwKICAgICAgICBicmFja2V0czogewogICAgICAgICAgc2luZ2xlOiBbCiAgICAgICAgICAgIHsgdXBUbzogMTIwMDAsIHJhdGU6IDAuMDMwNzggfSwKICAgICAgICAgICAgeyB1cFRvOiAyNTAwMCwgcmF0ZTogMC4wMzc2MiB9LAogICAgICAgICAgICB7IHVwVG86IDUwMDAwLCByYXRlOiAwLjAzODE5IH0sCiAgICAgICAgICAgIHsgdXBUbzogbnVsbCwgcmF0ZTogMC4wMzg3NiB9CiAgICAgICAgICBdLAogICAgICAgICAgbWFycmllZF9maWxpbmdfam9pbnRseTogWwogICAgICAgICAgICB7IHVwVG86IDIxNjAwLCByYXRlOiAwLjAzMDc4IH0sCiAgICAgICAgICAgIHsgdXBUbzogNDUwMDAsIHJhdGU6IDAuMDM3NjIgfSwKICAgICAgICAgICAgeyB1cFRvOiA5MDAwMCwgcmF0ZTogMC4wMzgxOSB9LAogICAgICAgICAgICB7IHVwVG86IG51bGwsIHJhdGU6IDAuMDM4NzYgfQogICAgICAgICAgXSwKICAgICAgICAgIG1hcnJpZWRfZmlsaW5nX3NlcGFyYXRlbHk6IFsKICAgICAgICAgICAgeyB1cFRvOiAxMjAwMCwgcmF0ZTogMC4wMzA3OCB9LAogICAgICAgICAgICB7IHVwVG86IDI1MDAwLCByYXRlOiAwLjAzNzYyIH0sCiAgICAgICAgICAgIHsgdXBUbzogNTAwMDAsIHJhdGU6IDAuMDM4MTkgfSwKICAgICAgICAgICAgeyB1cFRvOiBudWxsLCByYXRlOiAwLjAzODc2IH0KICAgICAgICAgIF0sCiAgICAgICAgICBoZWFkX29mX2hvdXNlaG9sZDogWwogICAgICAgICAgICB7IHVwVG86IDE0NDAwLCByYXRlOiAwLjAzMDc4IH0sCiAgICAgICAgICAgIHsgdXBUbzogMzAwMDAsIHJhdGU6IDAuMDM3NjIgfSwKICAgICAgICAgICAgeyB1cFRvOiA2MDAwMCwgcmF0ZTogMC4wMzgxOSB9LAogICAgICAgICAgICB7IHVwVG86IG51bGwsIHJhdGU6IDAuMDM4NzYgfQogICAgICAgICAgXQogICAgICAgIH0KICAgICAgfQogICAgfQogIH07Cn0pKCk7CgoKKGZ1bmN0aW9uICgpIHsKICAidXNlIHN0cmljdCI7CgogIHdpbmRvdy5JVEJDYXBpdGFsR2FpbnNEYXRhU291cmNlcyA9IHsKICAgIGxhc3RVcGRhdGVkOiAiMjAyNi0wNC0yNyIsCiAgICBub3RlczogWwogICAgICAiRmVkZXJhbCAyMDI2IG9yZGluYXJ5IGluY29tZSBhbmQgbG9uZy10ZXJtIGNhcGl0YWwgZ2FpbnMgdGhyZXNob2xkcyBhcmUgc291cmNlZCBmcm9tIElSUyBSZXYuIFByb2MuIDIwMjUtMzIuIiwKICAgICAgIk5JSVQgZGF0YSBpcyBzb3VyY2VkIGZyb20gSVJTIE5ldCBJbnZlc3RtZW50IEluY29tZSBUYXggZ3VpZGFuY2UuIiwKICAgICAgIlN0YXRlIGFuZCBsb2NhbCBlbnRyaWVzIHJlbWFpbiBtYXJrZWQgcmVxdWlyZXNfaHVtYW5fcmV2aWV3IGV2ZW4gd2hlbiBhIHNpbXBsaWZpZWQgY2FsY3VsYXRpb24gaXMgcHJlc2VudC4iCiAgICBdCiAgfTsKfSkoKTsKCgooZnVuY3Rpb24gKCkgewogICJ1c2Ugc3RyaWN0IjsKCiAgY29uc3QgREFUQSA9IHsKICAgIGx0Y2c6IHdpbmRvdy5JVEJDYXBpdGFsR2FpbnNGZWRlcmFsTFRDRzIwMjYsCiAgICBvcmRpbmFyeTogd2luZG93LklUQkZlZGVyYWxPcmRpbmFyeUluY29tZTIwMjYsCiAgICBuaWl0OiB3aW5kb3cuSVRCRmVkZXJhbE5JSVREYXRhLAogICAgc3RhdGVzOiB3aW5kb3cuSVRCU3RhdGVDYXBpdGFsR2FpbnNEYXRhLAogICAgbG9jYWw6IHdpbmRvdy5JVEJMb2NhbFRheERhdGEKICB9OwoKICBjb25zdCBGSUxJTkdfTEFCRUxTID0gewogICAgc2luZ2xlOiAiU2luZ2xlIiwKICAgIG1hcnJpZWRfZmlsaW5nX2pvaW50bHk6ICJNYXJyaWVkIEZpbGluZyBKb2ludGx5IiwKICAgIG1hcnJpZWRfZmlsaW5nX3NlcGFyYXRlbHk6ICJNYXJyaWVkIEZpbGluZyBTZXBhcmF0ZWx5IiwKICAgIGhlYWRfb2ZfaG91c2Vob2xkOiAiSGVhZCBvZiBIb3VzZWhvbGQiCiAgfTsKCiAgY29uc3QgQVNTRVRfTEFCRUxTID0gewogICAgc3RvY2s6ICJTdG9jaywgRVRGLCBvciBtdXR1YWwgZnVuZCIsCiAgICBjcnlwdG86ICJDcnlwdG8iLAogICAgcmVhbF9lc3RhdGU6ICJSZWFsIGVzdGF0ZSIsCiAgICBwcmltYXJ5X3Jlc2lkZW5jZTogIlByaW1hcnkgcmVzaWRlbmNlIiwKICAgIGNvbGxlY3RpYmxlOiAiQ29sbGVjdGlibGUiLAogICAgb3RoZXI6ICJPdGhlciBpbnZlc3RtZW50IGFzc2V0IgogIH07CgogIGNvbnN0IFJFTEFURURfVE9PTFMgPSBbCiAgICB7IGxhYmVsOiAiMjAyNiBGZWRlcmFsIEluY29tZSBUYXggQ2FsY3VsYXRvciIsIHVybDogIi93cC8yMDI2LWZlZGVyYWwtaW5jb21lLXRheC1jYWxjdWxhdG9yLyIgfSwKICAgIHsgbGFiZWw6ICIyMDI2IFF1YXJ0ZXJseSBFc3RpbWF0ZWQgVGF4IENhbGN1bGF0b3IiLCB1cmw6ICIvd3AvMjAyNi1xdWFydGVybHktZXN0aW1hdGVkLXRheC1jYWxjdWxhdG9yLyIgfSwKICAgIHsgbGFiZWw6ICI0MDEoayksIEhTQSBhbmQgUGF5cm9sbCBCZW5lZml0cyBDYWxjdWxhdG9yIiwgdXJsOiAiL3dwL3ByZXRheC1zYXZpbmdzLXRha2UtaG9tZS1wYXktY2FsY3VsYXRvci8iIH0sCiAgICB7IGxhYmVsOiAiTllDIENvbW11dGVyIFRheCBDYWxjdWxhdG9yIiwgdXJsOiAiL3dwL255Yy1jb21tdXRlci10YXgtY2FsY3VsYXRvci8iIH0sCiAgICB7IGxhYmVsOiAiTllDIFBhcnQtWWVhciBSZXNpZGVudCBUYXggQ2FsY3VsYXRvciIsIHVybDogIi93cC9ueWMtcGFydC15ZWFyLXJlc2lkZW50LXRheC1jYWxjdWxhdG9yLyIgfQogIF07CgogIGZ1bmN0aW9uIG1vbmV5KHZhbHVlKSB7CiAgICByZXR1cm4gbmV3IEludGwuTnVtYmVyRm9ybWF0KCJlbi1VUyIsIHsgc3R5bGU6ICJjdXJyZW5jeSIsIGN1cnJlbmN5OiAiVVNEIiwgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiAwIH0pLmZvcm1hdChNYXRoLnJvdW5kKHZhbHVlIHx8IDApKTsKICB9CgogIGZ1bmN0aW9uIHBlcmNlbnQodmFsdWUpIHsKICAgIGlmICghTnVtYmVyLmlzRmluaXRlKHZhbHVlKSkgcmV0dXJuICJOL0EiOwogICAgcmV0dXJuICh2YWx1ZSAqIDEwMCkudG9GaXhlZCgyKSArICIlIjsKICB9CgogIGZ1bmN0aW9uIG51bWJlcih2YWx1ZSkgewogICAgaWYgKHZhbHVlID09PSAiIiB8fCB2YWx1ZSA9PSBudWxsKSByZXR1cm4gMDsKICAgIGNvbnN0IHBhcnNlZCA9IE51bWJlcih2YWx1ZSk7CiAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHBhcnNlZCkgPyBwYXJzZWQgOiAwOwogIH0KCiAgZnVuY3Rpb24gb3B0aW9uYWxOdW1iZXIodmFsdWUpIHsKICAgIGlmICh2YWx1ZSA9PT0gIiIgfHwgdmFsdWUgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICBjb25zdCBwYXJzZWQgPSBOdW1iZXIodmFsdWUpOwogICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShwYXJzZWQpID8gcGFyc2VkIDogbnVsbDsKICB9CgogIGZ1bmN0aW9uIGZpZWxkVmFsdWUoZm9ybSwgZmllbGQpIHsKICAgIGNvbnN0IGVsZW1lbnQgPSBmb3JtLnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLWZpZWxkPSInICsgZmllbGQgKyAnIl0nKTsKICAgIGlmICghZWxlbWVudCkgcmV0dXJuICIiOwogICAgaWYgKGVsZW1lbnQudHlwZSA9PT0gImNoZWNrYm94IikgcmV0dXJuIGVsZW1lbnQuY2hlY2tlZCA\/ICJ5ZXMiIDogIm5vIjsKICAgIHJldHVybiBlbGVtZW50LnZhbHVlOwogIH0KCiAgZnVuY3Rpb24gbm9ybWFsaXplSW5wdXRzKHJhdykgewogICAgY29uc3QgYWRqdXN0ZWRCYXNpcyA9IG9wdGlvbmFsTnVtYmVyKHJhdy5hZGp1c3RlZEJhc2lzKTsKICAgIGNvbnN0IG1hbnVhbEhvbWVFeGNsdXNpb24gPSBvcHRpb25hbE51bWJlcihyYXcubWFudWFsSG9tZUV4Y2x1c2lvbik7CiAgICBjb25zdCBzdGF0ZVRheE92ZXJyaWRlID0gb3B0aW9uYWxOdW1iZXIocmF3LnN0YXRlVGF4T3ZlcnJpZGUpOwogICAgY29uc3QgbmlpdE92ZXJyaWRlID0gb3B0aW9uYWxOdW1iZXIocmF3Lm5paXRPdmVycmlkZSk7CiAgICByZXR1cm4gewogICAgICB0YXhZZWFyOiByYXcudGF4WWVhciB8fCAiMjAyNiIsCiAgICAgIGFzc2V0VHlwZTogcmF3LmFzc2V0VHlwZSB8fCAic3RvY2siLAogICAgICBwdXJjaGFzZVByaWNlOiBudW1iZXIocmF3LnB1cmNoYXNlUHJpY2UpLAogICAgICBzYWxlUHJpY2U6IG51bWJlcihyYXcuc2FsZVByaWNlKSwKICAgICAgc2VsbGluZ0V4cGVuc2VzOiBudW1iZXIocmF3LnNlbGxpbmdFeHBlbnNlcyksCiAgICAgIHB1cmNoYXNlRGF0ZTogcmF3LnB1cmNoYXNlRGF0ZSB8fCAiIiwKICAgICAgc2FsZURhdGU6IHJhdy5zYWxlRGF0ZSB8fCAiIiwKICAgICAgaG9sZGluZ1BlcmlvZE92ZXJyaWRlOiByYXcuaG9sZGluZ1BlcmlvZE92ZXJyaWRlIHx8ICIiLAogICAgICBjYXBpdGFsTG9zc2VzOiBudW1iZXIocmF3LmNhcGl0YWxMb3NzZXMpLAogICAgICBmaWxpbmdTdGF0dXM6IHJhdy5maWxpbmdTdGF0dXMgfHwgIiIsCiAgICAgIHRheGFibGVJbmNvbWVCZWZvcmVHYWluOiBudW1iZXIocmF3LnRheGFibGVJbmNvbWVCZWZvcmVHYWluKSwKICAgICAgbWFnaUJlZm9yZUdhaW46IG9wdGlvbmFsTnVtYmVyKHJhdy5tYWdpQmVmb3JlR2FpbiksCiAgICAgIHN0YXRlT2ZSZXNpZGVuY2U6IHJhdy5zdGF0ZU9mUmVzaWRlbmNlIHx8ICIiLAogICAgICBpc05ZQ1Jlc2lkZW50OiByYXcuc3RhdGVPZlJlc2lkZW5jZSA9PT0gIk5ZIiA\/IHJhdy5pc05ZQ1Jlc2lkZW50ID09PSAieWVzIiB8fCByYXcuaXNOWUNSZXNpZGVudCA9PT0gdHJ1ZSA6IGZhbHNlLAogICAgICBhZGp1c3RlZEJhc2lzLAogICAgICBkZXByZWNpYXRpb25SZWNhcHR1cmU6IG51bWJlcihyYXcuZGVwcmVjaWF0aW9uUmVjYXB0dXJlKSwKICAgICAgc3RhdGVUYXhhYmxlSW5jb21lT3ZlcnJpZGU6IG9wdGlvbmFsTnVtYmVyKHJhdy5zdGF0ZVRheGFibGVJbmNvbWVPdmVycmlkZSksCiAgICAgIHN0YXRlVGF4T3ZlcnJpZGUsCiAgICAgIG5paXRPdmVycmlkZSwKICAgICAgaG9tZU93bmVkVXNlZFR3b1llYXJzOiByYXcuaG9tZU93bmVkVXNlZFR3b1llYXJzIHx8ICJ5ZXMiLAogICAgICBob21lRXhjbHVzaW9uVXNlZFJlY2VudGx5OiByYXcuaG9tZUV4Y2x1c2lvblVzZWRSZWNlbnRseSB8fCAibm8iLAogICAgICBtYW51YWxIb21lRXhjbHVzaW9uCiAgICB9OwogIH0KCiAgZnVuY3Rpb24gY29sbGVjdElucHV0KGZvcm0pIHsKICAgIGNvbnN0IHJhdyA9IHt9OwogICAgZm9ybS5xdWVyeVNlbGVjdG9yQWxsKCJbZGF0YS1maWVsZF0iKS5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgIHJhd1tlbGVtZW50LmdldEF0dHJpYnV0ZSgiZGF0YS1maWVsZCIpXSA9IGVsZW1lbnQudHlwZSA9PT0gImNoZWNrYm94IiA\/IChlbGVtZW50LmNoZWNrZWQgPyAieWVzIiA6ICJubyIpIDogZWxlbWVudC52YWx1ZTsKICAgIH0pOwogICAgcmV0dXJuIG5vcm1hbGl6ZUlucHV0cyhyYXcpOwogIH0KCiAgZnVuY3Rpb24gdmFsaWRhdGVJbnB1dHMoaW5wdXQpIHsKICAgIGNvbnN0IGVycm9ycyA9IFtdOwogICAgaWYgKCFpbnB1dC5maWxpbmdTdGF0dXMpIGVycm9ycy5wdXNoKCJDaG9vc2UgYSBmaWxpbmcgc3RhdHVzIHRvIGNhbGN1bGF0ZSBhbiBlc3RpbWF0ZS4iKTsKICAgIGlmICghaW5wdXQuc3RhdGVPZlJlc2lkZW5jZSkgZXJyb3JzLnB1c2goIkNob29zZSBhIHN0YXRlIG9mIHJlc2lkZW5jZSB0byBjYWxjdWxhdGUgYW4gZXN0aW1hdGUuIik7CiAgICBpZiAoIWlucHV0LnB1cmNoYXNlUHJpY2UgJiYgaW5wdXQuYWRqdXN0ZWRCYXNpcyA9PSBudWxsKSBlcnJvcnMucHVzaCgiRW50ZXIgeW91ciBwdXJjaGFzZSBwcmljZSBvciBjb3N0IGJhc2lzIHRvIGNhbGN1bGF0ZSBhbiBlc3RpbWF0ZS4iKTsKICAgIGlmICghaW5wdXQuc2FsZVByaWNlKSBlcnJvcnMucHVzaCgiRW50ZXIgeW91ciBzYWxlIHByaWNlIHRvIGNhbGN1bGF0ZSBhbiBlc3RpbWF0ZS4iKTsKICAgIGNvbnN0IGNoZWNrcyA9IFsKICAgICAgWyJQdXJjaGFzZSBwcmljZSBvciBiYXNpcyIsIGlucHV0LnB1cmNoYXNlUHJpY2VdLAogICAgICBbIlNhbGUgcHJpY2UiLCBpbnB1dC5zYWxlUHJpY2VdLAogICAgICBbIlNlbGxpbmcgZXhwZW5zZXMiLCBpbnB1dC5zZWxsaW5nRXhwZW5zZXNdLAogICAgICBbIkNhcGl0YWwgbG9zc2VzIiwgaW5wdXQuY2FwaXRhbExvc3Nlc10sCiAgICAgIFsiT3RoZXIgdGF4YWJsZSBpbmNvbWUgZm9yIHRoZSB5ZWFyIiwgaW5wdXQudGF4YWJsZUluY29tZUJlZm9yZUdhaW5dLAogICAgICBbIkRlcHJlY2lhdGlvbiByZWNhcHR1cmUiLCBpbnB1dC5kZXByZWNpYXRpb25SZWNhcHR1cmVdCiAgICBdOwogICAgY2hlY2tzLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgaWYgKGl0ZW1bMV0gPCAwKSBlcnJvcnMucHVzaChpdGVtWzBdICsgIiBjYW5ub3QgYmUgbmVnYXRpdmUuIik7CiAgICB9KTsKICAgIGlmIChpbnB1dC5hZGp1c3RlZEJhc2lzICE9IG51bGwgJiYgaW5wdXQuYWRqdXN0ZWRCYXNpcyA8IDApIGVycm9ycy5wdXNoKCJBZGp1c3RlZCBiYXNpcyBjYW5ub3QgYmUgbmVnYXRpdmUuIik7CiAgICBpZiAoaW5wdXQuc3RhdGVUYXhPdmVycmlkZSAhPSBudWxsICYmIGlucHV0LnN0YXRlVGF4T3ZlcnJpZGUgPCAwKSBlcnJvcnMucHVzaCgiU3RhdGUgY2FwaXRhbCBnYWluIHRheCBvdmVycmlkZSBjYW5ub3QgYmUgbmVnYXRpdmUuIik7CiAgICBpZiAoaW5wdXQubmlpdE92ZXJyaWRlICE9IG51bGwgJiYgaW5wdXQubmlpdE92ZXJyaWRlIDwgMCkgZXJyb3JzLnB1c2goIk5JSVQgb3ZlcnJpZGUgY2Fubm90IGJlIG5lZ2F0aXZlLiIpOwogICAgaWYgKCFpbnB1dC5ob2xkaW5nUGVyaW9kT3ZlcnJpZGUpIHsKICAgICAgaWYgKCFpbnB1dC5wdXJjaGFzZURhdGUgfHwgIWlucHV0LnNhbGVEYXRlKSBlcnJvcnMucHVzaCgiRW50ZXIgcHVyY2hhc2UgYW5kIHNhbGUgZGF0ZXMsIG9yIGNob29zZSB3aGV0aGVyIHRoZSBnYWluIGlzIHNob3J0LXRlcm0gb3IgbG9uZy10ZXJtLiIpOwogICAgICBjb25zdCBwdXJjaGFzZSA9IERhdGUucGFyc2UoaW5wdXQucHVyY2hhc2VEYXRlKTsKICAgICAgY29uc3Qgc2FsZSA9IERhdGUucGFyc2UoaW5wdXQuc2FsZURhdGUpOwogICAgICBpZiAoaW5wdXQucHVyY2hhc2VEYXRlICYmIGlucHV0LnNhbGVEYXRlKSB7CiAgICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUocHVyY2hhc2UpIHx8ICFOdW1iZXIuaXNGaW5pdGUoc2FsZSkpIGVycm9ycy5wdXNoKCJFbnRlciB2YWxpZCBwdXJjaGFzZSBhbmQgc2FsZSBkYXRlcy4iKTsKICAgICAgICBlbHNlIGlmIChzYWxlIDwgcHVyY2hhc2UpIGVycm9ycy5wdXNoKCJTYWxlIGRhdGUgY2Fubm90IGJlIGJlZm9yZSBwdXJjaGFzZSBkYXRlLiIpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gZXJyb3JzOwogIH0KCiAgZnVuY3Rpb24gZGV0ZXJtaW5lSG9sZGluZ1BlcmlvZChpbnB1dCkgewogICAgaWYgKGlucHV0LmhvbGRpbmdQZXJpb2RPdmVycmlkZSA9PT0gImxvbmdfdGVybSIpIHJldHVybiB7IGhvbGRpbmdQZXJpb2Q6ICJMb25nLXRlcm0iLCBpc0xvbmdUZXJtOiB0cnVlLCBkYXlzSGVsZDogbnVsbCwgb3ZlcnJpZGRlbjogdHJ1ZSB9OwogICAgaWYgKGlucHV0LmhvbGRpbmdQZXJpb2RPdmVycmlkZSA9PT0gInNob3J0X3Rlcm0iKSByZXR1cm4geyBob2xkaW5nUGVyaW9kOiAiU2hvcnQtdGVybSIsIGlzTG9uZ1Rlcm06IGZhbHNlLCBkYXlzSGVsZDogbnVsbCwgb3ZlcnJpZGRlbjogdHJ1ZSB9OwogICAgY29uc3QgcHVyY2hhc2UgPSBEYXRlLnBhcnNlKGlucHV0LnB1cmNoYXNlRGF0ZSk7CiAgICBjb25zdCBzYWxlID0gRGF0ZS5wYXJzZShpbnB1dC5zYWxlRGF0ZSk7CiAgICBpZiAoIU51bWJlci5pc0Zpbml0ZShwdXJjaGFzZSkgfHwgIU51bWJlci5pc0Zpbml0ZShzYWxlKSkgcmV0dXJuIHsgaG9sZGluZ1BlcmlvZDogIlVua25vd24iLCBpc0xvbmdUZXJtOiBmYWxzZSwgZGF5c0hlbGQ6IG51bGwsIG92ZXJyaWRkZW46IGZhbHNlIH07CiAgICBjb25zdCBkYXlzSGVsZCA9IE1hdGguZmxvb3IoKHNhbGUgLSBwdXJjaGFzZSkgLyA4NjQwMDAwMCk7CiAgICByZXR1cm4geyBob2xkaW5nUGVyaW9kOiBkYXlzSGVsZCA+IDM2NSA\/ICJMb25nLXRlcm0iIDogIlNob3J0LXRlcm0iLCBpc0xvbmdUZXJtOiBkYXlzSGVsZCA+IDM2NSwgZGF5c0hlbGQsIG92ZXJyaWRkZW46IGZhbHNlIH07CiAgfQoKICBmdW5jdGlvbiBjYWxjdWxhdGVHcm9zc0dhaW4oaW5wdXQpIHsKICAgIHJldHVybiBpbnB1dC5zYWxlUHJpY2UgLSBpbnB1dC5wdXJjaGFzZVByaWNlOwogIH0KCiAgZnVuY3Rpb24gYXBwYXJlbnRIb21lRXhjbHVzaW9uKGlucHV0LCBuZXRHYWluKSB7CiAgICBpZiAoaW5wdXQuYXNzZXRUeXBlICE9PSAicHJpbWFyeV9yZXNpZGVuY2UiKSByZXR1cm4geyBhbW91bnQ6IDAsIGFwcGxpZWQ6IGZhbHNlLCB3YXJuaW5nOiAiIiB9OwogICAgY29uc3QgbWF4RXhjbHVzaW9uID0gaW5wdXQuZmlsaW5nU3RhdHVzID09PSAibWFycmllZF9maWxpbmdfam9pbnRseSIgPyA1MDAwMDAgOiAyNTAwMDA7CiAgICBpZiAoaW5wdXQubWFudWFsSG9tZUV4Y2x1c2lvbiAhPSBudWxsKSB7CiAgICAgIHJldHVybiB7IGFtb3VudDogTWF0aC5taW4obmV0R2FpbiwgaW5wdXQubWFudWFsSG9tZUV4Y2x1c2lvbiksIGFwcGxpZWQ6IGlucHV0Lm1hbnVhbEhvbWVFeGNsdXNpb24gPiAwLCB3YXJuaW5nOiAiUHJpbWFyeSByZXNpZGVuY2UgZXhjbHVzaW9uIHdhcyBtYW51YWxseSBlbnRlcmVkIGFuZCBpcyB0cmVhdGVkIGFzIHNpbXBsaWZpZWQuIiB9OwogICAgfQogICAgaWYgKGlucHV0LmhvbWVPd25lZFVzZWRUd29ZZWFycyA9PT0gInllcyIgJiYgaW5wdXQuaG9tZUV4Y2x1c2lvblVzZWRSZWNlbnRseSA9PT0gIm5vIikgewogICAgICByZXR1cm4geyBhbW91bnQ6IE1hdGgubWluKG5ldEdhaW4sIG1heEV4Y2x1c2lvbiksIGFwcGxpZWQ6IHRydWUsIHdhcm5pbmc6ICJTaW1wbGlmaWVkIFNlY3Rpb24gMTIxIGhvbWUgc2FsZSBleGNsdXNpb24gYXBwbGllZC4gQ29uZmlybSBmdWxsIGVsaWdpYmlsaXR5IGJlZm9yZSByZWx5aW5nIG9uIHRoZSByZXN1bHQuIiB9OwogICAgfQogICAgcmV0dXJuIHsgYW1vdW50OiAwLCBhcHBsaWVkOiBmYWxzZSwgd2FybmluZzogIlRoZSBob21lIHNhbGUgZXhjbHVzaW9uIGhhcyBlbGlnaWJpbGl0eSBydWxlcy4gVGhpcyBjYWxjdWxhdG9yIHVzZXMgYSBzaW1wbGlmaWVkIGVzdGltYXRlIGFuZCBkb2VzIG5vdCBkZXRlcm1pbmUgZnVsbCBlbGlnaWJpbGl0eS4iIH07CiAgfQoKICBmdW5jdGlvbiBjYWxjdWxhdGVUYXhhYmxlR2FpbihpbnB1dCkgewogICAgY29uc3QgYmFzaXMgPSBpbnB1dC5hZGp1c3RlZEJhc2lzICE9IG51bGwgPyBpbnB1dC5hZGp1c3RlZEJhc2lzIDogaW5wdXQucHVyY2hhc2VQcmljZTsKICAgIGNvbnN0IGdyb3NzR2FpbiA9IGlucHV0LnNhbGVQcmljZSAtIGlucHV0LnB1cmNoYXNlUHJpY2U7CiAgICBjb25zdCBuZXRHYWluQmVmb3JlRXhjbHVzaW9uID0gaW5wdXQuc2FsZVByaWNlIC0gaW5wdXQuc2VsbGluZ0V4cGVuc2VzIC0gYmFzaXM7CiAgICBjb25zdCBob21lRXhjbHVzaW9uID0gYXBwYXJlbnRIb21lRXhjbHVzaW9uKGlucHV0LCBNYXRoLm1heCgwLCBuZXRHYWluQmVmb3JlRXhjbHVzaW9uKSk7CiAgICBjb25zdCBhZnRlckV4Y2x1c2lvbiA9IE1hdGgubWF4KDAsIG5ldEdhaW5CZWZvcmVFeGNsdXNpb24gLSBob21lRXhjbHVzaW9uLmFtb3VudCk7CiAgICBjb25zdCBjYXBpdGFsTG9zc2VzQXBwbGllZCA9IE1hdGgubWluKGFmdGVyRXhjbHVzaW9uLCBpbnB1dC5jYXBpdGFsTG9zc2VzKTsKICAgIGNvbnN0IHRheGFibGVHYWluID0gTWF0aC5tYXgoMCwgYWZ0ZXJFeGNsdXNpb24gLSBjYXBpdGFsTG9zc2VzQXBwbGllZCk7CiAgICByZXR1cm4geyBiYXNpcywgZ3Jvc3NHYWluLCBuZXRHYWluOiBuZXRHYWluQmVmb3JlRXhjbHVzaW9uLCBob21lRXhjbHVzaW9uLCBjYXBpdGFsTG9zc2VzQXBwbGllZCwgdGF4YWJsZUdhaW4gfTsKICB9CgogIGZ1bmN0aW9uIHRheEZyb21CcmFja2V0cyhpbmNvbWUsIGJyYWNrZXRzKSB7CiAgICBpZiAoaW5jb21lIDw9IDApIHJldHVybiAwOwogICAgbGV0IHByZXZpb3VzID0gMDsKICAgIGxldCB0YXggPSAwOwogICAgZm9yIChjb25zdCBicmFja2V0IG9mIGJyYWNrZXRzKSB7CiAgICAgIGNvbnN0IHRvcCA9IGJyYWNrZXQudXBUbyA9PSBudWxsID8gSW5maW5pdHkgOiBicmFja2V0LnVwVG87CiAgICAgIGNvbnN0IHNsaWNlID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oaW5jb21lLCB0b3ApIC0gcHJldmlvdXMpOwogICAgICB0YXggKz0gc2xpY2UgKiBicmFja2V0LnJhdGU7CiAgICAgIGlmIChpbmNvbWUgPD0gdG9wKSBicmVhazsKICAgICAgcHJldmlvdXMgPSB0b3A7CiAgICB9CiAgICByZXR1cm4gdGF4OwogIH0KCiAgZnVuY3Rpb24gdGF4RnJvbUJhc2VCcmFja2V0cyhpbmNvbWUsIGJyYWNrZXRzKSB7CiAgICBpZiAoaW5jb21lIDw9IDApIHJldHVybiAwOwogICAgZm9yIChjb25zdCBicmFja2V0IG9mIGJyYWNrZXRzKSB7CiAgICAgIGNvbnN0IHRvcCA9IGJyYWNrZXQudXBUbyA9PSBudWxsID8gSW5maW5pdHkgOiBicmFja2V0LnVwVG87CiAgICAgIGlmIChpbmNvbWUgPD0gdG9wKSByZXR1cm4gYnJhY2tldC5iYXNlVGF4ICsgKGluY29tZSAtIGJyYWNrZXQub3ZlcikgKiBicmFja2V0LnJhdGU7CiAgICB9CiAgICByZXR1cm4gMDsKICB9CgogIGZ1bmN0aW9uIGluY3JlbWVudGFsT3JkaW5hcnlUYXgoYmVmb3JlSW5jb21lLCBhZGRlZEluY29tZSwgYnJhY2tldHMpIHsKICAgIHJldHVybiBNYXRoLm1heCgwLCB0YXhGcm9tQmFzZUJyYWNrZXRzKGJlZm9yZUluY29tZSArIGFkZGVkSW5jb21lLCBicmFja2V0cykgLSB0YXhGcm9tQmFzZUJyYWNrZXRzKGJlZm9yZUluY29tZSwgYnJhY2tldHMpKTsKICB9CgogIGZ1bmN0aW9uIGNhbGN1bGF0ZUxvbmdUZXJtRmVkZXJhbENhcGl0YWxHYWluc1RheChpbnB1dCwgdGF4YWJsZUdhaW4pIHsKICAgIGNvbnN0IHRocmVzaG9sZHMgPSBEQVRBLmx0Y2cudGhyZXNob2xkc1tpbnB1dC5maWxpbmdTdGF0dXNdOwogICAgbGV0IHJlbWFpbmluZyA9IHRheGFibGVHYWluOwogICAgbGV0IHRheCA9IDA7CiAgICBjb25zdCB6ZXJvUm9vbSA9IE1hdGgubWF4KDAsIHRocmVzaG9sZHMubWF4aW11bVplcm9SYXRlQW1vdW50IC0gaW5wdXQudGF4YWJsZUluY29tZUJlZm9yZUdhaW4pOwogICAgY29uc3QgemVyb1NsaWNlID0gTWF0aC5taW4ocmVtYWluaW5nLCB6ZXJvUm9vbSk7CiAgICByZW1haW5pbmcgLT0gemVyb1NsaWNlOwogICAgY29uc3QgaW5jb21lQWZ0ZXJaZXJvID0gaW5wdXQudGF4YWJsZUluY29tZUJlZm9yZUdhaW4gKyB6ZXJvU2xpY2U7CiAgICBjb25zdCBmaWZ0ZWVuUm9vbSA9IE1hdGgubWF4KDAsIHRocmVzaG9sZHMubWF4aW11bTE1UmF0ZUFtb3VudCAtIGluY29tZUFmdGVyWmVybyk7CiAgICBjb25zdCBmaWZ0ZWVuU2xpY2UgPSBNYXRoLm1pbihyZW1haW5pbmcsIGZpZnRlZW5Sb29tKTsKICAgIHRheCArPSBmaWZ0ZWVuU2xpY2UgKiAwLjE1OwogICAgcmVtYWluaW5nIC09IGZpZnRlZW5TbGljZTsKICAgIHRheCArPSByZW1haW5pbmcgKiAwLjIwOwogICAgcmV0dXJuIHsgdGF4QW1vdW50OiB0YXgsIHplcm9TbGljZSwgZmlmdGVlblNsaWNlLCB0d2VudHlTbGljZTogcmVtYWluaW5nIH07CiAgfQoKICBmdW5jdGlvbiBjYWxjdWxhdGVTaG9ydFRlcm1GZWRlcmFsVGF4SW1wYWN0KGlucHV0LCB0YXhhYmxlR2FpbikgewogICAgcmV0dXJuIGluY3JlbWVudGFsT3JkaW5hcnlUYXgoaW5wdXQudGF4YWJsZUluY29tZUJlZm9yZUdhaW4sIHRheGFibGVHYWluLCBEQVRBLm9yZGluYXJ5LmJyYWNrZXRzW2lucHV0LmZpbGluZ1N0YXR1c10pOwogIH0KCiAgZnVuY3Rpb24gY2FsY3VsYXRlTklJVChpbnB1dCwgdGF4YWJsZUdhaW4pIHsKICAgIGlmIChpbnB1dC5uaWl0T3ZlcnJpZGUgIT0gbnVsbCkgcmV0dXJuIHsgYW1vdW50OiBpbnB1dC5uaWl0T3ZlcnJpZGUsIG1hZ2lFc3RpbWF0ZWQ6IGZhbHNlLCBvdmVycmlkZGVuOiB0cnVlIH07CiAgICBjb25zdCBtYWdpQmVmb3JlID0gaW5wdXQubWFnaUJlZm9yZUdhaW4gPT0gbnVsbCA\/IGlucHV0LnRheGFibGVJbmNvbWVCZWZvcmVHYWluIDogaW5wdXQubWFnaUJlZm9yZUdhaW47CiAgICBjb25zdCBtYWdpQWZ0ZXIgPSBtYWdpQmVmb3JlICsgdGF4YWJsZUdhaW47CiAgICBjb25zdCB0aHJlc2hvbGQgPSBEQVRBLm5paXQudGhyZXNob2xkc1tpbnB1dC5maWxpbmdTdGF0dXNdOwogICAgY29uc3QgZXhjZXNzID0gTWF0aC5tYXgoMCwgbWFnaUFmdGVyIC0gdGhyZXNob2xkKTsKICAgIHJldHVybiB7IGFtb3VudDogTWF0aC5taW4odGF4YWJsZUdhaW4sIGV4Y2VzcykgKiBEQVRBLm5paXQucmF0ZSwgbWFnaUVzdGltYXRlZDogaW5wdXQubWFnaUJlZm9yZUdhaW4gPT0gbnVsbCwgb3ZlcnJpZGRlbjogZmFsc2UgfTsKICB9CgogIGZ1bmN0aW9uIGNhbGN1bGF0ZVN0YXRlSW5jcmVtZW50KGlucHV0LCB0YXhhYmxlR2Fpbiwgc3RhdGVEYXRhKSB7CiAgICBjb25zdCBiZWZvcmUgPSBNYXRoLm1heCgwLCAoaW5wdXQuc3RhdGVUYXhhYmxlSW5jb21lT3ZlcnJpZGUgPT0gbnVsbCA\/IGlucHV0LnRheGFibGVJbmNvbWVCZWZvcmVHYWluIDogaW5wdXQuc3RhdGVUYXhhYmxlSW5jb21lT3ZlcnJpZGUpIC0gKHN0YXRlRGF0YS5zdGFuZGFyZERlZHVjdGlvbiA\/IHN0YXRlRGF0YS5zdGFuZGFyZERlZHVjdGlvbltpbnB1dC5maWxpbmdTdGF0dXNdIHx8IDAgOiAwKSk7CiAgICBpZiAoc3RhdGVEYXRhLmZsYXRSYXRlICE9IG51bGwpIHJldHVybiB0YXhhYmxlR2FpbiAqIHN0YXRlRGF0YS5mbGF0UmF0ZTsKICAgIGlmIChzdGF0ZURhdGEuYnJhY2tldHMpIHJldHVybiBNYXRoLm1heCgwLCB0YXhGcm9tQnJhY2tldHMoYmVmb3JlICsgdGF4YWJsZUdhaW4sIHN0YXRlRGF0YS5icmFja2V0c1tpbnB1dC5maWxpbmdTdGF0dXNdKSAtIHRheEZyb21CcmFja2V0cyhiZWZvcmUsIHN0YXRlRGF0YS5icmFja2V0c1tpbnB1dC5maWxpbmdTdGF0dXNdKSk7CiAgICByZXR1cm4gMDsKICB9CgogIGZ1bmN0aW9uIGNhbGN1bGF0ZVN0YXRlQ2FwaXRhbEdhaW5zVGF4KGlucHV0LCB0YXhhYmxlR2FpbikgewogICAgY29uc3Qgc3RhdGVEYXRhID0gREFUQS5zdGF0ZXMuc3RhdGVzW2lucHV0LnN0YXRlT2ZSZXNpZGVuY2VdOwogICAgY29uc3Qgd2FybmluZ3MgPSBbXTsKICAgIGlmICghc3RhdGVEYXRhKSB7CiAgICAgIHJldHVybiB7IGFtb3VudDogMCwgc3VwcG9ydGVkOiBmYWxzZSwgbGFiZWw6ICJTdGF0ZSBjYXBpdGFsIGdhaW5zIGVzdGltYXRlIHVuYXZhaWxhYmxlIiwgd2FybmluZ3M6IFsiU3RhdGUgY2FwaXRhbCBnYWlucyBlc3RpbWF0ZSBpcyBub3QgeWV0IGF2YWlsYWJsZSBmb3IgdGhpcyBzdGF0ZS4iXSwgZGF0YU5vdGU6ICIiIH07CiAgICB9CiAgICBpZiAoaW5wdXQuc3RhdGVUYXhPdmVycmlkZSAhPSBudWxsKSB7CiAgICAgIHJldHVybiB7IGFtb3VudDogaW5wdXQuc3RhdGVUYXhPdmVycmlkZSwgc3VwcG9ydGVkOiB0cnVlLCBsYWJlbDogIk1hbnVhbCBzdGF0ZSB0YXggb3ZlcnJpZGUiLCB3YXJuaW5nczogWyJTdGF0ZSB0YXggb3ZlcnJpZGUgd2FzIG1hbnVhbGx5IGVudGVyZWQuIl0sIGRhdGFOb3RlOiBkYXRhTm90ZSgiU3RhdGUgZGF0YSIsIHN0YXRlRGF0YSkgfTsKICAgIH0KICAgIGlmIChzdGF0ZURhdGEuZGVmYXVsdENhcGl0YWxHYWluc1RyZWF0bWVudCA9PT0gIm5vX2Jyb2FkX2luZGl2aWR1YWxfaW5jb21lX3RheCIgJiYgc3RhdGVEYXRhLnN1cHBvcnRlZCkgewogICAgICByZXR1cm4geyBhbW91bnQ6IDAsIHN1cHBvcnRlZDogdHJ1ZSwgbGFiZWw6ICJFc3RpbWF0ZWQgc3RhdGUgY2FwaXRhbCBnYWlucyB0YXgiLCB3YXJuaW5nczogW3N0YXRlRGF0YS5ub3Rlc10sIGRhdGFOb3RlOiBkYXRhTm90ZShzdGF0ZURhdGEubmFtZSArICIgZGF0YSIsIHN0YXRlRGF0YSkgfTsKICAgIH0KICAgIGlmICghc3RhdGVEYXRhLnN1cHBvcnRlZCkgewogICAgICByZXR1cm4geyBhbW91bnQ6IDAsIHN1cHBvcnRlZDogZmFsc2UsIGxhYmVsOiAiU3RhdGUgY2FwaXRhbCBnYWlucyBlc3RpbWF0ZSB1bmF2YWlsYWJsZSIsIHdhcm5pbmdzOiBbc3RhdGVEYXRhLm5vdGVzIHx8ICJTdGF0ZSBjYXBpdGFsIGdhaW5zIGVzdGltYXRlIGlzIG5vdCB5ZXQgYXZhaWxhYmxlIGZvciB0aGlzIHN0YXRlLiJdLCBkYXRhTm90ZTogZGF0YU5vdGUoc3RhdGVEYXRhLm5hbWUgKyAiIGRhdGEiLCBzdGF0ZURhdGEpIH07CiAgICB9CiAgICB3YXJuaW5ncy5wdXNoKHN0YXRlRGF0YS5ub3RlcyB8fCAiU3RhdGUgY2FwaXRhbCBnYWlucyBjYWxjdWxhdGlvbiBpcyBzaW1wbGlmaWVkLiIpOwogICAgcmV0dXJuIHsgYW1vdW50OiBjYWxjdWxhdGVTdGF0ZUluY3JlbWVudChpbnB1dCwgdGF4YWJsZUdhaW4sIHN0YXRlRGF0YSksIHN1cHBvcnRlZDogdHJ1ZSwgbGFiZWw6ICJFc3RpbWF0ZWQgc3RhdGUgY2FwaXRhbCBnYWlucyB0YXgiLCB3YXJuaW5ncywgZGF0YU5vdGU6IGRhdGFOb3RlKHN0YXRlRGF0YS5uYW1lICsgIiBkYXRhIiwgc3RhdGVEYXRhKSB9OwogIH0KCiAgZnVuY3Rpb24gY2FsY3VsYXRlTG9jYWxUYXgoaW5wdXQsIHRheGFibGVHYWluKSB7CiAgICBpZiAoaW5wdXQuc3RhdGVPZlJlc2lkZW5jZSAhPT0gIk5ZIiB8fCAhaW5wdXQuaXNOWUNSZXNpZGVudCkgcmV0dXJuIHsgYW1vdW50OiAwLCBzdXBwb3J0ZWQ6IGZhbHNlLCB3YXJuaW5nczogW10sIGRhdGFOb3RlOiAiIiB9OwogICAgY29uc3QgbnljID0gREFUQS5sb2NhbC5qdXJpc2RpY3Rpb25zLk5ZQzsKICAgIGNvbnN0IGJlZm9yZSA9IGlucHV0LnRheGFibGVJbmNvbWVCZWZvcmVHYWluOwogICAgY29uc3QgYW1vdW50ID0gTWF0aC5tYXgoMCwgdGF4RnJvbUJyYWNrZXRzKGJlZm9yZSArIHRheGFibGVHYWluLCBueWMuYnJhY2tldHNbaW5wdXQuZmlsaW5nU3RhdHVzXSkgLSB0YXhGcm9tQnJhY2tldHMoYmVmb3JlLCBueWMuYnJhY2tldHNbaW5wdXQuZmlsaW5nU3RhdHVzXSkpOwogICAgcmV0dXJuIHsgYW1vdW50LCBzdXBwb3J0ZWQ6IHRydWUsIHdhcm5pbmdzOiBbbnljLm5vdGVzXSwgZGF0YU5vdGU6IGRhdGFOb3RlKCJOZXcgWW9yayBDaXR5IGRhdGEiLCBueWMpIH07CiAgfQoKICBmdW5jdGlvbiBjYWxjdWxhdGVBZnRlclRheFByb2NlZWRzKGlucHV0LCB0b3RhbEVzdGltYXRlZFRheCkgewogICAgcmV0dXJuIGlucHV0LnNhbGVQcmljZSAtIGlucHV0LnNlbGxpbmdFeHBlbnNlcyAtIHRvdGFsRXN0aW1hdGVkVGF4OwogIH0KCiAgZnVuY3Rpb24gZGF0YU5vdGUobGFiZWwsIHNvdXJjZSkgewogICAgaWYgKCFzb3VyY2UpIHJldHVybiAiIjsKICAgIHJldHVybiBsYWJlbCArICI6ICIgKyBzb3VyY2UuZGF0YVZpbnRhZ2UgKyAiLiBTb3VyY2U6ICIgKyBzb3VyY2Uuc291cmNlTmFtZSArICIuIExhc3QgdXBkYXRlZDogIiArIHNvdXJjZS5sYXN0VXBkYXRlZCArICIuIEFjY3VyYWN5IHN0YXR1czogIiArIHNvdXJjZS5hY2N1cmFjeVN0YXR1cyArICIuIjsKICB9CgogIGZ1bmN0aW9uIGNhbGN1bGF0ZUNhcGl0YWxHYWluc1NjZW5hcmlvKGlucHV0KSB7CiAgICBpbnB1dCA9IG5vcm1hbGl6ZUlucHV0cyhpbnB1dCB8fCB7fSk7CiAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGVJbnB1dHMoaW5wdXQpOwogICAgY29uc3QgZ2FpblByZXZpZXcgPSBjYWxjdWxhdGVUYXhhYmxlR2FpbihpbnB1dCk7CiAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMubGVuZ3RoICYmIGdhaW5QcmV2aWV3LnRheGFibGVHYWluIDw9IDApIHsKICAgICAgcmV0dXJuIHsKICAgICAgICB2YWxpZGF0aW9uRXJyb3JzOiBbIk5vIHRheGFibGUgZ2FpbiB3YXMgZXN0aW1hdGVkLiBZb3UgbWF5IGhhdmUgbm8gY2FwaXRhbCBnYWlucyB0YXggZm9yIHRoaXMgc2FsZSwgYnV0IG90aGVyIHRheCBydWxlcyBtYXkgc3RpbGwgYXBwbHkuIl0KICAgICAgfTsKICAgIH0KICAgIGlmICh2YWxpZGF0aW9uRXJyb3JzLmxlbmd0aCkgcmV0dXJuIHsgdmFsaWRhdGlvbkVycm9ycyB9OwoKICAgIGNvbnN0IGhvbGRpbmcgPSBkZXRlcm1pbmVIb2xkaW5nUGVyaW9kKGlucHV0KTsKICAgIGNvbnN0IGdhaW4gPSBnYWluUHJldmlldzsKICAgIGxldCBmZWRlcmFsQ2FwaXRhbEdhaW5zVGF4ID0gMDsKICAgIGxldCBmZWRlcmFsT3JkaW5hcnlJbmNvbWVUYXhPblNob3J0VGVybUdhaW4gPSAwOwogICAgbGV0IGNvbGxlY3RpYmxlc1RheCA9IDA7CiAgICBsZXQgZGVwcmVjaWF0aW9uUmVjYXB0dXJlVGF4ID0gMDsKICAgIGxldCBsdGNnRGV0YWlsID0gbnVsbDsKICAgIGNvbnN0IHdhcm5pbmdzID0gW107CgogICAgaWYgKGhvbGRpbmcub3ZlcnJpZGRlbikgd2FybmluZ3MucHVzaCgiSG9sZGluZyBwZXJpb2Qgd2FzIG1hbnVhbGx5IG92ZXJyaWRkZW4uIik7CiAgICBpZiAoaW5wdXQuY2FwaXRhbExvc3NlcyA+IDApIHdhcm5pbmdzLnB1c2goIkNhcGl0YWwgbG9zc2VzIHdlcmUgZW50ZXJlZCBtYW51YWxseS4iKTsKICAgIGlmIChpbnB1dC5hc3NldFR5cGUgPT09ICJjcnlwdG8iKSB3YXJuaW5ncy5wdXNoKCJDcnlwdG8gY2FsY3VsYXRpb24gaXMgbGltaXRlZCB0byBhIHNpbXBsaWZpZWQgc2luZ2xlLXNhbGUgZXN0aW1hdGUuIik7CiAgICBpZiAoZ2Fpbi5ob21lRXhjbHVzaW9uLndhcm5pbmcpIHdhcm5pbmdzLnB1c2goZ2Fpbi5ob21lRXhjbHVzaW9uLndhcm5pbmcpOwoKICAgIGxldCByZWd1bGFyVGF4YWJsZUdhaW4gPSBnYWluLnRheGFibGVHYWluOwogICAgaWYgKGlucHV0LmRlcHJlY2lhdGlvblJlY2FwdHVyZSA+IDApIHsKICAgICAgY29uc3QgcmVjYXB0dXJlQW1vdW50ID0gTWF0aC5taW4ocmVndWxhclRheGFibGVHYWluLCBpbnB1dC5kZXByZWNpYXRpb25SZWNhcHR1cmUpOwogICAgICBkZXByZWNpYXRpb25SZWNhcHR1cmVUYXggPSByZWNhcHR1cmVBbW91bnQgKiAwLjI1OwogICAgICByZWd1bGFyVGF4YWJsZUdhaW4gLT0gcmVjYXB0dXJlQW1vdW50OwogICAgICB3YXJuaW5ncy5wdXNoKCJEZXByZWNpYXRpb24gcmVjYXB0dXJlIGVzdGltYXRlIGlzIHNpbXBsaWZpZWQgYW5kIGRvZXMgbm90IHJlcGxhY2UgRm9ybSA0Nzk3IHRyZWF0bWVudC4iKTsKICAgIH0KCiAgICBpZiAoaG9sZGluZy5pc0xvbmdUZXJtKSB7CiAgICAgIGlmIChpbnB1dC5hc3NldFR5cGUgPT09ICJjb2xsZWN0aWJsZSIpIHsKICAgICAgICBjb2xsZWN0aWJsZXNUYXggPSBNYXRoLm1pbihjYWxjdWxhdGVTaG9ydFRlcm1GZWRlcmFsVGF4SW1wYWN0KGlucHV0LCByZWd1bGFyVGF4YWJsZUdhaW4pLCByZWd1bGFyVGF4YWJsZUdhaW4gKiAwLjI4KTsKICAgICAgICB3YXJuaW5ncy5wdXNoKCJDb2xsZWN0aWJsZXMgbWF5IGJlIHRheGVkIGRpZmZlcmVudGx5IGZyb20gb3JkaW5hcnkgbG9uZy10ZXJtIGNhcGl0YWwgZ2FpbnMuIFRoaXMgY2FsY3VsYXRvciB1c2VzIGEgc2ltcGxpZmllZCBlc3RpbWF0ZS4iKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsdGNnRGV0YWlsID0gY2FsY3VsYXRlTG9uZ1Rlcm1GZWRlcmFsQ2FwaXRhbEdhaW5zVGF4KGlucHV0LCByZWd1bGFyVGF4YWJsZUdhaW4pOwogICAgICAgIGZlZGVyYWxDYXBpdGFsR2FpbnNUYXggPSBsdGNnRGV0YWlsLnRheEFtb3VudDsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgZmVkZXJhbE9yZGluYXJ5SW5jb21lVGF4T25TaG9ydFRlcm1HYWluID0gY2FsY3VsYXRlU2hvcnRUZXJtRmVkZXJhbFRheEltcGFjdChpbnB1dCwgcmVndWxhclRheGFibGVHYWluKTsKICAgIH0KCiAgICBjb25zdCBuaWl0UmVzdWx0ID0gY2FsY3VsYXRlTklJVChpbnB1dCwgZ2Fpbi50YXhhYmxlR2Fpbik7CiAgICBpZiAobmlpdFJlc3VsdC5tYWdpRXN0aW1hdGVkKSB3YXJuaW5ncy5wdXNoKCJOSUlUIGRlcGVuZHMgb24gbW9kaWZpZWQgYWRqdXN0ZWQgZ3Jvc3MgaW5jb21lLiBCZWNhdXNlIHlvdSBkaWQgbm90IGVudGVyIE1BR0ksIHRoaXMgY2FsY3VsYXRvciBlc3RpbWF0ZXMgTUFHSSBmcm9tIG90aGVyIHRheGFibGUgaW5jb21lIHBsdXMgdGhpcyBzYWxlJ3MgdGF4YWJsZSBnYWluLiIpOwogICAgaWYgKG5paXRSZXN1bHQub3ZlcnJpZGRlbikgd2FybmluZ3MucHVzaCgiTklJVCB3YXMgbWFudWFsbHkgb3ZlcnJpZGRlbi4iKTsKCiAgICBjb25zdCBzdGF0ZVJlc3VsdCA9IGNhbGN1bGF0ZVN0YXRlQ2FwaXRhbEdhaW5zVGF4KGlucHV0LCBnYWluLnRheGFibGVHYWluKTsKICAgIGNvbnN0IGxvY2FsUmVzdWx0ID0gY2FsY3VsYXRlTG9jYWxUYXgoaW5wdXQsIGdhaW4udGF4YWJsZUdhaW4pOwogICAgd2FybmluZ3MucHVzaC5hcHBseSh3YXJuaW5ncywgc3RhdGVSZXN1bHQud2FybmluZ3MpOwogICAgd2FybmluZ3MucHVzaC5hcHBseSh3YXJuaW5ncywgbG9jYWxSZXN1bHQud2FybmluZ3MpOwoKICAgIGNvbnN0IHRvdGFsRXN0aW1hdGVkVGF4ID0gZmVkZXJhbENhcGl0YWxHYWluc1RheCArIGZlZGVyYWxPcmRpbmFyeUluY29tZVRheE9uU2hvcnRUZXJtR2FpbiArIGNvbGxlY3RpYmxlc1RheCArIGRlcHJlY2lhdGlvblJlY2FwdHVyZVRheCArIG5paXRSZXN1bHQuYW1vdW50ICsgc3RhdGVSZXN1bHQuYW1vdW50ICsgbG9jYWxSZXN1bHQuYW1vdW50OwogICAgY29uc3QgYWZ0ZXJUYXhQcm9jZWVkcyA9IGNhbGN1bGF0ZUFmdGVyVGF4UHJvY2VlZHMoaW5wdXQsIHRvdGFsRXN0aW1hdGVkVGF4KTsKICAgIGNvbnN0IGFmdGVyVGF4R2FpbiA9IGdhaW4udGF4YWJsZUdhaW4gLSB0b3RhbEVzdGltYXRlZFRheDsKICAgIGNvbnN0IGVmZmVjdGl2ZVRheFJhdGVPbkdhaW4gPSBnYWluLnRheGFibGVHYWluID4gMCA\/IHRvdGFsRXN0aW1hdGVkVGF4IC8gZ2Fpbi50YXhhYmxlR2FpbiA6IG51bGw7CgogICAgY29uc3QgZGF0YVZpbnRhZ2VOb3RlcyA9IFsKICAgICAgZGF0YU5vdGUoIkZlZGVyYWwgY2FwaXRhbCBnYWlucyBkYXRhIiwgREFUQS5sdGNnKSwKICAgICAgZGF0YU5vdGUoIkZlZGVyYWwgb3JkaW5hcnkgaW5jb21lIGRhdGEiLCBEQVRBLm9yZGluYXJ5KSwKICAgICAgZGF0YU5vdGUoIkZlZGVyYWwgTklJVCBkYXRhIiwgREFUQS5uaWl0KQogICAgXTsKICAgIGlmIChzdGF0ZVJlc3VsdC5kYXRhTm90ZSkgZGF0YVZpbnRhZ2VOb3Rlcy5wdXNoKHN0YXRlUmVzdWx0LmRhdGFOb3RlKTsKICAgIGlmIChsb2NhbFJlc3VsdC5kYXRhTm90ZSkgZGF0YVZpbnRhZ2VOb3Rlcy5wdXNoKGxvY2FsUmVzdWx0LmRhdGFOb3RlKTsKCiAgICBjb25zdCBoYXNTdGF0ZUxvY2FsRXN0aW1hdGUgPSBzdGF0ZVJlc3VsdC5zdXBwb3J0ZWQgfHwgbG9jYWxSZXN1bHQuc3VwcG9ydGVkOwogICAgY29uc3QgaGVhZGxpbmVSZXN1bHRzID0gWwogICAgICBbIkVzdGltYXRlZCB0b3RhbCB0YXgiLCBtb25leSh0b3RhbEVzdGltYXRlZFRheCldLAogICAgICBbaG9sZGluZy5pc0xvbmdUZXJtID8gIkZlZGVyYWwgY2FwaXRhbCBnYWlucyB0YXgiIDogIkZlZGVyYWwgb3JkaW5hcnkgaW5jb21lIHRheCBvbiBzaG9ydC10ZXJtIGdhaW4iLCBtb25leShmZWRlcmFsQ2FwaXRhbEdhaW5zVGF4ICsgZmVkZXJhbE9yZGluYXJ5SW5jb21lVGF4T25TaG9ydFRlcm1HYWluICsgY29sbGVjdGlibGVzVGF4ICsgZGVwcmVjaWF0aW9uUmVjYXB0dXJlVGF4KV0sCiAgICAgIFsiTmV0IEludmVzdG1lbnQgSW5jb21lIFRheCIsIG1vbmV5KG5paXRSZXN1bHQuYW1vdW50KV0sCiAgICAgIFsiU3RhdGUgYW5kIGxvY2FsIHRheCBlc3RpbWF0ZSIsIGhhc1N0YXRlTG9jYWxFc3RpbWF0ZSA\/IG1vbmV5KHN0YXRlUmVzdWx0LmFtb3VudCArIGxvY2FsUmVzdWx0LmFtb3VudCkgOiAiVW5hdmFpbGFibGUiXSwKICAgICAgWyJBZnRlci10YXggcHJvY2VlZHMiLCBtb25leShhZnRlclRheFByb2NlZWRzKV0sCiAgICAgIFsiRWZmZWN0aXZlIHRheCByYXRlIG9uIGdhaW4iLCBwZXJjZW50KGVmZmVjdGl2ZVRheFJhdGVPbkdhaW4pXQogICAgXTsKCiAgICBjb25zdCBkaXNwbGF5Um93cyA9IFsKICAgICAgWyJBc3NldCB0eXBlIiwgQVNTRVRfTEFCRUxTW2lucHV0LmFzc2V0VHlwZV1dLAogICAgICBbIkhvbGRpbmcgcGVyaW9kIGNsYXNzaWZpY2F0aW9uIiwgaG9sZGluZy5ob2xkaW5nUGVyaW9kXSwKICAgICAgWyJQdXJjaGFzZSBwcmljZSBvciBiYXNpcyIsIG1vbmV5KGdhaW4uYmFzaXMpXSwKICAgICAgWyJTYWxlIHByaWNlIiwgbW9uZXkoaW5wdXQuc2FsZVByaWNlKV0sCiAgICAgIFsiU2VsbGluZyBleHBlbnNlcyIsIG1vbmV5KGlucHV0LnNlbGxpbmdFeHBlbnNlcyldLAogICAgICBbIkdyb3NzIGdhaW4iLCBtb25leShnYWluLmdyb3NzR2FpbildLAogICAgICBbIk5ldCBnYWluIiwgbW9uZXkoZ2Fpbi5uZXRHYWluKV0sCiAgICAgIFsiSG9tZSBzYWxlIGV4Y2x1c2lvbiBhcHBsaWVkIiwgbW9uZXkoZ2Fpbi5ob21lRXhjbHVzaW9uLmFtb3VudCldLAogICAgICBbIkNhcGl0YWwgbG9zc2VzIGFwcGxpZWQiLCBtb25leShnYWluLmNhcGl0YWxMb3NzZXNBcHBsaWVkKV0sCiAgICAgIFsiVGF4YWJsZSBnYWluIiwgbW9uZXkoZ2Fpbi50YXhhYmxlR2FpbildLAogICAgICBbIkZlZGVyYWwgY2FwaXRhbCBnYWlucyB0YXgiLCBtb25leShmZWRlcmFsQ2FwaXRhbEdhaW5zVGF4KV0sCiAgICAgIFsiRmVkZXJhbCBvcmRpbmFyeSBpbmNvbWUgdGF4IG9uIHNob3J0LXRlcm0gZ2FpbiIsIG1vbmV5KGZlZGVyYWxPcmRpbmFyeUluY29tZVRheE9uU2hvcnRUZXJtR2FpbildLAogICAgICBbIkNvbGxlY3RpYmxlcyB0YXggZXN0aW1hdGUiLCBtb25leShjb2xsZWN0aWJsZXNUYXgpXSwKICAgICAgWyJEZXByZWNpYXRpb24gcmVjYXB0dXJlIGVzdGltYXRlIiwgbW9uZXkoZGVwcmVjaWF0aW9uUmVjYXB0dXJlVGF4KV0sCiAgICAgIFsiTmV0IEludmVzdG1lbnQgSW5jb21lIFRheCIsIG1vbmV5KG5paXRSZXN1bHQuYW1vdW50KV0sCiAgICAgIFtzdGF0ZVJlc3VsdC5sYWJlbCwgc3RhdGVSZXN1bHQuc3VwcG9ydGVkID8gbW9uZXkoc3RhdGVSZXN1bHQuYW1vdW50KSA6ICJVbmF2YWlsYWJsZSJdLAogICAgICBbIkxvY2FsIHRheCBlc3RpbWF0ZSIsIGxvY2FsUmVzdWx0LnN1cHBvcnRlZCA\/IG1vbmV5KGxvY2FsUmVzdWx0LmFtb3VudCkgOiAiTm90IGFwcGxpY2FibGUiXSwKICAgICAgWyJUb3RhbCBlc3RpbWF0ZWQgdGF4IiwgbW9uZXkodG90YWxFc3RpbWF0ZWRUYXgpXSwKICAgICAgWyJBZnRlci10YXggcHJvY2VlZHMiLCBtb25leShhZnRlclRheFByb2NlZWRzKV0sCiAgICAgIFsiQWZ0ZXItdGF4IGdhaW4iLCBtb25leShhZnRlclRheEdhaW4pXSwKICAgICAgWyJFZmZlY3RpdmUgdGF4IHJhdGUgb24gdGF4YWJsZSBnYWluIiwgcGVyY2VudChlZmZlY3RpdmVUYXhSYXRlT25HYWluKV0KICAgIF0uZmlsdGVyKGZ1bmN0aW9uIChyb3cpIHsKICAgICAgaWYgKC9Db2xsZWN0aWJsZXMvLnRlc3Qocm93WzBdKSAmJiBjb2xsZWN0aWJsZXNUYXggPT09IDApIHJldHVybiBmYWxzZTsKICAgICAgaWYgKC9EZXByZWNpYXRpb24vLnRlc3Qocm93WzBdKSAmJiBkZXByZWNpYXRpb25SZWNhcHR1cmVUYXggPT09IDApIHJldHVybiBmYWxzZTsKICAgICAgaWYgKC9Ib21lIHNhbGUvLnRlc3Qocm93WzBdKSAmJiBnYWluLmhvbWVFeGNsdXNpb24uYW1vdW50ID09PSAwKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICgvRmVkZXJhbCBjYXBpdGFsIGdhaW5zLy50ZXN0KHJvd1swXSkgJiYgZmVkZXJhbENhcGl0YWxHYWluc1RheCA9PT0gMCkgcmV0dXJuIGhvbGRpbmcuaXNMb25nVGVybSAmJiBpbnB1dC5hc3NldFR5cGUgIT09ICJjb2xsZWN0aWJsZSI7CiAgICAgIGlmICgvc2hvcnQtdGVybS8udGVzdChyb3dbMF0pICYmIGZlZGVyYWxPcmRpbmFyeUluY29tZVRheE9uU2hvcnRUZXJtR2FpbiA9PT0gMCkgcmV0dXJuICFob2xkaW5nLmlzTG9uZ1Rlcm07CiAgICAgIHJldHVybiB0cnVlOwogICAgfSk7CgogICAgcmV0dXJuIHsKICAgICAgdGF4WWVhcjogaW5wdXQudGF4WWVhciwKICAgICAgZmlsaW5nU3RhdHVzOiBpbnB1dC5maWxpbmdTdGF0dXMsCiAgICAgIGFzc2V0VHlwZTogaW5wdXQuYXNzZXRUeXBlLAogICAgICBwdXJjaGFzZVByaWNlOiBpbnB1dC5wdXJjaGFzZVByaWNlLAogICAgICBhZGp1c3RlZEJhc2lzOiBnYWluLmJhc2lzLAogICAgICBzYWxlUHJpY2U6IGlucHV0LnNhbGVQcmljZSwKICAgICAgc2VsbGluZ0V4cGVuc2VzOiBpbnB1dC5zZWxsaW5nRXhwZW5zZXMsCiAgICAgIGdyb3NzR2FpbjogZ2Fpbi5ncm9zc0dhaW4sCiAgICAgIG5ldEdhaW46IGdhaW4ubmV0R2FpbiwKICAgICAgY2FwaXRhbExvc3Nlc0FwcGxpZWQ6IGdhaW4uY2FwaXRhbExvc3Nlc0FwcGxpZWQsCiAgICAgIHRheGFibGVHYWluOiBnYWluLnRheGFibGVHYWluLAogICAgICBob2xkaW5nUGVyaW9kOiBob2xkaW5nLmhvbGRpbmdQZXJpb2QsCiAgICAgIGlzTG9uZ1Rlcm06IGhvbGRpbmcuaXNMb25nVGVybSwKICAgICAgZmVkZXJhbENhcGl0YWxHYWluc1RheCwKICAgICAgZmVkZXJhbE9yZGluYXJ5SW5jb21lVGF4T25TaG9ydFRlcm1HYWluLAogICAgICBjb2xsZWN0aWJsZXNUYXgsCiAgICAgIGRlcHJlY2lhdGlvblJlY2FwdHVyZVRheCwKICAgICAgbmlpdDogbmlpdFJlc3VsdC5hbW91bnQsCiAgICAgIHN0YXRlVGF4OiBzdGF0ZVJlc3VsdC5hbW91bnQsCiAgICAgIGxvY2FsVGF4OiBsb2NhbFJlc3VsdC5hbW91bnQsCiAgICAgIHRvdGFsRXN0aW1hdGVkVGF4LAogICAgICBhZnRlclRheFByb2NlZWRzLAogICAgICBhZnRlclRheEdhaW4sCiAgICAgIGVmZmVjdGl2ZVRheFJhdGVPbkdhaW4sCiAgICAgIHdhcm5pbmdzOiBBcnJheS5mcm9tKG5ldyBTZXQod2FybmluZ3MpKSwKICAgICAgZGF0YVZpbnRhZ2VOb3RlczogQXJyYXkuZnJvbShuZXcgU2V0KGRhdGFWaW50YWdlTm90ZXMuZmlsdGVyKEJvb2xlYW4pKSksCiAgICAgIGRpc3BsYXlSb3dzLAogICAgICBoZWFkbGluZVJlc3VsdHMsCiAgICAgIGx0Y2dEZXRhaWwsCiAgICAgIHZhbGlkYXRpb25FcnJvcnM6IFtdCiAgICB9OwogIH0KCiAgZnVuY3Rpb24gZXNjYXBlSHRtbCh2YWx1ZSkgewogICAgY29uc3QgYW1wID0gU3RyaW5nLmZyb21DaGFyQ29kZSgzOCk7CiAgICByZXR1cm4gU3RyaW5nKHZhbHVlKQogICAgICAucmVwbGFjZShuZXcgUmVnRXhwKFN0cmluZy5mcm9tQ2hhckNvZGUoNjApLCAiZyIpLCBhbXAgKyAibHQ7IikKICAgICAgLnJlcGxhY2UobmV3IFJlZ0V4cChTdHJpbmcuZnJvbUNoYXJDb2RlKDYyKSwgImciKSwgYW1wICsgImd0OyIpCiAgICAgIC5yZXBsYWNlKG5ldyBSZWdFeHAoU3RyaW5nLmZyb21DaGFyQ29kZSgzNCksICJnIiksIGFtcCArICJxdW90OyIpCiAgICAgIC5yZXBsYWNlKG5ldyBSZWdFeHAoU3RyaW5nLmZyb21DaGFyQ29kZSgzOSksICJnIiksIGFtcCArICIjMDM5OyIpOwogIH0KCiAgZnVuY3Rpb24gcmVuZGVyUmVzdWx0cyhyb290LCByZXN1bHQpIHsKICAgIGNvbnN0IHZhbGlkYXRpb25Cb3ggPSByb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXZhbGlkYXRpb24tbWVzc2FnZXNdIik7CiAgICB2YWxpZGF0aW9uQm94LmlubmVySFRNTCA9ICIiOwogICAgaWYgKHJlc3VsdC52YWxpZGF0aW9uRXJyb3JzICYmIHJlc3VsdC52YWxpZGF0aW9uRXJyb3JzLmxlbmd0aCkgewogICAgICB2YWxpZGF0aW9uQm94LmlubmVySFRNTCA9IHJlc3VsdC52YWxpZGF0aW9uRXJyb3JzLm1hcChmdW5jdGlvbiAoZXJyb3IpIHsKICAgICAgICByZXR1cm4gJzxkaXYgY2xhc3M9Iml0Yi1jYXBnYWlucy1lcnJvciI+JyArIGVzY2FwZUh0bWwoZXJyb3IpICsgIjwvZGl2PiI7CiAgICAgIH0pLmpvaW4oIiIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdCBlbXB0eSA9IHJvb3QucXVlcnlTZWxlY3RvcigiW2RhdGEtZW1wdHktcmVzdWx0c10iKTsKICAgIGNvbnN0IGNvbnRlbnQgPSByb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXJlc3VsdC1jb250ZW50XSIpOwogICAgY29uc3QgY29weWFibGUgPSByb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLWNvcHlhYmxlLXJlc3VsdHNdIik7CiAgICBlbXB0eS5jbGFzc0xpc3QuYWRkKCJpdGItY2FwZ2FpbnMtaGlkZGVuIik7CiAgICBjb250ZW50LmNsYXNzTGlzdC5yZW1vdmUoIml0Yi1jYXBnYWlucy1oaWRkZW4iKTsKICAgIGNvcHlhYmxlLmlubmVySFRNTCA9CiAgICAgIHJlc3VsdC5oZWFkbGluZVJlc3VsdHMubWFwKGZ1bmN0aW9uIChyb3cpIHsKICAgICAgICByZXR1cm4gJzxkaXYgY2xhc3M9Iml0Yi1jYXBnYWlucy1oZWFkbGluZSI+PHNwYW4+JyArIGVzY2FwZUh0bWwocm93WzBdKSArICI8L3NwYW4+PHN0cm9uZz4iICsgZXNjYXBlSHRtbChyb3dbMV0pICsgIjwvc3Ryb25nPjwvZGl2PiI7CiAgICAgIH0pLmpvaW4oIiIpICsKICAgICAgcmVzdWx0LmRpc3BsYXlSb3dzLm1hcChmdW5jdGlvbiAocm93KSB7CiAgICAgICAgcmV0dXJuICc8ZGl2IGNsYXNzPSJpdGItY2FwZ2FpbnMtcm93Ij48c3Bhbj4nICsgZXNjYXBlSHRtbChyb3dbMF0pICsgIjwvc3Bhbj48c3Ryb25nPiIgKyBlc2NhcGVIdG1sKHJvd1sxXSkgKyAiPC9zdHJvbmc+PC9kaXY+IjsKICAgICAgfSkuam9pbigiIikgKwogICAgICAnPGRpdiBjbGFzcz0iaXRiLWNhcGdhaW5zLXdhcm5pbmciPjxzdHJvbmc+V2FybmluZ3MgYW5kIGxpbWl0YXRpb25zPC9zdHJvbmc+JyArCiAgICAgIHJlc3VsdC53YXJuaW5ncy5tYXAoZnVuY3Rpb24gKHdhcm5pbmcpIHsgcmV0dXJuICI8cD4iICsgZXNjYXBlSHRtbCh3YXJuaW5nKSArICI8L3A+IjsgfSkuam9pbigiIikgKwogICAgICAiPC9kaXY+IiArCiAgICAgICc8ZGl2IGNsYXNzPSJpdGItY2FwZ2FpbnMtd2FybmluZyI+PHN0cm9uZz5EYXRhIG5vdGVzPC9zdHJvbmc+JyArCiAgICAgIHJlc3VsdC5kYXRhVmludGFnZU5vdGVzLm1hcChmdW5jdGlvbiAobm90ZSkgeyByZXR1cm4gIjxwPiIgKyBlc2NhcGVIdG1sKG5vdGUpICsgIjwvcD4iOyB9KS5qb2luKCIiKSArCiAgICAgICI8L2Rpdj4iOwogIH0KCiAgZnVuY3Rpb24gY29weVJlc3VsdHMocm9vdCkgewogICAgY29uc3Qgc3RhdHVzID0gcm9vdC5xdWVyeVNlbGVjdG9yKCJbZGF0YS1jb3B5LXN0YXR1c10iKTsKICAgIGlmIChyb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXJlc3VsdC1jb250ZW50XSIpLmNsYXNzTGlzdC5jb250YWlucygiaXRiLWNhcGdhaW5zLWhpZGRlbiIpKSB7CiAgICAgIHN0YXR1cy50ZXh0Q29udGVudCA9ICJQbGVhc2UgY2FsY3VsYXRlIHlvdXIgcmVzdWx0IGZpcnN0LiI7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IHRleHQgPSByb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLWNvcHlhYmxlLXJlc3VsdHNdIikuaW5uZXJUZXh0LnRyaW0oKTsKICAgIGlmICghbmF2aWdhdG9yLmNsaXBib2FyZCB8fCAhbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQpIHsKICAgICAgc3RhdHVzLnRleHRDb250ZW50ID0gIkNvcHkgaXMgdW5hdmFpbGFibGUgaW4gdGhpcyBicm93c2VyLiI7CiAgICAgIHJldHVybjsKICAgIH0KICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHRleHQpLnRoZW4oZnVuY3Rpb24gKCkgewogICAgICBzdGF0dXMudGV4dENvbnRlbnQgPSAiUmVzdWx0IHN1bW1hcnkgY29waWVkLiI7CiAgICB9KS5jYXRjaChmdW5jdGlvbiAoKSB7CiAgICAgIHN0YXR1cy50ZXh0Q29udGVudCA9ICJDb3B5IGZhaWxlZC4gU2VsZWN0IHRoZSByZXN1bHQgdGV4dCBhbmQgY29weSBpdCBtYW51YWxseS4iOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBwcmludFJlc3VsdHMoKSB7CiAgICB3aW5kb3cucHJpbnQoKTsKICB9CgogIGZ1bmN0aW9uIHNldFZpc2libGUoZWxlbWVudCwgdmlzaWJsZSkgewogICAgaWYgKCFlbGVtZW50KSByZXR1cm47CiAgICBlbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoIml0Yi1jYXBnYWlucy1oaWRkZW4iLCAhdmlzaWJsZSk7CiAgfQoKICBmdW5jdGlvbiB1cGRhdGVEaXNjbG9zdXJlKHJvb3QpIHsKICAgIGNvbnN0IGZvcm0gPSByb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLWNhcGdhaW5zLWZvcm1dIik7CiAgICBjb25zdCBhc3NldFR5cGUgPSBmaWVsZFZhbHVlKGZvcm0sICJhc3NldFR5cGUiKTsKICAgIGNvbnN0IHN0YXRlID0gZmllbGRWYWx1ZShmb3JtLCAic3RhdGVPZlJlc2lkZW5jZSIpOwogICAgc2V0VmlzaWJsZShyb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXByaW1hcnktcmVzaWRlbmNlLXNlY3Rpb25dIiksIGFzc2V0VHlwZSA9PT0gInByaW1hcnlfcmVzaWRlbmNlIik7CiAgICBzZXRWaXNpYmxlKHJvb3QucXVlcnlTZWxlY3RvcigiW2RhdGEtY3J5cHRvLXdhcm5pbmddIiksIGFzc2V0VHlwZSA9PT0gImNyeXB0byIpOwogICAgc2V0VmlzaWJsZShyb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXJlYWwtZXN0YXRlLXdhcm5pbmddIiksIGFzc2V0VHlwZSA9PT0gInJlYWxfZXN0YXRlIik7CiAgICBzZXRWaXNpYmxlKHJvb3QucXVlcnlTZWxlY3RvcigiW2RhdGEtbnljLXJlc2lkZW50LWZpZWxkXSIpLCBzdGF0ZSA9PT0gIk5ZIik7CiAgICBpZiAoc3RhdGUgIT09ICJOWSIpIHsKICAgICAgY29uc3QgbnljID0gZm9ybS5xdWVyeVNlbGVjdG9yKCdbZGF0YS1maWVsZD0iaXNOWUNSZXNpZGVudCJdJyk7CiAgICAgIGlmIChueWMpIG55Yy52YWx1ZSA9ICJubyI7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBwb3B1bGF0ZVN0YXRlT3B0aW9ucyhyb290KSB7CiAgICBjb25zdCBzZWxlY3QgPSByb290LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLWZpZWxkPSJzdGF0ZU9mUmVzaWRlbmNlIl0nKTsKICAgIGlmICghc2VsZWN0IHx8IHNlbGVjdC5vcHRpb25zLmxlbmd0aCkgcmV0dXJuOwogICAgY29uc3Qgc3RhdGVzID0gREFUQS5zdGF0ZXMuc3RhdGVzOwogICAgT2JqZWN0LmtleXMoc3RhdGVzKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7CiAgICAgIHJldHVybiBzdGF0ZXNbYV0ubmFtZS5sb2NhbGVDb21wYXJlKHN0YXRlc1tiXS5uYW1lKTsKICAgIH0pLmZvckVhY2goZnVuY3Rpb24gKGNvZGUpIHsKICAgICAgY29uc3Qgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgib3B0aW9uIik7CiAgICAgIG9wdGlvbi52YWx1ZSA9IGNvZGU7CiAgICAgIG9wdGlvbi50ZXh0Q29udGVudCA9IHN0YXRlc1tjb2RlXS5uYW1lOwogICAgICBpZiAoY29kZSA9PT0gIk5ZIikgb3B0aW9uLnNlbGVjdGVkID0gdHJ1ZTsKICAgICAgc2VsZWN0LmFwcGVuZENoaWxkKG9wdGlvbik7CiAgICB9KTsKICB9CgogIGZ1bmN0aW9uIHBvcHVsYXRlUmVsYXRlZFRvb2xzKHJvb3QpIHsKICAgIGNvbnN0IGxpc3QgPSByb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXJlbGF0ZWQtdG9vbHNdIik7CiAgICBpZiAoIWxpc3QpIHJldHVybjsKICAgIGxpc3QuaW5uZXJIVE1MID0gUkVMQVRFRF9UT09MUy5tYXAoZnVuY3Rpb24gKHRvb2wpIHsKICAgICAgaWYgKCF0b29sLnVybCkgcmV0dXJuICI8bGk+IiArIGVzY2FwZUh0bWwodG9vbC5sYWJlbCkgKyAodG9vbC5jb21pbmdTb29uID8gIiA8c3Bhbj5Db21pbmcgc29vbjwvc3Bhbj4iIDogIiIpICsgIjwvbGk+IjsKICAgICAgcmV0dXJuICc8bGk+PGEgaHJlZj0iJyArIGVzY2FwZUh0bWwodG9vbC51cmwpICsgJyI+JyArIGVzY2FwZUh0bWwodG9vbC5sYWJlbCkgKyAiPC9hPjwvbGk+IjsKICAgIH0pLmpvaW4oIiIpOwogIH0KCiAgZnVuY3Rpb24gaW5pdENhbGN1bGF0b3Iocm9vdCkgewogICAgaWYgKHJvb3QuZGF0YXNldC5pdGJDYXBnYWluc0luaXRpYWxpemVkID09PSAidHJ1ZSIpIHJldHVybjsKICAgIHJvb3QuZGF0YXNldC5pdGJDYXBnYWluc0luaXRpYWxpemVkID0gInRydWUiOwogICAgcG9wdWxhdGVTdGF0ZU9wdGlvbnMocm9vdCk7CiAgICBwb3B1bGF0ZVJlbGF0ZWRUb29scyhyb290KTsKICAgIGNvbnN0IGZvcm0gPSByb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLWNhcGdhaW5zLWZvcm1dIik7CiAgICB1cGRhdGVEaXNjbG9zdXJlKHJvb3QpOwogICAgZm9ybS5hZGRFdmVudExpc3RlbmVyKCJjaGFuZ2UiLCBmdW5jdGlvbiAoKSB7IHVwZGF0ZURpc2Nsb3N1cmUocm9vdCk7IH0pOwogICAgcm9vdC5xdWVyeVNlbGVjdG9yKCJbZGF0YS1hZHZhbmNlZC10b2dnbGVdIikuYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgY29uc3QgZXhwYW5kZWQgPSBldmVudC5jdXJyZW50VGFyZ2V0LmdldEF0dHJpYnV0ZSgiYXJpYS1leHBhbmRlZCIpID09PSAidHJ1ZSI7CiAgICAgIGV2ZW50LmN1cnJlbnRUYXJnZXQuc2V0QXR0cmlidXRlKCJhcmlhLWV4cGFuZGVkIiwgZXhwYW5kZWQgPyAiZmFsc2UiIDogInRydWUiKTsKICAgICAgcm9vdC5xdWVyeVNlbGVjdG9yKCJbZGF0YS1hZHZhbmNlZC1wYW5lbF0iKS5jbGFzc0xpc3QudG9nZ2xlKCJpdGItY2FwZ2FpbnMtaGlkZGVuIiwgZXhwYW5kZWQpOwogICAgfSk7CiAgICBmb3JtLmFkZEV2ZW50TGlzdGVuZXIoInN1Ym1pdCIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICByZW5kZXJSZXN1bHRzKHJvb3QsIGNhbGN1bGF0ZUNhcGl0YWxHYWluc1NjZW5hcmlvKGNvbGxlY3RJbnB1dChmb3JtKSkpOwogICAgfSk7CiAgICBmb3JtLmFkZEV2ZW50TGlzdGVuZXIoInJlc2V0IiwgZnVuY3Rpb24gKCkgewogICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICB1cGRhdGVEaXNjbG9zdXJlKHJvb3QpOwogICAgICAgIHJvb3QucXVlcnlTZWxlY3RvcigiW2RhdGEtcmVzdWx0LWNvbnRlbnRdIikuY2xhc3NMaXN0LmFkZCgiaXRiLWNhcGdhaW5zLWhpZGRlbiIpOwogICAgICAgIHJvb3QucXVlcnlTZWxlY3RvcigiW2RhdGEtZW1wdHktcmVzdWx0c10iKS5jbGFzc0xpc3QucmVtb3ZlKCJpdGItY2FwZ2FpbnMtaGlkZGVuIik7CiAgICAgICAgcm9vdC5xdWVyeVNlbGVjdG9yKCJbZGF0YS1jb3B5LXN0YXR1c10iKS50ZXh0Q29udGVudCA9ICIiOwogICAgICAgIHJvb3QucXVlcnlTZWxlY3RvcigiW2RhdGEtdmFsaWRhdGlvbi1tZXNzYWdlc10iKS5pbm5lckhUTUwgPSAiIjsKICAgICAgfSwgMCk7CiAgICB9KTsKICAgIHJvb3QucXVlcnlTZWxlY3RvcigiW2RhdGEtY29weS1yZXN1bHRzXSIpLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgZnVuY3Rpb24gKCkgeyBjb3B5UmVzdWx0cyhyb290KTsgfSk7CiAgICByb290LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXByaW50LXJlc3VsdHNdIikuYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCBwcmludFJlc3VsdHMpOwogIH0KCiAgZnVuY3Rpb24gaW5pdEFsbCgpIHsKICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIltkYXRhLWl0Yi1jYXBnYWlucy1jYWxjdWxhdG9yXSIpLmZvckVhY2goaW5pdENhbGN1bGF0b3IpOwogIH0KCiAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICJsb2FkaW5nIikgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigiRE9NQ29udGVudExvYWRlZCIsIGluaXRBbGwpOwogIGVsc2UgaW5pdEFsbCgpOwoKICB3aW5kb3cuSVRCQ2FwaXRhbEdhaW5zQ2FsY3VsYXRvciA9IHsKICAgIG5vcm1hbGl6ZUlucHV0cywKICAgIHZhbGlkYXRlSW5wdXRzLAogICAgZGV0ZXJtaW5lSG9sZGluZ1BlcmlvZCwKICAgIGNhbGN1bGF0ZUdyb3NzR2FpbiwKICAgIGNhbGN1bGF0ZVRheGFibGVHYWluLAogICAgY2FsY3VsYXRlTG9uZ1Rlcm1GZWRlcmFsQ2FwaXRhbEdhaW5zVGF4LAogICAgY2FsY3VsYXRlU2hvcnRUZXJtRmVkZXJhbFRheEltcGFjdCwKICAgIGNhbGN1bGF0ZU5JSVQsCiAgICBjYWxjdWxhdGVTdGF0ZUNhcGl0YWxHYWluc1RheCwKICAgIGNhbGN1bGF0ZUxvY2FsVGF4LAogICAgY2FsY3VsYXRlQWZ0ZXJUYXhQcm9jZWVkcywKICAgIGNhbGN1bGF0ZUNhcGl0YWxHYWluc1NjZW5hcmlvLAogICAgcmVuZGVyUmVzdWx0cywKICAgIGNvcHlSZXN1bHRzLAogICAgcHJpbnRSZXN1bHRzCiAgfTsKfSkoKTsK\"))();<\/script>\n<script type=\"application\/ld+json\">{\"@context\":\"https:\/\/schema.org\",\"@type\":\"SoftwareApplication\",\"name\":\"2026 Capital Gains Tax Calculator\",\"applicationCategory\":\"FinanceApplication\",\"operatingSystem\":\"Web\",\"description\":\"A browser-based planning calculator for estimating federal capital gains tax, Net Investment Income Tax, state tax, local tax where applicable, total estimated tax, and after-tax proceeds.\",\"offers\":{\"@type\":\"Offer\",\"price\":\"0\",\"priceCurrency\":\"USD\"}}<\/script>\n<script type=\"application\/ld+json\">{\"@context\":\"https:\/\/schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"What is capital gains tax?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Capital gains tax is tax on profit from selling an asset for more than its tax basis. Stocks, ETFs, mutual funds, crypto, real estate, collectibles, and other investments may create capital gains when sold.\"}},{\"@type\":\"Question\",\"name\":\"What is the difference between short-term and long-term capital gains?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Short-term capital gains generally apply to assets held for one year or less and are usually taxed like ordinary income. Long-term capital gains generally apply to assets held for more than one year and may qualify for lower federal tax rates.\"}},{\"@type\":\"Question\",\"name\":\"Does this calculator include state capital gains tax?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes, where state data is available. Many states tax capital gains as ordinary income, some states have no broad individual income tax, and some states have special capital gains rules. State results are labeled as simplified when appropriate.\"}},{\"@type\":\"Question\",\"name\":\"Does New York tax capital gains?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"New York generally taxes capital gains through its regular income tax system. New York City residents may also owe New York City resident income tax.\"}},{\"@type\":\"Question\",\"name\":\"Do states without income tax have capital gains tax?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"States without a broad individual income tax generally do not tax capital gains through a regular state income tax in this simplified model. Other taxes or special rules may still apply.\"}},{\"@type\":\"Question\",\"name\":\"Does this calculator include Net Investment Income Tax?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes. The calculator estimates the 3.8% Net Investment Income Tax when income appears to exceed the applicable threshold. If modified adjusted gross income is not entered, the NIIT result is simplified.\"}},{\"@type\":\"Question\",\"name\":\"Does this calculator handle home sale exclusions?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"It includes a simplified primary residence exclusion estimate for users who indicate they may qualify. The full home sale exclusion has detailed eligibility rules, so the result should not be treated as a tax return calculation.\"}},{\"@type\":\"Question\",\"name\":\"Does this calculator handle crypto gains?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes, basic crypto sales can be entered like other investment sales. The calculator estimates gain based on sale price, basis, expenses, holding period, and tax profile. It does not import exchange records or prepare Form 8949.\"}},{\"@type\":\"Question\",\"name\":\"Does this calculator handle collectibles?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"It includes a simplified collectibles estimate. Collectibles may be taxed differently from ordinary long-term capital gains, so users should confirm treatment before relying on the result.\"}},{\"@type\":\"Question\",\"name\":\"Why is this only an estimate?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Capital gains tax can depend on exact income, basis, holding period, losses, asset type, depreciation, exclusions, state law, local tax rules, and other facts. This calculator is a planning tool, not a tax return.\"}}]}<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Estimate federal capital gains tax, Net Investment Income Tax, state tax, local tax where applicable, total estimated tax, and after-tax proceeds.<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"class_list":["post-201","page","type-page","status-publish"],"_links":{"self":[{"href":"https:\/\/incometaxbill.com\/wp\/wp-json\/wp\/v2\/pages\/201","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/incometaxbill.com\/wp\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/incometaxbill.com\/wp\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/incometaxbill.com\/wp\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/incometaxbill.com\/wp\/wp-json\/wp\/v2\/comments?post=201"}],"version-history":[{"count":2,"href":"https:\/\/incometaxbill.com\/wp\/wp-json\/wp\/v2\/pages\/201\/revisions"}],"predecessor-version":[{"id":209,"href":"https:\/\/incometaxbill.com\/wp\/wp-json\/wp\/v2\/pages\/201\/revisions\/209"}],"wp:attachment":[{"href":"https:\/\/incometaxbill.com\/wp\/wp-json\/wp\/v2\/media?parent=201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}