세대원 중 한 명이라도 집이 있으면 무주택기간은 0점입니다. 소형·저가주택 예외는 공고문을 확인하세요.
만 30세부터 셉니다. 30세 전에 혼인했다면 혼인신고일부터. 집을 판 적이 있으면 마지막으로 처분한 날부터.
배우자, 같은 등본의 직계존속(3년 이상), 미혼 자녀(만 30세 이상은 1년 이상 같은 등본).
주택청약종합저축 가입일부터 입주자모집공고일까지.
배우자 가입 기간의 절반을 점수로 바꿔 최대 3점까지 더합니다(통장 점수 합계 17점 상한).
기간을 모르겠다면 — 날짜로 계산해서 넣기
내 점수로 당첨 가능했던 단지
청약홈에 당첨 가점이 공개된 최근 단지(2026.04 ~ 2026.09 발표, 76곳)의 주택형별 당첨 최저 가점(해당지역)과 비교합니다.
가점은 가점제 물량의 당첨선입니다. 추첨제 물량이 있는 주택형은 가점이 낮아도 당첨될 수 있고,
기타지역 신청자의 당첨선은 해당지역과 다릅니다. 줄을 누르면 그 단지의 분양가·경쟁률 페이지가 열립니다.
지역별 당첨 가점 커트라인
2026.04 ~ 2026.09 당첨자 발표 · 주택형별 당첨 최저 가점(해당지역)의 중앙값. 주택형이 적은 지역은 한두 단지에 크게 흔들립니다.
당첨 가점이 가장 높았던 단지
청약 가점, 이렇게 매깁니다 (84점 만점)
| 항목 | 기준 | 점수 |
| 무주택 기간 | 1년 미만 2점에서 1년마다 2점씩 · 15년 이상 만 30세 미만 미혼은 0점, 유주택자는 0점 | 최대 32점 |
| 부양가족 수 | 0명 5점에서 1명마다 5점씩 · 6명 이상 | 최대 35점 |
| 청약통장 가입 기간 | 6개월 미만 1점, 6개월~1년 2점, 1년 이상은 1년마다 1점씩 · 15년 이상
배우자 통장 기간의 절반을 점수로 바꿔 최대 3점 합산(합계 17점 상한) | 최대 17점 |
- 무주택 기간은 만 30세가 된 날부터 셉니다. 30세 전에 혼인신고를 했다면 그날부터입니다.
집을 가졌다가 처분했다면 처분한 날 이후부터 다시 셉니다. 세대원 모두가 무주택이어야 합니다.
- 부양가족은 같은 주민등록등본에 오른 사람만 셉니다. 배우자는 따로 살아도 인정되고,
부모·조부모(직계존속)는 3년 이상 같은 등본이어야 하며, 자녀는 미혼이어야 합니다(만 30세 이상 자녀는 1년 이상 같은 등본).
- 배우자 통장 합산은 2024년 3월 25일부터 시행됐습니다. 예를 들어 배우자가 30개월 가입했다면 절반인 15개월로 계산해 3점입니다.
- 모든 기간은 입주자모집공고일 기준입니다. 공고일 하루 차이로 1년 구간이 바뀔 수 있습니다.
가점이 낮아도 기회가 있는 경우
- 추첨제 물량 — 주택 면적과 규제지역 여부에 따라 일반공급 일부를 추첨으로 뽑습니다. 비율은 공고문에 나옵니다.
- 특별공급 — 신혼부부·생애최초·신생아·다자녀 등은 가점이 아니라 소득·자녀 수 등으로 뽑습니다.
- 무순위(줍줍) — 가점과 관계없이 추첨합니다. 지금 접수 중인 곳은 청약 일정에서 볼 수 있습니다.
출처: 한국부동산원 청약홈 청약접수 경쟁률·당첨 가점, 주택공급에 관한 규칙. 정확한 자격과 점수는
청약홈의 청약가점 계산기와 공고문으로 다시 확인하세요.
자주 묻는 질문
청약 가점 만점은 몇 점인가요?
84점입니다. 무주택 기간 32점, 부양가족 35점, 청약통장 가입 기간 17점을 더합니다.
만 30세 전에 결혼했으면 무주택 기간은 언제부터 세나요?
혼인신고일부터 셉니다. 미혼이면 만 30세가 된 날부터 셉니다. 만 30세 미만 미혼이면 무주택 기간은 0점입니다.
배우자 청약통장도 점수에 들어가나요?
2024년 3월 25일부터 배우자 통장 가입 기간의 절반을 점수로 바꿔 최대 3점까지 더할 수 있습니다. 본인과 배우자 통장 점수를 합쳐도 17점을 넘지 않습니다.
서울 아파트는 몇 점이면 당첨되나요?
단지와 주택형마다 다릅니다. 이 페이지의 ‘지역별 당첨 가점 커트라인’ 표에 최근 공개된 당첨 최저 가점의 중앙값과 범위를 정리해 두었습니다. 위에 점수를 넣으면 단지별로 바로 비교할 수 있습니다.
가점이 낮으면 당첨이 불가능한가요?
아닙니다. 추첨제 물량, 특별공급, 무순위 청약은 가점과 관계없이 뽑습니다. 공고문의 가점제·추첨제 비율을 확인하세요.
dmFyIEQ9SlNPTi5wYXJzZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndHBoLWRhdGExZjc2OGE2YmNkJykudGV4dENvbnRlbnQpOwp2YXIgVEhFTUVfSUNPPWZ1bmN0aW9uKHQpe3JldHVybiB0PT09J2RhcmsnPyc8c3ZnIGNsYXNzPSJ0cGgtaSBpY28tcyIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIxLjciIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgYXJpYS1oaWRkZW49InRydWUiPjxwYXRoIGQ9Ik0yMCAxNC41QTguNSA4LjUgMCAwIDEgOS41IDRhOC41IDguNSAwIDEgMCAxMC41IDEwLjV6Ii8+PC9zdmc+Jzp0PT09J2xpZ2h0Jz8nPHN2ZyBjbGFzcz0idHBoLWkgaWNvLXMiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMS43IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGFyaWEtaGlkZGVuPSJ0cnVlIj48cGF0aCBkPSJNMTIgNy41YTQuNSA0LjUgMCAxIDAgMCA5IDQuNSA0LjUgMCAwIDAgMC05ek0xMiAydjJNMTIgMjB2Mk00LjIgNC4ybDEuNCAxLjRNMTguNCAxOC40bDEuNCAxLjRNMiAxMmgyTTIwIDEyaDJNNC4yIDE5LjhsMS40LTEuNE0xOC40IDUuNmwxLjQtMS40Ii8+PC9zdmc+JzonPHN2ZyBjbGFzcz0idHBoLWkgaWNvLXMiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMS43IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGFyaWEtaGlkZGVuPSJ0cnVlIj48cGF0aCBkPSJNMTIgM2E5IDkgMCAxIDAgMCAxOCA5IDkgMCAwIDAgMC0xOHpNMTIgM3YxOGE5IDkgMCAwIDAgMC0xOHoiLz48L3N2Zz4nO307Cgp2YXIgJD1mdW5jdGlvbihpKXtyZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RwaC0nK2kpO307CnZhciB2PWZ1bmN0aW9uKGkpe3ZhciBlPSQoaSk7cmV0dXJuIGU/KCtlLnZhbHVlfHwwKTowO307CnZhciBzPWZ1bmN0aW9uKGkpe3ZhciBlPSQoaSk7cmV0dXJuIGU/ZS52YWx1ZTonJzt9Owp2YXIgZj1mdW5jdGlvbihuKXtyZXR1cm4gTWF0aC5yb3VuZChuKS50b0xvY2FsZVN0cmluZygna28tS1InKSsn7JuQJzt9Owp2YXIgZmQ9ZnVuY3Rpb24obixkKXtyZXR1cm4gbi50b0xvY2FsZVN0cmluZygna28tS1InLHttYXhpbXVtRnJhY3Rpb25EaWdpdHM6ZHx8MX0pO307CnZhciBjdXQxMD1mdW5jdGlvbih4KXtyZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJvdW5kKHgpLzEwKSoxMDt9Owp2YXIgc2V0PWZ1bmN0aW9uKGksdCl7dmFyIGU9JChpKTtpZighZSlyZXR1cm47aWYoaT09PSdtYWluJyl7Y291bnRVcChlLHQpO31lbHNle2UudGV4dENvbnRlbnQ9dDt9fTsKCi8qIOyViOyghO2VnCDsoIDsnqXshowg7KCR6re8IOKAlCDsi5ztgazrpr8g66qo65OcL+ywqOuLqCDtmZjqsr3sl5DshJzrj4Qg7KO97KeAIOyViuqyjCAqLwp2YXIgc3RvcmU9ewogIGdldDpmdW5jdGlvbihrKXt0cnl7cmV0dXJuIGxvY2FsU3RvcmFnZS5nZXRJdGVtKGspO31jYXRjaChlKXtyZXR1cm4gbnVsbDt9fSwKICBzZXQ6ZnVuY3Rpb24oayx2YWwpe3RyeXtsb2NhbFN0b3JhZ2Uuc2V0SXRlbShrLHZhbCk7fWNhdGNoKGUpe319LAogIGRlbDpmdW5jdGlvbihrKXt0cnl7bG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oayk7fWNhdGNoKGUpe319Cn07Cgp2YXIgdG9hc3Q9ZnVuY3Rpb24obXNnKXsKICB2YXIgdD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcudHBoLXRvYXN0Jyk7CiAgaWYoIXQpe3Q9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7dC5jbGFzc05hbWU9J3RwaC10b2FzdCc7ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0KTt9CiAgdC50ZXh0Q29udGVudD1tc2c7dC5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7CiAgY2xlYXJUaW1lb3V0KHQuX2gpO3QuX2g9c2V0VGltZW91dChmdW5jdGlvbigpe3QuY2xhc3NMaXN0LnJlbW92ZSgnc2hvdycpO30sMTkwMCk7Cn07CgovKiDthYzrp4gg7Yag6riAOiDsi5zsiqTthZwg7ISk7KCVIOKGkiDrnbzsnbTtirgg4oaSIOuLpO2BrCDsiJztmZggKi8KZnVuY3Rpb24gaW5pdFRoZW1lKHJvb3QpewogIHZhciBLPSd0cGgtdGhlbWUnLCBjdXI9c3RvcmUuZ2V0KEspOwogIGlmKGN1cikgcm9vdC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdGhlbWUnLGN1cik7CiAgdmFyIGI9JCgndGhlbWUnKTsKICBpZighYikgcmV0dXJuOwogIHZhciBsYWJlbD1mdW5jdGlvbigpewogICAgdmFyIHQ9cm9vdC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdGhlbWUnKTsKICAgIGIuaW5uZXJIVE1MPVRIRU1FX0lDTyh0KSsnIDxzcGFuPicrKHQ9PT0nZGFyayc/J+uLpO2BrCc6dD09PSdsaWdodCc/J+udvOydtO2KuCc6J+yekOuPmScpKyc8L3NwYW4+JzsKICB9OwogIGxhYmVsKCk7CiAgYi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsZnVuY3Rpb24oKXsKICAgIHZhciB0PXJvb3QuZ2V0QXR0cmlidXRlKCdkYXRhLXRoZW1lJyk7CiAgICB2YXIgbng9IXQ/J2xpZ2h0Jzp0PT09J2xpZ2h0Jz8nZGFyayc6Jyc7CiAgICBpZihueCl7cm9vdC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdGhlbWUnLG54KTtzdG9yZS5zZXQoSyxueCk7fQogICAgZWxzZXtyb290LnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS10aGVtZScpO3N0b3JlLmRlbChLKTt9CiAgICBsYWJlbCgpOwogIH0pOwp9CgovKiDsnoXroKXqsJIg4oaUIFVSTCDtjIzrnbzrr7jthLAg4oaUIGxvY2FsU3RvcmFnZSAqLwpmdW5jdGlvbiBpbml0U3RhdGUoc2x1ZywgaWRzLCBvbmNoYW5nZSl7CiAgdmFyIEtFWT0ndHBoLWluLScrc2x1ZywgcT1uZXcgVVJMU2VhcmNoUGFyYW1zKGxvY2F0aW9uLnNlYXJjaCksIHVzZWQ9ZmFsc2U7CiAgaWRzLmZvckVhY2goZnVuY3Rpb24oaSl7CiAgICB2YXIgZT0kKGkpOyBpZighZSkgcmV0dXJuOwogICAgaWYocS5oYXMoaSkpeyBlLnZhbHVlPXEuZ2V0KGkpOyB1c2VkPXRydWU7IH0KICB9KTsKICBpZighdXNlZCl7CiAgICB2YXIgcmF3PXN0b3JlLmdldChLRVkpOwogICAgaWYocmF3KXsgdHJ5eyB2YXIgbz1KU09OLnBhcnNlKHJhdyk7CiAgICAgIGlkcy5mb3JFYWNoKGZ1bmN0aW9uKGkpeyB2YXIgZT0kKGkpOyBpZihlJiZvW2ldIT09dW5kZWZpbmVkJiZvW2ldIT09JycpIGUudmFsdWU9b1tpXTsgfSk7CiAgICB9Y2F0Y2goZSl7fSB9CiAgfQogIHZhciBzYXZlPWZ1bmN0aW9uKCl7CiAgICB2YXIgbz17fTsgaWRzLmZvckVhY2goZnVuY3Rpb24oaSl7IHZhciBlPSQoaSk7IGlmKGUpIG9baV09ZS52YWx1ZTsgfSk7CiAgICBzdG9yZS5zZXQoS0VZLCBKU09OLnN0cmluZ2lmeShvKSk7CiAgfTsKICB2YXIgc2hhcmU9JCgnc2hhcmUnKTsKICBpZihzaGFyZSkgc2hhcmUuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLGZ1bmN0aW9uKCl7CiAgICB2YXIgcD1uZXcgVVJMU2VhcmNoUGFyYW1zKCk7CiAgICBpZHMuZm9yRWFjaChmdW5jdGlvbihpKXsgdmFyIGU9JChpKTsgaWYoZSkgcC5zZXQoaSxlLnZhbHVlKTsgfSk7CiAgICB2YXIgdXJsPWxvY2F0aW9uLm9yaWdpbitsb2NhdGlvbi5wYXRobmFtZSsnPycrcC50b1N0cmluZygpOwogICAgdmFyIGRvbmU9ZnVuY3Rpb24oKXt0b2FzdCgn66eB7YGs66W8IOuzteyCrO2WiOyKteuLiOuLpCcpO307CiAgICBpZihuYXZpZ2F0b3IuY2xpcGJvYXJkJiZuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dCl7CiAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHVybCkudGhlbihkb25lLGZ1bmN0aW9uKCl7cHJvbXB0KCfslYTrnpgg7KO87IaM66W8IOuzteyCrO2VmOyEuOyalCcsdXJsKTt9KTsKICAgIH0gZWxzZSBwcm9tcHQoJ+yVhOuemCDso7zshozrpbwg67O17IKs7ZWY7IS47JqUJyx1cmwpOwogIH0pOwogIHZhciBjb3B5PSQoJ2NvcHknKTsKICBpZihjb3B5KSBjb3B5LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJyxmdW5jdGlvbigpewogICAgdmFyIGxpbmVzPVtkb2N1bWVudC50aXRsZS5zcGxpdCgnfCcpWzBdLnRyaW0oKV07CiAgICBpZHMuZm9yRWFjaChmdW5jdGlvbihpKXsKICAgICAgdmFyIGU9JChpKTsgaWYoIWUpIHJldHVybjsKICAgICAgdmFyIGxhYj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdsYWJlbFtmb3I9dHBoLScraSsnXScpOwogICAgICB2YXIgdmFsPWUudGFnTmFtZT09PSdTRUxFQ1QnP2Uub3B0aW9uc1tlLnNlbGVjdGVkSW5kZXhdLnRleHQ6KCtlLnZhbHVlfHwwKS50b0xvY2FsZVN0cmluZygna28tS1InKTsKICAgICAgaWYobGFiKSBsaW5lcy5wdXNoKCfCtyAnK2xhYi50ZXh0Q29udGVudC50cmltKCkrJzogJyt2YWwpOwogICAgfSk7CiAgICBsaW5lcy5wdXNoKCcnKTsKICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy50cGgtdG90YWwnKS5mb3JFYWNoKGZ1bmN0aW9uKHQpewogICAgICB2YXIgbD10LnF1ZXJ5U2VsZWN0b3IoJy5sJyksIHZhbD10LnF1ZXJ5U2VsZWN0b3IoJy52Jyk7CiAgICAgIGlmKGwmJnZhbCkgbGluZXMucHVzaChsLnRleHRDb250ZW50LnRyaW0oKSsnOiAnK3ZhbC50ZXh0Q29udGVudC50cmltKCkpOwogICAgfSk7CiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudHBoLXBhZ2UgdGFibGUnKS5mb3JFYWNoKGZ1bmN0aW9uKHRiKXsKICAgICAgdGIucXVlcnlTZWxlY3RvckFsbCgndHInKS5mb3JFYWNoKGZ1bmN0aW9uKHRyKXsKICAgICAgICB2YXIgdGQ9dHIucXVlcnlTZWxlY3RvckFsbCgndGQnKTsKICAgICAgICBpZih0ZC5sZW5ndGg9PT0yKSBsaW5lcy5wdXNoKCfCtyAnK3RkWzBdLnRleHRDb250ZW50LnRyaW0oKSsnOiAnK3RkWzFdLnRleHRDb250ZW50LnRyaW0oKSk7CiAgICAgIH0pOwogICAgfSk7CiAgICBsaW5lcy5wdXNoKCcnLCBsb2NhdGlvbi5vcmlnaW4rbG9jYXRpb24ucGF0aG5hbWUpOwogICAgdmFyIHR4dD1saW5lcy5qb2luKCdcbicpOwogICAgdmFyIGRvbmU9ZnVuY3Rpb24oKXt0b2FzdCgn6rKw6rO866W8IOuzteyCrO2WiOyKteuLiOuLpCcpO307CiAgICBpZihuYXZpZ2F0b3IuY2xpcGJvYXJkJiZuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dCkgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQodHh0KS50aGVuKGRvbmUsZG9uZSk7CiAgICBlbHNlIHsgdmFyIHRhPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7IHRhLnZhbHVlPXR4dDsgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0YSk7CiAgICAgICAgICAgdGEuc2VsZWN0KCk7IHRyeXtkb2N1bWVudC5leGVjQ29tbWFuZCgnY29weScpO31jYXRjaChlKXt9IHRhLnJlbW92ZSgpOyBkb25lKCk7IH0KICB9KTsKICB2YXIgcmVzZXQ9JCgncmVzZXQnKTsKICBpZihyZXNldCkgcmVzZXQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLGZ1bmN0aW9uKCl7CiAgICBzdG9yZS5kZWwoS0VZKTsgbG9jYXRpb24uaHJlZj1sb2NhdGlvbi5wYXRobmFtZTsKICB9KTsKICByZXR1cm4gc2F2ZTsKfQoKLyog6riI7JWhIOyeheugpSDrsJEg67mg66W4IOyhsOyglSDsuakgKi8KZnVuY3Rpb24gaW5pdENoaXBzKG9uY2hhbmdlKXsKICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudHBoLWNoaXAnKS5mb3JFYWNoKGZ1bmN0aW9uKGMpewogICAgYy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsZnVuY3Rpb24oKXsKICAgICAgdmFyIGU9JChjLmRhdGFzZXQudCk7IGlmKCFlKSByZXR1cm47CiAgICAgIHZhciBkPWMuZGF0YXNldC5kOwogICAgICBlLnZhbHVlID0gZD09PScwJyA/IDAgOiBNYXRoLm1heCgwLCgrZS52YWx1ZXx8MCkrKCtkKSk7CiAgICAgIG9uY2hhbmdlKCk7CiAgICB9KTsKICB9KTsKfQoKLyog7J6F66Cl6rCS7J2EIOyCrOuejOydtCDsnb3ripQg66y47J6l7Jy866GcICgzLDAwMCwwMDAg4oaSIDMwMOunjOybkCkgKi8KZnVuY3Rpb24ga29yTW9uZXkobil7CiAgbj1NYXRoLnJvdW5kKG4pOyBpZighbikgcmV0dXJuICcw7JuQJzsKICB2YXIgZW9rPU1hdGguZmxvb3Iobi8xMDAwMDAwMDApLCBtYW49TWF0aC5mbG9vcigobiUxMDAwMDAwMDApLzEwMDAwKSwgd29uPW4lMTAwMDAsIHA9W107CiAgaWYoZW9rKSBwLnB1c2goZW9rKyfslrUnKTsKICBpZihtYW4pIHAucHVzaChtYW4udG9Mb2NhbGVTdHJpbmcoJ2tvLUtSJykrJ+unjCcpOwogIGlmKHdvbikgcC5wdXNoKHdvbi50b0xvY2FsZVN0cmluZygna28tS1InKSk7CiAgcmV0dXJuIHAuam9pbignICcpKyfsm5AnOwp9CmZ1bmN0aW9uIGluaXRSZWFkKG1hcCl7CiAgT2JqZWN0LmtleXMobWFwKS5mb3JFYWNoKGZ1bmN0aW9uKGlkKXsKICAgIHZhciBlPSQoaWQpLCBvdXQ9JChtYXBbaWRdKTsgaWYoIWV8fCFvdXQpIHJldHVybjsKICAgIHZhciB1cGQ9ZnVuY3Rpb24oKXsgb3V0LnRleHRDb250ZW50ID0gKCtlLnZhbHVlPjApID8ga29yTW9uZXkoK2UudmFsdWUpIDogJyc7IH07CiAgICBlLmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0Jyx1cGQpOyB1cGQoKTsKICB9KTsKfQoKCi8qIOyIq+yekCDsubTsmrTtirjsl4Ug4oCUIOqysOqzvOqwgCDrsJTrgJQg65WMIOu2gOuTnOufveqyjCAqLwpmdW5jdGlvbiBjb3VudFVwKGVsLCB0ZXh0KXsKICBpZighZWwpIHJldHVybjsKICB2YXIgcHJldj1lbC5fcmF3fHwnJywgY3VyPXRleHQ7CiAgZWwuX3Jhdz1jdXI7CiAgdmFyIHBuPXBhcnNlRmxvYXQoU3RyaW5nKHByZXYpLnJlcGxhY2UoL1teMC05Li1dL2csJycpKTsKICB2YXIgY249cGFyc2VGbG9hdChTdHJpbmcoY3VyKS5yZXBsYWNlKC9bXjAtOS4tXS9nLCcnKSk7CiAgdmFyIHJlZHVjZT13aW5kb3cubWF0Y2hNZWRpYSYmd2luZG93Lm1hdGNoTWVkaWEoJyhwcmVmZXJzLXJlZHVjZWQtbW90aW9uOiByZWR1Y2UpJykubWF0Y2hlczsKICBpZihyZWR1Y2V8fCFpc0Zpbml0ZShwbil8fCFpc0Zpbml0ZShjbil8fHBuPT09Y258fE1hdGguYWJzKGNuLXBuKTwxKXtlbC50ZXh0Q29udGVudD1jdXI7cmV0dXJuO30KICB2YXIgcHJlPWN1ci5zbGljZSgwLGN1ci5zZWFyY2goL1swLTktXS8pKTsKICB2YXIgcG9zdD1jdXIuc2xpY2UoY3VyLnNlYXJjaCgvWzAtOV1bXjAtOV0qJC8pKzEpLnJlcGxhY2UoL15bMC05XS8sJycpOwogIHZhciBzdWZmaXg9Y3VyLnJlcGxhY2UoL15bXjAtOS1dKi8sJycpLnJlcGxhY2UoL15bMC05LC5cLV0rLywnJyk7CiAgdmFyIHQwPW51bGwsIGR1cj0zODA7CiAgY2FuY2VsQW5pbWF0aW9uRnJhbWUoZWwuX2FmfHwwKTsKICBmdW5jdGlvbiBzdGVwKHQpewogICAgaWYoIXQwKSB0MD10OwogICAgdmFyIGs9TWF0aC5taW4oMSwodC10MCkvZHVyKSwgZT0xLU1hdGgucG93KDEtaywzKTsKICAgIHZhciB2YWw9cG4rKGNuLXBuKSplOwogICAgZWwudGV4dENvbnRlbnQ9cHJlK01hdGgucm91bmQodmFsKS50b0xvY2FsZVN0cmluZygna28tS1InKStzdWZmaXg7CiAgICBpZihrPDEpIGVsLl9hZj1yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoc3RlcCk7IGVsc2UgZWwudGV4dENvbnRlbnQ9Y3VyOwogIH0KICBlbC5fYWY9cmVxdWVzdEFuaW1hdGlvbkZyYW1lKHN0ZXApOwp9CgovKiDrqqjrsJTsnbwg6rOg7KCVIOqysOqzvOuwlCArIOunqCDsnITroZwgKi8KZnVuY3Rpb24gaW5pdFN0aWNreShyb290LCBsYWJlbCl7CiAgaWYoIXJvb3QpIHJldHVybjsKICB2YXIgbWFpbj0kKCdtYWluJyk7IGlmKCFtYWluKSByZXR1cm47CiAgdmFyIGJhcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICBiYXIuY2xhc3NOYW1lPSd0cGgtc3RpY2t5JzsKICBiYXIuaW5uZXJIVE1MPSc8ZGl2IGNsYXNzPSJsIj4nK2xhYmVsKyc8L2Rpdj48ZGl2IGNsYXNzPSJ2IiBpZD0idHBoLXN0aWNreXYiPuKApjwvZGl2Pic7CiAgcm9vdC5hcHBlbmRDaGlsZChiYXIpOwogIHZhciB0b3A9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7CiAgdG9wLnR5cGU9J2J1dHRvbic7IHRvcC5jbGFzc05hbWU9J3RwaC10b3AnOyB0b3Auc2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsJywn66eoIOychOuhnCcpOwogIHRvcC5pbm5lckhUTUw9Jzxzdmcgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTIgMTlWNSIvPjxwYXRoIGQ9Ik01IDEybDctNyA3IDciLz48L3N2Zz4nOwogIHRvcC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsZnVuY3Rpb24oKXt3aW5kb3cuc2Nyb2xsVG8oe3RvcDowLGJlaGF2aW9yOidzbW9vdGgnfSk7fSk7CiAgcm9vdC5hcHBlbmRDaGlsZCh0b3ApOwogIHZhciBzdj1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndHBoLXN0aWNreXYnKTsKICB2YXIgc3luYz1mdW5jdGlvbigpewogICAgaWYoc3YmJnN2LnRleHRDb250ZW50IT09bWFpbi50ZXh0Q29udGVudCkgc3YudGV4dENvbnRlbnQ9bWFpbi50ZXh0Q29udGVudDsKICAgIHZhciByPW1haW4uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CiAgICBiYXIuY2xhc3NMaXN0LnRvZ2dsZSgnb24nLCByLmJvdHRvbTw1Nik7CiAgICB0b3AuY2xhc3NMaXN0LnRvZ2dsZSgnb24nLCB3aW5kb3cuc2Nyb2xsWT41MDApOwogIH07CiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsc3luYyx7cGFzc2l2ZTp0cnVlfSk7CiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsc3luYyk7CiAgaWYod2luZG93Lk11dGF0aW9uT2JzZXJ2ZXIpIG5ldyBNdXRhdGlvbk9ic2VydmVyKHN5bmMpLm9ic2VydmUobWFpbix7Y2hpbGRMaXN0OnRydWUsY2hhcmFjdGVyRGF0YTp0cnVlLHN1YnRyZWU6dHJ1ZX0pOwogIHN5bmMoKTsKfQoKLyog4pSA4pSAIOywqO2KuCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAg7IOJ7J2AIENTUyDrs4DsiJggLS1zMS8tLXMyLy0tczMgKOqygOymneuQnCDsubTthYzqs6Drpqwg7YyU66CI7Yq4KS4KICAg6rOE7Je07J20IDLqsJwg7J207IOB7J2066m0IOuylOuhgOulvCDtla3sg4Eg67aZ7J206rOgLCDqsJLsnYAg7ZGc7JeQ64+EIOq3uOuMgOuhnCDsnojri6QuICovCnZhciBTVkdOUz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnOwpmdW5jdGlvbiBlbCh0LGEpe3ZhciBlPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdOUyx0KTtmb3IodmFyIGsgaW4gYSllLnNldEF0dHJpYnV0ZShrLGFba10pO3JldHVybiBlO30KCmZ1bmN0aW9uIHRpcChib3gpewogIHZhciB0PWJveC5xdWVyeVNlbGVjdG9yKCcudHBoLXRpcCcpOwogIGlmKCF0KXt0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO3QuY2xhc3NOYW1lPSd0cGgtdGlwJztib3guYXBwZW5kQ2hpbGQodCk7fQogIHJldHVybiB0Owp9CmZ1bmN0aW9uIHNob3dUaXAoYm94LHgseSxodG1sKXsKICB2YXIgdD10aXAoYm94KTsgdC5pbm5lckhUTUw9aHRtbDsgdC5zdHlsZS5vcGFjaXR5PScxJzsKICB2YXIgdz10Lm9mZnNldFdpZHRoLCBidz1ib3guY2xpZW50V2lkdGg7CiAgdC5zdHlsZS5sZWZ0PU1hdGgubWF4KDQsTWF0aC5taW4oYnctdy00LHgtdy8yKSkrJ3B4JzsKICB0LnN0eWxlLnRvcD1NYXRoLm1heCgyLHktdC5vZmZzZXRIZWlnaHQtMTApKydweCc7Cn0KZnVuY3Rpb24gaGlkZVRpcChib3gpe3ZhciB0PWJveC5xdWVyeVNlbGVjdG9yKCcudHBoLXRpcCcpO2lmKHQpdC5zdHlsZS5vcGFjaXR5PScwJzt9CgovKiDshLjroZwg64iE7KCBIOunieuMgCDigJQgY2F0czpb652867KoXSwgc2VyaWVzOlt7bmFtZSxjbHMsZGF0YTpbXX1dICovCmZ1bmN0aW9uIHN0YWNrQ2hhcnQoYm94SWQsIGNhdHMsIHNlcmllcywgZm10KXsKICB2YXIgYm94PSQoYm94SWQpOyBpZighYm94KSByZXR1cm47CiAgYm94LnF1ZXJ5U2VsZWN0b3JBbGwoJ3N2ZywudHBoLWxlZ2VuZCcpLmZvckVhY2goZnVuY3Rpb24obil7bi5yZW1vdmUoKTt9KTsKICB2YXIgVz02NjAsSD0yMzYsUEw9OCxQUj04LFBUPTE0LFBCPTI2OwogIHZhciBuPWNhdHMubGVuZ3RoOyBpZighbikgcmV0dXJuOwogIHZhciB0b3RhbHM9Y2F0cy5tYXAoZnVuY3Rpb24oXyxpKXtyZXR1cm4gc2VyaWVzLnJlZHVjZShmdW5jdGlvbihhLHMpe3JldHVybiBhKyhzLmRhdGFbaV18fDApO30sMCk7fSk7CiAgdmFyIG1heD1NYXRoLm1heC5hcHBseShudWxsLHRvdGFscyl8fDE7CiAgdmFyIGl3PVctUEwtUFIsIGloPUgtUFQtUEI7CiAgdmFyIGJ3PU1hdGgubWF4KDYsTWF0aC5taW4oNDYsaXcvbiowLjY4KSksIHN0ZXA9aXcvbjsKICB2YXIgc3ZnPWVsKCdzdmcnLHt2aWV3Qm94OicwIDAgJytXKycgJytILHJvbGU6J2ltZyd9KTsKICBmb3IodmFyIGc9MDtnPD0zO2crKyl7CiAgICB2YXIgZ3k9UFQraWgqZy8zOwogICAgc3ZnLmFwcGVuZENoaWxkKGVsKCdsaW5lJyx7eDE6UEwseTE6Z3kseDI6Vy1QUix5MjpneSwnY2xhc3MnOidnbCd9KSk7CiAgfQogIGNhdHMuZm9yRWFjaChmdW5jdGlvbihjLGkpewogICAgdmFyIGN4PVBMK3N0ZXAqaStzdGVwLzIsIHk9UFQraWgsIGFjYz0wOwogICAgc2VyaWVzLmZvckVhY2goZnVuY3Rpb24ocyxzaSl7CiAgICAgIHZhciB2YWw9cy5kYXRhW2ldfHwwOyBpZih2YWw8PTApIHJldHVybjsKICAgICAgdmFyIGg9dmFsL21heCppaDsgeS09aDsgYWNjKz12YWw7CiAgICAgIHZhciBpc1RvcCA9IHNpPT09c2VyaWVzLmxlbmd0aC0xIHx8ICFzZXJpZXMuc2xpY2Uoc2krMSkuc29tZShmdW5jdGlvbih6KXtyZXR1cm4gKHouZGF0YVtpXXx8MCk+MDt9KTsKICAgICAgdmFyIHI9ZWwoJ3JlY3QnLHt4OmN4LWJ3LzIseTp5LHdpZHRoOmJ3LGhlaWdodDpNYXRoLm1heCgxLGgpLCdjbGFzcyc6cy5jbHMsCiAgICAgICAgICAgICAgICAgICAgICAgcng6aXNUb3A/NDowLHJ5OmlzVG9wPzQ6MH0pOwogICAgICBzdmcuYXBwZW5kQ2hpbGQocik7CiAgICB9KTsKICAgIHZhciBoaXQ9ZWwoJ3JlY3QnLHt4OmN4LXN0ZXAvMisxLHk6UFQsd2lkdGg6c3RlcC0yLGhlaWdodDppaCwnY2xhc3MnOidoaXQnfSk7CiAgICBoaXQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJyxmdW5jdGlvbihldil7CiAgICAgIHZhciBicj1ib3guZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CiAgICAgIHZhciByb3dzPXNlcmllcy5tYXAoZnVuY3Rpb24ocyl7CiAgICAgICAgcmV0dXJuICc8c3BhbiBzdHlsZT0iZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6OHB4O2hlaWdodDo4cHg7Ym9yZGVyLXJhZGl1czoycHg7JwogICAgICAgICAgICAgKyAnYmFja2dyb3VuZDp2YXIoLS0nK3MuY2xzKycpO21hcmdpbi1yaWdodDo2cHgiPjwvc3Bhbj4nK3MubmFtZSsnICcrZm10KHMuZGF0YVtpXXx8MCk7CiAgICAgIH0pLmpvaW4oJzxicj4nKTsKICAgICAgc2hvd1RpcChib3gsZXYuY2xpZW50WC1ici5sZWZ0LGV2LmNsaWVudFktYnIudG9wLAogICAgICAgICAgICAgICc8Yj4nK2MrJzwvYj48YnI+Jytyb3dzKyc8YnI+7ZWp6rOEICcrZm10KGFjYykpOwogICAgfSk7CiAgICBoaXQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsZnVuY3Rpb24oKXtoaWRlVGlwKGJveCk7fSk7CiAgICBzdmcuYXBwZW5kQ2hpbGQoaGl0KTsKICAgIGlmKG48PTE0fHxpJU1hdGguY2VpbChuLzEyKT09PTApCiAgICAgIHN2Zy5hcHBlbmRDaGlsZChPYmplY3QuYXNzaWduKGVsKCd0ZXh0Jyx7eDpjeCx5OkgtOCwnY2xhc3MnOidsYicsJ3RleHQtYW5jaG9yJzonbWlkZGxlJ30pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dGV4dENvbnRlbnQ6Y30pKTsKICB9KTsKICBib3guYXBwZW5kQ2hpbGQoc3ZnKTsKICBib3guYXBwZW5kQ2hpbGQobGVnZW5kKHNlcmllcykpOwp9CgovKiDqsIDroZwg64iE7KCBIOunieuMgCjqtazshLEpIOKAlCBzZWdzOlt7bmFtZSxjbHMsdmFsdWV9XSDCtyDsp4HsoJEg652867KoICovCmZ1bmN0aW9uIGhTdGFjayhib3hJZCwgc2VncywgZm10KXsKICB2YXIgYm94PSQoYm94SWQpOyBpZighYm94KSByZXR1cm47CiAgYm94LnF1ZXJ5U2VsZWN0b3JBbGwoJ3N2ZywudHBoLWxlZ2VuZCcpLmZvckVhY2goZnVuY3Rpb24obil7bi5yZW1vdmUoKTt9KTsKICB2YXIgdG90YWw9c2Vncy5yZWR1Y2UoZnVuY3Rpb24oYSxzKXtyZXR1cm4gYStNYXRoLm1heCgwLHMudmFsdWUpO30sMCl8fDE7CiAgdmFyIFc9NjYwLEg9NjQsUEw9OCxQUj04LEJIPTM0LFRZPTEyOwogIHZhciBzdmc9ZWwoJ3N2Zycse3ZpZXdCb3g6JzAgMCAnK1crJyAnK0gscm9sZTonaW1nJ30pOwogIHZhciB4PVBMLCBpdz1XLVBMLVBSOwogIHNlZ3MuZm9yRWFjaChmdW5jdGlvbihzLGkpewogICAgdmFyIHc9TWF0aC5tYXgoMCxzLnZhbHVlKS90b3RhbCppdzsgaWYodzw9MCkgcmV0dXJuOwogICAgdmFyIGZpcnN0PWk9PT0wLCBsYXN0PWk9PT1zZWdzLmxlbmd0aC0xOwogICAgc3ZnLmFwcGVuZENoaWxkKGVsKCdyZWN0Jyx7eDp4LHk6VFksd2lkdGg6dyxoZWlnaHQ6QkgsJ2NsYXNzJzpzLmNscywKICAgICAgcng6KGZpcnN0fHxsYXN0KT80OjAscnk6KGZpcnN0fHxsYXN0KT80OjB9KSk7CiAgICB2YXIgcGN0PXMudmFsdWUvdG90YWwqMTAwOwogICAgaWYocGN0Pj05KQogICAgICBzdmcuYXBwZW5kQ2hpbGQoT2JqZWN0LmFzc2lnbihlbCgndGV4dCcse3g6eCt3LzIseTpUWStCSC8yKzQsJ2NsYXNzJzondmwnLAogICAgICAgICd0ZXh0LWFuY2hvcic6J21pZGRsZScsZmlsbDonI2ZmZid9KSx7dGV4dENvbnRlbnQ6cGN0LnRvRml4ZWQoMCkrJyUnfSkpOwogICAgdmFyIGhpdD1lbCgncmVjdCcse3g6eCx5OlRZLHdpZHRoOncsaGVpZ2h0OkJILCdjbGFzcyc6J2hpdCd9KTsKICAgIChmdW5jdGlvbihzZWcscHgscHcpewogICAgICBoaXQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJyxmdW5jdGlvbihldil7CiAgICAgICAgdmFyIGJyPWJveC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgICBzaG93VGlwKGJveCxldi5jbGllbnRYLWJyLmxlZnQsZXYuY2xpZW50WS1ici50b3AsCiAgICAgICAgICAnPGI+JytzZWcubmFtZSsnPC9iPjxicj4nK2ZtdChzZWcudmFsdWUpKycgwrcgJysoc2VnLnZhbHVlL3RvdGFsKjEwMCkudG9GaXhlZCgxKSsnJScpOwogICAgICB9KTsKICAgICAgaGl0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLGZ1bmN0aW9uKCl7aGlkZVRpcChib3gpO30pOwogICAgfSkocyx4LHcpOwogICAgc3ZnLmFwcGVuZENoaWxkKGhpdCk7CiAgICB4Kz13OwogIH0pOwogIGJveC5hcHBlbmRDaGlsZChzdmcpOwogIGJveC5hcHBlbmRDaGlsZChsZWdlbmQoc2Vncy5tYXAoZnVuY3Rpb24ocyl7cmV0dXJuIHtuYW1lOnMubmFtZSsnICcrZm10KHMudmFsdWUpLGNsczpzLmNsc307fSkpKTsKfQoKLyog7ISg7ZiVIOy2lOydtCDssKjtirgg4oCUIHNlcmllczpbe25hbWUsY2xzLGRhdGE6W119XSwgY2F0czpb652867KoXSAqLwpmdW5jdGlvbiBsaW5lQ2hhcnQoYm94SWQsIGNhdHMsIHNlcmllcywgZm10KXsKICB2YXIgYm94PSQoYm94SWQpOyBpZighYm94KSByZXR1cm47CiAgYm94LnF1ZXJ5U2VsZWN0b3JBbGwoJ3N2ZywudHBoLWxlZ2VuZCcpLmZvckVhY2goZnVuY3Rpb24obil7bi5yZW1vdmUoKTt9KTsKICB2YXIgbj1jYXRzLmxlbmd0aDsgaWYobjwyKSByZXR1cm47CiAgdmFyIFc9NjYwLEg9MjQwLFBMPTU0LFBSPTEyLFBUPTE0LFBCPTI2OwogIHZhciBhbGw9W107IHNlcmllcy5mb3JFYWNoKGZ1bmN0aW9uKHMpe2FsbD1hbGwuY29uY2F0KHMuZGF0YS5maWx0ZXIoZnVuY3Rpb24odil7cmV0dXJuIHYhPW51bGw7fSkpO30pOwogIGlmKCFhbGwubGVuZ3RoKSByZXR1cm47CiAgdmFyIG14PU1hdGgubWF4LmFwcGx5KG51bGwsYWxsKSwgbW49TWF0aC5taW4uYXBwbHkobnVsbCxhbGwpOwogIHZhciBwYWQ9KG14LW1uKSowLjE1fHxteCowLjAyfHwxOyBteCs9cGFkOyBtbj1NYXRoLm1heCgwLG1uLXBhZCk7CiAgdmFyIGl3PVctUEwtUFIsIGloPUgtUFQtUEI7CiAgdmFyIFg9ZnVuY3Rpb24oaSl7cmV0dXJuIFBMK2l3KihuPT09MT8wLjU6aS8obi0xKSk7fTsKICB2YXIgWT1mdW5jdGlvbih2KXtyZXR1cm4gUFQraWgqKDEtKHYtbW4pLygobXgtbW4pfHwxKSk7fTsKICB2YXIgc3ZnPWVsKCdzdmcnLHt2aWV3Qm94OicwIDAgJytXKycgJytILHJvbGU6J2ltZyd9KTsKICBmb3IodmFyIGc9MDtnPD00O2crKyl7CiAgICB2YXIgZ3Y9bW4rKG14LW1uKSpnLzQsIGd5PVkoZ3YpOwogICAgc3ZnLmFwcGVuZENoaWxkKGVsKCdsaW5lJyx7eDE6UEwseTE6Z3kseDI6Vy1QUix5MjpneSwnY2xhc3MnOidnbCd9KSk7CiAgICBzdmcuYXBwZW5kQ2hpbGQoT2JqZWN0LmFzc2lnbihlbCgndGV4dCcse3g6UEwtOCx5Omd5KzQsJ2NsYXNzJzonbGInLCd0ZXh0LWFuY2hvcic6J2VuZCd9KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt0ZXh0Q29udGVudDpNYXRoLnJvdW5kKGd2KS50b0xvY2FsZVN0cmluZygna28tS1InKX0pKTsKICB9CiAgc2VyaWVzLmZvckVhY2goZnVuY3Rpb24ocyl7CiAgICB2YXIgZD0nJywgc3RhcnRlZD1mYWxzZTsKICAgIHMuZGF0YS5mb3JFYWNoKGZ1bmN0aW9uKHYsaSl7CiAgICAgIGlmKHY9PW51bGwpIHJldHVybjsKICAgICAgZCs9KHN0YXJ0ZWQ/J0wnOidNJykrWChpKS50b0ZpeGVkKDEpKycgJytZKHYpLnRvRml4ZWQoMSkrJyAnOyBzdGFydGVkPXRydWU7CiAgICB9KTsKICAgIGlmKGQpIHN2Zy5hcHBlbmRDaGlsZChlbCgncGF0aCcse2Q6ZCxmaWxsOidub25lJywnc3Ryb2tlJzondmFyKC0tJytzLmNscysnKScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3Ryb2tlLXdpZHRoJzoyLjIsJ3N0cm9rZS1saW5lam9pbic6J3JvdW5kJywnc3Ryb2tlLWxpbmVjYXAnOidyb3VuZCd9KSk7CiAgICB2YXIgbGFzdD1zLmRhdGEubGVuZ3RoLTE7CiAgICBpZihzLmRhdGFbbGFzdF0hPW51bGwpCiAgICAgIHN2Zy5hcHBlbmRDaGlsZChlbCgnY2lyY2xlJyx7Y3g6WChsYXN0KSxjeTpZKHMuZGF0YVtsYXN0XSkscjo0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw6J3ZhcigtLScrcy5jbHMrJyknLHN0cm9rZTondmFyKC0tc3VyZmFjZSknLCdzdHJva2Utd2lkdGgnOjJ9KSk7CiAgfSk7CiAgY2F0cy5mb3JFYWNoKGZ1bmN0aW9uKGMsaSl7CiAgICBpZihuPjEwICYmIGklTWF0aC5jZWlsKG4vNykhPT0wICYmIGkhPT1uLTEpIHJldHVybjsKICAgIHN2Zy5hcHBlbmRDaGlsZChPYmplY3QuYXNzaWduKGVsKCd0ZXh0Jyx7eDpYKGkpLHk6SC04LCdjbGFzcyc6J2xiJywndGV4dC1hbmNob3InOidtaWRkbGUnfSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dGV4dENvbnRlbnQ6Y30pKTsKICB9KTsKICBmb3IodmFyIGk9MDtpPG47aSsrKXsKICAgIChmdW5jdGlvbihpZHgpewogICAgICB2YXIgaGl0PWVsKCdyZWN0Jyx7eDpYKGlkeCktaXcvKG4tMSkvMix5OlBULHdpZHRoOml3LyhuLTEpfHwyMCxoZWlnaHQ6aWgsJ2NsYXNzJzonaGl0J30pOwogICAgICBoaXQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJyxmdW5jdGlvbihldil7CiAgICAgICAgdmFyIGJyPWJveC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgICB2YXIgcm93cz1zZXJpZXMubWFwKGZ1bmN0aW9uKHMpewogICAgICAgICAgcmV0dXJuICc8c3BhbiBzdHlsZT0iZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6OHB4O2hlaWdodDo4cHg7Ym9yZGVyLXJhZGl1czoycHg7JwogICAgICAgICAgICAgICArICdiYWNrZ3JvdW5kOnZhcigtLScrcy5jbHMrJyk7bWFyZ2luLXJpZ2h0OjZweCI+PC9zcGFuPicrcy5uYW1lKycgJwogICAgICAgICAgICAgICArIChzLmRhdGFbaWR4XT09bnVsbD8nLSc6Zm10KHMuZGF0YVtpZHhdKSk7CiAgICAgICAgfSkuam9pbignPGJyPicpOwogICAgICAgIHNob3dUaXAoYm94LGV2LmNsaWVudFgtYnIubGVmdCxldi5jbGllbnRZLWJyLnRvcCwnPGI+JytjYXRzW2lkeF0rJzwvYj48YnI+Jytyb3dzKTsKICAgICAgfSk7CiAgICAgIGhpdC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJyxmdW5jdGlvbigpe2hpZGVUaXAoYm94KTt9KTsKICAgICAgc3ZnLmFwcGVuZENoaWxkKGhpdCk7CiAgICB9KShpKTsKICB9CiAgYm94LmFwcGVuZENoaWxkKHN2Zyk7CiAgYm94LmFwcGVuZENoaWxkKGxlZ2VuZChzZXJpZXMpKTsKfQoKZnVuY3Rpb24gbGVnZW5kKGl0ZW1zKXsKICB2YXIgZD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsgZC5jbGFzc05hbWU9J3RwaC1sZWdlbmQnOwogIGl0ZW1zLmZvckVhY2goZnVuY3Rpb24ocyl7CiAgICB2YXIgc3A9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOwogICAgc3AuaW5uZXJIVE1MPSc8aSBzdHlsZT0iYmFja2dyb3VuZDp2YXIoLS0nK3MuY2xzKycpIj48L2k+JytzLm5hbWU7CiAgICBkLmFwcGVuZENoaWxkKHNwKTsKICB9KTsKICByZXR1cm4gZDsKfQovKiAy7LCoIOuplOuJtDog7ZiE7J6sIO2DreydtCDtnLTrjIDtj7Ag7ZmU66m0IOuwlijsmKTrpbjsqr0p7JeQIOyeiOycvOuptCDqsIDroZzroZwg64u56rKoIOuztOydtOqyjCDtlZzri6Qo7Y6Y7J207KeA64qUIOyEuOuhnOuhnCDsm4Dsp4HsnbTsp4Ag7JWK64qU64ukKSAqLwooZnVuY3Rpb24oKXsKICB2YXIgYT1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcudHBoLXN1Ym5hdiBhW2FyaWEtY3VycmVudF0nKTsgaWYoIWEpIHJldHVybjsKICB2YXIgdz1hLnBhcmVudE5vZGUsIGFyPWEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIHdyPXcuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CiAgaWYoYXIucmlnaHQ+d3IucmlnaHQtOHx8YXIubGVmdDx3ci5sZWZ0KSB3LnNjcm9sbExlZnQrPWFyLmxlZnQtd3IubGVmdC0ody5jbGllbnRXaWR0aC1hLm9mZnNldFdpZHRoKS8yOwp9KSgpOwo7CnZhciBQPUQucCwgSURTPVsnb3duJywnbmgnLCdmYW0nLCdhY2MnLCdzcHMnXTsKdmFyIFRPREFZPShmdW5jdGlvbigpe3ZhciBkPW5ldyBEYXRlKCk7ZC5zZXRNaW51dGVzKGQuZ2V0TWludXRlcygpLWQuZ2V0VGltZXpvbmVPZmZzZXQoKSk7cmV0dXJuIGQudG9JU09TdHJpbmcoKS5zbGljZSgwLDEwKTt9KSgpOwp2YXIgTEFTVD1zdG9yZS5nZXQoJ3RwaC1zZWVuLWNnJyk7CmZ1bmN0aW9uIHYoaSl7IHJldHVybiArKCQoaSkudmFsdWV8fDApOyB9CmZ1bmN0aW9uIHNjb3JlKCl7CiAgdmFyIG93bj0kKCdvd24nKS52YWx1ZSwgbmg9IG93bj09PSduJyA/IDAgOiB2KCduaCcpLCBmYW09dignZmFtJyksIGFjYz1NYXRoLm1pbigxNywgdignYWNjJykrdignc3BzJykpOwogIHJldHVybiB7bmg6bmgsIGZhbTpmYW0sIGFjYzphY2MsIHRvdDpuaCtmYW0rYWNjfTsKfQpmdW5jdGlvbiBjYXJkKGssIG4sIG1heCwgc20pewogIHJldHVybiAnPGRpdiBjbGFzcz0idHBoLXN0YXQiPjxkaXYgY2xhc3M9ImsiPicraysnPC9kaXY+PGRpdiBjbGFzcz0ibiI+JytuKyfsoJAgPHNtYWxsIHN0eWxlPSJmb250LXNpemU6MTNweDtjb2xvcjp2YXIoLS1mYWludCkiPi8gJyttYXgrJzwvc21hbGw+PC9kaXY+JwogICAgKyc8ZGl2IHN0eWxlPSJoZWlnaHQ6NnB4O2JvcmRlci1yYWRpdXM6M3B4O2JhY2tncm91bmQ6dmFyKC0tbGluZSk7bWFyZ2luLXRvcDo2cHgiPjxkaXYgc3R5bGU9ImhlaWdodDo2cHg7Ym9yZGVyLXJhZGl1czozcHg7YmFja2dyb3VuZDp2YXIoLS1hY2NlbnQpO3dpZHRoOicrTWF0aC5yb3VuZChuL21heCoxMDApKyclIj48L2Rpdj48L2Rpdj4nCiAgICArKHNtPyc8ZGl2IGNsYXNzPSJzbSI+JytzbSsnPC9kaXY+JzonJykrJzwvZGl2Pic7Cn0KZnVuY3Rpb24gcmVuZGVyKCl7CiAgdmFyIHM9c2NvcmUoKTsKICAkKCdtYWluJykudGV4dENvbnRlbnQ9cy50b3QrJ+ygkCc7CiAgJCgnbmgnKS5kaXNhYmxlZCA9ICQoJ293bicpLnZhbHVlPT09J24nOwogICQoJ2JyaycpLmlubmVySFRNTCA9IGNhcmQoJ+ustOyjvO2DnSDquLDqsIQnLCBzLm5oLCAzMiwgJCgnb3duJykudmFsdWU9PT0nbic/J+ycoOyjvO2DneydtOuptCAw7KCQJzonJykKICAgICsgY2FyZCgn67aA7JaR6rCA7KGxJywgcy5mYW0sIDM1KSArIGNhcmQoJ+yyreyVve2GteyepScsIHMuYWNjLCAxNywgdignc3BzJyk/ICfrsLDsmrDsnpAgJyt2KCdzcHMnKSsn7KCQIO2PrO2VqCc6JycpOwogIHZhciBhcj0kKCdjZ2FyJykudmFsdWUsIGY9JCgnY2dmJykudmFsdWUsIG49MCwgb2s9MCwgbnc9MCwgaHRtbD0nJzsKICBQLmZvckVhY2goZnVuY3Rpb24oeCl7CiAgICBpZihhciAmJiB4WzFdIT09YXIpIHJldHVybjsKICAgIHZhciB0cz14WzRdLCBjYW49dHMuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVybiBzLnRvdD49dFsxXTt9KSwgbG89TWF0aC5taW4uYXBwbHkobnVsbCwgdHMubWFwKGZ1bmN0aW9uKHQpe3JldHVybiB0WzFdO30pKTsKICAgIHZhciBnYXA9bG8tcy50b3QsIHN0ID0gY2FuLmxlbmd0aD8gJ29rJyA6IChnYXA8PTM/ICduZWFyJzonZmFyJyk7CiAgICBuKys7IGlmKGNhbi5sZW5ndGgpIG9rKys7CiAgICB2YXIgaXNOZXcgPSBMQVNUICYmIHhbMl0+TEFTVCAmJiBjYW4ubGVuZ3RoOwogICAgaWYoaXNOZXcpIG53Kys7CiAgICBpZihmICYmIGYhPT1zdCkgcmV0dXJuOwogICAgdmFyIHJpZ2h0ID0gY2FuLmxlbmd0aCA/ICc8YiBzdHlsZT0iY29sb3I6dmFyKC0tb2spIj7qsIDriqUgJytjYW4ubGVuZ3RoKycvJyt0cy5sZW5ndGgrJ+2YlTwvYj4nCiAgICAgIDogJzxiIHN0eWxlPSJjb2xvcjonKyhzdD09PSduZWFyJz8nI2Q5NzcwNic6J3ZhcigtLW11dGVkKScpKyciPuy1nOyggCAnK2xvKyfsoJA8L2I+PHNtYWxsIHN0eWxlPSJkaXNwbGF5OmJsb2NrO2NvbG9yOnZhcigtLWZhaW50KSI+JytnYXArJ+ygkCDrtoDsobE8L3NtYWxsPic7CiAgICB2YXIgZGV0YWlsID0gdHMubWFwKGZ1bmN0aW9uKHQpeyByZXR1cm4gdFswXSsnICcrdFsxXSsn7KCQJzsgfSkuam9pbignIMK3ICcpOwogICAgaHRtbCArPSAnPGEgY2xhc3M9InRwaC1yb3ciIGhyZWY9IicrKHhbM118fCcjJykrJyI+PGRpdiBjbGFzcz0ibm0iPjxiPicreFswXQogICAgICArKGlzTmV3PycgPHNwYW4gY2xhc3M9InRwaC10YWcgdHBoLW5ldyI+TkVXPC9zcGFuPic6JycpKyc8L2I+JwogICAgICArJzxzcGFuPicreFs1XSsnIMK3IOuLueyyqCDrsJztkZwgJyt4WzJdLnNsaWNlKDUpLnJlcGxhY2UoJy0nLCcvJykrJzwvc3Bhbj48c3Bhbj4nK2RldGFpbCsnPC9zcGFuPjwvZGl2PicKICAgICAgKyc8ZGl2IGNsYXNzPSJwciIgc3R5bGU9ImZvbnQtc2l6ZToxM3B4Ij4nK3JpZ2h0Kyc8L2Rpdj48ZGl2IGNsYXNzPSJnbyI+4oC6PC9kaXY+PC9hPic7CiAgfSk7CiAgJCgnY2dsaXN0JykuaW5uZXJIVE1MID0gaHRtbCB8fCAnPGRpdiBjbGFzcz0idHBoLXJvdyI+PGRpdiBjbGFzcz0ibm0iPuyhsOqxtOyXkCDrp57ripQg64uo7KeA6rCAIOyXhuyKteuLiOuLpC48L2Rpdj48L2Rpdj4nOwogICQoJ2Nnc3VtJykudGV4dENvbnRlbnQgPSAoYXJ8fCfsoITqta0nKSsnIOy1nOq3vCAnK24rJ+qzsyDspJEg64K0IOygkOyImCgnK3MudG90KyfsoJAp66GcIDHqsJwg7KO87YOd7ZiVIOydtOyDgSDri7nssqgg6rCA64ql7ZaI642YIOqzs+ydgCAnK29rKyfqs7PsnoXri4jri6QuJzsKICBpZihMQVNUKSAkKCdjZ25ldycpLmlubmVySFRNTCA9IG53ID8gJ+yngOuCnCDrsKnrrLgoJytMQVNUKycpIOydtO2bhCDri7nssqgg67Cc7ZGc65CcIOuLqOyngCDspJEg64K0IOygkOyImOuhnCDqsIDriqXtlojrjZgg6rOzIDxiPicrbncrJ+qzszwvYj4g4oCUIE5FVyDtkZzsi5wnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICfsp4Drgpwg67Cp66y4KCcrTEFTVCsnKSDsnbTtm4Qg7IOI66GcIOuwnO2RnOuQnCDri6jsp4Ag7KSRIOuCtCDsoJDsiJjroZwg6rCA64ql7ZWcIOqzs+ydgCDsl4bsirXri4jri6QnOwp9Ci8qIOyeheugpcK37KeA7JetIOq4sOyWtSAo67iM65287Jqw7KCA7JeQ66eMIOyggOyepSkgKi8KdmFyIEtFWT0ndHBoLWluLeyyreyVvS3qsIDsoJAt6rOE7IKw6riwJzsKdHJ5eyB2YXIgbz1KU09OLnBhcnNlKHN0b3JlLmdldChLRVkpfHwne30nKTsgSURTLmNvbmNhdChbJ2NnYXInLCdjZ2YnXSkuZm9yRWFjaChmdW5jdGlvbihpKXsgaWYob1tpXSE9bnVsbCAmJiAkKGkpKSAkKGkpLnZhbHVlPW9baV07IH0pOyB9Y2F0Y2goZSl7fQpmdW5jdGlvbiBzYXZlKCl7IHZhciBvPXt9OyBJRFMuY29uY2F0KFsnY2dhcicsJ2NnZiddKS5mb3JFYWNoKGZ1bmN0aW9uKGkpeyBvW2ldPSQoaSkudmFsdWU7IH0pOyBzdG9yZS5zZXQoS0VZLCBKU09OLnN0cmluZ2lmeShvKSk7IH0KdmFyIFFBPShsb2NhdGlvbi5zZWFyY2gubWF0Y2goL1s/Jl1hcj0oW14mXSspLyl8fFtdKVsxXTsKaWYoUUEpeyBRQT1kZWNvZGVVUklDb21wb25lbnQoUUEpOyBpZihbXS5zb21lLmNhbGwoJCgnY2dhcicpLm9wdGlvbnMsZnVuY3Rpb24obyl7cmV0dXJuIG8udmFsdWU9PT1RQTt9KSkgJCgnY2dhcicpLnZhbHVlPVFBOyB9CklEUy5jb25jYXQoWydjZ2FyJywnY2dmJ10pLmZvckVhY2goZnVuY3Rpb24oaSl7ICQoaSkuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24oKXsgcmVuZGVyKCk7IHNhdmUoKTsgfSk7IH0pOwovKiDrgqDsp5zroZwg6rOE7IKw7ZW07IScIOuEo+q4sCAqLwpmdW5jdGlvbiBhZGRZKGQsIHkpeyB2YXIgeD1uZXcgRGF0ZShkKTsgeC5zZXRGdWxsWWVhcih4LmdldEZ1bGxZZWFyKCkreSk7IHJldHVybiB4OyB9CiQoJ2ZpbGwnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7CiAgdmFyIG5vdz1uZXcgRGF0ZShUT0RBWSksIG1zZz1bXTsKICBpZigkKCdiZCcpLnZhbHVlKXsKICAgIHZhciBiYXNlPWFkZFkoJCgnYmQnKS52YWx1ZSwgMzApOwogICAgaWYoJCgnbXInKS52YWx1ZSAmJiBuZXcgRGF0ZSgkKCdtcicpLnZhbHVlKTxiYXNlKSBiYXNlPW5ldyBEYXRlKCQoJ21yJykudmFsdWUpOwogICAgaWYoJCgnc29sZCcpLnZhbHVlICYmIG5ldyBEYXRlKCQoJ3NvbGQnKS52YWx1ZSk+YmFzZSkgYmFzZT1uZXcgRGF0ZSgkKCdzb2xkJykudmFsdWUpOwogICAgaWYobm93PGJhc2UpeyAkKCduaCcpLnZhbHVlPScwJzsgbXNnLnB1c2goJ+ustOyjvO2DnSDquLDqsIQ6IOyVhOyngSDsi5zsnpEg7KCEKDDsoJApJyk7IH0KICAgIGVsc2UgeyB2YXIgeT1NYXRoLmZsb29yKChub3ctYmFzZSkvKDM2NS4yNDI1Kjg2NGU1KSk7IHZhciBwPXk+PTE1PzMyOjIrMip5OyAkKCduaCcpLnZhbHVlPVN0cmluZyhwKTsgbXNnLnB1c2goJ+ustOyjvO2DnSDquLDqsIQgJyt5KyfrhYQg4oaSICcrcCsn7KCQJyk7IH0KICB9CiAgaWYoJCgnYWQnKS52YWx1ZSl7CiAgICB2YXIgbT0obm93LmdldEZ1bGxZZWFyKCktbmV3IERhdGUoJCgnYWQnKS52YWx1ZSkuZ2V0RnVsbFllYXIoKSkqMTIrKG5vdy5nZXRNb250aCgpLW5ldyBEYXRlKCQoJ2FkJykudmFsdWUpLmdldE1vbnRoKCkpLShub3cuZ2V0RGF0ZSgpPG5ldyBEYXRlKCQoJ2FkJykudmFsdWUpLmdldERhdGUoKT8xOjApOwogICAgdmFyIGEgPSBtPDY/MSA6IG08MTI/MiA6IE1hdGgubWluKDE3LCBNYXRoLmZsb29yKG0vMTIpKzIpOwogICAgJCgnYWNjJykudmFsdWU9U3RyaW5nKGEpOyBtc2cucHVzaCgn7Ya17J6lICcrTWF0aC5mbG9vcihtLzEyKSsn64WEICcrKG0lMTIpKyfqsJzsm5Qg4oaSICcrYSsn7KCQJyk7CiAgfQogICQoJ2ZpbGxtc2cnKS50ZXh0Q29udGVudCA9IG1zZy5sZW5ndGggPyBtc2cuam9pbignIMK3ICcpKycgKOyYpOuKmCDquLDspIApJyA6ICfsg53rhYTsm5TsnbzsnbTrgpgg7Ya17J6lIOqwgOyeheydvOydhCDrhKPslrQg7KO87IS47JqULic7CiAgcmVuZGVyKCk7IHNhdmUoKTsKfSk7CnJlbmRlcigpOwpzdG9yZS5zZXQoJ3RwaC1zZWVuLWNnJywgVE9EQVkpOwppbml0VGhlbWUoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRwaC1wYWdlJykpOwo=