Анализ сайта farmrio.com.br
Основное Готовность: 70%
Домен
farmrio.com.br
Состояние доменного имени
?
Проверяем корректность доменного имени и наличие технических проблем на уровне домена.
Используйте для продвижения только домен второго уровня.
Отличный запоминающийся домен.
Ответ сервера
200 Успешный ответ
HTTP-код ответа и цепочка редиректов
?
Код 200 — страница доступна. Коды 3xx — редиректы (цепочки замедляют загрузку и размывают ссылочный вес). Коды 4xx/5xx — ошибки, поисковик не сможет проиндексировать страницу.
Сервер настроен корректно.
Цепочка редиректов:
http://farmrio.com.br
301 MovedPermanently
https://www.farmrio.com.br/
200 OK
Безопасность
Сайт безопасен
Использование HTTPS и SSL-сертификат
?
HTTPS — обязательный стандарт. Google и Яндекс отдают предпочтение защищённым сайтам. Отсутствие SSL или просроченный сертификат ведут к предупреждениям в браузере и снижению позиций.
Не настроен HSTS (Strict-Transport-Security) — рекомендуется включить.
На сайте работает защищенный протокол ssl и сайт открывается по https.
Ssl-сертификат действителен до 22.01.2027 11:33:03.
HTTP автоматически перенаправляется на HTTPS.
Поздравляем! Сайт не содержится в реестре РКН.
Кодировка
Кодировка символов страницы
?
Стандарт — UTF-8. Неправильная кодировка вызывает нечитаемые символы и мешает поисковику корректно распознать текст страницы.
Кодировка на странице не определена. Укажите явно кодировку документа!
Язык
pt-BR
Атрибут lang в HTML-теге
?
Атрибут lang (<html lang="ru">) сообщает поисковикам и браузерам, на каком языке написана страница. Помогает при ранжировании в региональном поиске.
Язык документа указан явно: pt-BR.
Скорость загрузки
~0,78сек
Время отклика сервера (TTFB)
?
Time To First Byte — время до получения первого байта от сервера. Норма до 200 мс. Медленный отклик ухудшает пользовательский опыт и ранжирование: Яндекс и Google учитывают скорость страниц.
Скорость загрузки сайта 0,78сек оптимальна.
Объем документа
809Кб
Размер HTML-кода страницы
?
Слишком большой HTML замедляет парсинг браузером и сканирование поисковым роботом. Рекомендуется не более 200 Кб.
Объем html-документа 809Кб оптимален.
Структура html-документа корректна.
Ресурсы
Ресурсы: 23
Внешние ресурсы страницы (CSS, JS, изображения)
?
Количество и тип подключённых ресурсов влияют на скорость загрузки. Большое число запросов увеличивает время рендеринга страницы.
Кол-во файлов ресурсов 23 много для одной страницы. Приемлемо до 10. Проведите оптимизацию файлов ресурсов!
Показать полный список ресурсов
| Тип | Название | Значение |
|---|---|---|
| stylesheet | /styles.css?revision=685102389&__frsh_c=258db05ee97acd52e729509684b46d672caeb386 | |
| stylesheet | https://fonts.googleapis.com/css2?family=Montserrat:wght@100..900&display=swap | |
| js | data:text/javascript,(live%3D%3E%7Bconst%20onKeydown%3De%3D%3E%7Bif(globalThis.window%3D%3D%3DglobalThis.window.parent%26%26e.target%3D%3D%3Ddocument.body%26%26!e.defaultPrevented%26%26(e.ctrlKey%26%26e.shiftKey%26%26%22E%22%3D%3D%3De.key%7C%7C%22.%22%3D%3D%3De.key))%7Be.preventDefault()%2Ce.stopPropagation()%3Bconst%20o%3D%60%2Fchoose-editor%3Fsite%3D%24%7BglobalThis.window.LIVE.site.name%7D%26domain%3D%24%7BglobalThis.window.location.origin%7D%26pageId%3D%24%7BglobalThis.window.LIVE.page.id%7D%60%2Ca%3Dnew%20URL(o%2C%22https%3A%2F%2Fadmin.deco.cx%22)%3Bif(a.searchParams.set(%22path%22%2CencodeURIComponent(%60%24%7BglobalThis.window.location.pathname%7D%24%7BglobalThis.window.location.search%7D%60))%2Ca.searchParams.set(%22pathTemplate%22%2CencodeURIComponent(globalThis.window.LIVE.page.pathTemplate%7C%7C%22%2F*%22))%2C(e.ctrlKey%7C%7Ce.metaKey)%26%26%22.%22%3D%3D%3De.key)return%20globalThis.window.open(a%2C%22_blank%22)%2Cvoid%200%3BglobalThis.window.location.href%3D%60%24%7Ba%7D%60%7D%7D%2ConMessage%3Devent%3D%3E%7Bconst%7Bdata%7D%3Devent%3Bif(%22editor%3A%3Ainject%22%3D%3D%3Ddata.type)return%20eval(data.args.script)%7D%3BglobalThis.window.LIVE%3D%7B...globalThis.window.LIVE%2C...live%7D%2Clive.avoidRedirectingToEditor%7C%7Cdocument.body.addEventListener(%22keydown%22%2ConKeydown)%2CaddEventListener(%22message%22%2ConMessage)%7D)(%7B%22page%22%3A%7B%22id%22%3A%22pages-home-c4bcbfb771e9%22%2C%22pathTemplate%22%3A%22%2F%22%7D%2C%22site%22%3A%7B%22id%22%3A0%2C%22name%22%3A%22farmrio%22%7D%2C%22flags%22%3A%5B%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Header%20Global%20%40navItems.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Header%20Global%20%40newMenu.variants.1.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.2.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.4.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.8.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.16.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.18.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.23.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.24.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.25.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.10.section.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.13.section.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.15.section.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22benef%C3%ADcios%20app%20vers%C3%A3o%20att%40variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.26.section.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.10.section.variants.1.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.13.section.variants.1.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22benef%C3%ADcios%20app%20vers%C3%A3o%20att%40variants.1.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22variants.0.rule.matcher%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Atrue%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Atrue%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Minicart%40minicartProps.productShelf.productsLoader.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Minicart%40minicartProps.section.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22ETC%20Segment%40matchers.0%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22ETC%20Segment%40matchers.1.matchers.0%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22ETC%20Segment%40matchers.1%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22ETC%20Segment%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Atrue%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Alerta%40variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Alerta%40variants.1.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%5D%7D) | |
| js | data:text/javascript,((%7Bdeco%3A%7Bpage%3Ae%7D%2CsegmentCookie%3An%2CfeatureFlags%3At%7D)%3D%3E%7Bconst%20a%3Ddocument.cookie%2Co%3D%7B%7D%3Bif(null!%3D%3Da)%7Bconst%20e%3Da.split(%22%3B%22)%3Bfor(const%20n%20of%20e)%7Bconst%5Be%2C...t%5D%3Dn.split(%22%3D%22)%3Bo%5Be.trim()%5D%3Dt.join(%22%3D%22)%7D%7Dconst%20s%3D%5B%5D%3Bif(o%5Bn%5D)try%7Bconst%20e%3DJSON.parse(decodeURIComponent(atob(o%5Bn%5D)))%3Be.active%3F.forEach((e%3D%3Es.push(%7Bname%3Ae%2Cvalue%3A!0%7D)))%2Ce.inactiveDrawn%3F.forEach((e%3D%3Es.push(%7Bname%3Ae%2Cvalue%3A!1%7D)))%7Dcatch%7Bconsole.error(%22Error%20parsing%20deco_segment%20cookie%22)%7Dconst%20i%3Dnew%20EventTarget%2Cc%3De%3D%3E%7Bi.dispatchEvent(new%20CustomEvent(%22analytics%22%2C%7Bdetail%3Ae%7D))%7D%3BglobalThis.window.DECO_SITES_STD%3D%7BsendAnalyticsEvent%3Ac%7D%2CglobalThis.window.DECO%3D%7B...globalThis.window.DECO%2Cevents%3A%7Bdispatch%3Ac%2Csubscribe%3A(n%2Ct)%3D%3E%7Bconst%20a%3D(%7Bdetail%3Ae%7D)%3D%3En(e)%3Breturn%20n(%7Bname%3A%22deco%22%2Cparams%3A%7Bflags%3As%2Cpage%3Ae%7D%7D)%2Ci.addEventListener(%22analytics%22%2Ca%2Ct)%2C()%3D%3E%7Bi.removeEventListener(%22analytics%22%2Ca%2Ct)%7D%7D%7D%2CfeatureFlags%3At%7D%7D)(%7B%22deco%22%3A%7B%22flags%22%3A%5B%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Header%20Global%20%40navItems.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Header%20Global%20%40newMenu.variants.1.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.2.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.4.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.8.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.16.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.18.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.23.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.24.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.25.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.10.section.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.13.section.variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.15.section.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22benef%C3%ADcios%20app%20vers%C3%A3o%20att%40variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.26.section.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.10.section.variants.1.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22pages-home-c4bcbfb771e9%40sections.variants.0.value.13.section.variants.1.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22benef%C3%ADcios%20app%20vers%C3%A3o%20att%40variants.1.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22variants.0.rule.matcher%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Atrue%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Atrue%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Minicart%40minicartProps.productShelf.productsLoader.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Minicart%40minicartProps.section.variants.0.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22ETC%20Segment%40matchers.0%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22ETC%20Segment%40matchers.1.matchers.0%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22ETC%20Segment%40matchers.1%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22ETC%20Segment%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Atrue%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Alerta%40variants.0.rule%22%2C%22value%22%3Afalse%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%2C%7B%22name%22%3A%22Alerta%40variants.1.rule%22%2C%22value%22%3Atrue%2C%22isSegment%22%3Afalse%2C%22sticky%22%3Afalse%2C%22cacheable%22%3Atrue%7D%5D%2C%22page%22%3A%7B%22id%22%3A%22pages-home-c4bcbfb771e9%22%2C%22pathTemplate%22%3A%22%2F%22%7D%7D%2C%22segmentCookie%22%3A%22deco_segment%22%2C%22featureFlags%22%3A%7B%22bypassDecoImageOptimization%22%3Afalse%2C%22cdnHost%22%3A%22https%3A%2F%2Fdecoims.com%22%7D%7D) | |
| js | https://s.lilstts.com/deco.js | |
| js | data:text/javascript,(()%3D%3E%7Bconst%20s%3D%7B%7D%2Ct%3D()%3D%3EglobalThis.window.stonks%3F.view%3F.(s)%2Cn%3Dhistory.pushState%3Bn%26%26(history.pushState%3Dfunction()%7Bn.apply(this%2Carguments)%2Ct()%7D%2CaddEventListener(%22popstate%22%2Ct))%3Bconst%20o%3Ds%3D%3E%60%24%7Bs%7D%60.slice(0%2C990)%3BglobalThis.window.DECO.events.subscribe((n%3D%3E%7Bif(n%26%26%22deco%22%3D%3D%3Dn.name)%7Bif(n.params)%7Bconst%7Bflags%3At%2Cpage%3Ae%7D%3Dn.params%3Bif(Array.isArray(t))for(const%20n%20of%20t)s%5Bn.name%5D%3Do(n.value.toString())%3Bs.pageId%3Do(%60%24%7Be.id%7D%60)%7Dt()%7D%7D))()%2CglobalThis.window.DECO.events.subscribe((t%3D%3E%7Bif(!t)return%3Bconst%7Bname%3An%2Cparams%3Ae%7D%3Dt%3Bif(!n%7C%7C!e%7C%7C%22deco%22%3D%3D%3Dn)return%3Bconst%20i%3D%7B...s%7D%3Bfor(const%20s%20in%20e)%7Bconst%20t%3De%5Bs%5D%3Bnull!%3Dt%26%26(i%5Bs%5D%3Do(%22object%22!%3Dtypeof%20t%3Ft%3AJSON.stringify(t)))%7DglobalThis.window.stonks%3F.event%3F.(n%2Ci)%7D))%7D)() | |
| js | module | https://www.oppuz.com/script/farmrio.js |
| js | https://static.sizebay.technology/7664/prescript.js | |
| js | https://cdn.jsdelivr.net/npm/htmx.org@1.9.12 | |
| js | https://cdn.jsdelivr.net/npm/htmx.org@1.9.12/dist/ext/head-support.js | |
| js | https://cdn.jsdelivr.net/npm/@azzas/azzas-tracker-web@2.0.0-preview.20/dist/mod.global.js | |
| js | data:text/javascript,(e%3D%3E%7B(()%3D%3E%7Bconst%20o%3Dnew%20URL(e.url).pathname%3Bif(globalThis.window.dataLayer%3DglobalThis.window.dataLayer%7C%7C%5B%5D%2C%22%2F%22%3D%3D%3Do)return%20globalThis.window.dataLayer.push(%7Blocal%3A%22home%22%2Cpage_category%3A%22home%22%7D)%2Cvoid%200%3Bconst%20a%3Ddocument.querySelector(%22script%5Btype%3D'application%2Fld%2Bjson'%5D%22)%2Ct%3Da%3F.textContent%3Bif(!t)return%20globalThis.window.dataLayer.push(%7Blocal%3A%22other%22%7D)%2Cvoid%200%3Bconst%20r%3DJSON.parse(t)%3Bif(%22ProductDetailsPage%22%3D%3D%3Dr%5B%22%40type%22%5D)%7Bconst%20e%3Dr%3Breturn%20globalThis.window.dataLayer.push(%7Blocal%3A%22PDP%22%2Cpage_category%3A%22pdp%22%2Cseller_id%3Ae.product%3F.offers%3F.offers%3F.%5B0%5D%3F.seller%2Cseller_ids%3Ae.product%3F.offers%3F.offers%3F.map((e%3D%3Ee.seller)).join(%22%2C%22)%2Cproduct_reference_id%3Ae.product%3F.productID%2Csku_stocks%3Ae.product%3F.isVariantOf%3F.hasVariant%3F.map((e%3D%3E(%7B%5Be.productID%5D%3Ae.offers%3F.offers%3F.%5B0%5D%3F.inventoryLevel.value%7D)))%7D)%2Cvoid%200%7Dif(%22ProductListingPage%22%3D%3D%3Dr%5B%22%40type%22%5D)%7Bconst%20e%3Dr%3Breturn%20globalThis.window.dataLayer.push(%7Blocal%3A%22PLP%22%2Cpage_category%3A%22lista-produtos%22%2Cpage_department%3Ae.seo%3F.title%7D)%2Cvoid%200%7DglobalThis.window.dataLayer.push(%7Blocal%3A%22other%22%7D)%7D)()%7D)(%7B%22url%22%3A%22https%3A%2F%2Fwww.farmrio.com.br%2F%22%7D) | |
| js | data:text/javascript,(()%3D%3E%7BglobalThis.window.DECO.events.subscribe((e%3D%3E%7Bif(globalThis.window.dataLayer%3DglobalThis.window.dataLayer%7C%7C%5B%5D%2Ce%26%26globalThis.window.dataLayer%26%26%22function%22%3D%3Dtypeof%20globalThis.window.dataLayer.push)return%22deco%22%3D%3D%3De.name%3F(globalThis.window.dataLayer.push(%7Bevent%3Ae.name%2Cdeco%3Ae.params%7D)%2Cvoid%200)%3A(!function(e)%7Bconst%20a%3DglobalThis.window%3F.STOREFRONT%3F.AZZAS_TRACKER_WEB%3Bif(!a)return%20console.error(%22%5BDT%5D%20SDK%20de%20tracking%20n%C3%A3o%20encontrado%22)%2Cvoid%200%3Bconst%20o%3Da.availableEvents()%7C%7Cnull%3Bif(Object.values(o).find((a%3D%3Ea%3F.name%3D%3D%3De.name))%7C%7Cconsole.warn(%22%5BDT%5D%3A%20not%20azzas%20tracker%20event%3A%20%22%2Ce.name%7C%7CJSON.stringify(e))%2C%5B%22view_promotion%22%2C%22select_promotion%22%2C%22select_content%22%2C%22search%22%2C%22select_item%22%2C%22view_item%22%2C%22view_item_list%22%2C%22add_to_wishlist%22%2C%22add_to_cart%22%2C%22remove_from_cart%22%2C%22custom_view_cart%22%2C%22search_zipcode%22%2C%22notify_me%22%2C%22refine_results%22%2C%22custom_user_info%22%2C%22grid_size%22%5D.includes(e.name))a.trackEvent(e.name.toUpperCase()%2C%7B...e.params%2Cwindow%3AglobalThis.window%7D)%3Belse%20if(e.hasCommerce)globalThis.window.dataLayer.push(%7Bevent%3Ae.name%2Cecommerce%3Ae.params%7D)%3Belse%7Bconst%7BhasCommerce%3Aa%2C...o%7D%3De%3BglobalThis.window%3F.dataLayer%3F.push(%7B...o%7D)%7D%7D(e)%2Cvoid%200)%7D))%7D)() | |
| js | text/javascript | https://cdn.cookielaw.org/scripttemplates/otSDKStub.js |
| js | data:text/javascript;base64,ZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZSgoKHsgcm9vdElkLCBzY3JvbGwgPSAic21vb3RoIiwgaW50ZXJ2YWwsIGluZmluaXRlLCBvbmVCeW9uZSwgaXRlbURvdHMsIHBhZ2VEb3RzLCBzY3JvbGxEb3RzLCBpc0Zyb21Ib29rID0gZmFsc2UsIGRlc2t0b3BEcmFnZ2FibGUgPSBmYWxzZSB9KT0+ewogIGNvbnN0IEFUVFJJQlVURVMgPSBpc0Zyb21Ib29rIC8vIHRoaXMgaXMgdXNlZCB0byBrZWVwIGNvbXBhdGliaWxpdHkgdG8gdGhlIG9sZCB3YXkgdG8gY3JlYXRlIGEgc2xpZGVyCiAgID8gewogICAgImRhdGEtc2xpZGVyIjogYFtkYXRhLXNsaWRlcl1bZGF0YS1yb290PSR7cm9vdElkfV1gLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiBgW2RhdGEtc2xpZGVyLWl0ZW1dW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6IGBbZGF0YS1zbGlkZT0icHJldiJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6IGBbZGF0YS1zbGlkZT0ibmV4dCJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLWRvdCI6IGBbZGF0YS1kb3RdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLXByb2dyZXNzIjogYFtkYXRhLXByb2dyZXNzXVtkYXRhLXJvb3Q9JHtyb290SWR9XWAKICB9IDogewogICAgImRhdGEtc2xpZGVyIjogIltkYXRhLXNsaWRlcl0iLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiAiW2RhdGEtc2xpZGVyLWl0ZW1dIiwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6ICdbZGF0YS1zbGlkZT0icHJldiJdJywKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6ICdbZGF0YS1zbGlkZT0ibmV4dCJdJywKICAgICJkYXRhLWRvdCI6ICJbZGF0YS1kb3RdIiwKICAgICJkYXRhLXByb2dyZXNzIjogIltkYXRhLXByb2dyZXNzXSIKICB9OwogIC8vIFBlcmNlbnRhZ2Ugb2YgdGhlIGl0ZW0gdGhhdCBoYXMgdG8gYmUgaW5zaWRlIHRoZSBjb250YWluZXIKICAvLyBmb3IgaXQgaXQgYmUgY29uc2lkZXJlZCBhcyBpbnNpZGUgdGhlIGNvbnRhaW5lcgogIGNvbnN0IFRIUkVTSE9MRCA9IDAuNzU7CiAgY29uc3QgVVNFX0lORklOSVRFX0JFSEFWSU9VUiA9IHRydWU7CiAgY29uc3QgaW50ZXJzZWN0aW9uWCA9IChlbGVtZW50LCBjb250YWluZXIpPT57CiAgICBjb25zdCBkZWx0YSA9IGNvbnRhaW5lci53aWR0aCAvIDFfMDAwOwogICAgaWYgKGVsZW1lbnQucmlnaHQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiAwLjA7CiAgICB9CiAgICBpZiAoZWxlbWVudC5sZWZ0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIDAuMDsKICAgIH0KICAgIGlmIChlbGVtZW50LmxlZnQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiBlbGVtZW50LnJpZ2h0IC0gY29udGFpbmVyLmxlZnQgKyBkZWx0YTsKICAgIH0KICAgIGlmIChlbGVtZW50LnJpZ2h0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIGNvbnRhaW5lci5yaWdodCAtIGVsZW1lbnQubGVmdCArIGRlbHRhOwogICAgfQogICAgcmV0dXJuIGVsZW1lbnQud2lkdGg7CiAgfTsKICAvLyBhcyBhbnkgYXJlIG9rIGluIHR5cGVndWFyZCBmdW5jdGlvbnMKICBjb25zdCBpc0hUTUxFbGVtZW50ID0gKHgpPT4vLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueQogICAgdHlwZW9mIHgub2Zmc2V0TGVmdCA9PT0gIm51bWJlciI7CiAgY29uc3Qgcm9vdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHJvb3RJZCkgPz8gZG9jdW1lbnQuY3VycmVudFNjcmlwdD8ucGFyZW50RWxlbWVudCA/PyBudWxsOwogIGNvbnN0IHNsaWRlciA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1zbGlkZXIiXSk7CiAgY29uc3QgaXRlbXMgPSBzbGlkZXI/LnF1ZXJ5U2VsZWN0b3JBbGwoQVRUUklCVVRFU1siZGF0YS1zbGlkZXItaXRlbSJdKTsKICBjb25zdCBwcmV2ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJwcmV2IiddKTsKICBjb25zdCBuZXh0ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJuZXh0IiddKTsKICBjb25zdCBkb3RzID0gcm9vdD8ucXVlcnlTZWxlY3RvckFsbChBVFRSSUJVVEVTWyJkYXRhLWRvdCJdKTsKICBjb25zdCBwcm9ncmVzcyA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1wcm9ncmVzcyJdKTsKICBpZiAoIXJvb3QgfHwgIXNsaWRlciB8fCAhaXRlbXMgfHwgaXRlbXMubGVuZ3RoID09PSAwKSB7CiAgICBjb25zb2xlLndhcm4oIk1pc3NpbmcgbmVjZXNzYXJ5IHNsaWRlciBhdHRyaWJ1dGVzLiBJdCB3aWxsIG5vdCB3b3JrIGFzIGludGVuZGVkLiBOZWNlc3NhcnkgZWxlbWVudHM6IiwgewogICAgICByb290LAogICAgICBzbGlkZXIsCiAgICAgIGl0ZW1zLAogICAgICByb290SWQKICAgIH0pOwogICAgcmV0dXJuOwogIH0KICBjb25zdCBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lciA9ICgpPT57CiAgICBjb25zdCBpbmRpY2VzID0gW107CiAgICBjb25zdCBzbGlkZXJSZWN0ID0gc2xpZGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaXRlbXMubGVuZ3RoOyBpbmRleCsrKXsKICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zLml0ZW0oaW5kZXgpOwogICAgICBjb25zdCByZWN0ID0gaXRlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgY29uc3QgcmF0aW8gPSBpbnRlcnNlY3Rpb25YKHJlY3QsIHNsaWRlclJlY3QpIC8gcmVjdC53aWR0aDsKICAgICAgaWYgKHJhdGlvID4gVEhSRVNIT0xEKSB7CiAgICAgICAgaW5kaWNlcy5wdXNoKGluZGV4KTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGluZGljZXM7CiAgfTsKICBjb25zdCBlbGVtZW50c0luc2lkZUNvbnRhaW5lciA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgY29uc3QgaW5maW5pdGVCZWhhdmlvciA9ICFzY3JvbGxEb3RzICYmIGluZmluaXRlICYmIGVsZW1lbnRzSW5zaWRlQ29udGFpbmVyLmxlbmd0aCA9PT0gMSAmJiBpdGVtcy5sZW5ndGggPiAxICYmIFVTRV9JTkZJTklURV9CRUhBVklPVVI7CiAgY29uc3QgZ2V0TWF4U2Nyb2xsTGVmdCA9ICgpPT5NYXRoLm1heCgwLCBzbGlkZXIuc2Nyb2xsV2lkdGggLSBzbGlkZXIuY2xpZW50V2lkdGgpOwogIGNvbnN0IGNsYW1wU2Nyb2xsTGVmdCA9IChsZWZ0KT0+TWF0aC5taW4oTWF0aC5tYXgobGVmdCwgMCksIGdldE1heFNjcm9sbExlZnQoKSk7CiAgY29uc3QgZ2V0SXRlbVNjcm9sbExlZnQgPSAoaXRlbSk9PnsKICAgIGlmICghaXNIVE1MRWxlbWVudChpdGVtKSkgcmV0dXJuIDA7CiAgICByZXR1cm4gY2xhbXBTY3JvbGxMZWZ0KGl0ZW0ub2Zmc2V0TGVmdCAtIHNsaWRlci5vZmZzZXRMZWZ0KTsKICB9OwogIGxldCBzY3JvbGxEb3RQb3NpdGlvbnMgPSBbXTsKICBjb25zdCBnZXRTY3JvbGxEb3RQb3NpdGlvbnMgPSAoKT0+ewogICAgaWYgKCFzY3JvbGxEb3RzKSByZXR1cm4gW107CiAgICBpZiAoc2xpZGVyLmNsaWVudFdpZHRoIDw9IDApIHsKICAgICAgcmV0dXJuIHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggPyBzY3JvbGxEb3RQb3NpdGlvbnMgOiBbCiAgICAgICAgMAogICAgICBdOwogICAgfQogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHJldHVybiBbCiAgICAgIDAKICAgIF07CiAgICBjb25zdCB2aXNpYmxlSXRlbXMgPSBNYXRoLm1heChnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpLmxlbmd0aCwgMSk7CiAgICBjb25zdCBwb3NpdGlvbnMgPSBbCiAgICAgIDAKICAgIF07CiAgICBmb3IobGV0IGluZGV4ID0gdmlzaWJsZUl0ZW1zOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXggKz0gdmlzaWJsZUl0ZW1zKXsKICAgICAgcG9zaXRpb25zLnB1c2goZ2V0SXRlbVNjcm9sbExlZnQoaXRlbXMuaXRlbShpbmRleCkpKTsKICAgIH0KICAgIHBvc2l0aW9ucy5wdXNoKG1heFNjcm9sbExlZnQpOwogICAgcmV0dXJuIHBvc2l0aW9ucy5yZWR1Y2UoKGFjYywgcG9zaXRpb24pPT57CiAgICAgIGNvbnN0IHJvdW5kZWRQb3NpdGlvbiA9IE1hdGgucm91bmQoY2xhbXBTY3JvbGxMZWZ0KHBvc2l0aW9uKSk7CiAgICAgIGNvbnN0IGxhc3RQb3NpdGlvbiA9IGFjY1thY2MubGVuZ3RoIC0gMV07CiAgICAgIGlmIChsYXN0UG9zaXRpb24gPT09IHVuZGVmaW5lZCB8fCBNYXRoLmFicyhsYXN0UG9zaXRpb24gLSByb3VuZGVkUG9zaXRpb24pID4gMSkgewogICAgICAgIGFjYy5wdXNoKHJvdW5kZWRQb3NpdGlvbik7CiAgICAgIH0KICAgICAgcmV0dXJuIGFjYzsKICAgIH0sIFtdKTsKICB9OwogIGNvbnN0IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCA9ICgpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIHNjcm9sbERvdFBvc2l0aW9ucy5mb3JFYWNoKChwb3NpdGlvbiwgaW5kZXgpPT57CiAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnMoc2xpZGVyLnNjcm9sbExlZnQgLSBwb3NpdGlvbik7CiAgICAgIGlmIChkaXN0YW5jZSA8IHNtYWxsZXN0RGlzdGFuY2UpIHsKICAgICAgICBzbWFsbGVzdERpc3RhbmNlID0gZGlzdGFuY2U7CiAgICAgICAgYWN0aXZlSW5kZXggPSBpbmRleDsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gYWN0aXZlSW5kZXg7CiAgfTsKICBjb25zdCB1cGRhdGVTY3JvbGxEb3RzID0gKCk9PnsKICAgIGlmICghc2Nyb2xsRG90cyB8fCAhZG90cykgcmV0dXJuOwogICAgc2Nyb2xsRG90UG9zaXRpb25zID0gZ2V0U2Nyb2xsRG90UG9zaXRpb25zKCk7CiAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90LCBpbmRleCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIGlmIChpbmRleCA+PSBzY3JvbGxEb3RQb3NpdGlvbnMubGVuZ3RoKSB7CiAgICAgICAgZG90LmNsYXNzTGlzdC5hZGQoImhpZGRlbiIpOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgIGlmIChpbmRleCA9PT0gYWN0aXZlSW5kZXgpIHsKICAgICAgICBkb3Quc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgIH0KICAgIH0pOwogICAgaWYgKCFpbmZpbml0ZSkgewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxID8gcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKSA6IHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPj0gbWF4U2Nyb2xsTGVmdCAtIDEgPyBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpIDogbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgfQogIH07CiAgY29uc3QgZ29Ub1Njcm9sbERvdCA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGNvbnN0IHBvc2l0aW9uID0gc2Nyb2xsRG90UG9zaXRpb25zW2luZGV4XTsKICAgIGlmIChwb3NpdGlvbiA9PT0gdW5kZWZpbmVkKSByZXR1cm47CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBwb3NpdGlvbgogICAgfSk7CiAgfTsKICBjb25zdCBub3JtYWxpemVTY3JvbGxCb3VuZHMgPSAoKT0+ewogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA+IG1heFNjcm9sbExlZnQpIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBtYXhTY3JvbGxMZWZ0OwogICAgfSBlbHNlIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA8IDApIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSAwOwogICAgfQogIH07CiAgbGV0IHRvdWNoU3RhcnRYID0gMDsKICBsZXQgdG91Y2hTdGFydFkgPSAwOwogIGNvbnN0IGhhbmRsZVRvdWNoU3RhcnQgPSAoZXZlbnQpPT57CiAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07CiAgICBpZiAoIXRvdWNoKSByZXR1cm47CiAgICB0b3VjaFN0YXJ0WCA9IHRvdWNoLmNsaWVudFg7CiAgICB0b3VjaFN0YXJ0WSA9IHRvdWNoLmNsaWVudFk7CiAgfTsKICBjb25zdCBoYW5kbGVUb3VjaE1vdmUgPSAoZXZlbnQpPT57CiAgICBpZiAoIXNjcm9sbERvdHMpIHJldHVybjsKICAgIGNvbnN0IHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTsKICAgIGlmICghdG91Y2gpIHJldHVybjsKICAgIGNvbnN0IGRlbHRhWCA9IHRvdWNoLmNsaWVudFggLSB0b3VjaFN0YXJ0WDsKICAgIGNvbnN0IGRlbHRhWSA9IHRvdWNoLmNsaWVudFkgLSB0b3VjaFN0YXJ0WTsKICAgIGNvbnN0IGlzSG9yaXpvbnRhbEdlc3R1cmUgPSBNYXRoLmFicyhkZWx0YVgpID4gTWF0aC5hYnMoZGVsdGFZKTsKICAgIGlmICghaXNIb3Jpem9udGFsR2VzdHVyZSkgcmV0dXJuOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHsKICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcygpOwogICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdCBpc0F0U3RhcnQgPSBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxOwogICAgY29uc3QgaXNBdEVuZCA9IHNsaWRlci5zY3JvbGxMZWZ0ID49IG1heFNjcm9sbExlZnQgLSAxOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RTdGFydCA9IGlzQXRTdGFydCAmJiBkZWx0YVggPiAwOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RFbmQgPSBpc0F0RW5kICYmIGRlbHRhWCA8IDA7CiAgICBpZiAoaXNEcmFnZ2luZ1Bhc3RTdGFydCB8fCBpc0RyYWdnaW5nUGFzdEVuZCkgewogICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgbm9ybWFsaXplU2Nyb2xsQm91bmRzKCk7CiAgICB9CiAgfTsKICBjb25zdCBnb1RvSXRlbSA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBjb25zdCBpdGVtID0gc2xpZGVyLnF1ZXJ5U2VsZWN0b3IoYGxpW2RhdGEtcm9vdD0nJHtyb290SWR9J11bZGF0YS1zbGlkZXItaXRlbT0nJHtpbmRleH0nXWApID8/IHNsaWRlci5xdWVyeVNlbGVjdG9yKGBsaVtkYXRhLXNsaWRlci1pdGVtPScke2luZGV4fSddYCk7CiAgICBpZiAoaXRlbSkgewogICAgICBpZiAoIWlzSFRNTEVsZW1lbnQoaXRlbSkpIHsKICAgICAgICBjb25zb2xlLndhcm4oYEVsZW1lbnQgYXQgaW5kZXggJHtpbmRleH0gaXMgbm90IGFuIGh0bWwgZWxlbWVudC4gU2tpcHBpbmcgY2Fyb3VzZWxgKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgc2xpZGVyLnNjcm9sbFRvKHsKICAgICAgICB0b3A6IDAsCiAgICAgICAgYmVoYXZpb3I6IGJlaGF2aW9yLAogICAgICAgIGxlZnQ6IGl0ZW0ub2Zmc2V0TGVmdCAtIHJvb3Qub2Zmc2V0TGVmdAogICAgICB9KTsKICAgIH0KICB9OwogIGNvbnN0IGdvVG9JdGVtRG90ID0gKGluZGV4LCBiZWhhdmlvciA9IHNjcm9sbCk9PnsKICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgIGlmICghaXRlbSkgcmV0dXJuOwogICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSB7CiAgICAgIGNvbnNvbGUud2FybihgRWxlbWVudCBhdCBpbmRleCAke2luZGV4fSBpcyBub3QgYW4gaHRtbCBlbGVtZW50LiBTa2lwcGluZyBjYXJvdXNlbGApOwogICAgICByZXR1cm47CiAgICB9CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdAogICAgfSk7CiAgfTsKICBjb25zdCBnZXROZWFyZXN0SXRlbUluZGV4ID0gKCk9PnsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIGZvcihsZXQgaW5kZXggPSAwOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXgrKyl7CiAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSBjb250aW51ZTsKICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLmFicyhzbGlkZXIuc2Nyb2xsTGVmdCAtIChpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdCkpOwogICAgICBpZiAoZGlzdGFuY2UgPCBzbWFsbGVzdERpc3RhbmNlKSB7CiAgICAgICAgc21hbGxlc3REaXN0YW5jZSA9IGRpc3RhbmNlOwogICAgICAgIGFjdGl2ZUluZGV4ID0gaW5kZXg7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBhY3RpdmVJbmRleDsKICB9OwogIGNvbnN0IG9uQ2xpY2tQcmV2ID0gKCk9PnsKICAgIGlmIChzY3JvbGxEb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdFNjcm9sbERvdEluZGV4KCk7CiAgICAgIGFjdGl2ZUluZGV4ID09PSAwID8gaW5maW5pdGUgPyBnb1RvU2Nyb2xsRG90KHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggLSAxKSA6IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChpdGVtRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RJdGVtSW5kZXgoKTsKICAgICAgYWN0aXZlSW5kZXggPT09IDAgPyBpbmZpbml0ZSA/IGdvVG9JdGVtRG90KGl0ZW1zLmxlbmd0aCAtIDEpIDogbnVsbCA6IGdvVG9JdGVtRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIFdvdyEgaXRlbXMgcGVyIHBhZ2UgaXMgaG93IG1hbnkgZWxlbWVudHMgYXJlIGJlaW5nIGRpc3BsYXllZCBpbnNpZGUgdGhlIGNvbnRhaW5lciEhCiAgICBjb25zdCBpdGVtc1BlclBhZ2UgPSBpbmRpY2VzLmxlbmd0aDsKICAgIGNvbnN0IGlzU2hvd2luZ0ZpcnN0ID0gaW5kaWNlc1swXSA9PT0gMDsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdIC8gaXRlbXNQZXJQYWdlKTsKICAgIGlmIChvbmVCeW9uZSkgewogICAgICBpc1Nob3dpbmdGaXJzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oaXRlbXMubGVuZ3RoIC0gMSkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSAtIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nRmlyc3QgPyBpbmZpbml0ZUJlaGF2aW9yID8gaXRlbXMubGVuZ3RoIDogaXRlbXMubGVuZ3RoIC0gMSA6IChwYWdlSW5kZXggLSAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCBvbkNsaWNrTmV4dCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gc2Nyb2xsRG90UG9zaXRpb25zLmxlbmd0aCAtIDEgPyBpbmZpbml0ZSA/IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4KSA6IGdvVG9TY3JvbGxEb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGl0ZW1Eb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdEl0ZW1JbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gaXRlbXMubGVuZ3RoIC0gMSA/IGluZmluaXRlID8gZ29Ub0l0ZW1Eb3QoMCkgOiBudWxsIDogZ29Ub0l0ZW1Eb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgaW5kaWNlcyA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgICBpZiAoaW5kaWNlcy5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgLy8gV293ISBpdGVtcyBwZXIgcGFnZSBpcyBob3cgbWFueSBlbGVtZW50cyBhcmUgYmVpbmcgZGlzcGxheWVkIGluc2lkZSB0aGUgY29udGFpbmVyISEKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGluZGljZXMubGVuZ3RoOwogICAgY29uc3QgaXNTaG93aW5nTGFzdCA9IGluZGljZXNbaW5kaWNlcy5sZW5ndGggLSAxXSA9PT0gaXRlbXMubGVuZ3RoIC0gMTsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1swXSAvIGl0ZW1zUGVyUGFnZSk7CiAgICAvLyBnb1RvSXRlbShpc1Nob3dpbmdMYXN0ID8gMCA6IChpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICBpZiAob25lQnlvbmUpIHsKICAgICAgaXNTaG93aW5nTGFzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oMCkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSArIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nTGFzdCA/IGluZmluaXRlQmVoYXZpb3IgPyBpdGVtcy5sZW5ndGggKyAxIDogMCA6IChwYWdlSW5kZXggKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCB1cGRhdGVQYWdlRG90cyA9ICgpPT57CiAgICBpZiAoIXBhZ2VEb3RzIHx8ICFkb3RzKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IE1hdGgubWF4KGluZGljZXMubGVuZ3RoLCAxKTsKICAgIGNvbnN0IG1heFZpc2libGUgPSBNYXRoLm1heCguLi5pbmRpY2VzKTsKICAgIGNvbnN0IHBhZ2VEb3RJbmRleCA9IE1hdGguZmxvb3IobWF4VmlzaWJsZSAvIGl0ZW1zUGVyUGFnZSkgKiBpdGVtc1BlclBhZ2U7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCwgaSk9PnsKICAgICAgaWYgKGkgJSBpdGVtc1BlclBhZ2UgIT09IDApIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShwYWdlRG90SW5kZXgpOwogICAgaWYgKGFjdGl2ZURvdCkgewogICAgICBBcnJheS5mcm9tKGRvdHMpLmZpbHRlcigoX2RvdCwgaSk9PmkgPCBwYWdlRG90SW5kZXggJiYgaSAlIGl0ZW1zUGVyUGFnZSA9PT0gMCkuZm9yRWFjaCgoZG90KT0+ZG90LnNldEF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIiwgInRydWUiKSk7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IHVwZGF0ZUFjdGl2ZURvdCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICB1cGRhdGVTY3JvbGxEb3RzKCk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChwYWdlRG90cyB8fCAhZG90cykgewogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoaXRlbURvdHMpIHsKICAgICAgY29uc3QgYWN0aXZlSW5kZXggPSBnZXROZWFyZXN0SXRlbUluZGV4KCk7CiAgICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90KT0+ewogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtcGFpbnRlZCIpOwogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIH0pOwogICAgICBjb25zdCBhY3RpdmVEb3QgPSBkb3RzLml0ZW0oYWN0aXZlSW5kZXgpOwogICAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgICAgYWN0aXZlRG90LnNldEF0dHJpYnV0ZSgiZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gTWF0aC5taW4oLi4uaW5kaWNlcyk7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShhY3RpdmVJbmRleCk7CiAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGlmIChwYWdlRG90cykgewogICAgICB1cGRhdGVQYWdlRG90cygpOwogICAgfSBlbHNlIHsKICAgICAgdXBkYXRlQWN0aXZlRG90KCk7CiAgICB9CiAgICBlbGVtZW50cy5mb3JFYWNoKChpdGVtKT0+ewogICAgICBjb25zdCBpbmRleCA9IE51bWJlcihpdGVtLnRhcmdldC5nZXRBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKSkgfHwgMDsKICAgICAgaWYgKCFpbmZpbml0ZSAmJiAhc2Nyb2xsRG90cykgewogICAgICAgIGlmIChpbmRleCA9PT0gMCkgewogICAgICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcpIHsKICAgICAgICAgICAgcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGluZGV4ID09PSBpdGVtcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICBpZiAoaXRlbS5pc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocHJvZ3Jlc3MpIHsKICAgICAgICAgIGlmIChwcm9ncmVzcy5pZCA9PSAiMCIgJiYgaW5kZXggPT09IGl0ZW1zLmxlbmd0aCAtIDEpIHsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUuaGVpZ2h0ID0gYCR7MSAvIGl0ZW1zLmxlbmd0aCAqIDEwMH0lYDsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUud2lkdGggPSBgJHsxIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5pZCA9ICIxIjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByb2dyZXNzLnN0eWxlLmhlaWdodCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5zdHlsZS53aWR0aCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfSwgewogICAgdGhyZXNob2xkOiBUSFJFU0hPTEQsCiAgICByb290OiBzbGlkZXIsCiAgICByb290TWFyZ2luOiAiMTAwcHgiCiAgfSk7CiAgY29uc3QgZnVsbE9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGVsZW1lbnRzLmZvckVhY2goKGl0ZW0pPT57CiAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IHNsaWRlcj8ucXVlcnlTZWxlY3RvckFsbChgbGlgKTsKICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcgJiYgZWxlbWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT0gY3VycmVudEl0ZW1zWzFdKSB7CiAgICAgICAgICBzZXRUaW1lb3V0KCgpPT57CiAgICAgICAgICAgIGdvVG9JdGVtKGl0ZW1zLmxlbmd0aCAtIDEsICJpbnN0YW50Iik7CiAgICAgICAgICB9LCAyMDApOwogICAgICAgIH0KICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT09IGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pIHsKICAgICAgICAgIHNldFRpbWVvdXQoKCk9PnsKICAgICAgICAgICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICAgICAgICAgIH0sIDIwMCk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9LCB7CiAgICB0aHJlc2hvbGQ6IDAuNywKICAgIHJvb3Q6IHNsaWRlciwKICAgIHJvb3RNYXJnaW46ICIxMDBweCIKICB9KTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgY29uc3QgZmlyc3RJdGVtQ2xvbmUgPSBpdGVtc1swXS5jbG9uZU5vZGUodHJ1ZSk7CiAgICBjb25zdCBzZWNvbmRJdGVtQ2xvbmUgPSBpdGVtc1sxXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgcGVudWx0aW1hdGVJdGVtQ2xvbmUgPSBpdGVtc1tpdGVtcy5sZW5ndGggLSAyXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgbGFzdEl0ZW1DbG9uZSA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdLmNsb25lTm9kZSh0cnVlKTsKICAgIC8vIHdlIHJlbW92ZSB0aGVzZSBhdHRyaWJ1dGVzIGZyb20gdGhlIGNsb25lZCBpdGVtcyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gc2VuZCBldmVudHMgZm9yIHRoZSBjbG9uZWQgaXRlbXMKICAgIC8vIGJhbm5lciBjYXJvdXNlbCB1c2VzIGRhdGEtZXZlbnQgdG8gc2VuZCBldmVudHMgdG8gYW5hbHl0aWNzCiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBsYXN0SXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHBlbnVsdGltYXRlSXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuZmlyc3RFbGVtZW50Q2hpbGQ/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1ldmVudC10cmlnZ2VyIik7CiAgICBwZW51bHRpbWF0ZUl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgaXRlbXMubGVuZ3RoLnRvU3RyaW5nKCkpOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmU/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1zbGlkZXItaXRlbSIpOwogICAgZmlyc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgKGl0ZW1zLmxlbmd0aCArIDEpLnRvU3RyaW5nKCkpOwogICAgc2Vjb25kSXRlbUNsb25lPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKTsKICAgIHNsaWRlci5pbnNlcnRCZWZvcmUobGFzdEl0ZW1DbG9uZSwgaXRlbXNbMF0pOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmUgJiYgc2xpZGVyLmluc2VydEJlZm9yZShwZW51bHRpbWF0ZUl0ZW1DbG9uZSwgbGFzdEl0ZW1DbG9uZSk7CiAgICBzbGlkZXIuYXBwZW5kQ2hpbGQoZmlyc3RJdGVtQ2xvbmUpOwogICAgc2Vjb25kSXRlbUNsb25lICYmIHNsaWRlci5hcHBlbmRDaGlsZChzZWNvbmRJdGVtQ2xvbmUpOwogICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICB9CiAgY29uc3QgY3VycmVudEl0ZW1zID0gc2xpZGVyPy5xdWVyeVNlbGVjdG9yQWxsKGBsaWApOwogIGl0ZW1zLmZvckVhY2goKGl0ZW0pPT5vYnNlcnZlci5vYnNlcnZlKGl0ZW0pKTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgZnVsbE9ic2VydmVyLm9ic2VydmUoY3VycmVudEl0ZW1zWzFdKTsKICAgIGZ1bGxPYnNlcnZlci5vYnNlcnZlKGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pOwogIH0KICBpZiAocGFnZURvdHMpIHsKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCkubGVuZ3RoOwogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGNvbnN0IGRvdCA9IGRvdHM/Lml0ZW0oaXQpOwogICAgICBpZiAoIWRvdCkgY29udGludWU7CiAgICAgIGlmIChpdCAlIGl0ZW1zUGVyUGFnZSAhPT0gMCkgewogICAgICAgIGRvdC5jbGFzc0xpc3QuYWRkKCJoaWRkZW4iKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgICAgZG90LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKHNjcm9sbERvdHMpIHsKICAgIHVwZGF0ZVNjcm9sbERvdHMoKTsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5nb1RvU2Nyb2xsRG90KGl0KSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5pdGVtRG90cyA/IGdvVG9JdGVtRG90KGl0KSA6IGdvVG9JdGVtKGl0KSk7CiAgICB9CiAgfQogIHByZXY/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja1ByZXYpOwogIG5leHQ/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogIGlmIChzY3JvbGxEb3RzKSB7CiAgICBzbGlkZXIuc3R5bGUub3ZlcnNjcm9sbEJlaGF2aW9yWCA9ICJjb250YWluIjsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJzY3JvbGwiLCBub3JtYWxpemVTY3JvbGxCb3VuZHMsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2hzdGFydCIsIGhhbmRsZVRvdWNoU3RhcnQsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2htb3ZlIiwgaGFuZGxlVG91Y2hNb3ZlLCB7CiAgICAgIHBhc3NpdmU6IGZhbHNlCiAgICB9KTsKICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgfSBlbHNlIGlmIChwYWdlRG90cykgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZVBhZ2VEb3RzKTsKICB9IGVsc2UgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZUFjdGl2ZURvdCk7CiAgfQogIGNvbnN0IHRpbWVvdXQgPSBpbnRlcnZhbCAmJiBzZXRJbnRlcnZhbChvbkNsaWNrTmV4dCwgaW50ZXJ2YWwpOwogIGxldCBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXI7CiAgZnVuY3Rpb24gZW5hYmxlSG9yaXpvbnRhbFNjcm9sbCgpIHsKICAgIGlmICghc2xpZGVyKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGxldCBpc01vdXNlRG93biA9IGZhbHNlOwogICAgbGV0IHN0YXJ0WDsKICAgIGxldCBzY3JvbGxMZWZ0OwogICAgbGV0IHZlbG9jaXR5ID0gMDsKICAgIGxldCBtb21lbnR1bUZyYW1lOwogICAgY29uc3QgbW9tZW50dW1TY3JvbGwgPSAoKT0+ewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCArPSB2ZWxvY2l0eTsKICAgICAgdmVsb2NpdHkgKj0gMC45NTsKICAgICAgaWYgKE1hdGguYWJzKHZlbG9jaXR5KSA+IDAuMSkgewogICAgICAgIG1vbWVudHVtRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUobW9tZW50dW1TY3JvbGwpOwogICAgICB9CiAgICB9OwogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlZG93biIsIChlKT0+ewogICAgICBpc01vdXNlRG93biA9IHRydWU7CiAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAiZ3JhYmJpbmciOwogICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAiaW5pdGlhbCI7CiAgICAgIHN0YXJ0WCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgc2Nyb2xsTGVmdCA9IHNsaWRlci5zY3JvbGxMZWZ0OwogICAgICB2ZWxvY2l0eSA9IDA7CiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtRnJhbWUpOwogICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICB9KTsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWxlYXZlIiwgKCk9PnsKICAgICAgaWYgKGlzTW91c2VEb3duKSB7CiAgICAgICAgaXNNb3VzZURvd24gPSBmYWxzZTsKICAgICAgICBzbGlkZXIuZGF0YXNldFsiZHJhZ2dpbmciXSA9ICJmYWxzZSI7CiAgICAgICAgc2xpZGVyLnN0eWxlLmN1cnNvciA9ICJncmFiIjsKICAgICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAic21vb3RoIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2V1cCIsICgpPT57CiAgICAgIGlmIChpc01vdXNlRG93bikgewogICAgICAgIGlzTW91c2VEb3duID0gZmFsc2U7CiAgICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAiZmFsc2UiOwogICAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAibm9ybWFsIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2Vtb3ZlIiwgKGUpPT57CiAgICAgIGlmICghaXNNb3VzZURvd24pIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29uc3QgeCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgY29uc3Qgd2FsayA9ICh4IC0gc3RhcnRYKSAqIDAuNTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBzY3JvbGxMZWZ0IC0gd2FsazsKICAgICAgdmVsb2NpdHkgPSAtd2FsayAqIDAuMjsKICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAidHJ1ZSI7CiAgICB9KTsKICB9CiAgaWYgKGRlc2t0b3BEcmFnZ2FibGUpIHsKICAgIHNsaWRlci5kYXRhc2V0WyJkcmFnZ2FibGUiXSA9ICJ0cnVlIjsKICAgIGVuYWJsZUhvcml6b250YWxTY3JvbGwoKTsKICB9CiAgaWYgKHNjcm9sbERvdHMgJiYgIlJlc2l6ZU9ic2VydmVyIiBpbiBnbG9iYWxUaGlzKSB7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIodXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShzbGlkZXIpOwogIH0KICAvLyBVbnJlZ2lzdGVyIGNhbGxiYWNrcwogIHJldHVybiAoKT0+ewogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGRvdHM/Lml0ZW0oaXQpLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICB9CiAgICBwcmV2Py5yZW1vdmVFdmVudExpc3RlbmVyKCJjbGljayIsIG9uQ2xpY2tQcmV2KTsKICAgIG5leHQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogICAgaWYgKHNjcm9sbERvdHMpIHsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcyk7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVTY3JvbGxEb3RzKTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNoc3RhcnQiLCBoYW5kbGVUb3VjaFN0YXJ0KTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNobW92ZSIsIGhhbmRsZVRvdWNoTW92ZSk7CiAgICAgIGdsb2JhbFRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICB9IGVsc2UgaWYgKHBhZ2VEb3RzKSB7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVQYWdlRG90cyk7CiAgICB9IGVsc2UgewogICAgICBzbGlkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlQWN0aXZlRG90KTsKICAgIH0KICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTsKICAgIHNjcm9sbERvdHNSZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpOwogICAgY2xlYXJJbnRlcnZhbCh0aW1lb3V0KTsKICB9Owp9KSh7InJvb3RJZCI6Im5tUDAzMTI0MjMwMjUtc2xpZGVyLTAiLCJvbmVCeW9uZSI6dHJ1ZSwic2Nyb2xsRG90cyI6dHJ1ZSwiZGVza3RvcERyYWdnYWJsZSI6ZmFsc2V9KSkp | |
| js | data:text/javascript;base64,ZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZSgoKHsgcm9vdElkLCBzY3JvbGwgPSAic21vb3RoIiwgaW50ZXJ2YWwsIGluZmluaXRlLCBvbmVCeW9uZSwgaXRlbURvdHMsIHBhZ2VEb3RzLCBzY3JvbGxEb3RzLCBpc0Zyb21Ib29rID0gZmFsc2UsIGRlc2t0b3BEcmFnZ2FibGUgPSBmYWxzZSB9KT0+ewogIGNvbnN0IEFUVFJJQlVURVMgPSBpc0Zyb21Ib29rIC8vIHRoaXMgaXMgdXNlZCB0byBrZWVwIGNvbXBhdGliaWxpdHkgdG8gdGhlIG9sZCB3YXkgdG8gY3JlYXRlIGEgc2xpZGVyCiAgID8gewogICAgImRhdGEtc2xpZGVyIjogYFtkYXRhLXNsaWRlcl1bZGF0YS1yb290PSR7cm9vdElkfV1gLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiBgW2RhdGEtc2xpZGVyLWl0ZW1dW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6IGBbZGF0YS1zbGlkZT0icHJldiJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6IGBbZGF0YS1zbGlkZT0ibmV4dCJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLWRvdCI6IGBbZGF0YS1kb3RdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLXByb2dyZXNzIjogYFtkYXRhLXByb2dyZXNzXVtkYXRhLXJvb3Q9JHtyb290SWR9XWAKICB9IDogewogICAgImRhdGEtc2xpZGVyIjogIltkYXRhLXNsaWRlcl0iLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiAiW2RhdGEtc2xpZGVyLWl0ZW1dIiwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6ICdbZGF0YS1zbGlkZT0icHJldiJdJywKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6ICdbZGF0YS1zbGlkZT0ibmV4dCJdJywKICAgICJkYXRhLWRvdCI6ICJbZGF0YS1kb3RdIiwKICAgICJkYXRhLXByb2dyZXNzIjogIltkYXRhLXByb2dyZXNzXSIKICB9OwogIC8vIFBlcmNlbnRhZ2Ugb2YgdGhlIGl0ZW0gdGhhdCBoYXMgdG8gYmUgaW5zaWRlIHRoZSBjb250YWluZXIKICAvLyBmb3IgaXQgaXQgYmUgY29uc2lkZXJlZCBhcyBpbnNpZGUgdGhlIGNvbnRhaW5lcgogIGNvbnN0IFRIUkVTSE9MRCA9IDAuNzU7CiAgY29uc3QgVVNFX0lORklOSVRFX0JFSEFWSU9VUiA9IHRydWU7CiAgY29uc3QgaW50ZXJzZWN0aW9uWCA9IChlbGVtZW50LCBjb250YWluZXIpPT57CiAgICBjb25zdCBkZWx0YSA9IGNvbnRhaW5lci53aWR0aCAvIDFfMDAwOwogICAgaWYgKGVsZW1lbnQucmlnaHQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiAwLjA7CiAgICB9CiAgICBpZiAoZWxlbWVudC5sZWZ0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIDAuMDsKICAgIH0KICAgIGlmIChlbGVtZW50LmxlZnQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiBlbGVtZW50LnJpZ2h0IC0gY29udGFpbmVyLmxlZnQgKyBkZWx0YTsKICAgIH0KICAgIGlmIChlbGVtZW50LnJpZ2h0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIGNvbnRhaW5lci5yaWdodCAtIGVsZW1lbnQubGVmdCArIGRlbHRhOwogICAgfQogICAgcmV0dXJuIGVsZW1lbnQud2lkdGg7CiAgfTsKICAvLyBhcyBhbnkgYXJlIG9rIGluIHR5cGVndWFyZCBmdW5jdGlvbnMKICBjb25zdCBpc0hUTUxFbGVtZW50ID0gKHgpPT4vLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueQogICAgdHlwZW9mIHgub2Zmc2V0TGVmdCA9PT0gIm51bWJlciI7CiAgY29uc3Qgcm9vdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHJvb3RJZCkgPz8gZG9jdW1lbnQuY3VycmVudFNjcmlwdD8ucGFyZW50RWxlbWVudCA/PyBudWxsOwogIGNvbnN0IHNsaWRlciA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1zbGlkZXIiXSk7CiAgY29uc3QgaXRlbXMgPSBzbGlkZXI/LnF1ZXJ5U2VsZWN0b3JBbGwoQVRUUklCVVRFU1siZGF0YS1zbGlkZXItaXRlbSJdKTsKICBjb25zdCBwcmV2ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJwcmV2IiddKTsKICBjb25zdCBuZXh0ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJuZXh0IiddKTsKICBjb25zdCBkb3RzID0gcm9vdD8ucXVlcnlTZWxlY3RvckFsbChBVFRSSUJVVEVTWyJkYXRhLWRvdCJdKTsKICBjb25zdCBwcm9ncmVzcyA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1wcm9ncmVzcyJdKTsKICBpZiAoIXJvb3QgfHwgIXNsaWRlciB8fCAhaXRlbXMgfHwgaXRlbXMubGVuZ3RoID09PSAwKSB7CiAgICBjb25zb2xlLndhcm4oIk1pc3NpbmcgbmVjZXNzYXJ5IHNsaWRlciBhdHRyaWJ1dGVzLiBJdCB3aWxsIG5vdCB3b3JrIGFzIGludGVuZGVkLiBOZWNlc3NhcnkgZWxlbWVudHM6IiwgewogICAgICByb290LAogICAgICBzbGlkZXIsCiAgICAgIGl0ZW1zLAogICAgICByb290SWQKICAgIH0pOwogICAgcmV0dXJuOwogIH0KICBjb25zdCBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lciA9ICgpPT57CiAgICBjb25zdCBpbmRpY2VzID0gW107CiAgICBjb25zdCBzbGlkZXJSZWN0ID0gc2xpZGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaXRlbXMubGVuZ3RoOyBpbmRleCsrKXsKICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zLml0ZW0oaW5kZXgpOwogICAgICBjb25zdCByZWN0ID0gaXRlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgY29uc3QgcmF0aW8gPSBpbnRlcnNlY3Rpb25YKHJlY3QsIHNsaWRlclJlY3QpIC8gcmVjdC53aWR0aDsKICAgICAgaWYgKHJhdGlvID4gVEhSRVNIT0xEKSB7CiAgICAgICAgaW5kaWNlcy5wdXNoKGluZGV4KTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGluZGljZXM7CiAgfTsKICBjb25zdCBlbGVtZW50c0luc2lkZUNvbnRhaW5lciA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgY29uc3QgaW5maW5pdGVCZWhhdmlvciA9ICFzY3JvbGxEb3RzICYmIGluZmluaXRlICYmIGVsZW1lbnRzSW5zaWRlQ29udGFpbmVyLmxlbmd0aCA9PT0gMSAmJiBpdGVtcy5sZW5ndGggPiAxICYmIFVTRV9JTkZJTklURV9CRUhBVklPVVI7CiAgY29uc3QgZ2V0TWF4U2Nyb2xsTGVmdCA9ICgpPT5NYXRoLm1heCgwLCBzbGlkZXIuc2Nyb2xsV2lkdGggLSBzbGlkZXIuY2xpZW50V2lkdGgpOwogIGNvbnN0IGNsYW1wU2Nyb2xsTGVmdCA9IChsZWZ0KT0+TWF0aC5taW4oTWF0aC5tYXgobGVmdCwgMCksIGdldE1heFNjcm9sbExlZnQoKSk7CiAgY29uc3QgZ2V0SXRlbVNjcm9sbExlZnQgPSAoaXRlbSk9PnsKICAgIGlmICghaXNIVE1MRWxlbWVudChpdGVtKSkgcmV0dXJuIDA7CiAgICByZXR1cm4gY2xhbXBTY3JvbGxMZWZ0KGl0ZW0ub2Zmc2V0TGVmdCAtIHNsaWRlci5vZmZzZXRMZWZ0KTsKICB9OwogIGxldCBzY3JvbGxEb3RQb3NpdGlvbnMgPSBbXTsKICBjb25zdCBnZXRTY3JvbGxEb3RQb3NpdGlvbnMgPSAoKT0+ewogICAgaWYgKCFzY3JvbGxEb3RzKSByZXR1cm4gW107CiAgICBpZiAoc2xpZGVyLmNsaWVudFdpZHRoIDw9IDApIHsKICAgICAgcmV0dXJuIHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggPyBzY3JvbGxEb3RQb3NpdGlvbnMgOiBbCiAgICAgICAgMAogICAgICBdOwogICAgfQogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHJldHVybiBbCiAgICAgIDAKICAgIF07CiAgICBjb25zdCB2aXNpYmxlSXRlbXMgPSBNYXRoLm1heChnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpLmxlbmd0aCwgMSk7CiAgICBjb25zdCBwb3NpdGlvbnMgPSBbCiAgICAgIDAKICAgIF07CiAgICBmb3IobGV0IGluZGV4ID0gdmlzaWJsZUl0ZW1zOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXggKz0gdmlzaWJsZUl0ZW1zKXsKICAgICAgcG9zaXRpb25zLnB1c2goZ2V0SXRlbVNjcm9sbExlZnQoaXRlbXMuaXRlbShpbmRleCkpKTsKICAgIH0KICAgIHBvc2l0aW9ucy5wdXNoKG1heFNjcm9sbExlZnQpOwogICAgcmV0dXJuIHBvc2l0aW9ucy5yZWR1Y2UoKGFjYywgcG9zaXRpb24pPT57CiAgICAgIGNvbnN0IHJvdW5kZWRQb3NpdGlvbiA9IE1hdGgucm91bmQoY2xhbXBTY3JvbGxMZWZ0KHBvc2l0aW9uKSk7CiAgICAgIGNvbnN0IGxhc3RQb3NpdGlvbiA9IGFjY1thY2MubGVuZ3RoIC0gMV07CiAgICAgIGlmIChsYXN0UG9zaXRpb24gPT09IHVuZGVmaW5lZCB8fCBNYXRoLmFicyhsYXN0UG9zaXRpb24gLSByb3VuZGVkUG9zaXRpb24pID4gMSkgewogICAgICAgIGFjYy5wdXNoKHJvdW5kZWRQb3NpdGlvbik7CiAgICAgIH0KICAgICAgcmV0dXJuIGFjYzsKICAgIH0sIFtdKTsKICB9OwogIGNvbnN0IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCA9ICgpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIHNjcm9sbERvdFBvc2l0aW9ucy5mb3JFYWNoKChwb3NpdGlvbiwgaW5kZXgpPT57CiAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnMoc2xpZGVyLnNjcm9sbExlZnQgLSBwb3NpdGlvbik7CiAgICAgIGlmIChkaXN0YW5jZSA8IHNtYWxsZXN0RGlzdGFuY2UpIHsKICAgICAgICBzbWFsbGVzdERpc3RhbmNlID0gZGlzdGFuY2U7CiAgICAgICAgYWN0aXZlSW5kZXggPSBpbmRleDsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gYWN0aXZlSW5kZXg7CiAgfTsKICBjb25zdCB1cGRhdGVTY3JvbGxEb3RzID0gKCk9PnsKICAgIGlmICghc2Nyb2xsRG90cyB8fCAhZG90cykgcmV0dXJuOwogICAgc2Nyb2xsRG90UG9zaXRpb25zID0gZ2V0U2Nyb2xsRG90UG9zaXRpb25zKCk7CiAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90LCBpbmRleCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIGlmIChpbmRleCA+PSBzY3JvbGxEb3RQb3NpdGlvbnMubGVuZ3RoKSB7CiAgICAgICAgZG90LmNsYXNzTGlzdC5hZGQoImhpZGRlbiIpOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgIGlmIChpbmRleCA9PT0gYWN0aXZlSW5kZXgpIHsKICAgICAgICBkb3Quc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgIH0KICAgIH0pOwogICAgaWYgKCFpbmZpbml0ZSkgewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxID8gcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKSA6IHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPj0gbWF4U2Nyb2xsTGVmdCAtIDEgPyBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpIDogbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgfQogIH07CiAgY29uc3QgZ29Ub1Njcm9sbERvdCA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGNvbnN0IHBvc2l0aW9uID0gc2Nyb2xsRG90UG9zaXRpb25zW2luZGV4XTsKICAgIGlmIChwb3NpdGlvbiA9PT0gdW5kZWZpbmVkKSByZXR1cm47CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBwb3NpdGlvbgogICAgfSk7CiAgfTsKICBjb25zdCBub3JtYWxpemVTY3JvbGxCb3VuZHMgPSAoKT0+ewogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA+IG1heFNjcm9sbExlZnQpIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBtYXhTY3JvbGxMZWZ0OwogICAgfSBlbHNlIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA8IDApIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSAwOwogICAgfQogIH07CiAgbGV0IHRvdWNoU3RhcnRYID0gMDsKICBsZXQgdG91Y2hTdGFydFkgPSAwOwogIGNvbnN0IGhhbmRsZVRvdWNoU3RhcnQgPSAoZXZlbnQpPT57CiAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07CiAgICBpZiAoIXRvdWNoKSByZXR1cm47CiAgICB0b3VjaFN0YXJ0WCA9IHRvdWNoLmNsaWVudFg7CiAgICB0b3VjaFN0YXJ0WSA9IHRvdWNoLmNsaWVudFk7CiAgfTsKICBjb25zdCBoYW5kbGVUb3VjaE1vdmUgPSAoZXZlbnQpPT57CiAgICBpZiAoIXNjcm9sbERvdHMpIHJldHVybjsKICAgIGNvbnN0IHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTsKICAgIGlmICghdG91Y2gpIHJldHVybjsKICAgIGNvbnN0IGRlbHRhWCA9IHRvdWNoLmNsaWVudFggLSB0b3VjaFN0YXJ0WDsKICAgIGNvbnN0IGRlbHRhWSA9IHRvdWNoLmNsaWVudFkgLSB0b3VjaFN0YXJ0WTsKICAgIGNvbnN0IGlzSG9yaXpvbnRhbEdlc3R1cmUgPSBNYXRoLmFicyhkZWx0YVgpID4gTWF0aC5hYnMoZGVsdGFZKTsKICAgIGlmICghaXNIb3Jpem9udGFsR2VzdHVyZSkgcmV0dXJuOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHsKICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcygpOwogICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdCBpc0F0U3RhcnQgPSBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxOwogICAgY29uc3QgaXNBdEVuZCA9IHNsaWRlci5zY3JvbGxMZWZ0ID49IG1heFNjcm9sbExlZnQgLSAxOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RTdGFydCA9IGlzQXRTdGFydCAmJiBkZWx0YVggPiAwOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RFbmQgPSBpc0F0RW5kICYmIGRlbHRhWCA8IDA7CiAgICBpZiAoaXNEcmFnZ2luZ1Bhc3RTdGFydCB8fCBpc0RyYWdnaW5nUGFzdEVuZCkgewogICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgbm9ybWFsaXplU2Nyb2xsQm91bmRzKCk7CiAgICB9CiAgfTsKICBjb25zdCBnb1RvSXRlbSA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBjb25zdCBpdGVtID0gc2xpZGVyLnF1ZXJ5U2VsZWN0b3IoYGxpW2RhdGEtcm9vdD0nJHtyb290SWR9J11bZGF0YS1zbGlkZXItaXRlbT0nJHtpbmRleH0nXWApID8/IHNsaWRlci5xdWVyeVNlbGVjdG9yKGBsaVtkYXRhLXNsaWRlci1pdGVtPScke2luZGV4fSddYCk7CiAgICBpZiAoaXRlbSkgewogICAgICBpZiAoIWlzSFRNTEVsZW1lbnQoaXRlbSkpIHsKICAgICAgICBjb25zb2xlLndhcm4oYEVsZW1lbnQgYXQgaW5kZXggJHtpbmRleH0gaXMgbm90IGFuIGh0bWwgZWxlbWVudC4gU2tpcHBpbmcgY2Fyb3VzZWxgKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgc2xpZGVyLnNjcm9sbFRvKHsKICAgICAgICB0b3A6IDAsCiAgICAgICAgYmVoYXZpb3I6IGJlaGF2aW9yLAogICAgICAgIGxlZnQ6IGl0ZW0ub2Zmc2V0TGVmdCAtIHJvb3Qub2Zmc2V0TGVmdAogICAgICB9KTsKICAgIH0KICB9OwogIGNvbnN0IGdvVG9JdGVtRG90ID0gKGluZGV4LCBiZWhhdmlvciA9IHNjcm9sbCk9PnsKICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgIGlmICghaXRlbSkgcmV0dXJuOwogICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSB7CiAgICAgIGNvbnNvbGUud2FybihgRWxlbWVudCBhdCBpbmRleCAke2luZGV4fSBpcyBub3QgYW4gaHRtbCBlbGVtZW50LiBTa2lwcGluZyBjYXJvdXNlbGApOwogICAgICByZXR1cm47CiAgICB9CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdAogICAgfSk7CiAgfTsKICBjb25zdCBnZXROZWFyZXN0SXRlbUluZGV4ID0gKCk9PnsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIGZvcihsZXQgaW5kZXggPSAwOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXgrKyl7CiAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSBjb250aW51ZTsKICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLmFicyhzbGlkZXIuc2Nyb2xsTGVmdCAtIChpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdCkpOwogICAgICBpZiAoZGlzdGFuY2UgPCBzbWFsbGVzdERpc3RhbmNlKSB7CiAgICAgICAgc21hbGxlc3REaXN0YW5jZSA9IGRpc3RhbmNlOwogICAgICAgIGFjdGl2ZUluZGV4ID0gaW5kZXg7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBhY3RpdmVJbmRleDsKICB9OwogIGNvbnN0IG9uQ2xpY2tQcmV2ID0gKCk9PnsKICAgIGlmIChzY3JvbGxEb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdFNjcm9sbERvdEluZGV4KCk7CiAgICAgIGFjdGl2ZUluZGV4ID09PSAwID8gaW5maW5pdGUgPyBnb1RvU2Nyb2xsRG90KHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggLSAxKSA6IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChpdGVtRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RJdGVtSW5kZXgoKTsKICAgICAgYWN0aXZlSW5kZXggPT09IDAgPyBpbmZpbml0ZSA/IGdvVG9JdGVtRG90KGl0ZW1zLmxlbmd0aCAtIDEpIDogbnVsbCA6IGdvVG9JdGVtRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIFdvdyEgaXRlbXMgcGVyIHBhZ2UgaXMgaG93IG1hbnkgZWxlbWVudHMgYXJlIGJlaW5nIGRpc3BsYXllZCBpbnNpZGUgdGhlIGNvbnRhaW5lciEhCiAgICBjb25zdCBpdGVtc1BlclBhZ2UgPSBpbmRpY2VzLmxlbmd0aDsKICAgIGNvbnN0IGlzU2hvd2luZ0ZpcnN0ID0gaW5kaWNlc1swXSA9PT0gMDsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdIC8gaXRlbXNQZXJQYWdlKTsKICAgIGlmIChvbmVCeW9uZSkgewogICAgICBpc1Nob3dpbmdGaXJzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oaXRlbXMubGVuZ3RoIC0gMSkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSAtIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nRmlyc3QgPyBpbmZpbml0ZUJlaGF2aW9yID8gaXRlbXMubGVuZ3RoIDogaXRlbXMubGVuZ3RoIC0gMSA6IChwYWdlSW5kZXggLSAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCBvbkNsaWNrTmV4dCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gc2Nyb2xsRG90UG9zaXRpb25zLmxlbmd0aCAtIDEgPyBpbmZpbml0ZSA/IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4KSA6IGdvVG9TY3JvbGxEb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGl0ZW1Eb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdEl0ZW1JbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gaXRlbXMubGVuZ3RoIC0gMSA/IGluZmluaXRlID8gZ29Ub0l0ZW1Eb3QoMCkgOiBudWxsIDogZ29Ub0l0ZW1Eb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgaW5kaWNlcyA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgICBpZiAoaW5kaWNlcy5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgLy8gV293ISBpdGVtcyBwZXIgcGFnZSBpcyBob3cgbWFueSBlbGVtZW50cyBhcmUgYmVpbmcgZGlzcGxheWVkIGluc2lkZSB0aGUgY29udGFpbmVyISEKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGluZGljZXMubGVuZ3RoOwogICAgY29uc3QgaXNTaG93aW5nTGFzdCA9IGluZGljZXNbaW5kaWNlcy5sZW5ndGggLSAxXSA9PT0gaXRlbXMubGVuZ3RoIC0gMTsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1swXSAvIGl0ZW1zUGVyUGFnZSk7CiAgICAvLyBnb1RvSXRlbShpc1Nob3dpbmdMYXN0ID8gMCA6IChpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICBpZiAob25lQnlvbmUpIHsKICAgICAgaXNTaG93aW5nTGFzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oMCkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSArIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nTGFzdCA/IGluZmluaXRlQmVoYXZpb3IgPyBpdGVtcy5sZW5ndGggKyAxIDogMCA6IChwYWdlSW5kZXggKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCB1cGRhdGVQYWdlRG90cyA9ICgpPT57CiAgICBpZiAoIXBhZ2VEb3RzIHx8ICFkb3RzKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IE1hdGgubWF4KGluZGljZXMubGVuZ3RoLCAxKTsKICAgIGNvbnN0IG1heFZpc2libGUgPSBNYXRoLm1heCguLi5pbmRpY2VzKTsKICAgIGNvbnN0IHBhZ2VEb3RJbmRleCA9IE1hdGguZmxvb3IobWF4VmlzaWJsZSAvIGl0ZW1zUGVyUGFnZSkgKiBpdGVtc1BlclBhZ2U7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCwgaSk9PnsKICAgICAgaWYgKGkgJSBpdGVtc1BlclBhZ2UgIT09IDApIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShwYWdlRG90SW5kZXgpOwogICAgaWYgKGFjdGl2ZURvdCkgewogICAgICBBcnJheS5mcm9tKGRvdHMpLmZpbHRlcigoX2RvdCwgaSk9PmkgPCBwYWdlRG90SW5kZXggJiYgaSAlIGl0ZW1zUGVyUGFnZSA9PT0gMCkuZm9yRWFjaCgoZG90KT0+ZG90LnNldEF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIiwgInRydWUiKSk7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IHVwZGF0ZUFjdGl2ZURvdCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICB1cGRhdGVTY3JvbGxEb3RzKCk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChwYWdlRG90cyB8fCAhZG90cykgewogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoaXRlbURvdHMpIHsKICAgICAgY29uc3QgYWN0aXZlSW5kZXggPSBnZXROZWFyZXN0SXRlbUluZGV4KCk7CiAgICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90KT0+ewogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtcGFpbnRlZCIpOwogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIH0pOwogICAgICBjb25zdCBhY3RpdmVEb3QgPSBkb3RzLml0ZW0oYWN0aXZlSW5kZXgpOwogICAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgICAgYWN0aXZlRG90LnNldEF0dHJpYnV0ZSgiZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gTWF0aC5taW4oLi4uaW5kaWNlcyk7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShhY3RpdmVJbmRleCk7CiAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGlmIChwYWdlRG90cykgewogICAgICB1cGRhdGVQYWdlRG90cygpOwogICAgfSBlbHNlIHsKICAgICAgdXBkYXRlQWN0aXZlRG90KCk7CiAgICB9CiAgICBlbGVtZW50cy5mb3JFYWNoKChpdGVtKT0+ewogICAgICBjb25zdCBpbmRleCA9IE51bWJlcihpdGVtLnRhcmdldC5nZXRBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKSkgfHwgMDsKICAgICAgaWYgKCFpbmZpbml0ZSAmJiAhc2Nyb2xsRG90cykgewogICAgICAgIGlmIChpbmRleCA9PT0gMCkgewogICAgICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcpIHsKICAgICAgICAgICAgcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGluZGV4ID09PSBpdGVtcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICBpZiAoaXRlbS5pc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocHJvZ3Jlc3MpIHsKICAgICAgICAgIGlmIChwcm9ncmVzcy5pZCA9PSAiMCIgJiYgaW5kZXggPT09IGl0ZW1zLmxlbmd0aCAtIDEpIHsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUuaGVpZ2h0ID0gYCR7MSAvIGl0ZW1zLmxlbmd0aCAqIDEwMH0lYDsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUud2lkdGggPSBgJHsxIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5pZCA9ICIxIjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByb2dyZXNzLnN0eWxlLmhlaWdodCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5zdHlsZS53aWR0aCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfSwgewogICAgdGhyZXNob2xkOiBUSFJFU0hPTEQsCiAgICByb290OiBzbGlkZXIsCiAgICByb290TWFyZ2luOiAiMTAwcHgiCiAgfSk7CiAgY29uc3QgZnVsbE9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGVsZW1lbnRzLmZvckVhY2goKGl0ZW0pPT57CiAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IHNsaWRlcj8ucXVlcnlTZWxlY3RvckFsbChgbGlgKTsKICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcgJiYgZWxlbWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT0gY3VycmVudEl0ZW1zWzFdKSB7CiAgICAgICAgICBzZXRUaW1lb3V0KCgpPT57CiAgICAgICAgICAgIGdvVG9JdGVtKGl0ZW1zLmxlbmd0aCAtIDEsICJpbnN0YW50Iik7CiAgICAgICAgICB9LCAyMDApOwogICAgICAgIH0KICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT09IGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pIHsKICAgICAgICAgIHNldFRpbWVvdXQoKCk9PnsKICAgICAgICAgICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICAgICAgICAgIH0sIDIwMCk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9LCB7CiAgICB0aHJlc2hvbGQ6IDAuNywKICAgIHJvb3Q6IHNsaWRlciwKICAgIHJvb3RNYXJnaW46ICIxMDBweCIKICB9KTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgY29uc3QgZmlyc3RJdGVtQ2xvbmUgPSBpdGVtc1swXS5jbG9uZU5vZGUodHJ1ZSk7CiAgICBjb25zdCBzZWNvbmRJdGVtQ2xvbmUgPSBpdGVtc1sxXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgcGVudWx0aW1hdGVJdGVtQ2xvbmUgPSBpdGVtc1tpdGVtcy5sZW5ndGggLSAyXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgbGFzdEl0ZW1DbG9uZSA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdLmNsb25lTm9kZSh0cnVlKTsKICAgIC8vIHdlIHJlbW92ZSB0aGVzZSBhdHRyaWJ1dGVzIGZyb20gdGhlIGNsb25lZCBpdGVtcyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gc2VuZCBldmVudHMgZm9yIHRoZSBjbG9uZWQgaXRlbXMKICAgIC8vIGJhbm5lciBjYXJvdXNlbCB1c2VzIGRhdGEtZXZlbnQgdG8gc2VuZCBldmVudHMgdG8gYW5hbHl0aWNzCiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBsYXN0SXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHBlbnVsdGltYXRlSXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuZmlyc3RFbGVtZW50Q2hpbGQ/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1ldmVudC10cmlnZ2VyIik7CiAgICBwZW51bHRpbWF0ZUl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgaXRlbXMubGVuZ3RoLnRvU3RyaW5nKCkpOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmU/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1zbGlkZXItaXRlbSIpOwogICAgZmlyc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgKGl0ZW1zLmxlbmd0aCArIDEpLnRvU3RyaW5nKCkpOwogICAgc2Vjb25kSXRlbUNsb25lPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKTsKICAgIHNsaWRlci5pbnNlcnRCZWZvcmUobGFzdEl0ZW1DbG9uZSwgaXRlbXNbMF0pOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmUgJiYgc2xpZGVyLmluc2VydEJlZm9yZShwZW51bHRpbWF0ZUl0ZW1DbG9uZSwgbGFzdEl0ZW1DbG9uZSk7CiAgICBzbGlkZXIuYXBwZW5kQ2hpbGQoZmlyc3RJdGVtQ2xvbmUpOwogICAgc2Vjb25kSXRlbUNsb25lICYmIHNsaWRlci5hcHBlbmRDaGlsZChzZWNvbmRJdGVtQ2xvbmUpOwogICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICB9CiAgY29uc3QgY3VycmVudEl0ZW1zID0gc2xpZGVyPy5xdWVyeVNlbGVjdG9yQWxsKGBsaWApOwogIGl0ZW1zLmZvckVhY2goKGl0ZW0pPT5vYnNlcnZlci5vYnNlcnZlKGl0ZW0pKTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgZnVsbE9ic2VydmVyLm9ic2VydmUoY3VycmVudEl0ZW1zWzFdKTsKICAgIGZ1bGxPYnNlcnZlci5vYnNlcnZlKGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pOwogIH0KICBpZiAocGFnZURvdHMpIHsKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCkubGVuZ3RoOwogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGNvbnN0IGRvdCA9IGRvdHM/Lml0ZW0oaXQpOwogICAgICBpZiAoIWRvdCkgY29udGludWU7CiAgICAgIGlmIChpdCAlIGl0ZW1zUGVyUGFnZSAhPT0gMCkgewogICAgICAgIGRvdC5jbGFzc0xpc3QuYWRkKCJoaWRkZW4iKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgICAgZG90LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKHNjcm9sbERvdHMpIHsKICAgIHVwZGF0ZVNjcm9sbERvdHMoKTsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5nb1RvU2Nyb2xsRG90KGl0KSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5pdGVtRG90cyA/IGdvVG9JdGVtRG90KGl0KSA6IGdvVG9JdGVtKGl0KSk7CiAgICB9CiAgfQogIHByZXY/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja1ByZXYpOwogIG5leHQ/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogIGlmIChzY3JvbGxEb3RzKSB7CiAgICBzbGlkZXIuc3R5bGUub3ZlcnNjcm9sbEJlaGF2aW9yWCA9ICJjb250YWluIjsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJzY3JvbGwiLCBub3JtYWxpemVTY3JvbGxCb3VuZHMsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2hzdGFydCIsIGhhbmRsZVRvdWNoU3RhcnQsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2htb3ZlIiwgaGFuZGxlVG91Y2hNb3ZlLCB7CiAgICAgIHBhc3NpdmU6IGZhbHNlCiAgICB9KTsKICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgfSBlbHNlIGlmIChwYWdlRG90cykgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZVBhZ2VEb3RzKTsKICB9IGVsc2UgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZUFjdGl2ZURvdCk7CiAgfQogIGNvbnN0IHRpbWVvdXQgPSBpbnRlcnZhbCAmJiBzZXRJbnRlcnZhbChvbkNsaWNrTmV4dCwgaW50ZXJ2YWwpOwogIGxldCBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXI7CiAgZnVuY3Rpb24gZW5hYmxlSG9yaXpvbnRhbFNjcm9sbCgpIHsKICAgIGlmICghc2xpZGVyKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGxldCBpc01vdXNlRG93biA9IGZhbHNlOwogICAgbGV0IHN0YXJ0WDsKICAgIGxldCBzY3JvbGxMZWZ0OwogICAgbGV0IHZlbG9jaXR5ID0gMDsKICAgIGxldCBtb21lbnR1bUZyYW1lOwogICAgY29uc3QgbW9tZW50dW1TY3JvbGwgPSAoKT0+ewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCArPSB2ZWxvY2l0eTsKICAgICAgdmVsb2NpdHkgKj0gMC45NTsKICAgICAgaWYgKE1hdGguYWJzKHZlbG9jaXR5KSA+IDAuMSkgewogICAgICAgIG1vbWVudHVtRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUobW9tZW50dW1TY3JvbGwpOwogICAgICB9CiAgICB9OwogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlZG93biIsIChlKT0+ewogICAgICBpc01vdXNlRG93biA9IHRydWU7CiAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAiZ3JhYmJpbmciOwogICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAiaW5pdGlhbCI7CiAgICAgIHN0YXJ0WCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgc2Nyb2xsTGVmdCA9IHNsaWRlci5zY3JvbGxMZWZ0OwogICAgICB2ZWxvY2l0eSA9IDA7CiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtRnJhbWUpOwogICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICB9KTsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWxlYXZlIiwgKCk9PnsKICAgICAgaWYgKGlzTW91c2VEb3duKSB7CiAgICAgICAgaXNNb3VzZURvd24gPSBmYWxzZTsKICAgICAgICBzbGlkZXIuZGF0YXNldFsiZHJhZ2dpbmciXSA9ICJmYWxzZSI7CiAgICAgICAgc2xpZGVyLnN0eWxlLmN1cnNvciA9ICJncmFiIjsKICAgICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAic21vb3RoIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2V1cCIsICgpPT57CiAgICAgIGlmIChpc01vdXNlRG93bikgewogICAgICAgIGlzTW91c2VEb3duID0gZmFsc2U7CiAgICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAiZmFsc2UiOwogICAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAibm9ybWFsIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2Vtb3ZlIiwgKGUpPT57CiAgICAgIGlmICghaXNNb3VzZURvd24pIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29uc3QgeCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgY29uc3Qgd2FsayA9ICh4IC0gc3RhcnRYKSAqIDAuNTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBzY3JvbGxMZWZ0IC0gd2FsazsKICAgICAgdmVsb2NpdHkgPSAtd2FsayAqIDAuMjsKICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAidHJ1ZSI7CiAgICB9KTsKICB9CiAgaWYgKGRlc2t0b3BEcmFnZ2FibGUpIHsKICAgIHNsaWRlci5kYXRhc2V0WyJkcmFnZ2FibGUiXSA9ICJ0cnVlIjsKICAgIGVuYWJsZUhvcml6b250YWxTY3JvbGwoKTsKICB9CiAgaWYgKHNjcm9sbERvdHMgJiYgIlJlc2l6ZU9ic2VydmVyIiBpbiBnbG9iYWxUaGlzKSB7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIodXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShzbGlkZXIpOwogIH0KICAvLyBVbnJlZ2lzdGVyIGNhbGxiYWNrcwogIHJldHVybiAoKT0+ewogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGRvdHM/Lml0ZW0oaXQpLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICB9CiAgICBwcmV2Py5yZW1vdmVFdmVudExpc3RlbmVyKCJjbGljayIsIG9uQ2xpY2tQcmV2KTsKICAgIG5leHQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogICAgaWYgKHNjcm9sbERvdHMpIHsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcyk7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVTY3JvbGxEb3RzKTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNoc3RhcnQiLCBoYW5kbGVUb3VjaFN0YXJ0KTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNobW92ZSIsIGhhbmRsZVRvdWNoTW92ZSk7CiAgICAgIGdsb2JhbFRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICB9IGVsc2UgaWYgKHBhZ2VEb3RzKSB7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVQYWdlRG90cyk7CiAgICB9IGVsc2UgewogICAgICBzbGlkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlQWN0aXZlRG90KTsKICAgIH0KICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTsKICAgIHNjcm9sbERvdHNSZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpOwogICAgY2xlYXJJbnRlcnZhbCh0aW1lb3V0KTsKICB9Owp9KSh7InJvb3RJZCI6Im5tUDAzMTI0MjMwMjUtc2xpZGVyLTEiLCJvbmVCeW9uZSI6dHJ1ZSwic2Nyb2xsRG90cyI6dHJ1ZSwiZGVza3RvcERyYWdnYWJsZSI6ZmFsc2V9KSkp | |
| js | data:text/javascript;base64,ZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZSgoKHsgcm9vdElkLCBzY3JvbGwgPSAic21vb3RoIiwgaW50ZXJ2YWwsIGluZmluaXRlLCBvbmVCeW9uZSwgaXRlbURvdHMsIHBhZ2VEb3RzLCBzY3JvbGxEb3RzLCBpc0Zyb21Ib29rID0gZmFsc2UsIGRlc2t0b3BEcmFnZ2FibGUgPSBmYWxzZSB9KT0+ewogIGNvbnN0IEFUVFJJQlVURVMgPSBpc0Zyb21Ib29rIC8vIHRoaXMgaXMgdXNlZCB0byBrZWVwIGNvbXBhdGliaWxpdHkgdG8gdGhlIG9sZCB3YXkgdG8gY3JlYXRlIGEgc2xpZGVyCiAgID8gewogICAgImRhdGEtc2xpZGVyIjogYFtkYXRhLXNsaWRlcl1bZGF0YS1yb290PSR7cm9vdElkfV1gLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiBgW2RhdGEtc2xpZGVyLWl0ZW1dW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6IGBbZGF0YS1zbGlkZT0icHJldiJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6IGBbZGF0YS1zbGlkZT0ibmV4dCJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLWRvdCI6IGBbZGF0YS1kb3RdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLXByb2dyZXNzIjogYFtkYXRhLXByb2dyZXNzXVtkYXRhLXJvb3Q9JHtyb290SWR9XWAKICB9IDogewogICAgImRhdGEtc2xpZGVyIjogIltkYXRhLXNsaWRlcl0iLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiAiW2RhdGEtc2xpZGVyLWl0ZW1dIiwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6ICdbZGF0YS1zbGlkZT0icHJldiJdJywKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6ICdbZGF0YS1zbGlkZT0ibmV4dCJdJywKICAgICJkYXRhLWRvdCI6ICJbZGF0YS1kb3RdIiwKICAgICJkYXRhLXByb2dyZXNzIjogIltkYXRhLXByb2dyZXNzXSIKICB9OwogIC8vIFBlcmNlbnRhZ2Ugb2YgdGhlIGl0ZW0gdGhhdCBoYXMgdG8gYmUgaW5zaWRlIHRoZSBjb250YWluZXIKICAvLyBmb3IgaXQgaXQgYmUgY29uc2lkZXJlZCBhcyBpbnNpZGUgdGhlIGNvbnRhaW5lcgogIGNvbnN0IFRIUkVTSE9MRCA9IDAuNzU7CiAgY29uc3QgVVNFX0lORklOSVRFX0JFSEFWSU9VUiA9IHRydWU7CiAgY29uc3QgaW50ZXJzZWN0aW9uWCA9IChlbGVtZW50LCBjb250YWluZXIpPT57CiAgICBjb25zdCBkZWx0YSA9IGNvbnRhaW5lci53aWR0aCAvIDFfMDAwOwogICAgaWYgKGVsZW1lbnQucmlnaHQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiAwLjA7CiAgICB9CiAgICBpZiAoZWxlbWVudC5sZWZ0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIDAuMDsKICAgIH0KICAgIGlmIChlbGVtZW50LmxlZnQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiBlbGVtZW50LnJpZ2h0IC0gY29udGFpbmVyLmxlZnQgKyBkZWx0YTsKICAgIH0KICAgIGlmIChlbGVtZW50LnJpZ2h0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIGNvbnRhaW5lci5yaWdodCAtIGVsZW1lbnQubGVmdCArIGRlbHRhOwogICAgfQogICAgcmV0dXJuIGVsZW1lbnQud2lkdGg7CiAgfTsKICAvLyBhcyBhbnkgYXJlIG9rIGluIHR5cGVndWFyZCBmdW5jdGlvbnMKICBjb25zdCBpc0hUTUxFbGVtZW50ID0gKHgpPT4vLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueQogICAgdHlwZW9mIHgub2Zmc2V0TGVmdCA9PT0gIm51bWJlciI7CiAgY29uc3Qgcm9vdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHJvb3RJZCkgPz8gZG9jdW1lbnQuY3VycmVudFNjcmlwdD8ucGFyZW50RWxlbWVudCA/PyBudWxsOwogIGNvbnN0IHNsaWRlciA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1zbGlkZXIiXSk7CiAgY29uc3QgaXRlbXMgPSBzbGlkZXI/LnF1ZXJ5U2VsZWN0b3JBbGwoQVRUUklCVVRFU1siZGF0YS1zbGlkZXItaXRlbSJdKTsKICBjb25zdCBwcmV2ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJwcmV2IiddKTsKICBjb25zdCBuZXh0ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJuZXh0IiddKTsKICBjb25zdCBkb3RzID0gcm9vdD8ucXVlcnlTZWxlY3RvckFsbChBVFRSSUJVVEVTWyJkYXRhLWRvdCJdKTsKICBjb25zdCBwcm9ncmVzcyA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1wcm9ncmVzcyJdKTsKICBpZiAoIXJvb3QgfHwgIXNsaWRlciB8fCAhaXRlbXMgfHwgaXRlbXMubGVuZ3RoID09PSAwKSB7CiAgICBjb25zb2xlLndhcm4oIk1pc3NpbmcgbmVjZXNzYXJ5IHNsaWRlciBhdHRyaWJ1dGVzLiBJdCB3aWxsIG5vdCB3b3JrIGFzIGludGVuZGVkLiBOZWNlc3NhcnkgZWxlbWVudHM6IiwgewogICAgICByb290LAogICAgICBzbGlkZXIsCiAgICAgIGl0ZW1zLAogICAgICByb290SWQKICAgIH0pOwogICAgcmV0dXJuOwogIH0KICBjb25zdCBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lciA9ICgpPT57CiAgICBjb25zdCBpbmRpY2VzID0gW107CiAgICBjb25zdCBzbGlkZXJSZWN0ID0gc2xpZGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaXRlbXMubGVuZ3RoOyBpbmRleCsrKXsKICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zLml0ZW0oaW5kZXgpOwogICAgICBjb25zdCByZWN0ID0gaXRlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgY29uc3QgcmF0aW8gPSBpbnRlcnNlY3Rpb25YKHJlY3QsIHNsaWRlclJlY3QpIC8gcmVjdC53aWR0aDsKICAgICAgaWYgKHJhdGlvID4gVEhSRVNIT0xEKSB7CiAgICAgICAgaW5kaWNlcy5wdXNoKGluZGV4KTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGluZGljZXM7CiAgfTsKICBjb25zdCBlbGVtZW50c0luc2lkZUNvbnRhaW5lciA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgY29uc3QgaW5maW5pdGVCZWhhdmlvciA9ICFzY3JvbGxEb3RzICYmIGluZmluaXRlICYmIGVsZW1lbnRzSW5zaWRlQ29udGFpbmVyLmxlbmd0aCA9PT0gMSAmJiBpdGVtcy5sZW5ndGggPiAxICYmIFVTRV9JTkZJTklURV9CRUhBVklPVVI7CiAgY29uc3QgZ2V0TWF4U2Nyb2xsTGVmdCA9ICgpPT5NYXRoLm1heCgwLCBzbGlkZXIuc2Nyb2xsV2lkdGggLSBzbGlkZXIuY2xpZW50V2lkdGgpOwogIGNvbnN0IGNsYW1wU2Nyb2xsTGVmdCA9IChsZWZ0KT0+TWF0aC5taW4oTWF0aC5tYXgobGVmdCwgMCksIGdldE1heFNjcm9sbExlZnQoKSk7CiAgY29uc3QgZ2V0SXRlbVNjcm9sbExlZnQgPSAoaXRlbSk9PnsKICAgIGlmICghaXNIVE1MRWxlbWVudChpdGVtKSkgcmV0dXJuIDA7CiAgICByZXR1cm4gY2xhbXBTY3JvbGxMZWZ0KGl0ZW0ub2Zmc2V0TGVmdCAtIHNsaWRlci5vZmZzZXRMZWZ0KTsKICB9OwogIGxldCBzY3JvbGxEb3RQb3NpdGlvbnMgPSBbXTsKICBjb25zdCBnZXRTY3JvbGxEb3RQb3NpdGlvbnMgPSAoKT0+ewogICAgaWYgKCFzY3JvbGxEb3RzKSByZXR1cm4gW107CiAgICBpZiAoc2xpZGVyLmNsaWVudFdpZHRoIDw9IDApIHsKICAgICAgcmV0dXJuIHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggPyBzY3JvbGxEb3RQb3NpdGlvbnMgOiBbCiAgICAgICAgMAogICAgICBdOwogICAgfQogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHJldHVybiBbCiAgICAgIDAKICAgIF07CiAgICBjb25zdCB2aXNpYmxlSXRlbXMgPSBNYXRoLm1heChnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpLmxlbmd0aCwgMSk7CiAgICBjb25zdCBwb3NpdGlvbnMgPSBbCiAgICAgIDAKICAgIF07CiAgICBmb3IobGV0IGluZGV4ID0gdmlzaWJsZUl0ZW1zOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXggKz0gdmlzaWJsZUl0ZW1zKXsKICAgICAgcG9zaXRpb25zLnB1c2goZ2V0SXRlbVNjcm9sbExlZnQoaXRlbXMuaXRlbShpbmRleCkpKTsKICAgIH0KICAgIHBvc2l0aW9ucy5wdXNoKG1heFNjcm9sbExlZnQpOwogICAgcmV0dXJuIHBvc2l0aW9ucy5yZWR1Y2UoKGFjYywgcG9zaXRpb24pPT57CiAgICAgIGNvbnN0IHJvdW5kZWRQb3NpdGlvbiA9IE1hdGgucm91bmQoY2xhbXBTY3JvbGxMZWZ0KHBvc2l0aW9uKSk7CiAgICAgIGNvbnN0IGxhc3RQb3NpdGlvbiA9IGFjY1thY2MubGVuZ3RoIC0gMV07CiAgICAgIGlmIChsYXN0UG9zaXRpb24gPT09IHVuZGVmaW5lZCB8fCBNYXRoLmFicyhsYXN0UG9zaXRpb24gLSByb3VuZGVkUG9zaXRpb24pID4gMSkgewogICAgICAgIGFjYy5wdXNoKHJvdW5kZWRQb3NpdGlvbik7CiAgICAgIH0KICAgICAgcmV0dXJuIGFjYzsKICAgIH0sIFtdKTsKICB9OwogIGNvbnN0IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCA9ICgpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIHNjcm9sbERvdFBvc2l0aW9ucy5mb3JFYWNoKChwb3NpdGlvbiwgaW5kZXgpPT57CiAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnMoc2xpZGVyLnNjcm9sbExlZnQgLSBwb3NpdGlvbik7CiAgICAgIGlmIChkaXN0YW5jZSA8IHNtYWxsZXN0RGlzdGFuY2UpIHsKICAgICAgICBzbWFsbGVzdERpc3RhbmNlID0gZGlzdGFuY2U7CiAgICAgICAgYWN0aXZlSW5kZXggPSBpbmRleDsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gYWN0aXZlSW5kZXg7CiAgfTsKICBjb25zdCB1cGRhdGVTY3JvbGxEb3RzID0gKCk9PnsKICAgIGlmICghc2Nyb2xsRG90cyB8fCAhZG90cykgcmV0dXJuOwogICAgc2Nyb2xsRG90UG9zaXRpb25zID0gZ2V0U2Nyb2xsRG90UG9zaXRpb25zKCk7CiAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90LCBpbmRleCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIGlmIChpbmRleCA+PSBzY3JvbGxEb3RQb3NpdGlvbnMubGVuZ3RoKSB7CiAgICAgICAgZG90LmNsYXNzTGlzdC5hZGQoImhpZGRlbiIpOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgIGlmIChpbmRleCA9PT0gYWN0aXZlSW5kZXgpIHsKICAgICAgICBkb3Quc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgIH0KICAgIH0pOwogICAgaWYgKCFpbmZpbml0ZSkgewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxID8gcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKSA6IHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPj0gbWF4U2Nyb2xsTGVmdCAtIDEgPyBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpIDogbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgfQogIH07CiAgY29uc3QgZ29Ub1Njcm9sbERvdCA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGNvbnN0IHBvc2l0aW9uID0gc2Nyb2xsRG90UG9zaXRpb25zW2luZGV4XTsKICAgIGlmIChwb3NpdGlvbiA9PT0gdW5kZWZpbmVkKSByZXR1cm47CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBwb3NpdGlvbgogICAgfSk7CiAgfTsKICBjb25zdCBub3JtYWxpemVTY3JvbGxCb3VuZHMgPSAoKT0+ewogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA+IG1heFNjcm9sbExlZnQpIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBtYXhTY3JvbGxMZWZ0OwogICAgfSBlbHNlIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA8IDApIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSAwOwogICAgfQogIH07CiAgbGV0IHRvdWNoU3RhcnRYID0gMDsKICBsZXQgdG91Y2hTdGFydFkgPSAwOwogIGNvbnN0IGhhbmRsZVRvdWNoU3RhcnQgPSAoZXZlbnQpPT57CiAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07CiAgICBpZiAoIXRvdWNoKSByZXR1cm47CiAgICB0b3VjaFN0YXJ0WCA9IHRvdWNoLmNsaWVudFg7CiAgICB0b3VjaFN0YXJ0WSA9IHRvdWNoLmNsaWVudFk7CiAgfTsKICBjb25zdCBoYW5kbGVUb3VjaE1vdmUgPSAoZXZlbnQpPT57CiAgICBpZiAoIXNjcm9sbERvdHMpIHJldHVybjsKICAgIGNvbnN0IHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTsKICAgIGlmICghdG91Y2gpIHJldHVybjsKICAgIGNvbnN0IGRlbHRhWCA9IHRvdWNoLmNsaWVudFggLSB0b3VjaFN0YXJ0WDsKICAgIGNvbnN0IGRlbHRhWSA9IHRvdWNoLmNsaWVudFkgLSB0b3VjaFN0YXJ0WTsKICAgIGNvbnN0IGlzSG9yaXpvbnRhbEdlc3R1cmUgPSBNYXRoLmFicyhkZWx0YVgpID4gTWF0aC5hYnMoZGVsdGFZKTsKICAgIGlmICghaXNIb3Jpem9udGFsR2VzdHVyZSkgcmV0dXJuOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHsKICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcygpOwogICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdCBpc0F0U3RhcnQgPSBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxOwogICAgY29uc3QgaXNBdEVuZCA9IHNsaWRlci5zY3JvbGxMZWZ0ID49IG1heFNjcm9sbExlZnQgLSAxOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RTdGFydCA9IGlzQXRTdGFydCAmJiBkZWx0YVggPiAwOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RFbmQgPSBpc0F0RW5kICYmIGRlbHRhWCA8IDA7CiAgICBpZiAoaXNEcmFnZ2luZ1Bhc3RTdGFydCB8fCBpc0RyYWdnaW5nUGFzdEVuZCkgewogICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgbm9ybWFsaXplU2Nyb2xsQm91bmRzKCk7CiAgICB9CiAgfTsKICBjb25zdCBnb1RvSXRlbSA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBjb25zdCBpdGVtID0gc2xpZGVyLnF1ZXJ5U2VsZWN0b3IoYGxpW2RhdGEtcm9vdD0nJHtyb290SWR9J11bZGF0YS1zbGlkZXItaXRlbT0nJHtpbmRleH0nXWApID8/IHNsaWRlci5xdWVyeVNlbGVjdG9yKGBsaVtkYXRhLXNsaWRlci1pdGVtPScke2luZGV4fSddYCk7CiAgICBpZiAoaXRlbSkgewogICAgICBpZiAoIWlzSFRNTEVsZW1lbnQoaXRlbSkpIHsKICAgICAgICBjb25zb2xlLndhcm4oYEVsZW1lbnQgYXQgaW5kZXggJHtpbmRleH0gaXMgbm90IGFuIGh0bWwgZWxlbWVudC4gU2tpcHBpbmcgY2Fyb3VzZWxgKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgc2xpZGVyLnNjcm9sbFRvKHsKICAgICAgICB0b3A6IDAsCiAgICAgICAgYmVoYXZpb3I6IGJlaGF2aW9yLAogICAgICAgIGxlZnQ6IGl0ZW0ub2Zmc2V0TGVmdCAtIHJvb3Qub2Zmc2V0TGVmdAogICAgICB9KTsKICAgIH0KICB9OwogIGNvbnN0IGdvVG9JdGVtRG90ID0gKGluZGV4LCBiZWhhdmlvciA9IHNjcm9sbCk9PnsKICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgIGlmICghaXRlbSkgcmV0dXJuOwogICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSB7CiAgICAgIGNvbnNvbGUud2FybihgRWxlbWVudCBhdCBpbmRleCAke2luZGV4fSBpcyBub3QgYW4gaHRtbCBlbGVtZW50LiBTa2lwcGluZyBjYXJvdXNlbGApOwogICAgICByZXR1cm47CiAgICB9CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdAogICAgfSk7CiAgfTsKICBjb25zdCBnZXROZWFyZXN0SXRlbUluZGV4ID0gKCk9PnsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIGZvcihsZXQgaW5kZXggPSAwOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXgrKyl7CiAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSBjb250aW51ZTsKICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLmFicyhzbGlkZXIuc2Nyb2xsTGVmdCAtIChpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdCkpOwogICAgICBpZiAoZGlzdGFuY2UgPCBzbWFsbGVzdERpc3RhbmNlKSB7CiAgICAgICAgc21hbGxlc3REaXN0YW5jZSA9IGRpc3RhbmNlOwogICAgICAgIGFjdGl2ZUluZGV4ID0gaW5kZXg7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBhY3RpdmVJbmRleDsKICB9OwogIGNvbnN0IG9uQ2xpY2tQcmV2ID0gKCk9PnsKICAgIGlmIChzY3JvbGxEb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdFNjcm9sbERvdEluZGV4KCk7CiAgICAgIGFjdGl2ZUluZGV4ID09PSAwID8gaW5maW5pdGUgPyBnb1RvU2Nyb2xsRG90KHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggLSAxKSA6IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChpdGVtRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RJdGVtSW5kZXgoKTsKICAgICAgYWN0aXZlSW5kZXggPT09IDAgPyBpbmZpbml0ZSA/IGdvVG9JdGVtRG90KGl0ZW1zLmxlbmd0aCAtIDEpIDogbnVsbCA6IGdvVG9JdGVtRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIFdvdyEgaXRlbXMgcGVyIHBhZ2UgaXMgaG93IG1hbnkgZWxlbWVudHMgYXJlIGJlaW5nIGRpc3BsYXllZCBpbnNpZGUgdGhlIGNvbnRhaW5lciEhCiAgICBjb25zdCBpdGVtc1BlclBhZ2UgPSBpbmRpY2VzLmxlbmd0aDsKICAgIGNvbnN0IGlzU2hvd2luZ0ZpcnN0ID0gaW5kaWNlc1swXSA9PT0gMDsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdIC8gaXRlbXNQZXJQYWdlKTsKICAgIGlmIChvbmVCeW9uZSkgewogICAgICBpc1Nob3dpbmdGaXJzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oaXRlbXMubGVuZ3RoIC0gMSkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSAtIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nRmlyc3QgPyBpbmZpbml0ZUJlaGF2aW9yID8gaXRlbXMubGVuZ3RoIDogaXRlbXMubGVuZ3RoIC0gMSA6IChwYWdlSW5kZXggLSAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCBvbkNsaWNrTmV4dCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gc2Nyb2xsRG90UG9zaXRpb25zLmxlbmd0aCAtIDEgPyBpbmZpbml0ZSA/IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4KSA6IGdvVG9TY3JvbGxEb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGl0ZW1Eb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdEl0ZW1JbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gaXRlbXMubGVuZ3RoIC0gMSA/IGluZmluaXRlID8gZ29Ub0l0ZW1Eb3QoMCkgOiBudWxsIDogZ29Ub0l0ZW1Eb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgaW5kaWNlcyA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgICBpZiAoaW5kaWNlcy5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgLy8gV293ISBpdGVtcyBwZXIgcGFnZSBpcyBob3cgbWFueSBlbGVtZW50cyBhcmUgYmVpbmcgZGlzcGxheWVkIGluc2lkZSB0aGUgY29udGFpbmVyISEKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGluZGljZXMubGVuZ3RoOwogICAgY29uc3QgaXNTaG93aW5nTGFzdCA9IGluZGljZXNbaW5kaWNlcy5sZW5ndGggLSAxXSA9PT0gaXRlbXMubGVuZ3RoIC0gMTsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1swXSAvIGl0ZW1zUGVyUGFnZSk7CiAgICAvLyBnb1RvSXRlbShpc1Nob3dpbmdMYXN0ID8gMCA6IChpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICBpZiAob25lQnlvbmUpIHsKICAgICAgaXNTaG93aW5nTGFzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oMCkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSArIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nTGFzdCA/IGluZmluaXRlQmVoYXZpb3IgPyBpdGVtcy5sZW5ndGggKyAxIDogMCA6IChwYWdlSW5kZXggKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCB1cGRhdGVQYWdlRG90cyA9ICgpPT57CiAgICBpZiAoIXBhZ2VEb3RzIHx8ICFkb3RzKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IE1hdGgubWF4KGluZGljZXMubGVuZ3RoLCAxKTsKICAgIGNvbnN0IG1heFZpc2libGUgPSBNYXRoLm1heCguLi5pbmRpY2VzKTsKICAgIGNvbnN0IHBhZ2VEb3RJbmRleCA9IE1hdGguZmxvb3IobWF4VmlzaWJsZSAvIGl0ZW1zUGVyUGFnZSkgKiBpdGVtc1BlclBhZ2U7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCwgaSk9PnsKICAgICAgaWYgKGkgJSBpdGVtc1BlclBhZ2UgIT09IDApIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShwYWdlRG90SW5kZXgpOwogICAgaWYgKGFjdGl2ZURvdCkgewogICAgICBBcnJheS5mcm9tKGRvdHMpLmZpbHRlcigoX2RvdCwgaSk9PmkgPCBwYWdlRG90SW5kZXggJiYgaSAlIGl0ZW1zUGVyUGFnZSA9PT0gMCkuZm9yRWFjaCgoZG90KT0+ZG90LnNldEF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIiwgInRydWUiKSk7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IHVwZGF0ZUFjdGl2ZURvdCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICB1cGRhdGVTY3JvbGxEb3RzKCk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChwYWdlRG90cyB8fCAhZG90cykgewogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoaXRlbURvdHMpIHsKICAgICAgY29uc3QgYWN0aXZlSW5kZXggPSBnZXROZWFyZXN0SXRlbUluZGV4KCk7CiAgICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90KT0+ewogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtcGFpbnRlZCIpOwogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIH0pOwogICAgICBjb25zdCBhY3RpdmVEb3QgPSBkb3RzLml0ZW0oYWN0aXZlSW5kZXgpOwogICAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgICAgYWN0aXZlRG90LnNldEF0dHJpYnV0ZSgiZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gTWF0aC5taW4oLi4uaW5kaWNlcyk7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShhY3RpdmVJbmRleCk7CiAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGlmIChwYWdlRG90cykgewogICAgICB1cGRhdGVQYWdlRG90cygpOwogICAgfSBlbHNlIHsKICAgICAgdXBkYXRlQWN0aXZlRG90KCk7CiAgICB9CiAgICBlbGVtZW50cy5mb3JFYWNoKChpdGVtKT0+ewogICAgICBjb25zdCBpbmRleCA9IE51bWJlcihpdGVtLnRhcmdldC5nZXRBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKSkgfHwgMDsKICAgICAgaWYgKCFpbmZpbml0ZSAmJiAhc2Nyb2xsRG90cykgewogICAgICAgIGlmIChpbmRleCA9PT0gMCkgewogICAgICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcpIHsKICAgICAgICAgICAgcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGluZGV4ID09PSBpdGVtcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICBpZiAoaXRlbS5pc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocHJvZ3Jlc3MpIHsKICAgICAgICAgIGlmIChwcm9ncmVzcy5pZCA9PSAiMCIgJiYgaW5kZXggPT09IGl0ZW1zLmxlbmd0aCAtIDEpIHsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUuaGVpZ2h0ID0gYCR7MSAvIGl0ZW1zLmxlbmd0aCAqIDEwMH0lYDsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUud2lkdGggPSBgJHsxIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5pZCA9ICIxIjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByb2dyZXNzLnN0eWxlLmhlaWdodCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5zdHlsZS53aWR0aCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfSwgewogICAgdGhyZXNob2xkOiBUSFJFU0hPTEQsCiAgICByb290OiBzbGlkZXIsCiAgICByb290TWFyZ2luOiAiMTAwcHgiCiAgfSk7CiAgY29uc3QgZnVsbE9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGVsZW1lbnRzLmZvckVhY2goKGl0ZW0pPT57CiAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IHNsaWRlcj8ucXVlcnlTZWxlY3RvckFsbChgbGlgKTsKICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcgJiYgZWxlbWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT0gY3VycmVudEl0ZW1zWzFdKSB7CiAgICAgICAgICBzZXRUaW1lb3V0KCgpPT57CiAgICAgICAgICAgIGdvVG9JdGVtKGl0ZW1zLmxlbmd0aCAtIDEsICJpbnN0YW50Iik7CiAgICAgICAgICB9LCAyMDApOwogICAgICAgIH0KICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT09IGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pIHsKICAgICAgICAgIHNldFRpbWVvdXQoKCk9PnsKICAgICAgICAgICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICAgICAgICAgIH0sIDIwMCk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9LCB7CiAgICB0aHJlc2hvbGQ6IDAuNywKICAgIHJvb3Q6IHNsaWRlciwKICAgIHJvb3RNYXJnaW46ICIxMDBweCIKICB9KTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgY29uc3QgZmlyc3RJdGVtQ2xvbmUgPSBpdGVtc1swXS5jbG9uZU5vZGUodHJ1ZSk7CiAgICBjb25zdCBzZWNvbmRJdGVtQ2xvbmUgPSBpdGVtc1sxXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgcGVudWx0aW1hdGVJdGVtQ2xvbmUgPSBpdGVtc1tpdGVtcy5sZW5ndGggLSAyXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgbGFzdEl0ZW1DbG9uZSA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdLmNsb25lTm9kZSh0cnVlKTsKICAgIC8vIHdlIHJlbW92ZSB0aGVzZSBhdHRyaWJ1dGVzIGZyb20gdGhlIGNsb25lZCBpdGVtcyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gc2VuZCBldmVudHMgZm9yIHRoZSBjbG9uZWQgaXRlbXMKICAgIC8vIGJhbm5lciBjYXJvdXNlbCB1c2VzIGRhdGEtZXZlbnQgdG8gc2VuZCBldmVudHMgdG8gYW5hbHl0aWNzCiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBsYXN0SXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHBlbnVsdGltYXRlSXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuZmlyc3RFbGVtZW50Q2hpbGQ/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1ldmVudC10cmlnZ2VyIik7CiAgICBwZW51bHRpbWF0ZUl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgaXRlbXMubGVuZ3RoLnRvU3RyaW5nKCkpOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmU/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1zbGlkZXItaXRlbSIpOwogICAgZmlyc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgKGl0ZW1zLmxlbmd0aCArIDEpLnRvU3RyaW5nKCkpOwogICAgc2Vjb25kSXRlbUNsb25lPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKTsKICAgIHNsaWRlci5pbnNlcnRCZWZvcmUobGFzdEl0ZW1DbG9uZSwgaXRlbXNbMF0pOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmUgJiYgc2xpZGVyLmluc2VydEJlZm9yZShwZW51bHRpbWF0ZUl0ZW1DbG9uZSwgbGFzdEl0ZW1DbG9uZSk7CiAgICBzbGlkZXIuYXBwZW5kQ2hpbGQoZmlyc3RJdGVtQ2xvbmUpOwogICAgc2Vjb25kSXRlbUNsb25lICYmIHNsaWRlci5hcHBlbmRDaGlsZChzZWNvbmRJdGVtQ2xvbmUpOwogICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICB9CiAgY29uc3QgY3VycmVudEl0ZW1zID0gc2xpZGVyPy5xdWVyeVNlbGVjdG9yQWxsKGBsaWApOwogIGl0ZW1zLmZvckVhY2goKGl0ZW0pPT5vYnNlcnZlci5vYnNlcnZlKGl0ZW0pKTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgZnVsbE9ic2VydmVyLm9ic2VydmUoY3VycmVudEl0ZW1zWzFdKTsKICAgIGZ1bGxPYnNlcnZlci5vYnNlcnZlKGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pOwogIH0KICBpZiAocGFnZURvdHMpIHsKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCkubGVuZ3RoOwogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGNvbnN0IGRvdCA9IGRvdHM/Lml0ZW0oaXQpOwogICAgICBpZiAoIWRvdCkgY29udGludWU7CiAgICAgIGlmIChpdCAlIGl0ZW1zUGVyUGFnZSAhPT0gMCkgewogICAgICAgIGRvdC5jbGFzc0xpc3QuYWRkKCJoaWRkZW4iKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgICAgZG90LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKHNjcm9sbERvdHMpIHsKICAgIHVwZGF0ZVNjcm9sbERvdHMoKTsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5nb1RvU2Nyb2xsRG90KGl0KSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5pdGVtRG90cyA/IGdvVG9JdGVtRG90KGl0KSA6IGdvVG9JdGVtKGl0KSk7CiAgICB9CiAgfQogIHByZXY/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja1ByZXYpOwogIG5leHQ/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogIGlmIChzY3JvbGxEb3RzKSB7CiAgICBzbGlkZXIuc3R5bGUub3ZlcnNjcm9sbEJlaGF2aW9yWCA9ICJjb250YWluIjsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJzY3JvbGwiLCBub3JtYWxpemVTY3JvbGxCb3VuZHMsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2hzdGFydCIsIGhhbmRsZVRvdWNoU3RhcnQsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2htb3ZlIiwgaGFuZGxlVG91Y2hNb3ZlLCB7CiAgICAgIHBhc3NpdmU6IGZhbHNlCiAgICB9KTsKICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgfSBlbHNlIGlmIChwYWdlRG90cykgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZVBhZ2VEb3RzKTsKICB9IGVsc2UgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZUFjdGl2ZURvdCk7CiAgfQogIGNvbnN0IHRpbWVvdXQgPSBpbnRlcnZhbCAmJiBzZXRJbnRlcnZhbChvbkNsaWNrTmV4dCwgaW50ZXJ2YWwpOwogIGxldCBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXI7CiAgZnVuY3Rpb24gZW5hYmxlSG9yaXpvbnRhbFNjcm9sbCgpIHsKICAgIGlmICghc2xpZGVyKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGxldCBpc01vdXNlRG93biA9IGZhbHNlOwogICAgbGV0IHN0YXJ0WDsKICAgIGxldCBzY3JvbGxMZWZ0OwogICAgbGV0IHZlbG9jaXR5ID0gMDsKICAgIGxldCBtb21lbnR1bUZyYW1lOwogICAgY29uc3QgbW9tZW50dW1TY3JvbGwgPSAoKT0+ewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCArPSB2ZWxvY2l0eTsKICAgICAgdmVsb2NpdHkgKj0gMC45NTsKICAgICAgaWYgKE1hdGguYWJzKHZlbG9jaXR5KSA+IDAuMSkgewogICAgICAgIG1vbWVudHVtRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUobW9tZW50dW1TY3JvbGwpOwogICAgICB9CiAgICB9OwogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlZG93biIsIChlKT0+ewogICAgICBpc01vdXNlRG93biA9IHRydWU7CiAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAiZ3JhYmJpbmciOwogICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAiaW5pdGlhbCI7CiAgICAgIHN0YXJ0WCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgc2Nyb2xsTGVmdCA9IHNsaWRlci5zY3JvbGxMZWZ0OwogICAgICB2ZWxvY2l0eSA9IDA7CiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtRnJhbWUpOwogICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICB9KTsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWxlYXZlIiwgKCk9PnsKICAgICAgaWYgKGlzTW91c2VEb3duKSB7CiAgICAgICAgaXNNb3VzZURvd24gPSBmYWxzZTsKICAgICAgICBzbGlkZXIuZGF0YXNldFsiZHJhZ2dpbmciXSA9ICJmYWxzZSI7CiAgICAgICAgc2xpZGVyLnN0eWxlLmN1cnNvciA9ICJncmFiIjsKICAgICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAic21vb3RoIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2V1cCIsICgpPT57CiAgICAgIGlmIChpc01vdXNlRG93bikgewogICAgICAgIGlzTW91c2VEb3duID0gZmFsc2U7CiAgICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAiZmFsc2UiOwogICAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAibm9ybWFsIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2Vtb3ZlIiwgKGUpPT57CiAgICAgIGlmICghaXNNb3VzZURvd24pIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29uc3QgeCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgY29uc3Qgd2FsayA9ICh4IC0gc3RhcnRYKSAqIDAuNTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBzY3JvbGxMZWZ0IC0gd2FsazsKICAgICAgdmVsb2NpdHkgPSAtd2FsayAqIDAuMjsKICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAidHJ1ZSI7CiAgICB9KTsKICB9CiAgaWYgKGRlc2t0b3BEcmFnZ2FibGUpIHsKICAgIHNsaWRlci5kYXRhc2V0WyJkcmFnZ2FibGUiXSA9ICJ0cnVlIjsKICAgIGVuYWJsZUhvcml6b250YWxTY3JvbGwoKTsKICB9CiAgaWYgKHNjcm9sbERvdHMgJiYgIlJlc2l6ZU9ic2VydmVyIiBpbiBnbG9iYWxUaGlzKSB7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIodXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShzbGlkZXIpOwogIH0KICAvLyBVbnJlZ2lzdGVyIGNhbGxiYWNrcwogIHJldHVybiAoKT0+ewogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGRvdHM/Lml0ZW0oaXQpLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICB9CiAgICBwcmV2Py5yZW1vdmVFdmVudExpc3RlbmVyKCJjbGljayIsIG9uQ2xpY2tQcmV2KTsKICAgIG5leHQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogICAgaWYgKHNjcm9sbERvdHMpIHsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcyk7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVTY3JvbGxEb3RzKTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNoc3RhcnQiLCBoYW5kbGVUb3VjaFN0YXJ0KTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNobW92ZSIsIGhhbmRsZVRvdWNoTW92ZSk7CiAgICAgIGdsb2JhbFRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICB9IGVsc2UgaWYgKHBhZ2VEb3RzKSB7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVQYWdlRG90cyk7CiAgICB9IGVsc2UgewogICAgICBzbGlkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlQWN0aXZlRG90KTsKICAgIH0KICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTsKICAgIHNjcm9sbERvdHNSZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpOwogICAgY2xlYXJJbnRlcnZhbCh0aW1lb3V0KTsKICB9Owp9KSh7InJvb3RJZCI6Im5tUDAzMTI0MjMwMjUtc2xpZGVyLTIiLCJvbmVCeW9uZSI6dHJ1ZSwic2Nyb2xsRG90cyI6dHJ1ZSwiZGVza3RvcERyYWdnYWJsZSI6ZmFsc2V9KSkp | |
| js | data:text/javascript;base64,ZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZSgoKHsgcm9vdElkLCBzY3JvbGwgPSAic21vb3RoIiwgaW50ZXJ2YWwsIGluZmluaXRlLCBvbmVCeW9uZSwgaXRlbURvdHMsIHBhZ2VEb3RzLCBzY3JvbGxEb3RzLCBpc0Zyb21Ib29rID0gZmFsc2UsIGRlc2t0b3BEcmFnZ2FibGUgPSBmYWxzZSB9KT0+ewogIGNvbnN0IEFUVFJJQlVURVMgPSBpc0Zyb21Ib29rIC8vIHRoaXMgaXMgdXNlZCB0byBrZWVwIGNvbXBhdGliaWxpdHkgdG8gdGhlIG9sZCB3YXkgdG8gY3JlYXRlIGEgc2xpZGVyCiAgID8gewogICAgImRhdGEtc2xpZGVyIjogYFtkYXRhLXNsaWRlcl1bZGF0YS1yb290PSR7cm9vdElkfV1gLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiBgW2RhdGEtc2xpZGVyLWl0ZW1dW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6IGBbZGF0YS1zbGlkZT0icHJldiJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6IGBbZGF0YS1zbGlkZT0ibmV4dCJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLWRvdCI6IGBbZGF0YS1kb3RdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLXByb2dyZXNzIjogYFtkYXRhLXByb2dyZXNzXVtkYXRhLXJvb3Q9JHtyb290SWR9XWAKICB9IDogewogICAgImRhdGEtc2xpZGVyIjogIltkYXRhLXNsaWRlcl0iLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiAiW2RhdGEtc2xpZGVyLWl0ZW1dIiwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6ICdbZGF0YS1zbGlkZT0icHJldiJdJywKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6ICdbZGF0YS1zbGlkZT0ibmV4dCJdJywKICAgICJkYXRhLWRvdCI6ICJbZGF0YS1kb3RdIiwKICAgICJkYXRhLXByb2dyZXNzIjogIltkYXRhLXByb2dyZXNzXSIKICB9OwogIC8vIFBlcmNlbnRhZ2Ugb2YgdGhlIGl0ZW0gdGhhdCBoYXMgdG8gYmUgaW5zaWRlIHRoZSBjb250YWluZXIKICAvLyBmb3IgaXQgaXQgYmUgY29uc2lkZXJlZCBhcyBpbnNpZGUgdGhlIGNvbnRhaW5lcgogIGNvbnN0IFRIUkVTSE9MRCA9IDAuNzU7CiAgY29uc3QgVVNFX0lORklOSVRFX0JFSEFWSU9VUiA9IHRydWU7CiAgY29uc3QgaW50ZXJzZWN0aW9uWCA9IChlbGVtZW50LCBjb250YWluZXIpPT57CiAgICBjb25zdCBkZWx0YSA9IGNvbnRhaW5lci53aWR0aCAvIDFfMDAwOwogICAgaWYgKGVsZW1lbnQucmlnaHQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiAwLjA7CiAgICB9CiAgICBpZiAoZWxlbWVudC5sZWZ0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIDAuMDsKICAgIH0KICAgIGlmIChlbGVtZW50LmxlZnQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiBlbGVtZW50LnJpZ2h0IC0gY29udGFpbmVyLmxlZnQgKyBkZWx0YTsKICAgIH0KICAgIGlmIChlbGVtZW50LnJpZ2h0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIGNvbnRhaW5lci5yaWdodCAtIGVsZW1lbnQubGVmdCArIGRlbHRhOwogICAgfQogICAgcmV0dXJuIGVsZW1lbnQud2lkdGg7CiAgfTsKICAvLyBhcyBhbnkgYXJlIG9rIGluIHR5cGVndWFyZCBmdW5jdGlvbnMKICBjb25zdCBpc0hUTUxFbGVtZW50ID0gKHgpPT4vLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueQogICAgdHlwZW9mIHgub2Zmc2V0TGVmdCA9PT0gIm51bWJlciI7CiAgY29uc3Qgcm9vdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHJvb3RJZCkgPz8gZG9jdW1lbnQuY3VycmVudFNjcmlwdD8ucGFyZW50RWxlbWVudCA/PyBudWxsOwogIGNvbnN0IHNsaWRlciA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1zbGlkZXIiXSk7CiAgY29uc3QgaXRlbXMgPSBzbGlkZXI/LnF1ZXJ5U2VsZWN0b3JBbGwoQVRUUklCVVRFU1siZGF0YS1zbGlkZXItaXRlbSJdKTsKICBjb25zdCBwcmV2ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJwcmV2IiddKTsKICBjb25zdCBuZXh0ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJuZXh0IiddKTsKICBjb25zdCBkb3RzID0gcm9vdD8ucXVlcnlTZWxlY3RvckFsbChBVFRSSUJVVEVTWyJkYXRhLWRvdCJdKTsKICBjb25zdCBwcm9ncmVzcyA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1wcm9ncmVzcyJdKTsKICBpZiAoIXJvb3QgfHwgIXNsaWRlciB8fCAhaXRlbXMgfHwgaXRlbXMubGVuZ3RoID09PSAwKSB7CiAgICBjb25zb2xlLndhcm4oIk1pc3NpbmcgbmVjZXNzYXJ5IHNsaWRlciBhdHRyaWJ1dGVzLiBJdCB3aWxsIG5vdCB3b3JrIGFzIGludGVuZGVkLiBOZWNlc3NhcnkgZWxlbWVudHM6IiwgewogICAgICByb290LAogICAgICBzbGlkZXIsCiAgICAgIGl0ZW1zLAogICAgICByb290SWQKICAgIH0pOwogICAgcmV0dXJuOwogIH0KICBjb25zdCBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lciA9ICgpPT57CiAgICBjb25zdCBpbmRpY2VzID0gW107CiAgICBjb25zdCBzbGlkZXJSZWN0ID0gc2xpZGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaXRlbXMubGVuZ3RoOyBpbmRleCsrKXsKICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zLml0ZW0oaW5kZXgpOwogICAgICBjb25zdCByZWN0ID0gaXRlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgY29uc3QgcmF0aW8gPSBpbnRlcnNlY3Rpb25YKHJlY3QsIHNsaWRlclJlY3QpIC8gcmVjdC53aWR0aDsKICAgICAgaWYgKHJhdGlvID4gVEhSRVNIT0xEKSB7CiAgICAgICAgaW5kaWNlcy5wdXNoKGluZGV4KTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGluZGljZXM7CiAgfTsKICBjb25zdCBlbGVtZW50c0luc2lkZUNvbnRhaW5lciA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgY29uc3QgaW5maW5pdGVCZWhhdmlvciA9ICFzY3JvbGxEb3RzICYmIGluZmluaXRlICYmIGVsZW1lbnRzSW5zaWRlQ29udGFpbmVyLmxlbmd0aCA9PT0gMSAmJiBpdGVtcy5sZW5ndGggPiAxICYmIFVTRV9JTkZJTklURV9CRUhBVklPVVI7CiAgY29uc3QgZ2V0TWF4U2Nyb2xsTGVmdCA9ICgpPT5NYXRoLm1heCgwLCBzbGlkZXIuc2Nyb2xsV2lkdGggLSBzbGlkZXIuY2xpZW50V2lkdGgpOwogIGNvbnN0IGNsYW1wU2Nyb2xsTGVmdCA9IChsZWZ0KT0+TWF0aC5taW4oTWF0aC5tYXgobGVmdCwgMCksIGdldE1heFNjcm9sbExlZnQoKSk7CiAgY29uc3QgZ2V0SXRlbVNjcm9sbExlZnQgPSAoaXRlbSk9PnsKICAgIGlmICghaXNIVE1MRWxlbWVudChpdGVtKSkgcmV0dXJuIDA7CiAgICByZXR1cm4gY2xhbXBTY3JvbGxMZWZ0KGl0ZW0ub2Zmc2V0TGVmdCAtIHNsaWRlci5vZmZzZXRMZWZ0KTsKICB9OwogIGxldCBzY3JvbGxEb3RQb3NpdGlvbnMgPSBbXTsKICBjb25zdCBnZXRTY3JvbGxEb3RQb3NpdGlvbnMgPSAoKT0+ewogICAgaWYgKCFzY3JvbGxEb3RzKSByZXR1cm4gW107CiAgICBpZiAoc2xpZGVyLmNsaWVudFdpZHRoIDw9IDApIHsKICAgICAgcmV0dXJuIHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggPyBzY3JvbGxEb3RQb3NpdGlvbnMgOiBbCiAgICAgICAgMAogICAgICBdOwogICAgfQogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHJldHVybiBbCiAgICAgIDAKICAgIF07CiAgICBjb25zdCB2aXNpYmxlSXRlbXMgPSBNYXRoLm1heChnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpLmxlbmd0aCwgMSk7CiAgICBjb25zdCBwb3NpdGlvbnMgPSBbCiAgICAgIDAKICAgIF07CiAgICBmb3IobGV0IGluZGV4ID0gdmlzaWJsZUl0ZW1zOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXggKz0gdmlzaWJsZUl0ZW1zKXsKICAgICAgcG9zaXRpb25zLnB1c2goZ2V0SXRlbVNjcm9sbExlZnQoaXRlbXMuaXRlbShpbmRleCkpKTsKICAgIH0KICAgIHBvc2l0aW9ucy5wdXNoKG1heFNjcm9sbExlZnQpOwogICAgcmV0dXJuIHBvc2l0aW9ucy5yZWR1Y2UoKGFjYywgcG9zaXRpb24pPT57CiAgICAgIGNvbnN0IHJvdW5kZWRQb3NpdGlvbiA9IE1hdGgucm91bmQoY2xhbXBTY3JvbGxMZWZ0KHBvc2l0aW9uKSk7CiAgICAgIGNvbnN0IGxhc3RQb3NpdGlvbiA9IGFjY1thY2MubGVuZ3RoIC0gMV07CiAgICAgIGlmIChsYXN0UG9zaXRpb24gPT09IHVuZGVmaW5lZCB8fCBNYXRoLmFicyhsYXN0UG9zaXRpb24gLSByb3VuZGVkUG9zaXRpb24pID4gMSkgewogICAgICAgIGFjYy5wdXNoKHJvdW5kZWRQb3NpdGlvbik7CiAgICAgIH0KICAgICAgcmV0dXJuIGFjYzsKICAgIH0sIFtdKTsKICB9OwogIGNvbnN0IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCA9ICgpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIHNjcm9sbERvdFBvc2l0aW9ucy5mb3JFYWNoKChwb3NpdGlvbiwgaW5kZXgpPT57CiAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnMoc2xpZGVyLnNjcm9sbExlZnQgLSBwb3NpdGlvbik7CiAgICAgIGlmIChkaXN0YW5jZSA8IHNtYWxsZXN0RGlzdGFuY2UpIHsKICAgICAgICBzbWFsbGVzdERpc3RhbmNlID0gZGlzdGFuY2U7CiAgICAgICAgYWN0aXZlSW5kZXggPSBpbmRleDsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gYWN0aXZlSW5kZXg7CiAgfTsKICBjb25zdCB1cGRhdGVTY3JvbGxEb3RzID0gKCk9PnsKICAgIGlmICghc2Nyb2xsRG90cyB8fCAhZG90cykgcmV0dXJuOwogICAgc2Nyb2xsRG90UG9zaXRpb25zID0gZ2V0U2Nyb2xsRG90UG9zaXRpb25zKCk7CiAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90LCBpbmRleCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIGlmIChpbmRleCA+PSBzY3JvbGxEb3RQb3NpdGlvbnMubGVuZ3RoKSB7CiAgICAgICAgZG90LmNsYXNzTGlzdC5hZGQoImhpZGRlbiIpOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgIGlmIChpbmRleCA9PT0gYWN0aXZlSW5kZXgpIHsKICAgICAgICBkb3Quc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgIH0KICAgIH0pOwogICAgaWYgKCFpbmZpbml0ZSkgewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxID8gcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKSA6IHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPj0gbWF4U2Nyb2xsTGVmdCAtIDEgPyBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpIDogbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgfQogIH07CiAgY29uc3QgZ29Ub1Njcm9sbERvdCA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGNvbnN0IHBvc2l0aW9uID0gc2Nyb2xsRG90UG9zaXRpb25zW2luZGV4XTsKICAgIGlmIChwb3NpdGlvbiA9PT0gdW5kZWZpbmVkKSByZXR1cm47CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBwb3NpdGlvbgogICAgfSk7CiAgfTsKICBjb25zdCBub3JtYWxpemVTY3JvbGxCb3VuZHMgPSAoKT0+ewogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA+IG1heFNjcm9sbExlZnQpIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBtYXhTY3JvbGxMZWZ0OwogICAgfSBlbHNlIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA8IDApIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSAwOwogICAgfQogIH07CiAgbGV0IHRvdWNoU3RhcnRYID0gMDsKICBsZXQgdG91Y2hTdGFydFkgPSAwOwogIGNvbnN0IGhhbmRsZVRvdWNoU3RhcnQgPSAoZXZlbnQpPT57CiAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07CiAgICBpZiAoIXRvdWNoKSByZXR1cm47CiAgICB0b3VjaFN0YXJ0WCA9IHRvdWNoLmNsaWVudFg7CiAgICB0b3VjaFN0YXJ0WSA9IHRvdWNoLmNsaWVudFk7CiAgfTsKICBjb25zdCBoYW5kbGVUb3VjaE1vdmUgPSAoZXZlbnQpPT57CiAgICBpZiAoIXNjcm9sbERvdHMpIHJldHVybjsKICAgIGNvbnN0IHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTsKICAgIGlmICghdG91Y2gpIHJldHVybjsKICAgIGNvbnN0IGRlbHRhWCA9IHRvdWNoLmNsaWVudFggLSB0b3VjaFN0YXJ0WDsKICAgIGNvbnN0IGRlbHRhWSA9IHRvdWNoLmNsaWVudFkgLSB0b3VjaFN0YXJ0WTsKICAgIGNvbnN0IGlzSG9yaXpvbnRhbEdlc3R1cmUgPSBNYXRoLmFicyhkZWx0YVgpID4gTWF0aC5hYnMoZGVsdGFZKTsKICAgIGlmICghaXNIb3Jpem9udGFsR2VzdHVyZSkgcmV0dXJuOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHsKICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcygpOwogICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdCBpc0F0U3RhcnQgPSBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxOwogICAgY29uc3QgaXNBdEVuZCA9IHNsaWRlci5zY3JvbGxMZWZ0ID49IG1heFNjcm9sbExlZnQgLSAxOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RTdGFydCA9IGlzQXRTdGFydCAmJiBkZWx0YVggPiAwOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RFbmQgPSBpc0F0RW5kICYmIGRlbHRhWCA8IDA7CiAgICBpZiAoaXNEcmFnZ2luZ1Bhc3RTdGFydCB8fCBpc0RyYWdnaW5nUGFzdEVuZCkgewogICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgbm9ybWFsaXplU2Nyb2xsQm91bmRzKCk7CiAgICB9CiAgfTsKICBjb25zdCBnb1RvSXRlbSA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBjb25zdCBpdGVtID0gc2xpZGVyLnF1ZXJ5U2VsZWN0b3IoYGxpW2RhdGEtcm9vdD0nJHtyb290SWR9J11bZGF0YS1zbGlkZXItaXRlbT0nJHtpbmRleH0nXWApID8/IHNsaWRlci5xdWVyeVNlbGVjdG9yKGBsaVtkYXRhLXNsaWRlci1pdGVtPScke2luZGV4fSddYCk7CiAgICBpZiAoaXRlbSkgewogICAgICBpZiAoIWlzSFRNTEVsZW1lbnQoaXRlbSkpIHsKICAgICAgICBjb25zb2xlLndhcm4oYEVsZW1lbnQgYXQgaW5kZXggJHtpbmRleH0gaXMgbm90IGFuIGh0bWwgZWxlbWVudC4gU2tpcHBpbmcgY2Fyb3VzZWxgKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgc2xpZGVyLnNjcm9sbFRvKHsKICAgICAgICB0b3A6IDAsCiAgICAgICAgYmVoYXZpb3I6IGJlaGF2aW9yLAogICAgICAgIGxlZnQ6IGl0ZW0ub2Zmc2V0TGVmdCAtIHJvb3Qub2Zmc2V0TGVmdAogICAgICB9KTsKICAgIH0KICB9OwogIGNvbnN0IGdvVG9JdGVtRG90ID0gKGluZGV4LCBiZWhhdmlvciA9IHNjcm9sbCk9PnsKICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgIGlmICghaXRlbSkgcmV0dXJuOwogICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSB7CiAgICAgIGNvbnNvbGUud2FybihgRWxlbWVudCBhdCBpbmRleCAke2luZGV4fSBpcyBub3QgYW4gaHRtbCBlbGVtZW50LiBTa2lwcGluZyBjYXJvdXNlbGApOwogICAgICByZXR1cm47CiAgICB9CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdAogICAgfSk7CiAgfTsKICBjb25zdCBnZXROZWFyZXN0SXRlbUluZGV4ID0gKCk9PnsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIGZvcihsZXQgaW5kZXggPSAwOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXgrKyl7CiAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSBjb250aW51ZTsKICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLmFicyhzbGlkZXIuc2Nyb2xsTGVmdCAtIChpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdCkpOwogICAgICBpZiAoZGlzdGFuY2UgPCBzbWFsbGVzdERpc3RhbmNlKSB7CiAgICAgICAgc21hbGxlc3REaXN0YW5jZSA9IGRpc3RhbmNlOwogICAgICAgIGFjdGl2ZUluZGV4ID0gaW5kZXg7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBhY3RpdmVJbmRleDsKICB9OwogIGNvbnN0IG9uQ2xpY2tQcmV2ID0gKCk9PnsKICAgIGlmIChzY3JvbGxEb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdFNjcm9sbERvdEluZGV4KCk7CiAgICAgIGFjdGl2ZUluZGV4ID09PSAwID8gaW5maW5pdGUgPyBnb1RvU2Nyb2xsRG90KHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggLSAxKSA6IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChpdGVtRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RJdGVtSW5kZXgoKTsKICAgICAgYWN0aXZlSW5kZXggPT09IDAgPyBpbmZpbml0ZSA/IGdvVG9JdGVtRG90KGl0ZW1zLmxlbmd0aCAtIDEpIDogbnVsbCA6IGdvVG9JdGVtRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIFdvdyEgaXRlbXMgcGVyIHBhZ2UgaXMgaG93IG1hbnkgZWxlbWVudHMgYXJlIGJlaW5nIGRpc3BsYXllZCBpbnNpZGUgdGhlIGNvbnRhaW5lciEhCiAgICBjb25zdCBpdGVtc1BlclBhZ2UgPSBpbmRpY2VzLmxlbmd0aDsKICAgIGNvbnN0IGlzU2hvd2luZ0ZpcnN0ID0gaW5kaWNlc1swXSA9PT0gMDsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdIC8gaXRlbXNQZXJQYWdlKTsKICAgIGlmIChvbmVCeW9uZSkgewogICAgICBpc1Nob3dpbmdGaXJzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oaXRlbXMubGVuZ3RoIC0gMSkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSAtIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nRmlyc3QgPyBpbmZpbml0ZUJlaGF2aW9yID8gaXRlbXMubGVuZ3RoIDogaXRlbXMubGVuZ3RoIC0gMSA6IChwYWdlSW5kZXggLSAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCBvbkNsaWNrTmV4dCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gc2Nyb2xsRG90UG9zaXRpb25zLmxlbmd0aCAtIDEgPyBpbmZpbml0ZSA/IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4KSA6IGdvVG9TY3JvbGxEb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGl0ZW1Eb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdEl0ZW1JbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gaXRlbXMubGVuZ3RoIC0gMSA/IGluZmluaXRlID8gZ29Ub0l0ZW1Eb3QoMCkgOiBudWxsIDogZ29Ub0l0ZW1Eb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgaW5kaWNlcyA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgICBpZiAoaW5kaWNlcy5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgLy8gV293ISBpdGVtcyBwZXIgcGFnZSBpcyBob3cgbWFueSBlbGVtZW50cyBhcmUgYmVpbmcgZGlzcGxheWVkIGluc2lkZSB0aGUgY29udGFpbmVyISEKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGluZGljZXMubGVuZ3RoOwogICAgY29uc3QgaXNTaG93aW5nTGFzdCA9IGluZGljZXNbaW5kaWNlcy5sZW5ndGggLSAxXSA9PT0gaXRlbXMubGVuZ3RoIC0gMTsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1swXSAvIGl0ZW1zUGVyUGFnZSk7CiAgICAvLyBnb1RvSXRlbShpc1Nob3dpbmdMYXN0ID8gMCA6IChpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICBpZiAob25lQnlvbmUpIHsKICAgICAgaXNTaG93aW5nTGFzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oMCkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSArIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nTGFzdCA/IGluZmluaXRlQmVoYXZpb3IgPyBpdGVtcy5sZW5ndGggKyAxIDogMCA6IChwYWdlSW5kZXggKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCB1cGRhdGVQYWdlRG90cyA9ICgpPT57CiAgICBpZiAoIXBhZ2VEb3RzIHx8ICFkb3RzKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IE1hdGgubWF4KGluZGljZXMubGVuZ3RoLCAxKTsKICAgIGNvbnN0IG1heFZpc2libGUgPSBNYXRoLm1heCguLi5pbmRpY2VzKTsKICAgIGNvbnN0IHBhZ2VEb3RJbmRleCA9IE1hdGguZmxvb3IobWF4VmlzaWJsZSAvIGl0ZW1zUGVyUGFnZSkgKiBpdGVtc1BlclBhZ2U7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCwgaSk9PnsKICAgICAgaWYgKGkgJSBpdGVtc1BlclBhZ2UgIT09IDApIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShwYWdlRG90SW5kZXgpOwogICAgaWYgKGFjdGl2ZURvdCkgewogICAgICBBcnJheS5mcm9tKGRvdHMpLmZpbHRlcigoX2RvdCwgaSk9PmkgPCBwYWdlRG90SW5kZXggJiYgaSAlIGl0ZW1zUGVyUGFnZSA9PT0gMCkuZm9yRWFjaCgoZG90KT0+ZG90LnNldEF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIiwgInRydWUiKSk7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IHVwZGF0ZUFjdGl2ZURvdCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICB1cGRhdGVTY3JvbGxEb3RzKCk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChwYWdlRG90cyB8fCAhZG90cykgewogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoaXRlbURvdHMpIHsKICAgICAgY29uc3QgYWN0aXZlSW5kZXggPSBnZXROZWFyZXN0SXRlbUluZGV4KCk7CiAgICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90KT0+ewogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtcGFpbnRlZCIpOwogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIH0pOwogICAgICBjb25zdCBhY3RpdmVEb3QgPSBkb3RzLml0ZW0oYWN0aXZlSW5kZXgpOwogICAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgICAgYWN0aXZlRG90LnNldEF0dHJpYnV0ZSgiZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gTWF0aC5taW4oLi4uaW5kaWNlcyk7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShhY3RpdmVJbmRleCk7CiAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGlmIChwYWdlRG90cykgewogICAgICB1cGRhdGVQYWdlRG90cygpOwogICAgfSBlbHNlIHsKICAgICAgdXBkYXRlQWN0aXZlRG90KCk7CiAgICB9CiAgICBlbGVtZW50cy5mb3JFYWNoKChpdGVtKT0+ewogICAgICBjb25zdCBpbmRleCA9IE51bWJlcihpdGVtLnRhcmdldC5nZXRBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKSkgfHwgMDsKICAgICAgaWYgKCFpbmZpbml0ZSAmJiAhc2Nyb2xsRG90cykgewogICAgICAgIGlmIChpbmRleCA9PT0gMCkgewogICAgICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcpIHsKICAgICAgICAgICAgcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGluZGV4ID09PSBpdGVtcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICBpZiAoaXRlbS5pc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocHJvZ3Jlc3MpIHsKICAgICAgICAgIGlmIChwcm9ncmVzcy5pZCA9PSAiMCIgJiYgaW5kZXggPT09IGl0ZW1zLmxlbmd0aCAtIDEpIHsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUuaGVpZ2h0ID0gYCR7MSAvIGl0ZW1zLmxlbmd0aCAqIDEwMH0lYDsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUud2lkdGggPSBgJHsxIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5pZCA9ICIxIjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByb2dyZXNzLnN0eWxlLmhlaWdodCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5zdHlsZS53aWR0aCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfSwgewogICAgdGhyZXNob2xkOiBUSFJFU0hPTEQsCiAgICByb290OiBzbGlkZXIsCiAgICByb290TWFyZ2luOiAiMTAwcHgiCiAgfSk7CiAgY29uc3QgZnVsbE9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGVsZW1lbnRzLmZvckVhY2goKGl0ZW0pPT57CiAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IHNsaWRlcj8ucXVlcnlTZWxlY3RvckFsbChgbGlgKTsKICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcgJiYgZWxlbWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT0gY3VycmVudEl0ZW1zWzFdKSB7CiAgICAgICAgICBzZXRUaW1lb3V0KCgpPT57CiAgICAgICAgICAgIGdvVG9JdGVtKGl0ZW1zLmxlbmd0aCAtIDEsICJpbnN0YW50Iik7CiAgICAgICAgICB9LCAyMDApOwogICAgICAgIH0KICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT09IGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pIHsKICAgICAgICAgIHNldFRpbWVvdXQoKCk9PnsKICAgICAgICAgICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICAgICAgICAgIH0sIDIwMCk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9LCB7CiAgICB0aHJlc2hvbGQ6IDAuNywKICAgIHJvb3Q6IHNsaWRlciwKICAgIHJvb3RNYXJnaW46ICIxMDBweCIKICB9KTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgY29uc3QgZmlyc3RJdGVtQ2xvbmUgPSBpdGVtc1swXS5jbG9uZU5vZGUodHJ1ZSk7CiAgICBjb25zdCBzZWNvbmRJdGVtQ2xvbmUgPSBpdGVtc1sxXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgcGVudWx0aW1hdGVJdGVtQ2xvbmUgPSBpdGVtc1tpdGVtcy5sZW5ndGggLSAyXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgbGFzdEl0ZW1DbG9uZSA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdLmNsb25lTm9kZSh0cnVlKTsKICAgIC8vIHdlIHJlbW92ZSB0aGVzZSBhdHRyaWJ1dGVzIGZyb20gdGhlIGNsb25lZCBpdGVtcyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gc2VuZCBldmVudHMgZm9yIHRoZSBjbG9uZWQgaXRlbXMKICAgIC8vIGJhbm5lciBjYXJvdXNlbCB1c2VzIGRhdGEtZXZlbnQgdG8gc2VuZCBldmVudHMgdG8gYW5hbHl0aWNzCiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBsYXN0SXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHBlbnVsdGltYXRlSXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuZmlyc3RFbGVtZW50Q2hpbGQ/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1ldmVudC10cmlnZ2VyIik7CiAgICBwZW51bHRpbWF0ZUl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgaXRlbXMubGVuZ3RoLnRvU3RyaW5nKCkpOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmU/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1zbGlkZXItaXRlbSIpOwogICAgZmlyc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgKGl0ZW1zLmxlbmd0aCArIDEpLnRvU3RyaW5nKCkpOwogICAgc2Vjb25kSXRlbUNsb25lPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKTsKICAgIHNsaWRlci5pbnNlcnRCZWZvcmUobGFzdEl0ZW1DbG9uZSwgaXRlbXNbMF0pOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmUgJiYgc2xpZGVyLmluc2VydEJlZm9yZShwZW51bHRpbWF0ZUl0ZW1DbG9uZSwgbGFzdEl0ZW1DbG9uZSk7CiAgICBzbGlkZXIuYXBwZW5kQ2hpbGQoZmlyc3RJdGVtQ2xvbmUpOwogICAgc2Vjb25kSXRlbUNsb25lICYmIHNsaWRlci5hcHBlbmRDaGlsZChzZWNvbmRJdGVtQ2xvbmUpOwogICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICB9CiAgY29uc3QgY3VycmVudEl0ZW1zID0gc2xpZGVyPy5xdWVyeVNlbGVjdG9yQWxsKGBsaWApOwogIGl0ZW1zLmZvckVhY2goKGl0ZW0pPT5vYnNlcnZlci5vYnNlcnZlKGl0ZW0pKTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgZnVsbE9ic2VydmVyLm9ic2VydmUoY3VycmVudEl0ZW1zWzFdKTsKICAgIGZ1bGxPYnNlcnZlci5vYnNlcnZlKGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pOwogIH0KICBpZiAocGFnZURvdHMpIHsKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCkubGVuZ3RoOwogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGNvbnN0IGRvdCA9IGRvdHM/Lml0ZW0oaXQpOwogICAgICBpZiAoIWRvdCkgY29udGludWU7CiAgICAgIGlmIChpdCAlIGl0ZW1zUGVyUGFnZSAhPT0gMCkgewogICAgICAgIGRvdC5jbGFzc0xpc3QuYWRkKCJoaWRkZW4iKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgICAgZG90LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKHNjcm9sbERvdHMpIHsKICAgIHVwZGF0ZVNjcm9sbERvdHMoKTsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5nb1RvU2Nyb2xsRG90KGl0KSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5pdGVtRG90cyA/IGdvVG9JdGVtRG90KGl0KSA6IGdvVG9JdGVtKGl0KSk7CiAgICB9CiAgfQogIHByZXY/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja1ByZXYpOwogIG5leHQ/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogIGlmIChzY3JvbGxEb3RzKSB7CiAgICBzbGlkZXIuc3R5bGUub3ZlcnNjcm9sbEJlaGF2aW9yWCA9ICJjb250YWluIjsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJzY3JvbGwiLCBub3JtYWxpemVTY3JvbGxCb3VuZHMsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2hzdGFydCIsIGhhbmRsZVRvdWNoU3RhcnQsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2htb3ZlIiwgaGFuZGxlVG91Y2hNb3ZlLCB7CiAgICAgIHBhc3NpdmU6IGZhbHNlCiAgICB9KTsKICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgfSBlbHNlIGlmIChwYWdlRG90cykgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZVBhZ2VEb3RzKTsKICB9IGVsc2UgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZUFjdGl2ZURvdCk7CiAgfQogIGNvbnN0IHRpbWVvdXQgPSBpbnRlcnZhbCAmJiBzZXRJbnRlcnZhbChvbkNsaWNrTmV4dCwgaW50ZXJ2YWwpOwogIGxldCBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXI7CiAgZnVuY3Rpb24gZW5hYmxlSG9yaXpvbnRhbFNjcm9sbCgpIHsKICAgIGlmICghc2xpZGVyKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGxldCBpc01vdXNlRG93biA9IGZhbHNlOwogICAgbGV0IHN0YXJ0WDsKICAgIGxldCBzY3JvbGxMZWZ0OwogICAgbGV0IHZlbG9jaXR5ID0gMDsKICAgIGxldCBtb21lbnR1bUZyYW1lOwogICAgY29uc3QgbW9tZW50dW1TY3JvbGwgPSAoKT0+ewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCArPSB2ZWxvY2l0eTsKICAgICAgdmVsb2NpdHkgKj0gMC45NTsKICAgICAgaWYgKE1hdGguYWJzKHZlbG9jaXR5KSA+IDAuMSkgewogICAgICAgIG1vbWVudHVtRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUobW9tZW50dW1TY3JvbGwpOwogICAgICB9CiAgICB9OwogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlZG93biIsIChlKT0+ewogICAgICBpc01vdXNlRG93biA9IHRydWU7CiAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAiZ3JhYmJpbmciOwogICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAiaW5pdGlhbCI7CiAgICAgIHN0YXJ0WCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgc2Nyb2xsTGVmdCA9IHNsaWRlci5zY3JvbGxMZWZ0OwogICAgICB2ZWxvY2l0eSA9IDA7CiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtRnJhbWUpOwogICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICB9KTsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWxlYXZlIiwgKCk9PnsKICAgICAgaWYgKGlzTW91c2VEb3duKSB7CiAgICAgICAgaXNNb3VzZURvd24gPSBmYWxzZTsKICAgICAgICBzbGlkZXIuZGF0YXNldFsiZHJhZ2dpbmciXSA9ICJmYWxzZSI7CiAgICAgICAgc2xpZGVyLnN0eWxlLmN1cnNvciA9ICJncmFiIjsKICAgICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAic21vb3RoIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2V1cCIsICgpPT57CiAgICAgIGlmIChpc01vdXNlRG93bikgewogICAgICAgIGlzTW91c2VEb3duID0gZmFsc2U7CiAgICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAiZmFsc2UiOwogICAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAibm9ybWFsIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2Vtb3ZlIiwgKGUpPT57CiAgICAgIGlmICghaXNNb3VzZURvd24pIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29uc3QgeCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgY29uc3Qgd2FsayA9ICh4IC0gc3RhcnRYKSAqIDAuNTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBzY3JvbGxMZWZ0IC0gd2FsazsKICAgICAgdmVsb2NpdHkgPSAtd2FsayAqIDAuMjsKICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAidHJ1ZSI7CiAgICB9KTsKICB9CiAgaWYgKGRlc2t0b3BEcmFnZ2FibGUpIHsKICAgIHNsaWRlci5kYXRhc2V0WyJkcmFnZ2FibGUiXSA9ICJ0cnVlIjsKICAgIGVuYWJsZUhvcml6b250YWxTY3JvbGwoKTsKICB9CiAgaWYgKHNjcm9sbERvdHMgJiYgIlJlc2l6ZU9ic2VydmVyIiBpbiBnbG9iYWxUaGlzKSB7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIodXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShzbGlkZXIpOwogIH0KICAvLyBVbnJlZ2lzdGVyIGNhbGxiYWNrcwogIHJldHVybiAoKT0+ewogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGRvdHM/Lml0ZW0oaXQpLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICB9CiAgICBwcmV2Py5yZW1vdmVFdmVudExpc3RlbmVyKCJjbGljayIsIG9uQ2xpY2tQcmV2KTsKICAgIG5leHQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogICAgaWYgKHNjcm9sbERvdHMpIHsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcyk7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVTY3JvbGxEb3RzKTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNoc3RhcnQiLCBoYW5kbGVUb3VjaFN0YXJ0KTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNobW92ZSIsIGhhbmRsZVRvdWNoTW92ZSk7CiAgICAgIGdsb2JhbFRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICB9IGVsc2UgaWYgKHBhZ2VEb3RzKSB7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVQYWdlRG90cyk7CiAgICB9IGVsc2UgewogICAgICBzbGlkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlQWN0aXZlRG90KTsKICAgIH0KICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTsKICAgIHNjcm9sbERvdHNSZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpOwogICAgY2xlYXJJbnRlcnZhbCh0aW1lb3V0KTsKICB9Owp9KSh7InJvb3RJZCI6Im5tUDAzMTI0MjMwMjUtc2xpZGVyLTMiLCJvbmVCeW9uZSI6dHJ1ZSwic2Nyb2xsRG90cyI6dHJ1ZSwiZGVza3RvcERyYWdnYWJsZSI6ZmFsc2V9KSkp | |
| js | data:text/javascript;base64,ZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZSgoKHsgcm9vdElkLCBzY3JvbGwgPSAic21vb3RoIiwgaW50ZXJ2YWwsIGluZmluaXRlLCBvbmVCeW9uZSwgaXRlbURvdHMsIHBhZ2VEb3RzLCBzY3JvbGxEb3RzLCBpc0Zyb21Ib29rID0gZmFsc2UsIGRlc2t0b3BEcmFnZ2FibGUgPSBmYWxzZSB9KT0+ewogIGNvbnN0IEFUVFJJQlVURVMgPSBpc0Zyb21Ib29rIC8vIHRoaXMgaXMgdXNlZCB0byBrZWVwIGNvbXBhdGliaWxpdHkgdG8gdGhlIG9sZCB3YXkgdG8gY3JlYXRlIGEgc2xpZGVyCiAgID8gewogICAgImRhdGEtc2xpZGVyIjogYFtkYXRhLXNsaWRlcl1bZGF0YS1yb290PSR7cm9vdElkfV1gLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiBgW2RhdGEtc2xpZGVyLWl0ZW1dW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6IGBbZGF0YS1zbGlkZT0icHJldiJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6IGBbZGF0YS1zbGlkZT0ibmV4dCJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLWRvdCI6IGBbZGF0YS1kb3RdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLXByb2dyZXNzIjogYFtkYXRhLXByb2dyZXNzXVtkYXRhLXJvb3Q9JHtyb290SWR9XWAKICB9IDogewogICAgImRhdGEtc2xpZGVyIjogIltkYXRhLXNsaWRlcl0iLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiAiW2RhdGEtc2xpZGVyLWl0ZW1dIiwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6ICdbZGF0YS1zbGlkZT0icHJldiJdJywKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6ICdbZGF0YS1zbGlkZT0ibmV4dCJdJywKICAgICJkYXRhLWRvdCI6ICJbZGF0YS1kb3RdIiwKICAgICJkYXRhLXByb2dyZXNzIjogIltkYXRhLXByb2dyZXNzXSIKICB9OwogIC8vIFBlcmNlbnRhZ2Ugb2YgdGhlIGl0ZW0gdGhhdCBoYXMgdG8gYmUgaW5zaWRlIHRoZSBjb250YWluZXIKICAvLyBmb3IgaXQgaXQgYmUgY29uc2lkZXJlZCBhcyBpbnNpZGUgdGhlIGNvbnRhaW5lcgogIGNvbnN0IFRIUkVTSE9MRCA9IDAuNzU7CiAgY29uc3QgVVNFX0lORklOSVRFX0JFSEFWSU9VUiA9IHRydWU7CiAgY29uc3QgaW50ZXJzZWN0aW9uWCA9IChlbGVtZW50LCBjb250YWluZXIpPT57CiAgICBjb25zdCBkZWx0YSA9IGNvbnRhaW5lci53aWR0aCAvIDFfMDAwOwogICAgaWYgKGVsZW1lbnQucmlnaHQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiAwLjA7CiAgICB9CiAgICBpZiAoZWxlbWVudC5sZWZ0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIDAuMDsKICAgIH0KICAgIGlmIChlbGVtZW50LmxlZnQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiBlbGVtZW50LnJpZ2h0IC0gY29udGFpbmVyLmxlZnQgKyBkZWx0YTsKICAgIH0KICAgIGlmIChlbGVtZW50LnJpZ2h0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIGNvbnRhaW5lci5yaWdodCAtIGVsZW1lbnQubGVmdCArIGRlbHRhOwogICAgfQogICAgcmV0dXJuIGVsZW1lbnQud2lkdGg7CiAgfTsKICAvLyBhcyBhbnkgYXJlIG9rIGluIHR5cGVndWFyZCBmdW5jdGlvbnMKICBjb25zdCBpc0hUTUxFbGVtZW50ID0gKHgpPT4vLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueQogICAgdHlwZW9mIHgub2Zmc2V0TGVmdCA9PT0gIm51bWJlciI7CiAgY29uc3Qgcm9vdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHJvb3RJZCkgPz8gZG9jdW1lbnQuY3VycmVudFNjcmlwdD8ucGFyZW50RWxlbWVudCA/PyBudWxsOwogIGNvbnN0IHNsaWRlciA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1zbGlkZXIiXSk7CiAgY29uc3QgaXRlbXMgPSBzbGlkZXI/LnF1ZXJ5U2VsZWN0b3JBbGwoQVRUUklCVVRFU1siZGF0YS1zbGlkZXItaXRlbSJdKTsKICBjb25zdCBwcmV2ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJwcmV2IiddKTsKICBjb25zdCBuZXh0ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJuZXh0IiddKTsKICBjb25zdCBkb3RzID0gcm9vdD8ucXVlcnlTZWxlY3RvckFsbChBVFRSSUJVVEVTWyJkYXRhLWRvdCJdKTsKICBjb25zdCBwcm9ncmVzcyA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1wcm9ncmVzcyJdKTsKICBpZiAoIXJvb3QgfHwgIXNsaWRlciB8fCAhaXRlbXMgfHwgaXRlbXMubGVuZ3RoID09PSAwKSB7CiAgICBjb25zb2xlLndhcm4oIk1pc3NpbmcgbmVjZXNzYXJ5IHNsaWRlciBhdHRyaWJ1dGVzLiBJdCB3aWxsIG5vdCB3b3JrIGFzIGludGVuZGVkLiBOZWNlc3NhcnkgZWxlbWVudHM6IiwgewogICAgICByb290LAogICAgICBzbGlkZXIsCiAgICAgIGl0ZW1zLAogICAgICByb290SWQKICAgIH0pOwogICAgcmV0dXJuOwogIH0KICBjb25zdCBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lciA9ICgpPT57CiAgICBjb25zdCBpbmRpY2VzID0gW107CiAgICBjb25zdCBzbGlkZXJSZWN0ID0gc2xpZGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaXRlbXMubGVuZ3RoOyBpbmRleCsrKXsKICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zLml0ZW0oaW5kZXgpOwogICAgICBjb25zdCByZWN0ID0gaXRlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgY29uc3QgcmF0aW8gPSBpbnRlcnNlY3Rpb25YKHJlY3QsIHNsaWRlclJlY3QpIC8gcmVjdC53aWR0aDsKICAgICAgaWYgKHJhdGlvID4gVEhSRVNIT0xEKSB7CiAgICAgICAgaW5kaWNlcy5wdXNoKGluZGV4KTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGluZGljZXM7CiAgfTsKICBjb25zdCBlbGVtZW50c0luc2lkZUNvbnRhaW5lciA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgY29uc3QgaW5maW5pdGVCZWhhdmlvciA9ICFzY3JvbGxEb3RzICYmIGluZmluaXRlICYmIGVsZW1lbnRzSW5zaWRlQ29udGFpbmVyLmxlbmd0aCA9PT0gMSAmJiBpdGVtcy5sZW5ndGggPiAxICYmIFVTRV9JTkZJTklURV9CRUhBVklPVVI7CiAgY29uc3QgZ2V0TWF4U2Nyb2xsTGVmdCA9ICgpPT5NYXRoLm1heCgwLCBzbGlkZXIuc2Nyb2xsV2lkdGggLSBzbGlkZXIuY2xpZW50V2lkdGgpOwogIGNvbnN0IGNsYW1wU2Nyb2xsTGVmdCA9IChsZWZ0KT0+TWF0aC5taW4oTWF0aC5tYXgobGVmdCwgMCksIGdldE1heFNjcm9sbExlZnQoKSk7CiAgY29uc3QgZ2V0SXRlbVNjcm9sbExlZnQgPSAoaXRlbSk9PnsKICAgIGlmICghaXNIVE1MRWxlbWVudChpdGVtKSkgcmV0dXJuIDA7CiAgICByZXR1cm4gY2xhbXBTY3JvbGxMZWZ0KGl0ZW0ub2Zmc2V0TGVmdCAtIHNsaWRlci5vZmZzZXRMZWZ0KTsKICB9OwogIGxldCBzY3JvbGxEb3RQb3NpdGlvbnMgPSBbXTsKICBjb25zdCBnZXRTY3JvbGxEb3RQb3NpdGlvbnMgPSAoKT0+ewogICAgaWYgKCFzY3JvbGxEb3RzKSByZXR1cm4gW107CiAgICBpZiAoc2xpZGVyLmNsaWVudFdpZHRoIDw9IDApIHsKICAgICAgcmV0dXJuIHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggPyBzY3JvbGxEb3RQb3NpdGlvbnMgOiBbCiAgICAgICAgMAogICAgICBdOwogICAgfQogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHJldHVybiBbCiAgICAgIDAKICAgIF07CiAgICBjb25zdCB2aXNpYmxlSXRlbXMgPSBNYXRoLm1heChnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpLmxlbmd0aCwgMSk7CiAgICBjb25zdCBwb3NpdGlvbnMgPSBbCiAgICAgIDAKICAgIF07CiAgICBmb3IobGV0IGluZGV4ID0gdmlzaWJsZUl0ZW1zOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXggKz0gdmlzaWJsZUl0ZW1zKXsKICAgICAgcG9zaXRpb25zLnB1c2goZ2V0SXRlbVNjcm9sbExlZnQoaXRlbXMuaXRlbShpbmRleCkpKTsKICAgIH0KICAgIHBvc2l0aW9ucy5wdXNoKG1heFNjcm9sbExlZnQpOwogICAgcmV0dXJuIHBvc2l0aW9ucy5yZWR1Y2UoKGFjYywgcG9zaXRpb24pPT57CiAgICAgIGNvbnN0IHJvdW5kZWRQb3NpdGlvbiA9IE1hdGgucm91bmQoY2xhbXBTY3JvbGxMZWZ0KHBvc2l0aW9uKSk7CiAgICAgIGNvbnN0IGxhc3RQb3NpdGlvbiA9IGFjY1thY2MubGVuZ3RoIC0gMV07CiAgICAgIGlmIChsYXN0UG9zaXRpb24gPT09IHVuZGVmaW5lZCB8fCBNYXRoLmFicyhsYXN0UG9zaXRpb24gLSByb3VuZGVkUG9zaXRpb24pID4gMSkgewogICAgICAgIGFjYy5wdXNoKHJvdW5kZWRQb3NpdGlvbik7CiAgICAgIH0KICAgICAgcmV0dXJuIGFjYzsKICAgIH0sIFtdKTsKICB9OwogIGNvbnN0IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCA9ICgpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIHNjcm9sbERvdFBvc2l0aW9ucy5mb3JFYWNoKChwb3NpdGlvbiwgaW5kZXgpPT57CiAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnMoc2xpZGVyLnNjcm9sbExlZnQgLSBwb3NpdGlvbik7CiAgICAgIGlmIChkaXN0YW5jZSA8IHNtYWxsZXN0RGlzdGFuY2UpIHsKICAgICAgICBzbWFsbGVzdERpc3RhbmNlID0gZGlzdGFuY2U7CiAgICAgICAgYWN0aXZlSW5kZXggPSBpbmRleDsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gYWN0aXZlSW5kZXg7CiAgfTsKICBjb25zdCB1cGRhdGVTY3JvbGxEb3RzID0gKCk9PnsKICAgIGlmICghc2Nyb2xsRG90cyB8fCAhZG90cykgcmV0dXJuOwogICAgc2Nyb2xsRG90UG9zaXRpb25zID0gZ2V0U2Nyb2xsRG90UG9zaXRpb25zKCk7CiAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90LCBpbmRleCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIGlmIChpbmRleCA+PSBzY3JvbGxEb3RQb3NpdGlvbnMubGVuZ3RoKSB7CiAgICAgICAgZG90LmNsYXNzTGlzdC5hZGQoImhpZGRlbiIpOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgIGlmIChpbmRleCA9PT0gYWN0aXZlSW5kZXgpIHsKICAgICAgICBkb3Quc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgIH0KICAgIH0pOwogICAgaWYgKCFpbmZpbml0ZSkgewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxID8gcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKSA6IHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPj0gbWF4U2Nyb2xsTGVmdCAtIDEgPyBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpIDogbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgfQogIH07CiAgY29uc3QgZ29Ub1Njcm9sbERvdCA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGNvbnN0IHBvc2l0aW9uID0gc2Nyb2xsRG90UG9zaXRpb25zW2luZGV4XTsKICAgIGlmIChwb3NpdGlvbiA9PT0gdW5kZWZpbmVkKSByZXR1cm47CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBwb3NpdGlvbgogICAgfSk7CiAgfTsKICBjb25zdCBub3JtYWxpemVTY3JvbGxCb3VuZHMgPSAoKT0+ewogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA+IG1heFNjcm9sbExlZnQpIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBtYXhTY3JvbGxMZWZ0OwogICAgfSBlbHNlIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA8IDApIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSAwOwogICAgfQogIH07CiAgbGV0IHRvdWNoU3RhcnRYID0gMDsKICBsZXQgdG91Y2hTdGFydFkgPSAwOwogIGNvbnN0IGhhbmRsZVRvdWNoU3RhcnQgPSAoZXZlbnQpPT57CiAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07CiAgICBpZiAoIXRvdWNoKSByZXR1cm47CiAgICB0b3VjaFN0YXJ0WCA9IHRvdWNoLmNsaWVudFg7CiAgICB0b3VjaFN0YXJ0WSA9IHRvdWNoLmNsaWVudFk7CiAgfTsKICBjb25zdCBoYW5kbGVUb3VjaE1vdmUgPSAoZXZlbnQpPT57CiAgICBpZiAoIXNjcm9sbERvdHMpIHJldHVybjsKICAgIGNvbnN0IHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTsKICAgIGlmICghdG91Y2gpIHJldHVybjsKICAgIGNvbnN0IGRlbHRhWCA9IHRvdWNoLmNsaWVudFggLSB0b3VjaFN0YXJ0WDsKICAgIGNvbnN0IGRlbHRhWSA9IHRvdWNoLmNsaWVudFkgLSB0b3VjaFN0YXJ0WTsKICAgIGNvbnN0IGlzSG9yaXpvbnRhbEdlc3R1cmUgPSBNYXRoLmFicyhkZWx0YVgpID4gTWF0aC5hYnMoZGVsdGFZKTsKICAgIGlmICghaXNIb3Jpem9udGFsR2VzdHVyZSkgcmV0dXJuOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHsKICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcygpOwogICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdCBpc0F0U3RhcnQgPSBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxOwogICAgY29uc3QgaXNBdEVuZCA9IHNsaWRlci5zY3JvbGxMZWZ0ID49IG1heFNjcm9sbExlZnQgLSAxOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RTdGFydCA9IGlzQXRTdGFydCAmJiBkZWx0YVggPiAwOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RFbmQgPSBpc0F0RW5kICYmIGRlbHRhWCA8IDA7CiAgICBpZiAoaXNEcmFnZ2luZ1Bhc3RTdGFydCB8fCBpc0RyYWdnaW5nUGFzdEVuZCkgewogICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgbm9ybWFsaXplU2Nyb2xsQm91bmRzKCk7CiAgICB9CiAgfTsKICBjb25zdCBnb1RvSXRlbSA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBjb25zdCBpdGVtID0gc2xpZGVyLnF1ZXJ5U2VsZWN0b3IoYGxpW2RhdGEtcm9vdD0nJHtyb290SWR9J11bZGF0YS1zbGlkZXItaXRlbT0nJHtpbmRleH0nXWApID8/IHNsaWRlci5xdWVyeVNlbGVjdG9yKGBsaVtkYXRhLXNsaWRlci1pdGVtPScke2luZGV4fSddYCk7CiAgICBpZiAoaXRlbSkgewogICAgICBpZiAoIWlzSFRNTEVsZW1lbnQoaXRlbSkpIHsKICAgICAgICBjb25zb2xlLndhcm4oYEVsZW1lbnQgYXQgaW5kZXggJHtpbmRleH0gaXMgbm90IGFuIGh0bWwgZWxlbWVudC4gU2tpcHBpbmcgY2Fyb3VzZWxgKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgc2xpZGVyLnNjcm9sbFRvKHsKICAgICAgICB0b3A6IDAsCiAgICAgICAgYmVoYXZpb3I6IGJlaGF2aW9yLAogICAgICAgIGxlZnQ6IGl0ZW0ub2Zmc2V0TGVmdCAtIHJvb3Qub2Zmc2V0TGVmdAogICAgICB9KTsKICAgIH0KICB9OwogIGNvbnN0IGdvVG9JdGVtRG90ID0gKGluZGV4LCBiZWhhdmlvciA9IHNjcm9sbCk9PnsKICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgIGlmICghaXRlbSkgcmV0dXJuOwogICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSB7CiAgICAgIGNvbnNvbGUud2FybihgRWxlbWVudCBhdCBpbmRleCAke2luZGV4fSBpcyBub3QgYW4gaHRtbCBlbGVtZW50LiBTa2lwcGluZyBjYXJvdXNlbGApOwogICAgICByZXR1cm47CiAgICB9CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdAogICAgfSk7CiAgfTsKICBjb25zdCBnZXROZWFyZXN0SXRlbUluZGV4ID0gKCk9PnsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIGZvcihsZXQgaW5kZXggPSAwOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXgrKyl7CiAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSBjb250aW51ZTsKICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLmFicyhzbGlkZXIuc2Nyb2xsTGVmdCAtIChpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdCkpOwogICAgICBpZiAoZGlzdGFuY2UgPCBzbWFsbGVzdERpc3RhbmNlKSB7CiAgICAgICAgc21hbGxlc3REaXN0YW5jZSA9IGRpc3RhbmNlOwogICAgICAgIGFjdGl2ZUluZGV4ID0gaW5kZXg7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBhY3RpdmVJbmRleDsKICB9OwogIGNvbnN0IG9uQ2xpY2tQcmV2ID0gKCk9PnsKICAgIGlmIChzY3JvbGxEb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdFNjcm9sbERvdEluZGV4KCk7CiAgICAgIGFjdGl2ZUluZGV4ID09PSAwID8gaW5maW5pdGUgPyBnb1RvU2Nyb2xsRG90KHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggLSAxKSA6IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChpdGVtRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RJdGVtSW5kZXgoKTsKICAgICAgYWN0aXZlSW5kZXggPT09IDAgPyBpbmZpbml0ZSA/IGdvVG9JdGVtRG90KGl0ZW1zLmxlbmd0aCAtIDEpIDogbnVsbCA6IGdvVG9JdGVtRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIFdvdyEgaXRlbXMgcGVyIHBhZ2UgaXMgaG93IG1hbnkgZWxlbWVudHMgYXJlIGJlaW5nIGRpc3BsYXllZCBpbnNpZGUgdGhlIGNvbnRhaW5lciEhCiAgICBjb25zdCBpdGVtc1BlclBhZ2UgPSBpbmRpY2VzLmxlbmd0aDsKICAgIGNvbnN0IGlzU2hvd2luZ0ZpcnN0ID0gaW5kaWNlc1swXSA9PT0gMDsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdIC8gaXRlbXNQZXJQYWdlKTsKICAgIGlmIChvbmVCeW9uZSkgewogICAgICBpc1Nob3dpbmdGaXJzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oaXRlbXMubGVuZ3RoIC0gMSkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSAtIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nRmlyc3QgPyBpbmZpbml0ZUJlaGF2aW9yID8gaXRlbXMubGVuZ3RoIDogaXRlbXMubGVuZ3RoIC0gMSA6IChwYWdlSW5kZXggLSAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCBvbkNsaWNrTmV4dCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gc2Nyb2xsRG90UG9zaXRpb25zLmxlbmd0aCAtIDEgPyBpbmZpbml0ZSA/IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4KSA6IGdvVG9TY3JvbGxEb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGl0ZW1Eb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdEl0ZW1JbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gaXRlbXMubGVuZ3RoIC0gMSA/IGluZmluaXRlID8gZ29Ub0l0ZW1Eb3QoMCkgOiBudWxsIDogZ29Ub0l0ZW1Eb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgaW5kaWNlcyA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgICBpZiAoaW5kaWNlcy5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgLy8gV293ISBpdGVtcyBwZXIgcGFnZSBpcyBob3cgbWFueSBlbGVtZW50cyBhcmUgYmVpbmcgZGlzcGxheWVkIGluc2lkZSB0aGUgY29udGFpbmVyISEKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGluZGljZXMubGVuZ3RoOwogICAgY29uc3QgaXNTaG93aW5nTGFzdCA9IGluZGljZXNbaW5kaWNlcy5sZW5ndGggLSAxXSA9PT0gaXRlbXMubGVuZ3RoIC0gMTsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1swXSAvIGl0ZW1zUGVyUGFnZSk7CiAgICAvLyBnb1RvSXRlbShpc1Nob3dpbmdMYXN0ID8gMCA6IChpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICBpZiAob25lQnlvbmUpIHsKICAgICAgaXNTaG93aW5nTGFzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oMCkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSArIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nTGFzdCA/IGluZmluaXRlQmVoYXZpb3IgPyBpdGVtcy5sZW5ndGggKyAxIDogMCA6IChwYWdlSW5kZXggKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCB1cGRhdGVQYWdlRG90cyA9ICgpPT57CiAgICBpZiAoIXBhZ2VEb3RzIHx8ICFkb3RzKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IE1hdGgubWF4KGluZGljZXMubGVuZ3RoLCAxKTsKICAgIGNvbnN0IG1heFZpc2libGUgPSBNYXRoLm1heCguLi5pbmRpY2VzKTsKICAgIGNvbnN0IHBhZ2VEb3RJbmRleCA9IE1hdGguZmxvb3IobWF4VmlzaWJsZSAvIGl0ZW1zUGVyUGFnZSkgKiBpdGVtc1BlclBhZ2U7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCwgaSk9PnsKICAgICAgaWYgKGkgJSBpdGVtc1BlclBhZ2UgIT09IDApIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShwYWdlRG90SW5kZXgpOwogICAgaWYgKGFjdGl2ZURvdCkgewogICAgICBBcnJheS5mcm9tKGRvdHMpLmZpbHRlcigoX2RvdCwgaSk9PmkgPCBwYWdlRG90SW5kZXggJiYgaSAlIGl0ZW1zUGVyUGFnZSA9PT0gMCkuZm9yRWFjaCgoZG90KT0+ZG90LnNldEF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIiwgInRydWUiKSk7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IHVwZGF0ZUFjdGl2ZURvdCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICB1cGRhdGVTY3JvbGxEb3RzKCk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChwYWdlRG90cyB8fCAhZG90cykgewogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoaXRlbURvdHMpIHsKICAgICAgY29uc3QgYWN0aXZlSW5kZXggPSBnZXROZWFyZXN0SXRlbUluZGV4KCk7CiAgICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90KT0+ewogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtcGFpbnRlZCIpOwogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIH0pOwogICAgICBjb25zdCBhY3RpdmVEb3QgPSBkb3RzLml0ZW0oYWN0aXZlSW5kZXgpOwogICAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgICAgYWN0aXZlRG90LnNldEF0dHJpYnV0ZSgiZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gTWF0aC5taW4oLi4uaW5kaWNlcyk7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShhY3RpdmVJbmRleCk7CiAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGlmIChwYWdlRG90cykgewogICAgICB1cGRhdGVQYWdlRG90cygpOwogICAgfSBlbHNlIHsKICAgICAgdXBkYXRlQWN0aXZlRG90KCk7CiAgICB9CiAgICBlbGVtZW50cy5mb3JFYWNoKChpdGVtKT0+ewogICAgICBjb25zdCBpbmRleCA9IE51bWJlcihpdGVtLnRhcmdldC5nZXRBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKSkgfHwgMDsKICAgICAgaWYgKCFpbmZpbml0ZSAmJiAhc2Nyb2xsRG90cykgewogICAgICAgIGlmIChpbmRleCA9PT0gMCkgewogICAgICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcpIHsKICAgICAgICAgICAgcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGluZGV4ID09PSBpdGVtcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICBpZiAoaXRlbS5pc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocHJvZ3Jlc3MpIHsKICAgICAgICAgIGlmIChwcm9ncmVzcy5pZCA9PSAiMCIgJiYgaW5kZXggPT09IGl0ZW1zLmxlbmd0aCAtIDEpIHsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUuaGVpZ2h0ID0gYCR7MSAvIGl0ZW1zLmxlbmd0aCAqIDEwMH0lYDsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUud2lkdGggPSBgJHsxIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5pZCA9ICIxIjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByb2dyZXNzLnN0eWxlLmhlaWdodCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5zdHlsZS53aWR0aCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfSwgewogICAgdGhyZXNob2xkOiBUSFJFU0hPTEQsCiAgICByb290OiBzbGlkZXIsCiAgICByb290TWFyZ2luOiAiMTAwcHgiCiAgfSk7CiAgY29uc3QgZnVsbE9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGVsZW1lbnRzLmZvckVhY2goKGl0ZW0pPT57CiAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IHNsaWRlcj8ucXVlcnlTZWxlY3RvckFsbChgbGlgKTsKICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcgJiYgZWxlbWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT0gY3VycmVudEl0ZW1zWzFdKSB7CiAgICAgICAgICBzZXRUaW1lb3V0KCgpPT57CiAgICAgICAgICAgIGdvVG9JdGVtKGl0ZW1zLmxlbmd0aCAtIDEsICJpbnN0YW50Iik7CiAgICAgICAgICB9LCAyMDApOwogICAgICAgIH0KICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT09IGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pIHsKICAgICAgICAgIHNldFRpbWVvdXQoKCk9PnsKICAgICAgICAgICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICAgICAgICAgIH0sIDIwMCk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9LCB7CiAgICB0aHJlc2hvbGQ6IDAuNywKICAgIHJvb3Q6IHNsaWRlciwKICAgIHJvb3RNYXJnaW46ICIxMDBweCIKICB9KTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgY29uc3QgZmlyc3RJdGVtQ2xvbmUgPSBpdGVtc1swXS5jbG9uZU5vZGUodHJ1ZSk7CiAgICBjb25zdCBzZWNvbmRJdGVtQ2xvbmUgPSBpdGVtc1sxXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgcGVudWx0aW1hdGVJdGVtQ2xvbmUgPSBpdGVtc1tpdGVtcy5sZW5ndGggLSAyXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgbGFzdEl0ZW1DbG9uZSA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdLmNsb25lTm9kZSh0cnVlKTsKICAgIC8vIHdlIHJlbW92ZSB0aGVzZSBhdHRyaWJ1dGVzIGZyb20gdGhlIGNsb25lZCBpdGVtcyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gc2VuZCBldmVudHMgZm9yIHRoZSBjbG9uZWQgaXRlbXMKICAgIC8vIGJhbm5lciBjYXJvdXNlbCB1c2VzIGRhdGEtZXZlbnQgdG8gc2VuZCBldmVudHMgdG8gYW5hbHl0aWNzCiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBsYXN0SXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHBlbnVsdGltYXRlSXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuZmlyc3RFbGVtZW50Q2hpbGQ/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1ldmVudC10cmlnZ2VyIik7CiAgICBwZW51bHRpbWF0ZUl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgaXRlbXMubGVuZ3RoLnRvU3RyaW5nKCkpOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmU/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1zbGlkZXItaXRlbSIpOwogICAgZmlyc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgKGl0ZW1zLmxlbmd0aCArIDEpLnRvU3RyaW5nKCkpOwogICAgc2Vjb25kSXRlbUNsb25lPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKTsKICAgIHNsaWRlci5pbnNlcnRCZWZvcmUobGFzdEl0ZW1DbG9uZSwgaXRlbXNbMF0pOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmUgJiYgc2xpZGVyLmluc2VydEJlZm9yZShwZW51bHRpbWF0ZUl0ZW1DbG9uZSwgbGFzdEl0ZW1DbG9uZSk7CiAgICBzbGlkZXIuYXBwZW5kQ2hpbGQoZmlyc3RJdGVtQ2xvbmUpOwogICAgc2Vjb25kSXRlbUNsb25lICYmIHNsaWRlci5hcHBlbmRDaGlsZChzZWNvbmRJdGVtQ2xvbmUpOwogICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICB9CiAgY29uc3QgY3VycmVudEl0ZW1zID0gc2xpZGVyPy5xdWVyeVNlbGVjdG9yQWxsKGBsaWApOwogIGl0ZW1zLmZvckVhY2goKGl0ZW0pPT5vYnNlcnZlci5vYnNlcnZlKGl0ZW0pKTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgZnVsbE9ic2VydmVyLm9ic2VydmUoY3VycmVudEl0ZW1zWzFdKTsKICAgIGZ1bGxPYnNlcnZlci5vYnNlcnZlKGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pOwogIH0KICBpZiAocGFnZURvdHMpIHsKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCkubGVuZ3RoOwogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGNvbnN0IGRvdCA9IGRvdHM/Lml0ZW0oaXQpOwogICAgICBpZiAoIWRvdCkgY29udGludWU7CiAgICAgIGlmIChpdCAlIGl0ZW1zUGVyUGFnZSAhPT0gMCkgewogICAgICAgIGRvdC5jbGFzc0xpc3QuYWRkKCJoaWRkZW4iKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgICAgZG90LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKHNjcm9sbERvdHMpIHsKICAgIHVwZGF0ZVNjcm9sbERvdHMoKTsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5nb1RvU2Nyb2xsRG90KGl0KSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5pdGVtRG90cyA/IGdvVG9JdGVtRG90KGl0KSA6IGdvVG9JdGVtKGl0KSk7CiAgICB9CiAgfQogIHByZXY/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja1ByZXYpOwogIG5leHQ/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogIGlmIChzY3JvbGxEb3RzKSB7CiAgICBzbGlkZXIuc3R5bGUub3ZlcnNjcm9sbEJlaGF2aW9yWCA9ICJjb250YWluIjsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJzY3JvbGwiLCBub3JtYWxpemVTY3JvbGxCb3VuZHMsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2hzdGFydCIsIGhhbmRsZVRvdWNoU3RhcnQsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2htb3ZlIiwgaGFuZGxlVG91Y2hNb3ZlLCB7CiAgICAgIHBhc3NpdmU6IGZhbHNlCiAgICB9KTsKICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgfSBlbHNlIGlmIChwYWdlRG90cykgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZVBhZ2VEb3RzKTsKICB9IGVsc2UgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZUFjdGl2ZURvdCk7CiAgfQogIGNvbnN0IHRpbWVvdXQgPSBpbnRlcnZhbCAmJiBzZXRJbnRlcnZhbChvbkNsaWNrTmV4dCwgaW50ZXJ2YWwpOwogIGxldCBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXI7CiAgZnVuY3Rpb24gZW5hYmxlSG9yaXpvbnRhbFNjcm9sbCgpIHsKICAgIGlmICghc2xpZGVyKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGxldCBpc01vdXNlRG93biA9IGZhbHNlOwogICAgbGV0IHN0YXJ0WDsKICAgIGxldCBzY3JvbGxMZWZ0OwogICAgbGV0IHZlbG9jaXR5ID0gMDsKICAgIGxldCBtb21lbnR1bUZyYW1lOwogICAgY29uc3QgbW9tZW50dW1TY3JvbGwgPSAoKT0+ewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCArPSB2ZWxvY2l0eTsKICAgICAgdmVsb2NpdHkgKj0gMC45NTsKICAgICAgaWYgKE1hdGguYWJzKHZlbG9jaXR5KSA+IDAuMSkgewogICAgICAgIG1vbWVudHVtRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUobW9tZW50dW1TY3JvbGwpOwogICAgICB9CiAgICB9OwogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlZG93biIsIChlKT0+ewogICAgICBpc01vdXNlRG93biA9IHRydWU7CiAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAiZ3JhYmJpbmciOwogICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAiaW5pdGlhbCI7CiAgICAgIHN0YXJ0WCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgc2Nyb2xsTGVmdCA9IHNsaWRlci5zY3JvbGxMZWZ0OwogICAgICB2ZWxvY2l0eSA9IDA7CiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtRnJhbWUpOwogICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICB9KTsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWxlYXZlIiwgKCk9PnsKICAgICAgaWYgKGlzTW91c2VEb3duKSB7CiAgICAgICAgaXNNb3VzZURvd24gPSBmYWxzZTsKICAgICAgICBzbGlkZXIuZGF0YXNldFsiZHJhZ2dpbmciXSA9ICJmYWxzZSI7CiAgICAgICAgc2xpZGVyLnN0eWxlLmN1cnNvciA9ICJncmFiIjsKICAgICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAic21vb3RoIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2V1cCIsICgpPT57CiAgICAgIGlmIChpc01vdXNlRG93bikgewogICAgICAgIGlzTW91c2VEb3duID0gZmFsc2U7CiAgICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAiZmFsc2UiOwogICAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAibm9ybWFsIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2Vtb3ZlIiwgKGUpPT57CiAgICAgIGlmICghaXNNb3VzZURvd24pIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29uc3QgeCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgY29uc3Qgd2FsayA9ICh4IC0gc3RhcnRYKSAqIDAuNTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBzY3JvbGxMZWZ0IC0gd2FsazsKICAgICAgdmVsb2NpdHkgPSAtd2FsayAqIDAuMjsKICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAidHJ1ZSI7CiAgICB9KTsKICB9CiAgaWYgKGRlc2t0b3BEcmFnZ2FibGUpIHsKICAgIHNsaWRlci5kYXRhc2V0WyJkcmFnZ2FibGUiXSA9ICJ0cnVlIjsKICAgIGVuYWJsZUhvcml6b250YWxTY3JvbGwoKTsKICB9CiAgaWYgKHNjcm9sbERvdHMgJiYgIlJlc2l6ZU9ic2VydmVyIiBpbiBnbG9iYWxUaGlzKSB7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIodXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShzbGlkZXIpOwogIH0KICAvLyBVbnJlZ2lzdGVyIGNhbGxiYWNrcwogIHJldHVybiAoKT0+ewogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGRvdHM/Lml0ZW0oaXQpLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICB9CiAgICBwcmV2Py5yZW1vdmVFdmVudExpc3RlbmVyKCJjbGljayIsIG9uQ2xpY2tQcmV2KTsKICAgIG5leHQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogICAgaWYgKHNjcm9sbERvdHMpIHsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcyk7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVTY3JvbGxEb3RzKTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNoc3RhcnQiLCBoYW5kbGVUb3VjaFN0YXJ0KTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNobW92ZSIsIGhhbmRsZVRvdWNoTW92ZSk7CiAgICAgIGdsb2JhbFRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICB9IGVsc2UgaWYgKHBhZ2VEb3RzKSB7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVQYWdlRG90cyk7CiAgICB9IGVsc2UgewogICAgICBzbGlkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlQWN0aXZlRG90KTsKICAgIH0KICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTsKICAgIHNjcm9sbERvdHNSZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpOwogICAgY2xlYXJJbnRlcnZhbCh0aW1lb3V0KTsKICB9Owp9KSh7InJvb3RJZCI6Im5tUDAzMTI0MjMwMjUtc2xpZGVyLTQiLCJvbmVCeW9uZSI6dHJ1ZSwic2Nyb2xsRG90cyI6dHJ1ZSwiZGVza3RvcERyYWdnYWJsZSI6ZmFsc2V9KSkp | |
| js | data:text/javascript;base64,ZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZSgoKHsgcm9vdElkLCBzY3JvbGwgPSAic21vb3RoIiwgaW50ZXJ2YWwsIGluZmluaXRlLCBvbmVCeW9uZSwgaXRlbURvdHMsIHBhZ2VEb3RzLCBzY3JvbGxEb3RzLCBpc0Zyb21Ib29rID0gZmFsc2UsIGRlc2t0b3BEcmFnZ2FibGUgPSBmYWxzZSB9KT0+ewogIGNvbnN0IEFUVFJJQlVURVMgPSBpc0Zyb21Ib29rIC8vIHRoaXMgaXMgdXNlZCB0byBrZWVwIGNvbXBhdGliaWxpdHkgdG8gdGhlIG9sZCB3YXkgdG8gY3JlYXRlIGEgc2xpZGVyCiAgID8gewogICAgImRhdGEtc2xpZGVyIjogYFtkYXRhLXNsaWRlcl1bZGF0YS1yb290PSR7cm9vdElkfV1gLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiBgW2RhdGEtc2xpZGVyLWl0ZW1dW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6IGBbZGF0YS1zbGlkZT0icHJldiJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6IGBbZGF0YS1zbGlkZT0ibmV4dCJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLWRvdCI6IGBbZGF0YS1kb3RdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLXByb2dyZXNzIjogYFtkYXRhLXByb2dyZXNzXVtkYXRhLXJvb3Q9JHtyb290SWR9XWAKICB9IDogewogICAgImRhdGEtc2xpZGVyIjogIltkYXRhLXNsaWRlcl0iLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiAiW2RhdGEtc2xpZGVyLWl0ZW1dIiwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6ICdbZGF0YS1zbGlkZT0icHJldiJdJywKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6ICdbZGF0YS1zbGlkZT0ibmV4dCJdJywKICAgICJkYXRhLWRvdCI6ICJbZGF0YS1kb3RdIiwKICAgICJkYXRhLXByb2dyZXNzIjogIltkYXRhLXByb2dyZXNzXSIKICB9OwogIC8vIFBlcmNlbnRhZ2Ugb2YgdGhlIGl0ZW0gdGhhdCBoYXMgdG8gYmUgaW5zaWRlIHRoZSBjb250YWluZXIKICAvLyBmb3IgaXQgaXQgYmUgY29uc2lkZXJlZCBhcyBpbnNpZGUgdGhlIGNvbnRhaW5lcgogIGNvbnN0IFRIUkVTSE9MRCA9IDAuNzU7CiAgY29uc3QgVVNFX0lORklOSVRFX0JFSEFWSU9VUiA9IHRydWU7CiAgY29uc3QgaW50ZXJzZWN0aW9uWCA9IChlbGVtZW50LCBjb250YWluZXIpPT57CiAgICBjb25zdCBkZWx0YSA9IGNvbnRhaW5lci53aWR0aCAvIDFfMDAwOwogICAgaWYgKGVsZW1lbnQucmlnaHQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiAwLjA7CiAgICB9CiAgICBpZiAoZWxlbWVudC5sZWZ0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIDAuMDsKICAgIH0KICAgIGlmIChlbGVtZW50LmxlZnQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiBlbGVtZW50LnJpZ2h0IC0gY29udGFpbmVyLmxlZnQgKyBkZWx0YTsKICAgIH0KICAgIGlmIChlbGVtZW50LnJpZ2h0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIGNvbnRhaW5lci5yaWdodCAtIGVsZW1lbnQubGVmdCArIGRlbHRhOwogICAgfQogICAgcmV0dXJuIGVsZW1lbnQud2lkdGg7CiAgfTsKICAvLyBhcyBhbnkgYXJlIG9rIGluIHR5cGVndWFyZCBmdW5jdGlvbnMKICBjb25zdCBpc0hUTUxFbGVtZW50ID0gKHgpPT4vLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueQogICAgdHlwZW9mIHgub2Zmc2V0TGVmdCA9PT0gIm51bWJlciI7CiAgY29uc3Qgcm9vdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHJvb3RJZCkgPz8gZG9jdW1lbnQuY3VycmVudFNjcmlwdD8ucGFyZW50RWxlbWVudCA/PyBudWxsOwogIGNvbnN0IHNsaWRlciA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1zbGlkZXIiXSk7CiAgY29uc3QgaXRlbXMgPSBzbGlkZXI/LnF1ZXJ5U2VsZWN0b3JBbGwoQVRUUklCVVRFU1siZGF0YS1zbGlkZXItaXRlbSJdKTsKICBjb25zdCBwcmV2ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJwcmV2IiddKTsKICBjb25zdCBuZXh0ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJuZXh0IiddKTsKICBjb25zdCBkb3RzID0gcm9vdD8ucXVlcnlTZWxlY3RvckFsbChBVFRSSUJVVEVTWyJkYXRhLWRvdCJdKTsKICBjb25zdCBwcm9ncmVzcyA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1wcm9ncmVzcyJdKTsKICBpZiAoIXJvb3QgfHwgIXNsaWRlciB8fCAhaXRlbXMgfHwgaXRlbXMubGVuZ3RoID09PSAwKSB7CiAgICBjb25zb2xlLndhcm4oIk1pc3NpbmcgbmVjZXNzYXJ5IHNsaWRlciBhdHRyaWJ1dGVzLiBJdCB3aWxsIG5vdCB3b3JrIGFzIGludGVuZGVkLiBOZWNlc3NhcnkgZWxlbWVudHM6IiwgewogICAgICByb290LAogICAgICBzbGlkZXIsCiAgICAgIGl0ZW1zLAogICAgICByb290SWQKICAgIH0pOwogICAgcmV0dXJuOwogIH0KICBjb25zdCBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lciA9ICgpPT57CiAgICBjb25zdCBpbmRpY2VzID0gW107CiAgICBjb25zdCBzbGlkZXJSZWN0ID0gc2xpZGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaXRlbXMubGVuZ3RoOyBpbmRleCsrKXsKICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zLml0ZW0oaW5kZXgpOwogICAgICBjb25zdCByZWN0ID0gaXRlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgY29uc3QgcmF0aW8gPSBpbnRlcnNlY3Rpb25YKHJlY3QsIHNsaWRlclJlY3QpIC8gcmVjdC53aWR0aDsKICAgICAgaWYgKHJhdGlvID4gVEhSRVNIT0xEKSB7CiAgICAgICAgaW5kaWNlcy5wdXNoKGluZGV4KTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGluZGljZXM7CiAgfTsKICBjb25zdCBlbGVtZW50c0luc2lkZUNvbnRhaW5lciA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgY29uc3QgaW5maW5pdGVCZWhhdmlvciA9ICFzY3JvbGxEb3RzICYmIGluZmluaXRlICYmIGVsZW1lbnRzSW5zaWRlQ29udGFpbmVyLmxlbmd0aCA9PT0gMSAmJiBpdGVtcy5sZW5ndGggPiAxICYmIFVTRV9JTkZJTklURV9CRUhBVklPVVI7CiAgY29uc3QgZ2V0TWF4U2Nyb2xsTGVmdCA9ICgpPT5NYXRoLm1heCgwLCBzbGlkZXIuc2Nyb2xsV2lkdGggLSBzbGlkZXIuY2xpZW50V2lkdGgpOwogIGNvbnN0IGNsYW1wU2Nyb2xsTGVmdCA9IChsZWZ0KT0+TWF0aC5taW4oTWF0aC5tYXgobGVmdCwgMCksIGdldE1heFNjcm9sbExlZnQoKSk7CiAgY29uc3QgZ2V0SXRlbVNjcm9sbExlZnQgPSAoaXRlbSk9PnsKICAgIGlmICghaXNIVE1MRWxlbWVudChpdGVtKSkgcmV0dXJuIDA7CiAgICByZXR1cm4gY2xhbXBTY3JvbGxMZWZ0KGl0ZW0ub2Zmc2V0TGVmdCAtIHNsaWRlci5vZmZzZXRMZWZ0KTsKICB9OwogIGxldCBzY3JvbGxEb3RQb3NpdGlvbnMgPSBbXTsKICBjb25zdCBnZXRTY3JvbGxEb3RQb3NpdGlvbnMgPSAoKT0+ewogICAgaWYgKCFzY3JvbGxEb3RzKSByZXR1cm4gW107CiAgICBpZiAoc2xpZGVyLmNsaWVudFdpZHRoIDw9IDApIHsKICAgICAgcmV0dXJuIHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggPyBzY3JvbGxEb3RQb3NpdGlvbnMgOiBbCiAgICAgICAgMAogICAgICBdOwogICAgfQogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHJldHVybiBbCiAgICAgIDAKICAgIF07CiAgICBjb25zdCB2aXNpYmxlSXRlbXMgPSBNYXRoLm1heChnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpLmxlbmd0aCwgMSk7CiAgICBjb25zdCBwb3NpdGlvbnMgPSBbCiAgICAgIDAKICAgIF07CiAgICBmb3IobGV0IGluZGV4ID0gdmlzaWJsZUl0ZW1zOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXggKz0gdmlzaWJsZUl0ZW1zKXsKICAgICAgcG9zaXRpb25zLnB1c2goZ2V0SXRlbVNjcm9sbExlZnQoaXRlbXMuaXRlbShpbmRleCkpKTsKICAgIH0KICAgIHBvc2l0aW9ucy5wdXNoKG1heFNjcm9sbExlZnQpOwogICAgcmV0dXJuIHBvc2l0aW9ucy5yZWR1Y2UoKGFjYywgcG9zaXRpb24pPT57CiAgICAgIGNvbnN0IHJvdW5kZWRQb3NpdGlvbiA9IE1hdGgucm91bmQoY2xhbXBTY3JvbGxMZWZ0KHBvc2l0aW9uKSk7CiAgICAgIGNvbnN0IGxhc3RQb3NpdGlvbiA9IGFjY1thY2MubGVuZ3RoIC0gMV07CiAgICAgIGlmIChsYXN0UG9zaXRpb24gPT09IHVuZGVmaW5lZCB8fCBNYXRoLmFicyhsYXN0UG9zaXRpb24gLSByb3VuZGVkUG9zaXRpb24pID4gMSkgewogICAgICAgIGFjYy5wdXNoKHJvdW5kZWRQb3NpdGlvbik7CiAgICAgIH0KICAgICAgcmV0dXJuIGFjYzsKICAgIH0sIFtdKTsKICB9OwogIGNvbnN0IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCA9ICgpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIHNjcm9sbERvdFBvc2l0aW9ucy5mb3JFYWNoKChwb3NpdGlvbiwgaW5kZXgpPT57CiAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnMoc2xpZGVyLnNjcm9sbExlZnQgLSBwb3NpdGlvbik7CiAgICAgIGlmIChkaXN0YW5jZSA8IHNtYWxsZXN0RGlzdGFuY2UpIHsKICAgICAgICBzbWFsbGVzdERpc3RhbmNlID0gZGlzdGFuY2U7CiAgICAgICAgYWN0aXZlSW5kZXggPSBpbmRleDsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gYWN0aXZlSW5kZXg7CiAgfTsKICBjb25zdCB1cGRhdGVTY3JvbGxEb3RzID0gKCk9PnsKICAgIGlmICghc2Nyb2xsRG90cyB8fCAhZG90cykgcmV0dXJuOwogICAgc2Nyb2xsRG90UG9zaXRpb25zID0gZ2V0U2Nyb2xsRG90UG9zaXRpb25zKCk7CiAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90LCBpbmRleCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIGlmIChpbmRleCA+PSBzY3JvbGxEb3RQb3NpdGlvbnMubGVuZ3RoKSB7CiAgICAgICAgZG90LmNsYXNzTGlzdC5hZGQoImhpZGRlbiIpOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgIGlmIChpbmRleCA9PT0gYWN0aXZlSW5kZXgpIHsKICAgICAgICBkb3Quc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgIH0KICAgIH0pOwogICAgaWYgKCFpbmZpbml0ZSkgewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxID8gcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKSA6IHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPj0gbWF4U2Nyb2xsTGVmdCAtIDEgPyBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpIDogbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgfQogIH07CiAgY29uc3QgZ29Ub1Njcm9sbERvdCA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGNvbnN0IHBvc2l0aW9uID0gc2Nyb2xsRG90UG9zaXRpb25zW2luZGV4XTsKICAgIGlmIChwb3NpdGlvbiA9PT0gdW5kZWZpbmVkKSByZXR1cm47CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBwb3NpdGlvbgogICAgfSk7CiAgfTsKICBjb25zdCBub3JtYWxpemVTY3JvbGxCb3VuZHMgPSAoKT0+ewogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA+IG1heFNjcm9sbExlZnQpIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBtYXhTY3JvbGxMZWZ0OwogICAgfSBlbHNlIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA8IDApIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSAwOwogICAgfQogIH07CiAgbGV0IHRvdWNoU3RhcnRYID0gMDsKICBsZXQgdG91Y2hTdGFydFkgPSAwOwogIGNvbnN0IGhhbmRsZVRvdWNoU3RhcnQgPSAoZXZlbnQpPT57CiAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07CiAgICBpZiAoIXRvdWNoKSByZXR1cm47CiAgICB0b3VjaFN0YXJ0WCA9IHRvdWNoLmNsaWVudFg7CiAgICB0b3VjaFN0YXJ0WSA9IHRvdWNoLmNsaWVudFk7CiAgfTsKICBjb25zdCBoYW5kbGVUb3VjaE1vdmUgPSAoZXZlbnQpPT57CiAgICBpZiAoIXNjcm9sbERvdHMpIHJldHVybjsKICAgIGNvbnN0IHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTsKICAgIGlmICghdG91Y2gpIHJldHVybjsKICAgIGNvbnN0IGRlbHRhWCA9IHRvdWNoLmNsaWVudFggLSB0b3VjaFN0YXJ0WDsKICAgIGNvbnN0IGRlbHRhWSA9IHRvdWNoLmNsaWVudFkgLSB0b3VjaFN0YXJ0WTsKICAgIGNvbnN0IGlzSG9yaXpvbnRhbEdlc3R1cmUgPSBNYXRoLmFicyhkZWx0YVgpID4gTWF0aC5hYnMoZGVsdGFZKTsKICAgIGlmICghaXNIb3Jpem9udGFsR2VzdHVyZSkgcmV0dXJuOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHsKICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcygpOwogICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdCBpc0F0U3RhcnQgPSBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxOwogICAgY29uc3QgaXNBdEVuZCA9IHNsaWRlci5zY3JvbGxMZWZ0ID49IG1heFNjcm9sbExlZnQgLSAxOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RTdGFydCA9IGlzQXRTdGFydCAmJiBkZWx0YVggPiAwOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RFbmQgPSBpc0F0RW5kICYmIGRlbHRhWCA8IDA7CiAgICBpZiAoaXNEcmFnZ2luZ1Bhc3RTdGFydCB8fCBpc0RyYWdnaW5nUGFzdEVuZCkgewogICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgbm9ybWFsaXplU2Nyb2xsQm91bmRzKCk7CiAgICB9CiAgfTsKICBjb25zdCBnb1RvSXRlbSA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBjb25zdCBpdGVtID0gc2xpZGVyLnF1ZXJ5U2VsZWN0b3IoYGxpW2RhdGEtcm9vdD0nJHtyb290SWR9J11bZGF0YS1zbGlkZXItaXRlbT0nJHtpbmRleH0nXWApID8/IHNsaWRlci5xdWVyeVNlbGVjdG9yKGBsaVtkYXRhLXNsaWRlci1pdGVtPScke2luZGV4fSddYCk7CiAgICBpZiAoaXRlbSkgewogICAgICBpZiAoIWlzSFRNTEVsZW1lbnQoaXRlbSkpIHsKICAgICAgICBjb25zb2xlLndhcm4oYEVsZW1lbnQgYXQgaW5kZXggJHtpbmRleH0gaXMgbm90IGFuIGh0bWwgZWxlbWVudC4gU2tpcHBpbmcgY2Fyb3VzZWxgKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgc2xpZGVyLnNjcm9sbFRvKHsKICAgICAgICB0b3A6IDAsCiAgICAgICAgYmVoYXZpb3I6IGJlaGF2aW9yLAogICAgICAgIGxlZnQ6IGl0ZW0ub2Zmc2V0TGVmdCAtIHJvb3Qub2Zmc2V0TGVmdAogICAgICB9KTsKICAgIH0KICB9OwogIGNvbnN0IGdvVG9JdGVtRG90ID0gKGluZGV4LCBiZWhhdmlvciA9IHNjcm9sbCk9PnsKICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgIGlmICghaXRlbSkgcmV0dXJuOwogICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSB7CiAgICAgIGNvbnNvbGUud2FybihgRWxlbWVudCBhdCBpbmRleCAke2luZGV4fSBpcyBub3QgYW4gaHRtbCBlbGVtZW50LiBTa2lwcGluZyBjYXJvdXNlbGApOwogICAgICByZXR1cm47CiAgICB9CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdAogICAgfSk7CiAgfTsKICBjb25zdCBnZXROZWFyZXN0SXRlbUluZGV4ID0gKCk9PnsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIGZvcihsZXQgaW5kZXggPSAwOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXgrKyl7CiAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSBjb250aW51ZTsKICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLmFicyhzbGlkZXIuc2Nyb2xsTGVmdCAtIChpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdCkpOwogICAgICBpZiAoZGlzdGFuY2UgPCBzbWFsbGVzdERpc3RhbmNlKSB7CiAgICAgICAgc21hbGxlc3REaXN0YW5jZSA9IGRpc3RhbmNlOwogICAgICAgIGFjdGl2ZUluZGV4ID0gaW5kZXg7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBhY3RpdmVJbmRleDsKICB9OwogIGNvbnN0IG9uQ2xpY2tQcmV2ID0gKCk9PnsKICAgIGlmIChzY3JvbGxEb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdFNjcm9sbERvdEluZGV4KCk7CiAgICAgIGFjdGl2ZUluZGV4ID09PSAwID8gaW5maW5pdGUgPyBnb1RvU2Nyb2xsRG90KHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggLSAxKSA6IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChpdGVtRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RJdGVtSW5kZXgoKTsKICAgICAgYWN0aXZlSW5kZXggPT09IDAgPyBpbmZpbml0ZSA/IGdvVG9JdGVtRG90KGl0ZW1zLmxlbmd0aCAtIDEpIDogbnVsbCA6IGdvVG9JdGVtRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIFdvdyEgaXRlbXMgcGVyIHBhZ2UgaXMgaG93IG1hbnkgZWxlbWVudHMgYXJlIGJlaW5nIGRpc3BsYXllZCBpbnNpZGUgdGhlIGNvbnRhaW5lciEhCiAgICBjb25zdCBpdGVtc1BlclBhZ2UgPSBpbmRpY2VzLmxlbmd0aDsKICAgIGNvbnN0IGlzU2hvd2luZ0ZpcnN0ID0gaW5kaWNlc1swXSA9PT0gMDsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdIC8gaXRlbXNQZXJQYWdlKTsKICAgIGlmIChvbmVCeW9uZSkgewogICAgICBpc1Nob3dpbmdGaXJzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oaXRlbXMubGVuZ3RoIC0gMSkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSAtIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nRmlyc3QgPyBpbmZpbml0ZUJlaGF2aW9yID8gaXRlbXMubGVuZ3RoIDogaXRlbXMubGVuZ3RoIC0gMSA6IChwYWdlSW5kZXggLSAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCBvbkNsaWNrTmV4dCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gc2Nyb2xsRG90UG9zaXRpb25zLmxlbmd0aCAtIDEgPyBpbmZpbml0ZSA/IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4KSA6IGdvVG9TY3JvbGxEb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGl0ZW1Eb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdEl0ZW1JbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gaXRlbXMubGVuZ3RoIC0gMSA/IGluZmluaXRlID8gZ29Ub0l0ZW1Eb3QoMCkgOiBudWxsIDogZ29Ub0l0ZW1Eb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgaW5kaWNlcyA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgICBpZiAoaW5kaWNlcy5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgLy8gV293ISBpdGVtcyBwZXIgcGFnZSBpcyBob3cgbWFueSBlbGVtZW50cyBhcmUgYmVpbmcgZGlzcGxheWVkIGluc2lkZSB0aGUgY29udGFpbmVyISEKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGluZGljZXMubGVuZ3RoOwogICAgY29uc3QgaXNTaG93aW5nTGFzdCA9IGluZGljZXNbaW5kaWNlcy5sZW5ndGggLSAxXSA9PT0gaXRlbXMubGVuZ3RoIC0gMTsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1swXSAvIGl0ZW1zUGVyUGFnZSk7CiAgICAvLyBnb1RvSXRlbShpc1Nob3dpbmdMYXN0ID8gMCA6IChpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICBpZiAob25lQnlvbmUpIHsKICAgICAgaXNTaG93aW5nTGFzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oMCkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSArIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nTGFzdCA/IGluZmluaXRlQmVoYXZpb3IgPyBpdGVtcy5sZW5ndGggKyAxIDogMCA6IChwYWdlSW5kZXggKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCB1cGRhdGVQYWdlRG90cyA9ICgpPT57CiAgICBpZiAoIXBhZ2VEb3RzIHx8ICFkb3RzKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IE1hdGgubWF4KGluZGljZXMubGVuZ3RoLCAxKTsKICAgIGNvbnN0IG1heFZpc2libGUgPSBNYXRoLm1heCguLi5pbmRpY2VzKTsKICAgIGNvbnN0IHBhZ2VEb3RJbmRleCA9IE1hdGguZmxvb3IobWF4VmlzaWJsZSAvIGl0ZW1zUGVyUGFnZSkgKiBpdGVtc1BlclBhZ2U7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCwgaSk9PnsKICAgICAgaWYgKGkgJSBpdGVtc1BlclBhZ2UgIT09IDApIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShwYWdlRG90SW5kZXgpOwogICAgaWYgKGFjdGl2ZURvdCkgewogICAgICBBcnJheS5mcm9tKGRvdHMpLmZpbHRlcigoX2RvdCwgaSk9PmkgPCBwYWdlRG90SW5kZXggJiYgaSAlIGl0ZW1zUGVyUGFnZSA9PT0gMCkuZm9yRWFjaCgoZG90KT0+ZG90LnNldEF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIiwgInRydWUiKSk7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IHVwZGF0ZUFjdGl2ZURvdCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICB1cGRhdGVTY3JvbGxEb3RzKCk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChwYWdlRG90cyB8fCAhZG90cykgewogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoaXRlbURvdHMpIHsKICAgICAgY29uc3QgYWN0aXZlSW5kZXggPSBnZXROZWFyZXN0SXRlbUluZGV4KCk7CiAgICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90KT0+ewogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtcGFpbnRlZCIpOwogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIH0pOwogICAgICBjb25zdCBhY3RpdmVEb3QgPSBkb3RzLml0ZW0oYWN0aXZlSW5kZXgpOwogICAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgICAgYWN0aXZlRG90LnNldEF0dHJpYnV0ZSgiZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gTWF0aC5taW4oLi4uaW5kaWNlcyk7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShhY3RpdmVJbmRleCk7CiAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGlmIChwYWdlRG90cykgewogICAgICB1cGRhdGVQYWdlRG90cygpOwogICAgfSBlbHNlIHsKICAgICAgdXBkYXRlQWN0aXZlRG90KCk7CiAgICB9CiAgICBlbGVtZW50cy5mb3JFYWNoKChpdGVtKT0+ewogICAgICBjb25zdCBpbmRleCA9IE51bWJlcihpdGVtLnRhcmdldC5nZXRBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKSkgfHwgMDsKICAgICAgaWYgKCFpbmZpbml0ZSAmJiAhc2Nyb2xsRG90cykgewogICAgICAgIGlmIChpbmRleCA9PT0gMCkgewogICAgICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcpIHsKICAgICAgICAgICAgcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGluZGV4ID09PSBpdGVtcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICBpZiAoaXRlbS5pc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocHJvZ3Jlc3MpIHsKICAgICAgICAgIGlmIChwcm9ncmVzcy5pZCA9PSAiMCIgJiYgaW5kZXggPT09IGl0ZW1zLmxlbmd0aCAtIDEpIHsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUuaGVpZ2h0ID0gYCR7MSAvIGl0ZW1zLmxlbmd0aCAqIDEwMH0lYDsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUud2lkdGggPSBgJHsxIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5pZCA9ICIxIjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByb2dyZXNzLnN0eWxlLmhlaWdodCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5zdHlsZS53aWR0aCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfSwgewogICAgdGhyZXNob2xkOiBUSFJFU0hPTEQsCiAgICByb290OiBzbGlkZXIsCiAgICByb290TWFyZ2luOiAiMTAwcHgiCiAgfSk7CiAgY29uc3QgZnVsbE9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGVsZW1lbnRzLmZvckVhY2goKGl0ZW0pPT57CiAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IHNsaWRlcj8ucXVlcnlTZWxlY3RvckFsbChgbGlgKTsKICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcgJiYgZWxlbWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT0gY3VycmVudEl0ZW1zWzFdKSB7CiAgICAgICAgICBzZXRUaW1lb3V0KCgpPT57CiAgICAgICAgICAgIGdvVG9JdGVtKGl0ZW1zLmxlbmd0aCAtIDEsICJpbnN0YW50Iik7CiAgICAgICAgICB9LCAyMDApOwogICAgICAgIH0KICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT09IGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pIHsKICAgICAgICAgIHNldFRpbWVvdXQoKCk9PnsKICAgICAgICAgICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICAgICAgICAgIH0sIDIwMCk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9LCB7CiAgICB0aHJlc2hvbGQ6IDAuNywKICAgIHJvb3Q6IHNsaWRlciwKICAgIHJvb3RNYXJnaW46ICIxMDBweCIKICB9KTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgY29uc3QgZmlyc3RJdGVtQ2xvbmUgPSBpdGVtc1swXS5jbG9uZU5vZGUodHJ1ZSk7CiAgICBjb25zdCBzZWNvbmRJdGVtQ2xvbmUgPSBpdGVtc1sxXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgcGVudWx0aW1hdGVJdGVtQ2xvbmUgPSBpdGVtc1tpdGVtcy5sZW5ndGggLSAyXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgbGFzdEl0ZW1DbG9uZSA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdLmNsb25lTm9kZSh0cnVlKTsKICAgIC8vIHdlIHJlbW92ZSB0aGVzZSBhdHRyaWJ1dGVzIGZyb20gdGhlIGNsb25lZCBpdGVtcyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gc2VuZCBldmVudHMgZm9yIHRoZSBjbG9uZWQgaXRlbXMKICAgIC8vIGJhbm5lciBjYXJvdXNlbCB1c2VzIGRhdGEtZXZlbnQgdG8gc2VuZCBldmVudHMgdG8gYW5hbHl0aWNzCiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBsYXN0SXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHBlbnVsdGltYXRlSXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuZmlyc3RFbGVtZW50Q2hpbGQ/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1ldmVudC10cmlnZ2VyIik7CiAgICBwZW51bHRpbWF0ZUl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgaXRlbXMubGVuZ3RoLnRvU3RyaW5nKCkpOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmU/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1zbGlkZXItaXRlbSIpOwogICAgZmlyc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgKGl0ZW1zLmxlbmd0aCArIDEpLnRvU3RyaW5nKCkpOwogICAgc2Vjb25kSXRlbUNsb25lPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKTsKICAgIHNsaWRlci5pbnNlcnRCZWZvcmUobGFzdEl0ZW1DbG9uZSwgaXRlbXNbMF0pOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmUgJiYgc2xpZGVyLmluc2VydEJlZm9yZShwZW51bHRpbWF0ZUl0ZW1DbG9uZSwgbGFzdEl0ZW1DbG9uZSk7CiAgICBzbGlkZXIuYXBwZW5kQ2hpbGQoZmlyc3RJdGVtQ2xvbmUpOwogICAgc2Vjb25kSXRlbUNsb25lICYmIHNsaWRlci5hcHBlbmRDaGlsZChzZWNvbmRJdGVtQ2xvbmUpOwogICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICB9CiAgY29uc3QgY3VycmVudEl0ZW1zID0gc2xpZGVyPy5xdWVyeVNlbGVjdG9yQWxsKGBsaWApOwogIGl0ZW1zLmZvckVhY2goKGl0ZW0pPT5vYnNlcnZlci5vYnNlcnZlKGl0ZW0pKTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgZnVsbE9ic2VydmVyLm9ic2VydmUoY3VycmVudEl0ZW1zWzFdKTsKICAgIGZ1bGxPYnNlcnZlci5vYnNlcnZlKGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pOwogIH0KICBpZiAocGFnZURvdHMpIHsKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCkubGVuZ3RoOwogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGNvbnN0IGRvdCA9IGRvdHM/Lml0ZW0oaXQpOwogICAgICBpZiAoIWRvdCkgY29udGludWU7CiAgICAgIGlmIChpdCAlIGl0ZW1zUGVyUGFnZSAhPT0gMCkgewogICAgICAgIGRvdC5jbGFzc0xpc3QuYWRkKCJoaWRkZW4iKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgICAgZG90LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKHNjcm9sbERvdHMpIHsKICAgIHVwZGF0ZVNjcm9sbERvdHMoKTsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5nb1RvU2Nyb2xsRG90KGl0KSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5pdGVtRG90cyA/IGdvVG9JdGVtRG90KGl0KSA6IGdvVG9JdGVtKGl0KSk7CiAgICB9CiAgfQogIHByZXY/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja1ByZXYpOwogIG5leHQ/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogIGlmIChzY3JvbGxEb3RzKSB7CiAgICBzbGlkZXIuc3R5bGUub3ZlcnNjcm9sbEJlaGF2aW9yWCA9ICJjb250YWluIjsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJzY3JvbGwiLCBub3JtYWxpemVTY3JvbGxCb3VuZHMsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2hzdGFydCIsIGhhbmRsZVRvdWNoU3RhcnQsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2htb3ZlIiwgaGFuZGxlVG91Y2hNb3ZlLCB7CiAgICAgIHBhc3NpdmU6IGZhbHNlCiAgICB9KTsKICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgfSBlbHNlIGlmIChwYWdlRG90cykgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZVBhZ2VEb3RzKTsKICB9IGVsc2UgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZUFjdGl2ZURvdCk7CiAgfQogIGNvbnN0IHRpbWVvdXQgPSBpbnRlcnZhbCAmJiBzZXRJbnRlcnZhbChvbkNsaWNrTmV4dCwgaW50ZXJ2YWwpOwogIGxldCBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXI7CiAgZnVuY3Rpb24gZW5hYmxlSG9yaXpvbnRhbFNjcm9sbCgpIHsKICAgIGlmICghc2xpZGVyKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGxldCBpc01vdXNlRG93biA9IGZhbHNlOwogICAgbGV0IHN0YXJ0WDsKICAgIGxldCBzY3JvbGxMZWZ0OwogICAgbGV0IHZlbG9jaXR5ID0gMDsKICAgIGxldCBtb21lbnR1bUZyYW1lOwogICAgY29uc3QgbW9tZW50dW1TY3JvbGwgPSAoKT0+ewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCArPSB2ZWxvY2l0eTsKICAgICAgdmVsb2NpdHkgKj0gMC45NTsKICAgICAgaWYgKE1hdGguYWJzKHZlbG9jaXR5KSA+IDAuMSkgewogICAgICAgIG1vbWVudHVtRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUobW9tZW50dW1TY3JvbGwpOwogICAgICB9CiAgICB9OwogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlZG93biIsIChlKT0+ewogICAgICBpc01vdXNlRG93biA9IHRydWU7CiAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAiZ3JhYmJpbmciOwogICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAiaW5pdGlhbCI7CiAgICAgIHN0YXJ0WCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgc2Nyb2xsTGVmdCA9IHNsaWRlci5zY3JvbGxMZWZ0OwogICAgICB2ZWxvY2l0eSA9IDA7CiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtRnJhbWUpOwogICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICB9KTsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWxlYXZlIiwgKCk9PnsKICAgICAgaWYgKGlzTW91c2VEb3duKSB7CiAgICAgICAgaXNNb3VzZURvd24gPSBmYWxzZTsKICAgICAgICBzbGlkZXIuZGF0YXNldFsiZHJhZ2dpbmciXSA9ICJmYWxzZSI7CiAgICAgICAgc2xpZGVyLnN0eWxlLmN1cnNvciA9ICJncmFiIjsKICAgICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAic21vb3RoIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2V1cCIsICgpPT57CiAgICAgIGlmIChpc01vdXNlRG93bikgewogICAgICAgIGlzTW91c2VEb3duID0gZmFsc2U7CiAgICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAiZmFsc2UiOwogICAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAibm9ybWFsIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2Vtb3ZlIiwgKGUpPT57CiAgICAgIGlmICghaXNNb3VzZURvd24pIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29uc3QgeCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgY29uc3Qgd2FsayA9ICh4IC0gc3RhcnRYKSAqIDAuNTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBzY3JvbGxMZWZ0IC0gd2FsazsKICAgICAgdmVsb2NpdHkgPSAtd2FsayAqIDAuMjsKICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAidHJ1ZSI7CiAgICB9KTsKICB9CiAgaWYgKGRlc2t0b3BEcmFnZ2FibGUpIHsKICAgIHNsaWRlci5kYXRhc2V0WyJkcmFnZ2FibGUiXSA9ICJ0cnVlIjsKICAgIGVuYWJsZUhvcml6b250YWxTY3JvbGwoKTsKICB9CiAgaWYgKHNjcm9sbERvdHMgJiYgIlJlc2l6ZU9ic2VydmVyIiBpbiBnbG9iYWxUaGlzKSB7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIodXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShzbGlkZXIpOwogIH0KICAvLyBVbnJlZ2lzdGVyIGNhbGxiYWNrcwogIHJldHVybiAoKT0+ewogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGRvdHM/Lml0ZW0oaXQpLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICB9CiAgICBwcmV2Py5yZW1vdmVFdmVudExpc3RlbmVyKCJjbGljayIsIG9uQ2xpY2tQcmV2KTsKICAgIG5leHQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogICAgaWYgKHNjcm9sbERvdHMpIHsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcyk7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVTY3JvbGxEb3RzKTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNoc3RhcnQiLCBoYW5kbGVUb3VjaFN0YXJ0KTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNobW92ZSIsIGhhbmRsZVRvdWNoTW92ZSk7CiAgICAgIGdsb2JhbFRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICB9IGVsc2UgaWYgKHBhZ2VEb3RzKSB7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVQYWdlRG90cyk7CiAgICB9IGVsc2UgewogICAgICBzbGlkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlQWN0aXZlRG90KTsKICAgIH0KICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTsKICAgIHNjcm9sbERvdHNSZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpOwogICAgY2xlYXJJbnRlcnZhbCh0aW1lb3V0KTsKICB9Owp9KSh7InJvb3RJZCI6Im5tUDAzMTI0MjMwMjUtc2xpZGVyLTUiLCJvbmVCeW9uZSI6dHJ1ZSwic2Nyb2xsRG90cyI6dHJ1ZSwiZGVza3RvcERyYWdnYWJsZSI6ZmFsc2V9KSkp | |
| js | data:text/javascript;base64,ZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZSgoKHN0YXJ0c0F0LCBleHBpcmVzQXQsIHJvb3RJZCwgaXNBYm92ZUhlYWRlcik9PnsKICBjb25zdCBnZXREZWx0YSA9IChleHBpcmF0aW9uRGF0ZSk9PnsKICAgIGNvbnN0IGRlbHRhID0gZXhwaXJhdGlvbkRhdGUgLSBuZXcgRGF0ZSgpLmdldFRpbWUoKTsKICAgIHJldHVybiB7CiAgICAgIGRheXM6IE1hdGguZmxvb3IoZGVsdGEgLyAoMTAwMCAqIDYwICogNjAgKiAyNCkpLAogICAgICBob3VyczogTWF0aC5mbG9vcihkZWx0YSAlICgxMDAwICogNjAgKiA2MCAqIDI0KSAvICgxMDAwICogNjAgKiA2MCkpLAogICAgICBtaW51dGVzOiBNYXRoLmZsb29yKGRlbHRhICUgKDEwMDAgKiA2MCAqIDYwKSAvICgxMDAwICogNjApKSwKICAgICAgc2Vjb25kczogTWF0aC5mbG9vcihkZWx0YSAlICgxMDAwICogNjApIC8gMTAwMCkKICAgIH07CiAgfTsKICBjb25zdCBzZXRWYWx1ZSA9IChpZCwgdmFsdWUpPT57CiAgICBjb25zdCBlbGVtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpOwogICAgaWYgKGVsZW0pIHsKICAgICAgZWxlbS5zdHlsZS5zZXRQcm9wZXJ0eSgiLS12YWx1ZSIsIHZhbHVlLnRvU3RyaW5nKCkpOwogICAgfQogIH07CiAgY29uc3Qgc3RhcnREYXRlID0gbmV3IERhdGUoc3RhcnRzQXQpLmdldFRpbWUoKTsKICBjb25zdCBleHBpcmF0aW9uRGF0ZSA9IG5ldyBEYXRlKGV4cGlyZXNBdCkuZ2V0VGltZSgpOwogIGNvbnN0IHVwZGF0ZUhlaWdodEFuZEFsZXJ0cyA9ICgpPT57CiAgICBjb25zdCBub3dDaGVjayA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpOwogICAgaWYgKG5vd0NoZWNrIDwgc3RhcnREYXRlKSByZXR1cm47CiAgICBjb25zdCB0aW1lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0aW1lci1jb250YWluZXIiKTsKICAgIGlmICh0aW1lciAmJiAhdGltZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCJoaWRkZW4iKSkgewogICAgICBjb25zdCBoID0gdGltZXIub2Zmc2V0SGVpZ2h0IHx8IHRpbWVyLmNsaWVudEhlaWdodCB8fCAwOwogICAgICBpZiAoaCA+IDApIHsKICAgICAgICBjb25zdCB2YWwgPSBoICsgInB4IjsKICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoIi0tdGltZXItaGVpZ2h0IiwgdmFsKTsKICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnNldFByb3BlcnR5KCItLXRpbWVyLWhlaWdodCIsIHZhbCk7CiAgICAgICAgZG9jdW1lbnQuYm9keS5zZXRBdHRyaWJ1dGUoImRhdGEtdGltZXItYWN0aXZlIiwgInRydWUiKTsKICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCIuYWxlcnQtY29tcG9uZW50IikuZm9yRWFjaChmdW5jdGlvbihlbCkgewogICAgICAgICAgY29uc3QgaHRtbEVsID0gZWw7CiAgICAgICAgICBpZiAoaHRtbEVsLnN0eWxlLmRpc3BsYXkgIT09ICJub25lIikgewogICAgICAgICAgICBodG1sRWwuc3R5bGUuc2V0UHJvcGVydHkoImRpc3BsYXkiLCAibm9uZSIsICJpbXBvcnRhbnQiKTsKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfQogICAgfQogIH07CiAgY29uc3Qgbm93U3RhcnQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTsKICBjb25zdCBpbml0aWFsVGltZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidGltZXItY29udGFpbmVyIik7CiAgaWYgKG5vd1N0YXJ0IDwgc3RhcnREYXRlICYmIGluaXRpYWxUaW1lcikgewogICAgaWYgKCFpbml0aWFsVGltZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCJoaWRkZW4iKSkgewogICAgICBpbml0aWFsVGltZXIuY2xhc3NMaXN0LmFkZCgiaGlkZGVuIik7CiAgICB9CiAgICBpbml0aWFsVGltZXIuY2xhc3NMaXN0LnJlbW92ZSgiY2FtcGFpZ24tdGltZXItYWJvdmUtaGVhZGVyIik7CiAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS10aW1lci1hY3RpdmUiKTsKICB9CiAgbGV0IG9ic2VydmVyQXR0YWNoZWQgPSBmYWxzZTsKICBjb25zdCBhdHRhY2hPYnNlcnZlciA9ICgpPT57CiAgICBpZiAoIW9ic2VydmVyQXR0YWNoZWQgJiYgd2luZG93LlJlc2l6ZU9ic2VydmVyKSB7CiAgICAgIGNvbnN0IHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidGltZXItY29udGFpbmVyIik7CiAgICAgIGlmICh0KSB7CiAgICAgICAgbmV3IFJlc2l6ZU9ic2VydmVyKHVwZGF0ZUhlaWdodEFuZEFsZXJ0cykub2JzZXJ2ZSh0KTsKICAgICAgICBvYnNlcnZlckF0dGFjaGVkID0gdHJ1ZTsKICAgICAgfQogICAgfQogIH07CiAgY29uc3QgdXBkYXRlVGltZXIgPSAoKT0+ewogICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7CiAgICBjb25zdCBpc1N0YXJ0ZWQgPSBub3cgPj0gc3RhcnREYXRlOwogICAgY29uc3QgeyBkYXlzLCBob3VycywgbWludXRlcywgc2Vjb25kcyB9ID0gZ2V0RGVsdGEoZXhwaXJhdGlvbkRhdGUpOwogICAgY29uc3QgaXNFeHBpcmVkID0gZGF5cyArIGhvdXJzICsgbWludXRlcyArIHNlY29uZHMgPCAwOwogICAgaWYgKGlzRXhwaXJlZCkgewogICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS10aW1lci1hY3RpdmUiKTsKICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiLmFsZXJ0LWNvbXBvbmVudCIpLmZvckVhY2goZnVuY3Rpb24oZWwpIHsKICAgICAgICBjb25zdCBodG1sRWwgPSBlbDsKICAgICAgICBpZiAoaHRtbEVsLnN0eWxlLmRpc3BsYXkgPT09ICJub25lIikgewogICAgICAgICAgaHRtbEVsLnN0eWxlLnJlbW92ZVByb3BlcnR5KCJkaXNwbGF5Iik7CiAgICAgICAgfQogICAgICB9KTsKICAgICAgY29uc3QgZXhwaXJlZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGB0aW1lci1jb250YWluZXJgKTsKICAgICAgaWYgKGV4cGlyZWQpIHsKICAgICAgICAvLyBBZGljaW9uYSBhbmltYcOnw6NvIGRlIGZhZGUgb3V0CiAgICAgICAgZXhwaXJlZC5zdHlsZS50cmFuc2l0aW9uID0gIm9wYWNpdHkgMC41cyBlYXNlLW91dCwgdHJhbnNmb3JtIDAuNXMgZWFzZS1vdXQiOwogICAgICAgIGV4cGlyZWQuc3R5bGUub3BhY2l0eSA9ICIwIjsKICAgICAgICBleHBpcmVkLnN0eWxlLnRyYW5zZm9ybSA9ICJ0cmFuc2xhdGVZKC0yMHB4KSI7CiAgICAgICAgLy8gUmVtb3ZlIG8gZWxlbWVudG8gYXDDs3MgYSBhbmltYcOnw6NvCiAgICAgICAgc2V0VGltZW91dCgoKT0+ewogICAgICAgICAgZXhwaXJlZC5yZW1vdmUoKTsKICAgICAgICB9LCA1MDApOwogICAgICB9CiAgICB9IGVsc2UgaWYgKGlzU3RhcnRlZCkgewogICAgICBjb25zdCB0aW1lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0aW1lci1jb250YWluZXIiKTsKICAgICAgaWYgKHRpbWVyICYmIHRpbWVyLmNsYXNzTGlzdC5jb250YWlucygiaGlkZGVuIikpIHsKICAgICAgICB0aW1lci5jbGFzc0xpc3QucmVtb3ZlKCJoaWRkZW4iKTsKICAgICAgICBpZiAoaXNBYm92ZUhlYWRlcikgewogICAgICAgICAgdGltZXIuY2xhc3NMaXN0LmFkZCgiY2FtcGFpZ24tdGltZXItYWJvdmUtaGVhZGVyIik7CiAgICAgICAgfQogICAgICAgIHVwZGF0ZUhlaWdodEFuZEFsZXJ0cygpOwogICAgICAgIHNldFRpbWVvdXQodXBkYXRlSGVpZ2h0QW5kQWxlcnRzLCAxMDApOwogICAgICAgIHNldFRpbWVvdXQodXBkYXRlSGVpZ2h0QW5kQWxlcnRzLCA1MDApOwogICAgICB9CiAgICAgIGF0dGFjaE9ic2VydmVyKCk7CiAgICAgIHVwZGF0ZUhlaWdodEFuZEFsZXJ0cygpOwogICAgICBzZXRWYWx1ZShgJHtyb290SWR9OjpkYXlzYCwgZGF5cyk7CiAgICAgIHNldFZhbHVlKGAke3Jvb3RJZH06OmhvdXJzYCwgaG91cnMpOwogICAgICBzZXRWYWx1ZShgJHtyb290SWR9OjptaW51dGVzYCwgbWludXRlcyk7CiAgICAgIHNldFZhbHVlKGAke3Jvb3RJZH06OnNlY29uZHNgLCBzZWNvbmRzKTsKICAgIH0KICB9OwogIGNvbnN0IHN0YXJ0ID0gKCk9PnsKICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpOwogICAgaWYgKG5vdyA+PSBzdGFydERhdGUpIHsKICAgICAgYXR0YWNoT2JzZXJ2ZXIoKTsKICAgICAgdXBkYXRlSGVpZ2h0QW5kQWxlcnRzKCk7CiAgICAgIHNldFRpbWVvdXQodXBkYXRlSGVpZ2h0QW5kQWxlcnRzLCAxMDApOwogICAgICBzZXRUaW1lb3V0KHVwZGF0ZUhlaWdodEFuZEFsZXJ0cywgNTAwKTsKICAgIH0KICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlSGVpZ2h0QW5kQWxlcnRzKTsKICAgIHNldEludGVydmFsKHVwZGF0ZVRpbWVyLCAxMDAwKTsKICB9OwogIGlmIChkb2N1bWVudC5yZWFkeVN0YXRlID09PSAibG9hZGluZyIpIHsKICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLCBzdGFydCk7CiAgfSBlbHNlIHsKICAgIHN0YXJ0KCk7CiAgfQp9KSgiMjAyNi0wOC0yMlQwMTowMDowMC4wMDBaIiwgIjIwMjYtMDgtMjJUMDI6MDA6MDAuMDAwWiIsICJQMC0zMTMxMTMxNDQiLCB0cnVlKSkp | |
| js | data:text/javascript;base64,ZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZSgoKHsgcm9vdElkLCBzY3JvbGwgPSAic21vb3RoIiwgaW50ZXJ2YWwsIGluZmluaXRlLCBvbmVCeW9uZSwgaXRlbURvdHMsIHBhZ2VEb3RzLCBzY3JvbGxEb3RzLCBpc0Zyb21Ib29rID0gZmFsc2UsIGRlc2t0b3BEcmFnZ2FibGUgPSBmYWxzZSB9KT0+ewogIGNvbnN0IEFUVFJJQlVURVMgPSBpc0Zyb21Ib29rIC8vIHRoaXMgaXMgdXNlZCB0byBrZWVwIGNvbXBhdGliaWxpdHkgdG8gdGhlIG9sZCB3YXkgdG8gY3JlYXRlIGEgc2xpZGVyCiAgID8gewogICAgImRhdGEtc2xpZGVyIjogYFtkYXRhLXNsaWRlcl1bZGF0YS1yb290PSR7cm9vdElkfV1gLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiBgW2RhdGEtc2xpZGVyLWl0ZW1dW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6IGBbZGF0YS1zbGlkZT0icHJldiJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6IGBbZGF0YS1zbGlkZT0ibmV4dCJdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLWRvdCI6IGBbZGF0YS1kb3RdW2RhdGEtcm9vdD0ke3Jvb3RJZH1dYCwKICAgICJkYXRhLXByb2dyZXNzIjogYFtkYXRhLXByb2dyZXNzXVtkYXRhLXJvb3Q9JHtyb290SWR9XWAKICB9IDogewogICAgImRhdGEtc2xpZGVyIjogIltkYXRhLXNsaWRlcl0iLAogICAgImRhdGEtc2xpZGVyLWl0ZW0iOiAiW2RhdGEtc2xpZGVyLWl0ZW1dIiwKICAgICdkYXRhLXNsaWRlPSJwcmV2Iic6ICdbZGF0YS1zbGlkZT0icHJldiJdJywKICAgICdkYXRhLXNsaWRlPSJuZXh0Iic6ICdbZGF0YS1zbGlkZT0ibmV4dCJdJywKICAgICJkYXRhLWRvdCI6ICJbZGF0YS1kb3RdIiwKICAgICJkYXRhLXByb2dyZXNzIjogIltkYXRhLXByb2dyZXNzXSIKICB9OwogIC8vIFBlcmNlbnRhZ2Ugb2YgdGhlIGl0ZW0gdGhhdCBoYXMgdG8gYmUgaW5zaWRlIHRoZSBjb250YWluZXIKICAvLyBmb3IgaXQgaXQgYmUgY29uc2lkZXJlZCBhcyBpbnNpZGUgdGhlIGNvbnRhaW5lcgogIGNvbnN0IFRIUkVTSE9MRCA9IDAuNzU7CiAgY29uc3QgVVNFX0lORklOSVRFX0JFSEFWSU9VUiA9IHRydWU7CiAgY29uc3QgaW50ZXJzZWN0aW9uWCA9IChlbGVtZW50LCBjb250YWluZXIpPT57CiAgICBjb25zdCBkZWx0YSA9IGNvbnRhaW5lci53aWR0aCAvIDFfMDAwOwogICAgaWYgKGVsZW1lbnQucmlnaHQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiAwLjA7CiAgICB9CiAgICBpZiAoZWxlbWVudC5sZWZ0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIDAuMDsKICAgIH0KICAgIGlmIChlbGVtZW50LmxlZnQgPCBjb250YWluZXIubGVmdCAtIGRlbHRhKSB7CiAgICAgIHJldHVybiBlbGVtZW50LnJpZ2h0IC0gY29udGFpbmVyLmxlZnQgKyBkZWx0YTsKICAgIH0KICAgIGlmIChlbGVtZW50LnJpZ2h0ID4gY29udGFpbmVyLnJpZ2h0ICsgZGVsdGEpIHsKICAgICAgcmV0dXJuIGNvbnRhaW5lci5yaWdodCAtIGVsZW1lbnQubGVmdCArIGRlbHRhOwogICAgfQogICAgcmV0dXJuIGVsZW1lbnQud2lkdGg7CiAgfTsKICAvLyBhcyBhbnkgYXJlIG9rIGluIHR5cGVndWFyZCBmdW5jdGlvbnMKICBjb25zdCBpc0hUTUxFbGVtZW50ID0gKHgpPT4vLyBkZW5vLWxpbnQtaWdub3JlIG5vLWV4cGxpY2l0LWFueQogICAgdHlwZW9mIHgub2Zmc2V0TGVmdCA9PT0gIm51bWJlciI7CiAgY29uc3Qgcm9vdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHJvb3RJZCkgPz8gZG9jdW1lbnQuY3VycmVudFNjcmlwdD8ucGFyZW50RWxlbWVudCA/PyBudWxsOwogIGNvbnN0IHNsaWRlciA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1zbGlkZXIiXSk7CiAgY29uc3QgaXRlbXMgPSBzbGlkZXI/LnF1ZXJ5U2VsZWN0b3JBbGwoQVRUUklCVVRFU1siZGF0YS1zbGlkZXItaXRlbSJdKTsKICBjb25zdCBwcmV2ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJwcmV2IiddKTsKICBjb25zdCBuZXh0ID0gcm9vdD8ucXVlcnlTZWxlY3RvcihBVFRSSUJVVEVTWydkYXRhLXNsaWRlPSJuZXh0IiddKTsKICBjb25zdCBkb3RzID0gcm9vdD8ucXVlcnlTZWxlY3RvckFsbChBVFRSSUJVVEVTWyJkYXRhLWRvdCJdKTsKICBjb25zdCBwcm9ncmVzcyA9IHJvb3Q/LnF1ZXJ5U2VsZWN0b3IoQVRUUklCVVRFU1siZGF0YS1wcm9ncmVzcyJdKTsKICBpZiAoIXJvb3QgfHwgIXNsaWRlciB8fCAhaXRlbXMgfHwgaXRlbXMubGVuZ3RoID09PSAwKSB7CiAgICBjb25zb2xlLndhcm4oIk1pc3NpbmcgbmVjZXNzYXJ5IHNsaWRlciBhdHRyaWJ1dGVzLiBJdCB3aWxsIG5vdCB3b3JrIGFzIGludGVuZGVkLiBOZWNlc3NhcnkgZWxlbWVudHM6IiwgewogICAgICByb290LAogICAgICBzbGlkZXIsCiAgICAgIGl0ZW1zLAogICAgICByb290SWQKICAgIH0pOwogICAgcmV0dXJuOwogIH0KICBjb25zdCBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lciA9ICgpPT57CiAgICBjb25zdCBpbmRpY2VzID0gW107CiAgICBjb25zdCBzbGlkZXJSZWN0ID0gc2xpZGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgZm9yKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaXRlbXMubGVuZ3RoOyBpbmRleCsrKXsKICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zLml0ZW0oaW5kZXgpOwogICAgICBjb25zdCByZWN0ID0gaXRlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgY29uc3QgcmF0aW8gPSBpbnRlcnNlY3Rpb25YKHJlY3QsIHNsaWRlclJlY3QpIC8gcmVjdC53aWR0aDsKICAgICAgaWYgKHJhdGlvID4gVEhSRVNIT0xEKSB7CiAgICAgICAgaW5kaWNlcy5wdXNoKGluZGV4KTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGluZGljZXM7CiAgfTsKICBjb25zdCBlbGVtZW50c0luc2lkZUNvbnRhaW5lciA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgY29uc3QgaW5maW5pdGVCZWhhdmlvciA9ICFzY3JvbGxEb3RzICYmIGluZmluaXRlICYmIGVsZW1lbnRzSW5zaWRlQ29udGFpbmVyLmxlbmd0aCA9PT0gMSAmJiBpdGVtcy5sZW5ndGggPiAxICYmIFVTRV9JTkZJTklURV9CRUhBVklPVVI7CiAgY29uc3QgZ2V0TWF4U2Nyb2xsTGVmdCA9ICgpPT5NYXRoLm1heCgwLCBzbGlkZXIuc2Nyb2xsV2lkdGggLSBzbGlkZXIuY2xpZW50V2lkdGgpOwogIGNvbnN0IGNsYW1wU2Nyb2xsTGVmdCA9IChsZWZ0KT0+TWF0aC5taW4oTWF0aC5tYXgobGVmdCwgMCksIGdldE1heFNjcm9sbExlZnQoKSk7CiAgY29uc3QgZ2V0SXRlbVNjcm9sbExlZnQgPSAoaXRlbSk9PnsKICAgIGlmICghaXNIVE1MRWxlbWVudChpdGVtKSkgcmV0dXJuIDA7CiAgICByZXR1cm4gY2xhbXBTY3JvbGxMZWZ0KGl0ZW0ub2Zmc2V0TGVmdCAtIHNsaWRlci5vZmZzZXRMZWZ0KTsKICB9OwogIGxldCBzY3JvbGxEb3RQb3NpdGlvbnMgPSBbXTsKICBjb25zdCBnZXRTY3JvbGxEb3RQb3NpdGlvbnMgPSAoKT0+ewogICAgaWYgKCFzY3JvbGxEb3RzKSByZXR1cm4gW107CiAgICBpZiAoc2xpZGVyLmNsaWVudFdpZHRoIDw9IDApIHsKICAgICAgcmV0dXJuIHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggPyBzY3JvbGxEb3RQb3NpdGlvbnMgOiBbCiAgICAgICAgMAogICAgICBdOwogICAgfQogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHJldHVybiBbCiAgICAgIDAKICAgIF07CiAgICBjb25zdCB2aXNpYmxlSXRlbXMgPSBNYXRoLm1heChnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpLmxlbmd0aCwgMSk7CiAgICBjb25zdCBwb3NpdGlvbnMgPSBbCiAgICAgIDAKICAgIF07CiAgICBmb3IobGV0IGluZGV4ID0gdmlzaWJsZUl0ZW1zOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXggKz0gdmlzaWJsZUl0ZW1zKXsKICAgICAgcG9zaXRpb25zLnB1c2goZ2V0SXRlbVNjcm9sbExlZnQoaXRlbXMuaXRlbShpbmRleCkpKTsKICAgIH0KICAgIHBvc2l0aW9ucy5wdXNoKG1heFNjcm9sbExlZnQpOwogICAgcmV0dXJuIHBvc2l0aW9ucy5yZWR1Y2UoKGFjYywgcG9zaXRpb24pPT57CiAgICAgIGNvbnN0IHJvdW5kZWRQb3NpdGlvbiA9IE1hdGgucm91bmQoY2xhbXBTY3JvbGxMZWZ0KHBvc2l0aW9uKSk7CiAgICAgIGNvbnN0IGxhc3RQb3NpdGlvbiA9IGFjY1thY2MubGVuZ3RoIC0gMV07CiAgICAgIGlmIChsYXN0UG9zaXRpb24gPT09IHVuZGVmaW5lZCB8fCBNYXRoLmFicyhsYXN0UG9zaXRpb24gLSByb3VuZGVkUG9zaXRpb24pID4gMSkgewogICAgICAgIGFjYy5wdXNoKHJvdW5kZWRQb3NpdGlvbik7CiAgICAgIH0KICAgICAgcmV0dXJuIGFjYzsKICAgIH0sIFtdKTsKICB9OwogIGNvbnN0IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCA9ICgpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIHNjcm9sbERvdFBvc2l0aW9ucy5mb3JFYWNoKChwb3NpdGlvbiwgaW5kZXgpPT57CiAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnMoc2xpZGVyLnNjcm9sbExlZnQgLSBwb3NpdGlvbik7CiAgICAgIGlmIChkaXN0YW5jZSA8IHNtYWxsZXN0RGlzdGFuY2UpIHsKICAgICAgICBzbWFsbGVzdERpc3RhbmNlID0gZGlzdGFuY2U7CiAgICAgICAgYWN0aXZlSW5kZXggPSBpbmRleDsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gYWN0aXZlSW5kZXg7CiAgfTsKICBjb25zdCB1cGRhdGVTY3JvbGxEb3RzID0gKCk9PnsKICAgIGlmICghc2Nyb2xsRG90cyB8fCAhZG90cykgcmV0dXJuOwogICAgc2Nyb2xsRG90UG9zaXRpb25zID0gZ2V0U2Nyb2xsRG90UG9zaXRpb25zKCk7CiAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90LCBpbmRleCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIGlmIChpbmRleCA+PSBzY3JvbGxEb3RQb3NpdGlvbnMubGVuZ3RoKSB7CiAgICAgICAgZG90LmNsYXNzTGlzdC5hZGQoImhpZGRlbiIpOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgIGlmIChpbmRleCA9PT0gYWN0aXZlSW5kZXgpIHsKICAgICAgICBkb3Quc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgIH0KICAgIH0pOwogICAgaWYgKCFpbmZpbml0ZSkgewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxID8gcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKSA6IHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPj0gbWF4U2Nyb2xsTGVmdCAtIDEgPyBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpIDogbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgfQogIH07CiAgY29uc3QgZ29Ub1Njcm9sbERvdCA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBzY3JvbGxEb3RQb3NpdGlvbnMgPSBnZXRTY3JvbGxEb3RQb3NpdGlvbnMoKTsKICAgIGNvbnN0IHBvc2l0aW9uID0gc2Nyb2xsRG90UG9zaXRpb25zW2luZGV4XTsKICAgIGlmIChwb3NpdGlvbiA9PT0gdW5kZWZpbmVkKSByZXR1cm47CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBwb3NpdGlvbgogICAgfSk7CiAgfTsKICBjb25zdCBub3JtYWxpemVTY3JvbGxCb3VuZHMgPSAoKT0+ewogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA+IG1heFNjcm9sbExlZnQpIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBtYXhTY3JvbGxMZWZ0OwogICAgfSBlbHNlIGlmIChzbGlkZXIuc2Nyb2xsTGVmdCA8IDApIHsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSAwOwogICAgfQogIH07CiAgbGV0IHRvdWNoU3RhcnRYID0gMDsKICBsZXQgdG91Y2hTdGFydFkgPSAwOwogIGNvbnN0IGhhbmRsZVRvdWNoU3RhcnQgPSAoZXZlbnQpPT57CiAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07CiAgICBpZiAoIXRvdWNoKSByZXR1cm47CiAgICB0b3VjaFN0YXJ0WCA9IHRvdWNoLmNsaWVudFg7CiAgICB0b3VjaFN0YXJ0WSA9IHRvdWNoLmNsaWVudFk7CiAgfTsKICBjb25zdCBoYW5kbGVUb3VjaE1vdmUgPSAoZXZlbnQpPT57CiAgICBpZiAoIXNjcm9sbERvdHMpIHJldHVybjsKICAgIGNvbnN0IHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTsKICAgIGlmICghdG91Y2gpIHJldHVybjsKICAgIGNvbnN0IGRlbHRhWCA9IHRvdWNoLmNsaWVudFggLSB0b3VjaFN0YXJ0WDsKICAgIGNvbnN0IGRlbHRhWSA9IHRvdWNoLmNsaWVudFkgLSB0b3VjaFN0YXJ0WTsKICAgIGNvbnN0IGlzSG9yaXpvbnRhbEdlc3R1cmUgPSBNYXRoLmFicyhkZWx0YVgpID4gTWF0aC5hYnMoZGVsdGFZKTsKICAgIGlmICghaXNIb3Jpem9udGFsR2VzdHVyZSkgcmV0dXJuOwogICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGdldE1heFNjcm9sbExlZnQoKTsKICAgIGlmIChtYXhTY3JvbGxMZWZ0IDw9IDEpIHsKICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcygpOwogICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdCBpc0F0U3RhcnQgPSBzbGlkZXIuc2Nyb2xsTGVmdCA8PSAxOwogICAgY29uc3QgaXNBdEVuZCA9IHNsaWRlci5zY3JvbGxMZWZ0ID49IG1heFNjcm9sbExlZnQgLSAxOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RTdGFydCA9IGlzQXRTdGFydCAmJiBkZWx0YVggPiAwOwogICAgY29uc3QgaXNEcmFnZ2luZ1Bhc3RFbmQgPSBpc0F0RW5kICYmIGRlbHRhWCA8IDA7CiAgICBpZiAoaXNEcmFnZ2luZ1Bhc3RTdGFydCB8fCBpc0RyYWdnaW5nUGFzdEVuZCkgewogICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgbm9ybWFsaXplU2Nyb2xsQm91bmRzKCk7CiAgICB9CiAgfTsKICBjb25zdCBnb1RvSXRlbSA9IChpbmRleCwgYmVoYXZpb3IgPSBzY3JvbGwpPT57CiAgICBjb25zdCBpdGVtID0gc2xpZGVyLnF1ZXJ5U2VsZWN0b3IoYGxpW2RhdGEtcm9vdD0nJHtyb290SWR9J11bZGF0YS1zbGlkZXItaXRlbT0nJHtpbmRleH0nXWApID8/IHNsaWRlci5xdWVyeVNlbGVjdG9yKGBsaVtkYXRhLXNsaWRlci1pdGVtPScke2luZGV4fSddYCk7CiAgICBpZiAoaXRlbSkgewogICAgICBpZiAoIWlzSFRNTEVsZW1lbnQoaXRlbSkpIHsKICAgICAgICBjb25zb2xlLndhcm4oYEVsZW1lbnQgYXQgaW5kZXggJHtpbmRleH0gaXMgbm90IGFuIGh0bWwgZWxlbWVudC4gU2tpcHBpbmcgY2Fyb3VzZWxgKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgc2xpZGVyLnNjcm9sbFRvKHsKICAgICAgICB0b3A6IDAsCiAgICAgICAgYmVoYXZpb3I6IGJlaGF2aW9yLAogICAgICAgIGxlZnQ6IGl0ZW0ub2Zmc2V0TGVmdCAtIHJvb3Qub2Zmc2V0TGVmdAogICAgICB9KTsKICAgIH0KICB9OwogIGNvbnN0IGdvVG9JdGVtRG90ID0gKGluZGV4LCBiZWhhdmlvciA9IHNjcm9sbCk9PnsKICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgIGlmICghaXRlbSkgcmV0dXJuOwogICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSB7CiAgICAgIGNvbnNvbGUud2FybihgRWxlbWVudCBhdCBpbmRleCAke2luZGV4fSBpcyBub3QgYW4gaHRtbCBlbGVtZW50LiBTa2lwcGluZyBjYXJvdXNlbGApOwogICAgICByZXR1cm47CiAgICB9CiAgICBzbGlkZXIuc2Nyb2xsVG8oewogICAgICB0b3A6IDAsCiAgICAgIGJlaGF2aW9yLAogICAgICBsZWZ0OiBpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdAogICAgfSk7CiAgfTsKICBjb25zdCBnZXROZWFyZXN0SXRlbUluZGV4ID0gKCk9PnsKICAgIGxldCBhY3RpdmVJbmRleCA9IDA7CiAgICBsZXQgc21hbGxlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTsKICAgIGZvcihsZXQgaW5kZXggPSAwOyBpbmRleCA8IGl0ZW1zLmxlbmd0aDsgaW5kZXgrKyl7CiAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5pdGVtKGluZGV4KTsKICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGl0ZW0pKSBjb250aW51ZTsKICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLmFicyhzbGlkZXIuc2Nyb2xsTGVmdCAtIChpdGVtLm9mZnNldExlZnQgLSBzbGlkZXIub2Zmc2V0TGVmdCkpOwogICAgICBpZiAoZGlzdGFuY2UgPCBzbWFsbGVzdERpc3RhbmNlKSB7CiAgICAgICAgc21hbGxlc3REaXN0YW5jZSA9IGRpc3RhbmNlOwogICAgICAgIGFjdGl2ZUluZGV4ID0gaW5kZXg7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBhY3RpdmVJbmRleDsKICB9OwogIGNvbnN0IG9uQ2xpY2tQcmV2ID0gKCk9PnsKICAgIGlmIChzY3JvbGxEb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdFNjcm9sbERvdEluZGV4KCk7CiAgICAgIGFjdGl2ZUluZGV4ID09PSAwID8gaW5maW5pdGUgPyBnb1RvU2Nyb2xsRG90KHNjcm9sbERvdFBvc2l0aW9ucy5sZW5ndGggLSAxKSA6IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChpdGVtRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RJdGVtSW5kZXgoKTsKICAgICAgYWN0aXZlSW5kZXggPT09IDAgPyBpbmZpbml0ZSA/IGdvVG9JdGVtRG90KGl0ZW1zLmxlbmd0aCAtIDEpIDogbnVsbCA6IGdvVG9JdGVtRG90KGFjdGl2ZUluZGV4IC0gMSk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIFdvdyEgaXRlbXMgcGVyIHBhZ2UgaXMgaG93IG1hbnkgZWxlbWVudHMgYXJlIGJlaW5nIGRpc3BsYXllZCBpbnNpZGUgdGhlIGNvbnRhaW5lciEhCiAgICBjb25zdCBpdGVtc1BlclBhZ2UgPSBpbmRpY2VzLmxlbmd0aDsKICAgIGNvbnN0IGlzU2hvd2luZ0ZpcnN0ID0gaW5kaWNlc1swXSA9PT0gMDsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdIC8gaXRlbXNQZXJQYWdlKTsKICAgIGlmIChvbmVCeW9uZSkgewogICAgICBpc1Nob3dpbmdGaXJzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oaXRlbXMubGVuZ3RoIC0gMSkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSAtIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nRmlyc3QgPyBpbmZpbml0ZUJlaGF2aW9yID8gaXRlbXMubGVuZ3RoIDogaXRlbXMubGVuZ3RoIC0gMSA6IChwYWdlSW5kZXggLSAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCBvbkNsaWNrTmV4dCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGdldE5lYXJlc3RTY3JvbGxEb3RJbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gc2Nyb2xsRG90UG9zaXRpb25zLmxlbmd0aCAtIDEgPyBpbmZpbml0ZSA/IGdvVG9TY3JvbGxEb3QoMCkgOiBnb1RvU2Nyb2xsRG90KGFjdGl2ZUluZGV4KSA6IGdvVG9TY3JvbGxEb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGl0ZW1Eb3RzKSB7CiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gZ2V0TmVhcmVzdEl0ZW1JbmRleCgpOwogICAgICBhY3RpdmVJbmRleCA9PT0gaXRlbXMubGVuZ3RoIC0gMSA/IGluZmluaXRlID8gZ29Ub0l0ZW1Eb3QoMCkgOiBudWxsIDogZ29Ub0l0ZW1Eb3QoYWN0aXZlSW5kZXggKyAxKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgaW5kaWNlcyA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCk7CiAgICBpZiAoaW5kaWNlcy5sZW5ndGggPT09IDApIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgLy8gV293ISBpdGVtcyBwZXIgcGFnZSBpcyBob3cgbWFueSBlbGVtZW50cyBhcmUgYmVpbmcgZGlzcGxheWVkIGluc2lkZSB0aGUgY29udGFpbmVyISEKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGluZGljZXMubGVuZ3RoOwogICAgY29uc3QgaXNTaG93aW5nTGFzdCA9IGluZGljZXNbaW5kaWNlcy5sZW5ndGggLSAxXSA9PT0gaXRlbXMubGVuZ3RoIC0gMTsKICAgIGNvbnN0IHBhZ2VJbmRleCA9IE1hdGguZmxvb3IoaW5kaWNlc1swXSAvIGl0ZW1zUGVyUGFnZSk7CiAgICAvLyBnb1RvSXRlbShpc1Nob3dpbmdMYXN0ID8gMCA6IChpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICBpZiAob25lQnlvbmUpIHsKICAgICAgaXNTaG93aW5nTGFzdCA/IGluZmluaXRlID8gZ29Ub0l0ZW0oMCkgOiBudWxsIDogZ29Ub0l0ZW0oaW5kaWNlc1swXSArIDEpOwogICAgfSBlbHNlIHsKICAgICAgZ29Ub0l0ZW0oaXNTaG93aW5nTGFzdCA/IGluZmluaXRlQmVoYXZpb3IgPyBpdGVtcy5sZW5ndGggKyAxIDogMCA6IChwYWdlSW5kZXggKyAxKSAqIGl0ZW1zUGVyUGFnZSk7CiAgICB9CiAgfTsKICBjb25zdCB1cGRhdGVQYWdlRG90cyA9ICgpPT57CiAgICBpZiAoIXBhZ2VEb3RzIHx8ICFkb3RzKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IE1hdGgubWF4KGluZGljZXMubGVuZ3RoLCAxKTsKICAgIGNvbnN0IG1heFZpc2libGUgPSBNYXRoLm1heCguLi5pbmRpY2VzKTsKICAgIGNvbnN0IHBhZ2VEb3RJbmRleCA9IE1hdGguZmxvb3IobWF4VmlzaWJsZSAvIGl0ZW1zUGVyUGFnZSkgKiBpdGVtc1BlclBhZ2U7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCwgaSk9PnsKICAgICAgaWYgKGkgJSBpdGVtc1BlclBhZ2UgIT09IDApIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShwYWdlRG90SW5kZXgpOwogICAgaWYgKGFjdGl2ZURvdCkgewogICAgICBBcnJheS5mcm9tKGRvdHMpLmZpbHRlcigoX2RvdCwgaSk9PmkgPCBwYWdlRG90SW5kZXggJiYgaSAlIGl0ZW1zUGVyUGFnZSA9PT0gMCkuZm9yRWFjaCgoZG90KT0+ZG90LnNldEF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIiwgInRydWUiKSk7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IHVwZGF0ZUFjdGl2ZURvdCA9ICgpPT57CiAgICBpZiAoc2Nyb2xsRG90cykgewogICAgICB1cGRhdGVTY3JvbGxEb3RzKCk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChwYWdlRG90cyB8fCAhZG90cykgewogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoaXRlbURvdHMpIHsKICAgICAgY29uc3QgYWN0aXZlSW5kZXggPSBnZXROZWFyZXN0SXRlbUluZGV4KCk7CiAgICAgIEFycmF5LmZyb20oZG90cykuZm9yRWFjaCgoZG90KT0+ewogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtcGFpbnRlZCIpOwogICAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgIH0pOwogICAgICBjb25zdCBhY3RpdmVEb3QgPSBkb3RzLml0ZW0oYWN0aXZlSW5kZXgpOwogICAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgICAgYWN0aXZlRG90LnNldEF0dHJpYnV0ZSgiZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGluZGljZXMgPSBnZXRFbGVtZW50c0luc2lkZUNvbnRhaW5lcigpOwogICAgaWYgKGluZGljZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gTWF0aC5taW4oLi4uaW5kaWNlcyk7CiAgICBBcnJheS5mcm9tKGRvdHMpLmZvckVhY2goKGRvdCk9PnsKICAgICAgZG90LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1wYWludGVkIik7CiAgICAgIGRvdC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICB9KTsKICAgIGNvbnN0IGFjdGl2ZURvdCA9IGRvdHMuaXRlbShhY3RpdmVJbmRleCk7CiAgICBpZiAoYWN0aXZlRG90KSB7CiAgICAgIGFjdGl2ZURvdC5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgInRydWUiKTsKICAgIH0KICB9OwogIGNvbnN0IG9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGlmIChwYWdlRG90cykgewogICAgICB1cGRhdGVQYWdlRG90cygpOwogICAgfSBlbHNlIHsKICAgICAgdXBkYXRlQWN0aXZlRG90KCk7CiAgICB9CiAgICBlbGVtZW50cy5mb3JFYWNoKChpdGVtKT0+ewogICAgICBjb25zdCBpbmRleCA9IE51bWJlcihpdGVtLnRhcmdldC5nZXRBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKSkgfHwgMDsKICAgICAgaWYgKCFpbmZpbml0ZSAmJiAhc2Nyb2xsRG90cykgewogICAgICAgIGlmIChpbmRleCA9PT0gMCkgewogICAgICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcpIHsKICAgICAgICAgICAgcHJldj8uc2V0QXR0cmlidXRlKCJkaXNhYmxlZCIsICIiKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByZXY/LnJlbW92ZUF0dHJpYnV0ZSgiZGlzYWJsZWQiKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGluZGV4ID09PSBpdGVtcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICBpZiAoaXRlbS5pc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBuZXh0Py5zZXRBdHRyaWJ1dGUoImRpc2FibGVkIiwgIiIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmV4dD8ucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocHJvZ3Jlc3MpIHsKICAgICAgICAgIGlmIChwcm9ncmVzcy5pZCA9PSAiMCIgJiYgaW5kZXggPT09IGl0ZW1zLmxlbmd0aCAtIDEpIHsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUuaGVpZ2h0ID0gYCR7MSAvIGl0ZW1zLmxlbmd0aCAqIDEwMH0lYDsKICAgICAgICAgICAgcHJvZ3Jlc3Muc3R5bGUud2lkdGggPSBgJHsxIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5pZCA9ICIxIjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByb2dyZXNzLnN0eWxlLmhlaWdodCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgICBwcm9ncmVzcy5zdHlsZS53aWR0aCA9IGAkeyhpbmRleCArIDEpIC8gaXRlbXMubGVuZ3RoICogMTAwfSVgOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfSwgewogICAgdGhyZXNob2xkOiBUSFJFU0hPTEQsCiAgICByb290OiBzbGlkZXIsCiAgICByb290TWFyZ2luOiAiMTAwcHgiCiAgfSk7CiAgY29uc3QgZnVsbE9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKChlbGVtZW50cyk9PnsKICAgIGVsZW1lbnRzLmZvckVhY2goKGl0ZW0pPT57CiAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IHNsaWRlcj8ucXVlcnlTZWxlY3RvckFsbChgbGlgKTsKICAgICAgaWYgKGl0ZW0uaXNJbnRlcnNlY3RpbmcgJiYgZWxlbWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT0gY3VycmVudEl0ZW1zWzFdKSB7CiAgICAgICAgICBzZXRUaW1lb3V0KCgpPT57CiAgICAgICAgICAgIGdvVG9JdGVtKGl0ZW1zLmxlbmd0aCAtIDEsICJpbnN0YW50Iik7CiAgICAgICAgICB9LCAyMDApOwogICAgICAgIH0KICAgICAgICBpZiAoaXRlbS50YXJnZXQgPT09IGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pIHsKICAgICAgICAgIHNldFRpbWVvdXQoKCk9PnsKICAgICAgICAgICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICAgICAgICAgIH0sIDIwMCk7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9LCB7CiAgICB0aHJlc2hvbGQ6IDAuNywKICAgIHJvb3Q6IHNsaWRlciwKICAgIHJvb3RNYXJnaW46ICIxMDBweCIKICB9KTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgY29uc3QgZmlyc3RJdGVtQ2xvbmUgPSBpdGVtc1swXS5jbG9uZU5vZGUodHJ1ZSk7CiAgICBjb25zdCBzZWNvbmRJdGVtQ2xvbmUgPSBpdGVtc1sxXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgcGVudWx0aW1hdGVJdGVtQ2xvbmUgPSBpdGVtc1tpdGVtcy5sZW5ndGggLSAyXT8uY2xvbmVOb2RlKHRydWUpOwogICAgY29uc3QgbGFzdEl0ZW1DbG9uZSA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdLmNsb25lTm9kZSh0cnVlKTsKICAgIC8vIHdlIHJlbW92ZSB0aGVzZSBhdHRyaWJ1dGVzIGZyb20gdGhlIGNsb25lZCBpdGVtcyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gc2VuZCBldmVudHMgZm9yIHRoZSBjbG9uZWQgaXRlbXMKICAgIC8vIGJhbm5lciBjYXJvdXNlbCB1c2VzIGRhdGEtZXZlbnQgdG8gc2VuZCBldmVudHMgdG8gYW5hbHl0aWNzCiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBsYXN0SXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHBlbnVsdGltYXRlSXRlbUNsb25lLmZpcnN0RWxlbWVudENoaWxkPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtZXZlbnQiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50Iik7CiAgICBmaXJzdEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuZmlyc3RFbGVtZW50Q2hpbGQ/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1ldmVudC10cmlnZ2VyIik7CiAgICBwZW51bHRpbWF0ZUl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIHNlY29uZEl0ZW1DbG9uZS5maXJzdEVsZW1lbnRDaGlsZD8ucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWV2ZW50LXRyaWdnZXIiKTsKICAgIGxhc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgaXRlbXMubGVuZ3RoLnRvU3RyaW5nKCkpOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmU/LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1zbGlkZXItaXRlbSIpOwogICAgZmlyc3RJdGVtQ2xvbmUuc2V0QXR0cmlidXRlKCJkYXRhLXNsaWRlci1pdGVtIiwgKGl0ZW1zLmxlbmd0aCArIDEpLnRvU3RyaW5nKCkpOwogICAgc2Vjb25kSXRlbUNsb25lPy5yZW1vdmVBdHRyaWJ1dGUoImRhdGEtc2xpZGVyLWl0ZW0iKTsKICAgIHNsaWRlci5pbnNlcnRCZWZvcmUobGFzdEl0ZW1DbG9uZSwgaXRlbXNbMF0pOwogICAgcGVudWx0aW1hdGVJdGVtQ2xvbmUgJiYgc2xpZGVyLmluc2VydEJlZm9yZShwZW51bHRpbWF0ZUl0ZW1DbG9uZSwgbGFzdEl0ZW1DbG9uZSk7CiAgICBzbGlkZXIuYXBwZW5kQ2hpbGQoZmlyc3RJdGVtQ2xvbmUpOwogICAgc2Vjb25kSXRlbUNsb25lICYmIHNsaWRlci5hcHBlbmRDaGlsZChzZWNvbmRJdGVtQ2xvbmUpOwogICAgZ29Ub0l0ZW0oMCwgImluc3RhbnQiKTsKICB9CiAgY29uc3QgY3VycmVudEl0ZW1zID0gc2xpZGVyPy5xdWVyeVNlbGVjdG9yQWxsKGBsaWApOwogIGl0ZW1zLmZvckVhY2goKGl0ZW0pPT5vYnNlcnZlci5vYnNlcnZlKGl0ZW0pKTsKICBpZiAoaW5maW5pdGVCZWhhdmlvcikgewogICAgZnVsbE9ic2VydmVyLm9ic2VydmUoY3VycmVudEl0ZW1zWzFdKTsKICAgIGZ1bGxPYnNlcnZlci5vYnNlcnZlKGN1cnJlbnRJdGVtc1tjdXJyZW50SXRlbXMubGVuZ3RoIC0gMl0pOwogIH0KICBpZiAocGFnZURvdHMpIHsKICAgIGNvbnN0IGl0ZW1zUGVyUGFnZSA9IGdldEVsZW1lbnRzSW5zaWRlQ29udGFpbmVyKCkubGVuZ3RoOwogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGNvbnN0IGRvdCA9IGRvdHM/Lml0ZW0oaXQpOwogICAgICBpZiAoIWRvdCkgY29udGludWU7CiAgICAgIGlmIChpdCAlIGl0ZW1zUGVyUGFnZSAhPT0gMCkgewogICAgICAgIGRvdC5jbGFzc0xpc3QuYWRkKCJoaWRkZW4iKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkb3QuY2xhc3NMaXN0LnJlbW92ZSgiaGlkZGVuIik7CiAgICAgICAgZG90LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKHNjcm9sbERvdHMpIHsKICAgIHVwZGF0ZVNjcm9sbERvdHMoKTsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5nb1RvU2Nyb2xsRG90KGl0KSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGZvcihsZXQgaXQgPSAwOyBpdCA8IChkb3RzPy5sZW5ndGggPz8gMCk7IGl0KyspewogICAgICBkb3RzPy5pdGVtKGl0KS5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsICgpPT5pdGVtRG90cyA/IGdvVG9JdGVtRG90KGl0KSA6IGdvVG9JdGVtKGl0KSk7CiAgICB9CiAgfQogIHByZXY/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja1ByZXYpOwogIG5leHQ/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogIGlmIChzY3JvbGxEb3RzKSB7CiAgICBzbGlkZXIuc3R5bGUub3ZlcnNjcm9sbEJlaGF2aW9yWCA9ICJjb250YWluIjsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJzY3JvbGwiLCBub3JtYWxpemVTY3JvbGxCb3VuZHMsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2hzdGFydCIsIGhhbmRsZVRvdWNoU3RhcnQsIHsKICAgICAgcGFzc2l2ZTogdHJ1ZQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2htb3ZlIiwgaGFuZGxlVG91Y2hNb3ZlLCB7CiAgICAgIHBhc3NpdmU6IGZhbHNlCiAgICB9KTsKICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgfSBlbHNlIGlmIChwYWdlRG90cykgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZVBhZ2VEb3RzKTsKICB9IGVsc2UgewogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIHVwZGF0ZUFjdGl2ZURvdCk7CiAgfQogIGNvbnN0IHRpbWVvdXQgPSBpbnRlcnZhbCAmJiBzZXRJbnRlcnZhbChvbkNsaWNrTmV4dCwgaW50ZXJ2YWwpOwogIGxldCBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXI7CiAgZnVuY3Rpb24gZW5hYmxlSG9yaXpvbnRhbFNjcm9sbCgpIHsKICAgIGlmICghc2xpZGVyKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGxldCBpc01vdXNlRG93biA9IGZhbHNlOwogICAgbGV0IHN0YXJ0WDsKICAgIGxldCBzY3JvbGxMZWZ0OwogICAgbGV0IHZlbG9jaXR5ID0gMDsKICAgIGxldCBtb21lbnR1bUZyYW1lOwogICAgY29uc3QgbW9tZW50dW1TY3JvbGwgPSAoKT0+ewogICAgICBzbGlkZXIuc2Nyb2xsTGVmdCArPSB2ZWxvY2l0eTsKICAgICAgdmVsb2NpdHkgKj0gMC45NTsKICAgICAgaWYgKE1hdGguYWJzKHZlbG9jaXR5KSA+IDAuMSkgewogICAgICAgIG1vbWVudHVtRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUobW9tZW50dW1TY3JvbGwpOwogICAgICB9CiAgICB9OwogICAgc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlZG93biIsIChlKT0+ewogICAgICBpc01vdXNlRG93biA9IHRydWU7CiAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAiZ3JhYmJpbmciOwogICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAiaW5pdGlhbCI7CiAgICAgIHN0YXJ0WCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgc2Nyb2xsTGVmdCA9IHNsaWRlci5zY3JvbGxMZWZ0OwogICAgICB2ZWxvY2l0eSA9IDA7CiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtRnJhbWUpOwogICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICB9KTsKICAgIHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWxlYXZlIiwgKCk9PnsKICAgICAgaWYgKGlzTW91c2VEb3duKSB7CiAgICAgICAgaXNNb3VzZURvd24gPSBmYWxzZTsKICAgICAgICBzbGlkZXIuZGF0YXNldFsiZHJhZ2dpbmciXSA9ICJmYWxzZSI7CiAgICAgICAgc2xpZGVyLnN0eWxlLmN1cnNvciA9ICJncmFiIjsKICAgICAgICBzbGlkZXIuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAic21vb3RoIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2V1cCIsICgpPT57CiAgICAgIGlmIChpc01vdXNlRG93bikgewogICAgICAgIGlzTW91c2VEb3duID0gZmFsc2U7CiAgICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAiZmFsc2UiOwogICAgICAgIHNsaWRlci5zdHlsZS5jdXJzb3IgPSAibm9ybWFsIjsKICAgICAgICBtb21lbnR1bUZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1vbWVudHVtU2Nyb2xsKTsKICAgICAgfQogICAgfSk7CiAgICBzbGlkZXIuYWRkRXZlbnRMaXN0ZW5lcigibW91c2Vtb3ZlIiwgKGUpPT57CiAgICAgIGlmICghaXNNb3VzZURvd24pIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29uc3QgeCA9IGUucGFnZVggLSBzbGlkZXIub2Zmc2V0TGVmdDsKICAgICAgY29uc3Qgd2FsayA9ICh4IC0gc3RhcnRYKSAqIDAuNTsKICAgICAgc2xpZGVyLnNjcm9sbExlZnQgPSBzY3JvbGxMZWZ0IC0gd2FsazsKICAgICAgdmVsb2NpdHkgPSAtd2FsayAqIDAuMjsKICAgICAgc2xpZGVyLmRhdGFzZXRbImRyYWdnaW5nIl0gPSAidHJ1ZSI7CiAgICB9KTsKICB9CiAgaWYgKGRlc2t0b3BEcmFnZ2FibGUpIHsKICAgIHNsaWRlci5kYXRhc2V0WyJkcmFnZ2FibGUiXSA9ICJ0cnVlIjsKICAgIGVuYWJsZUhvcml6b250YWxTY3JvbGwoKTsKICB9CiAgaWYgKHNjcm9sbERvdHMgJiYgIlJlc2l6ZU9ic2VydmVyIiBpbiBnbG9iYWxUaGlzKSB7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIodXBkYXRlU2Nyb2xsRG90cyk7CiAgICBzY3JvbGxEb3RzUmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShzbGlkZXIpOwogIH0KICAvLyBVbnJlZ2lzdGVyIGNhbGxiYWNrcwogIHJldHVybiAoKT0+ewogICAgZm9yKGxldCBpdCA9IDA7IGl0IDwgKGRvdHM/Lmxlbmd0aCA/PyAwKTsgaXQrKyl7CiAgICAgIGRvdHM/Lml0ZW0oaXQpLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgKCk9PmdvVG9JdGVtKGl0KSk7CiAgICB9CiAgICBwcmV2Py5yZW1vdmVFdmVudExpc3RlbmVyKCJjbGljayIsIG9uQ2xpY2tQcmV2KTsKICAgIG5leHQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgb25DbGlja05leHQpOwogICAgaWYgKHNjcm9sbERvdHMpIHsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInNjcm9sbCIsIG5vcm1hbGl6ZVNjcm9sbEJvdW5kcyk7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVTY3JvbGxEb3RzKTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNoc3RhcnQiLCBoYW5kbGVUb3VjaFN0YXJ0KTsKICAgICAgc2xpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRvdWNobW92ZSIsIGhhbmRsZVRvdWNoTW92ZSk7CiAgICAgIGdsb2JhbFRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigicmVzaXplIiwgdXBkYXRlU2Nyb2xsRG90cyk7CiAgICB9IGVsc2UgaWYgKHBhZ2VEb3RzKSB7CiAgICAgIHNsaWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCJzY3JvbGwiLCB1cGRhdGVQYWdlRG90cyk7CiAgICB9IGVsc2UgewogICAgICBzbGlkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigic2Nyb2xsIiwgdXBkYXRlQWN0aXZlRG90KTsKICAgIH0KICAgIG9ic2VydmVyLmRpc2Nvbm5lY3QoKTsKICAgIHNjcm9sbERvdHNSZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpOwogICAgY2xlYXJJbnRlcnZhbCh0aW1lb3V0KTsKICB9Owp9KSh7InJvb3RJZCI6IlAwLTMxNTQ4NzAwNCIsImludGVydmFsIjo5MDAwLCJpbmZpbml0ZSI6dHJ1ZSwiZGVza3RvcERyYWdnYWJsZSI6ZmFsc2V9KSkp | |
| js | text/javascript | https://s3.amazonaws.com/raichu-beta/selos/bundle.js |
Серверные заголовки
Кол-во: 13
HTTP-заголовки ответа сервера
?
Заголовки сервера передают браузеру и поисковику служебную информацию: кеширование, безопасность (CSP, HSTS), сжатие (gzip). Правильная настройка ускоряет загрузку и повышает защищённость.
Найдены серверные заголовки 13шт. Подробнее про серверные заголовки.
Показать полный список серверных заголовков
| Ключ | Значение |
|---|---|
| Date | Fri, 21 Aug 2026 10:06:56 GMT |
| Cache-Control | public, max-age=180, stale-while-revalidate=3600 |
| Content-Security-Policy | frame-ancestors 'self' https://deco.cx https://www.deco.cx 127.0.0.1:* localhost:* http://localhost:* http://127.0.0.1:* https://admin.deco.cx https://admin-cx.deco.page https://deco.chat https://admin.decocms.com https://decocms.com https://studio.decocms.com |
| Link | </styles.css?revision=685102389&__frsh_c=258db05ee97acd52e729509684b46d672caeb386>; rel=preload; as=style |
| Vary | Accept-Encoding |
| x-deco-platform | kubernetes |
| x-fresh-uuid | 16f0a990-fd93-486e-b735-5c7092177f45 |
| X-Powered-By | deco@1.207.0 |
| x-envoy-upstream-service-time | 70 |
| Server | cloudflare |
| Set-Cookie | __cf_bm=tp567PfIiL407tndnSWceKSC3cxdVZZKRck9GfvMFUM-1787306816.5230856-1.0.1.1-Oj5VyPY5USxW8tbdahlNbWh9vryewn7LYTDqjSGyY3EBJjihqo3Yk7tuClgp6X5XV2YeRrPghv70YKndoGqTPwdmq4Yl0CKNBmmsovLYNPdyUkgMhxirDeZvnBI59QEj; HttpOnly; SameSite=None; Secure; Path=/; Domain=www.farmrio.com.br; Expires=Fri, 21 Aug 2026 10:36:56 GMT |
| cf-cache-status | EXPIRED |
| cf-ray | a2e8d3f348e8e92d-DME |
CMS
Не определена
Система управления сайтом (движок)
?
CMS — это движок, на котором работает сайт (WordPress, 1C-Bitrix, Tilda и др.). Знание CMS помогает понять возможности SEO-оптимизации и подобрать подходящие инструменты. «Не определена» — вероятно, самописный сайт или нестандартная сборка.
CMS не определена. Вероятно, сайт самописный либо движок надёжно скрыт. Это не ошибка.
Веб-сервер
Программное обеспечение сервера
?
Веб-сервер — это ПО, которое отдаёт страницы посетителям (nginx, Apache, IIS, LiteSpeed и др.). Определяется по серверным заголовкам ответа (Server, X-Powered-By и т.п.). «Не определён» — сервер намеренно скрывает эти заголовки, это нормальная практика безопасности.
Сайт работает на веб-сервере Cloudflare.
Мета-теги Готовность: 23%
Title
Novos Looks Originais | Moda Brasileira com Estilo
Заголовок страницы в браузере и поисковой выдаче
?
Title — главный SEO-заголовок страницы. Влияет на CTR в поиске и ранжирование. Оптимальная длина: 50–70 символов. Ключевые слова — ближе к началу.
Необходимо уменьшить число символов в title (текущее значение: 50, оптимально: от 40 до 45)
Дублей словоформ в title не найдено.
Description
Explore a coleção com estampas autorais e designs únicos. Fácil de combinar com outras peças do guarda-roupa. Renove seu estilo agora mesmo!
Описание страницы в поисковой выдаче (сниппет)
?
Meta Description — текст под заголовком в выдаче. Напрямую на позиции не влияет, но влияет на CTR. Оптимальная длина: 120–160 символов.
Необходимо уменьшить число символов в description (текущее значение: 140, оптимально: от 120 до 130)
Keywords
Список ключевых слов страницы (устаревший тег)
?
Meta Keywords не учитывается Яндексом и Google для ранжирования с 2009–2012 годов. Заполнение не обязательно, но не вредит. Конкурент может использовать содержимое для анализа.
Установите мета-тег keywords!
Канонический Url
https://www.farmrio.com.br/
Указывает поисковику основную версию страницы
?
Canonical (rel=canonical) предотвращает проблему дублей страниц. Должен точно совпадать с URL проверяемой страницы. Неправильный canonical может передать ссылочный вес на другую страницу.
Канонический Url прописан корректно.
Robots
index, follow
Директивы для поисковых роботов на уровне страницы
?
Meta Robots управляет индексацией конкретной страницы: index/noindex — индексировать ли, follow/nofollow — следовать ли по ссылкам. Noindex полностью исключает страницу из поиска.
Meta-тег robots со значениями index, follow не накладывает ограничений на индексирование и показ контента.
Адаптивность
width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0
Настройка масштабирования на мобильных устройствах
?
Тег viewport (<meta name="viewport">) сообщает браузеру, как масштабировать страницу на мобильных. Стандарт: width=device-width, initial-scale=1. Отсутствие — признак отсутствия мобильной версии.
Meta-тег viewport со значением-константой width=device-width задаёт ширину страницы в соответствии с размером экрана.
Meta-тег viewport со значением initial-scale=1.0 определяет масштаб 1:1, т.е. «не масштабировать».
Meta-тег viewport со значением user-scalable определяет доступность масштабирования страницы пользователем.
Meta-тег viewport со значением minimum-scale определяет минимальный масштаб области просмотра.
Meta-тег viewport со значением maximum-scale определяет максимальный масштаб области просмотра.
Разметка OpenGraph
Кол-во: 5
Мета-теги для красивых превью в соцсетях
?
OpenGraph (og:title, og:description, og:image) управляет тем, как страница выглядит при репосте в социальных сетях и мессенджерах. Отсутствие OG-тегов — невзрачный превью при шеринге.
Разметка OpenGraph задана. Страница оптимизирована под социальные сети.
Показать полный список og мета-тегов
| Тип | Значение |
|---|---|
| og:title | Novos Looks Originais | Moda Brasileira com Estilo |
| og:description | Explore a coleção com estampas autorais e designs únicos. Fácil de combinar com outras peças do guarda-roupa. Renove seu estilo agora mesmo! |
| og:type | website |
| og:image | https://decoims.com/farmrio/6e2b56df-e143-47f0-9808-e5b3f61589f5/1742399970134-bccb96ce-a9c0-4a90-8c64-db91bbef46bc.png |
| og:url | https://www.farmrio.com.br/ |
Все мета-теги
Кол-во: 14
Полный список мета-тегов страницы
?
Таблица всех meta-тегов, включая нестандартные. Позволяет найти опечатки, дубли и лишние теги.
Найдены мета-теги 14шт. Мета-теги не видимы для человека и предназначены для обмена информацией между веб-страницей и поисковыми системами, браузерами и другими веб-службами. С ними роботы 🤖 и устройства ведут себя более ожидаемо.
Показать полный список мета-тегов
| Тип | Название | Значение |
|---|---|---|
| name | description | Explore a coleção com estampas autorais e designs únicos. Fácil de combinar com outras peças do guarda-roupa. Renove seu estilo agora mesmo! |
| name | theme-color | |
| name | robots | index, follow |
| name | viewport | width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0 |
| name | botify-site-verification | |
| property | twitter:title | Novos Looks Originais | Moda Brasileira com Estilo |
| property | twitter:description | Explore a coleção com estampas autorais e designs únicos. Fácil de combinar com outras peças do guarda-roupa. Renove seu estilo agora mesmo! |
| property | twitter:image | https://decoims.com/farmrio/6e2b56df-e143-47f0-9808-e5b3f61589f5/1742399970134-bccb96ce-a9c0-4a90-8c64-db91bbef46bc.png |
| property | twitter:card | summary |
| property | og:title | Novos Looks Originais | Moda Brasileira com Estilo |
| property | og:description | Explore a coleção com estampas autorais e designs únicos. Fácil de combinar com outras peças do guarda-roupa. Renove seu estilo agora mesmo! |
| property | og:type | website |
| property | og:image | https://decoims.com/farmrio/6e2b56df-e143-47f0-9808-e5b3f61589f5/1742399970134-bccb96ce-a9c0-4a90-8c64-db91bbef46bc.png |
| property | og:url | https://www.farmrio.com.br/ |
Оптимизация Готовность: 35%
Структура
Ошибок нет
Семантические HTML-элементы страницы
?
Проверяет наличие основных структурных элементов: nav, header, footer, main. Корректная семантическая структура помогает поисковику понять архитектуру страницы.
Структура документа корректна (теги <html> и <body> присутствуют по одному на документ).
Контент
Есть ошибки
Объём и качество текстового содержимого
?
Анализирует объём полезного текста на странице. Слишком мало — страница может считаться малополезной. Слишком много — ухудшается читаемость и восприятие.
Среднее число слов в абзаце 5 слишком мало. Сделайте контент более читаемым!
Слова из title 3 встречаются в тексте достаточно.
Абзацев с текстом 66 достаточно.
Кол-во знаков контента 18825 на странице оптимально.
Кол-во слов 1403 на странице оптимально.
Заголовки
Есть ошибки
Иерархия заголовков H1–H6
?
H1 должен быть один и содержать ключевой запрос. H2–H6 описывают подразделы. Пропуск уровней (H1 → H3) и несколько H1 — типичные ошибки, снижающие понятность страницы для поисковика.
Не обнаружено заголовков на странице. Добавьте заголовки (<h1>, <h2> или <h3>)
Тошнота
9,11
Насколько одно слово доминирует в тексте
?
Классическая тошнота = √(частота самого повторяющегося слова). Норма до 7–8: текст воспринимается естественно. Выше — поисковик может счесть страницу переспамленной.
Тошнота превышает норму 5. Измените текст страницы!
Академич. тошнота
14,61%
Насколько текст перенасыщен ключевыми словами
?
Академическая тошнота = (частота слова / общее количество слов) × 100%. Показывает долю конкретного слова в тексте. Норма 5–15%.
Академическая тошнота страницы в пределах нормы.
Семантическое ядро
20
Наиболее часто встречающиеся слова на странице
?
Топ слов по частоте использования. Показывает, какие слова доминируют в тексте с точки зрения поисковика.
Контент страницы содержит осмысленный текст и слова.
Показать список слов
| Слово | Кол-во | Частота |
|---|---|---|
| classlist | 83 | 5,92% |
| remove | 48 | 3,42% |
| checked= | 32 | 2,28% |
| text-white | 22 | 1,57% |
| getelementbyid | 20 | 1,43% |
| btn-outline | 20 | 1,43% |
| bg-white | 20 | 1,43% |
| border-neutral | 20 | 1,43% |
| bg-primary | 18 | 1,28% |
| border-primary | 18 | 1,28% |
| getelementsbyclassname | 14 | 1,00% |
| md:btn-outline-hover | 14 | 1,00% |
| md:text-white | 14 | 1,00% |
| right-2 | 14 | 1,00% |
| md:right-10 | 14 | 1,00% |
| right-120 | 14 | 1,00% |
| checked | 13 | 0,93% |
| produtos | 12 | 0,86% |
| acessórios | 10 | 0,71% |
| foreach | 9 | 0,64% |
Индексация Готовность: 0%
Индексирование
Есть ошибки
Разрешено ли индексирование страницы
?
Проверяет, не закрыта ли страница от индексации через robots.txt, meta robots или X-Robots-Tag. Страница, закрытая от индексации, не появится в поисковой выдаче.
Анкоров на странице 491 слишком много. Проведите ревизию и оптимизацию ссылок сайта.
Robots.txt
Не загружен
Файл управления сканированием сайта роботами
?
Robots.txt указывает поисковым роботам, какие страницы сканировать, а какие — нет. Ошибки в файле могут случайно закрыть важные разделы от индексации.
Файл robots.txt вернул ошибку 0! Проверьте настройки сайта и веб-сервера!
Sitemap
Кол-во: 0
XML-карта сайта для поисковиков
?
Sitemap.xml помогает поисковику быстрее находить и индексировать страницы. Особенно важен для крупных сайтов и новых страниц, на которые ещё нет входящих ссылок.
Robots.txt не содержит ссылку на карту сайта. Рекомендуется добавить карту сайта и указать ссылку на нее в robots.txt.
Внутренние ссылки
Кол-во: 428
Ссылки на другие страницы своего сайта
?
Внутренние ссылки распределяют ссылочный вес между страницами и помогают поисковику обходить сайт. Пустые анкоры и ссылки на запрещённые robots.txt страницы — типичные ошибки.
Внутренних ссылок на странице 428 слишком много. Проведите оптимизацию сайта!
На странице присутствуют изображения 29.
Показать первые 100 внутренних ссылок
| Url | Анкор | Состояние | Анализировать |
|---|---|---|---|
| /fala-farm |
<input type="checkbox" class="input-buttons"><p class="group-has-[input:checked]:hidden text-sm md:text-base font-light text-primary whitespace-nowrap group-hover:md:text-white">Fala Farm</p><svg width="16" height="24" stroke-width="1" class="absolute hidden group-has-[input:checked]:block"><use href="/sprites.svg?__deco_c=2#Help"></use></svg>
|
|
Анализировать url |
| /produtos/promo |
vem!
|
|
Анализировать url |
| /farm-etc |
<span class="flex items-center"><svg stroke-width="16" class="h-10 w-[29px]"><use href="/sprites.svg?__deco_c=2#switch-brand-etc-logo"></use></svg></span><span class="flex items-center"><svg width="23" height="23" stroke-width="16"><use href="/sprites.svg?__deco_c=2#switch-brand-arrow-right"></use></svg></span>
|
|
Анализировать url |
| /novidades |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/stanley |
<span class="flex items-center gap-2"><span class="relative">Stanley 1913 + FARM Rio </span></span>
|
|
Анализировать url |
| /cariocas |
<span class="flex items-center gap-2"><span class="relative">As Cariocas</span></span>
|
|
Анализировать url |
| /ta-na-vitrine |
<span class="flex items-center gap-2"><span class="relative">Tá na vitrine</span></span>
|
|
Анализировать url |
| /produtos |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/vestido |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/vestido-longo |
<span class="flex items-center gap-2"><span class="relative">Longo</span></span>
|
|
Анализировать url |
| /produtos/vestido-curto |
<span class="flex items-center gap-2"><span class="relative">Curto</span></span>
|
|
Анализировать url |
| /produtos/vestido-midi |
<span class="flex items-center gap-2"><span class="relative">Midi</span></span>
|
|
Анализировать url |
| /produtos/vestido-liso |
<span class="flex items-center gap-2"><span class="relative">Liso</span></span>
|
|
Анализировать url |
| /produtos/vestido-com-manga |
<span class="flex items-center gap-2"><span class="relative">Com manga</span></span>
|
|
Анализировать url |
| /produtos/t-shirt |
<span class="flex items-center gap-2"><span class="relative">T-shirts</span></span>
|
|
Анализировать url |
| /produtos/blusa |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/bata |
<span class="flex items-center gap-2"><span class="relative">Bata</span></span>
|
|
Анализировать url |
| /produtos/regata |
<span class="flex items-center gap-2"><span class="relative">Regata</span></span>
|
|
Анализировать url |
| /produtos/camisa |
<span class="flex items-center gap-2"><span class="relative">Camisa</span></span>
|
|
Анализировать url |
| /produtos/top |
<span class="flex items-center gap-2"><span class="relative">Top</span></span>
|
|
Анализировать url |
| /produtos/blusa-manga-longa |
<span class="flex items-center gap-2"><span class="relative">Manga longa</span></span>
|
|
Анализировать url |
| /produtos/coletes |
<span class="flex items-center gap-2"><span class="relative">Colete</span></span>
|
|
Анализировать url |
| /produtos/kimono |
<span class="flex items-center gap-2"><span class="relative">Kimono</span></span>
|
|
Анализировать url |
| /produtos/tunicas |
<span class="flex items-center gap-2"><span class="relative">Túnica</span></span>
|
|
Анализировать url |
| /produtos/body |
<span class="flex items-center gap-2"><span class="relative">Body</span></span>
|
|
Анализировать url |
| /produtos/casaco |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/pelinhos |
<span class="flex items-center gap-2"><span class="relative">Pelinho</span></span>
|
|
Анализировать url |
| /produtos/casaco-tricot |
<span class="flex items-center gap-2"><span class="relative">Tricot</span></span>
|
|
Анализировать url |
| /produtos/jaquetas |
<span class="flex items-center gap-2"><span class="relative">Jaqueta</span></span>
|
|
Анализировать url |
| /produtos/cardigan |
<span class="flex items-center gap-2"><span class="relative">Cardigan</span></span>
|
|
Анализировать url |
| /produtos/moletom |
<span class="flex items-center gap-2"><span class="relative">Moletom</span></span>
|
|
Анализировать url |
| /produtos/saia |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/saia-longa |
<span class="flex items-center gap-2"><span class="relative">Longa</span></span>
|
|
Анализировать url |
| /produtos/saia-curta |
<span class="flex items-center gap-2"><span class="relative">Curta</span></span>
|
|
Анализировать url |
| /produtos/saia-midi |
<span class="flex items-center gap-2"><span class="relative">Midi</span></span>
|
|
Анализировать url |
| /produtos/calca |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/calca-estampada |
<span class="flex items-center gap-2"><span class="relative">Estampada</span></span>
|
|
Анализировать url |
| /produtos/calca-pantalona |
<span class="flex items-center gap-2"><span class="relative">Pantalona</span></span>
|
|
Анализировать url |
| /produtos/calca-jeans |
<span class="flex items-center gap-2"><span class="relative">Jeans</span></span>
|
|
Анализировать url |
| /produtos/calca-aladim |
<span class="flex items-center gap-2"><span class="relative">Aladim</span></span>
|
|
Анализировать url |
| /produtos/calca-capri |
<span class="flex items-center gap-2"><span class="relative">Capri</span></span>
|
|
Анализировать url |
| /produtos/calca-alfaiataria |
<span class="flex items-center gap-2"><span class="relative">Alfaiataria </span></span>
|
|
Анализировать url |
| /produtos/short |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/short-estampado |
<span class="flex items-center gap-2"><span class="relative">Estampado</span></span>
|
|
Анализировать url |
| /produtos/short-jeans |
<span class="flex items-center gap-2"><span class="relative">Jeans</span></span>
|
|
Анализировать url |
| /produtos/bermuda |
<span class="flex items-center gap-2"><span class="relative">Bermuda</span></span>
|
|
Анализировать url |
| /produtos/short-saia |
<span class="flex items-center gap-2"><span class="relative">Short saia</span></span>
|
|
Анализировать url |
| /produtos/short-alfaiataria |
<span class="flex items-center gap-2"><span class="relative">Alfaiataria</span></span>
|
|
Анализировать url |
| /produtos/conjuntos |
<span class="flex items-center gap-2"><span class="relative">Conjuntos</span></span>
|
|
Анализировать url |
| /produtos/lisos |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/vestido-liso |
<span class="flex items-center gap-2"><span class="relative">Vestido</span></span>
|
|
Анализировать url |
| /produtos/partes-de-cima-lisas |
<span class="flex items-center gap-2"><span class="relative">Blusa</span></span>
|
|
Анализировать url |
| /produtos/partes-de-baixo-lisas |
<span class="flex items-center gap-2"><span class="relative">Partes de baixo</span></span>
|
|
Анализировать url |
| /produtos/casaco-liso |
<span class="flex items-center gap-2"><span class="relative">Casaco</span></span>
|
|
Анализировать url |
| /produtos/macacao-liso |
<span class="flex items-center gap-2"><span class="relative">Macacão</span></span>
|
|
Анализировать url |
| /produtos/jeans-refarm |
<span class="flex items-center gap-2"><span class="relative">Jeans</span></span>
|
|
Анализировать url |
| /produtos/macacao |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/macacao-longo |
<span class="flex items-center gap-2"><span class="relative">Longo</span></span>
|
|
Анализировать url |
| /produtos/macaquinho |
<span class="flex items-center gap-2"><span class="relative">Curto</span></span>
|
|
Анализировать url |
| /produtos/praia |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /produtos/praia/biquinis |
<span class="flex items-center gap-2"><span class="relative">Biquíni</span></span>
|
|
Анализировать url |
| /produtos/praia/maios |
<span class="flex items-center gap-2"><span class="relative">Maiô</span></span>
|
|
Анализировать url |
| /produtos/roupas-de-praia |
<span class="flex items-center gap-2"><span class="relative">Saída de praia</span></span>
|
|
Анализировать url |
| /produtos/praia/cangas |
<span class="flex items-center gap-2"><span class="relative">Canga</span></span>
|
|
Анализировать url |
| /produtos/tricot |
<span class="flex items-center gap-2"><span class="relative">Tricot</span></span>
|
|
Анализировать url |
| /bazar |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /bazar/tamanho-pp |
<span class="flex items-center gap-2"><span class="relative">PP</span></span>
|
|
Анализировать url |
| /bazar/tamanho-p |
<span class="flex items-center gap-2"><span class="relative">P</span></span>
|
|
Анализировать url |
| /bazar/tamanho-m |
<span class="flex items-center gap-2"><span class="relative">M</span></span>
|
|
Анализировать url |
| /bazar/tamanho-g |
<span class="flex items-center gap-2"><span class="relative">G</span></span>
|
|
Анализировать url |
| /bazar/tamanho-gg |
<span class="flex items-center gap-2"><span class="relative">GG</span></span>
|
|
Анализировать url |
| /bazar/vestido |
<span class="flex items-center gap-2"><span class="relative">Vestidos</span></span>
|
|
Анализировать url |
| /farm-etc/ver-tudo |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /farm-etc/bazar |
<span class="flex items-center gap-2"><span class="relative">Bazar </span></span>
|
|
Анализировать url |
| /farm-etc/ver-tudo |
<span class="flex items-center gap-2"><span class="relative">Ver tudo</span></span>
|
|
Анализировать url |
| /farm-etc/copo-termico |
<span class="flex items-center gap-2"><span class="relative">Copo</span></span>
|
|
Анализировать url |
| /farm-etc/garrafa |
<span class="flex items-center gap-2"><span class="relative">Garrafa</span></span>
|
|
Анализировать url |
| /farm-etc/bolsa |
<span class="flex items-center gap-2"><span class="relative">Bolsa</span></span>
|
|
Анализировать url |
| /farm-etc/mochila |
<span class="flex items-center gap-2"><span class="relative">Mochila</span></span>
|
|
Анализировать url |
| /farm-etc/chaveiro |
<span class="flex items-center gap-2"><span class="relative">Chaveiro</span></span>
|
|
Анализировать url |
| /farm-etc/para-cabelo |
<span class="flex items-center gap-2"><span class="relative">Pra cabelo</span></span>
|
|
Анализировать url |
| /farm-etc/almofada-viagem |
<span class="flex items-center gap-2"><span class="relative">Almofada de viagem</span></span>
|
|
Анализировать url |
| /farm-etc/lev |
<span class="flex items-center gap-2"><span class="relative">Bike</span></span>
|
|
Анализировать url |
| /farm-etc/boia |
<span class="flex items-center gap-2"><span class="relative">Boia</span></span>
|
|
Анализировать url |
| /farm-etc/bola |
<span class="flex items-center gap-2"><span class="relative">Bola</span></span>
|
|
Анализировать url |
| /farm-etc/bone |
<span class="flex items-center gap-2"><span class="relative">Boné</span></span>
|
|
Анализировать url |
| /farm-etc/caderno |
<span class="flex items-center gap-2"><span class="relative">Caderno</span></span>
|
|
Анализировать url |
| /farm-etc/caixa-de-metal |
<span class="flex items-center gap-2"><span class="relative">Caixa de metal</span></span>
|
|
Анализировать url |
| /farm-etc/caixinha-de-som |
<span class="flex items-center gap-2"><span class="relative">Caixinha de som</span></span>
|
|
Анализировать url |
| /farm-etc/camping |
<span class="flex items-center gap-2"><span class="relative">Camping</span></span>
|
|
Анализировать url |
| /farm-etc/canga |
<span class="flex items-center gap-2"><span class="relative">Canga</span></span>
|
|
Анализировать url |
| /farm-etc/cartao-postal |
<span class="flex items-center gap-2"><span class="relative">Cartão postal</span></span>
|
|
Анализировать url |
| /farm-etc/carteira |
<span class="flex items-center gap-2"><span class="relative">Carteira</span></span>
|
|
Анализировать url |
| /farm-etc/cooler |
<span class="flex items-center gap-2"><span class="relative">Cooler</span></span>
|
|
Анализировать url |
| /farm-etc/corda-celular |
<span class="flex items-center gap-2"><span class="relative">Corda de celular</span></span>
|
|
Анализировать url |
| /farm-etc/espelho |
<span class="flex items-center gap-2"><span class="relative">Espelho de bolsa</span></span>
|
|
Анализировать url |
| /farm-etc/estojo |
<span class="flex items-center gap-2"><span class="relative">Estojo </span></span>
|
|
Анализировать url |
| /farm-etc/fone-de-ouvido |
<span class="flex items-center gap-2"><span class="relative">Fone e headphone</span></span>
|
|
Анализировать url |
| /farm-etc/frescobol |
<span class="flex items-center gap-2"><span class="relative">Frescobol</span></span>
|
|
Анализировать url |
| /farm-etc/lancheira |
<span class="flex items-center gap-2"><span class="relative">Lancheira</span></span>
|
|
Анализировать url |
Внешние ссылки
Кол-во: 21
Ссылки на сторонние сайты
?
Исходящие внешние ссылки передают часть ссылочного веса на чужие сайты. Ссылки на авторитетные ресурсы безопасны; ссылки на мусорные сайты могут навредить репутации страницы.
Внешних ссылок на странице 21 слишком много. Спрячьте лишние ссылки в тег noindex или атрибут rel='nofollow'!
Показать внешние ссылки
| Url | Анкор | Анализировать |
|---|---|---|
| api.whatsapp.com |
<input type="checkbox" class="input-buttons"><p class="group-has-[input:checked]:hidden text-sm md:text-base font-light text-primary whitespace-nowrap group-hover:md:text-white">Whatsapp</p><svg width="16" height="24" stroke-width="1" class="absolute hidden group-has-[input:checked]:block"><use href="/sprites.svg?__deco_c=2#WhatsApp"></use></svg>
|
|
| farmrio.troque.app.br |
Devolução no site
|
Анализировать url |
| farm.gupy.io |
Trabalhe aqui
|
Анализировать url |
| azzas2154.com.br |
Azzas 2154
|
Анализировать url |
| wa.me |
Falar via Whatsapp
|
|
| farmrio.com.ar |
Argentina
|
Анализировать url |
| farmrio.cl |
Chile
|
Анализировать url |
| farmrio.com.co |
Colômbia
|
Анализировать url |
| farmrio.com.py |
Paraguai
|
Анализировать url |
| farmrio.com.pe |
Peru
|
Анализировать url |
| farmrio.com.uy |
Uruguai
|
Анализировать url |
| farmrio.com.bo |
Bolívia
|
Анализировать url |
| farmrio.com.ve |
Venezuela
|
Анализировать url |
| farmrio.com.pa |
Panamá
|
Анализировать url |
| farmrio.com.ec |
Equador
|
Анализировать url |
| facebook.com |
<span><svg width="18" height="18" stroke-width="16" class="md:w-[23px] md:h-auto md:ml-0 ml-[14px]"><use href="/sprites.svg?__deco_c=2#Facebook"></use></svg></span>
|
|
| twitter.com |
<span><svg width="18" height="18" stroke-width="16" class="md:w-[23px] md:h-auto md:ml-0 ml-[14px]"><use href="/sprites.svg?__deco_c=2#Twitter"></use></svg></span>
|
|
| instagram.com |
<span><svg width="18" height="18" stroke-width="16" class="md:w-[23px] md:h-auto md:ml-0 ml-[14px]"><use href="/sprites.svg?__deco_c=2#Instagram"></use></svg></span>
|
|
| br.pinterest.com |
<span><svg width="18" height="18" stroke-width="16" class="md:w-[23px] md:h-auto md:ml-0 ml-[14px]"><use href="/sprites.svg?__deco_c=2#Pinterest"></use></svg></span>
|
Анализировать url |
| youtube.com |
<span><svg width="18" height="18" stroke-width="16" class="md:w-[23px] md:h-auto md:ml-0 ml-[14px]"><use href="/sprites.svg?__deco_c=2#Youtube"></use></svg></span>
|
Анализировать url |
| open.spotify.com |
<span><svg width="18" height="18" stroke-width="16" class="md:w-[23px] md:h-auto md:ml-0 ml-[14px]"><use href="/sprites.svg?__deco_c=2#Spotify"></use></svg></span>
|
Анализировать url |
Конкуренты Готовность: 0%
Конкуренты в Яндексе
Кол-во: 0
Топ сайтов-конкурентов в Яндексе
?
Сайты, чаще всего появляющиеся в ТОПе Яндекса по запросам из семантического ядра этой страницы.
Мы не нашли у вас конкурентов в Яндексе. Сайт или очень молодой или плохо продвигается.
Конкурентов в ТОП-10 Яндекса не нашлось.
Конкуренты в Google
Кол-во: 0
Топ сайтов-конкурентов в Google
?
Сайты, чаще всего появляющиеся в ТОПе Google по запросам из семантического ядра этой страницы.
Конкуренты в Google тоже не найдены. Займитесь продвижением сайта!
Конкурентов в ТОП-10 Google не нашлось.
ЗоЗПП: права потребителей Готовность: 100%
Нарушения
Не выявлены
Признаков дистанционной продажи товаров (интернет-магазина) не обнаружено — требования ЗоЗПП о раскрытии информации продавца к сайту не применяются. Нарушений нет.
ФЗ-149: рекомендательные технологии Готовность: 100%
Нарушения
Не выявлены
Рекомендательные блоки («с этим покупают», «похожие товары» и т.п.) на сайте не обнаружены — требования ст. 10.7 ФЗ-149 к сайту не применяются. Нарушений нет.
ФЗ-38: реклама Готовность: 100%
Нарушения
Не выявлены
Рекламных тематик с обязательными оговорками (медицина, БАД, кредиты и займы, новостройки) на сайте не обнаружено. Нарушений нет.
ФЗ-436: защита детей Готовность: 100%
Нарушения
Не выявлены
Признаков информационной продукции (новости, видео, книги, игры, курсы) не обнаружено — обязательная возрастная маркировка по ФЗ-436 сайту не требуется. Нарушений нет.
Вердикт
Таким сайт farmrio.com.br видят поисковые системы. Процент оптимизации невысокий - 32%. Чтобы улучшить сайт и попасть в ТОП необходимо:
Исправьте ошибки в мета-тегах.
Исправьте ошибки оптимизации.
Исправьте ошибки индексации.
Поделитесь с друзьями: