IEN Pathways to Nursing Licensure
Answer a few questions to see your tailored registration journey by province.
1Licence Type
2Destination
3Background
→Results
Step 1: What nursing designation are you applying for?
Click on the registration type you are pursuing to get started.
RN – Registered Nurse
Degree-level nursing practice. Pathway available in British Columbia, Manitoba, and Ontario.
RPN – Registered Psychiatric Nurse
Psychiatric nursing specialization. Available in British Columbia and Manitoba.
LPN – Licensed Practical Nurse
Diploma-level practical nursing. Available in British Columbia and Manitoba.
Select one to continue
Step 2: Which province(s) are you considering?
Click on each province you want to explore. Select multiple to compare pathways side by side, then click Next.
BC
British Columbia
BCCNM + Inspire Global Assessments
MB
Manitoba
CRNM · CRPNM · CLPNM
ON
Ontario
College of Nurses of Ontario (CNO)
AB
Alberta
CRNA · CRPNA · CLHA
SK
Saskatchewan
CRNS · CRPNS · CLPNS
NS
Nova Scotia
College of Registered Nurses of Nova Scotia (CRNNS)
Coming Soon
Select at least one province
Step 3: Where did you complete your nursing education or most recent practice?
Click on the country that applies to you. This determines whether you qualify for an expedited registration pathway in BC or Manitoba. For Alberta RPN, both the Expedited and NNAS pathways are shown on your results — use the self-assessment questionnaire on the CRPNA website to confirm which applies to you.
AUAustralia
IEIreland
NZNew Zealand
UKUnited Kingdom
USUnited States
OtherAnother country
Select one to continue
Your Pathways
IEN Support Resources Near You
Settlement, bridging, and navigation supports — filtered to your selected province(s)
| Term | What it means |
|---|---|
| IEN | Internationally Educated Nurse — a nurse who completed their training outside Canada. |
| NNAS | National Nursing Assessment Service — Canada’s main credential assessment body for IENs. Produces an Advisory Report sent to your chosen regulator. |
| ECA | Educational Credential Assessment — a formal evaluation comparing your nursing education to Canadian standards. Required to open a file in some provinces (e.g., CRNM in Manitoba). |
| CCA | Clinical Competence Assessment — a practical skills evaluation required in BC (via Inspire) and Manitoba (CRNM) to assess readiness for Canadian practice. |
| SLA | Simulation Lab Assessment — a hands-on competency test delivered by Inspire Global Assessments in BC. |
| CBA | Computer-Based Assessment — a written knowledge test delivered by Inspire Global Assessments in BC. |
| TPE | Transitional Practice Experience — a supervised 250-hour clinical placement required in BC for some IENs after the BCCNM review. |
| SPEP | Supervised Practice Experience Partnership — approximately 140 hours of supervised clinical practice in Ontario for nurses who lack recent Evidence of Practice. Supported by Ontario Health. |
| TTP | Transition to Practice — an Ontario CNO requirement; met through recent Canadian nursing education, registration, or practice, or a CNO-approved TTP course. |
| NREP | Nurse Re-entry Program — a bridging program at RRC Polytechnic in Manitoba for RNs whose education is found comparable by CRNM. |
| EOP | Evidence of Practice — proof of recent nursing work, typically within the past 3 years, required by Ontario CNO before registration. |
| ATT | Authorization to Test — a document from Pearson VUE permitting you to book your NCLEX-RN or REx-PN exam. |
| VSS | Vulnerable Sector Search — a type of criminal record check required for roles working with vulnerable persons (children, elderly). Required by CRNM, CRPNM, and others. |
| NCLEX-RN | National Council Licensure Examination for Registered Nurses — the mandatory entry-to-practice exam for RN registration across Canada, administered via Pearson VUE. |
| REx-PN | Registered Practical Nurse Regulatory Examination — the mandatory exam for LPN (BC) and RPN (Ontario) registration, administered via Pearson VUE. |
| RPNCE | Registered Psychiatric Nurses Canadian Examination — the mandatory entry-to-practice exam for RPN registration in BC and Manitoba. |
| BCCNM | BC College of Nurses and Midwives — regulates RNs, RPNs, and LPNs in British Columbia. |
| Inspire | Inspire Global Assessments — BC’s independent credential and competency assessment body for IENs applying through BCCNM. |
| CRNM | College of Registered Nurses of Manitoba — regulates RNs in Manitoba. |
| CRPNM | College of Registered Psychiatric Nurses of Manitoba — regulates RPNs in Manitoba. |
| CLPNM | College of Licensed Practical Nurses of Manitoba — regulates LPNs in Manitoba. |
| CNO | College of Nurses of Ontario — regulates both RNs and RPNs (the Ontario equivalent of LPN) in Ontario. |
Can I work in Canada while my registration application is in progress?
It depends on your immigration status and province. In BC and Manitoba, some provinces offer provisional or temporary registration once certain requirements are met, allowing supervised practice. In Ontario, a Temporary Class certificate may be available with an employer offer. You may also be eligible to work as an unregulated healthcare aide while your nursing application is pending — check with your province’s health authority.
What happens if my education is found “not comparable”?
In BC, BCCNM may require bridging courses or a Transitional Practice Experience (TPE). In Manitoba, CRNM may refer you to the Nurse Re-entry Program (NREP) at RRC Polytechnic. In Ontario, CNO may require a CNO-approved IEN education pathway (theory + clinical) or a Competency Assessment Supplement (CAS). “Not comparable” does not mean your application is rejected — it means additional education is needed before the exam.
Do I need to rewrite NCLEX-RN if I move to a different province?
No. The NCLEX-RN is recognized Canada-wide. If you have passed it in one province, you do not need to retake it when applying in another — you simply provide proof of your result. The same applies to REx-PN and RPNCE.
How long does NNAS take?
Typically 3–12 months, depending on how quickly your educational institutions and licensing bodies send documents. The most common delay is waiting for transcripts from international schools. You can speed this up by contacting your institutions immediately after creating your NNAS profile and requesting direct submission.
Can I apply to multiple provinces at the same time?
Yes, and it is often recommended. Your NNAS Advisory Report can be shared with multiple regulators. Applying concurrently increases your chances of an earlier start and lets you compare timelines. Note that each province charges its own application fee separately.
Can I apply to NNAS while my immigration application is still in progress?
Yes. You do not need to be in Canada or have permanent residency to apply to NNAS or open a file with most provincial regulators. Starting early is strongly recommended — credential assessment often takes longer than immigration processing.
What is the BC IEN Bursary?
A financial support program in British Columbia that may cover fees for the Inspire Global Assessments competency assessment (SLA/CBA) for eligible IENs. Contact Inspire or BCCNM directly to confirm current eligibility criteria and application process.
Disclaimer: General overview only — not legal or regulatory advice. Requirements, fees, and timelines are subject to change. Always confirm current information directly with the relevant provincial regulatory body before making decisions. Data last reviewed: 2026 |
nnas.ca
Cgp3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIGZ1bmN0aW9uICgpIHsKCgoKLyog4pSA4pSAIFNUQVRFIOKUgOKUgCAqLwoKdmFyIFMgPSB7IGxpYzogbnVsbCwgcHJvdnM6IFtdLCBjb3VudHJ5OiBudWxsIH07CgoKCi8qIOKUgOKUgCBXT1JLRk9SQ0UgREFUQSAoQ0lISSBOdXJzaW5nIERhdGFiYXNlICsgR292ZXJubWVudCBvZiBDYW5hZGEgSm9iIEJhbmspIOKUgOKUgCAqLwoKdmFyIFdGX0RBVEEgPSB7CgogIGJjX3JuX2V4cDogeyB5ZWFyOjIwMjQsIHRvdGFsOjQxMTE1LCBpZW5JbmZsb3c6NjcwLCB0b3RhbEluZmxvdzozNjI1LAoKICAgIHdvcmtwbGFjZXM6W3tsYWJlbDonSG9zcGl0YWwnLG46MjU2MDl9LHtsYWJlbDonQ29tbXVuaXR5IGhlYWx0aCcsbjo3ODU5fSx7bGFiZWw6J0xUQyAvIE51cnNpbmcgaG9tZScsbjoyNDMwfSx7bGFiZWw6J090aGVyJyxuOjQ4MjF9XSwKCiAgICBlbXBsb3ltZW50Olt7bGFiZWw6J0Z1bGwgdGltZScsbjoyMjgxNn0se2xhYmVsOidQYXJ0IHRpbWUnLG46MTMwMzR9LHtsYWJlbDonQ2FzdWFsJyxuOjUxNzd9XSwKCiAgICB3YWdlczp7IGxvdzozMi41MCwgbWVkaWFuOjQ1LjAwLCBoaWdoOjUyLjAwLCB3YWdlWWVhcjoyMDI0IH0gfSwKCiAgYmNfcm5fc3RkOiB7IHllYXI6MjAyNCwgdG90YWw6NDExMTUsIGllbkluZmxvdzo2NzAsIHRvdGFsSW5mbG93OjM2MjUsCgogICAgd29ya3BsYWNlczpbe2xhYmVsOidIb3NwaXRhbCcsbjoyNTYwOX0se2xhYmVsOidDb21tdW5pdHkgaGVhbHRoJyxuOjc4NTl9LHtsYWJlbDonTFRDIC8gTnVyc2luZyBob21lJyxuOjI0MzB9LHtsYWJlbDonT3RoZXInLG46NDgyMX1dLAoKICAgIGVtcGxveW1lbnQ6W3tsYWJlbDonRnVsbCB0aW1lJyxuOjIyODE2fSx7bGFiZWw6J1BhcnQgdGltZScsbjoxMzAzNH0se2xhYmVsOidDYXN1YWwnLG46NTE3N31dLAoKICAgIHdhZ2VzOnsgbG93OjMyLjUwLCBtZWRpYW46NDUuMDAsIGhpZ2g6NTIuMDAsIHdhZ2VZZWFyOjIwMjQgfSB9LAoKICBiY19scG46IHsgeWVhcjoyMDI0LCB0b3RhbDoxMzc3MSwgaWVuSW5mbG93OjM5LCB0b3RhbEluZmxvdzoxMzY5LAoKICAgIHdvcmtwbGFjZXM6W3tsYWJlbDonSG9zcGl0YWwnLG46NTEwNH0se2xhYmVsOidDb21tdW5pdHkgaGVhbHRoJyxuOjIwNTB9LHtsYWJlbDonTFRDIC8gTnVyc2luZyBob21lJyxuOjUxNTB9LHtsYWJlbDonT3RoZXInLG46MTMyMn1dLAoKICAgIGVtcGxveW1lbnQ6W3tsYWJlbDonRnVsbCB0aW1lJyxuOjc2MjV9LHtsYWJlbDonUGFydCB0aW1lJyxuOjM2MDB9LHtsYWJlbDonQ2FzdWFsJyxuOjI1MDJ9XSwKCiAgICB3YWdlczp7IGxvdzoyNy4wMCwgbWVkaWFuOjM3LjAwLCBoaWdoOjQ0LjAwLCB3YWdlWWVhcjoyMDI0IH0gfSwKCiAgbWJfcm5fc3RkOiB7IHllYXI6MjAxOCwgdG90YWw6MTE2NzAsIGllbkluZmxvdzo5MCwgdG90YWxJbmZsb3c6NzMxLCBub3RlOidNQiBSTiBkYXRhIG5vdCBhdmFpbGFibGUgcGFzdCAyMDE4JywKCiAgICB3b3JrcGxhY2VzOlt7bGFiZWw6J0hvc3BpdGFsJyxuOjcyMDZ9LHtsYWJlbDonQ29tbXVuaXR5IGhlYWx0aCcsbjoxNzk1fSx7bGFiZWw6J0xUQyAvIE51cnNpbmcgaG9tZScsbjoxMzU0fSx7bGFiZWw6J090aGVyJyxuOjEyODJ9XSwKCiAgICBlbXBsb3ltZW50Olt7bGFiZWw6J0Z1bGwgdGltZScsbjo1MjQ0fSx7bGFiZWw6J1BhcnQgdGltZScsbjo1MzU2fSx7bGFiZWw6J0Nhc3VhbCcsbjoxMDE2fV0sCgogICAgd2FnZXM6eyBsb3c6MzMuMDAsIG1lZGlhbjo0NC4wMCwgaGlnaDo1MS4wMCwgd2FnZVllYXI6MjAyNCB9IH0sCgogIG1iX3JuX2V4cDogeyB5ZWFyOjIwMTgsIHRvdGFsOjExNjcwLCBpZW5JbmZsb3c6OTAsIHRvdGFsSW5mbG93OjczMSwgbm90ZTonTUIgUk4gZGF0YSBub3QgYXZhaWxhYmxlIHBhc3QgMjAxOCcsCgogICAgd29ya3BsYWNlczpbe2xhYmVsOidIb3NwaXRhbCcsbjo3MjA2fSx7bGFiZWw6J0NvbW11bml0eSBoZWFsdGgnLG46MTc5NX0se2xhYmVsOidMVEMgLyBOdXJzaW5nIGhvbWUnLG46MTM1NH0se2xhYmVsOidPdGhlcicsbjoxMjgyfV0sCgogICAgZW1wbG95bWVudDpbe2xhYmVsOidGdWxsIHRpbWUnLG46NTI0NH0se2xhYmVsOidQYXJ0IHRpbWUnLG46NTM1Nn0se2xhYmVsOidDYXN1YWwnLG46MTAxNn1dLAoKICAgIHdhZ2VzOnsgbG93OjMzLjAwLCBtZWRpYW46NDQuMDAsIGhpZ2g6NTEuMDAsIHdhZ2VZZWFyOjIwMjQgfSB9LAoKICBtYl9scG46IHsgeWVhcjoyMDI0LCB0b3RhbDozNTI1LCBpZW5JbmZsb3c6OTcsIHRvdGFsSW5mbG93OjM3MCwKCiAgICB3b3JrcGxhY2VzOlt7bGFiZWw6J0hvc3BpdGFsJyxuOjEzNDN9LHtsYWJlbDonQ29tbXVuaXR5IGhlYWx0aCcsbjo1NDN9LHtsYWJlbDonTFRDIC8gTnVyc2luZyBob21lJyxuOjEyOTZ9LHtsYWJlbDonT3RoZXInLG46MzM5fV0sCgogICAgZW1wbG95bWVudDpbe2xhYmVsOidGdWxsIHRpbWUnLG46MTE4Mn0se2xhYmVsOidQYXJ0IHRpbWUnLG46MTk4OH0se2xhYmVsOidDYXN1YWwnLG46MzU1fV0sCgogICAgd2FnZXM6eyBsb3c6MjIuMDAsIG1lZGlhbjozMC4wMCwgaGlnaDozOC4wMCwgd2FnZVllYXI6MjAyNCB9IH0sCgogIG9uX3JuOiB7IHllYXI6MjAyNCwgdG90YWw6MTA2NTIzLCBpZW5JbmZsb3c6NDc2OCwgdG90YWxJbmZsb3c6MTI2NTgsCgogICAgd29ya3BsYWNlczpbe2xhYmVsOidIb3NwaXRhbCcsbjo2ODYyNn0se2xhYmVsOidDb21tdW5pdHkgaGVhbHRoJyxuOjE2NTEzfSx7bGFiZWw6J0xUQyAvIE51cnNpbmcgaG9tZScsbjo4NDE5fSx7bGFiZWw6J090aGVyJyxuOjEyOTQzfV0sCgogICAgZW1wbG95bWVudDpbe2xhYmVsOidGdWxsIHRpbWUnLG46NzUwMDd9LHtsYWJlbDonUGFydCB0aW1lJyxuOjIyNTYwfSx7bGFiZWw6J0Nhc3VhbCcsbjo4OTU2fV0sCgogICAgd2FnZXM6eyBsb3c6MzQuMDAsIG1lZGlhbjo0NS4wMCwgaGlnaDo1Mi4wMCwgd2FnZVllYXI6MjAyNCB9IH0sCgogIG9uX3JwbjogeyB5ZWFyOjIwMjQsIHRvdGFsOjUzNDYyLCBpZW5JbmZsb3c6MTMyOSwgdG90YWxJbmZsb3c6Njg4NSwgbm90ZTonT250YXJpbyBSUE4gZmlndXJlcyB1c2UgTFBOIHJlZ2lzdHJhbnQgZGF0YScsCgogICAgd29ya3BsYWNlczpbe2xhYmVsOidIb3NwaXRhbCcsbjoyMzg3M30se2xhYmVsOidDb21tdW5pdHkgaGVhbHRoJyxuOjkwNDV9LHtsYWJlbDonTFRDIC8gTnVyc2luZyBob21lJyxuOjE1NDYxfSx7bGFiZWw6J090aGVyJyxuOjUwNjd9XSwKCiAgICBlbXBsb3ltZW50Olt7bGFiZWw6J0Z1bGwgdGltZScsbjozNDU5M30se2xhYmVsOidQYXJ0IHRpbWUnLG46MTQ0NjV9LHtsYWJlbDonQ2FzdWFsJyxuOjQ0MDR9XSwKCiAgICB3YWdlczp7IGxvdzoyNi4wMCwgbWVkaWFuOjM0LjAwLCBoaWdoOjQxLjAwLCB3YWdlWWVhcjoyMDI0IH0gfSwKICBhYl9ybjogeyB5ZWFyOjIwMjQsIHRvdGFsOjQzODcwLCBpZW5JbmZsb3c6NzAwLCB0b3RhbEluZmxvdzo0NDQ5LAogICAgd29ya3BsYWNlczpbe2xhYmVsOidIb3NwaXRhbCcsbjoyNDkwMH0se2xhYmVsOidDb21tdW5pdHkgaGVhbHRoJyxuOjc1MDB9LHtsYWJlbDonTFRDIC8gTnVyc2luZyBob21lJyxuOjUyMDB9LHtsYWJlbDonT3RoZXInLG46NjI3MH1dLAogICAgZW1wbG95bWVudDpbe2xhYmVsOidGdWxsIHRpbWUnLG46MTkzNDd9LHtsYWJlbDonUGFydCB0aW1lJyxuOjE0NTAwfSx7bGFiZWw6J0Nhc3VhbCcsbjoxMDAyM31dLAogICAgd2FnZXM6eyBsb3c6MzAuMDAsIG1lZGlhbjo0Ny4zOCwgaGlnaDo1NC40OSwgd2FnZVllYXI6MjAyNCB9IH0sCgogIGFiX3Jwbl9leHA6IHsgeWVhcjoyMDI0LCB0b3RhbDoxNTAwLCBpZW5JbmZsb3c6NDUsIHRvdGFsSW5mbG93OjEyMCwKICAgIHdvcmtwbGFjZXM6W3tsYWJlbDonSG9zcGl0YWwnLG46Njc1fSx7bGFiZWw6J0NvbW11bml0eSBoZWFsdGgnLG46Mzc1fSx7bGFiZWw6J0xUQyAvIE51cnNpbmcgaG9tZScsbjozMDB9LHtsYWJlbDonT3RoZXInLG46MTUwfV0sCiAgICBlbXBsb3ltZW50Olt7bGFiZWw6J0Z1bGwgdGltZScsbjo4MjV9LHtsYWJlbDonUGFydCB0aW1lJyxuOjQ1MH0se2xhYmVsOidDYXN1YWwnLG46MjI1fV0sCiAgICB3YWdlczp7IGxvdzozMC4wMCwgbWVkaWFuOjQ3LjM4LCBoaWdoOjU0LjM3LCB3YWdlWWVhcjoyMDI0IH0gfSwKCiAgYWJfcnBuX25uYXM6IHsgeWVhcjoyMDI0LCB0b3RhbDoxNTAwLCBpZW5JbmZsb3c6NDUsIHRvdGFsSW5mbG93OjEyMCwKICAgIHdvcmtwbGFjZXM6W3tsYWJlbDonSG9zcGl0YWwnLG46Njc1fSx7bGFiZWw6J0NvbW11bml0eSBoZWFsdGgnLG46Mzc1fSx7bGFiZWw6J0xUQyAvIE51cnNpbmcgaG9tZScsbjozMDB9LHtsYWJlbDonT3RoZXInLG46MTUwfV0sCiAgICBlbXBsb3ltZW50Olt7bGFiZWw6J0Z1bGwgdGltZScsbjo4MjV9LHtsYWJlbDonUGFydCB0aW1lJyxuOjQ1MH0se2xhYmVsOidDYXN1YWwnLG46MjI1fV0sCiAgICB3YWdlczp7IGxvdzozMC4wMCwgbWVkaWFuOjQ3LjM4LCBoaWdoOjU0LjM3LCB3YWdlWWVhcjoyMDI0IH0gfSwKCiAgYWJfbHBuOiB7IHllYXI6MjAyNCwgdG90YWw6MjA2OTcsIGllbkluZmxvdzo0MDAsIHRvdGFsSW5mbG93OjIwNTAsCiAgICB3b3JrcGxhY2VzOlt7bGFiZWw6J0hvc3BpdGFsJyxuOjEwMTQyfSx7bGFiZWw6J0NvbW11bml0eSBoZWFsdGgnLG46MzMxMn0se2xhYmVsOidMVEMgLyBOdXJzaW5nIGhvbWUnLG46NTU4OH0se2xhYmVsOidPdGhlcicsbjoxNjU1fV0sCiAgICBlbXBsb3ltZW50Olt7bGFiZWw6J0Z1bGwgdGltZScsbjoxMTM4M30se2xhYmVsOidQYXJ0IHRpbWUnLG46NjIwOX0se2xhYmVsOidDYXN1YWwnLG46MzEwNX1dLAogICAgd2FnZXM6eyBsb3c6MjUuODAsIG1lZGlhbjozMS45MSwgaGlnaDozNi4wMCwgd2FnZVllYXI6MjAyNCB9IH0sCgogIHNrX3JuOiB7IHllYXI6MjAyNCwgdG90YWw6MTI1NzQsIGllbkluZmxvdzo0MDAsIHRvdGFsSW5mbG93OjExMDAsCiAgICB3b3JrcGxhY2VzOlt7bGFiZWw6J0hvc3BpdGFsJyxuOjgwNDd9LHtsYWJlbDonQ29tbXVuaXR5IGhlYWx0aCcsbjoxNjM1fSx7bGFiZWw6J0xUQyAvIE51cnNpbmcgaG9tZScsbjoxMzgzfSx7bGFiZWw6J090aGVyJyxuOjE1MDl9XSwKICAgIGVtcGxveW1lbnQ6W3tsYWJlbDonRnVsbCB0aW1lJyxuOjgyNDl9LHtsYWJlbDonUGFydCB0aW1lJyxuOjI4OTJ9LHtsYWJlbDonQ2FzdWFsJyxuOjE0MzN9XSwKICAgIHdhZ2VzOnsgbG93OjM3LjA2LCBtZWRpYW46NDguMjAsIGhpZ2g6NTEuMDcsIHdhZ2VZZWFyOjIwMjQgfSB9LAoKICBza19ycG46IHsgeWVhcjoyMDI0LCB0b3RhbDo3OTgsIGllbkluZmxvdzoxMiwgdG90YWxJbmZsb3c6ODAsCiAgICB3b3JrcGxhY2VzOlt7bGFiZWw6J0hvc3BpdGFsJyxuOjM1OX0se2xhYmVsOidDb21tdW5pdHkgaGVhbHRoJyxuOjIwMH0se2xhYmVsOidMVEMgLyBOdXJzaW5nIGhvbWUnLG46MTYwfSx7bGFiZWw6J090aGVyJyxuOjc5fV0sCiAgICBlbXBsb3ltZW50Olt7bGFiZWw6J0Z1bGwgdGltZScsbjo0Mzl9LHtsYWJlbDonUGFydCB0aW1lJyxuOjIzOX0se2xhYmVsOidDYXN1YWwnLG46MTIwfV0sCiAgICB3YWdlczp7IGxvdzozMC4wMCwgbWVkaWFuOjM1LjQzLCBoaWdoOjU0LjM3LCB3YWdlWWVhcjoyMDI0IH0gfSwKCiAgc2tfbHBuOiB7IHllYXI6MjAyNCwgdG90YWw6MzkyNywgaWVuSW5mbG93Ojk1LCB0b3RhbEluZmxvdzo0MDAsCiAgICB3b3JrcGxhY2VzOlt7bGFiZWw6J0hvc3BpdGFsJyxuOjE5MjR9LHtsYWJlbDonQ29tbXVuaXR5IGhlYWx0aCcsbjo2Mjh9LHtsYWJlbDonTFRDIC8gTnVyc2luZyBob21lJyxuOjEwNjB9LHtsYWJlbDonT3RoZXInLG46MzE1fV0sCiAgICBlbXBsb3ltZW50Olt7bGFiZWw6J0Z1bGwgdGltZScsbjoyMzU2fSx7bGFiZWw6J1BhcnQgdGltZScsbjoxMTAwfSx7bGFiZWw6J0Nhc3VhbCcsbjo0NzF9XSwKICAgIHdhZ2VzOnsgbG93OjMzLjAwLCBtZWRpYW46MzcuNDEsIGhpZ2g6NDIuMDAsIHdhZ2VZZWFyOjIwMjQgfSB9CgoKfTsKCgoKCgoKCi8qIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkAoKICAgUEFUSFdBWSBEQVRBCgogICDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAgKi8KCi8qIFBBVEhTIGxvYWRlZCBmcm9tICNwdy1kYXRhIHNjcmlwdCB0YWcgKi8KCgoKLyog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQCgogICBIRUxQRVJTCgogICDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAgKi8KCmZ1bmN0aW9uIHBhdGhLZXkocHJvdiwgbGljLCBjb3VudHJ5KSB7CgogIHZhciBjID0gY291bnRyeSB8fCAnb3RoZXInOwoKICBpZiAocHJvdiA9PT0gJ2JjJykgewoKICAgIGlmIChsaWMgPT09ICdybicpIHJldHVybiBbJ2F1JywnbnonLCd1aycsJ3VzJ10uaW5kZXhPZihjKSA+IC0xID8gJ2JjX3JuX2V4cCcgOiAnYmNfcm5fc3RkJzsKCiAgICBpZiAobGljID09PSAncnBuJykgcmV0dXJuICdiY19ycG4nOwoKICAgIGlmIChsaWMgPT09ICdscG4nKSByZXR1cm4gJ2JjX2xwbic7CgogIH0KCiAgaWYgKHByb3YgPT09ICdtYicpIHsKCiAgICBpZiAobGljID09PSAncm4nKSByZXR1cm4gWydhdScsJ2llJywnbnonLCd1ayddLmluZGV4T2YoYykgPiAtMSA/ICdtYl9ybl9leHAnIDogJ21iX3JuX3N0ZCc7CgogICAgaWYgKGxpYyA9PT0gJ3JwbicpIHJldHVybiAnbWJfcnBuJzsKCiAgICBpZiAobGljID09PSAnbHBuJykgcmV0dXJuICdtYl9scG4nOwoKICB9CgogIGlmIChwcm92ID09PSAnb24nKSB7CgogICAgaWYgKGxpYyA9PT0gJ3JuJykgcmV0dXJuICdvbl9ybic7CgogICAgaWYgKGxpYyA9PT0gJ3JwbicpIHJldHVybiAnb25fcnBuJzsKCiAgICBpZiAobGljID09PSAnbHBuJykgcmV0dXJuICdvbl9scG4nOwoKICB9CgogIGlmIChwcm92ID09PSAnYWInKSB7CgogICAgaWYgKGxpYyA9PT0gJ3JuJykgcmV0dXJuICdhYl9ybic7CgogICAgaWYgKGxpYyA9PT0gJ3JwbicpIHJldHVybiBbJ2FiX3Jwbl9leHAnLCAnYWJfcnBuX25uYXMnXTsKCiAgICBpZiAobGljID09PSAnbHBuJykgcmV0dXJuICdhYl9scG4nOwoKICB9CgogIGlmIChwcm92ID09PSAnc2snKSB7CgogICAgaWYgKGxpYyA9PT0gJ3JuJykgcmV0dXJuICdza19ybic7CgogICAgaWYgKGxpYyA9PT0gJ3JwbicpIHJldHVybiAnc2tfcnBuJzsKCiAgICBpZiAobGljID09PSAnbHBuJykgcmV0dXJuICdza19scG4nOwoKICB9CgogIHJldHVybiBudWxsOwoKfQoKCgpmdW5jdGlvbiBlc2MocykgewoKICByZXR1cm4gU3RyaW5nKHN8fCcnKS5yZXBsYWNlKC8mL2csJyZhbXA7JykucmVwbGFjZSgvPC9nLCcmbHQ7JykucmVwbGFjZSgvPi9nLCcmZ3Q7Jyk7Cgp9CgoKCmZ1bmN0aW9uIHVpZCgpIHsgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIsOCk7IH0KCgoKLyog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQCgogICBSRU5ERVIgUkVTVUxUIENBUkQKCiAgIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAqLwoKZnVuY3Rpb24gaW5pdFRhYmxlYXVWaXooYnRuKSB7CgogIGlmICghYnRuIHx8IGJ0bi5nZXRBdHRyaWJ1dGUoJ2RhdGEtdGFibGVhdS1pbml0JykpIHJldHVybjsKCiAgdmFyIHZpeklkID0gYnRuLmdldEF0dHJpYnV0ZSgnZGF0YS10YWJsZWF1LXZpeicpOwoKICBpZiAoIXZpeklkKSByZXR1cm47CgogIGJ0bi5zZXRBdHRyaWJ1dGUoJ2RhdGEtdGFibGVhdS1pbml0JywgJzEnKTsKCiAgdmFyIHdyYXAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh2aXpJZCk7CgogIGlmICghd3JhcCkgcmV0dXJuOwoKICB2YXIgb2JqID0gd3JhcC5xdWVyeVNlbGVjdG9yKCdvYmplY3QudGFibGVhdVZpeicpOwoKICBpZiAoIW9iaikgcmV0dXJuOwoKICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewoKICAgIHZhciBjb250YWluZXIgPSB3cmFwLnBhcmVudEVsZW1lbnQgfHwgd3JhcDsKCiAgICB2YXIgdyA9IGNvbnRhaW5lci5vZmZzZXRXaWR0aCB8fCB3cmFwLm9mZnNldFdpZHRoIHx8IDcwMDsKCiAgICB2YXIgaCA9IHcgPD0gNTAwID8gJzE0MDBweCcgOiAnOTAwcHgnOwoKICAgIG9iai5zdHlsZS53aWR0aCA9ICcxMDAlJzsKCiAgICBvYmouc3R5bGUuaGVpZ2h0ID0gaDsKCiAgICB2YXIgcGggPSB3cmFwLnF1ZXJ5U2VsZWN0b3IoJy50YWJsZWF1UGxhY2Vob2xkZXInKTsKCiAgICBpZiAocGgpIHsgcGguc3R5bGUuaGVpZ2h0ID0gaDsgcGguc3R5bGUud2lkdGggPSAnMTAwJSc7IH0KCiAgICBpZiAoIXdpbmRvdy5fcHdUYWJMb2FkZWQpIHsKCiAgICAgIHdpbmRvdy5fcHdUYWJMb2FkZWQgPSB0cnVlOwoKICAgICAgdmFyIHNjID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7CgogICAgICBzYy5zcmMgPSAnaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vamF2YXNjcmlwdHMvYXBpL3Zpel92MS5qcyc7CgogICAgICBvYmoucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc2MsIG9iaik7CgogICAgfQoKICB9LCAyMDApOwoKfQoKCgpmdW5jdGlvbiByZW5kZXJXZkJhcnMoaXRlbXMpIHsKCiAgdmFyIG1heCA9IE1hdGgubWF4LmFwcGx5KG51bGwsIGl0ZW1zLm1hcChmdW5jdGlvbih4KXsgcmV0dXJuIHgubjsgfSkpOwoKICB2YXIgdG90ID0gaXRlbXMucmVkdWNlKGZ1bmN0aW9uKHMseCl7IHJldHVybiBzK3gubjsgfSwgMCk7CgogIHJldHVybiBpdGVtcy5tYXAoZnVuY3Rpb24oaXRlbSkgewoKICAgIHZhciBwY3QgPSB0b3QgPiAwID8gTWF0aC5yb3VuZChpdGVtLm4vdG90KjEwMCkgOiAwOwoKICAgIHZhciBiYXJXID0gbWF4ID4gMCA/IE1hdGgucm91bmQoaXRlbS5uL21heCoxMDApIDogMDsKCiAgICByZXR1cm4gJzxkaXYgY2xhc3M9InB3LXdmLWJhci1yb3ciPicgKwoKICAgICAgJzxzcGFuIGNsYXNzPSJwdy13Zi1iYXItbGJsIj4nICsgZXNjKGl0ZW0ubGFiZWwpICsgJzwvc3Bhbj4nICsKCiAgICAgICc8ZGl2IGNsYXNzPSJwdy13Zi1iYXItdHJhY2siPjxkaXYgY2xhc3M9InB3LXdmLWJhci1maWxsIiBzdHlsZT0id2lkdGg6JyArIGJhclcgKyAnJSI+PC9kaXY+PC9kaXY+JyArCgogICAgICAnPHNwYW4gY2xhc3M9InB3LXdmLWJhci1wY3QiPicgKyBwY3QgKyAnJTwvc3Bhbj4nICsKCiAgICAnPC9kaXY+JzsKCiAgfSkuam9pbignJyk7Cgp9CgoKCmZ1bmN0aW9uIHJlbmRlckNhcmQoa2V5KSB7CgogIHZhciBkID0gUEFUSFNba2V5XTsKCiAgaWYgKCFkKSByZXR1cm4gJyc7CgoKCiAgdmFyIGhlYWQgPSAnPGRpdiBjbGFzcz0icHctcmMtaGVhZCI+JyArCgogICAgJzxzcGFuIGNsYXNzPSJwdy1yYy1hYmJyIj4nICsgZXNjKGQuYWJicikgKyAnPC9zcGFuPicgKwoKICAgICc8c3BhbiBjbGFzcz0icHctcmMtaW5mbyI+JyArCgogICAgICAnPHNwYW4gY2xhc3M9InB3LXJjLXRpdGxlIj4nICsgZXNjKGQucHJvdmluY2UpICsgJyDCtyAnICsgZXNjKGQubGljTGFiZWwpICsgJzwvc3Bhbj4nICsKCiAgICAgICc8c3BhbiBjbGFzcz0icHctcmMtcmVnIj4nICsgZXNjKGQucmVndWxhdG9yKSArIChkLmFzc2Vzc29yID8gJyArICcgKyBlc2MoZC5hc3Nlc3NvcikgOiAnJykgKyAnPC9zcGFuPicgKwoKICAgICc8L3NwYW4+JyArCgogICAgKGQuYmFkZ2UgPyAnPHNwYW4gY2xhc3M9InB3LXJjLWJhZGdlICcgKyBkLmJhZGdlQ2xzICsgJyI+JyArIGQuYmFkZ2UgKyAnPC9zcGFuPicgOiAnJykgKwoKICAnPC9kaXY+JzsKCgoKICBpZiAoZC51bmF2YWlsKSB7CgogICAgcmV0dXJuICc8ZGl2IGNsYXNzPSJwdy1yZXMtY2FyZCI+JyArIGhlYWQgKwoKICAgICAgJzxkaXYgY2xhc3M9InB3LXJjLWJvZHkiPjxkaXYgY2xhc3M9InB3LXVuYXZhaWwiPicgKwoKICAgICAgICAnPHNwYW4gY2xhc3M9InB3LXVuYXZhaWwtaWNvbiIgYXJpYS1oaWRkZW49InRydWUiPjxzdmcgd2lkdGg9IjM2IiBoZWlnaHQ9IjM2IiB2aWV3Qm94PSIwIDAgMzYgMzYiIGZpbGw9Im5vbmUiIHN0eWxlPSJkaXNwbGF5OmJsb2NrO21hcmdpbjowIGF1dG8gMTJweCIgYXJpYS1oaWRkZW49InRydWUiPjxyZWN0IHg9IjUiIHk9IjQiIHdpZHRoPSIyNiIgaGVpZ2h0PSIzMCIgcng9IjMiIHN0cm9rZT0iI2FkYjdjNSIgc3Ryb2tlLXdpZHRoPSIyIi8+PHBhdGggZD0iTTExIDEyaDE0TTExIDE4aDE0TTExIDI0aDkiIHN0cm9rZT0iI2FkYjdjNSIgc3Ryb2tlLXdpZHRoPSIxLjgiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvc3ZnPjwvc3Bhbj4nICsKCiAgICAgICAgJzxwPicgKyBkLm1zZyArICc8L3A+JyArCgogICAgICAnPC9kaXY+PC9kaXY+PC9kaXY+JzsKCiAgfQoKCgogIHZhciBpZCA9IHVpZCgpOwoKICB2YXIgd2YgPSBXRl9EQVRBW2tleV07CgogIHZhciBzdGVwc0lkID0gJ3N0XycgKyBpZCwgZmVlc0lkID0gJ2ZlXycgKyBpZCwgZG9jc0lkID0gJ2RvXycgKyBpZDsKCgoKICB2YXIgYm9keSA9ICc8ZGl2IGNsYXNzPSJwdy1yYy1ib2R5Ij4nOwoKCgogIGlmIChkLmVsaWdpYmlsaXR5KSB7CgogICAgYm9keSArPSAnPHNwYW4gY2xhc3M9InB3LWVsaWdpYmlsaXR5Ij48c3Ryb25nPkVsaWdpYmlsaXR5OiA8L3N0cm9uZz4nICsgZC5lbGlnaWJpbGl0eSArICc8L3NwYW4+JzsKCiAgfQoKCgogIC8vIFN0ZXBzCgogIGJvZHkgKz0gJzxkaXYgY2xhc3M9InB3LWFjYyI+JyArCgogICAgJzxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0icHctYWNjLWJ0biIgZGF0YS1hY2M9IicgKyBzdGVwc0lkICsgJyI+JyArCgogICAgICAnUmVnaXN0cmF0aW9uIEpvdXJuZXkgKCcgKyBkLnN0ZXBzLmxlbmd0aCArICcgc3RlcHMpIDxzcGFuIGNsYXNzPSJwdy1hY2MtaWNvbiI+4pa+PC9zcGFuPicgKwoKICAgICc8L2J1dHRvbj4nICsKCiAgICAnPGRpdiBjbGFzcz0icHctYWNjLWJvZHkiIGlkPSInICsgc3RlcHNJZCArICciPic7CgogIGQuc3RlcHMuZm9yRWFjaChmdW5jdGlvbihzLCBpKSB7CgogICAgdmFyIHRhZ3MgPSAocy50YWdzfHxbXSkubWFwKGZ1bmN0aW9uKHQpewoKICAgICAgcmV0dXJuICc8c3BhbiBjbGFzcz0icHctdGFnIHB3LXRhZy0nICsgdC50ICsgJyI+JyArIGVzYyh0LnYpICsgJzwvc3Bhbj4nOwoKICAgIH0pLmpvaW4oJycpOwoKICAgIHZhciBsaXN0ID0gKHMubGlzdCAmJiBzLmxpc3QubGVuZ3RoKQoKICAgICAgPyAnPHVsPicgKyBzLmxpc3QubWFwKGZ1bmN0aW9uKGxpKXsgcmV0dXJuICc8bGk+JyArIGVzYyhsaSkgKyAnPC9saT4nOyB9KS5qb2luKCcnKSArICc8L3VsPicgOiAnJzsKCiAgICBib2R5ICs9ICc8ZGl2IGNsYXNzPSJwdy1zdGVwLXJvdyI+JyArCgogICAgICAnPGRpdiBjbGFzcz0icHctc3RlcC1udW0iPicgKyAoaSsxKSArICc8L2Rpdj4nICsKCiAgICAgICc8ZGl2IGNsYXNzPSJwdy1zdGVwLWNvbnRlbnQiPicgKwoKICAgICAgICAnPGg1PicgKyBlc2Mocy50aXRsZSkgKyAnPC9oNT4nICsKCiAgICAgICAgJzxwPicgKyBzLmRlc2MgKyAnPC9wPicgKyBsaXN0ICsKCiAgICAgICAgKHRhZ3MgPyAnPGRpdiBjbGFzcz0icHctdGFncyI+JyArIHRhZ3MgKyAnPC9kaXY+JyA6ICcnKSArCgogICAgICAnPC9kaXY+PC9kaXY+JzsKCiAgfSk7CgogIGJvZHkgKz0gJzwvZGl2PjwvZGl2Pic7CgoKCiAgLy8gRmVlcwoKICBpZiAoZC5mZWVzICYmIGQuZmVlcy5sZW5ndGgpIHsKCiAgICBib2R5ICs9ICc8ZGl2IGNsYXNzPSJwdy1hY2MiPicgKwoKICAgICAgJzxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0icHctYWNjLWJ0biIgZGF0YS1hY2M9IicgKyBmZWVzSWQgKyAnIj4nICsKCiAgICAgICAgJ0ZlZSBTdW1tYXJ5IDxzcGFuIGNsYXNzPSJwdy1hY2MtaWNvbiI+4pa+PC9zcGFuPicgKwoKICAgICAgJzwvYnV0dG9uPicgKwoKICAgICAgJzxkaXYgY2xhc3M9InB3LWFjYy1ib2R5IiBpZD0iJyArIGZlZXNJZCArICciPic7CgogICAgZC5mZWVzLmZvckVhY2goZnVuY3Rpb24oZil7CgogICAgICBib2R5ICs9ICc8ZGl2IGNsYXNzPSJwdy1mZWUtcm93JyArIChmLnRvdGFsPycgcHctZmVlLXRvdGFsJzonJykgKyAnIj4nICsKCiAgICAgICAgJzxzcGFuPicgKyBlc2MoZi5sYWJlbCkgKyAnPC9zcGFuPicgKwoKICAgICAgICAnPHNwYW4gY2xhc3M9InB3LWZlZS1hbXQiPicgKyBlc2MoZi5hbXQpICsgJzwvc3Bhbj48L2Rpdj4nOwoKICAgIH0pOwoKICAgIGJvZHkgKz0gJzwvZGl2PjwvZGl2Pic7CgogIH0KCgoKICAvLyBEb2NzCgogIGlmIChkLmRvY3MgJiYgZC5kb2NzLmxlbmd0aCkgewoKICAgIGJvZHkgKz0gJzxkaXYgY2xhc3M9InB3LWFjYyI+JyArCgogICAgICAnPGJ1dHRvbiB0eXBlPSJidXR0b24iIGNsYXNzPSJwdy1hY2MtYnRuIiBkYXRhLWFjYz0iJyArIGRvY3NJZCArICciPicgKwoKICAgICAgICAnRG9jdW1lbnQgQ2hlY2tsaXN0ICgnICsgZC5kb2NzLmxlbmd0aCArICcgaXRlbXMpIDxzcGFuIGNsYXNzPSJwdy1hY2MtaWNvbiI+4pa+PC9zcGFuPicgKwoKICAgICAgJzwvYnV0dG9uPicgKwoKICAgICAgJzxkaXYgY2xhc3M9InB3LWFjYy1ib2R5IiBpZD0iJyArIGRvY3NJZCArICciPicgKwoKICAgICAgICAnPHVsIGNsYXNzPSJwdy1kb2NzIHB3LWRvY3MtY2hlY2siIGlkPSInICsgZG9jc0lkICsgJy1saXN0Ij4nICsKCiAgICAgICAgICBkLmRvY3MubWFwKGZ1bmN0aW9uKGRvYywgaSkgewoKICAgICAgICAgICAgdmFyIGNiSWQgPSBkb2NzSWQgKyAnX2MnICsgaTsKCiAgICAgICAgICAgIHJldHVybiAnPGxpIGNsYXNzPSJwdy1kb2MtaXRlbSI+PGxhYmVsIGNsYXNzPSJwdy1kb2MtbGFiZWwiIGZvcj0iJyArIGNiSWQgKyAnIj48aW5wdXQgdHlwZT0iY2hlY2tib3giIGNsYXNzPSJwdy1kb2MtY2IiIGlkPSInICsgY2JJZCArICciIGRhdGEtZG9jcy1saXN0PSInICsgZG9jc0lkICsgJy1saXN0Ij4gPHNwYW4+JyArIGVzYyhkb2MpICsgJzwvc3Bhbj48L2xhYmVsPjwvbGk+JzsKCiAgICAgICAgICB9KS5qb2luKCcnKSArCgogICAgICAgICc8L3VsPicgKwoKICAgICAgICAnPGRpdiBjbGFzcz0icHctcmVhZHktbXNnIiBpZD0iJyArIGRvY3NJZCArICctcmVhZHkiPicgKwoKICAgICAgICAgICc8c3ZnIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgdmlld0JveD0iMCAwIDE4IDE4IiBmaWxsPSJub25lIiBhcmlhLWhpZGRlbj0idHJ1ZSI+PGNpcmNsZSBjeD0iOSIgY3k9IjkiIHI9IjkiIGZpbGw9IiMwMDNhNWEiLz48cGF0aCBkPSJNNSA5bDMgMyA1LTUiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4nICsKCiAgICAgICAgICAnIFlvdVx1MjAxOXZlIHJldmlld2VkIGFsbCByZXF1aXJlZCBkb2N1bWVudHMgXHUyMDE0IHlvdVx1MjAxOXJlIHJlYWR5IHRvIGFwcGx5IScgKwoKICAgICAgICAnPC9kaXY+JyArCgogICAgICAnPC9kaXY+PC9kaXY+JzsKCiAgfQoKCgoKCiAgLy8gV29ya2ZvcmNlIGRhdGEKCiAgaWYgKHdmKSB7CgogICAgdmFyIGllblBjdCA9IHdmLnRvdGFsSW5mbG93ID4gMCA/IE1hdGgucm91bmQod2YuaWVuSW5mbG93IC8gd2YudG90YWxJbmZsb3cgKiAxMDApIDogMDsKCiAgICB2YXIgd2ZJZCA9ICd3Zl8nICsgaWQ7CgogICAgdmFyIHdhZ2VzSHRtbCA9ICcnOwoKICAgIHZhciB0YWJBY2NJZCA9ICd0Yl8nICsgaWQ7CgogICAgdmFyIHRhYlZpeklkID0gJ3Zpel9wd18nICsgaWQ7CgogICAgdmFyIHRhYmxlYXVIdG1sID0gJzxkaXYgY2xhc3M9InB3LWFjYyBwdy10YWItYWNjIj4nICsKCiAgICAgICc8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9InB3LWFjYy1idG4gcHctdGFiLWJ0biIgZGF0YS1hY2M9IicgKyB0YWJBY2NJZCArICciIGRhdGEtdGFibGVhdS12aXo9IicgKyB0YWJWaXpJZCArICciPicgKwoKICAgICAgICAnRXhwbG9yZSBNb3JlIENlbnN1cyBEYXRhIDxzcGFuIGNsYXNzPSJwdy1hY2MtaWNvbiI+4pa+PC9zcGFuPicgKwoKICAgICAgJzwvYnV0dG9uPicgKwoKICAgICAgJzxkaXYgY2xhc3M9InB3LWFjYy1ib2R5IHB3LXRhYi1ib2R5IiBpZD0iJyArIHRhYkFjY0lkICsgJyI+JyArCgogICAgICAgICc8ZGl2IGNsYXNzPSJwdy10YWItd3JhcCIgaWQ9IicgKyB0YWJWaXpJZCArICciPicgKwoKICAgICAgICAgICc8ZGl2IGNsYXNzPSJ0YWJsZWF1UGxhY2Vob2xkZXIiIHN0eWxlPSJwb3NpdGlvbjpyZWxhdGl2ZTt3aWR0aDoxMDAlO2hlaWdodDo4NjBweCI+JyArCgogICAgICAgICAgICAnPG5vc2NyaXB0PjxhIGhyZWY9IiMiPlZpZXcgdGhlIGludGVyYWN0aXZlIGRhc2hib2FyZCBvbiBUYWJsZWF1IFB1YmxpYzwvYT48L25vc2NyaXB0PicgKwoKICAgICAgICAgICAgJzxvYmplY3QgY2xhc3M9InRhYmxlYXVWaXoiIHN0eWxlPSJkaXNwbGF5Om5vbmU7d2lkdGg6MTAwJTtoZWlnaHQ6ODYwcHgiPicgKwoKICAgICAgICAgICAgICAnPHBhcmFtIG5hbWU9Imhvc3RfdXJsIiB2YWx1ZT0iaHR0cHMlM0ElMkYlMkZwdWJsaWMudGFibGVhdS5jb20lMkYiIC8+JyArCgogICAgICAgICAgICAgICc8cGFyYW0gbmFtZT0iZW1iZWRfY29kZV92ZXJzaW9uIiB2YWx1ZT0iMyIgLz4nICsKCiAgICAgICAgICAgICAgJzxwYXJhbSBuYW1lPSJzaXRlX3Jvb3QiIHZhbHVlPSIiIC8+JyArCgogICAgICAgICAgICAgICc8cGFyYW0gbmFtZT0ibmFtZSIgdmFsdWU9ImludGVyYWN0aXZlLXBhdGh3YXktZGFzaGJvYXJkJiM0NztpbnRlcmFjdGl2ZS1wYXRod2F5LWRhc2hib2FyZC1wYWdlLTEiIC8+JyArCgogICAgICAgICAgICAgICc8cGFyYW0gbmFtZT0idGFicyIgdmFsdWU9Im5vIiAvPicgKwoKICAgICAgICAgICAgICAnPHBhcmFtIG5hbWU9InRvb2xiYXIiIHZhbHVlPSJ5ZXMiIC8+JyArCgogICAgICAgICAgICAgICc8cGFyYW0gbmFtZT0iYW5pbWF0ZV90cmFuc2l0aW9uIiB2YWx1ZT0ieWVzIiAvPicgKwoKICAgICAgICAgICAgICAnPHBhcmFtIG5hbWU9ImRpc3BsYXlfc3RhdGljX2ltYWdlIiB2YWx1ZT0ieWVzIiAvPicgKwoKICAgICAgICAgICAgICAnPHBhcmFtIG5hbWU9ImRpc3BsYXlfc3Bpbm5lciIgdmFsdWU9InllcyIgLz4nICsKCiAgICAgICAgICAgICAgJzxwYXJhbSBuYW1lPSJkaXNwbGF5X292ZXJsYXkiIHZhbHVlPSJ5ZXMiIC8+JyArCgogICAgICAgICAgICAgICc8cGFyYW0gbmFtZT0iZGlzcGxheV9jb3VudCIgdmFsdWU9InllcyIgLz4nICsKCiAgICAgICAgICAgICAgJzxwYXJhbSBuYW1lPSJsYW5ndWFnZSIgdmFsdWU9ImVuLVVTIiAvPicgKwoKICAgICAgICAgICAgJzwvb2JqZWN0PicgKwoKICAgICAgICAgICc8L2Rpdj4nICsKCiAgICAgICAgICAnPHAgY2xhc3M9InB3LXRhYi1ub3RlIj5Tb3VyY2U6IE5OQVMgSW50ZXJhY3RpdmUgUGF0aHdheSBEYXNoYm9hcmQgwrcgPGEgaHJlZj0iaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vYXBwL3Byb2ZpbGUvZWRkaWUucGhhbTY4NzUvdml6L2ludGVyYWN0aXZlLXBhdGh3YXktZGFzaGJvYXJkL2ludGVyYWN0aXZlLXBhdGh3YXktZGFzaGJvYXJkLXBhZ2UtMSIgdGFyZ2V0PSJfYmxhbmsiIHJlbD0ibm9vcGVuZXIiPlZpZXcgZnVsbCBkYXNoYm9hcmQg4oaXPC9hPjwvcD4nICsKCiAgICAgICAgJzwvZGl2PicgKwoKICAgICAgJzwvZGl2PicgKwoKICAgICc8L2Rpdj4nOwoKICAgIGlmICh3Zi53YWdlcykgewoKICAgICAgdmFyIHcgPSB3Zi53YWdlczsKCiAgICAgIHdhZ2VzSHRtbCA9CgogICAgICAgICc8ZGl2IGNsYXNzPSJwdy13Zi1zZWN0aW9uIHB3LXdmLXdhZ2VzLXNlY3Rpb24iPicgKwoKICAgICAgICAgICc8ZGl2IGNsYXNzPSJwdy13Zi1zZWN0aW9uLXRpdGxlIj5Ib3VybHkgV2FnZXMgKCcgKyB3LndhZ2VZZWFyICsgJyk8L2Rpdj4nICsKCiAgICAgICAgICAnPGRpdiBjbGFzcz0icHctd2Ytd2FnZXMiPicgKwoKICAgICAgICAgICAgJzxkaXYgY2xhc3M9InB3LXdmLXdhZ2UgcHctd2Ytd2FnZS1sb3ciPjxzcGFuIGNsYXNzPSJwdy13Zi13YWdlLXZhbCI+JCcgKyB3Lmxvdy50b0ZpeGVkKDIpICsgJzwvc3Bhbj48c3BhbiBjbGFzcz0icHctd2Ytd2FnZS1sYmwiPkxvdzwvc3Bhbj48L2Rpdj4nICsKCiAgICAgICAgICAgICc8ZGl2IGNsYXNzPSJwdy13Zi13YWdlIHB3LXdmLXdhZ2UtbWVkIj48c3BhbiBjbGFzcz0icHctd2Ytd2FnZS12YWwiPiQnICsgdy5tZWRpYW4udG9GaXhlZCgyKSArICc8L3NwYW4+PHNwYW4gY2xhc3M9InB3LXdmLXdhZ2UtbGJsIj5NZWRpYW48L3NwYW4+PC9kaXY+JyArCgogICAgICAgICAgICAnPGRpdiBjbGFzcz0icHctd2Ytd2FnZSBwdy13Zi13YWdlLWhpZ2giPjxzcGFuIGNsYXNzPSJwdy13Zi13YWdlLXZhbCI+JCcgKyB3LmhpZ2gudG9GaXhlZCgyKSArICc8L3NwYW4+PHNwYW4gY2xhc3M9InB3LXdmLXdhZ2UtbGJsIj5IaWdoPC9zcGFuPjwvZGl2PicgKwoKICAgICAgICAgICc8L2Rpdj4nICsKCiAgICAgICAgICAnPGRpdiBjbGFzcz0icHctd2Ytd2FnZS1zb3VyY2UiPlNvdXJjZTogR292ZXJubWVudCBvZiBDYW5hZGEgSm9iIEJhbmsgJyArIHcud2FnZVllYXIgKyAnPC9kaXY+JyArCgogICAgICAgICc8L2Rpdj4nOwoKICAgIH0KCiAgICBib2R5ICs9ICc8ZGl2IGNsYXNzPSJwdy1hY2MiPicgKwoKICAgICAgJzxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0icHctYWNjLWJ0biIgZGF0YS1hY2M9IicgKyB3ZklkICsgJyI+JyArCgogICAgICAgICdXb3JrZm9yY2UgRGF0YSAoJyArIHdmLnllYXIgKyAnKSA8c3BhbiBjbGFzcz0icHctYWNjLWljb24iPuKWvjwvc3Bhbj4nICsKCiAgICAgICc8L2J1dHRvbj4nICsKCiAgICAgICc8ZGl2IGNsYXNzPSJwdy1hY2MtYm9keSIgaWQ9IicgKyB3ZklkICsgJyI+JyArCgogICAgICAgICc8ZGl2IGNsYXNzPSJwdy13Zi1zdGF0cyI+JyArCgogICAgICAgICAgJzxkaXYgY2xhc3M9InB3LXdmLXN0YXQiPjxzcGFuIGNsYXNzPSJwdy13Zi12YWwiPicgKyBOdW1iZXIod2YudG90YWwpLnRvTG9jYWxlU3RyaW5nKCkgKyAnPC9zcGFuPjxzcGFuIGNsYXNzPSJwdy13Zi1sYmwiPlJlZ2lzdGVyZWQgaW4gcHJvdmluY2U8L3NwYW4+PC9kaXY+JyArCgogICAgICAgICAgJzxkaXYgY2xhc3M9InB3LXdmLXN0YXQiPjxzcGFuIGNsYXNzPSJwdy13Zi12YWwiPicgKyBOdW1iZXIod2YuaWVuSW5mbG93KS50b0xvY2FsZVN0cmluZygpICsgJzwvc3Bhbj48c3BhbiBjbGFzcz0icHctd2YtbGJsIj5JRU4gbmV3IHJlZ2lzdHJhbnRzPC9zcGFuPjwvZGl2PicgKwoKICAgICAgICAgICc8ZGl2IGNsYXNzPSJwdy13Zi1zdGF0Ij48c3BhbiBjbGFzcz0icHctd2YtdmFsIj4nICsgaWVuUGN0ICsgJyU8L3NwYW4+PHNwYW4gY2xhc3M9InB3LXdmLWxibCI+b2YgbmV3IHJlZ2lzdHJhbnRzIGFyZSBJRU48L3NwYW4+PC9kaXY+JyArCgogICAgICAgICc8L2Rpdj4nICsKCiAgICAgICAgd2FnZXNIdG1sICsKCiAgICAgICAgdGFibGVhdUh0bWwgKwoKICAgICAgICAnPGRpdiBjbGFzcz0icHctd2Ytc2VjdGlvbiI+PGRpdiBjbGFzcz0icHctd2Ytc2VjdGlvbi10aXRsZSI+RW1wbG95bWVudCBTZXR0aW5nPC9kaXY+JyArIHJlbmRlcldmQmFycyh3Zi53b3JrcGxhY2VzKSArICc8L2Rpdj4nICsKCiAgICAgICAgJzxkaXYgY2xhc3M9InB3LXdmLXNlY3Rpb24iPjxkaXYgY2xhc3M9InB3LXdmLXNlY3Rpb24tdGl0bGUiPkVtcGxveW1lbnQgVHlwZTwvZGl2PicgKyByZW5kZXJXZkJhcnMod2YuZW1wbG95bWVudCkgKyAnPC9kaXY+JyArCgogICAgICAgICc8ZGl2IGNsYXNzPSJwdy13Zi1ub3RlIj5Xb3JrZm9yY2Ugc291cmNlOiBDSUhJIE51cnNpbmcgRGF0YWJhc2UgJyArIHdmLnllYXIgKyAod2Yubm90ZSA/ICcg4oCUICcgKyB3Zi5ub3RlIDogJycpICsgJy4gRGF0YSByZXByZXNlbnRzIGFsbCBudXJzZXMgcmVnaXN0ZXJlZCBpbiB0aGUgcHJvdmluY2UsIG5vdCBvbmx5IElFTnMuPC9kaXY+JyArCgogICAgICAnPC9kaXY+PC9kaXY+JzsKCiAgfQoKCgogIGlmIChkLm5uYXMpIHsKICAgIGJvZHkgKz0gJzxhIGNsYXNzPSJwdy1ubmFzLWN0YSIgaHJlZj0iaHR0cHM6Ly9teS5ubmFzLmNhL25uYXN3ZWIvc3lzdGVtL0lFTi8xIiB0YXJnZXQ9Il9ibGFuayIgcmVsPSJub29wZW5lciI+QXBwbHkgd2l0aCBOTkFTIOKGlzwvYT4nOwogIH0KICBib2R5ICs9ICc8YSBjbGFzcz0icHctcmVnLWxpbmsiIGhyZWY9IicgKyBlc2MoZC51cmwpICsgJyIgdGFyZ2V0PSJfYmxhbmsiIHJlbD0ibm9vcGVuZXIiPlZpc2l0ICcgKyBlc2MoZC5yZWd1bGF0b3IpICsgJyDihpc8L2E+JzsKCiAgYm9keSArPSAnPC9kaXY+JzsKCgoKICBpZiAoZC5jb250YWN0KSB7CgogICAgdmFyIGNzID0gJzxkaXYgY2xhc3M9InB3LWNvbnRhY3Qtc3RyaXAiPic7CgogICAgY3MgKz0gJzxzcGFuIGNsYXNzPSJwdy1jb250YWN0LWl0ZW0iPjxzdmcgd2lkdGg9IjEzIiBoZWlnaHQ9IjEzIiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgYXJpYS1oaWRkZW49InRydWUiPjxwYXRoIGQ9Ik0yMiAxNi45MnYzYTIgMiAwIDAxLTIuMTggMiAxOS43OSAxOS43OSAwIDAxLTguNjMtMy4wN0ExOS41IDE5LjUgMCAwMTMuMDcgOC44MSAxOS43OSAxOS43OSAwIDAxMCAyLjE4IDIgMiAwIDAxMiAwaDNhMiAyIDAgMDEyIDEuNzJjLjEyNy45Ni4zNjEgMS45MDMuNyAyLjgxYTIgMiAwIDAxLS40NSAyLjExTDYuMDkgNy45MWExNiAxNiAwIDAwNiA2bDEuMjctMS4yN2EyIDIgMCAwMTIuMTEtLjQ1Yy45MDcuMzM5IDEuODUuNTczIDIuODEuN0EyIDIgMCAwMTIyIDE0LjkydjJ6Ii8+PC9zdmc+IDxhIGhyZWY9InRlbDonICsgZC5jb250YWN0LnBob25lLnJlcGxhY2UoL1teMC05K10vZywnJykgKyAnIj4nICsgZC5jb250YWN0LnBob25lICsgJzwvYT48L3NwYW4+JzsKCiAgICBpZiAoZC5jb250YWN0LmVtYWlsKSB7CgogICAgICBjcyArPSAnPHNwYW4gY2xhc3M9InB3LWNvbnRhY3QtaXRlbSI+PHN2ZyB3aWR0aD0iMTMiIGhlaWdodD0iMTMiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBhcmlhLWhpZGRlbj0idHJ1ZSI+PHBhdGggZD0iTTQgNGgxNmMxLjEgMCAyIC45IDIgMnYxMmMwIDEuMS0uOSAyLTIgMkg0Yy0xLjEgMC0yLS45LTItMlY2YzAtMS4xLjktMiAyLTJ6Ii8+PHBvbHlsaW5lIHBvaW50cz0iMjIsNiAxMiwxMyAyLDYiLz48L3N2Zz4gPGEgaHJlZj0ibWFpbHRvOicgKyBkLmNvbnRhY3QuZW1haWwgKyAnIj4nICsgZC5jb250YWN0LmVtYWlsICsgJzwvYT48L3NwYW4+JzsKCiAgICB9CgogICAgY3MgKz0gJzwvZGl2Pic7CgogICAgYm9keSArPSBjczsKCiAgfQoKCgogIHJldHVybiAnPGRpdiBjbGFzcz0icHctcmVzLWNhcmQiPicgKyBoZWFkICsgYm9keSArICc8L2Rpdj4nOwoKfQoKCgovKiDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAKCiAgIFdJWkFSRCBDT05UUk9MTEVSCgogICDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAgKi8KCnZhciByb290ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25uYXMtcGF0aHdheXMnKTsKCmlmICghcm9vdCkgcmV0dXJuOwoKCgp2YXIgU1RFUFMgPSBbJ3MxJywnczInLCdzMycsJ3Jlc3VsdHMnXTsKCgoKZnVuY3Rpb24gc2hvd1N0ZXAoaWQpIHsKCiAgU1RFUFMuZm9yRWFjaChmdW5jdGlvbihrKSB7CgogICAgdmFyIGVsID0gcm9vdC5xdWVyeVNlbGVjdG9yKCcjcHctJyArIGspOwoKICAgIGlmICghZWwpIHJldHVybjsKCiAgICBlbC5jbGFzc05hbWUgPSBlbC5jbGFzc05hbWUucmVwbGFjZSgnIHB3LXN0ZXAtYWN0aXZlJywnJykucmVwbGFjZSgncHctc3RlcC1hY3RpdmUnLCcnKS50cmltKCk7CgogICAgZWwuc3R5bGUuZGlzcGxheSA9ICdub25lJzsKCiAgfSk7CgogIHZhciB0YXJnZXQgPSByb290LnF1ZXJ5U2VsZWN0b3IoJyNwdy0nICsgaWQpOwoKICBpZiAodGFyZ2V0KSB7CgogICAgdGFyZ2V0LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOwoKICAgIHRhcmdldC5jbGFzc05hbWUgPSAodGFyZ2V0LmNsYXNzTmFtZSArICcgcHctc3RlcC1hY3RpdmUnKS50cmltKCk7CgogIH0KCgoKICAvLyBVcGRhdGUgcHJvZ3Jlc3MgaW5kaWNhdG9ycwoKICB2YXIgb3JkZXIgPSB7IHMxOicxJywgczI6JzInLCBzMzonMycsIHJlc3VsdHM6J1InIH07CgogIHZhciBjdXIgPSBvcmRlcltpZF07CgogIHJvb3QucXVlcnlTZWxlY3RvckFsbCgnLnB3LXBpJykuZm9yRWFjaChmdW5jdGlvbihwaSkgewoKICAgIHZhciBuID0gcGkuZ2V0QXR0cmlidXRlKCdkYXRhLXBzdGVwJyk7CgogICAgcGkuY2xhc3NOYW1lID0gJ3B3LXBpJzsKCiAgICBpZiAobiA9PT0gY3VyKSBwaS5jbGFzc05hbWUgKz0gJyBwdy1waS1hY3RpdmUnOwoKICAgIGVsc2UgaWYgKChjdXIgIT09ICdSJyAmJiBwYXJzZUludChuKSA8IHBhcnNlSW50KGN1cikpIHx8IChjdXIgPT09ICdSJyAmJiBuICE9PSAnUicpKSBwaS5jbGFzc05hbWUgKz0gJyBwdy1waS1kb25lJzsKCiAgfSk7Cgp9CgoKCi8qIFNpbmdsZSBkZWxlZ2F0ZWQgZXZlbnQgaGFuZGxlciAqLwoKZnVuY3Rpb24gaGFuZGxlSW50ZXJhY3Rpb24odGFyZ2V0KSB7CgogIHZhciBhY3Rpb24gPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWFjdGlvbicpOwoKICBpZiAoIWFjdGlvbikgewoKICAgIC8vIENoZWNrIGFuY2VzdG9ycwoKICAgIHZhciBlbCA9IHRhcmdldC5wYXJlbnRFbGVtZW50OwoKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNSAmJiBlbCAmJiBlbCAhPT0gcm9vdDsgaSsrKSB7CgogICAgICBhY3Rpb24gPSBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtYWN0aW9uJyk7CgogICAgICBpZiAoYWN0aW9uKSB7IHRhcmdldCA9IGVsOyBicmVhazsgfQoKICAgICAgZWwgPSBlbC5wYXJlbnRFbGVtZW50OwoKICAgIH0KCiAgfQoKICBpZiAoIWFjdGlvbikgcmV0dXJuOwoKCgogIC8qIExpY2VuY2UgdHlwZSBzZWxlY3Rpb24gKi8KCiAgaWYgKGFjdGlvbiA9PT0gJ2xpYycpIHsKCiAgICByb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWFjdGlvbj0ibGljIl0nKS5mb3JFYWNoKGZ1bmN0aW9uKGMpIHsKCiAgICAgIGMuY2xhc3NOYW1lID0gYy5jbGFzc05hbWUucmVwbGFjZSgnIHB3LWNhcmQtc2VsJywnJykucmVwbGFjZSgncHctY2FyZC1zZWwnLCcnKS50cmltKCk7CgogICAgICBjLnNldEF0dHJpYnV0ZSgnYXJpYS1jaGVja2VkJywnZmFsc2UnKTsKCiAgICB9KTsKCiAgICB0YXJnZXQuY2xhc3NOYW1lID0gKHRhcmdldC5jbGFzc05hbWUgKyAnIHB3LWNhcmQtc2VsJykudHJpbSgpOwoKICAgIHRhcmdldC5zZXRBdHRyaWJ1dGUoJ2FyaWEtY2hlY2tlZCcsJ3RydWUnKTsKCiAgICBTLmxpYyA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtbGljJyk7CgogICAgUy5wcm92cyA9IFtdOwoKICAgIFMuY291bnRyeSA9IG51bGw7CgogICAgLy8gcmVzZXQgcHJvdmluY2UgY2FyZHMKCiAgICByb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWFjdGlvbj0icHJvdiJdJykuZm9yRWFjaChmdW5jdGlvbihjKSB7CgogICAgICBjLmNsYXNzTmFtZSA9IGMuY2xhc3NOYW1lLnJlcGxhY2UoJyBwdy1wY2FyZC1zZWwnLCcnKS5yZXBsYWNlKCdwdy1wY2FyZC1zZWwnLCcnKS50cmltKCk7CgogICAgICBjLnNldEF0dHJpYnV0ZSgnYXJpYS1jaGVja2VkJywnZmFsc2UnKTsKCiAgICB9KTsKCiAgICB2YXIgbmV4dEJ0biA9IHJvb3QucXVlcnlTZWxlY3RvcignI3B3LXMyLW5leHQnKTsKCiAgICBpZiAobmV4dEJ0bikgewoKICAgICAgbmV4dEJ0bi5jbGFzc05hbWUgPSBuZXh0QnRuLmNsYXNzTmFtZS5yZXBsYWNlKCcgcHctZGlzYWJsZWQnLCcnKS5yZXBsYWNlKCdwdy1kaXNhYmxlZCcsJycpLnRyaW0oKSArICcgcHctZGlzYWJsZWQnOwoKICAgIH0KCiAgICByb290LnF1ZXJ5U2VsZWN0b3IoJyNwdy1zMi1oaW50JykudGV4dENvbnRlbnQgPSAnU2VsZWN0IGF0IGxlYXN0IG9uZSBwcm92aW5jZSc7CgogICAgc2V0VGltZW91dChmdW5jdGlvbigpeyBzaG93U3RlcCgnczInKTsgfSwgMjAwKTsKCiAgICByZXR1cm47CgogIH0KCgoKICAvKiBQcm92aW5jZSBzZWxlY3Rpb24gKG11bHRpKSAqLwoKICBpZiAoYWN0aW9uID09PSAncHJvdicpIHsKCiAgICB2YXIgaXNTZWwgPSB0YXJnZXQuY2xhc3NOYW1lLmluZGV4T2YoJ3B3LXBjYXJkLXNlbCcpID4gLTE7CgogICAgaWYgKGlzU2VsKSB7CgogICAgICB0YXJnZXQuY2xhc3NOYW1lID0gdGFyZ2V0LmNsYXNzTmFtZS5yZXBsYWNlKCcgcHctcGNhcmQtc2VsJywnJykucmVwbGFjZSgncHctcGNhcmQtc2VsJywnJykudHJpbSgpOwoKICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZSgnYXJpYS1jaGVja2VkJywnZmFsc2UnKTsKCiAgICB9IGVsc2UgewoKICAgICAgdGFyZ2V0LmNsYXNzTmFtZSA9ICh0YXJnZXQuY2xhc3NOYW1lICsgJyBwdy1wY2FyZC1zZWwnKS50cmltKCk7CgogICAgICB0YXJnZXQuc2V0QXR0cmlidXRlKCdhcmlhLWNoZWNrZWQnLCd0cnVlJyk7CgogICAgfQoKICAgIFMucHJvdnMgPSBbXTsKCiAgICByb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWFjdGlvbj0icHJvdiJdJykuZm9yRWFjaChmdW5jdGlvbihjKSB7CgogICAgICBpZiAoYy5jbGFzc05hbWUuaW5kZXhPZigncHctcGNhcmQtc2VsJykgPiAtMSkgUy5wcm92cy5wdXNoKGMuZ2V0QXR0cmlidXRlKCdkYXRhLXByb3YnKSk7CgogICAgfSk7CgogICAgdmFyIG5leHRCdG4gPSByb290LnF1ZXJ5U2VsZWN0b3IoJyNwdy1zMi1uZXh0Jyk7CgogICAgaWYgKG5leHRCdG4pIHsKCiAgICAgIGlmIChTLnByb3ZzLmxlbmd0aCA+IDApIHsKCiAgICAgICAgbmV4dEJ0bi5jbGFzc05hbWUgPSBuZXh0QnRuLmNsYXNzTmFtZS5yZXBsYWNlKCcgcHctZGlzYWJsZWQnLCcnKS5yZXBsYWNlKCdwdy1kaXNhYmxlZCcsJycpLnRyaW0oKTsKCiAgICAgIH0gZWxzZSB7CgogICAgICAgIG5leHRCdG4uY2xhc3NOYW1lID0gKG5leHRCdG4uY2xhc3NOYW1lICsgJyBwdy1kaXNhYmxlZCcpLnRyaW0oKTsKCiAgICAgIH0KCiAgICB9CgogICAgcm9vdC5xdWVyeVNlbGVjdG9yKCcjcHctczItaGludCcpLnRleHRDb250ZW50ID0gUy5wcm92cy5sZW5ndGggPyBTLnByb3ZzLmxlbmd0aCArICcgcHJvdmluY2Uocykgc2VsZWN0ZWQnIDogJ1NlbGVjdCBhdCBsZWFzdCBvbmUgcHJvdmluY2UnOwoKICAgIHJldHVybjsKCiAgfQoKCgogIC8qIENvdW50cnkgc2VsZWN0aW9uICovCgogIGlmIChhY3Rpb24gPT09ICdjb3VudHJ5JykgewoKICAgIHJvb3QucXVlcnlTZWxlY3RvckFsbCgnW2RhdGEtYWN0aW9uPSJjb3VudHJ5Il0nKS5mb3JFYWNoKGZ1bmN0aW9uKGMpIHsKCiAgICAgIGMuY2xhc3NOYW1lID0gYy5jbGFzc05hbWUucmVwbGFjZSgnIHB3LWNjYXJkLXNlbCcsJycpLnJlcGxhY2UoJ3B3LWNjYXJkLXNlbCcsJycpLnRyaW0oKTsKCiAgICAgIGMuc2V0QXR0cmlidXRlKCdhcmlhLWNoZWNrZWQnLCdmYWxzZScpOwoKICAgIH0pOwoKICAgIHRhcmdldC5jbGFzc05hbWUgPSAodGFyZ2V0LmNsYXNzTmFtZSArICcgcHctY2NhcmQtc2VsJykudHJpbSgpOwoKICAgIHRhcmdldC5zZXRBdHRyaWJ1dGUoJ2FyaWEtY2hlY2tlZCcsJ3RydWUnKTsKCiAgICBTLmNvdW50cnkgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWNvdW50cnknKTsKCiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7IGJ1aWxkUmVzdWx0cygpOyBzaG93U3RlcCgncmVzdWx0cycpOyB9LCAyMDApOwoKICAgIHJldHVybjsKCiAgfQoKCgogIC8qIE5hdjogZ28gdG8gc3RlcCAxICovCgogIGlmIChhY3Rpb24gPT09ICdnby1zMScpIHsgc2hvd1N0ZXAoJ3MxJyk7IHJldHVybjsgfQoKCgogIC8qIE5hdjogZ28gdG8gc3RlcCAyICovCgogIGlmIChhY3Rpb24gPT09ICdnby1zMicpIHsgc2hvd1N0ZXAoJ3MyJyk7IHJldHVybjsgfQoKCgogIC8qIE5hdjogZ28gdG8gc3RlcCAzIG9yIHJlc3VsdHMgKi8KCiAgaWYgKGFjdGlvbiA9PT0gJ2dvLXMzJykgewoKICAgIGlmIChTLnByb3ZzLmxlbmd0aCA9PT0gMCkgcmV0dXJuOwoKICAgIHZhciBuZWVkQ291bnRyeSA9IFMubGljID09PSAncm4nICYmIChTLnByb3ZzLmluZGV4T2YoJ2JjJykgPiAtMSB8fCBTLnByb3ZzLmluZGV4T2YoJ21iJykgPiAtMSk7CgogICAgdmFyIHBpMyA9IHJvb3QucXVlcnlTZWxlY3RvcignI3B3LXBpMycpOwoKICAgIGlmIChwaTMpIHBpMy5zdHlsZS5kaXNwbGF5ID0gbmVlZENvdW50cnkgPyAnJyA6ICdub25lJzsKCiAgICBpZiAobmVlZENvdW50cnkpIHsKCiAgICAgIHJvb3QucXVlcnlTZWxlY3RvckFsbCgnW2RhdGEtYWN0aW9uPSJjb3VudHJ5Il0nKS5mb3JFYWNoKGZ1bmN0aW9uKGMpIHsKCiAgICAgICAgYy5jbGFzc05hbWUgPSBjLmNsYXNzTmFtZS5yZXBsYWNlKCcgcHctY2NhcmQtc2VsJywnJykucmVwbGFjZSgncHctY2NhcmQtc2VsJywnJykudHJpbSgpOwoKICAgICAgICBjLnNldEF0dHJpYnV0ZSgnYXJpYS1jaGVja2VkJywnZmFsc2UnKTsKCiAgICAgIH0pOwoKICAgICAgUy5jb3VudHJ5ID0gbnVsbDsKCiAgICAgIHNob3dTdGVwKCdzMycpOwoKICAgIH0gZWxzZSB7CgogICAgICBTLmNvdW50cnkgPSAnb3RoZXInOwoKICAgICAgYnVpbGRSZXN1bHRzKCk7CgogICAgICBzaG93U3RlcCgncmVzdWx0cycpOwoKICAgIH0KCiAgICByZXR1cm47CgogIH0KCgoKICAvKiBOYXY6IGdvIGJhY2sgZnJvbSByZXN1bHRzICovCgogIGlmIChhY3Rpb24gPT09ICdnby1iYWNrLXJlc3VsdHMnKSB7CgogICAgdmFyIG5lZWRDb3VudHJ5ID0gUy5saWMgPT09ICdybicgJiYgKFMucHJvdnMuaW5kZXhPZignYmMnKSA+IC0xIHx8IFMucHJvdnMuaW5kZXhPZignbWInKSA+IC0xKTsKCiAgICBzaG93U3RlcChuZWVkQ291bnRyeSA/ICdzMycgOiAnczInKTsKCiAgICByZXR1cm47CgogIH0KCgoKICAgIC8qIFJlc3RhcnQgKi8KCiAgaWYgKGFjdGlvbiA9PT0gJ3Jlc3RhcnQnKSB7CgogICAgUyA9IHsgbGljOiBudWxsLCBwcm92czogW10sIGNvdW50cnk6IG51bGwgfTsKCiAgICByb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWFjdGlvbj0ibGljIl0nKS5mb3JFYWNoKGZ1bmN0aW9uKGMpIHsKCiAgICAgIGMuY2xhc3NOYW1lID0gYy5jbGFzc05hbWUucmVwbGFjZSgnIHB3LWNhcmQtc2VsJywnJykucmVwbGFjZSgncHctY2FyZC1zZWwnLCcnKS50cmltKCk7CgogICAgICBjLnNldEF0dHJpYnV0ZSgnYXJpYS1jaGVja2VkJywnZmFsc2UnKTsKCiAgICB9KTsKCiAgICByb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWFjdGlvbj0icHJvdiJdJykuZm9yRWFjaChmdW5jdGlvbihjKSB7CgogICAgICBjLmNsYXNzTmFtZSA9IGMuY2xhc3NOYW1lLnJlcGxhY2UoJyBwdy1wY2FyZC1zZWwnLCcnKS5yZXBsYWNlKCdwdy1wY2FyZC1zZWwnLCcnKS50cmltKCk7CgogICAgICBjLnNldEF0dHJpYnV0ZSgnYXJpYS1jaGVja2VkJywnZmFsc2UnKTsKCiAgICB9KTsKCiAgICB2YXIgbmV4dEJ0biA9IHJvb3QucXVlcnlTZWxlY3RvcignI3B3LXMyLW5leHQnKTsKCiAgICBpZiAobmV4dEJ0bikgbmV4dEJ0bi5jbGFzc05hbWUgPSAobmV4dEJ0bi5jbGFzc05hbWUgKyAnIHB3LWRpc2FibGVkJykudHJpbSgpOwoKICAgIHJvb3QucXVlcnlTZWxlY3RvcignI3B3LXMxLWhpbnQnKS50ZXh0Q29udGVudCA9ICdTZWxlY3Qgb25lIHRvIGNvbnRpbnVlJzsKCiAgICByb290LnF1ZXJ5U2VsZWN0b3IoJyNwdy1zMi1oaW50JykudGV4dENvbnRlbnQgPSAnU2VsZWN0IGF0IGxlYXN0IG9uZSBwcm92aW5jZSc7CgogICAgc2hvd1N0ZXAoJ3MxJyk7CgogICAgcmV0dXJuOwoKICB9CgoKCiAgLyogQWNjb3JkaW9uIHRvZ2dsZSAqLwoKICBpZiAoYWN0aW9uID09PSAnYWNjJyB8fCB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWFjYycpKSB7CgogICAgdmFyIGJvZHlJZCA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtYWNjJykgfHwgdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1hY3Rpb24nKTsKCiAgICB2YXIgYWNjQm9keSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGJvZHlJZCk7CgogICAgaWYgKCFhY2NCb2R5KSByZXR1cm47CgogICAgdmFyIGlzT3BlbiA9IGFjY0JvZHkuY2xhc3NOYW1lLmluZGV4T2YoJ3B3LWFjYy1ib2R5LW9wZW4nKSA+IC0xOwoKICAgIGlmIChpc09wZW4pIHsKCiAgICAgIGFjY0JvZHkuY2xhc3NOYW1lID0gYWNjQm9keS5jbGFzc05hbWUucmVwbGFjZSgnIHB3LWFjYy1ib2R5LW9wZW4nLCcnKS5yZXBsYWNlKCdwdy1hY2MtYm9keS1vcGVuJywnJykudHJpbSgpOwoKICAgICAgYWNjQm9keS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOwoKICAgICAgdGFyZ2V0LmNsYXNzTmFtZSA9IHRhcmdldC5jbGFzc05hbWUucmVwbGFjZSgnIHB3LWFjYy1idG4tb3BlbicsJycpLnJlcGxhY2UoJ3B3LWFjYy1idG4tb3BlbicsJycpLnRyaW0oKTsKCiAgICAgIHZhciBpY29uID0gdGFyZ2V0LnF1ZXJ5U2VsZWN0b3IoJy5wdy1hY2MtaWNvbicpOwoKICAgICAgaWYgKGljb24pIGljb24uY2xhc3NOYW1lID0gJ3B3LWFjYy1pY29uJzsKCiAgICB9IGVsc2UgewoKICAgICAgYWNjQm9keS5jbGFzc05hbWUgPSAoYWNjQm9keS5jbGFzc05hbWUgKyAnIHB3LWFjYy1ib2R5LW9wZW4nKS50cmltKCk7CgogICAgICBhY2NCb2R5LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOwoKICAgICAgdGFyZ2V0LmNsYXNzTmFtZSA9ICh0YXJnZXQuY2xhc3NOYW1lICsgJyBwdy1hY2MtYnRuLW9wZW4nKS50cmltKCk7CgogICAgICB2YXIgaWNvbiA9IHRhcmdldC5xdWVyeVNlbGVjdG9yKCcucHctYWNjLWljb24nKTsKCiAgICAgIGlmIChpY29uKSBpY29uLmNsYXNzTmFtZSA9ICdwdy1hY2MtaWNvbiBwdy1hY2MtaWNvbi1vcGVuJzsKCiAgICAgIGluaXRUYWJsZWF1Vml6KHRhcmdldCk7CgogICAgfQoKICAgIHJldHVybjsKCiAgfQoKfQoKCgpyb290LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZSkgewoKICBoYW5kbGVJbnRlcmFjdGlvbihlLnRhcmdldCk7Cgp9KTsKCgoKcm9vdC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgZnVuY3Rpb24oZSkgewoKICBpZiAoZS5rZXkgPT09ICdFbnRlcicgfHwgZS5rZXkgPT09ICcgJykgewoKICAgIHZhciB0ID0gZS50YXJnZXQ7CgogICAgdmFyIHJvbGUgPSB0LmdldEF0dHJpYnV0ZSgncm9sZScpOwoKICAgIGlmIChyb2xlID09PSAncmFkaW8nIHx8IHJvbGUgPT09ICdjaGVja2JveCcgfHwgcm9sZSA9PT0gJ2J1dHRvbicpIHsKCiAgICAgIGUucHJldmVudERlZmF1bHQoKTsKCiAgICAgIGhhbmRsZUludGVyYWN0aW9uKHQpOwoKICAgIH0KCiAgfQoKfSk7CgoKCi8qIEFjY29yZGlvbiBidXR0b25zICh0eXBlPWJ1dHRvbikgdXNlIGRhdGEtYWNjICovCgpyb290LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZSkgewoKICB2YXIgYnRuID0gZS50YXJnZXQuY2xvc2VzdCgnW2RhdGEtYWNjXScpOwoKICBpZiAoYnRuKSB7CgogICAgZS5zdG9wUHJvcGFnYXRpb24oKTsKCiAgICB2YXIgYm9keUlkID0gYnRuLmdldEF0dHJpYnV0ZSgnZGF0YS1hY2MnKTsKCiAgICB2YXIgYWNjQm9keSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGJvZHlJZCk7CgogICAgaWYgKCFhY2NCb2R5KSByZXR1cm47CgogICAgdmFyIGlzT3BlbiA9IGFjY0JvZHkuY2xhc3NOYW1lLmluZGV4T2YoJ3B3LWFjYy1ib2R5LW9wZW4nKSA+IC0xOwoKICAgIGlmIChpc09wZW4pIHsKCiAgICAgIGFjY0JvZHkuY2xhc3NOYW1lID0gYWNjQm9keS5jbGFzc05hbWUucmVwbGFjZSgnIHB3LWFjYy1ib2R5LW9wZW4nLCcnKS5yZXBsYWNlKCdwdy1hY2MtYm9keS1vcGVuJywnJykudHJpbSgpOwoKICAgICAgYWNjQm9keS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOwoKICAgICAgYnRuLmNsYXNzTmFtZSA9IGJ0bi5jbGFzc05hbWUucmVwbGFjZSgnIHB3LWFjYy1idG4tb3BlbicsJycpLnJlcGxhY2UoJ3B3LWFjYy1idG4tb3BlbicsJycpLnRyaW0oKTsKCiAgICAgIHZhciBpY29uID0gYnRuLnF1ZXJ5U2VsZWN0b3IoJy5wdy1hY2MtaWNvbicpOwoKICAgICAgaWYgKGljb24pIGljb24uY2xhc3NOYW1lID0gJ3B3LWFjYy1pY29uJzsKCiAgICB9IGVsc2UgewoKICAgICAgYWNjQm9keS5jbGFzc05hbWUgPSAoYWNjQm9keS5jbGFzc05hbWUgKyAnIHB3LWFjYy1ib2R5LW9wZW4nKS50cmltKCk7CgogICAgICBhY2NCb2R5LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOwoKICAgICAgYnRuLmNsYXNzTmFtZSA9IChidG4uY2xhc3NOYW1lICsgJyBwdy1hY2MtYnRuLW9wZW4nKS50cmltKCk7CgogICAgICB2YXIgaWNvbiA9IGJ0bi5xdWVyeVNlbGVjdG9yKCcucHctYWNjLWljb24nKTsKCiAgICAgIGlmIChpY29uKSBpY29uLmNsYXNzTmFtZSA9ICdwdy1hY2MtaWNvbiBwdy1hY2MtaWNvbi1vcGVuJzsKCiAgICAgIGluaXRUYWJsZWF1Vml6KGJ0bik7CgogICAgfQoKICB9Cgp9KTsKCgoKLyogQnVpbGQgcmVzdWx0IGNhcmRzICovCgpmdW5jdGlvbiBidWlsZFJlc3VsdHMoKSB7CgogIHZhciBMSUMgPSB7IHJuOidSTicsIHJwbjonUlBOJywgbHBuOidMUE4nIH07CgogIHZhciBQUk9WID0geyBiYzonQnJpdGlzaCBDb2x1bWJpYScsIG1iOidNYW5pdG9iYScsIG9uOidPbnRhcmlvJywgYWI6J0FsYmVydGEnLCBzazonU2Fza2F0Y2hld2FuJyB9OwoKICB2YXIgQ1RSID0geyBhdTonQXVzdHJhbGlhJywgaWU6J0lyZWxhbmQnLCBuejonTmV3IFplYWxhbmQnLCB1azonVW5pdGVkIEtpbmdkb20nLCB1czonVW5pdGVkIFN0YXRlcycsIG90aGVyOicnIH07CgoKCiAgdmFyIHBpbGxzID0gcm9vdC5xdWVyeVNlbGVjdG9yKCcjcHctcGlsbHMnKTsKCiAgcGlsbHMuaW5uZXJIVE1MID0KCiAgICAnPHNwYW4gY2xhc3M9InB3LXBpbGwgcHctcGlsbC1saWMiPicgKyBlc2MoTElDW1MubGljXXx8Uy5saWMpICsgJzwvc3Bhbj4nICsKCiAgICBTLnByb3ZzLm1hcChmdW5jdGlvbihwKXsgcmV0dXJuICc8c3BhbiBjbGFzcz0icHctcGlsbCBwdy1waWxsLXByb3YiPicgKyBlc2MoUFJPVltwXXx8cCkgKyAnPC9zcGFuPic7IH0pLmpvaW4oJycpICsKCiAgICAoUy5jb3VudHJ5ICYmIENUUltTLmNvdW50cnldID8gJzxzcGFuIGNsYXNzPSJwdy1waWxsIHB3LXBpbGwtY291bnRyeSI+JyArIGVzYyhDVFJbUy5jb3VudHJ5XSkgKyAnPC9zcGFuPicgOiAnJyk7CgoKCiAgdmFyIGdyaWQgPSByb290LnF1ZXJ5U2VsZWN0b3IoJyNwdy1yZXMtZ3JpZCcpOwoKICB2YXIga2V5cyA9IFtdOwogIFMucHJvdnMuZm9yRWFjaChmdW5jdGlvbihwKSB7CiAgICB2YXIgayA9IHBhdGhLZXkocCwgUy5saWMsIFMuY291bnRyeSk7CiAgICBpZiAoIWspIHJldHVybjsKICAgIGlmIChBcnJheS5pc0FycmF5KGspKSB7IGtleXMgPSBrZXlzLmNvbmNhdChrKTsgfSBlbHNlIHsga2V5cy5wdXNoKGspOyB9CiAgfSk7CgogIGdyaWQuaW5uZXJIVE1MID0ga2V5cy5tYXAocmVuZGVyQ2FyZCkuam9pbignJyk7Cgp9CgoKCgoKLyogRG9jdW1lbnQgY2hlY2tsaXN0OiBjaGVjay1vZmYgaGFuZGxlciAqLwoKcm9vdC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBmdW5jdGlvbihlKSB7CgogIHZhciBjYiA9IGUudGFyZ2V0OwoKICBpZiAoIWNiLmdldEF0dHJpYnV0ZSB8fCAhY2IuZ2V0QXR0cmlidXRlKCdkYXRhLWRvY3MtbGlzdCcpKSByZXR1cm47CgogIHZhciBsYWJlbCA9IGNiLnBhcmVudEVsZW1lbnQ7CgogIHdoaWxlIChsYWJlbCAmJiBsYWJlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgIT09ICdsYWJlbCcpIGxhYmVsID0gbGFiZWwucGFyZW50RWxlbWVudDsKCiAgaWYgKGxhYmVsKSB7CgogICAgaWYgKGNiLmNoZWNrZWQpIHsKCiAgICAgIGxhYmVsLmNsYXNzTmFtZSA9IChsYWJlbC5jbGFzc05hbWUgKyAnIHB3LWRvYy1kb25lJykudHJpbSgpOwoKICAgIH0gZWxzZSB7CgogICAgICBsYWJlbC5jbGFzc05hbWUgPSBsYWJlbC5jbGFzc05hbWUucmVwbGFjZSgnIHB3LWRvYy1kb25lJywnJykucmVwbGFjZSgncHctZG9jLWRvbmUnLCcnKS50cmltKCk7CgogICAgfQoKICB9CgogIHZhciBsaXN0SWQgPSBjYi5nZXRBdHRyaWJ1dGUoJ2RhdGEtZG9jcy1saXN0Jyk7CgogIHZhciBsaXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQobGlzdElkKTsKCiAgaWYgKCFsaXN0KSByZXR1cm47CgogIHZhciBhbGwgPSBsaXN0LnF1ZXJ5U2VsZWN0b3JBbGwoJy5wdy1kb2MtY2InKTsKCiAgdmFyIGNoZWNrZWQgPSBsaXN0LnF1ZXJ5U2VsZWN0b3JBbGwoJy5wdy1kb2MtY2I6Y2hlY2tlZCcpOwoKICB2YXIgcmVhZHlNc2cgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChsaXN0SWQucmVwbGFjZSgnLWxpc3QnLCAnLXJlYWR5JykpOwoKICBpZiAocmVhZHlNc2cpIHsKCiAgICBpZiAoYWxsLmxlbmd0aCA+IDAgJiYgYWxsLmxlbmd0aCA9PT0gY2hlY2tlZC5sZW5ndGgpIHsKCiAgICAgIHJlYWR5TXNnLmNsYXNzTmFtZSA9IChyZWFkeU1zZy5jbGFzc05hbWUgKyAnIHB3LXJlYWR5LXNob3cnKS50cmltKCk7CgogICAgfSBlbHNlIHsKCiAgICAgIHJlYWR5TXNnLmNsYXNzTmFtZSA9IHJlYWR5TXNnLmNsYXNzTmFtZS5yZXBsYWNlKCcgcHctcmVhZHktc2hvdycsJycpLnJlcGxhY2UoJ3B3LXJlYWR5LXNob3cnLCcnKS50cmltKCk7CgogICAgfQoKICB9Cgp9KTsKCgoKLyogSW5pdCAqLwoKc2hvd1N0ZXAoJ3MxJyk7CgogIC8qIFByaW50IGhhbmRsZXIgKi8KICB2YXIgcHJpbnRCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHctcHJpbnQtYnRuJyk7CiAgaWYgKHByaW50QnRuKSB7CiAgICBwcmludEJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkgeyB3aW5kb3cucHJpbnQoKTsgfSk7CiAgfQoKfSk7IC8vIGVuZCB3aW5kb3cubG9hZAoK
Ci8qIC0tIE5OQVMgSUVOIFJlc291cmNlIERpcmVjdG9yeSAtLSAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgdmFyIFBST1ZfTUFQID0geyBiYzonQkMnLCBtYjonTUInLCBvbjonT04nLCBhYjonQUInLCBzazonU0snLCBuczonTlMnLAogICAgICAgICAgICAgICAgICAgbmI6J05CJywgcGVpOidQRUknLCBubDonTkwnLCBxYzonUUMnLCBudDonTlQnLCB5dDonWVQnLCBudTonTlUnLCBjYTonQ0EnIH07CiAgdmFyIFBST1ZfT1JERVIgPSBbJ0NBJywnQkMnLCdBQicsJ1NLJywnTUInLCdPTicsJ1FDJywnTlMnLCdOQicsJ1BFSScsJ05MJywnTlQnLCdZVCcsJ05VJ107CiAgdmFyIFBST1ZfTEFCRUxTID0gewogICAgQ0E6J05hdGlvbmFsIC8gVmlydHVhbCcsIEJDOidCcml0aXNoIENvbHVtYmlhJywgQUI6J0FsYmVydGEnLAogICAgU0s6J1Nhc2thdGNoZXdhbicsIE1COidNYW5pdG9iYScsIE9OOidPbnRhcmlvJywgUUM6J1F1ZWJlYycsCiAgICBOUzonTm92YSBTY290aWEnLCBOQjonTmV3IEJydW5zd2ljaycsIFBFSTonUHJpbmNlIEVkd2FyZCBJc2xhbmQnLAogICAgTkw6J05ld2ZvdW5kbGFuZCAmIExhYnJhZG9yJywgTlQ6J05vcnRod2VzdCBUZXJyaXRvcmllcycsIFlUOidZdWtvbicsIE5VOidOdW5hdnV0JwogIH07CgogIHZhciBSRVNPVVJDRVMgPSBudWxsOwogIHZhciBnQWN0aXZlSWQgPSBudWxsOwogIHZhciBnQWN0aXZlVGFncyA9IFtdOwogIHZhciBnUHJvdkZpbHRlciA9ICcnOwoKICBmdW5jdGlvbiBnZXRSZXNvdXJjZXMoKSB7CiAgICBpZiAoUkVTT1VSQ0VTKSByZXR1cm4gUkVTT1VSQ0VTOwogICAgUkVTT1VSQ0VTID0gW107CiAgICB2YXIgZWxzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI3B3LXJlc291cmNlcy1kYXRhIFtkYXRhLWlkXScpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbHMubGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIGVsID0gZWxzW2ldOwogICAgICB2YXIgcmF3VGFncyA9IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS10YWdzJykgfHwgJyc7CiAgICAgIFJFU09VUkNFUy5wdXNoKHsKICAgICAgICBpZDogICAgICAgICAgZWwuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJykgICAgICAgICAgfHwgKCdyJyArIGkpLAogICAgICAgIG5hbWU6ICAgICAgICBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtbmFtZScpICAgICAgICB8fCAnJywKICAgICAgICB0eXBlOiAgICAgICAgZWwuZ2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnKSAgICAgICAgfHwgJycsCiAgICAgICAgd2Vic2l0ZTogICAgIGVsLmdldEF0dHJpYnV0ZSgnZGF0YS13ZWJzaXRlJykgICAgIHx8ICcnLAogICAgICAgIGNpdHk6ICAgICAgICBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY2l0eScpICAgICAgICB8fCAnJywKICAgICAgICBwcm92aW5jZTogICAgZWwuZ2V0QXR0cmlidXRlKCdkYXRhLXByb3ZpbmNlJykgICAgfHwgJ0NBJywKICAgICAgICBkZXNjcmlwdGlvbjogZWwuZ2V0QXR0cmlidXRlKCdkYXRhLWRlc2NyaXB0aW9uJykgfHwgJycsCiAgICAgICAgdGFnczogICAgICAgIHJhd1RhZ3MgPyByYXdUYWdzLnNwbGl0KCcsJykubWFwKGZ1bmN0aW9uKHQpe3JldHVybiB0LnRyaW0oKTt9KS5maWx0ZXIoQm9vbGVhbikgOiBbXQogICAgICB9KTsKICAgIH0KICAgIHJldHVybiBSRVNPVVJDRVM7CiAgfQoKICBmdW5jdGlvbiBnZXRBbGxUYWdzKCkgewogICAgdmFyIHNlZW4gPSB7fSwgYXJyID0gW107CiAgICBnZXRSZXNvdXJjZXMoKS5mb3JFYWNoKGZ1bmN0aW9uIChyKSB7CiAgICAgIGlmIChyLnR5cGUgJiYgIXNlZW5bci50eXBlXSkgeyBzZWVuW3IudHlwZV0gPSB0cnVlOyBhcnIucHVzaChyLnR5cGUpOyB9CiAgICAgIHIudGFncy5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7CiAgICAgICAgaWYgKHQgJiYgIXNlZW5bdF0pIHsgc2Vlblt0XSA9IHRydWU7IGFyci5wdXNoKHQpOyB9CiAgICAgIH0pOwogICAgfSk7CiAgICByZXR1cm4gYXJyLnNvcnQoKTsKICB9CgogIGZ1bmN0aW9uIHJlbmRlckZpbHRlckJhcigpIHsKICAgIHZhciBlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwdy1ybS1maWx0ZXJiYXInKTsKICAgIGlmICghZWwpIHJldHVybjsKICAgIHZhciB0YWdzID0gZ2V0QWxsVGFncygpOwogICAgdmFyIHByb3ZIdG1sID0gJzxsYWJlbCBjbGFzcz0icHctcm0tZmJhci1sYWJlbCIgZm9yPSJwdy1ybS1wcm92ZmlsdGVyIj5Qcm92aW5jZTo8L2xhYmVsPicgKwogICAgICAnPHNlbGVjdCBpZD0icHctcm0tcHJvdmZpbHRlciIgY2xhc3M9InB3LXJtLXByb3ZzZWxlY3QiPicgKwogICAgICAnPG9wdGlvbiB2YWx1ZT0iIj5BbGw8L29wdGlvbj4nOwogICAgUFJPVl9PUkRFUi5mb3JFYWNoKGZ1bmN0aW9uIChjb2RlKSB7CiAgICAgIHZhciBzZWwgPSBnUHJvdkZpbHRlciA9PT0gY29kZSA/ICcgc2VsZWN0ZWQnIDogJyc7CiAgICAgIHByb3ZIdG1sICs9ICc8b3B0aW9uIHZhbHVlPSInICsgZXNjKGNvZGUpICsgJyInICsgc2VsICsgJz4nICsgZXNjKFBST1ZfTEFCRUxTW2NvZGVdIHx8IGNvZGUpICsgJzwvb3B0aW9uPic7CiAgICB9KTsKICAgIHByb3ZIdG1sICs9ICc8L3NlbGVjdD4nOwogICAgdmFyIHBpbGxzSHRtbCA9ICc8c3BhbiBjbGFzcz0icHctcm0tZmJhci1sYWJlbCI+VHlwZTo8L3NwYW4+JzsKICAgIHRhZ3MuZm9yRWFjaChmdW5jdGlvbiAodCkgewogICAgICB2YXIgaXNPbiA9IGdBY3RpdmVUYWdzLmluZGV4T2YodCkgIT09IC0xOwogICAgICBwaWxsc0h0bWwgKz0gJzxzcGFuIGNsYXNzPSJwdy1ybS1mdGFnJyArIChpc09uID8gJyBwdy1ybS1mdGFnLW9uJyA6ICcnKSArICciIGRhdGEtZnRhZz0iJyArIGVzYyh0KSArICciPicgKyBlc2ModCkgKyAnPC9zcGFuPic7CiAgICB9KTsKICAgIGVsLmlubmVySFRNTCA9ICc8ZGl2IGNsYXNzPSJwdy1ybS1mcm93Ij4nICsgcHJvdkh0bWwgKyAnPC9kaXY+PGRpdiBjbGFzcz0icHctcm0tZnJvdyBwdy1ybS1mcm93LXRhZ3MiPicgKyBwaWxsc0h0bWwgKyAnPC9kaXY+JzsKICAgIHZhciBwcm92U2VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3B3LXJtLXByb3ZmaWx0ZXInKTsKICAgIGlmIChwcm92U2VsKSBwcm92U2VsLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGZ1bmN0aW9uICgpIHsgZ1Byb3ZGaWx0ZXIgPSBwcm92U2VsLnZhbHVlOyB1cGRhdGUoKTsgfSk7CiAgICBlbC5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS1mdGFnXScpLmZvckVhY2goZnVuY3Rpb24gKHBpbGwpIHsKICAgICAgcGlsbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgdCA9IHBpbGwuZ2V0QXR0cmlidXRlKCdkYXRhLWZ0YWcnKTsKICAgICAgICB2YXIgaWR4ID0gZ0FjdGl2ZVRhZ3MuaW5kZXhPZih0KTsKICAgICAgICBpZiAoaWR4ID09PSAtMSkgZ0FjdGl2ZVRhZ3MucHVzaCh0KTsgZWxzZSBnQWN0aXZlVGFncy5zcGxpY2UoaWR4LCAxKTsKICAgICAgICB0cnkgeyByZW5kZXJGaWx0ZXJCYXIoKTsgfSBjYXRjaCAoZSkge30KICAgICAgICB1cGRhdGUoKTsKICAgICAgfSk7CiAgICB9KTsKICB9CgogIGZ1bmN0aW9uIGVzYyhzKSB7CiAgICByZXR1cm4gU3RyaW5nKHMgfHwgJycpLnJlcGxhY2UoLyYvZywnJmFtcDsnKS5yZXBsYWNlKC88L2csJyZsdDsnKS5yZXBsYWNlKC8+L2csJyZndDsnKTsKICB9CgogIGZ1bmN0aW9uIGdldERvbWFpbih1cmwpIHsKICAgIHRyeSB7IHZhciBtID0gU3RyaW5nKHVybHx8JycpLm1hdGNoKC9eaHR0cHM/OlwvXC8oW14vXSspLyk7IHJldHVybiBtID8gbVsxXSA6ICcnOyB9IGNhdGNoKGUpIHsgcmV0dXJuICcnOyB9CiAgfQoKICBmdW5jdGlvbiBnZXRTZWxlY3RlZFByb3ZzKCkgewogICAgdmFyIG91dCA9IFtdLCBlbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS1wcm92XS5wdy1wY2FyZC1zZWwnKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBjID0gUFJPVl9NQVBbZWxzW2ldLmdldEF0dHJpYnV0ZSgnZGF0YS1wcm92JyldOwogICAgICBpZiAoYykgb3V0LnB1c2goYyk7CiAgICB9CiAgICByZXR1cm4gb3V0OwogIH0KCiAgZnVuY3Rpb24gZ2V0RmlsdGVyZWQocHJvdnMsIHF1ZXJ5KSB7CiAgICB2YXIgcSA9IChxdWVyeSB8fCAnJykudHJpbSgpLnRvTG93ZXJDYXNlKCk7CiAgICB2YXIgZnAgPSBnUHJvdkZpbHRlciB8fCBudWxsOwogICAgcmV0dXJuIGdldFJlc291cmNlcygpLmZpbHRlcihmdW5jdGlvbiAocikgewogICAgICB2YXIgb2tQcm92ID0gZnAKICAgICAgICA/IChyLnByb3ZpbmNlID09PSAnQ0EnIHx8IHIucHJvdmluY2UgPT09IGZwKQogICAgICAgIDogKHByb3ZzLmxlbmd0aCA9PT0gMCB8fCByLnByb3ZpbmNlID09PSAnQ0EnIHx8IHByb3ZzLmluZGV4T2Yoci5wcm92aW5jZSkgIT09IC0xKTsKICAgICAgaWYgKCFva1Byb3YpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdBY3RpdmVUYWdzLmxlbmd0aCkgewogICAgICAgIHZhciByVGFncyA9IFtyLnR5cGVdLmNvbmNhdChyLnRhZ3MpOwogICAgICAgIGlmICghZ0FjdGl2ZVRhZ3Muc29tZShmdW5jdGlvbiAodCkgeyByZXR1cm4gclRhZ3MuaW5kZXhPZih0KSAhPT0gLTE7IH0pKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFxKSByZXR1cm4gdHJ1ZTsKICAgICAgcmV0dXJuIFtyLm5hbWUsIHIudHlwZSwgci5jaXR5LCByLnByb3ZpbmNlLCByLmRlc2NyaXB0aW9uXS5jb25jYXQoci50YWdzKS5qb2luKCcgJykudG9Mb3dlckNhc2UoKS5pbmRleE9mKHEpICE9PSAtMTsKICAgIH0pOwogIH0KCiAgZnVuY3Rpb24gcmVuZGVyUHJvdlBpbGxzKHByb3ZzKSB7CiAgICB2YXIgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHctcm0tcHJvdnBpbGxzJyk7CiAgICBpZiAoIWVsKSByZXR1cm47CiAgICBpZiAoIXByb3ZzLmxlbmd0aCkgeyBlbC5pbm5lckhUTUwgPSAnPHNwYW4gY2xhc3M9InB3LXJlc21hcC1wcGlsbCI+QWxsIHByb3ZpbmNlczwvc3Bhbj4nOyByZXR1cm47IH0KICAgIGVsLmlubmVySFRNTCA9IHByb3ZzLm1hcChmdW5jdGlvbiAocCkgeyByZXR1cm4gJzxzcGFuIGNsYXNzPSJwdy1yZXNtYXAtcHBpbGwiPicgKyBlc2MocCkgKyAnPC9zcGFuPic7IH0pLmpvaW4oJycpOwogIH0KCiAgZnVuY3Rpb24gcmVuZGVyRGV0YWlsUGFuZWwocikgewogICAgdmFyIHBhbmVsRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHctcm0tcHJvdmNvbCcpOwogICAgaWYgKCFwYW5lbEVsKSByZXR1cm47CiAgICBpZiAoIXIpIHsKICAgICAgcGFuZWxFbC5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz0icHctcm1wYW5lbC1lbXB0eSI+Q2xpY2sgYSByZXNvdXJjZSB0byBzZWUgZGV0YWlscy48L2Rpdj4nOwogICAgICByZXR1cm47CiAgICB9CiAgICB2YXIgZG9tYWluID0gZ2V0RG9tYWluKHIud2Vic2l0ZSk7CiAgICB2YXIgbG9nb1VybCA9IGRvbWFpbiA/ICdodHRwczovL3d3dy5nb29nbGUuY29tL3MyL2Zhdmljb25zP2RvbWFpbj0nICsgZW5jb2RlVVJJQ29tcG9uZW50KGRvbWFpbikgKyAnJnN6PTY0JyA6ICcnOwogICAgdmFyIGxvZ29IdG1sID0gbG9nb1VybCA/ICc8aW1nIGNsYXNzPSJwdy1ybXBhbmVsLWxvZ28iIHNyYz0iJyArIGVzYyhsb2dvVXJsKSArICciIGFsdD0iIiBhcmlhLWhpZGRlbj0idHJ1ZSIgb25lcnJvcj0idGhpcy5zdHlsZS5kaXNwbGF5PVwnbm9uZVwnIj4nIDogJyc7CiAgICB2YXIgbWV0YSA9IFtyLnR5cGUsIChyLmNpdHkgJiYgci5jaXR5ICE9PSAnVmlydHVhbCcpID8gci5jaXR5IDogbnVsbCwgci5wcm92aW5jZV0uZmlsdGVyKEJvb2xlYW4pLmpvaW4oJyBcdTAwYjcgJyk7CiAgICB2YXIgZGVzY0h0bWwgPSByLmRlc2NyaXB0aW9uID8gJzxwIGNsYXNzPSJwdy1ybXBhbmVsLWRlc2MiPicgKyBlc2Moci5kZXNjcmlwdGlvbikgKyAnPC9wPicgOiAnJzsKICAgIHZhciBsaW5rSHRtbCA9IHIud2Vic2l0ZSA/ICc8YSBjbGFzcz0icHctcm1wYW5lbC1saW5rIHB3LXJtcGFuZWwtZGV0YWlsbGluayIgaHJlZj0iJyArIGVzYyhyLndlYnNpdGUpICsgJyIgdGFyZ2V0PSJfYmxhbmsiIHJlbD0ibm9vcGVuZXIgbm9yZWZlcnJlciI+VmlzaXQgd2Vic2l0ZSBcdTIxOTc8L2E+JyA6ICcnOwogICAgcGFuZWxFbC5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz0icHctcm1wYW5lbC1kZXRhaWwiPicgKwogICAgICAobG9nb1VybCA/ICc8ZGl2IGNsYXNzPSJwdy1ybXBhbmVsLWxvZ293cmFwIj4nICsgbG9nb0h0bWwgKyAnPC9kaXY+JyA6ICcnKSArCiAgICAgICc8ZGl2IGNsYXNzPSJwdy1ybXBhbmVsLWRuYW1lIj4nICsgZXNjKHIubmFtZSkgKyAnPC9kaXY+JyArCiAgICAgICc8ZGl2IGNsYXNzPSJwdy1ybXBhbmVsLWR0eXBlIj4nICsgZXNjKG1ldGEpICsgJzwvZGl2PicgKwogICAgICBkZXNjSHRtbCArIGxpbmtIdG1sICsgJzwvZGl2Pic7CiAgfQoKICBmdW5jdGlvbiBzZXRBY3RpdmUoaWQpIHsKICAgIGlmIChnQWN0aXZlSWQpIHsKICAgICAgdmFyIG9sZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXJtaWQ9IicgKyBnQWN0aXZlSWQgKyAnIl0nKTsKICAgICAgaWYgKG9sZCkgb2xkLmNsYXNzTGlzdC5yZW1vdmUoJ3B3LXJlc21hcC1pdGVtLW9uJyk7CiAgICB9CiAgICBnQWN0aXZlSWQgPSBpZDsKICAgIGlmIChpZCkgewogICAgICB2YXIgZWxMaXN0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtcm1pZD0iJyArIGlkICsgJyJdJyk7CiAgICAgIGlmIChlbExpc3QpIHsgZWxMaXN0LmNsYXNzTGlzdC5hZGQoJ3B3LXJlc21hcC1pdGVtLW9uJyk7IGVsTGlzdC5zY3JvbGxJbnRvVmlldyh7IGJsb2NrOiduZWFyZXN0JywgYmVoYXZpb3I6J3Ntb290aCcgfSk7IH0KICAgICAgdmFyIHJlcyA9IG51bGw7CiAgICAgIHZhciBhbGwgPSBnZXRSZXNvdXJjZXMoKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbGwubGVuZ3RoOyBpKyspIHsgaWYgKGFsbFtpXS5pZCA9PT0gaWQpIHsgcmVzID0gYWxsW2ldOyBicmVhazsgfSB9CiAgICAgIHJlbmRlckRldGFpbFBhbmVsKHJlcyk7CiAgICB9IGVsc2UgewogICAgICByZW5kZXJEZXRhaWxQYW5lbChudWxsKTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIHJlbmRlckxpc3QobGlzdCkgewogICAgdmFyIGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3B3LXJtLWxpc3QnKTsKICAgIGlmICghZWwpIHJldHVybjsKICAgIGVsLmlubmVySFRNTCA9ICcnOwogICAgaWYgKCFsaXN0Lmxlbmd0aCkgewogICAgICBlbC5pbm5lckhUTUwgPSAnPGRpdiBjbGFzcz0icHctcmVzbWFwLWl0ZW0iIHN0eWxlPSJjdXJzb3I6ZGVmYXVsdCFpbXBvcnRhbnQiPicgKwogICAgICAgICc8c3BhbiBjbGFzcz0icHctcmVzbWFwLWluYW1lIj5ObyByZXNvdXJjZXMgZm91bmQ8L3NwYW4+JyArCiAgICAgICAgJzxzcGFuIGNsYXNzPSJwdy1yZXNtYXAtaW1ldGEiPlRyeSBjbGVhcmluZyB0aGUgc2VhcmNoLCBkZXNlbGVjdGluZyB0eXBlIGZpbHRlcnMsIG9yIHNlbGVjdGluZyBtb3JlIHByb3ZpbmNlcy48L3NwYW4+PC9kaXY+JzsKICAgICAgcmV0dXJuOwogICAgfQogICAgbGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChyKSB7CiAgICAgIHZhciBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgICAgIGQuY2xhc3NOYW1lID0gJ3B3LXJlc21hcC1pdGVtJyArIChyLmlkID09PSBnQWN0aXZlSWQgPyAnIHB3LXJlc21hcC1pdGVtLW9uJyA6ICcnKTsKICAgICAgZC5zZXRBdHRyaWJ1dGUoJ2RhdGEtcm1pZCcsIHIuaWQpOwogICAgICBkLmlubmVySFRNTCA9CiAgICAgICAgJzxzcGFuIGNsYXNzPSJwdy1yZXNtYXAtaW5hbWUiPicgKyBlc2Moci5uYW1lKSArICc8L3NwYW4+JyArCiAgICAgICAgJzxzcGFuIGNsYXNzPSJwdy1yZXNtYXAtaW1ldGEiPicgKyBlc2MoW3IuY2l0eSwgci5wcm92aW5jZV0uZmlsdGVyKEJvb2xlYW4pLmpvaW4oJywgJykpICsgJzwvc3Bhbj4nICsKICAgICAgICAnPGRpdiBjbGFzcz0icHctcmVzbWFwLWl0YWdzIj4nICsKICAgICAgICAgICc8c3BhbiBjbGFzcz0icHctcmVzbWFwLWl0YWcgcHctcmVzbWFwLWl0YWctdHlwZSI+JyArIGVzYyhyLnR5cGUpICsgJzwvc3Bhbj4nICsKICAgICAgICAgICc8c3BhbiBjbGFzcz0icHctcmVzbWFwLWl0YWcgcHctcmVzbWFwLWl0YWctcHJvdiI+JyArIGVzYyhyLnByb3ZpbmNlKSArICc8L3NwYW4+JyArCiAgICAgICAgJzwvZGl2Pic7CiAgICAgIGQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7IHNldEFjdGl2ZShyLmlkKTsgfSk7CiAgICAgIGVsLmFwcGVuZENoaWxkKGQpOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiB1cGRhdGUoKSB7CiAgICB2YXIgcHJvdnMgPSBnZXRTZWxlY3RlZFByb3ZzKCk7CiAgICB2YXIgcSA9IChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHctcm0tc2VhcmNoJykgfHwge30pLnZhbHVlIHx8ICcnOwogICAgdmFyIGxpc3QgPSBnZXRGaWx0ZXJlZChwcm92cywgcSk7CiAgICByZW5kZXJMaXN0KGxpc3QpOwogICAgaWYgKGdBY3RpdmVJZCAmJiAhbGlzdC5zb21lKGZ1bmN0aW9uIChyKSB7IHJldHVybiByLmlkID09PSBnQWN0aXZlSWQ7IH0pKSB7CiAgICAgIHNldEFjdGl2ZShudWxsKTsKICAgIH0gZWxzZSBpZiAoIWdBY3RpdmVJZCkgewogICAgICByZW5kZXJEZXRhaWxQYW5lbChudWxsKTsKICAgIH0KICAgIHZhciBjbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHctcm0tY250Jyk7CiAgICBpZiAoY250KSBjbnQudGV4dENvbnRlbnQgPSBsaXN0Lmxlbmd0aCArICcgcmVzb3VyY2UnICsgKGxpc3QubGVuZ3RoICE9PSAxID8gJ3MnIDogJycpOwogIH0KCiAgZnVuY3Rpb24gYWN0aXZhdGUoKSB7CiAgICBSRVNPVVJDRVMgPSBudWxsOwogICAgZ0FjdGl2ZVRhZ3MgPSBbXTsKICAgIHZhciBwcm92cyA9IGdldFNlbGVjdGVkUHJvdnMoKTsKICAgIGlmIChwcm92cy5sZW5ndGgpIHsKICAgICAgdmFyIHNvcnRlZCA9IHByb3ZzLnNsaWNlKCkuc29ydChmdW5jdGlvbiAoYSwgYikgewogICAgICAgIHJldHVybiAoUFJPVl9MQUJFTFNbYV0gfHwgYSkubG9jYWxlQ29tcGFyZShQUk9WX0xBQkVMU1tiXSB8fCBiKTsKICAgICAgfSk7CiAgICAgIGdQcm92RmlsdGVyID0gc29ydGVkWzBdOwogICAgfSBlbHNlIHsKICAgICAgZ1Byb3ZGaWx0ZXIgPSAnJzsKICAgIH0KICAgIHJlbmRlclByb3ZQaWxscyhwcm92cyk7CiAgICB2YXIgc2VhcmNoRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHctcm0tc2VhcmNoJyk7CiAgICBpZiAoc2VhcmNoRWwpIHNlYXJjaEVsLnZhbHVlID0gJyc7CiAgICB0cnkgeyByZW5kZXJGaWx0ZXJCYXIoKTsgfSBjYXRjaCAoZSkge30KICAgIHNldEFjdGl2ZShudWxsKTsKICAgIHVwZGF0ZSgpOwogIH0KCiAgdmFyIHJlc3VsdHNFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwdy1yZXN1bHRzJyk7CiAgaWYgKHJlc3VsdHNFbCkgewogICAgaWYgKHJlc3VsdHNFbC5jbGFzc0xpc3QuY29udGFpbnMoJ3B3LXN0ZXAtYWN0aXZlJykpIGFjdGl2YXRlKCk7CiAgICB2YXIgX29icyA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGZ1bmN0aW9uIChtdXRzKSB7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXV0cy5sZW5ndGg7IGkrKykgewogICAgICAgIGlmIChtdXRzW2ldLmF0dHJpYnV0ZU5hbWUgPT09ICdjbGFzcycpIHsKICAgICAgICAgIGlmIChyZXN1bHRzRWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdwdy1zdGVwLWFjdGl2ZScpKSBhY3RpdmF0ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICAgIF9vYnMub2JzZXJ2ZShyZXN1bHRzRWwsIHsgYXR0cmlidXRlczogdHJ1ZSwgYXR0cmlidXRlRmlsdGVyOiBbJ2NsYXNzJ10gfSk7CiAgfQoKICB2YXIgc2VhcmNoRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHctcm0tc2VhcmNoJyk7CiAgaWYgKHNlYXJjaEVsKSBzZWFyY2hFbC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHVwZGF0ZSk7Cgp9KCkpOwo=