NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Twitch Chat Emotes // @namespace #Cletus // @version 2.1.5 // @description Adds a button to Twitch that allows you to "click-to-insert" an emote. // @copyright 2011+, Ryan Chatham <ryan.b.chatham@gmail.com> (https://github.com/cletusc) // @author Ryan Chatham <ryan.b.chatham@gmail.com> (https://github.com/cletusc) // @icon http://www.gravatar.com/avatar.php?gravatar_id=6875e83aa6c563790cb2da914aaba8b3&r=PG&s=48&default=identicon // @license MIT; http://opensource.org/licenses/MIT // @license CC BY-NC-SA 3.0; http://creativecommons.org/licenses/by-nc-sa/3.0/ // @homepage http://cletusc.github.io/Userscript--Twitch-Chat-Emotes/ // @supportURL https://github.com/cletusc/Userscript--Twitch-Chat-Emotes/issues // @contributionURL http://cletusc.github.io/Userscript--Twitch-Chat-Emotes/#donate // @grant none // @include http://*.twitch.tv/* // @include https://*.twitch.tv/* // @exclude http://api.twitch.tv/* // @exclude https://api.twitch.tv/* // @exclude http://tmi.twitch.tv/* // @exclude https://tmi.twitch.tv/* // @exclude http://*.twitch.tv/*/dashboard // @exclude https://*.twitch.tv/*/dashboard // @exclude http://chatdepot.twitch.tv/* // @exclude https://chatdepot.twitch.tv/* // @exclude http://im.twitch.tv/* // @exclude https://im.twitch.tv/* // @exclude http://platform.twitter.com/* // @exclude https://platform.twitter.com/* // @exclude http://www.facebook.com/* // @exclude https://www.facebook.com/* // ==/UserScript== /* Script compiled using build script. Script uses Browserify for CommonJS modules. */ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ var pkg = require('../package.json'); var publicApi = require('./modules/public-api'); var ember = require('./modules/ember-api'); var logger = require('./modules/logger'); var emotes = require('./modules/emotes'); var ui = require('./modules/ui'); logger.log('(v'+ pkg.version + ') Initial load on ' + location.href); // Only enable script if we have the right variables. //--------------------------------------------------- var initTimer = 0; (function init(time) { if (!time) { time = 0; } var objectsLoaded = ( window.Twitch !== undefined && window.jQuery !== undefined && ember.isLoaded() ); if (!objectsLoaded) { // Stops trying after 10 minutes. if (initTimer >= 600000) { logger.log('Taking too long to load, stopping. Refresh the page to try again. (' + initTimer + 'ms)'); return; } // Give an update every 10 seconds. if (initTimer % 10000) { logger.debug('Still waiting for objects to load. (' + initTimer + 'ms)'); } // Bump time up after 1s to reduce possible lag. time = time >= 1000 ? 1000 : time + 25; initTimer += time; setTimeout(init, time, time); return; } // Expose public api. if (typeof window.emoteMenu === 'undefined') { window.emoteMenu = publicApi; } ember.hook('route:channel', activate, deactivate); ember.hook('route:chat', activate, deactivate); activate(); })(); function activate() { ui.init(); emotes.init(); } function deactivate() { ui.hideMenu(); } },{"../package.json":7,"./modules/ember-api":8,"./modules/emotes":9,"./modules/logger":10,"./modules/public-api":11,"./modules/ui":15}],2:[function(require,module,exports){ (function (doc, cssText) { var id = "emote-menu-for-twitch-styles"; var styleEl = doc.getElementById(id); if (!styleEl) { styleEl = doc.createElement("style"); styleEl.id = id; doc.getElementsByTagName("head")[0].appendChild(styleEl); } if (styleEl.styleSheet) { if (!styleEl.styleSheet.disabled) { styleEl.styleSheet.cssText = cssText; } } else { try { styleEl.innerHTML = cssText; } catch (ignore) { styleEl.innerText = cssText; } } }(document, "/**\n" + " * Minified style.\n" + " * Original filename: \\node_modules\\jquery.scrollbar\\jquery.scrollbar.css\n" + " */\n" + ".scroll-wrapper{overflow:hidden!important;padding:0!important;position:relative}.scroll-wrapper>.scroll-content{border:none!important;-moz-box-sizing:content-box!important;box-sizing:content-box!important;height:auto;left:0;margin:0;max-height:none!important;max-width:none!important;overflow:scroll!important;padding:0;position:relative!important;top:0;width:auto!important}.scroll-wrapper>.scroll-content::-webkit-scrollbar{height:0;width:0}.scroll-element{display:none}.scroll-element,.scroll-element div{-moz-box-sizing:content-box;box-sizing:content-box}.scroll-element.scroll-x.scroll-scrollx_visible,.scroll-element.scroll-y.scroll-scrolly_visible{display:block}.scroll-element .scroll-arrow,.scroll-element .scroll-bar{cursor:default}.scroll-textarea{border:1px solid #ccc;border-top-color:#999}.scroll-textarea>.scroll-content{overflow:hidden!important}.scroll-textarea>.scroll-content>textarea{border:none!important;-moz-box-sizing:border-box;box-sizing:border-box;height:100%!important;margin:0;max-height:none!important;max-width:none!important;overflow:scroll!important;outline:0;padding:2px;position:relative!important;top:0;width:100%!important}.scroll-textarea>.scroll-content>textarea::-webkit-scrollbar{height:0;width:0}.scrollbar-inner>.scroll-element,.scrollbar-inner>.scroll-element div{border:none;margin:0;padding:0;position:absolute;z-index:10}.scrollbar-inner>.scroll-element div{display:block;height:100%;left:0;top:0;width:100%}.scrollbar-inner>.scroll-element.scroll-x{bottom:2px;height:8px;left:0;width:100%}.scrollbar-inner>.scroll-element.scroll-y{height:100%;right:2px;top:0;width:8px}.scrollbar-inner>.scroll-element .scroll-element_outer{overflow:hidden}.scrollbar-inner>.scroll-element .scroll-bar,.scrollbar-inner>.scroll-element .scroll-element_outer,.scrollbar-inner>.scroll-element .scroll-element_track{border-radius:8px}.scrollbar-inner>.scroll-element .scroll-bar,.scrollbar-inner>.scroll-element .scroll-element_track{-ms-filter:\"progid:DXImageTransform.Microsoft.Alpha(Opacity=40)\";filter:alpha(opacity=40);opacity:.4}.scrollbar-inner>.scroll-element .scroll-element_track{background-color:#e0e0e0}.scrollbar-inner>.scroll-element .scroll-bar{background-color:#c2c2c2}.scrollbar-inner>.scroll-element.scroll-draggable .scroll-bar,.scrollbar-inner>.scroll-element:hover .scroll-bar{background-color:#919191}.scrollbar-inner>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track{left:-12px}.scrollbar-inner>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track{top:-12px}.scrollbar-inner>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size{left:-12px}.scrollbar-inner>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size{top:-12px}.scrollbar-outer>.scroll-element,.scrollbar-outer>.scroll-element div{border:none;margin:0;padding:0;position:absolute;z-index:10}.scrollbar-outer>.scroll-element{background-color:#fff}.scrollbar-outer>.scroll-element div{display:block;height:100%;left:0;top:0;width:100%}.scrollbar-outer>.scroll-element.scroll-x{bottom:0;height:12px;left:0;width:100%}.scrollbar-outer>.scroll-element.scroll-y{height:100%;right:0;top:0;width:12px}.scrollbar-outer>.scroll-element.scroll-x .scroll-element_outer{height:8px;top:2px}.scrollbar-outer>.scroll-element.scroll-y .scroll-element_outer{left:2px;width:8px}.scrollbar-outer>.scroll-element .scroll-element_outer{overflow:hidden}.scrollbar-outer>.scroll-element .scroll-element_track{background-color:#eee}.scrollbar-outer>.scroll-element .scroll-bar,.scrollbar-outer>.scroll-element .scroll-element_outer,.scrollbar-outer>.scroll-element .scroll-element_track{border-radius:8px}.scrollbar-outer>.scroll-element .scroll-bar{background-color:#d9d9d9}.scrollbar-outer>.scroll-element .scroll-bar:hover{background-color:#c2c2c2}.scrollbar-outer>.scroll-element.scroll-draggable .scroll-bar{background-color:#919191}.scrollbar-outer>.scroll-content.scroll-scrolly_visible{left:-12px;margin-left:12px}.scrollbar-outer>.scroll-content.scroll-scrollx_visible{top:-12px;margin-top:12px}.scrollbar-outer>.scroll-element.scroll-x .scroll-bar{min-width:10px}.scrollbar-outer>.scroll-element.scroll-y .scroll-bar{min-height:10px}.scrollbar-outer>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track{left:-14px}.scrollbar-outer>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track{top:-14px}.scrollbar-outer>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size{left:-14px}.scrollbar-outer>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size{top:-14px}.scrollbar-macosx>.scroll-element,.scrollbar-macosx>.scroll-element div{background:0 0;border:none;margin:0;padding:0;position:absolute;z-index:10}.scrollbar-macosx>.scroll-element div{display:block;height:100%;left:0;top:0;width:100%}.scrollbar-macosx>.scroll-element .scroll-element_track{display:none}.scrollbar-macosx>.scroll-element .scroll-bar{background-color:#6C6E71;display:block;-ms-filter:\"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)\";filter:alpha(opacity=0);opacity:0;border-radius:7px;transition:opacity .2s linear}.scrollbar-macosx:hover>.scroll-element .scroll-bar,.scrollbar-macosx>.scroll-element.scroll-draggable .scroll-bar{-ms-filter:\"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)\";filter:alpha(opacity=70);opacity:.7}.scrollbar-macosx>.scroll-element.scroll-x{bottom:0;height:0;left:0;min-width:100%;overflow:visible;width:100%}.scrollbar-macosx>.scroll-element.scroll-y{height:100%;min-height:100%;right:0;top:0;width:0}.scrollbar-macosx>.scroll-element.scroll-x .scroll-bar{height:7px;min-width:10px;top:-9px}.scrollbar-macosx>.scroll-element.scroll-y .scroll-bar{left:-9px;min-height:10px;width:7px}.scrollbar-macosx>.scroll-element.scroll-x .scroll-element_outer{left:2px}.scrollbar-macosx>.scroll-element.scroll-x .scroll-element_size{left:-4px}.scrollbar-macosx>.scroll-element.scroll-y .scroll-element_outer{top:2px}.scrollbar-macosx>.scroll-element.scroll-y .scroll-element_size{top:-4px}.scrollbar-macosx>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size{left:-11px}.scrollbar-macosx>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size{top:-11px}.scrollbar-light>.scroll-element,.scrollbar-light>.scroll-element div{border:none;margin:0;overflow:hidden;padding:0;position:absolute;z-index:10}.scrollbar-light>.scroll-element{background-color:#fff}.scrollbar-light>.scroll-element div{display:block;height:100%;left:0;top:0;width:100%}.scrollbar-light>.scroll-element .scroll-element_outer{border-radius:10px}.scrollbar-light>.scroll-element .scroll-element_size{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiZGJkYiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlOGU4ZTgiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);background:linear-gradient(to right,#dbdbdb 0,#e8e8e8 100%);border-radius:10px}.scrollbar-light>.scroll-element.scroll-x{bottom:0;height:17px;left:0;min-width:100%;width:100%}.scrollbar-light>.scroll-element.scroll-y{height:100%;min-height:100%;right:0;top:0;width:17px}.scrollbar-light>.scroll-element .scroll-bar{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZmVmZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNWY1ZjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);background:linear-gradient(to right,#fefefe 0,#f5f5f5 100%);border:1px solid #dbdbdb;border-radius:10px}.scrollbar-light>.scroll-content.scroll-scrolly_visible{left:-17px;margin-left:17px}.scrollbar-light>.scroll-content.scroll-scrollx_visible{top:-17px;margin-top:17px}.scrollbar-light>.scroll-element.scroll-x .scroll-bar{height:10px;min-width:10px;top:0}.scrollbar-light>.scroll-element.scroll-y .scroll-bar{left:0;min-height:10px;width:10px}.scrollbar-light>.scroll-element.scroll-x .scroll-element_outer{height:12px;left:2px;top:2px}.scrollbar-light>.scroll-element.scroll-x .scroll-element_size{left:-4px}.scrollbar-light>.scroll-element.scroll-y .scroll-element_outer{left:2px;top:2px;width:12px}.scrollbar-light>.scroll-element.scroll-y .scroll-element_size{top:-4px}.scrollbar-light>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size{left:-19px}.scrollbar-light>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size{top:-19px}.scrollbar-light>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track{left:-19px}.scrollbar-light>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track{top:-19px}.scrollbar-rail>.scroll-element,.scrollbar-rail>.scroll-element div{border:none;margin:0;overflow:hidden;padding:0;position:absolute;z-index:10}.scrollbar-rail>.scroll-element{background-color:#fff}.scrollbar-rail>.scroll-element div{display:block;height:100%;left:0;top:0;width:100%}.scrollbar-rail>.scroll-element .scroll-element_size{background-color:#999;background-color:rgba(0,0,0,.3)}.scrollbar-rail>.scroll-element .scroll-element_outer:hover .scroll-element_size{background-color:#666;background-color:rgba(0,0,0,.5)}.scrollbar-rail>.scroll-element.scroll-x{bottom:0;height:12px;left:0;min-width:100%;padding:3px 0 2px;width:100%}.scrollbar-rail>.scroll-element.scroll-y{height:100%;min-height:100%;padding:0 2px 0 3px;right:0;top:0;width:12px}.scrollbar-rail>.scroll-element .scroll-bar{background-color:#d0b9a0;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.5)}.scrollbar-rail>.scroll-element .scroll-element_outer:hover .scroll-bar{box-shadow:1px 1px 3px rgba(0,0,0,.6)}.scrollbar-rail>.scroll-content.scroll-scrolly_visible{left:-17px;margin-left:17px}.scrollbar-rail>.scroll-content.scroll-scrollx_visible{margin-top:17px;top:-17px}.scrollbar-rail>.scroll-element.scroll-x .scroll-bar{height:10px;min-width:10px;top:1px}.scrollbar-rail>.scroll-element.scroll-y .scroll-bar{left:1px;min-height:10px;width:10px}.scrollbar-rail>.scroll-element.scroll-x .scroll-element_outer{height:15px;left:5px}.scrollbar-rail>.scroll-element.scroll-x .scroll-element_size{height:2px;left:-10px;top:5px}.scrollbar-rail>.scroll-element.scroll-y .scroll-element_outer{top:5px;width:15px}.scrollbar-rail>.scroll-element.scroll-y .scroll-element_size{left:5px;top:-10px;width:2px}.scrollbar-rail>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size{left:-25px}.scrollbar-rail>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size{top:-25px}.scrollbar-rail>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track{left:-25px}.scrollbar-rail>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track{top:-25px}.scrollbar-dynamic>.scroll-element,.scrollbar-dynamic>.scroll-element div{background:0 0;border:none;margin:0;padding:0;position:absolute;z-index:10}.scrollbar-dynamic>.scroll-element div{display:block;height:100%;left:0;top:0;width:100%}.scrollbar-dynamic>.scroll-element.scroll-x{bottom:2px;height:7px;left:0;min-width:100%;width:100%}.scrollbar-dynamic>.scroll-element.scroll-y{height:100%;min-height:100%;right:2px;top:0;width:7px}.scrollbar-dynamic>.scroll-element .scroll-element_outer{opacity:.3;border-radius:12px}.scrollbar-dynamic>.scroll-element .scroll-element_size{background-color:#ccc;opacity:0;border-radius:12px;transition:opacity .2s}.scrollbar-dynamic>.scroll-element .scroll-bar{background-color:#6c6e71;border-radius:7px}.scrollbar-dynamic>.scroll-element.scroll-x .scroll-bar{bottom:0;height:7px;min-width:24px;top:auto}.scrollbar-dynamic>.scroll-element.scroll-y .scroll-bar{left:auto;min-height:24px;right:0;width:7px}.scrollbar-dynamic>.scroll-element.scroll-x .scroll-element_outer{bottom:0;top:auto;left:2px;transition:height .2s}.scrollbar-dynamic>.scroll-element.scroll-y .scroll-element_outer{left:auto;right:0;top:2px;transition:width .2s}.scrollbar-dynamic>.scroll-element.scroll-x .scroll-element_size{left:-4px}.scrollbar-dynamic>.scroll-element.scroll-y .scroll-element_size{top:-4px}.scrollbar-dynamic>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size{left:-11px}.scrollbar-dynamic>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size{top:-11px}.scrollbar-dynamic>.scroll-element.scroll-draggable .scroll-element_outer,.scrollbar-dynamic>.scroll-element:hover .scroll-element_outer{overflow:hidden;-ms-filter:\"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)\";filter:alpha(opacity=70);opacity:.7}.scrollbar-dynamic>.scroll-element.scroll-draggable .scroll-element_outer .scroll-element_size,.scrollbar-dynamic>.scroll-element:hover .scroll-element_outer .scroll-element_size{opacity:1}.scrollbar-dynamic>.scroll-element.scroll-draggable .scroll-element_outer .scroll-bar,.scrollbar-dynamic>.scroll-element:hover .scroll-element_outer .scroll-bar{height:100%;width:100%;border-radius:12px}.scrollbar-dynamic>.scroll-element.scroll-x.scroll-draggable .scroll-element_outer,.scrollbar-dynamic>.scroll-element.scroll-x:hover .scroll-element_outer{height:20px;min-height:7px}.scrollbar-dynamic>.scroll-element.scroll-y.scroll-draggable .scroll-element_outer,.scrollbar-dynamic>.scroll-element.scroll-y:hover .scroll-element_outer{min-width:7px;width:20px}.scrollbar-chrome>.scroll-element,.scrollbar-chrome>.scroll-element div{border:none;margin:0;overflow:hidden;padding:0;position:absolute;z-index:10}.scrollbar-chrome>.scroll-element{background-color:#fff}.scrollbar-chrome>.scroll-element div{display:block;height:100%;left:0;top:0;width:100%}.scrollbar-chrome>.scroll-element .scroll-element_track{background:#f1f1f1;border:1px solid #dbdbdb}.scrollbar-chrome>.scroll-element.scroll-x{bottom:0;height:16px;left:0;min-width:100%;width:100%}.scrollbar-chrome>.scroll-element.scroll-y{height:100%;min-height:100%;right:0;top:0;width:16px}.scrollbar-chrome>.scroll-element .scroll-bar{background-color:#d9d9d9;border:1px solid #bdbdbd;cursor:default;border-radius:2px}.scrollbar-chrome>.scroll-element .scroll-bar:hover{background-color:#c2c2c2;border-color:#a9a9a9}.scrollbar-chrome>.scroll-element.scroll-draggable .scroll-bar{background-color:#919191;border-color:#7e7e7e}.scrollbar-chrome>.scroll-content.scroll-scrolly_visible{left:-16px;margin-left:16px}.scrollbar-chrome>.scroll-content.scroll-scrollx_visible{top:-16px;margin-top:16px}.scrollbar-chrome>.scroll-element.scroll-x .scroll-bar{height:8px;min-width:10px;top:3px}.scrollbar-chrome>.scroll-element.scroll-y .scroll-bar{left:3px;min-height:10px;width:8px}.scrollbar-chrome>.scroll-element.scroll-x .scroll-element_outer{border-left:1px solid #dbdbdb}.scrollbar-chrome>.scroll-element.scroll-x .scroll-element_track{height:14px;left:-3px}.scrollbar-chrome>.scroll-element.scroll-x .scroll-element_size{height:14px;left:-4px}.scrollbar-chrome>.scroll-element.scroll-y .scroll-element_outer{border-top:1px solid #dbdbdb}.scrollbar-chrome>.scroll-element.scroll-y .scroll-element_track{top:-3px;width:14px}.scrollbar-chrome>.scroll-element.scroll-y .scroll-element_size{top:-4px;width:14px}.scrollbar-chrome>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size{left:-19px}.scrollbar-chrome>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size{top:-19px}.scrollbar-chrome>.scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track{left:-19px}.scrollbar-chrome>.scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track{top:-19px}\n" + "/**\n" + " * Minified style.\n" + " * Original filename: \\src\\styles\\style.css\n" + " */\n" + "@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}#emote-menu-button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKUSURBVDhPfZTNi1JRGMZvMIsWUZts5SIXFYK0CME/IGghxVC7WUoU1NBixI+mRSD4MQzmxziKO3XUBhRmUGZKdBG40XEGU6d0GFGZcT4qxW1hi7fzvNwZqKwDD5z7vs/vueeee+6VMJxO5wUhhdvtfuHz+T4tLS2NhegfGsMDLxiwHIIhLi57PJ75VCr1Y39/n4bDIY1Go4lCDx54wYCVYzjoVjQa/dxutyfCkwSvYJpgOSQf708tuBa1yWRy/L+V/Cl4wYBFhhTxfLhum/esiiJ1u12KRCJksVhofX2dTk5OzkHMUUMPHnjB2F55VpEhPde/Lbx8FqBEIkHpdJoMBgNptVrS6XRUqVTOg7a3t2lmZob0ej2p1Wr2ggGLDOnJ3QSZH4coHo/TysoKhygUCtJoNFQsFmkwGLAwR7hSqSSVSsVeMGCRIT29F6fXJi8Xy+Uymc1mmp6eJofDQfV6nU5PT1mY2+127uHxSqUSh4FFhhQLvrvtcrm+YpkHBwdUrVZpa2uLarUadTodOjw8ZGGOGnrwwAsGLDLw1i4uLrzRYeOOj49pb2+Pdnd3qdVq8StGAIQ5ao1Ggz3wggGLDD4C4izcEcWfR0dHbMrlcrSxscGbjVAIK8lms7S5ucmB/X6fXz9YDsEQFzdjsVit2Wzyqc1kMrwfVquVjEYjzc3NkclkIpvNRmtra+yBVzAfBXtDjuGgS8FgcFbc8QvuhjNSKBQoFAqR6LFEn/L5PPfggXd5eXkWrBzDQdC1QCBgFoeut7Ozw/tyBp2FQzhPwtOFFwzY34Yo4A9wRXzdD8LhcE48wncE9no9Fuaoid574bkPLxgZ/3uI5pTQVfFlP/L7/Wmhb7JSXq/3IXrwyHZ5SNIvGCnqyh+J7+gAAAAASUVORK5CYII=)!important;background-position:50%;background-repeat:no-repeat;cursor:pointer;height:30px;width:30px}#emote-menu-button:focus{box-shadow:none}#emote-menu-button.active{box-shadow:0 0 6px 0 #7d5bbe,inset 0 0 0 1px rgba(100,65,164,.5)}.emote-menu{padding:5px;z-index:1000;display:none;background-color:#202020;position:absolute}.emote-menu a{color:#fff}.emote-menu a:hover{cursor:pointer;text-decoration:underline;color:#ccc}.emote-menu .emotes-starred{height:38px}.emote-menu .draggable{background-image:repeating-linear-gradient(45deg,transparent,transparent 5px,rgba(255,255,255,.05) 5px,rgba(255,255,255,.05) 10px);cursor:move;height:7px;margin-bottom:3px}.emote-menu .draggable:hover{background-image:repeating-linear-gradient(45deg,transparent,transparent 5px,rgba(255,255,255,.1) 5px,rgba(255,255,255,.1) 10px)}.emote-menu .header-info{border-top:1px solid #000;box-shadow:0 1px 0 rgba(255,255,255,.05) inset;background-image:linear-gradient(to top,transparent,rgba(0,0,0,.5));padding:2px;color:#ddd;text-align:center;position:relative}.emote-menu .header-info img{margin-right:8px}.emote-menu .emote{display:inline-block;padding:2px;margin:1px;cursor:pointer;border-radius:5px;text-align:center;position:relative;width:30px;height:30px;transition:all .25s ease;border:1px solid transparent}.emote-menu.editing .emote{cursor:auto}.emote-menu .emote img{max-width:100%;max-height:100%;margin:auto;position:absolute;top:0;bottom:0;left:0;right:0}.emote-menu .single-row .emote-container{overflow:hidden;height:37px}.emote-menu .single-row .emote{display:inline-block;margin-bottom:100px}.emote-menu .emote:hover{background-color:rgba(255,255,255,.1)}.emote-menu .pull-left{float:left}.emote-menu .pull-right{float:right}.emote-menu .footer{text-align:center;border-top:1px solid #000;box-shadow:0 1px 0 rgba(255,255,255,.05) inset;padding:5px 0 2px;margin-top:5px;height:18px}.emote-menu .footer .pull-left{margin-right:5px}.emote-menu .footer .pull-right{margin-left:5px}.emote-menu .icon{height:16px;width:16px;opacity:.5;background-size:contain!important}.emote-menu .icon:hover{opacity:1}.emote-menu .icon-home{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8IS0tIENyZWF0ZWQgd2l0aCBJbmtzY2FwZSAoaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvKSAtLT4NCg0KPHN2Zw0KICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIg0KICAgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyINCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyINCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB2ZXJzaW9uPSIxLjEiDQogICB3aWR0aD0iNjQiDQogICBoZWlnaHQ9IjY0Ig0KICAgdmlld0JveD0iMCAwIDY0IDY0Ig0KICAgaWQ9IkNhcGFfMSINCiAgIHhtbDpzcGFjZT0icHJlc2VydmUiPjxtZXRhZGF0YQ0KICAgaWQ9Im1ldGFkYXRhMzAwMSI+PHJkZjpSREY+PGNjOldvcmsNCiAgICAgICByZGY6YWJvdXQ9IiI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUNCiAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+PGRjOnRpdGxlPjwvZGM6dGl0bGU+PC9jYzpXb3JrPjwvcmRmOlJERj48L21ldGFkYXRhPjxkZWZzDQogICBpZD0iZGVmczI5OTkiIC8+DQo8cGF0aA0KICAgZD0ibSA1Ny4wNjIsMzEuMzk4IGMgMC45MzIsLTEuMDI1IDAuODQyLC0yLjU5NiAtMC4yMDEsLTMuNTA4IEwgMzMuODg0LDcuNzg1IEMgMzIuODQxLDYuODczIDMxLjE2OSw2Ljg5MiAzMC4xNDgsNy44MjggTCA3LjA5MywyOC45NjIgYyAtMS4wMjEsMC45MzYgLTEuMDcxLDIuNTA1IC0wLjExMSwzLjUwMyBsIDAuNTc4LDAuNjAyIGMgMC45NTksMC45OTggMi41MDksMS4xMTcgMy40NiwwLjI2NSBsIDEuNzIzLC0xLjU0MyB2IDIyLjU5IGMgMCwxLjM4NiAxLjEyMywyLjUwOCAyLjUwOCwyLjUwOCBoIDguOTg3IGMgMS4zODUsMCAyLjUwOCwtMS4xMjIgMi41MDgsLTIuNTA4IFYgMzguNTc1IGggMTEuNDYzIHYgMTUuODA0IGMgLTAuMDIsMS4zODUgMC45NzEsMi41MDcgMi4zNTYsMi41MDcgaCA5LjUyNCBjIDEuMzg1LDAgMi41MDgsLTEuMTIyIDIuNTA4LC0yLjUwOCBWIDMyLjEwNyBjIDAsMCAwLjQ3NiwwLjQxNyAxLjA2MywwLjkzMyAwLjU4NiwwLjUxNSAxLjgxNywwLjEwMiAyLjc0OSwtMC45MjQgbCAwLjY1MywtMC43MTggeiINCiAgIGlkPSJwYXRoMjk5NSINCiAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjEiIC8+DQo8L3N2Zz4=) 50% no-repeat}.emote-menu .icon-gear{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8IS0tIENyZWF0ZWQgd2l0aCBJbmtzY2FwZSAoaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvKSAtLT4NCg0KPHN2Zw0KICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIg0KICAgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyINCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyINCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB2ZXJzaW9uPSIxLjEiDQogICB3aWR0aD0iMjEuNTkiDQogICBoZWlnaHQ9IjIxLjEzNjk5OSINCiAgIHZpZXdCb3g9IjAgMCAyMS41OSAyMS4xMzciDQogICBpZD0iQ2FwYV8xIg0KICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhDQogICBpZD0ibWV0YWRhdGEzOSI+PHJkZjpSREY+PGNjOldvcmsNCiAgICAgICByZGY6YWJvdXQ9IiI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUNCiAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+PGRjOnRpdGxlPjwvZGM6dGl0bGU+PC9jYzpXb3JrPjwvcmRmOlJERj48L21ldGFkYXRhPjxkZWZzDQogICBpZD0iZGVmczM3IiAvPg0KPHBhdGgNCiAgIGQ9Ik0gMTguNjIyLDguMTQ1IDE4LjA3Nyw2Ljg1IGMgMCwwIDEuMjY4LC0yLjg2MSAxLjE1NiwtMi45NzEgTCAxNy41NTQsMi4yNCBDIDE3LjQzOCwyLjEyNyAxNC41NzYsMy40MzMgMTQuNTc2LDMuNDMzIEwgMTMuMjU2LDIuOSBDIDEzLjI1NiwyLjkgMTIuMDksMCAxMS45MywwIEggOS41NjEgQyA5LjM5NiwwIDguMzE3LDIuOTA2IDguMzE3LDIuOTA2IEwgNi45OTksMy40NDEgYyAwLDAgLTIuOTIyLC0xLjI0MiAtMy4wMzQsLTEuMTMxIEwgMi4yODksMy45NTEgQyAyLjE3Myw0LjA2NCAzLjUwNyw2Ljg2NyAzLjUwNyw2Ljg2NyBMIDIuOTYyLDguMTYgQyAyLjk2Miw4LjE2IDAsOS4zMDEgMCw5LjQ1NSB2IDIuMzIyIGMgMCwwLjE2MiAyLjk2OSwxLjIxOSAyLjk2OSwxLjIxOSBsIDAuNTQ1LDEuMjkxIGMgMCwwIC0xLjI2OCwyLjg1OSAtMS4xNTcsMi45NjkgbCAxLjY3OCwxLjY0MyBjIDAuMTE0LDAuMTExIDIuOTc3LC0xLjE5NSAyLjk3NywtMS4xOTUgbCAxLjMyMSwwLjUzNSBjIDAsMCAxLjE2NiwyLjg5OCAxLjMyNywyLjg5OCBoIDIuMzY5IGMgMC4xNjQsMCAxLjI0NCwtMi45MDYgMS4yNDQsLTIuOTA2IGwgMS4zMjIsLTAuNTM1IGMgMCwwIDIuOTE2LDEuMjQyIDMuMDI5LDEuMTMzIGwgMS42NzgsLTEuNjQxIGMgMC4xMTcsLTAuMTE1IC0xLjIyLC0yLjkxNiAtMS4yMiwtMi45MTYgbCAwLjU0NCwtMS4yOTMgYyAwLDAgMi45NjMsLTEuMTQzIDIuOTYzLC0xLjI5OSBWIDkuMzYgQyAyMS41OSw5LjE5OSAxOC42MjIsOC4xNDUgMTguNjIyLDguMTQ1IHogbSAtNC4zNjYsMi40MjMgYyAwLDEuODY3IC0xLjU1MywzLjM4NyAtMy40NjEsMy4zODcgLTEuOTA2LDAgLTMuNDYxLC0xLjUyIC0zLjQ2MSwtMy4zODcgMCwtMS44NjcgMS41NTUsLTMuMzg1IDMuNDYxLC0zLjM4NSAxLjkwOSwwLjAwMSAzLjQ2MSwxLjUxOCAzLjQ2MSwzLjM4NSB6Ig0KICAgaWQ9InBhdGgzIg0KICAgc3R5bGU9ImZpbGw6I0ZGRkZGRiIgLz4NCjxnDQogICBpZD0iZzUiPg0KPC9nPg0KPGcNCiAgIGlkPSJnNyI+DQo8L2c+DQo8Zw0KICAgaWQ9Imc5Ij4NCjwvZz4NCjxnDQogICBpZD0iZzExIj4NCjwvZz4NCjxnDQogICBpZD0iZzEzIj4NCjwvZz4NCjxnDQogICBpZD0iZzE1Ij4NCjwvZz4NCjxnDQogICBpZD0iZzE3Ij4NCjwvZz4NCjxnDQogICBpZD0iZzE5Ij4NCjwvZz4NCjxnDQogICBpZD0iZzIxIj4NCjwvZz4NCjxnDQogICBpZD0iZzIzIj4NCjwvZz4NCjxnDQogICBpZD0iZzI1Ij4NCjwvZz4NCjxnDQogICBpZD0iZzI3Ij4NCjwvZz4NCjxnDQogICBpZD0iZzI5Ij4NCjwvZz4NCjxnDQogICBpZD0iZzMxIj4NCjwvZz4NCjxnDQogICBpZD0iZzMzIj4NCjwvZz4NCjwvc3ZnPg0K) 50% no-repeat}.emote-menu.editing .icon-gear{-webkit-animation:spin 4s linear infinite;animation:spin 4s linear infinite}.emote-menu .icon-resize-handle{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8IS0tIENyZWF0ZWQgd2l0aCBJbmtzY2FwZSAoaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvKSAtLT4NCg0KPHN2Zw0KICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIg0KICAgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyINCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyINCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB2ZXJzaW9uPSIxLjEiDQogICB3aWR0aD0iMTYiDQogICBoZWlnaHQ9IjE2Ig0KICAgdmlld0JveD0iMCAwIDE2IDE2Ig0KICAgaWQ9IkNhcGFfMSINCiAgIHhtbDpzcGFjZT0icHJlc2VydmUiPjxtZXRhZGF0YQ0KICAgaWQ9Im1ldGFkYXRhNDM1NyI+PHJkZjpSREY+PGNjOldvcmsNCiAgICAgICByZGY6YWJvdXQ9IiI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUNCiAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+PGRjOnRpdGxlPjwvZGM6dGl0bGU+PC9jYzpXb3JrPjwvcmRmOlJERj48L21ldGFkYXRhPjxkZWZzDQogICBpZD0iZGVmczQzNTUiIC8+DQo8cGF0aA0KICAgZD0iTSAxMy41LDggQyAxMy4yMjUsOCAxMyw4LjIyNCAxMyw4LjUgdiAzLjc5MyBMIDMuNzA3LDMgSCA3LjUgQyA3Ljc3NiwzIDgsMi43NzYgOCwyLjUgOCwyLjIyNCA3Ljc3NiwyIDcuNSwyIGggLTUgTCAyLjMwOSwyLjAzOSAyLjE1LDIuMTQ0IDIuMTQ2LDIuMTQ2IDIuMTQzLDIuMTUyIDIuMDM5LDIuMzA5IDIsMi41IHYgNSBDIDIsNy43NzYgMi4yMjQsOCAyLjUsOCAyLjc3Niw4IDMsNy43NzYgMyw3LjUgViAzLjcwNyBMIDEyLjI5MywxMyBIIDguNSBDIDguMjI0LDEzIDgsMTMuMjI1IDgsMTMuNSA4LDEzLjc3NSA4LjIyNCwxNCA4LjUsMTQgaCA1IGwgMC4xOTEsLTAuMDM5IGMgMC4xMjEsLTAuMDUxIDAuMjIsLTAuMTQ4IDAuMjcsLTAuMjcgTCAxNCwxMy41MDIgViA4LjUgQyAxNCw4LjIyNCAxMy43NzUsOCAxMy41LDggeiINCiAgIGlkPSJwYXRoNDM1MSINCiAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjEiIC8+DQo8L3N2Zz4=) 50% no-repeat;cursor:nwse-resize!important}.emote-menu .icon-pin{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8IS0tIENyZWF0ZWQgd2l0aCBJbmtzY2FwZSAoaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvKSAtLT4NCg0KPHN2Zw0KICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIg0KICAgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyINCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyINCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB2ZXJzaW9uPSIxLjEiDQogICB3aWR0aD0iMTYiDQogICBoZWlnaHQ9IjE2Ig0KICAgaWQ9InN2ZzMwMDUiPg0KICA8bWV0YWRhdGENCiAgICAgaWQ9Im1ldGFkYXRhMzAyMyI+DQogICAgPHJkZjpSREY+DQogICAgICA8Y2M6V29yaw0KICAgICAgICAgcmRmOmFib3V0PSIiPg0KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4NCiAgICAgICAgPGRjOnR5cGUNCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4NCiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+DQogICAgICA8L2NjOldvcms+DQogICAgPC9yZGY6UkRGPg0KICA8L21ldGFkYXRhPg0KICA8ZGVmcw0KICAgICBpZD0iZGVmczMwMjEiIC8+DQogIDxnDQogICAgIHRyYW5zZm9ybT0ibWF0cml4KDAuNzkzMDc4MiwwLDAsMC43OTMwNzgyLC0yLjE3MDk4NSwtODE0LjY5Mjk5KSINCiAgICAgaWQ9ImczMDA3Ij4NCiAgICA8Zw0KICAgICAgIHRyYW5zZm9ybT0ibWF0cml4KDAuNzA3MTEsMC43MDcxMSwtMC43MDcxMSwwLjcwNzExLDczNy43MDc1NSwyOTUuNDg4MDgpIg0KICAgICAgIGlkPSJnMzAwOSI+DQogICAgICA8Zw0KICAgICAgICAgaWQ9ImczNzU1Ij4NCiAgICAgICAgPHBhdGgNCiAgICAgICAgICAgZD0iTSA5Ljc4MTI1LDAgQyA5LjQ3NDA1NjIsMC42ODkxMTIgOS41MjA2OCwxLjUyMzA4NTMgOS4zMTI1LDIuMTg3NSBMIDQuOTM3NSw2LjU5Mzc1IEMgMy45NTg5NjA4LDYuNDI5NDgzIDIuOTQ3NzU0OCw2LjUzMjc4OTkgMiw2LjgxMjUgTCA1LjAzMTI1LDkuODQzNzUgMC41NjI1LDE0LjMxMjUgMCwxNiBDIDAuNTY5Mjk2MjgsMTUuNzk1NjI2IDEuMTY3NzM3OCwxNS42NDAyMzcgMS43MTg3NSwxNS40MDYyNSBMIDYuMTU2MjUsMTAuOTY4NzUgOS4xODc1LDE0IGMgMC4yNzk2ODIzLC0wLjk0Nzc4MyAwLjM4MzE1MjgsLTEuOTU4OTM3IDAuMjE4NzUsLTIuOTM3NSAxLjUwMDAxMSwtMS40ODk1Nzk4IDMuMDAwMDAxLC0yLjk3OTE1OSA0LjUsLTQuNDY4NzUgMC42MDExMDIsLTAuMDMxMzYxIDEuODIyMTM4LC0wLjA5NjEzNyAyLC0wLjQ2ODc1IEMgMTMuODc5ODkyLDQuMDY5NDgwMyAxMS44NDI4NjUsMi4wMjAyMjgyIDkuNzgxMjUsMCB6Ig0KICAgICAgICAgICB0cmFuc2Zvcm09Im1hdHJpeCgwLjg5MTU5Mzc0LC0wLjg5MTU5Mzc0LDAuODkxNTkzNzQsMC44OTE1OTM3NCwtMi4yNjU1LDEwMzcuMTM0NSkiDQogICAgICAgICAgIGlkPSJwYXRoMzAxMSINCiAgICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MSIgLz4NCiAgICAgIDwvZz4NCiAgICA8L2c+DQogIDwvZz4NCjwvc3ZnPg0K) 50% no-repeat;transition:all .25s ease}.emote-menu .icon-pin:hover,.emote-menu.pinned .icon-pin{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:1}.emote-menu .edit-tool{background-position:50%;background-repeat:no-repeat;background-size:14px;border-radius:4px;border:1px solid #000;cursor:pointer;display:none;height:14px;opacity:.25;position:absolute;transition:all .25s ease;width:14px;z-index:1}.emote-menu .edit-tool:hover,.emote-menu .emote:hover .edit-tool{opacity:1}.emote-menu .edit-visibility{background-color:#00c800;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8IS0tIENyZWF0ZWQgd2l0aCBJbmtzY2FwZSAoaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvKSAtLT4NCg0KPHN2Zw0KICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIg0KICAgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyINCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyINCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB2ZXJzaW9uPSIxLjEiDQogICB3aWR0aD0iMTAwIg0KICAgaGVpZ2h0PSIxMDAiDQogICB2aWV3Qm94PSIwIDAgMTAwIDEwMCINCiAgIGlkPSJMYXllcl8xIg0KICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhDQogICBpZD0ibWV0YWRhdGE5Ij48cmRmOlJERj48Y2M6V29yaw0KICAgICAgIHJkZjphYm91dD0iIj48ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD48ZGM6dHlwZQ0KICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48ZGM6dGl0bGU+PC9kYzp0aXRsZT48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMNCiAgIGlkPSJkZWZzNyIgLz4NCjxwYXRoDQogICBkPSJNIDk3Ljk2NCw0Ni41NDggQyA5Ny4wOTgsNDUuNTI4IDc2LjQyNywyMS42MDMgNTAsMjEuNjAzIGMgLTI2LjQyNywwIC00Ny4wOTgsMjMuOTI1IC00Ny45NjUsMjQuOTQ2IC0xLjcwMSwyIC0xLjcwMSw0LjkwMiAxMGUtNCw2LjkwMyAwLjg2NiwxLjAyIDIxLjUzNywyNC45NDUgNDcuOTY0LDI0Ljk0NSAyNi40MjcsMCA0Ny4wOTgsLTIzLjkyNiA0Ny45NjUsLTI0Ljk0NiAxLjcwMSwtMiAxLjcwMSwtNC45MDIgLTAuMDAxLC02LjkwMyB6IE0gNTguMDczLDM1Ljk3NSBjIDEuNzc3LC0wLjk3IDQuMjU1LDAuMTQzIDUuNTM0LDIuNDg1IDEuMjc5LDIuMzQzIDAuODc1LDUuMDI5IC0wLjkwMiw1Ljk5OSAtMS43NzcsMC45NzEgLTQuMjU1LC0wLjE0MyAtNS41MzUsLTIuNDg1IC0xLjI3OSwtMi4zNDMgLTAuODc1LC01LjAyOSAwLjkwMywtNS45OTkgeiBNIDUwLDY5LjcyOSBDIDMxLjU0LDY5LjcyOSAxNi4wMDUsNTUuNTUzIDEwLjYyOCw1MCAxNC4yNTksNDYuMjQ5IDIyLjUyNiwzOC41NzEgMzMuMTk1LDMzLjk3OSAzMS4xMTQsMzcuMTQ1IDI5Ljg5NCw0MC45MjggMjkuODk0LDQ1IGMgMCwxMS4xMDQgOS4wMDEsMjAuMTA1IDIwLjEwNSwyMC4xMDUgMTEuMTA0LDAgMjAuMTA2LC05LjAwMSAyMC4xMDYsLTIwLjEwNSAwLC00LjA3MiAtMS4yMTksLTcuODU1IC0zLjMsLTExLjAyMSBDIDc3LjQ3NCwzOC41NzIgODUuNzQxLDQ2LjI1IDg5LjM3Miw1MCA4My45OTUsNTUuNTU1IDY4LjQ2LDY5LjcyOSA1MCw2OS43MjkgeiINCiAgIGlkPSJwYXRoMyIgLz4NCjwvc3ZnPg==)}.emote-menu .edit-starred{background-color:#323232;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8IS0tIENyZWF0ZWQgd2l0aCBJbmtzY2FwZSAoaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvKSAtLT4NCg0KPHN2Zw0KICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIg0KICAgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyINCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyINCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB2ZXJzaW9uPSIxLjEiDQogICB3aWR0aD0iNTAiDQogICBoZWlnaHQ9IjUwIg0KICAgdmlld0JveD0iMCAwIDUwIDUwIg0KICAgaWQ9IkxheWVyXzEiDQogICB4bWw6c3BhY2U9InByZXNlcnZlIj48bWV0YWRhdGENCiAgIGlkPSJtZXRhZGF0YTMwMDEiPjxyZGY6UkRGPjxjYzpXb3JrDQogICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlDQogICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPjxkYzp0aXRsZT48L2RjOnRpdGxlPjwvY2M6V29yaz48L3JkZjpSREY+PC9tZXRhZGF0YT48ZGVmcw0KICAgaWQ9ImRlZnMyOTk5IiAvPg0KPHBhdGgNCiAgIGQ9Im0gNDMuMDQsMjIuNjk2IC03LjU2OCw3LjM3NyAxLjc4NywxMC40MTcgYyAwLjEyNywwLjc1IC0wLjE4MiwxLjUwOSAtMC43OTcsMS45NTcgLTAuMzQ4LDAuMjUzIC0wLjc2MiwwLjM4MiAtMS4xNzYsMC4zODIgLTAuMzE4LDAgLTAuNjM4LC0wLjA3NiAtMC45MzEsLTAuMjMgTCAyNSwzNy42ODEgMTUuNjQ1LDQyLjU5OSBjIC0wLjY3NCwwLjM1NSAtMS40OSwwLjI5NSAtMi4xMDcsLTAuMTUxIEMgMTIuOTIzLDQyIDEyLjYxNCw0MS4yNDIgMTIuNzQzLDQwLjQ5MSBMIDE0LjUzLDMwLjA3NCA2Ljk2MiwyMi42OTcgQyA2LjQxNSwyMi4xNjYgNi4yMjEsMjEuMzcxIDYuNDU0LDIwLjY0NyA2LjY5LDE5LjkyMyA3LjMxNSwxOS4zOTYgOC4wNjksMTkuMjg2IGwgMTAuNDU5LC0xLjUyMSA0LjY4LC05LjQ3OCBDIDIzLjU0Myw3LjYwMyAyNC4yMzksNy4xNzEgMjUsNy4xNzEgYyAwLjc2MywwIDEuNDU2LDAuNDMyIDEuNzkzLDEuMTE1IGwgNC42NzksOS40NzggMTAuNDYxLDEuNTIxIGMgMC43NTIsMC4xMDkgMS4zNzksMC42MzcgMS42MTIsMS4zNjEgMC4yMzcsMC43MjQgMC4wMzgsMS41MTkgLTAuNTA1LDIuMDUgeiINCiAgIGlkPSJwYXRoMjk5NSINCiAgIHN0eWxlPSJmaWxsOiNjY2NjY2M7ZmlsbC1vcGFjaXR5OjEiIC8+DQo8L3N2Zz4NCg==)}.emote-menu .emote>.edit-visibility{bottom:auto;left:auto;right:0;top:0}.emote-menu .emote>.edit-starred{bottom:auto;left:0;right:auto;top:0}.emote-menu .header-info>.edit-tool{margin-left:5px}.emote-menu.editing .edit-tool{display:inline-block}.emote-menu .emote-menu-hidden .edit-visibility{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8IS0tIENyZWF0ZWQgd2l0aCBJbmtzY2FwZSAoaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvKSAtLT4NCg0KPHN2Zw0KICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIg0KICAgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyINCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyINCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB2ZXJzaW9uPSIxLjEiDQogICB3aWR0aD0iMTAwIg0KICAgaGVpZ2h0PSIxMDAiDQogICB2aWV3Qm94PSIwIDAgMTAwIDEwMCINCiAgIGlkPSJMYXllcl8zIg0KICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhDQogICBpZD0ibWV0YWRhdGExNSI+PHJkZjpSREY+PGNjOldvcmsNCiAgICAgICByZGY6YWJvdXQ9IiI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUNCiAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+PGRjOnRpdGxlPjwvZGM6dGl0bGU+PC9jYzpXb3JrPjwvcmRmOlJERj48L21ldGFkYXRhPjxkZWZzDQogICBpZD0iZGVmczEzIiAvPg0KPGcNCiAgIGlkPSJnMyI+DQoJPHBhdGgNCiAgIGQ9Ik0gNzAuMDgyLDQ1LjQ3NSA1MC40NzQsNjUuMDgyIEMgNjEuMTk4LDY0LjgzMSA2OS44MzEsNTYuMTk3IDcwLjA4Miw0NS40NzUgeiINCiAgIGlkPSJwYXRoNSINCiAgIHN0eWxlPSJmaWxsOiNGRkZGRkYiIC8+DQoJPHBhdGgNCiAgIGQ9Im0gOTcuOTY0LDQ2LjU0OCBjIC0wLjQ1LC0wLjUyOSAtNi4yNDUsLTcuMjMgLTE1LjQwMywtMTMuNTU0IGwgLTYuMiw2LjIgQyA4Mi4zNTEsNDMuMTQ4IDg2LjkyLDQ3LjQ2OSA4OS4zNzIsNTAgODMuOTk1LDU1LjU1NSA2OC40Niw2OS43MjkgNTAsNjkuNzI5IGMgLTEuMzM0LDAgLTIuNjUxLC0wLjA4MiAtMy45NTIsLTAuMjIyIGwgLTcuNDM5LDcuNDM5IGMgMy42MzksMC45MDkgNy40NDksMS40NSAxMS4zOTEsMS40NSAyNi40MjcsMCA0Ny4wOTgsLTIzLjkyNiA0Ny45NjUsLTI0Ljk0NiAxLjcwMSwtMS45OTkgMS43MDEsLTQuOTAxIC0wLjAwMSwtNi45MDIgeiINCiAgIGlkPSJwYXRoNyINCiAgIHN0eWxlPSJmaWxsOiNGRkZGRkYiIC8+DQoJPHBhdGgNCiAgIGQ9Im0gOTEuNDExLDE2LjY2IGMgMCwtMC4yNjYgLTAuMTA1LC0wLjUyIC0wLjI5MywtMC43MDcgbCAtNy4wNzEsLTcuMDcgYyAtMC4zOTEsLTAuMzkxIC0xLjAyMywtMC4zOTEgLTEuNDE0LDAgTCA2Ni44MDQsMjQuNzExIEMgNjEuNjAyLDIyLjgxOCA1NS45NDksMjEuNjAzIDUwLDIxLjYwMyBjIC0yNi40MjcsMCAtNDcuMDk4LDIzLjkyNiAtNDcuOTY1LDI0Ljk0NiAtMS43MDEsMiAtMS43MDEsNC45MDIgMTBlLTQsNi45MDMgMC41MTcsMC42MDcgOC4wODMsOS4zNTQgMTkuNzA3LDE2LjMyIEwgOC44ODMsODIuNjMyIEMgOC42OTUsODIuODIgOC41OSw4My4wNzMgOC41OSw4My4zMzkgYyAwLDAuMjY2IDAuMTA1LDAuNTIgMC4yOTMsMC43MDcgbCA3LjA3MSw3LjA3IGMgMC4xOTUsMC4xOTUgMC40NTEsMC4yOTMgMC43MDcsMC4yOTMgMC4yNTYsMCAwLjUxMiwtMC4wOTggMC43MDcsLTAuMjkzIGwgNzMuNzUsLTczLjc1IGMgMC4xODcsLTAuMTg2IDAuMjkzLC0wLjQ0IDAuMjkzLC0wLjcwNiB6IE0gMTAuNjI4LDUwIEMgMTQuMjU5LDQ2LjI0OSAyMi41MjYsMzguNTcxIDMzLjE5NSwzMy45NzkgMzEuMTE0LDM3LjE0NSAyOS44OTQsNDAuOTI4IDI5Ljg5NCw0NSBjIDAsNC42NjUgMS42MDEsOC45NDUgNC4yNywxMi4zNTEgTCAyOC4wNCw2My40NzUgQyAxOS44ODgsNTguOTU1IDEzLjY0OSw1My4xMiAxMC42MjgsNTAgeiINCiAgIGlkPSJwYXRoOSINCiAgIHN0eWxlPSJmaWxsOiNGRkZGRkYiIC8+DQo8L2c+DQo8L3N2Zz4NCg==);background-color:red}.emote-menu .emote-menu-starred .edit-starred{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8IS0tIENyZWF0ZWQgd2l0aCBJbmtzY2FwZSAoaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvKSAtLT4NCg0KPHN2Zw0KICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIg0KICAgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyINCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyINCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICB2ZXJzaW9uPSIxLjEiDQogICB3aWR0aD0iNTAiDQogICBoZWlnaHQ9IjUwIg0KICAgdmlld0JveD0iMCAwIDUwIDUwIg0KICAgaWQ9IkxheWVyXzEiDQogICB4bWw6c3BhY2U9InByZXNlcnZlIj48bWV0YWRhdGENCiAgIGlkPSJtZXRhZGF0YTMwMDEiPjxyZGY6UkRGPjxjYzpXb3JrDQogICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlDQogICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPjxkYzp0aXRsZT48L2RjOnRpdGxlPjwvY2M6V29yaz48L3JkZjpSREY+PC9tZXRhZGF0YT48ZGVmcw0KICAgaWQ9ImRlZnMyOTk5IiAvPg0KPHBhdGgNCiAgIGQ9Im0gNDMuMDQsMjIuNjk2IC03LjU2OCw3LjM3NyAxLjc4NywxMC40MTcgYyAwLjEyNywwLjc1IC0wLjE4MiwxLjUwOSAtMC43OTcsMS45NTcgLTAuMzQ4LDAuMjUzIC0wLjc2MiwwLjM4MiAtMS4xNzYsMC4zODIgLTAuMzE4LDAgLTAuNjM4LC0wLjA3NiAtMC45MzEsLTAuMjMgTCAyNSwzNy42ODEgMTUuNjQ1LDQyLjU5OSBjIC0wLjY3NCwwLjM1NSAtMS40OSwwLjI5NSAtMi4xMDcsLTAuMTUxIEMgMTIuOTIzLDQyIDEyLjYxNCw0MS4yNDIgMTIuNzQzLDQwLjQ5MSBMIDE0LjUzLDMwLjA3NCA2Ljk2MiwyMi42OTcgQyA2LjQxNSwyMi4xNjYgNi4yMjEsMjEuMzcxIDYuNDU0LDIwLjY0NyA2LjY5LDE5LjkyMyA3LjMxNSwxOS4zOTYgOC4wNjksMTkuMjg2IGwgMTAuNDU5LC0xLjUyMSA0LjY4LC05LjQ3OCBDIDIzLjU0Myw3LjYwMyAyNC4yMzksNy4xNzEgMjUsNy4xNzEgYyAwLjc2MywwIDEuNDU2LDAuNDMyIDEuNzkzLDEuMTE1IGwgNC42NzksOS40NzggMTAuNDYxLDEuNTIxIGMgMC43NTIsMC4xMDkgMS4zNzksMC42MzcgMS42MTIsMS4zNjEgMC4yMzcsMC43MjQgMC4wMzgsMS41MTkgLTAuNTA1LDIuMDUgeiINCiAgIGlkPSJwYXRoMjk5NSINCiAgIHN0eWxlPSJmaWxsOiNmZmNjMDA7ZmlsbC1vcGFjaXR5OjEiIC8+DQo8L3N2Zz4NCg==)}.emote-menu .emote.emote-menu-starred{border-color:rgba(200,200,0,.5)}.emote-menu .emote.emote-menu-hidden{border-color:rgba(255,0,0,.5)}.emote-menu #starred-emotes-group .emote:not(.emote-menu-starred),.emote-menu:not(.editing) .emote-menu-hidden{display:none}.emote-menu:not(.editing) #starred-emotes-group .emote-menu-starred{border-color:transparent}.emote-menu #starred-emotes-group{text-align:center;color:#646464}.emote-menu #starred-emotes-group:empty:before{content:\"Use the edit mode to star an emote!\";position:relative;top:8px}.emote-menu .scrollable{height:calc(100% - 101px);overflow-y:auto}.emote-menu .sticky{position:absolute;bottom:0;width:100%}.emote-menu .emote-menu-inner{position:relative;max-height:100%;height:100%}")); },{}],3:[function(require,module,exports){ module.exports = (function() { var Hogan = require('hogan.js/lib/template.js'); var templates = {}; templates['emote'] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"emote");if(t.s(t.f("thirdParty",c,p,1),c,p,0,32,44,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" third-party");});c.pop();}if(!t.s(t.f("isVisible",c,p,1),c,p,1,0,0,"")){t.b(" emote-menu-hidden");};if(t.s(t.f("isStarred",c,p,1),c,p,0,119,138,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" emote-menu-starred");});c.pop();}t.b("\" data-emote=\"");t.b(t.v(t.f("text",c,p,0)));t.b("\" title=\"");t.b(t.v(t.f("text",c,p,0)));if(t.s(t.f("thirdParty",c,p,1),c,p,0,206,229,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" (from 3rd party addon)");});c.pop();}t.b("\">\r");t.b("\n" + i);t.b(" <img src=\"");t.b(t.t(t.f("url",c,p,0)));t.b("\">\r");t.b("\n" + i);t.b(" <div class=\"edit-tool edit-starred\" data-which=\"");t.b(t.v(t.f("text",c,p,0)));t.b("\" data-command=\"toggle-starred\" title=\"Star/unstar emote: ");t.b(t.v(t.f("text",c,p,0)));t.b("\"></div>\r");t.b("\n" + i);t.b(" <div class=\"edit-tool edit-visibility\" data-which=\"");t.b(t.v(t.f("text",c,p,0)));t.b("\" data-command=\"toggle-visibility\" title=\"Hide/show emote: ");t.b(t.v(t.f("text",c,p,0)));t.b("\"></div>\r");t.b("\n" + i);t.b("</div>\r");t.b("\n");return t.fl(); },partials: {}, subs: { }}); templates['emoteButton'] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<button class=\"button button--icon-only float-left\" title=\"Emote Menu\" id=\"emote-menu-button\"></button>\r");t.b("\n");return t.fl(); },partials: {}, subs: { }}); templates['emoteGroupHeader'] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"group-header\" data-emote-channel=\"");t.b(t.v(t.f("channel",c,p,0)));t.b("\">\r");t.b("\n" + i);t.b(" <div class=\"header-info\">\r");t.b("\n" + i);t.b(" <img src=\"");t.b(t.v(t.f("badge",c,p,0)));t.b("\" />\r");t.b("\n" + i);t.b(" ");t.b(t.v(t.f("channelDisplayName",c,p,0)));t.b("\r");t.b("\n" + i);t.b(" <div class=\"edit-tool edit-visibility\" data-which=\"channel-");t.b(t.v(t.f("channel",c,p,0)));t.b("\" data-command=\"toggle-visibility\" title=\"Hide/show current emotes for ");t.b(t.v(t.f("channelDisplayName",c,p,0)));t.b(" (note: new emotes will still show up if they are added)\"></div>\r");t.b("\n" + i);t.b(" </div>\r");t.b("\n" + i);t.b(" <div class=\"emote-container\"></div>\r");t.b("\n" + i);t.b("</div>\r");t.b("\n");return t.fl(); },partials: {}, subs: { }}); templates['menu'] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"emote-menu\" id=\"emote-menu-for-twitch\">\r");t.b("\n" + i);t.b(" <div class=\"emote-menu-inner\">\r");t.b("\n" + i);t.b("\r");t.b("\n" + i);t.b(" <div class=\"draggable\"></div>\r");t.b("\n" + i);t.b("\r");t.b("\n" + i);t.b(" <div class=\"scrollable scrollbar-macosx\">\r");t.b("\n" + i);t.b(" <div class=\"group-container\" id=\"all-emotes-group\"></div>\r");t.b("\n" + i);t.b(" </div>\r");t.b("\n" + i);t.b("\r");t.b("\n" + i);t.b(" <div class=\"sticky\">\r");t.b("\n" + i);t.b(" <div class=\"group-header single-row\" id=\"starred-emotes-group\">\r");t.b("\n" + i);t.b(" <div class=\"header-info\">Favorite Emotes</div>\r");t.b("\n" + i);t.b(" <div class=\"emote-container\"></div>\r");t.b("\n" + i);t.b(" </div>\r");t.b("\n" + i);t.b("\r");t.b("\n" + i);t.b(" <div class=\"footer\">\r");t.b("\n" + i);t.b(" <a class=\"pull-left icon icon-home\" href=\"http://cletusc.github.io/Userscript--Twitch-Chat-Emotes\" target=\"_blank\" title=\"Visit the homepage where you can donate, post a review, or contact the developer\"></a>\r");t.b("\n" + i);t.b(" <a class=\"pull-left icon icon-gear\" data-command=\"toggle-editing\" title=\"Toggle edit mode\"></a>\r");t.b("\n" + i);t.b(" <a class=\"pull-right icon icon-resize-handle\" data-command=\"resize-handle\"></a>\r");t.b("\n" + i);t.b(" <a class=\"pull-right icon icon-pin\" data-command=\"toggle-pinned\" title=\"Pin/unpin the emote menu to the screen\"></a>\r");t.b("\n" + i);t.b(" </div>\r");t.b("\n" + i);t.b(" </div>\r");t.b("\n" + i);t.b("\r");t.b("\n" + i);t.b(" </div>\r");t.b("\n" + i);t.b("</div>\r");t.b("\n");return t.fl(); },partials: {}, subs: { }}); templates['newsMessage'] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("\r");t.b("\n" + i);t.b("<div class=\"twitch-chat-emotes-news\">\r");t.b("\n" + i);t.b(" [");t.b(t.v(t.f("scriptName",c,p,0)));t.b("] News: ");t.b(t.t(t.f("message",c,p,0)));t.b(" (<a href=\"#\" data-command=\"twitch-chat-emotes:dismiss-news\" data-news-id=\"");t.b(t.v(t.f("id",c,p,0)));t.b("\">Dismiss</a>)\r");t.b("\n" + i);t.b("</div>\r");t.b("\n");return t.fl(); },partials: {}, subs: { }}); return templates; })(); },{"hogan.js/lib/template.js":4}],4:[function(require,module,exports){ /* * Copyright 2011 Twitter, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Hogan = {}; (function (Hogan) { Hogan.Template = function (codeObj, text, compiler, options) { codeObj = codeObj || {}; this.r = codeObj.code || this.r; this.c = compiler; this.options = options || {}; this.text = text || ''; this.partials = codeObj.partials || {}; this.subs = codeObj.subs || {}; this.buf = ''; } Hogan.Template.prototype = { // render: replaced by generated code. r: function (context, partials, indent) { return ''; }, // variable escaping v: hoganEscape, // triple stache t: coerceToString, render: function render(context, partials, indent) { return this.ri([context], partials || {}, indent); }, // render internal -- a hook for overrides that catches partials too ri: function (context, partials, indent) { return this.r(context, partials, indent); }, // ensurePartial ep: function(symbol, partials) { var partial = this.partials[symbol]; // check to see that if we've instantiated this partial before var template = partials[partial.name]; if (partial.instance && partial.base == template) { return partial.instance; } if (typeof template == 'string') { if (!this.c) { throw new Error("No compiler available."); } template = this.c.compile(template, this.options); } if (!template) { return null; } // We use this to check whether the partials dictionary has changed this.partials[symbol].base = template; if (partial.subs) { // Make sure we consider parent template now if (!partials.stackText) partials.stackText = {}; for (key in partial.subs) { if (!partials.stackText[key]) { partials.stackText[key] = (this.activeSub !== undefined && partials.stackText[this.activeSub]) ? partials.stackText[this.activeSub] : this.text; } } template = createSpecializedPartial(template, partial.subs, partial.partials, this.stackSubs, this.stackPartials, partials.stackText); } this.partials[symbol].instance = template; return template; }, // tries to find a partial in the current scope and render it rp: function(symbol, context, partials, indent) { var partial = this.ep(symbol, partials); if (!partial) { return ''; } return partial.ri(context, partials, indent); }, // render a section rs: function(context, partials, section) { var tail = context[context.length - 1]; if (!isArray(tail)) { section(context, partials, this); return; } for (var i = 0; i < tail.length; i++) { context.push(tail[i]); section(context, partials, this); context.pop(); } }, // maybe start a section s: function(val, ctx, partials, inverted, start, end, tags) { var pass; if (isArray(val) && val.length === 0) { return false; } if (typeof val == 'function') { val = this.ms(val, ctx, partials, inverted, start, end, tags); } pass = !!val; if (!inverted && pass && ctx) { ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]); } return pass; }, // find values with dotted names d: function(key, ctx, partials, returnFound) { var found, names = key.split('.'), val = this.f(names[0], ctx, partials, returnFound), doModelGet = this.options.modelGet, cx = null; if (key === '.' && isArray(ctx[ctx.length - 2])) { val = ctx[ctx.length - 1]; } else { for (var i = 1; i < names.length; i++) { found = findInScope(names[i], val, doModelGet); if (found !== undefined) { cx = val; val = found; } else { val = ''; } } } if (returnFound && !val) { return false; } if (!returnFound && typeof val == 'function') { ctx.push(cx); val = this.mv(val, ctx, partials); ctx.pop(); } return val; }, // find values with normal names f: function(key, ctx, partials, returnFound) { var val = false, v = null, found = false, doModelGet = this.options.modelGet; for (var i = ctx.length - 1; i >= 0; i--) { v = ctx[i]; val = findInScope(key, v, doModelGet); if (val !== undefined) { found = true; break; } } if (!found) { return (returnFound) ? false : ""; } if (!returnFound && typeof val == 'function') { val = this.mv(val, ctx, partials); } return val; }, // higher order templates ls: function(func, cx, partials, text, tags) { var oldTags = this.options.delimiters; this.options.delimiters = tags; this.b(this.ct(coerceToString(func.call(cx, text)), cx, partials)); this.options.delimiters = oldTags; return false; }, // compile text ct: function(text, cx, partials) { if (this.options.disableLambda) { throw new Error('Lambda features disabled.'); } return this.c.compile(text, this.options).render(cx, partials); }, // template result buffering b: function(s) { this.buf += s; }, fl: function() { var r = this.buf; this.buf = ''; return r; }, // method replace section ms: function(func, ctx, partials, inverted, start, end, tags) { var textSource, cx = ctx[ctx.length - 1], result = func.call(cx); if (typeof result == 'function') { if (inverted) { return true; } else { textSource = (this.activeSub && this.subsText && this.subsText[this.activeSub]) ? this.subsText[this.activeSub] : this.text; return this.ls(result, cx, partials, textSource.substring(start, end), tags); } } return result; }, // method replace variable mv: function(func, ctx, partials) { var cx = ctx[ctx.length - 1]; var result = func.call(cx); if (typeof result == 'function') { return this.ct(coerceToString(result.call(cx)), cx, partials); } return result; }, sub: function(name, context, partials, indent) { var f = this.subs[name]; if (f) { this.activeSub = name; f(context, partials, this, indent); this.activeSub = false; } } }; //Find a key in an object function findInScope(key, scope, doModelGet) { var val; if (scope && typeof scope == 'object') { if (scope[key] !== undefined) { val = scope[key]; // try lookup with get for backbone or similar model data } else if (doModelGet && scope.get && typeof scope.get == 'function') { val = scope.get(key); } } return val; } function createSpecializedPartial(instance, subs, partials, stackSubs, stackPartials, stackText) { function PartialTemplate() {}; PartialTemplate.prototype = instance; function Substitutions() {}; Substitutions.prototype = instance.subs; var key; var partial = new PartialTemplate(); partial.subs = new Substitutions(); partial.subsText = {}; //hehe. substext. partial.buf = ''; stackSubs = stackSubs || {}; partial.stackSubs = stackSubs; partial.subsText = stackText; for (key in subs) { if (!stackSubs[key]) stackSubs[key] = subs[key]; } for (key in stackSubs) { partial.subs[key] = stackSubs[key]; } stackPartials = stackPartials || {}; partial.stackPartials = stackPartials; for (key in partials) { if (!stackPartials[key]) stackPartials[key] = partials[key]; } for (key in stackPartials) { partial.partials[key] = stackPartials[key]; } return partial; } var rAmp = /&/g, rLt = /</g, rGt = />/g, rApos = /\'/g, rQuot = /\"/g, hChars = /[&<>\"\']/; function coerceToString(val) { return String((val === null || val === undefined) ? '' : val); } function hoganEscape(str) { str = coerceToString(str); return hChars.test(str) ? str .replace(rAmp, '&') .replace(rLt, '<') .replace(rGt, '>') .replace(rApos, ''') .replace(rQuot, '"') : str; } var isArray = Array.isArray || function(a) { return Object.prototype.toString.call(a) === '[object Array]'; }; })(typeof exports !== 'undefined' ? exports : Hogan); },{}],5:[function(require,module,exports){ /** * jQuery CSS Customizable Scrollbar * * Copyright 2014, Yuriy Khabarov * Dual licensed under the MIT or GPL Version 2 licenses. * * If you found bug, please contact me via email <13real008@gmail.com> * * @author Yuriy Khabarov aka Gromo * @version 0.2.6 * @url https://github.com/gromo/jquery.scrollbar/ * */ (function(e,t,n){"use strict";function h(t){if(o.webkit&&!t){return{height:0,width:0}}if(!o.data.outer){var n={border:"none","box-sizing":"content-box",height:"200px",margin:"0",padding:"0",width:"200px"};o.data.inner=e("<div>").css(e.extend({},n));o.data.outer=e("<div>").css(e.extend({left:"-1000px",overflow:"scroll",position:"absolute",top:"-1000px"},n)).append(o.data.inner).appendTo("body")}o.data.outer.scrollLeft(1e3).scrollTop(1e3);return{height:Math.ceil(o.data.outer.offset().top-o.data.inner.offset().top||0),width:Math.ceil(o.data.outer.offset().left-o.data.inner.offset().left||0)}}function p(n,r){e(t).on({"blur.scrollbar":function(){e(t).add("body").off(".scrollbar");n&&n()},"dragstart.scrollbar":function(e){e.preventDefault();return false},"mouseup.scrollbar":function(){e(t).add("body").off(".scrollbar");n&&n()}});e("body").on({"selectstart.scrollbar":function(e){e.preventDefault();return false}});r&&r.preventDefault();return false}function d(){var e=h(true);return!(e.height||e.width)}function v(e){var t=e.originalEvent;if(t.axis&&t.axis===t.HORIZONTAL_AXIS)return false;if(t.wheelDeltaX)return false;return true}var r=false;var i=1,s="px";var o={data:{},macosx:n.navigator.platform.toLowerCase().indexOf("mac")!==-1,mobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(n.navigator.userAgent),overlay:null,scroll:null,scrolls:[],webkit:/WebKit/.test(n.navigator.userAgent),log:r?function(t,r){var i=t;if(r&&typeof t!="string"){i=[];e.each(t,function(e,t){i.push('"'+e+'": '+t)});i=i.join(", ")}if(n.console&&n.console.log){n.console.log(i)}else{alert(i)}}:function(){}};var u={autoScrollSize:true,autoUpdate:true,debug:false,disableBodyScroll:false,duration:200,ignoreMobile:true,ignoreOverlay:true,scrollStep:30,showArrows:false,stepScrolling:true,type:"simple",scrollx:null,scrolly:null,onDestroy:null,onInit:null,onScroll:null,onUpdate:null};var a=function(t,r){if(!o.scroll){o.log("Init jQuery Scrollbar v0.2.6");o.overlay=d();o.scroll=h();c();e(n).resize(function(){var e=false;if(o.scroll&&(o.scroll.height||o.scroll.width)){var t=h();if(t.height!=o.scroll.height||t.width!=o.scroll.width){o.scroll=t;e=true}}c(e)})}this.container=t;this.options=e.extend({},u,n.jQueryScrollbarOptions||{});this.scrollTo=null;this.scrollx={};this.scrolly={};this.init(r)};a.prototype={destroy:function(){if(!this.wrapper){return}var n=this.container.scrollLeft();var r=this.container.scrollTop();this.container.insertBefore(this.wrapper).css({height:"",margin:""}).removeClass("scroll-content").removeClass("scroll-scrollx_visible").removeClass("scroll-scrolly_visible").off(".scrollbar").scrollLeft(n).scrollTop(r);this.scrollx.scrollbar.removeClass("scroll-scrollx_visible").find("div").andSelf().off(".scrollbar");this.scrolly.scrollbar.removeClass("scroll-scrolly_visible").find("div").andSelf().off(".scrollbar");this.wrapper.remove();e(t).add("body").off(".scrollbar");if(e.isFunction(this.options.onDestroy))this.options.onDestroy.apply(this,[this.container])},getScrollbar:function(t){var n=this.options["scroll"+t];var r={advanced:'<div class="scroll-element_corner"></div>'+'<div class="scroll-arrow scroll-arrow_less"></div>'+'<div class="scroll-arrow scroll-arrow_more"></div>'+'<div class="scroll-element_outer">'+' <div class="scroll-element_size"></div>'+' <div class="scroll-element_inner-wrapper">'+' <div class="scroll-element_inner scroll-element_track">'+' <div class="scroll-element_inner-bottom"></div>'+" </div>"+" </div>"+' <div class="scroll-bar">'+' <div class="scroll-bar_body">'+' <div class="scroll-bar_body-inner"></div>'+" </div>"+' <div class="scroll-bar_bottom"></div>'+' <div class="scroll-bar_center"></div>'+" </div>"+"</div>",simple:'<div class="scroll-element_outer">'+' <div class="scroll-element_size"></div>'+' <div class="scroll-element_track"></div>'+' <div class="scroll-bar"></div>'+"</div>"};var i=r[this.options.type]?this.options.type:"advanced";if(n){if(typeof n=="string"){n=e(n).appendTo(this.wrapper)}else{n=e(n)}}else{n=e("<div>").addClass("scroll-element").html(r[i]).appendTo(this.wrapper)}if(this.options.showArrows){n.addClass("scroll-element_arrows_visible")}return n.addClass("scroll-"+t)},init:function(n){var r=this;var u=this.container;var a=this.containerWrapper||u;var f=e.extend(this.options,n||{});var l={x:this.scrollx,y:this.scrolly};var c=this.wrapper;var h={scrollLeft:u.scrollLeft(),scrollTop:u.scrollTop()};if(o.mobile&&f.ignoreMobile||o.overlay&&f.ignoreOverlay||o.macosx&&!o.webkit){return false}if(!c){this.wrapper=c=e("<div>").addClass("scroll-wrapper").addClass(u.attr("class")).css("position",u.css("position")=="absolute"?"absolute":"relative").insertBefore(u).append(u);if(u.is("textarea")){this.containerWrapper=a=e("<div>").insertBefore(u).append(u);c.addClass("scroll-textarea")}a.addClass("scroll-content").css({height:"","margin-bottom":o.scroll.height*-1+s,"margin-right":o.scroll.width*-1+s});u.on("scroll.scrollbar",function(t){if(e.isFunction(f.onScroll)){f.onScroll.call(r,{maxScroll:l.y.maxScrollOffset,scroll:u.scrollTop(),size:l.y.size,visible:l.y.visible},{maxScroll:l.x.maxScrollOffset,scroll:u.scrollLeft(),size:l.x.size,visible:l.x.visible})}l.x.isVisible&&l.x.scroller.css("left",u.scrollLeft()*l.x.kx+s);l.y.isVisible&&l.y.scroller.css("top",u.scrollTop()*l.y.kx+s)});c.on("scroll",function(){c.scrollTop(0).scrollLeft(0)});if(f.disableBodyScroll){var d=function(e){v(e)?l.y.isVisible&&l.y.mousewheel(e):l.x.isVisible&&l.x.mousewheel(e)};c.on({"MozMousePixelScroll.scrollbar":d,"mousewheel.scrollbar":d});if(o.mobile){c.on("touchstart.scrollbar",function(n){var r=n.originalEvent.touches&&n.originalEvent.touches[0]||n;var i={pageX:r.pageX,pageY:r.pageY};var s={left:u.scrollLeft(),top:u.scrollTop()};e(t).on({"touchmove.scrollbar":function(e){var t=e.originalEvent.targetTouches&&e.originalEvent.targetTouches[0]||e;u.scrollLeft(s.left+i.pageX-t.pageX);u.scrollTop(s.top+i.pageY-t.pageY);e.preventDefault()},"touchend.scrollbar":function(){e(t).off(".scrollbar")}})})}}if(e.isFunction(f.onInit))f.onInit.apply(this,[u])}else{a.css({height:"","margin-bottom":o.scroll.height*-1+s,"margin-right":o.scroll.width*-1+s})}e.each(l,function(n,s){var o=null;var a=1;var c=n=="x"?"scrollLeft":"scrollTop";var h=f.scrollStep;var d=function(){var e=u[c]();u[c](e+h);if(a==1&&e+h>=m)e=u[c]();if(a==-1&&e+h<=m)e=u[c]();if(u[c]()==e&&o){o()}};var m=0;if(!s.scrollbar){s.scrollbar=r.getScrollbar(n);s.scroller=s.scrollbar.find(".scroll-bar");s.mousewheel=function(e){if(!s.isVisible||n=="x"&&v(e)){return true}if(n=="y"&&!v(e)){l.x.mousewheel(e);return true}var t=e.originalEvent.wheelDelta*-1||e.originalEvent.detail;var i=s.size-s.visible-s.offset;if(!(m<=0&&t<0||m>=i&&t>0)){m=m+t;if(m<0)m=0;if(m>i)m=i;r.scrollTo=r.scrollTo||{};r.scrollTo[c]=m;setTimeout(function(){if(r.scrollTo){u.stop().animate(r.scrollTo,240,"linear",function(){m=u[c]()});r.scrollTo=null}},1)}e.preventDefault();return false};s.scrollbar.on({"MozMousePixelScroll.scrollbar":s.mousewheel,"mousewheel.scrollbar":s.mousewheel,"mouseenter.scrollbar":function(){m=u[c]()}});s.scrollbar.find(".scroll-arrow, .scroll-element_track").on("mousedown.scrollbar",function(t){if(t.which!=i)return true;a=1;var l={eventOffset:t[n=="x"?"pageX":"pageY"],maxScrollValue:s.size-s.visible-s.offset,scrollbarOffset:s.scroller.offset()[n=="x"?"left":"top"],scrollbarSize:s.scroller[n=="x"?"outerWidth":"outerHeight"]()};var v=0,g=0;if(e(this).hasClass("scroll-arrow")){a=e(this).hasClass("scroll-arrow_more")?1:-1;h=f.scrollStep*a;m=a>0?l.maxScrollValue:0}else{a=l.eventOffset>l.scrollbarOffset+l.scrollbarSize?1:l.eventOffset<l.scrollbarOffset?-1:0;h=Math.round(s.visible*.75)*a;m=l.eventOffset-l.scrollbarOffset-(f.stepScrolling?a==1?l.scrollbarSize:0:Math.round(l.scrollbarSize/2));m=u[c]()+m/s.kx}r.scrollTo=r.scrollTo||{};r.scrollTo[c]=f.stepScrolling?u[c]()+h:m;if(f.stepScrolling){o=function(){m=u[c]();clearInterval(g);clearTimeout(v);v=0;g=0};v=setTimeout(function(){g=setInterval(d,40)},f.duration+100)}setTimeout(function(){if(r.scrollTo){u.animate(r.scrollTo,f.duration);r.scrollTo=null}},1);return p(o,t)});s.scroller.on("mousedown.scrollbar",function(r){if(r.which!=i)return true;var o=r[n=="x"?"pageX":"pageY"];var a=u[c]();s.scrollbar.addClass("scroll-draggable");e(t).on("mousemove.scrollbar",function(e){var t=parseInt((e[n=="x"?"pageX":"pageY"]-o)/s.kx,10);u[c](a+t)});return p(function(){s.scrollbar.removeClass("scroll-draggable");m=u[c]()},r)})}});e.each(l,function(e,t){var n="scroll-scroll"+e+"_visible";var r=e=="x"?l.y:l.x;t.scrollbar.removeClass(n);r.scrollbar.removeClass(n);a.removeClass(n)});e.each(l,function(t,n){e.extend(n,t=="x"?{offset:parseInt(u.css("left"),10)||0,size:u.prop("scrollWidth"),visible:c.width()}:{offset:parseInt(u.css("top"),10)||0,size:u.prop("scrollHeight"),visible:c.height()})});var m=function(t,n){var r="scroll-scroll"+t+"_visible";var i=t=="x"?l.y:l.x;var f=parseInt(u.css(t=="x"?"left":"top"),10)||0;var h=n.size;var p=n.visible+f;n.isVisible=h-p>1;if(n.isVisible){n.scrollbar.addClass(r);i.scrollbar.addClass(r);a.addClass(r)}else{n.scrollbar.removeClass(r);i.scrollbar.removeClass(r);a.removeClass(r)}if(t=="y"&&(n.isVisible||n.size<n.visible)){a.css("height",p+o.scroll.height+s)}if(l.x.size!=u.prop("scrollWidth")||l.y.size!=u.prop("scrollHeight")||l.x.visible!=c.width()||l.y.visible!=c.height()||l.x.offset!=(parseInt(u.css("left"),10)||0)||l.y.offset!=(parseInt(u.css("top"),10)||0)){e.each(l,function(t,n){e.extend(n,t=="x"?{offset:parseInt(u.css("left"),10)||0,size:u.prop("scrollWidth"),visible:c.width()}:{offset:parseInt(u.css("top"),10)||0,size:u.prop("scrollHeight"),visible:c.height()})});m(t=="x"?"y":"x",i)}};e.each(l,m);if(e.isFunction(f.onUpdate))f.onUpdate.apply(this,[u]);e.each(l,function(e,t){var n=e=="x"?"left":"top";var r=e=="x"?"outerWidth":"outerHeight";var i=e=="x"?"width":"height";var o=parseInt(u.css(n),10)||0;var a=t.size;var l=t.visible+o;var c=t.scrollbar.find(".scroll-element_size");c=c[r]()+(parseInt(c.css(n),10)||0);if(f.autoScrollSize){t.scrollbarSize=parseInt(c*l/a,10);t.scroller.css(i,t.scrollbarSize+s)}t.scrollbarSize=t.scroller[r]();t.kx=(c-t.scrollbarSize)/(a-l)||1;t.maxScrollOffset=a-l});u.scrollLeft(h.scrollLeft).scrollTop(h.scrollTop).trigger("scroll")}};e.fn.scrollbar=function(t,n){var r=this;if(t==="get")r=null;this.each(function(){var i=e(this);if(i.hasClass("scroll-wrapper")||i.get(0).nodeName=="body"){return true}var s=i.data("scrollbar");if(s){if(t==="get"){r=s;return false}var u=typeof t=="string"&&s[t]?t:"init";s[u].apply(s,e.isArray(n)?n:[]);if(t==="destroy"){i.removeData("scrollbar");while(e.inArray(s,o.scrolls)>=0)o.scrolls.splice(e.inArray(s,o.scrolls),1)}}else{if(typeof t!="string"){s=new a(i,t);i.data("scrollbar",s);o.scrolls.push(s)}}return true});return r};e.fn.scrollbar.options=u;if(n.angular){(function(e){var t=e.module("jQueryScrollbar",[]);t.directive("jqueryScrollbar",function(){return{link:function(e,t){t.scrollbar(e.options).on("$destroy",function(){t.scrollbar("destroy")})},restring:"AC",scope:{options:"=jqueryScrollbar"}}})})(n.angular)}var f=0,l=0;var c=function(e){var t,n,i,s,u,a,h;for(t=0;t<o.scrolls.length;t++){s=o.scrolls[t];n=s.container;i=s.options;u=s.wrapper;a=s.scrollx;h=s.scrolly;if(e||i.autoUpdate&&u&&u.is(":visible")&&(n.prop("scrollWidth")!=a.size||n.prop("scrollHeight")!=h.size||u.width()!=a.visible||u.height()!=h.visible)){s.init();if(r){o.log({scrollHeight:n.prop("scrollHeight")+":"+s.scrolly.size,scrollWidth:n.prop("scrollWidth")+":"+s.scrollx.size,visibleHeight:u.height()+":"+s.scrolly.visible,visibleWidth:u.width()+":"+s.scrollx.visible},true);l++}}}if(r&&l>10){o.log("Scroll updates exceed 10");c=function(){}}else{clearTimeout(f);f=setTimeout(c,300)}}})(jQuery,document,window); },{}],6:[function(require,module,exports){ // Storage cache. var cache = {}; // The store handling expiration of data. var expiresStore = new Store({ namespace: '__storage-wrapper:expires' }); /** * Storage wrapper for making routine storage calls super easy. * @class Store * @constructor * @param {object} [options] The options for the store. Options not overridden will use the defaults. * @param {mixed} [options.namespace=''] See {{#crossLink "Store/setNamespace"}}Store#setNamespace{{/crossLink}} * @param {mixed} [options.storageType='local'] See {{#crossLink "Store/setStorageType"}}Store#setStorageType{{/crossLink}} */ function Store(options) { var settings = { namespace: '', storageType: 'local' }; /** * Sets the storage namespace. * @method setNamespace * @param {string|false|null} namespace The namespace to work under. To use no namespace (e.g. global namespace), pass in `false` or `null` or an empty string. */ this.setNamespace = function (namespace) { var validNamespace = /^[\w-:]+$/; // No namespace. if (namespace === false || namespace == null || namespace === '') { settings.namespace = ''; return; } if (typeof namespace !== 'string' || !validNamespace.test(namespace)) { throw new Error('Invalid namespace.'); } settings.namespace = namespace; }; /** * Gets the current storage namespace. * @method getNamespace * @return {string} The current namespace. */ this.getNamespace = function (includeSeparator) { if (includeSeparator && settings.namespace !== '') { return settings.namespace + ':'; } return settings.namespace; } /** * Sets the type of storage to use. * @method setStorageType * @param {string} type The type of storage to use. Use `session` for `sessionStorage` and `local` for `localStorage`. */ this.setStorageType = function (type) { if (['session', 'local'].indexOf(type) < 0) { throw new Error('Invalid storage type.'); } settings.storageType = type; }; /** * Get the type of storage being used. * @method getStorageType * @return {string} The type of storage being used. */ this.getStorageType = function () { return settings.storageType; }; // Override default settings. if (options) { for (var key in options) { switch (key) { case 'namespace': this.setNamespace(options[key]); break; case 'storageType': this.setStorageType(options[key]); break; } } } } /** * Gets the actual handler to use * @method getStorageHandler * @return {mixed} The storage handler. */ Store.prototype.getStorageHandler = function () { var handlers = { 'local': localStorage, 'session': sessionStorage }; return handlers[this.getStorageType()]; } /** * Gets the full storage name for a key, including the namespace, if any. * @method getStorageKey * @param {string} key The storage key name. * @return {string} The full storage name that is used by the storage methods. */ Store.prototype.getStorageKey = function (key) { if (!key || typeof key !== 'string' || key.length < 1) { throw new Error('Key must be a string.'); } return this.getNamespace(true) + key; }; /** * Gets a storage item from the current namespace. * @method get * @param {string} key The key that the data can be accessed under. * @param {mixed} defaultValue The default value to return in case the storage value is not set or `null`. * @return {mixed} The data for the storage. */ Store.prototype.get = function (key, defaultValue) { // Prevent recursion. Only check expire date if it isn't called from `expiresStore`. if (this !== expiresStore) { // Check if key is expired. var expireDate = expiresStore.get(this.getStorageKey(key)); if (expireDate !== null && expireDate.getTime() < Date.now()) { // Expired, remove it. this.remove(key); expiresStore.remove(this.getStorageKey(key)); } } // Cached, read from memory. if (cache[this.getStorageKey(key)] != null) { return cache[this.getStorageKey(key)]; } var val = this.getStorageHandler().getItem(this.getStorageKey(key)); // Value doesn't exist and we have a default, return default. if (val === null && typeof defaultValue !== 'undefined') { return defaultValue; } // Only pre-process strings. if (typeof val === 'string') { // Handle RegExps. if (val.indexOf('~RegExp:') === 0) { var matches = /^~RegExp:([gim]*?):(.*)/.exec(val); val = new RegExp(matches[2], matches[1]); } // Handle Dates. else if (val.indexOf('~Date:') === 0) { val = new Date(val.replace(/^~Date:/, '')); } // Handle numbers. else if (val.indexOf('~Number:') === 0) { val = parseInt(val.replace(/^~Number:/, ''), 10); } // Handle booleans. else if (val.indexOf('~Boolean:') === 0) { val = val.replace(/^~Boolean:/, '') === 'true'; } // Handle objects. else if (val.indexOf('~JSON:') === 0) { val = val.replace(/^~JSON:/, ''); // Try parsing it. try { val = JSON.parse(val); } // Parsing went wrong (invalid JSON), return default or null. catch (e) { if (typeof defaultValue !== 'undefined') { return defaultValue; } return null; } } } // Return it. cache[this.getStorageKey(key)] = val; return val; }; /** * Sets a storage item on the current namespace. * @method set * @param {string} key The key that the data can be accessed under. * @param {mixed} val The value to store. May be the following types of data: `RegExp`, `Date`, `Object`, `String`, `Boolean`, `Number` * @param {Date|number} [expires] The date in the future to expire, or relative number of milliseconds from `Date#now` to expire. * * Note: This converts special data types that normally can't be stored in the following way: * * - `RegExp`: prefixed with type, flags stored, and source stored as string. * - `Date`: prefixed with type, stored as string using `Date#toString`. * - `Object`: prefixed with "JSON" indicator, stored as string using `JSON#stringify`. */ Store.prototype.set = function (key, val, expires) { var parsedVal = null; // Handle RegExps. if (val instanceof RegExp) { var flags = [ val.global ? 'g' : '', val.ignoreCase ? 'i' : '', val.multiline ? 'm' : '', ].join(''); parsedVal = '~RegExp:' + flags + ':' + val.source; } // Handle Dates. else if (val instanceof Date) { parsedVal = '~Date:' + val.toString(); } // Handle objects. else if (val === Object(val)) { parsedVal = '~JSON:' + JSON.stringify(val); } // Handle numbers. else if (typeof val === 'number') { parsedVal = '~Number:' + val.toString(); } // Handle booleans. else if (typeof val === 'boolean') { parsedVal = '~Boolean:' + val.toString(); } // Handle strings. else if (typeof val === 'string') { parsedVal = val; } // Throw if we don't know what it is. else { throw new Error('Unable to store this value; wrong value type.'); } // Set expire date if needed. if (typeof expires !== 'undefined') { // Convert to a relative date. if (typeof expires === 'number') { expires = new Date(Date.now() + expires); } // Make sure it is a date. if (expires instanceof Date) { expiresStore.set(this.getStorageKey(key), expires); } else { throw new Error('Key expire must be a valid date or timestamp.'); } } // Save it. cache[this.getStorageKey(key)] = val; this.getStorageHandler().setItem(this.getStorageKey(key), parsedVal); }; /** * Gets all data for the current namespace. * @method getAll * @return {object} An object containing all data in the form of `{theKey: theData}` where `theData` is parsed using {{#crossLink "Store/get"}}Store#get{{/crossLink}}. */ Store.prototype.getAll = function () { var keys = this.listKeys(); var data = {}; keys.forEach(function (key) { data[key] = this.get(key); }, this); return data; }; /** * List all keys that are tied to the current namespace. * @method listKeys * @return {array} The storage keys. */ Store.prototype.listKeys = function () { var keys = []; var key = null; var storageLength = this.getStorageHandler().length; var prefix = new RegExp('^' + this.getNamespace(true)); for (var i = 0; i < storageLength; i++) { key = this.getStorageHandler().key(i) if (prefix.test(key)) { keys.push(key.replace(prefix, '')); } } return keys; }; /** * Removes a specific key and data from the current namespace. * @method remove * @param {string} key The key to remove the data for. */ Store.prototype.remove = function (key) { cache[this.getStorageKey(key)] = null; this.getStorageHandler().removeItem(this.getStorageKey(key)); }; /** * Removes all data and keys from the current namespace. * @method removeAll */ Store.prototype.removeAll = function () { this.listKeys().forEach(this.remove, this); }; /** * Removes namespaced items from the cache so your next {{#crossLink "Store/get"}}Store#get{{/crossLink}} will be fresh from the storage. * @method freshen * @param {string} key The key to remove the cache data for. */ Store.prototype.freshen = function (key) { var keys = key ? [key] : this.listKeys(); keys.forEach(function (key) { cache[this.getStorageKey(key)] = null; }, this); }; /** * Migrate data from a different namespace to current namespace. * @method migrate * @param {object} migration The migration object. * @param {string} migration.toKey The key name under your current namespace the old data should change to. * @param {string} migration.fromNamespace The old namespace that the old key belongs to. * @param {string} migration.fromKey The old key name to migrate from. * @param {string} [migration.fromStorageType] The storage type to migrate from. Defaults to same type as where you are migrating to. * @param {boolean} [migration.keepOldData=false] Whether old data should be kept after it has been migrated. * @param {boolean} [migration.overwriteNewData=false] Whether old data should overwrite currently stored data if it exists. * @param {function} [migration.transform] The function to pass the old key data through before migrating. * @example * * var Store = require('storage-wrapper'); * var store = new Store({ * namespace: 'myNewApp' * }); * * // Migrate from the old app. * store.migrate({ * toKey: 'new-key', * fromNamespace: 'myOldApp', * fromKey: 'old-key' * }); * * // Migrate from global data. Useful when moving from other storage wrappers or regular ol' `localStorage`. * store.migrate({ * toKey: 'other-new-key', * fromNamespace: '', * fromKey: 'other-old-key-on-global' * }); * * // Migrate some JSON data that was stored as a string. * store.migrate({ * toKey: 'new-json-key', * fromNamespace: 'myOldApp', * fromKey: 'old-json-key', * // Try converting some old JSON data. * transform: function (data) { * try { * return JSON.parse(data); * } * catch (e) { * return data; * } * } * }); */ Store.prototype.migrate = function (migration) { // Save our current namespace. var toNamespace = this.getNamespace(); var toStorageType = this.getStorageType(); // Create a temporary store to avoid changing namespace during actual get/sets. var store = new Store({ namespace: toNamespace, storageType: toStorageType }); var data = null; // Get data from old namespace. store.setNamespace(migration.fromNamespace); if (typeof migration.fromStorageType !== 'undefined') { store.setStorageType(migration.fromStorageType); } data = store.get(migration.fromKey); // Remove old if needed. if (!migration.keepOldData) { store.remove(migration.fromKey); } // No data, ignore this migration. if (data === null) { return; } // Transform data if needed. if (typeof migration.transform === 'function') { data = migration.transform(data); } else if (typeof migration.transform !== 'undefined') { throw new Error('Invalid transform callback.'); } // Go back to current namespace. store.setNamespace(toNamespace); store.setStorageType(toStorageType); // Only overwrite new data if it doesn't exist or it's requested. if (store.get(migration.toKey) === null || migration.overwriteNewData) { store.set(migration.toKey, data); } }; /** * Creates a substore that is nested in the current namespace. * @method createSubstore * @param {string} namespace The substore's namespace. * @return {Store} The substore. * @example * * var Store = require('storage-wrapper'); * // Create main store. * var store = new Store({ * namespace: 'myapp' * }); * * // Create substore. * var substore = store.createSubstore('things'); * substore.set('foo', 'bar'); * * substore.get('foo') === store.get('things:foo'); * // true */ Store.prototype.createSubstore = function (namespace) { return new Store({ namespace: this.getNamespace(true) + namespace, storageType: this.getStorageType() }); }; module.exports = Store; },{}],7:[function(require,module,exports){ module.exports={ "name": "twitch-chat-emotes", "version": "2.1.5", "homepage": "http://cletusc.github.io/Userscript--Twitch-Chat-Emotes/", "bugs": "https://github.com/cletusc/Userscript--Twitch-Chat-Emotes/issues", "author": "Ryan Chatham <ryan.b.chatham@gmail.com> (https://github.com/cletusc)", "repository": { "type": "git", "url": "https://github.com/cletusc/Userscript--Twitch-Chat-Emotes.git" }, "userscript": { "name": "Twitch Chat Emotes", "namespace": "#Cletus", "version": "{{{pkg.version}}}", "description": "Adds a button to Twitch that allows you to \"click-to-insert\" an emote.", "copyright": "2011+, {{{pkg.author}}}", "author": "{{{pkg.author}}}", "icon": "http://www.gravatar.com/avatar.php?gravatar_id=6875e83aa6c563790cb2da914aaba8b3&r=PG&s=48&default=identicon", "license": [ "MIT; http://opensource.org/licenses/MIT", "CC BY-NC-SA 3.0; http://creativecommons.org/licenses/by-nc-sa/3.0/" ], "homepage": "{{{pkg.homepage}}}", "supportURL": "{{{pkg.bugs}}}", "contributionURL": "http://cletusc.github.io/Userscript--Twitch-Chat-Emotes/#donate", "grant": "none", "include": [ "http://*.twitch.tv/*", "https://*.twitch.tv/*" ], "exclude": [ "http://api.twitch.tv/*", "https://api.twitch.tv/*", "http://tmi.twitch.tv/*", "https://tmi.twitch.tv/*", "http://*.twitch.tv/*/dashboard", "https://*.twitch.tv/*/dashboard", "http://chatdepot.twitch.tv/*", "https://chatdepot.twitch.tv/*", "http://im.twitch.tv/*", "https://im.twitch.tv/*", "http://platform.twitter.com/*", "https://platform.twitter.com/*", "http://www.facebook.com/*", "https://www.facebook.com/*" ] }, "devDependencies": { "browser-sync": "^1.3.2", "browserify": "^5.9.1", "generate-userscript-header": "^1.0.0", "gulp": "^3.8.3", "gulp-autoprefixer": "0.0.8", "gulp-beautify": "1.1.0", "gulp-changed": "^0.4.1", "gulp-concat": "^2.2.0", "gulp-conflict": "^0.1.2", "gulp-css-base64": "^1.1.0", "gulp-css2js": "^1.0.2", "gulp-header": "^1.0.2", "gulp-hogan-compile": "^0.2.1", "gulp-minify-css": "^0.3.5", "gulp-notify": "^1.4.1", "gulp-rename": "^1.2.0", "gulp-uglify": "^0.3.1", "gulp-util": "^3.0.0", "hogan.js": "^3.0.2", "jquery-ui": "^1.10.5", "jquery.scrollbar": "^0.2.7", "pretty-hrtime": "^0.2.1", "storage-wrapper": "cletusc/storage-wrapper#v0.1.1", "vinyl-map": "^1.0.1", "vinyl-source-stream": "^0.1.1", "watchify": "^1.0.1" } } },{}],8:[function(require,module,exports){ var logger = require('./logger'); var api = {}; var ember = null; var hookedFactories = {}; api.getEmber = function () { if (ember) { return ember; } if (window.App && window.App.__container__) { ember = window.App.__container__; return ember; } return false; }; api.isLoaded = function () { return Boolean(api.getEmber()); }; api.lookup = function (lookupFactory) { if (!api.isLoaded()) { logger.debug('Factory lookup failure, Ember not loaded.'); return false; } return api.getEmber().lookup(lookupFactory); }; api.hook = function (lookupFactory, activateCb, deactivateCb) { if (!api.isLoaded()) { logger.debug('Factory hook failure, Ember not loaded.'); return false; } if (hookedFactories[lookupFactory]) { logger.debug('Factory already hooked: ' + lookupFactory); return true; } var reopenOptions = {}; var factory = api.lookup(lookupFactory); if (!factory) { logger.debug('Factory hook failure, factory not found: ' + lookupFactory); return false; } if (activateCb) { reopenOptions.activate = function () { this._super(); activateCb.call(this); logger.debug('Hook run on activate: ' + lookupFactory); }; } if (deactivateCb) { reopenOptions.deactivate = function () { this._super(); deactivateCb.call(this); logger.debug('Hook run on deactivate: ' + lookupFactory); }; } try { factory.reopen(reopenOptions); hookedFactories[lookupFactory] = true; logger.debug('Factory hooked: ' + lookupFactory); return true; } catch (err) { logger.debug('Factory hook failure, unexpected error: ' + lookupFactory); logger.debug(err); return false; } }; api.get = function (lookupFactory, property) { if (!api.isLoaded()) { logger.debug('Factory get failure, Ember not loaded.'); return false; } var properties = property.split('.'); var getter = api.lookup(lookupFactory); properties.some(function (property) { // If getter fails, just exit, otherwise, keep looping. if (getter == null || typeof getter === 'undefined') { getter = null; return true; } if (getter[property] == null || typeof getter[property] === 'undefined') { getter = null; return true; } if (typeof getter.get === 'function') { getter = getter.get(property); if (getter == null || typeof getter === 'undefined') { getter = null; return true; } return false; } getter = getter[property]; }); return getter; }; module.exports = api; },{"./logger":10}],9:[function(require,module,exports){ var storage = require('./storage'); var logger = require('./logger'); var ui = require('./ui'); var api = {}; var emoteStore = new EmoteStore(); var $ = window.jQuery; /** * The entire emote storing system. */ function EmoteStore() { var getters = {}; var nativeEmotes = {}; var hasInitialized = false; /** * Get a list of usable emoticons. * @param {function} [filters] A filter method to limit what emotes are returned. Passed to Array#filter. * @param {function|string} [sortBy] How the emotes should be sorted. `function` will be passed to sort via Array#sort. `'channel'` sorts by channel name, globals first. All other values (or omitted) sort alphanumerically. * @param {string} [returnType] `'object'` will return in object format, e.g. `{'Kappa': Emote(...), ...}`. All other values (or omitted) return an array format, e.g. `[Emote(...), ...]`. * @return {object|array} See `returnType` param. */ this.getEmotes = function (filters, sortBy, returnType) { var twitchApi = require('./twitch-api'); // Get native emotes. var emotes = $.extend({}, nativeEmotes); // Parse the custom emotes provided by third party addons. Object.keys(getters).forEach(function (getterName) { // Try the getter. var results = null; try { results = getters[getterName](); } catch (err) { logger.debug('Emote getter `' + getterName + '` failed unexpectedly, skipping.', err.toString()); return; } if (!Array.isArray(results)) { logger.debug('Emote getter `' + getterName + '` must return an array, skipping.'); return; } // Override natives and previous getters. results.forEach(function (emote) { try { // Create the emote. var instance = new Emote(emote); // Force the getter. instance.setGetterName(getterName); // Force emotes without channels to the getter's name. if (!emote.channel) { instance.setChannelName(getterName); } // Add/override it. emotes[instance.getText()] = instance; } catch (err) { logger.debug('Emote parsing for getter `' + getterName + '` failed, skipping.', err.toString(), emote); } }); }); // Covert to array. emotes = Object.keys(emotes).map(function (emote) { return emotes[emote]; }); // Filter results. if (typeof filters === 'function') { emotes = emotes.filter(filters); } // Return as an object if requested. if (returnType === 'object') { var asObject = {}; emotes.forEach(function (emote) { asObject[emote.getText()] = emote; }); return asObject; } // Sort results. if (typeof sortBy === 'function') { emotes.sort(sortBy); } else if (sortBy === 'channel') { emotes.sort(sorting.allEmotesCategory); } else { emotes.sort(sorting.byText); } // Return the emotes in array format. return emotes; }; /** * Registers a 3rd party emote hook. * @param {string} name The name of the 3rd party registering the hook. * @param {function} getter The function called when looking for emotes. Must return an array of emote objects, e.g. `[emote, ...]`. See Emote class. */ this.registerGetter = function (name, getter) { if (typeof name !== 'string') { throw new Error('Name must be a string.'); } if (getters[name]) { throw new Error('Getter already exists.'); } if (typeof getter !== 'function') { throw new Error('Getter must be a function.'); } logger.debug('Getter registered: ' + name); getters[name] = getter; ui.updateEmotes(); }; /** * Registers a 3rd party emote hook. * @param {string} name The name of the 3rd party hook to deregister. */ this.deregisterGetter = function (name) { logger.debug('Getter unregistered: ' + name); delete getters[name]; ui.updateEmotes(); }; /** * Initializes the raw data from the API endpoints. Should be called at load and/or whenever the API may have changed. Populates internal objects with updated data. */ this.init = function () { if (hasInitialized) { logger.debug('Already initialized EmoteStore, stopping init.'); return; } logger.debug('Starting initialization.'); var twitchApi = require('./twitch-api'); var self = this; // Hash of emote set to forced channel. var forcedSetsToChannels = { // Globals. 0: '~global', // Bubble emotes. 33: 'turbo', // Monkey emotes. 42: 'turbo', // Hidden turbo emotes. 457: 'turbo', 793: 'turbo', 19151: 'twitch_prime', 19194: 'twitch_prime' }; logger.debug('Initializing emote set change listener.'); twitchApi.getEmotes(function (emoteSets) { logger.debug('Parsing emote sets.'); Object.keys(emoteSets).forEach(function (set) { var emotes = emoteSets[set]; set = Number(set); emotes.forEach(function (emote) { // Set some required info. emote.url = '//static-cdn.jtvnw.net/emoticons/v1/' + emote.id + '/1.0'; emote.text = getEmoteFromRegEx(emote.code); emote.set = set; // Hardcode the channels of certain sets. if (forcedSetsToChannels[set]) { emote.channel = forcedSetsToChannels[set]; } var instance = new Emote(emote); // Save the emote for use later. nativeEmotes[emote.text] = instance; }); }); logger.debug('Loading subscription data.'); // Get active subscriptions to find the channels. twitchApi.getTickets(function (tickets) { // Instances from each channel to preload channel data. var deferredChannelGets = {}; logger.debug('Tickets loaded from the API.', tickets); tickets.forEach(function (ticket) { var product = ticket.product; var channel = product.owner_name || product.short_name; // Get subscriptions with emotes only. if (!product.emoticons || !product.emoticons.length) { return; } // Set the channel on the emotes. product.emoticons.forEach(function (emote) { var instance = nativeEmotes[getEmoteFromRegEx(emote.regex)]; instance.setChannelName(channel); // Save instance for later, but only one instance per channel. if (!deferredChannelGets[channel]) { deferredChannelGets[channel] = instance; } }); }); // Preload channel data. Object.keys(deferredChannelGets).forEach(function (key) { var instance = deferredChannelGets[key]; instance.getChannelBadge(); instance.getChannelDisplayName(); }); ui.updateEmotes(); }); ui.updateEmotes(); }); hasInitialized = true; logger.debug('Finished EmoteStore initialization.'); }; }; /** * Gets a specific emote, if available. * @param {string} text The text of the emote to get. * @return {Emote|null} The Emote instance of the emote or `null` if it couldn't be found. */ EmoteStore.prototype.getEmote = function (text) { return this.getEmotes(null, null, 'object')[text] || null; }; /** * Emote object. * @param {object} details Object describing the emote. * @param {string} details.text The text to use in the chat box when emote is clicked. * @param {string} details.url The URL of the image for the emote. * @param {string} [details.badge] The URL of the badge for the emote. * @param {string} [details.channel] The channel the emote should be categorized under. * @param {string} [details.getterName] The 3rd party getter that registered the emote. Used internally only. */ function Emote(details) { var text = null; var url = null; var getterName = null; var channel = { name: null, displayName: null, badge: null }; /** * Gets the text of the emote. * @return {string} The emote text. */ this.getText = function () { return text; }; /** * Sets the text of the emote. * @param {string} theText The text to set. */ this.setText = function (theText) { if (typeof theText !== 'string' || theText.length < 1) { throw new Error('Invalid text'); } text = theText; }; /** * Gets the getter name this emote belongs to. * @return {string} The getter's name. */ this.getGetterName = function () { return getterName; }; /** * Sets the getter name this emote belongs to. * @param {string} theGetterName The getter's name. */ this.setGetterName = function (theGetterName) { if (typeof theGetterName !== 'string' || theGetterName.length < 1) { throw new Error('Invalid getter name'); } getterName = theGetterName; }; /** * Gets the emote's image URL. * @return {string} The emote image URL. */ this.getUrl = function () { return url; }; /** * Sets the emote's image URL. * @param {string} theUrl The image URL to set. */ this.setUrl = function (theUrl) { if (typeof theUrl !== 'string' || theUrl.length < 1) { throw new Error('Invalid URL'); } url = theUrl; }; /** * Gets the emote's channel name. * @return {string} The emote's channel or an empty string if it doesn't have one. */ this.getChannelName = function () { if (!channel.name) { channel.name = storage.channelNames.get(this.getText()); } return channel.name || ''; }; /** * Sets the emote's channel name. * @param {string} theChannel The channel name to set. */ this.setChannelName = function (theChannel) { if (typeof theChannel !== 'string' || theChannel.length < 1) { throw new Error('Invalid channel'); } // Only save the channel to storage if it's dynamic. if (theChannel !== '~global' && theChannel !== 'turbo' && theChannel !== 'twitch_prime') { storage.channelNames.set(this.getText(), theChannel); } channel.name = theChannel; }; /** * Gets the emote channel's badge image URL. * @return {string|null} The URL of the badge image for the emote's channel or `null` if it doesn't have a channel. */ this.getChannelBadge = function () { var twitchApi = require('./twitch-api'); var channelName = this.getChannelName(); var defaultBadge = '//static-cdn.jtvnw.net/jtv_user_pictures/subscriber-star.png'; // No channel. if (!channelName) { return null; } // Give globals a default badge. if (channelName === '~global') { return '/favicon.ico'; } // Already have one preset. if (channel.badge) { return channel.badge; } // Check storage. channel.badge = storage.badges.get(channelName); if (channel.badge !== null) { return channel.badge; } // Set default until API returns something. channel.badge = defaultBadge; // Get from API. logger.debug('Getting fresh badge for: ' + channelName); twitchApi.getBadges(channelName, function (badges) { var badge = null; // Save turbo badge while we are here. if (badges.turbo && badges.turbo.image) { badge = badges.turbo.image; storage.badges.set('turbo', badge, 86400000); // Turbo is actually what we wanted, so we are done. if (channelName === 'turbo') { channel.badge = badge; return; } } // Save turbo badge while we are here. if (badges.premium && badges.premium.image) { badge = badges.premium.image; storage.badges.set('twitch_prime', badge, 86400000); // Turbo is actually what we wanted, so we are done. if (channelName === 'twitch_prime') { channel.badge = badge; return; } } // Save subscriber badge in storage. if (badges.subscriber && badges.subscriber.image) { channel.badge = badges.subscriber.image; storage.badges.set(channelName, channel.badge, 86400000); ui.updateEmotes(); } // No subscriber badge. else { channel.badge = defaultBadge; logger.debug('Failed to get subscriber badge for: ' + channelName); } }); return channel.badge || defaultBadge; }; /** * Sets the emote's channel badge image URL. * @param {string} theBadge The badge image URL to set. */ this.setChannelBadge = function (theBadge) { if (typeof theBadge !== 'string' || theBadge.length < 1) { throw new Error('Invalid badge'); } channel.badge = theBadge; }; /** * Get a channel's display name. * @return {string} The channel's display name. May be equivalent to the channel the first time the API needs to be called. */ this.getChannelDisplayName = function () { var twitchApi = require('./twitch-api'); var channelName = this.getChannelName(); var self = this; var forcedChannelToDisplayNames = { '~global': 'Global', 'turbo': 'Twitch Turbo', 'twitch_prime': 'Twitch Prime' }; // No channel. if (!channelName) { return ''; } // Forced display name. if (forcedChannelToDisplayNames[channelName]) { return forcedChannelToDisplayNames[channelName]; } // Already have one preset. if (channel.displayName) { return channel.displayName; } // Look for obvious bad channel names that shouldn't hit the API or storage. Use channel name instead. if (/[^a-z0-9_]/.test(channelName)) { logger.debug('Unable to get display name due to obvious non-standard channel name for: ' + channelName); return channelName; } // Check storage. channel.displayName = storage.displayNames.get(channelName); if (channel.displayName !== null) { return channel.displayName; } // Get from API. else { // Set default until API returns something. channel.displayName = channelName; logger.debug('Getting fresh display name for: ' + channelName); twitchApi.getUser(channelName, function (user) { if (!user || !user.display_name) { logger.debug('Failed to get display name for: ' + channelName); return; } // Save it. self.setChannelDisplayName(user.display_name); ui.updateEmotes(); }); } return channel.displayName; }; /** * Sets the emote's channel badge image URL. * @param {string} theBadge The badge image URL to set. */ this.setChannelDisplayName = function (displayName) { if (typeof displayName !== 'string' || displayName.length < 1) { throw new Error('Invalid displayName'); } channel.displayName = displayName; storage.displayNames.set(this.getChannelName(), displayName, 86400000); }; /** * Initialize the details. */ // Required fields. this.setText(details.text); this.setUrl(details.url); // Optional fields. if (details.getterName) { this.setGetterName(details.getterName); } if (details.channel) { this.setChannelName(details.channel); } if (details.channelDisplayName) { this.setChannelDisplayName(details.channelDisplayName); } if (details.badge) { this.setChannelBadge(details.badge); } }; /** * State changers. */ /** * Toggle whether an emote should be a favorite. * @param {boolean} [force] `true` forces the emote to be a favorite, `false` forces the emote to not be a favorite. */ Emote.prototype.toggleFavorite = function (force) { if (typeof force !== 'undefined') { storage.starred.set(this.getText(), !!force); return; } storage.starred.set(this.getText(), !this.isFavorite()); }; /** * Toggle whether an emote should be visible out of editing mode. * @param {boolean} [force] `true` forces the emote to be visible, `false` forces the emote to be hidden. */ Emote.prototype.toggleVisibility = function (force) { if (typeof force !== 'undefined') { storage.visibility.set(this.getText(), !!force); return; } storage.visibility.set(this.getText(), !this.isVisible()); }; /** * State getters. */ /** * Whether the emote is from a 3rd party. * @return {boolean} Whether the emote is from a 3rd party. */ Emote.prototype.isThirdParty = function () { return !!this.getGetterName(); }; /** * Whether the emote was favorited. * @return {boolean} Whether the emote was favorited. */ Emote.prototype.isFavorite = function () { return storage.starred.get(this.getText(), false); }; /** * Whether the emote is visible outside of editing mode. * @return {boolean} Whether the emote is visible outside of editing mode. */ Emote.prototype.isVisible = function () { return storage.visibility.get(this.getText(), true); }; /** * Whether the emote is considered a simple smiley. * @return {boolean} Whether the emote is considered a simple smiley. */ Emote.prototype.isSmiley = function () { // The basic smiley emotes. var emotes = [':(', ':)', ':/', ':\\', ':D', ':o', ':p', ':z', ';)', ';p', '<3', '>(', 'B)', 'R)', 'o_o', 'O_O', '#/', ':7', ':>', ':S', '<]']; return emotes.indexOf(this.getText()) !== -1; }; /** * Property getters/setters. */ /** * Gets the usable emote text from a regex. */ function getEmoteFromRegEx(regex) { if (typeof regex === 'string') { regex = new RegExp(regex); } if (!regex) { throw new Error('`regex` must be a RegExp string or object.'); } return decodeURI(regex.source) // Replace HTML entity brackets with actual brackets. .replace('>\\;', '>') .replace('<\\;', '<') // Remove negative groups. // // / // \(\?! // (?! // [^)]* // any amount of characters that are not ) // \) // ) // /g .replace(/\(\?![^)]*\)/g, '') // Pick first option from a group. // // / // \( // ( // ([^|])* // any amount of characters that are not | // \|? // an optional | character // [^)]* // any amount of characters that are not ) // \) // ) // /g .replace(/\(([^|])*\|?[^)]*\)/g, '$1') // Pick first character from a character group. // // / // \[ // [ // ([^|\]\[])* // any amount of characters that are not |, [, or ] // \|? // an optional | character // [^\]]* // any amount of characters that are not [, or ] // \] // ] // /g .replace(/\[([^|\]\[])*\|?[^\]\[]*\]/g, '$1') // Remove optional characters. // // / // [^\\] // any character that is not \ // \? // ? // /g .replace(/[^\\]\?/g, '') // Remove boundaries at beginning and end. .replace(/^\\b|\\b$/g, '') // Unescape only single backslash, not multiple. // // / // \\ // \ // (?!\\) // look-ahead, any character that isn't \ // /g .replace(/\\(?!\\)/g, ''); } var sorting = {}; /** * Sort by alphanumeric in this order: symbols -> numbers -> AaBb... -> numbers */ sorting.byText = function (a, b) { textA = a.getText().toLowerCase(); textB = b.getText().toLowerCase(); if (textA < textB) { return -1; } if (textA > textB) { return 1; } return 0; } /** * Basic smilies before non-basic smilies. */ sorting.bySmiley = function (a, b) { if (a.isSmiley() && !b.isSmiley()) { return -1; } if (b.isSmiley() && !a.isSmiley()) { return 1; } return 0; }; /** * Globals before subscription emotes, subscriptions in alphabetical order. */ sorting.byChannelName = function (a, b) { var channelA = a.getChannelName(); var channelB = b.getChannelName(); // Both don't have channels. if (!channelA && !channelB) { return 0; } // "A" has channel, "B" doesn't. if (channelA && !channelB) { return 1; } // "B" has channel, "A" doesn't. if (channelB && !channelA) { return -1; } channelA = channelA.toLowerCase(); channelB = channelB.toLowerCase(); if (channelA < channelB) { return -1; } if (channelB > channelA) { return 1; } // All the same return 0; }; /** * The general sort order for the all emotes category. * Smileys -> Channel grouping -> alphanumeric */ sorting.allEmotesCategory = function (a, b) { var bySmiley = sorting.bySmiley(a, b); var byChannelName = sorting.byChannelName(a, b); var byText = sorting.byText(a, b); if (bySmiley !== 0) { return bySmiley; } if (byChannelName !== 0) { return byChannelName; } return byText; }; module.exports = emoteStore; },{"./logger":10,"./storage":12,"./twitch-api":14,"./ui":15}],10:[function(require,module,exports){ var api = {}; var instance = '[instance ' + (Math.floor(Math.random() * (999 - 100)) + 100) + '] '; var prefix = '[Emote Menu] '; var storage = require('./storage'); api.log = function () { if (typeof console.log === 'undefined') { return; } arguments = [].slice.call(arguments).map(function (arg) { if (typeof arg !== 'string') { return JSON.stringify(arg); } return arg; }); if (storage.global.get('debugMessagesEnabled', false)) { arguments.unshift(instance); } arguments.unshift(prefix); console.log.apply(console, arguments); }; api.debug = function () { if (!storage.global.get('debugMessagesEnabled', false)) { return; } arguments = [].slice.call(arguments); arguments.unshift('[DEBUG] '); api.log.apply(null, arguments); } module.exports = api; },{"./storage":12}],11:[function(require,module,exports){ var storage = require('./storage'); var logger = require('./logger'); var emotes = require('./emotes'); var api = {}; api.toggleDebug = function (forced) { if (typeof forced === 'undefined') { forced = !storage.global.get('debugMessagesEnabled', false); } else { forced = !!forced; } storage.global.set('debugMessagesEnabled', forced); logger.log('Debug messages are now ' + (forced ? 'enabled' : 'disabled')); }; api.registerEmoteGetter = emotes.registerGetter; api.deregisterEmoteGetter = emotes.deregisterGetter; module.exports = api; },{"./emotes":9,"./logger":10,"./storage":12}],12:[function(require,module,exports){ var Store = require('storage-wrapper'); var storage = {}; // General storage. storage.global = new Store({ namespace: 'emote-menu-for-twitch' }); // Emote visibility storage. storage.visibility = storage.global.createSubstore('visibility'); // Emote starred storage. storage.starred = storage.global.createSubstore('starred'); // Display name storage. storage.displayNames = storage.global.createSubstore('displayNames'); // Channel name storage. storage.channelNames = storage.global.createSubstore('channelNames'); // Badges storage. storage.badges = storage.global.createSubstore('badges'); module.exports = storage; },{"storage-wrapper":6}],13:[function(require,module,exports){ var templates = require('../../build/templates'); module.exports = (function () { var data = {}; var key = null; // Convert templates to their shorter "render" form. for (key in templates) { if (!templates.hasOwnProperty(key)) { continue; } data[key] = render(key); } // Shortcut the render function. All templates will be passed in as partials by default. function render(template) { template = templates[template]; return function (context, partials, indent) { return template.render(context, partials || templates, indent); }; } return data; })(); },{"../../build/templates":3}],14:[function(require,module,exports){ var twitchApi = window.Twitch.api; var jQuery = window.jQuery; var logger = require('./logger'); var api = {}; api.getBadges = function (username, callback) { if ( [ '~global', 'turbo', 'twitch_prime' ].indexOf(username) > -1 ) { if (!jQuery) { callback({}); } // Note: not a documented API endpoint. jQuery.getJSON('https://badges.twitch.tv/v1/badges/global/display') .done(function (api) { var badges = { turbo: { image: api.badge_sets.turbo.versions['1'].image_url_1x }, premium: { image: api.badge_sets.premium.versions['1'].image_url_1x } }; callback(badges); }) .fail(function () { callback({}); }); } else { twitchApi.get('chat/' + username + '/badges') .done(function (api) { callback(api); }) .fail(function () { callback({}); }); } }; api.getUser = function (username, callback) { // Note: not a documented API endpoint. twitchApi.get('users/' + username) .done(function (api) { callback(api); }) .fail(function () { callback({}); }); }; api.getTickets = function (callback) { // Note: not a documented API endpoint. twitchApi.get( '/api/users/:login/tickets', { offset: 0, limit: 100, unended: true } ) .done(function (api) { callback(api.tickets || []); }) .fail(function () { callback([]); }); }; api.getEmotes = function (callback) { twitchApi.get('users/:login/emotes') .done(function (response) { if (!response || !response.emoticon_sets) { logger.debug('getEmotes emoticon_sets empty'); callback({}); return; } callback(response.emoticon_sets); }) .fail(function () { logger.debug('getEmotes API call failed'); callback({}); }); }; module.exports = api; },{"./logger":10}],15:[function(require,module,exports){ var api = {}; var $ = jQuery = window.jQuery; var templates = require('./templates'); var storage = require('./storage'); var emotes = require('./emotes'); var logger = require('./logger'); var theMenu = new UIMenu(); var theMenuButton = new UIMenuButton(); api.init = function () { // Load CSS. require('../../build/styles'); // Load jQuery plugins. require('../plugins/resizable'); require('jquery.scrollbar'); theMenuButton.init(); theMenu.init(); }; api.hideMenu = function () { if (theMenu.dom && theMenu.dom.length) { theMenu.toggleDisplay(false); } }; api.updateEmotes = function () { theMenu.updateEmotes(); } function UIMenuButton() { this.dom = null; } UIMenuButton.prototype.init = function (timesFailed) { var self = this; var chatButton = $('.send-chat-button, .chat-buttons-container button'); var failCounter = timesFailed || 0; this.dom = $('#emote-menu-button'); // Element already exists. if (this.dom.length) { logger.debug('MenuButton already exists, stopping init.'); return this; } if (!chatButton.length) { failCounter += 1; if (failCounter === 1) { logger.log('MenuButton container missing, trying again.'); } if (failCounter >= 10) { logger.log('MenuButton container missing, MenuButton unable to be added, stopping init.'); return this; } setTimeout(function () { self.init(failCounter); }, 1000); return this; } // Create element. this.dom = $(templates.emoteButton()); this.dom.insertBefore(chatButton); // Hide then fade it in. this.dom.hide(); this.dom.fadeIn(); // Enable clicking. this.dom.on('click', function () { theMenu.toggleDisplay(); }); return this; }; UIMenuButton.prototype.toggleDisplay = function (forced) { var state = typeof forced !== 'undefined' ? !!forced : !this.isVisible(); if (state) { this.dom.addClass('active'); return this; } this.dom.removeClass('active'); return this; }; UIMenuButton.prototype.isVisible = function () { return this.dom.hasClass('active'); }; function UIMenu() { this.dom = null; this.groups = {}; this.emotes = []; this.offset = null; this.favorites = null; } UIMenu.prototype.init = function () { var logger = require('./logger'); var self = this; this.dom = $('#emote-menu-for-twitch'); // Element already exists. if (this.dom.length) { return this; } // Create element. this.dom = $(templates.menu()); $(document.body).append(this.dom); this.favorites = new UIFavoritesGroup(); // Enable dragging. this.dom.draggable({ handle: '.draggable', start: function () { self.togglePinned(true); self.toggleMovement(true); }, stop: function () { self.offset = self.dom.offset(); }, containment: $(document.body) }); // Enable resizing. this.dom.resizable({ handle: '[data-command="resize-handle"]', stop: function () { self.togglePinned(true); self.toggleMovement(true); }, alsoResize: self.dom.find('.scrollable'), containment: $(document.body), minHeight: 180, minWidth: 200 }); // Enable pinning. this.dom.find('[data-command="toggle-pinned"]').on('click', function () { self.togglePinned(); }); // Enable editing. this.dom.find('[data-command="toggle-editing"]').on('click', function () { self.toggleEditing(); }); this.dom.find('.scrollable').scrollbar() this.updateEmotes(); return this; }; UIMenu.prototype._detectOutsideClick = function (event) { // Not outside of the menu, ignore the click. if ($(event.target).is('#emote-menu-for-twitch, #emote-menu-for-twitch *')) { return; } // Clicked on the menu button, just remove the listener and let the normal listener handle it. if (!this.isVisible() || $(event.target).is('#emote-menu-button, #emote-menu-button *')) { $(document).off('mouseup', this._detectOutsideClick.bind(this)); return; } // Clicked outside, make sure the menu isn't pinned. if (!this.isPinned()) { // Menu wasn't pinned, remove listener. $(document).off('mouseup', this._detectOutsideClick.bind(this)); this.toggleDisplay(); } }; UIMenu.prototype.toggleDisplay = function (forced) { var state = typeof forced !== 'undefined' ? !!forced : !this.isVisible(); var loggedIn = window.Twitch && window.Twitch.user.isLoggedIn(); // Menu should be shown. if (state) { // Check if user is logged in. if (!loggedIn) { // Call native login form. $.login(); return this; } this.updateEmotes(); this.dom.show(); // Menu moved, move it back. if (this.hasMoved()) { this.dom.offset(this.offset); } // Never moved, make it the same size as the chat window. else { var chatContainer = $('.chat-messages'); // Adjust the size to be the same as the chat container. this.dom.height(chatContainer.outerHeight() - (this.dom.outerHeight() - this.dom.height())); this.dom.width(chatContainer.outerWidth() - (this.dom.outerWidth() - this.dom.width())); // Adjust the offset to be the same as the chat container. this.offset = chatContainer.offset(); this.dom.offset(this.offset); } // Listen for outside click. $(document).on('mouseup', this._detectOutsideClick.bind(this)); } // Menu should be hidden. else { this.dom.hide(); this.toggleEditing(false); this.togglePinned(false); } // Also toggle the menu button. theMenuButton.toggleDisplay(this.isVisible()); return this; }; UIMenu.prototype.isVisible = function () { return this.dom.is(':visible'); }; UIMenu.prototype.updateEmotes = function (which) { var emote = which ? this.getEmote(which) : null; var favoriteEmote = emote ? this.favorites.getEmote(which) : null; if (emote) { emote.update(); if (favoriteEmote) { favoriteEmote.update(); } return this; } var emotes = require('./emotes'); var theEmotes = emotes.getEmotes(); var theEmotesKeys = []; var self = this; theEmotes.forEach(function (emoteInstance) { self.addEmote(emoteInstance); theEmotesKeys.push(emoteInstance.getText()); }); // Difference the emotes and remove all non-valid emotes. this.emotes.forEach(function (oldEmote) { var text = oldEmote.getText() if (theEmotesKeys.indexOf(text) < 0) { logger.debug('Emote difference found, removing emote from UI: ' + text); self.removeEmote(text); } }); // Save the emotes for next differencing. this.emotes = theEmotes; //Update groups. Object.keys(this.groups).forEach(function (group) { self.getGroup(group).init(); }); return this; }; UIMenu.prototype.toggleEditing = function (forced) { var state = typeof forced !== 'undefined' ? !!forced : !this.isEditing(); this.dom.toggleClass('editing', state); return this; }; UIMenu.prototype.isEditing = function () { return this.dom.hasClass('editing'); }; UIMenu.prototype.togglePinned = function (forced) { var state = typeof forced !== 'undefined' ? !!forced : !this.isPinned(); this.dom.toggleClass('pinned', state); return this; }; UIMenu.prototype.isPinned = function () { return this.dom.hasClass('pinned'); }; UIMenu.prototype.toggleMovement = function (forced) { var state = typeof forced !== 'undefined' ? !!forced : !this.hasMoved(); this.dom.toggleClass('moved', state); return this; }; UIMenu.prototype.hasMoved = function () { return this.dom.hasClass('moved'); }; UIMenu.prototype.addGroup = function (emoteInstance) { var channel = emoteInstance.getChannelName(); var self = this; // Already added, don't add again. if (this.getGroup(channel)) { return this; } // Add to current menu groups. var group = new UIGroup(emoteInstance); this.groups[channel] = group; // Sort group names, get index of where this group should go. var keys = Object.keys(this.groups); keys.sort(function (a, b) { // Get the instances. a = self.groups[a].emoteInstance; b = self.groups[b].emoteInstance; // Get the channel name. var aChannel = a.getChannelName(); var bChannel = b.getChannelName(); // Get the channel display name. a = a.getChannelDisplayName().toLowerCase(); b = b.getChannelDisplayName().toLowerCase(); // Prime goes first, always. if (aChannel === 'twitch_prime' && bChannel !== 'twitch_prime') { return -1; } if (bChannel === 'twitch_prime' && aChannel !== 'twitch_prime') { return 1; } // Turbo goes after Prime, always. if (aChannel === 'turbo' && bChannel !== 'turbo') { return -1; } if (bChannel === 'turbo' && aChannel !== 'turbo') { return 1; } // Global goes after Turbo, always. if (aChannel === '~global' && bChannel !== '~global') { return -1; } if (bChannel === '~global' && aChannel !== '~global') { return 1; } // A goes first. if (a < b) { return -1; } // B goest first. if (a > b) { return 1; } // Both the same, doesn't matter. return 0; }); var index = keys.indexOf(channel); // First in the sort, place at the beginning of the menu. if (index === 0) { group.dom.prependTo(this.dom.find('#all-emotes-group')); } // Insert after the previous group in the sort. else { group.dom.insertAfter(this.getGroup(keys[index - 1]).dom); } return group; }; UIMenu.prototype.getGroup = function (name) { return this.groups[name] || null; }; UIMenu.prototype.addEmote = function (emoteInstance) { // Get the group, or add if needed. var group = this.getGroup(emoteInstance.getChannelName()) || this.addGroup(emoteInstance); group.addEmote(emoteInstance); group.toggleDisplay(group.isVisible(), true); this.favorites.addEmote(emoteInstance); return this; }; UIMenu.prototype.removeEmote = function (name) { var self = this; Object.keys(this.groups).forEach(function (groupName) { self.groups[groupName].removeEmote(name); }); this.favorites.removeEmote(name); return this; }; UIMenu.prototype.getEmote = function (name) { var groupName = null; var group = null; var emote = null; for (groupName in this.groups) { group = this.groups[groupName]; emote = group.getEmote(name); if (emote) { return emote; } } return null; }; function UIGroup(emoteInstance) { this.dom = null; this.emotes = {}; this.emoteInstance = emoteInstance; this.init(); } UIGroup.prototype.init = function () { var self = this; var emoteInstance = this.emoteInstance; // First init, create new DOM. if (this.dom === null) { this.dom = $(templates.emoteGroupHeader({ badge: emoteInstance.getChannelBadge(), channel: emoteInstance.getChannelName(), channelDisplayName: emoteInstance.getChannelDisplayName() })); } // Update DOM instead. else { this.dom.find('.header-info').replaceWith( $(templates.emoteGroupHeader({ badge: emoteInstance.getChannelBadge(), channel: emoteInstance.getChannelName(), channelDisplayName: emoteInstance.getChannelDisplayName() })) .find('.header-info') ); } // Enable emote hiding. this.dom.find('.header-info [data-command="toggle-visibility"]').on('click', function () { if (!theMenu.isEditing()) { return; } self.toggleDisplay(); }); this.toggleDisplay(this.isVisible(), true); }; UIGroup.prototype.toggleDisplay = function (forced, skipUpdatingEmoteDisplay) { var self = this; var state = typeof forced !== 'undefined' ? !forced : this.isVisible(); this.dom.toggleClass('emote-menu-hidden', state); // Update the display of all emotes. if (!skipUpdatingEmoteDisplay) { Object.keys(this.emotes).forEach(function (emoteName) { self.emotes[emoteName].toggleDisplay(!state); theMenu.updateEmotes(self.emotes[emoteName].instance.getText()); }); } return this; }; UIGroup.prototype.isVisible = function () { var self = this; // If any emote is visible, the group should be visible. return Object.keys(this.emotes).some(function (emoteName) { return self.emotes[emoteName].isVisible(); }); }; UIGroup.prototype.addEmote = function (emoteInstance) { var self = this; var emote = this.getEmote(emoteInstance.getText()); // Already added, update instead. if (emote) { emote.update(); return this; } // Add to current emotes. emote = new UIEmote(emoteInstance); this.emotes[emoteInstance.getText()] = emote; var keys = Object.keys(this.emotes); keys.sort(function (a, b) { // Get the emote instances. a = self.emotes[a].instance; b = self.emotes[b].instance; // A is a smiley, B isn't. A goes first. if (a.isSmiley() && !b.isSmiley()) { return -1; } // B is a smiley, A isn't. B goes first. if (b.isSmiley() && !a.isSmiley()) { return 1; } // Get the text of the emotes. a = a.getText().toLowerCase(); b = b.getText().toLowerCase(); // A goes first. if (a < b) { return -1; } // B goest first. if (a > b) { return 1; } // Both the same, doesn't matter. return 0; }); var index = keys.indexOf(emoteInstance.getText()); // First in the sort, place at the beginning of the group. if (index === 0) { emote.dom.prependTo(this.dom.find('.emote-container')); } // Insert after the previous emote in the sort. else { emote.dom.insertAfter(this.getEmote(keys[index - 1]).dom); } return this; }; UIGroup.prototype.getEmote = function (name) { return this.emotes[name] || null; }; UIGroup.prototype.removeEmote = function (name) { var emote = this.getEmote(name); if (!emote) { return this; } emote.dom.remove(); delete this.emotes[name]; return this; }; function UIFavoritesGroup() { this.dom = $('#starred-emotes-group'); this.emotes = {}; } UIFavoritesGroup.prototype.addEmote = UIGroup.prototype.addEmote; UIFavoritesGroup.prototype.getEmote = UIGroup.prototype.getEmote; UIFavoritesGroup.prototype.removeEmote = UIGroup.prototype.removeEmote; function UIEmote(emoteInstance) { this.dom = null; this.instance = emoteInstance; this.init(); } UIEmote.prototype.init = function () { var self = this; // Create element. this.dom = $(templates.emote({ url: this.instance.getUrl(), text: this.instance.getText(), thirdParty: this.instance.isThirdParty(), isVisible: this.instance.isVisible(), isStarred: this.instance.isFavorite() })); // Enable clicking. this.dom.on('click', function () { if (!theMenu.isEditing()) { self.addToChat(); // Close the menu if not pinned. if (!theMenu.isPinned()) { theMenu.toggleDisplay(); } } }); // Enable emote hiding. this.dom.find('[data-command="toggle-visibility"]').on('click', function () { if (!theMenu.isEditing()) { return; } self.toggleDisplay(); theMenu.updateEmotes(self.instance.getText()); }); // Enable emote favoriting. this.dom.find('[data-command="toggle-starred"]').on('click', function () { if (!theMenu.isEditing()) { return; } self.toggleFavorite(); theMenu.updateEmotes(self.instance.getText()); }); return this; }; UIEmote.prototype.toggleDisplay = function (forced, skipInstanceUpdate) { var state = typeof forced !== 'undefined' ? !forced : this.isVisible(); this.dom.toggleClass('emote-menu-hidden', state); if (!skipInstanceUpdate) { this.instance.toggleVisibility(!state); } var group = this.getGroup(); group.toggleDisplay(group.isVisible(), true); return this; }; UIEmote.prototype.isVisible = function () { return !this.dom.hasClass('emote-menu-hidden'); }; UIEmote.prototype.toggleFavorite = function (forced, skipInstanceUpdate) { var state = typeof forced !== 'undefined' ? !!forced : !this.isFavorite(); this.dom.toggleClass('emote-menu-starred', state); if (!skipInstanceUpdate) { this.instance.toggleFavorite(state); } return this; }; UIEmote.prototype.isFavorite = function () { return this.dom.hasClass('emote-menu-starred'); }; UIEmote.prototype.addToChat = function () { var ember = require('./ember-api'); // Get textarea element. var element = $('.chat-interface textarea').get(0); var text = this.instance.getText(); // Insert at cursor / replace selection. // https://developer.mozilla.org/en-US/docs/Code_snippets/Miscellaneous var selectionEnd = element.selectionStart + text.length; var currentValue = element.value; var beforeText = currentValue.substring(0, element.selectionStart); var afterText = currentValue.substring(element.selectionEnd, currentValue.length); // Smart padding, only put space at start if needed. if ( beforeText !== '' && beforeText.substr(-1) !== ' ' ) { text = ' ' + text; } // Always put space at end. text = beforeText + text + ' ' + afterText; // Set the text. ember.get('controller:chat', 'currentRoom').set('messageToSend', text); element.focus(); // Put cursor at end. selectionEnd = element.selectionStart + text.length; element.setSelectionRange(selectionEnd, selectionEnd); return this; }; UIEmote.prototype.getGroup = function () { return theMenu.getGroup(this.instance.getChannelName()); }; UIEmote.prototype.update = function () { this.toggleDisplay(this.instance.isVisible(), true); this.toggleFavorite(this.instance.isFavorite(), true); }; module.exports = api; },{"../../build/styles":2,"../plugins/resizable":16,"./ember-api":8,"./emotes":9,"./logger":10,"./storage":12,"./templates":13,"jquery.scrollbar":5}],16:[function(require,module,exports){ (function ($) { $.fn.resizable = function (options) { var settings = $.extend({ alsoResize: null, alsoResizeType: 'both', // `height`, `width`, `both` containment: null, create: null, destroy: null, handle: '.resize-handle', maxHeight: 9999, maxWidth: 9999, minHeight: 0, minWidth: 0, resize: null, resizeOnce: null, snapSize: 1, start: null, stop: null }, options); settings.element = $(this); function recalculateSize(evt) { var data = evt.data, resized = {}; data.diffX = Math.round((evt.pageX - data.pageX) / settings.snapSize) * settings.snapSize; data.diffY = Math.round((evt.pageY - data.pageY) / settings.snapSize) * settings.snapSize; if (Math.abs(data.diffX) > 0 || Math.abs(data.diffY) > 0) { if ( settings.element.height() !== data.height + data.diffY && data.height + data.diffY >= settings.minHeight && data.height + data.diffY <= settings.maxHeight && (settings.containment ? data.outerHeight + data.diffY + data.offset.top <= settings.containment.offset().top + settings.containment.outerHeight() : true) ) { settings.element.height(data.height + data.diffY); resized.height = true; } if ( settings.element.width() !== data.width + data.diffX && data.width + data.diffX >= settings.minWidth && data.width + data.diffX <= settings.maxWidth && (settings.containment ? data.outerWidth + data.diffX + data.offset.left <= settings.containment.offset().left + settings.containment.outerWidth() : true) ) { settings.element.width(data.width + data.diffX); resized.width = true; } if (resized.height || resized.width) { if (settings.resizeOnce) { settings.resizeOnce.bind(settings.element)(evt.data); settings.resizeOnce = null; } if (settings.resize) { settings.resize.bind(settings.element)(evt.data); } if (settings.alsoResize) { if (resized.height && (settings.alsoResizeType === 'height' || settings.alsoResizeType === 'both')) { settings.alsoResize.height(data.alsoResizeHeight + data.diffY); } if (resized.width && (settings.alsoResizeType === 'width' || settings.alsoResizeType === 'both')) { settings.alsoResize.width(data.alsoResizeWidth + data.diffX); } } } } } function start(evt) { evt.preventDefault(); if (settings.start) { settings.start.bind(settings.element)(); } var data = { alsoResizeHeight: settings.alsoResize ? settings.alsoResize.height() : 0, alsoResizeWidth: settings.alsoResize ? settings.alsoResize.width() : 0, height: settings.element.height(), offset: settings.element.offset(), outerHeight: settings.element.outerHeight(), outerWidth: settings.element.outerWidth(), pageX: evt.pageX, pageY: evt.pageY, width: settings.element.width() }; $(document).on('mousemove', '*', data, recalculateSize); $(document).on('mouseup', '*', stop); } function stop() { if (settings.stop) { settings.stop.bind(settings.element)(); } $(document).off('mousemove', '*', recalculateSize); $(document).off('mouseup', '*', stop); } if (settings.handle) { if (settings.alsoResize && ['both', 'height', 'width'].indexOf(settings.alsoResizeType) >= 0) { settings.alsoResize = $(settings.alsoResize); } if (settings.containment) { settings.containment = $(settings.containment); } settings.handle = $(settings.handle); settings.snapSize = settings.snapSize < 1 ? 1 : settings.snapSize; if (options === 'destroy') { settings.handle.off('mousedown', start); if (settings.destroy) { settings.destroy.bind(this)(); } return this; } settings.handle.on('mousedown', start); if (settings.create) { settings.create.bind(this)(); } } return this; }; })(jQuery); },{}]},{},[1]) //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlc1xcYnJvd3NlcmlmeVxcbm9kZV9tb2R1bGVzXFxicm93c2VyLXBhY2tcXF9wcmVsdWRlLmpzIiwiLi9zcmMvc2NyaXB0LmpzIiwiQzovVXNlcnMvQ2xldHVzL1Byb2plY3RzL1VzZXJzY3JpcHQtLVR3aXRjaC1DaGF0LUVtb3Rlcy9idWlsZC9zdHlsZXMuanMiLCJDOi9Vc2Vycy9DbGV0dXMvUHJvamVjdHMvVXNlcnNjcmlwdC0tVHdpdGNoLUNoYXQtRW1vdGVzL2J1aWxkL3RlbXBsYXRlcy5qcyIsIkM6L1VzZXJzL0NsZXR1cy9Qcm9qZWN0cy9Vc2Vyc2NyaXB0LS1Ud2l0Y2gtQ2hhdC1FbW90ZXMvbm9kZV9tb2R1bGVzL2hvZ2FuLmpzL2xpYi90ZW1wbGF0ZS5qcyIsIkM6L1VzZXJzL0NsZXR1cy9Qcm9qZWN0cy9Vc2Vyc2NyaXB0LS1Ud2l0Y2gtQ2hhdC1FbW90ZXMvbm9kZV9tb2R1bGVzL2pxdWVyeS5zY3JvbGxiYXIvanF1ZXJ5LnNjcm9sbGJhci5taW4uanMiLCJDOi9Vc2Vycy9DbGV0dXMvUHJvamVjdHMvVXNlcnNjcmlwdC0tVHdpdGNoLUNoYXQtRW1vdGVzL25vZGVfbW9kdWxlcy9zdG9yYWdlLXdyYXBwZXIvaW5kZXguanMiLCJDOi9Vc2Vycy9DbGV0dXMvUHJvamVjdHMvVXNlcnNjcmlwdC0tVHdpdGNoLUNoYXQtRW1vdGVzL3BhY2thZ2UuanNvbiIsIkM6L1VzZXJzL0NsZXR1cy9Qcm9qZWN0cy9Vc2Vyc2NyaXB0LS1Ud2l0Y2gtQ2hhdC1FbW90ZXMvc3JjL21vZHVsZXMvZW1iZXItYXBpLmpzIiwiQzovVXNlcnMvQ2xldHVzL1Byb2plY3RzL1VzZXJzY3JpcHQtLVR3aXRjaC1DaGF0LUVtb3Rlcy9zcmMvbW9kdWxlcy9lbW90ZXMuanMiLCJDOi9Vc2Vycy9DbGV0dXMvUHJvamVjdHMvVXNlcnNjcmlwdC0tVHdpdGNoLUNoYXQtRW1vdGVzL3NyYy9tb2R1bGVzL2xvZ2dlci5qcyIsIkM6L1VzZXJzL0NsZXR1cy9Qcm9qZWN0cy9Vc2Vyc2NyaXB0LS1Ud2l0Y2gtQ2hhdC1FbW90ZXMvc3JjL21vZHVsZXMvcHVibGljLWFwaS5qcyIsIkM6L1VzZXJzL0NsZXR1cy9Qcm9qZWN0cy9Vc2Vyc2NyaXB0LS1Ud2l0Y2gtQ2hhdC1FbW90ZXMvc3JjL21vZHVsZXMvc3RvcmFnZS5qcyIsIkM6L1VzZXJzL0NsZXR1cy9Qcm9qZWN0cy9Vc2Vyc2NyaXB0LS1Ud2l0Y2gtQ2hhdC1FbW90ZXMvc3JjL21vZHVsZXMvdGVtcGxhdGVzLmpzIiwiQzovVXNlcnMvQ2xldHVzL1Byb2plY3RzL1VzZXJzY3JpcHQtLVR3aXRjaC1DaGF0LUVtb3Rlcy9zcmMvbW9kdWxlcy90d2l0Y2gtYXBpLmpzIiwiQzovVXNlcnMvQ2xldHVzL1Byb2plY3RzL1VzZXJzY3JpcHQtLVR3aXRjaC1DaGF0LUVtb3Rlcy9zcmMvbW9kdWxlcy91aS5qcyIsIkM6L1VzZXJzL0NsZXR1cy9Qcm9qZWN0cy9Vc2Vyc2NyaXB0LS1Ud2l0Y2gtQ2hhdC1FbW90ZXMvc3JjL3BsdWdpbnMvcmVzaXphYmxlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdmJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL3VCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsInZhciBwa2cgPSByZXF1aXJlKCcuLi9wYWNrYWdlLmpzb24nKTtcclxudmFyIHB1YmxpY0FwaSA9IHJlcXVpcmUoJy4vbW9kdWxlcy9wdWJsaWMtYXBpJyk7XHJcbnZhciBlbWJlciA9IHJlcXVpcmUoJy4vbW9kdWxlcy9lbWJlci1hcGknKTtcclxudmFyIGxvZ2dlciA9IHJlcXVpcmUoJy4vbW9kdWxlcy9sb2dnZXInKTtcclxudmFyIGVtb3RlcyA9IHJlcXVpcmUoJy4vbW9kdWxlcy9lbW90ZXMnKTtcclxudmFyIHVpID0gcmVxdWlyZSgnLi9tb2R1bGVzL3VpJyk7XHJcblxyXG5sb2dnZXIubG9nKCcodicrIHBrZy52ZXJzaW9uICsgJykgSW5pdGlhbCBsb2FkIG9uICcgKyBsb2NhdGlvbi5ocmVmKTtcclxuXHJcbi8vIE9ubHkgZW5hYmxlIHNjcmlwdCBpZiB3ZSBoYXZlIHRoZSByaWdodCB2YXJpYWJsZXMuXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbnZhciBpbml0VGltZXIgPSAwO1xyXG4oZnVuY3Rpb24gaW5pdCh0aW1lKSB7XHRcclxuXHRpZiAoIXRpbWUpIHtcclxuXHRcdHRpbWUgPSAwO1xyXG5cdH1cclxuXHJcblx0dmFyIG9iamVjdHNMb2FkZWQgPSAoXHJcblx0XHR3aW5kb3cuVHdpdGNoICE9PSB1bmRlZmluZWQgJiZcclxuXHRcdHdpbmRvdy5qUXVlcnkgIT09IHVuZGVmaW5lZCAmJlxyXG5cdFx0ZW1iZXIuaXNMb2FkZWQoKVxyXG5cdCk7XHJcblx0aWYgKCFvYmplY3RzTG9hZGVkKSB7XHJcblx0XHQvLyBTdG9wcyB0cnlpbmcgYWZ0ZXIgMTAgbWludXRlcy5cclxuXHRcdGlmIChpbml0VGltZXIgPj0gNjAwMDAwKSB7XHJcblx0XHRcdGxvZ2dlci5sb2coJ1Rha2luZyB0b28gbG9uZyB0byBsb2FkLCBzdG9wcGluZy4gUmVmcmVzaCB0aGUgcGFnZSB0byB0cnkgYWdhaW4uICgnICsgaW5pdFRpbWVyICsgJ21zKScpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gR2l2ZSBhbiB1cGRhdGUgZXZlcnkgMTAgc2Vjb25kcy5cclxuXHRcdGlmIChpbml0VGltZXIgJSAxMDAwMCkge1xyXG5cdFx0XHRsb2dnZXIuZGVidWcoJ1N0aWxsIHdhaXRpbmcgZm9yIG9iamVjdHMgdG8gbG9hZC4gKCcgKyBpbml0VGltZXIgKyAnbXMpJyk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQnVtcCB0aW1lIHVwIGFmdGVyIDFzIHRvIHJlZHVjZSBwb3NzaWJsZSBsYWcuXHJcblx0XHR0aW1lID0gdGltZSA+PSAxMDAwID8gMTAwMCA6IHRpbWUgKyAyNTtcclxuXHRcdGluaXRUaW1lciArPSB0aW1lO1xyXG5cclxuXHRcdHNldFRpbWVvdXQoaW5pdCwgdGltZSwgdGltZSk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdFxyXG5cdC8vIEV4cG9zZSBwdWJsaWMgYXBpLlxyXG5cdGlmICh0eXBlb2Ygd2luZG93LmVtb3RlTWVudSA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuXHRcdHdpbmRvdy5lbW90ZU1lbnUgPSBwdWJsaWNBcGk7XHJcblx0fVxyXG5cclxuXHRlbWJlci5ob29rKCdyb3V0ZTpjaGFubmVsJywgYWN0aXZhdGUsIGRlYWN0aXZhdGUpO1xyXG5cdGVtYmVyLmhvb2soJ3JvdXRlOmNoYXQnLCBhY3RpdmF0ZSwgZGVhY3RpdmF0ZSk7XHJcblxyXG5cdGFjdGl2YXRlKCk7XHJcbn0pKCk7XHJcblxyXG5mdW5jdGlvbiBhY3RpdmF0ZSgpIHtcclxuXHR1aS5pbml0KCk7XHJcblx0ZW1vdGVzLmluaXQoKTtcclxufVxyXG5mdW5jdGlvbiBkZWFjdGl2YXRlKCkge1xyXG5cdHVpLmhpZGVNZW51KCk7XHJcbn1cclxuIiwiKGZ1bmN0aW9uIChkb2MsIGNzc1RleHQpIHtcbiAgICB2YXIgaWQgPSBcImVtb3RlLW1lbnUtZm9yLXR3aXRjaC1zdHlsZXNcIjtcbiAgICB2YXIgc3R5bGVFbCA9IGRvYy5nZXRFbGVtZW50QnlJZChpZCk7XG4gICAgaWYgKCFzdHlsZUVsKSB7XG4gICAgICAgIHN0eWxlRWwgPSBkb2MuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICAgICAgICBzdHlsZUVsLmlkID0gaWQ7XG4gICAgICAgIGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQoc3R5bGVFbCk7XG4gICAgfVxuICAgIGlmIChzdHlsZUVsLnN0eWxlU2hlZXQpIHtcbiAgICAgICAgaWYgKCFzdHlsZUVsLnN0eWxlU2hlZXQuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHN0eWxlRWwuc3R5bGVTaGVldC5jc3NUZXh0ID0gY3NzVGV4dDtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzdHlsZUVsLmlubmVySFRNTCA9IGNzc1RleHQ7XG4gICAgICAgIH0gY2F0Y2ggKGlnbm9yZSkge1xuICAgICAgICAgICAgc3R5bGVFbC5pbm5lclRleHQgPSBjc3NUZXh0O1xuICAgICAgICB9XG4gICAgfVxufShkb2N1bWVudCwgXCIvKipcXG5cIiArXG5cIiAqIE1pbmlmaWVkIHN0eWxlLlxcblwiICtcblwiICogT3JpZ2luYWwgZmlsZW5hbWU6IFxcXFxub2RlX21vZHVsZXNcXFxcanF1ZXJ5LnNjcm9sbGJhclxcXFxqcXVlcnkuc2Nyb2xsYmFyLmNzc1xcblwiICtcblwiICovXFxuXCIgK1xuXCIuc2Nyb2xsLXdyYXBwZXJ7b3ZlcmZsb3c6aGlkZGVuIWltcG9ydGFudDtwYWRkaW5nOjAhaW1wb3J0YW50O3Bvc2l0aW9uOnJlbGF0aXZlfS5zY3JvbGwtd3JhcHBlcj4uc2Nyb2xsLWNvbnRlbnR7Ym9yZGVyOm5vbmUhaW1wb3J0YW50Oy1tb3otYm94LXNpemluZzpjb250ZW50LWJveCFpbXBvcnRhbnQ7Ym94LXNpemluZzpjb250ZW50LWJveCFpbXBvcnRhbnQ7aGVpZ2h0OmF1dG87bGVmdDowO21hcmdpbjowO21heC1oZWlnaHQ6bm9uZSFpbXBvcnRhbnQ7bWF4LXdpZHRoOm5vbmUhaW1wb3J0YW50O292ZXJmbG93OnNjcm9sbCFpbXBvcnRhbnQ7cGFkZGluZzowO3Bvc2l0aW9uOnJlbGF0aXZlIWltcG9ydGFudDt0b3A6MDt3aWR0aDphdXRvIWltcG9ydGFudH0uc2Nyb2xsLXdyYXBwZXI+LnNjcm9sbC1jb250ZW50Ojotd2Via2l0LXNjcm9sbGJhcntoZWlnaHQ6MDt3aWR0aDowfS5zY3JvbGwtZWxlbWVudHtkaXNwbGF5Om5vbmV9LnNjcm9sbC1lbGVtZW50LC5zY3JvbGwtZWxlbWVudCBkaXZ7LW1vei1ib3gtc2l6aW5nOmNvbnRlbnQtYm94O2JveC1zaXppbmc6Y29udGVudC1ib3h9LnNjcm9sbC1lbGVtZW50LnNjcm9sbC14LnNjcm9sbC1zY3JvbGx4X3Zpc2libGUsLnNjcm9sbC1lbGVtZW50LnNjcm9sbC15LnNjcm9sbC1zY3JvbGx5X3Zpc2libGV7ZGlzcGxheTpibG9ja30uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1hcnJvdywuc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1iYXJ7Y3Vyc29yOmRlZmF1bHR9LnNjcm9sbC10ZXh0YXJlYXtib3JkZXI6MXB4IHNvbGlkICNjY2M7Ym9yZGVyLXRvcC1jb2xvcjojOTk5fS5zY3JvbGwtdGV4dGFyZWE+LnNjcm9sbC1jb250ZW50e292ZXJmbG93OmhpZGRlbiFpbXBvcnRhbnR9LnNjcm9sbC10ZXh0YXJlYT4uc2Nyb2xsLWNvbnRlbnQ+dGV4dGFyZWF7Ym9yZGVyOm5vbmUhaW1wb3J0YW50Oy1tb3otYm94LXNpemluZzpib3JkZXItYm94O2JveC1zaXppbmc6Ym9yZGVyLWJveDtoZWlnaHQ6MTAwJSFpbXBvcnRhbnQ7bWFyZ2luOjA7bWF4LWhlaWdodDpub25lIWltcG9ydGFudDttYXgtd2lkdGg6bm9uZSFpbXBvcnRhbnQ7b3ZlcmZsb3c6c2Nyb2xsIWltcG9ydGFudDtvdXRsaW5lOjA7cGFkZGluZzoycHg7cG9zaXRpb246cmVsYXRpdmUhaW1wb3J0YW50O3RvcDowO3dpZHRoOjEwMCUhaW1wb3J0YW50fS5zY3JvbGwtdGV4dGFyZWE+LnNjcm9sbC1jb250ZW50PnRleHRhcmVhOjotd2Via2l0LXNjcm9sbGJhcntoZWlnaHQ6MDt3aWR0aDowfS5zY3JvbGxiYXItaW5uZXI+LnNjcm9sbC1lbGVtZW50LC5zY3JvbGxiYXItaW5uZXI+LnNjcm9sbC1lbGVtZW50IGRpdntib3JkZXI6bm9uZTttYXJnaW46MDtwYWRkaW5nOjA7cG9zaXRpb246YWJzb2x1dGU7ei1pbmRleDoxMH0uc2Nyb2xsYmFyLWlubmVyPi5zY3JvbGwtZWxlbWVudCBkaXZ7ZGlzcGxheTpibG9jaztoZWlnaHQ6MTAwJTtsZWZ0OjA7dG9wOjA7d2lkdGg6MTAwJX0uc2Nyb2xsYmFyLWlubmVyPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteHtib3R0b206MnB4O2hlaWdodDo4cHg7bGVmdDowO3dpZHRoOjEwMCV9LnNjcm9sbGJhci1pbm5lcj4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXl7aGVpZ2h0OjEwMCU7cmlnaHQ6MnB4O3RvcDowO3dpZHRoOjhweH0uc2Nyb2xsYmFyLWlubmVyPi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWVsZW1lbnRfb3V0ZXJ7b3ZlcmZsb3c6aGlkZGVufS5zY3JvbGxiYXItaW5uZXI+LnNjcm9sbC1lbGVtZW50IC5zY3JvbGwtYmFyLC5zY3JvbGxiYXItaW5uZXI+LnNjcm9sbC1lbGVtZW50IC5zY3JvbGwtZWxlbWVudF9vdXRlciwuc2Nyb2xsYmFyLWlubmVyPi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWVsZW1lbnRfdHJhY2t7Ym9yZGVyLXJhZGl1czo4cHh9LnNjcm9sbGJhci1pbm5lcj4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1iYXIsLnNjcm9sbGJhci1pbm5lcj4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1lbGVtZW50X3RyYWNrey1tcy1maWx0ZXI6XFxcInByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5BbHBoYShPcGFjaXR5PTQwKVxcXCI7ZmlsdGVyOmFscGhhKG9wYWNpdHk9NDApO29wYWNpdHk6LjR9LnNjcm9sbGJhci1pbm5lcj4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1lbGVtZW50X3RyYWNre2JhY2tncm91bmQtY29sb3I6I2UwZTBlMH0uc2Nyb2xsYmFyLWlubmVyPi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWJhcntiYWNrZ3JvdW5kLWNvbG9yOiNjMmMyYzJ9LnNjcm9sbGJhci1pbm5lcj4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLWRyYWdnYWJsZSAuc2Nyb2xsLWJhciwuc2Nyb2xsYmFyLWlubmVyPi5zY3JvbGwtZWxlbWVudDpob3ZlciAuc2Nyb2xsLWJhcntiYWNrZ3JvdW5kLWNvbG9yOiM5MTkxOTF9LnNjcm9sbGJhci1pbm5lcj4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXguc2Nyb2xsLXNjcm9sbHlfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfdHJhY2t7bGVmdDotMTJweH0uc2Nyb2xsYmFyLWlubmVyPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteS5zY3JvbGwtc2Nyb2xseF92aXNpYmxlIC5zY3JvbGwtZWxlbWVudF90cmFja3t0b3A6LTEycHh9LnNjcm9sbGJhci1pbm5lcj4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXguc2Nyb2xsLXNjcm9sbHlfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXtsZWZ0Oi0xMnB4fS5zY3JvbGxiYXItaW5uZXI+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15LnNjcm9sbC1zY3JvbGx4X3Zpc2libGUgLnNjcm9sbC1lbGVtZW50X3NpemV7dG9wOi0xMnB4fS5zY3JvbGxiYXItb3V0ZXI+LnNjcm9sbC1lbGVtZW50LC5zY3JvbGxiYXItb3V0ZXI+LnNjcm9sbC1lbGVtZW50IGRpdntib3JkZXI6bm9uZTttYXJnaW46MDtwYWRkaW5nOjA7cG9zaXRpb246YWJzb2x1dGU7ei1pbmRleDoxMH0uc2Nyb2xsYmFyLW91dGVyPi5zY3JvbGwtZWxlbWVudHtiYWNrZ3JvdW5kLWNvbG9yOiNmZmZ9LnNjcm9sbGJhci1vdXRlcj4uc2Nyb2xsLWVsZW1lbnQgZGl2e2Rpc3BsYXk6YmxvY2s7aGVpZ2h0OjEwMCU7bGVmdDowO3RvcDowO3dpZHRoOjEwMCV9LnNjcm9sbGJhci1vdXRlcj4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXh7Ym90dG9tOjA7aGVpZ2h0OjEycHg7bGVmdDowO3dpZHRoOjEwMCV9LnNjcm9sbGJhci1vdXRlcj4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXl7aGVpZ2h0OjEwMCU7cmlnaHQ6MDt0b3A6MDt3aWR0aDoxMnB4fS5zY3JvbGxiYXItb3V0ZXI+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC14IC5zY3JvbGwtZWxlbWVudF9vdXRlcntoZWlnaHQ6OHB4O3RvcDoycHh9LnNjcm9sbGJhci1vdXRlcj4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkgLnNjcm9sbC1lbGVtZW50X291dGVye2xlZnQ6MnB4O3dpZHRoOjhweH0uc2Nyb2xsYmFyLW91dGVyPi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWVsZW1lbnRfb3V0ZXJ7b3ZlcmZsb3c6aGlkZGVufS5zY3JvbGxiYXItb3V0ZXI+LnNjcm9sbC1lbGVtZW50IC5zY3JvbGwtZWxlbWVudF90cmFja3tiYWNrZ3JvdW5kLWNvbG9yOiNlZWV9LnNjcm9sbGJhci1vdXRlcj4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1iYXIsLnNjcm9sbGJhci1vdXRlcj4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1lbGVtZW50X291dGVyLC5zY3JvbGxiYXItb3V0ZXI+LnNjcm9sbC1lbGVtZW50IC5zY3JvbGwtZWxlbWVudF90cmFja3tib3JkZXItcmFkaXVzOjhweH0uc2Nyb2xsYmFyLW91dGVyPi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWJhcntiYWNrZ3JvdW5kLWNvbG9yOiNkOWQ5ZDl9LnNjcm9sbGJhci1vdXRlcj4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1iYXI6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojYzJjMmMyfS5zY3JvbGxiYXItb3V0ZXI+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC1kcmFnZ2FibGUgLnNjcm9sbC1iYXJ7YmFja2dyb3VuZC1jb2xvcjojOTE5MTkxfS5zY3JvbGxiYXItb3V0ZXI+LnNjcm9sbC1jb250ZW50LnNjcm9sbC1zY3JvbGx5X3Zpc2libGV7bGVmdDotMTJweDttYXJnaW4tbGVmdDoxMnB4fS5zY3JvbGxiYXItb3V0ZXI+LnNjcm9sbC1jb250ZW50LnNjcm9sbC1zY3JvbGx4X3Zpc2libGV7dG9wOi0xMnB4O21hcmdpbi10b3A6MTJweH0uc2Nyb2xsYmFyLW91dGVyPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteCAuc2Nyb2xsLWJhcnttaW4td2lkdGg6MTBweH0uc2Nyb2xsYmFyLW91dGVyPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteSAuc2Nyb2xsLWJhcnttaW4taGVpZ2h0OjEwcHh9LnNjcm9sbGJhci1vdXRlcj4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXguc2Nyb2xsLXNjcm9sbHlfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfdHJhY2t7bGVmdDotMTRweH0uc2Nyb2xsYmFyLW91dGVyPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteS5zY3JvbGwtc2Nyb2xseF92aXNpYmxlIC5zY3JvbGwtZWxlbWVudF90cmFja3t0b3A6LTE0cHh9LnNjcm9sbGJhci1vdXRlcj4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXguc2Nyb2xsLXNjcm9sbHlfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXtsZWZ0Oi0xNHB4fS5zY3JvbGxiYXItb3V0ZXI+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15LnNjcm9sbC1zY3JvbGx4X3Zpc2libGUgLnNjcm9sbC1lbGVtZW50X3NpemV7dG9wOi0xNHB4fS5zY3JvbGxiYXItbWFjb3N4Pi5zY3JvbGwtZWxlbWVudCwuc2Nyb2xsYmFyLW1hY29zeD4uc2Nyb2xsLWVsZW1lbnQgZGl2e2JhY2tncm91bmQ6MCAwO2JvcmRlcjpub25lO21hcmdpbjowO3BhZGRpbmc6MDtwb3NpdGlvbjphYnNvbHV0ZTt6LWluZGV4OjEwfS5zY3JvbGxiYXItbWFjb3N4Pi5zY3JvbGwtZWxlbWVudCBkaXZ7ZGlzcGxheTpibG9jaztoZWlnaHQ6MTAwJTtsZWZ0OjA7dG9wOjA7d2lkdGg6MTAwJX0uc2Nyb2xsYmFyLW1hY29zeD4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1lbGVtZW50X3RyYWNre2Rpc3BsYXk6bm9uZX0uc2Nyb2xsYmFyLW1hY29zeD4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1iYXJ7YmFja2dyb3VuZC1jb2xvcjojNkM2RTcxO2Rpc3BsYXk6YmxvY2s7LW1zLWZpbHRlcjpcXFwicHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LkFscGhhKE9wYWNpdHk9MClcXFwiO2ZpbHRlcjphbHBoYShvcGFjaXR5PTApO29wYWNpdHk6MDtib3JkZXItcmFkaXVzOjdweDt0cmFuc2l0aW9uOm9wYWNpdHkgLjJzIGxpbmVhcn0uc2Nyb2xsYmFyLW1hY29zeDpob3Zlcj4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1iYXIsLnNjcm9sbGJhci1tYWNvc3g+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC1kcmFnZ2FibGUgLnNjcm9sbC1iYXJ7LW1zLWZpbHRlcjpcXFwicHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LkFscGhhKE9wYWNpdHk9NzApXFxcIjtmaWx0ZXI6YWxwaGEob3BhY2l0eT03MCk7b3BhY2l0eTouN30uc2Nyb2xsYmFyLW1hY29zeD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXh7Ym90dG9tOjA7aGVpZ2h0OjA7bGVmdDowO21pbi13aWR0aDoxMDAlO292ZXJmbG93OnZpc2libGU7d2lkdGg6MTAwJX0uc2Nyb2xsYmFyLW1hY29zeD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXl7aGVpZ2h0OjEwMCU7bWluLWhlaWdodDoxMDAlO3JpZ2h0OjA7dG9wOjA7d2lkdGg6MH0uc2Nyb2xsYmFyLW1hY29zeD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXggLnNjcm9sbC1iYXJ7aGVpZ2h0OjdweDttaW4td2lkdGg6MTBweDt0b3A6LTlweH0uc2Nyb2xsYmFyLW1hY29zeD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkgLnNjcm9sbC1iYXJ7bGVmdDotOXB4O21pbi1oZWlnaHQ6MTBweDt3aWR0aDo3cHh9LnNjcm9sbGJhci1tYWNvc3g+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC14IC5zY3JvbGwtZWxlbWVudF9vdXRlcntsZWZ0OjJweH0uc2Nyb2xsYmFyLW1hY29zeD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXggLnNjcm9sbC1lbGVtZW50X3NpemV7bGVmdDotNHB4fS5zY3JvbGxiYXItbWFjb3N4Pi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteSAuc2Nyb2xsLWVsZW1lbnRfb3V0ZXJ7dG9wOjJweH0uc2Nyb2xsYmFyLW1hY29zeD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkgLnNjcm9sbC1lbGVtZW50X3NpemV7dG9wOi00cHh9LnNjcm9sbGJhci1tYWNvc3g+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC14LnNjcm9sbC1zY3JvbGx5X3Zpc2libGUgLnNjcm9sbC1lbGVtZW50X3NpemV7bGVmdDotMTFweH0uc2Nyb2xsYmFyLW1hY29zeD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkuc2Nyb2xsLXNjcm9sbHhfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXt0b3A6LTExcHh9LnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQsLnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQgZGl2e2JvcmRlcjpub25lO21hcmdpbjowO292ZXJmbG93OmhpZGRlbjtwYWRkaW5nOjA7cG9zaXRpb246YWJzb2x1dGU7ei1pbmRleDoxMH0uc2Nyb2xsYmFyLWxpZ2h0Pi5zY3JvbGwtZWxlbWVudHtiYWNrZ3JvdW5kLWNvbG9yOiNmZmZ9LnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQgZGl2e2Rpc3BsYXk6YmxvY2s7aGVpZ2h0OjEwMCU7bGVmdDowO3RvcDowO3dpZHRoOjEwMCV9LnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1lbGVtZW50X291dGVye2JvcmRlci1yYWRpdXM6MTBweH0uc2Nyb2xsYmFyLWxpZ2h0Pi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXtiYWNrZ3JvdW5kOnVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQS9QZ284YzNabklIaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2QybGtkR2c5SWpFd01DVWlJR2hsYVdkb2REMGlNVEF3SlNJZ2RtbGxkMEp2ZUQwaU1DQXdJREVnTVNJZ2NISmxjMlZ5ZG1WQmMzQmxZM1JTWVhScGJ6MGlibTl1WlNJK0NpQWdQR3hwYm1WaGNrZHlZV1JwWlc1MElHbGtQU0puY21Ga0xYVmpaMmN0WjJWdVpYSmhkR1ZrSWlCbmNtRmthV1Z1ZEZWdWFYUnpQU0oxYzJWeVUzQmhZMlZQYmxWelpTSWdlREU5SWpBbElpQjVNVDBpTUNVaUlIZ3lQU0l4TURBbElpQjVNajBpTUNVaVBnb2dJQ0FnUEhOMGIzQWdiMlptYzJWMFBTSXdKU0lnYzNSdmNDMWpiMnh2Y2owaUkyUmlaR0prWWlJZ2MzUnZjQzF2Y0dGamFYUjVQU0l4SWk4K0NpQWdJQ0E4YzNSdmNDQnZabVp6WlhROUlqRXdNQ1VpSUhOMGIzQXRZMjlzYjNJOUlpTmxPR1U0WlRnaUlITjBiM0F0YjNCaFkybDBlVDBpTVNJdlBnb2dJRHd2YkdsdVpXRnlSM0poWkdsbGJuUStDaUFnUEhKbFkzUWdlRDBpTUNJZ2VUMGlNQ0lnZDJsa2RHZzlJakVpSUdobGFXZG9kRDBpTVNJZ1ptbHNiRDBpZFhKc0tDTm5jbUZrTFhWaloyY3RaMlZ1WlhKaGRHVmtLU0lnTHo0S1BDOXpkbWMrKTtiYWNrZ3JvdW5kOmxpbmVhci1ncmFkaWVudCh0byByaWdodCwjZGJkYmRiIDAsI2U4ZThlOCAxMDAlKTtib3JkZXItcmFkaXVzOjEwcHh9LnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXh7Ym90dG9tOjA7aGVpZ2h0OjE3cHg7bGVmdDowO21pbi13aWR0aDoxMDAlO3dpZHRoOjEwMCV9LnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXl7aGVpZ2h0OjEwMCU7bWluLWhlaWdodDoxMDAlO3JpZ2h0OjA7dG9wOjA7d2lkdGg6MTdweH0uc2Nyb2xsYmFyLWxpZ2h0Pi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWJhcntiYWNrZ3JvdW5kOnVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQS9QZ284YzNabklIaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2QybGtkR2c5SWpFd01DVWlJR2hsYVdkb2REMGlNVEF3SlNJZ2RtbGxkMEp2ZUQwaU1DQXdJREVnTVNJZ2NISmxjMlZ5ZG1WQmMzQmxZM1JTWVhScGJ6MGlibTl1WlNJK0NpQWdQR3hwYm1WaGNrZHlZV1JwWlc1MElHbGtQU0puY21Ga0xYVmpaMmN0WjJWdVpYSmhkR1ZrSWlCbmNtRmthV1Z1ZEZWdWFYUnpQU0oxYzJWeVUzQmhZMlZQYmxWelpTSWdlREU5SWpBbElpQjVNVDBpTUNVaUlIZ3lQU0l4TURBbElpQjVNajBpTUNVaVBnb2dJQ0FnUEhOMGIzQWdiMlptYzJWMFBTSXdKU0lnYzNSdmNDMWpiMnh2Y2owaUkyWmxabVZtWlNJZ2MzUnZjQzF2Y0dGamFYUjVQU0l4SWk4K0NpQWdJQ0E4YzNSdmNDQnZabVp6WlhROUlqRXdNQ1VpSUhOMGIzQXRZMjlzYjNJOUlpTm1OV1kxWmpVaUlITjBiM0F0YjNCaFkybDBlVDBpTVNJdlBnb2dJRHd2YkdsdVpXRnlSM0poWkdsbGJuUStDaUFnUEhKbFkzUWdlRDBpTUNJZ2VUMGlNQ0lnZDJsa2RHZzlJakVpSUdobGFXZG9kRDBpTVNJZ1ptbHNiRDBpZFhKc0tDTm5jbUZrTFhWaloyY3RaMlZ1WlhKaGRHVmtLU0lnTHo0S1BDOXpkbWMrKTtiYWNrZ3JvdW5kOmxpbmVhci1ncmFkaWVudCh0byByaWdodCwjZmVmZWZlIDAsI2Y1ZjVmNSAxMDAlKTtib3JkZXI6MXB4IHNvbGlkICNkYmRiZGI7Ym9yZGVyLXJhZGl1czoxMHB4fS5zY3JvbGxiYXItbGlnaHQ+LnNjcm9sbC1jb250ZW50LnNjcm9sbC1zY3JvbGx5X3Zpc2libGV7bGVmdDotMTdweDttYXJnaW4tbGVmdDoxN3B4fS5zY3JvbGxiYXItbGlnaHQ+LnNjcm9sbC1jb250ZW50LnNjcm9sbC1zY3JvbGx4X3Zpc2libGV7dG9wOi0xN3B4O21hcmdpbi10b3A6MTdweH0uc2Nyb2xsYmFyLWxpZ2h0Pi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteCAuc2Nyb2xsLWJhcntoZWlnaHQ6MTBweDttaW4td2lkdGg6MTBweDt0b3A6MH0uc2Nyb2xsYmFyLWxpZ2h0Pi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteSAuc2Nyb2xsLWJhcntsZWZ0OjA7bWluLWhlaWdodDoxMHB4O3dpZHRoOjEwcHh9LnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXggLnNjcm9sbC1lbGVtZW50X291dGVye2hlaWdodDoxMnB4O2xlZnQ6MnB4O3RvcDoycHh9LnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXggLnNjcm9sbC1lbGVtZW50X3NpemV7bGVmdDotNHB4fS5zY3JvbGxiYXItbGlnaHQ+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15IC5zY3JvbGwtZWxlbWVudF9vdXRlcntsZWZ0OjJweDt0b3A6MnB4O3dpZHRoOjEycHh9LnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkgLnNjcm9sbC1lbGVtZW50X3NpemV7dG9wOi00cHh9LnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXguc2Nyb2xsLXNjcm9sbHlfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXtsZWZ0Oi0xOXB4fS5zY3JvbGxiYXItbGlnaHQ+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15LnNjcm9sbC1zY3JvbGx4X3Zpc2libGUgLnNjcm9sbC1lbGVtZW50X3NpemV7dG9wOi0xOXB4fS5zY3JvbGxiYXItbGlnaHQ+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC14LnNjcm9sbC1zY3JvbGx5X3Zpc2libGUgLnNjcm9sbC1lbGVtZW50X3RyYWNre2xlZnQ6LTE5cHh9LnNjcm9sbGJhci1saWdodD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkuc2Nyb2xsLXNjcm9sbHhfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfdHJhY2t7dG9wOi0xOXB4fS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWVsZW1lbnQsLnNjcm9sbGJhci1yYWlsPi5zY3JvbGwtZWxlbWVudCBkaXZ7Ym9yZGVyOm5vbmU7bWFyZ2luOjA7b3ZlcmZsb3c6aGlkZGVuO3BhZGRpbmc6MDtwb3NpdGlvbjphYnNvbHV0ZTt6LWluZGV4OjEwfS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWVsZW1lbnR7YmFja2dyb3VuZC1jb2xvcjojZmZmfS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWVsZW1lbnQgZGl2e2Rpc3BsYXk6YmxvY2s7aGVpZ2h0OjEwMCU7bGVmdDowO3RvcDowO3dpZHRoOjEwMCV9LnNjcm9sbGJhci1yYWlsPi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXtiYWNrZ3JvdW5kLWNvbG9yOiM5OTk7YmFja2dyb3VuZC1jb2xvcjpyZ2JhKDAsMCwwLC4zKX0uc2Nyb2xsYmFyLXJhaWw+LnNjcm9sbC1lbGVtZW50IC5zY3JvbGwtZWxlbWVudF9vdXRlcjpob3ZlciAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXtiYWNrZ3JvdW5kLWNvbG9yOiM2NjY7YmFja2dyb3VuZC1jb2xvcjpyZ2JhKDAsMCwwLC41KX0uc2Nyb2xsYmFyLXJhaWw+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC14e2JvdHRvbTowO2hlaWdodDoxMnB4O2xlZnQ6MDttaW4td2lkdGg6MTAwJTtwYWRkaW5nOjNweCAwIDJweDt3aWR0aDoxMDAlfS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXl7aGVpZ2h0OjEwMCU7bWluLWhlaWdodDoxMDAlO3BhZGRpbmc6MCAycHggMCAzcHg7cmlnaHQ6MDt0b3A6MDt3aWR0aDoxMnB4fS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWVsZW1lbnQgLnNjcm9sbC1iYXJ7YmFja2dyb3VuZC1jb2xvcjojZDBiOWEwO2JvcmRlci1yYWRpdXM6MnB4O2JveC1zaGFkb3c6MXB4IDFweCAzcHggcmdiYSgwLDAsMCwuNSl9LnNjcm9sbGJhci1yYWlsPi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWVsZW1lbnRfb3V0ZXI6aG92ZXIgLnNjcm9sbC1iYXJ7Ym94LXNoYWRvdzoxcHggMXB4IDNweCByZ2JhKDAsMCwwLC42KX0uc2Nyb2xsYmFyLXJhaWw+LnNjcm9sbC1jb250ZW50LnNjcm9sbC1zY3JvbGx5X3Zpc2libGV7bGVmdDotMTdweDttYXJnaW4tbGVmdDoxN3B4fS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWNvbnRlbnQuc2Nyb2xsLXNjcm9sbHhfdmlzaWJsZXttYXJnaW4tdG9wOjE3cHg7dG9wOi0xN3B4fS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXggLnNjcm9sbC1iYXJ7aGVpZ2h0OjEwcHg7bWluLXdpZHRoOjEwcHg7dG9wOjFweH0uc2Nyb2xsYmFyLXJhaWw+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15IC5zY3JvbGwtYmFye2xlZnQ6MXB4O21pbi1oZWlnaHQ6MTBweDt3aWR0aDoxMHB4fS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXggLnNjcm9sbC1lbGVtZW50X291dGVye2hlaWdodDoxNXB4O2xlZnQ6NXB4fS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXggLnNjcm9sbC1lbGVtZW50X3NpemV7aGVpZ2h0OjJweDtsZWZ0Oi0xMHB4O3RvcDo1cHh9LnNjcm9sbGJhci1yYWlsPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteSAuc2Nyb2xsLWVsZW1lbnRfb3V0ZXJ7dG9wOjVweDt3aWR0aDoxNXB4fS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkgLnNjcm9sbC1lbGVtZW50X3NpemV7bGVmdDo1cHg7dG9wOi0xMHB4O3dpZHRoOjJweH0uc2Nyb2xsYmFyLXJhaWw+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC14LnNjcm9sbC1zY3JvbGx5X3Zpc2libGUgLnNjcm9sbC1lbGVtZW50X3NpemV7bGVmdDotMjVweH0uc2Nyb2xsYmFyLXJhaWw+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15LnNjcm9sbC1zY3JvbGx4X3Zpc2libGUgLnNjcm9sbC1lbGVtZW50X3NpemV7dG9wOi0yNXB4fS5zY3JvbGxiYXItcmFpbD4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXguc2Nyb2xsLXNjcm9sbHlfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfdHJhY2t7bGVmdDotMjVweH0uc2Nyb2xsYmFyLXJhaWw+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15LnNjcm9sbC1zY3JvbGx4X3Zpc2libGUgLnNjcm9sbC1lbGVtZW50X3RyYWNre3RvcDotMjVweH0uc2Nyb2xsYmFyLWR5bmFtaWM+LnNjcm9sbC1lbGVtZW50LC5zY3JvbGxiYXItZHluYW1pYz4uc2Nyb2xsLWVsZW1lbnQgZGl2e2JhY2tncm91bmQ6MCAwO2JvcmRlcjpub25lO21hcmdpbjowO3BhZGRpbmc6MDtwb3NpdGlvbjphYnNvbHV0ZTt6LWluZGV4OjEwfS5zY3JvbGxiYXItZHluYW1pYz4uc2Nyb2xsLWVsZW1lbnQgZGl2e2Rpc3BsYXk6YmxvY2s7aGVpZ2h0OjEwMCU7bGVmdDowO3RvcDowO3dpZHRoOjEwMCV9LnNjcm9sbGJhci1keW5hbWljPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteHtib3R0b206MnB4O2hlaWdodDo3cHg7bGVmdDowO21pbi13aWR0aDoxMDAlO3dpZHRoOjEwMCV9LnNjcm9sbGJhci1keW5hbWljPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteXtoZWlnaHQ6MTAwJTttaW4taGVpZ2h0OjEwMCU7cmlnaHQ6MnB4O3RvcDowO3dpZHRoOjdweH0uc2Nyb2xsYmFyLWR5bmFtaWM+LnNjcm9sbC1lbGVtZW50IC5zY3JvbGwtZWxlbWVudF9vdXRlcntvcGFjaXR5Oi4zO2JvcmRlci1yYWRpdXM6MTJweH0uc2Nyb2xsYmFyLWR5bmFtaWM+LnNjcm9sbC1lbGVtZW50IC5zY3JvbGwtZWxlbWVudF9zaXple2JhY2tncm91bmQtY29sb3I6I2NjYztvcGFjaXR5OjA7Ym9yZGVyLXJhZGl1czoxMnB4O3RyYW5zaXRpb246b3BhY2l0eSAuMnN9LnNjcm9sbGJhci1keW5hbWljPi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWJhcntiYWNrZ3JvdW5kLWNvbG9yOiM2YzZlNzE7Ym9yZGVyLXJhZGl1czo3cHh9LnNjcm9sbGJhci1keW5hbWljPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteCAuc2Nyb2xsLWJhcntib3R0b206MDtoZWlnaHQ6N3B4O21pbi13aWR0aDoyNHB4O3RvcDphdXRvfS5zY3JvbGxiYXItZHluYW1pYz4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkgLnNjcm9sbC1iYXJ7bGVmdDphdXRvO21pbi1oZWlnaHQ6MjRweDtyaWdodDowO3dpZHRoOjdweH0uc2Nyb2xsYmFyLWR5bmFtaWM+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC14IC5zY3JvbGwtZWxlbWVudF9vdXRlcntib3R0b206MDt0b3A6YXV0bztsZWZ0OjJweDt0cmFuc2l0aW9uOmhlaWdodCAuMnN9LnNjcm9sbGJhci1keW5hbWljPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteSAuc2Nyb2xsLWVsZW1lbnRfb3V0ZXJ7bGVmdDphdXRvO3JpZ2h0OjA7dG9wOjJweDt0cmFuc2l0aW9uOndpZHRoIC4yc30uc2Nyb2xsYmFyLWR5bmFtaWM+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC14IC5zY3JvbGwtZWxlbWVudF9zaXple2xlZnQ6LTRweH0uc2Nyb2xsYmFyLWR5bmFtaWM+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15IC5zY3JvbGwtZWxlbWVudF9zaXple3RvcDotNHB4fS5zY3JvbGxiYXItZHluYW1pYz4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXguc2Nyb2xsLXNjcm9sbHlfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXtsZWZ0Oi0xMXB4fS5zY3JvbGxiYXItZHluYW1pYz4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkuc2Nyb2xsLXNjcm9sbHhfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXt0b3A6LTExcHh9LnNjcm9sbGJhci1keW5hbWljPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwtZHJhZ2dhYmxlIC5zY3JvbGwtZWxlbWVudF9vdXRlciwuc2Nyb2xsYmFyLWR5bmFtaWM+LnNjcm9sbC1lbGVtZW50OmhvdmVyIC5zY3JvbGwtZWxlbWVudF9vdXRlcntvdmVyZmxvdzpoaWRkZW47LW1zLWZpbHRlcjpcXFwicHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LkFscGhhKE9wYWNpdHk9NzApXFxcIjtmaWx0ZXI6YWxwaGEob3BhY2l0eT03MCk7b3BhY2l0eTouN30uc2Nyb2xsYmFyLWR5bmFtaWM+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC1kcmFnZ2FibGUgLnNjcm9sbC1lbGVtZW50X291dGVyIC5zY3JvbGwtZWxlbWVudF9zaXplLC5zY3JvbGxiYXItZHluYW1pYz4uc2Nyb2xsLWVsZW1lbnQ6aG92ZXIgLnNjcm9sbC1lbGVtZW50X291dGVyIC5zY3JvbGwtZWxlbWVudF9zaXple29wYWNpdHk6MX0uc2Nyb2xsYmFyLWR5bmFtaWM+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC1kcmFnZ2FibGUgLnNjcm9sbC1lbGVtZW50X291dGVyIC5zY3JvbGwtYmFyLC5zY3JvbGxiYXItZHluYW1pYz4uc2Nyb2xsLWVsZW1lbnQ6aG92ZXIgLnNjcm9sbC1lbGVtZW50X291dGVyIC5zY3JvbGwtYmFye2hlaWdodDoxMDAlO3dpZHRoOjEwMCU7Ym9yZGVyLXJhZGl1czoxMnB4fS5zY3JvbGxiYXItZHluYW1pYz4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXguc2Nyb2xsLWRyYWdnYWJsZSAuc2Nyb2xsLWVsZW1lbnRfb3V0ZXIsLnNjcm9sbGJhci1keW5hbWljPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteDpob3ZlciAuc2Nyb2xsLWVsZW1lbnRfb3V0ZXJ7aGVpZ2h0OjIwcHg7bWluLWhlaWdodDo3cHh9LnNjcm9sbGJhci1keW5hbWljPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteS5zY3JvbGwtZHJhZ2dhYmxlIC5zY3JvbGwtZWxlbWVudF9vdXRlciwuc2Nyb2xsYmFyLWR5bmFtaWM+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15OmhvdmVyIC5zY3JvbGwtZWxlbWVudF9vdXRlcnttaW4td2lkdGg6N3B4O3dpZHRoOjIwcHh9LnNjcm9sbGJhci1jaHJvbWU+LnNjcm9sbC1lbGVtZW50LC5zY3JvbGxiYXItY2hyb21lPi5zY3JvbGwtZWxlbWVudCBkaXZ7Ym9yZGVyOm5vbmU7bWFyZ2luOjA7b3ZlcmZsb3c6aGlkZGVuO3BhZGRpbmc6MDtwb3NpdGlvbjphYnNvbHV0ZTt6LWluZGV4OjEwfS5zY3JvbGxiYXItY2hyb21lPi5zY3JvbGwtZWxlbWVudHtiYWNrZ3JvdW5kLWNvbG9yOiNmZmZ9LnNjcm9sbGJhci1jaHJvbWU+LnNjcm9sbC1lbGVtZW50IGRpdntkaXNwbGF5OmJsb2NrO2hlaWdodDoxMDAlO2xlZnQ6MDt0b3A6MDt3aWR0aDoxMDAlfS5zY3JvbGxiYXItY2hyb21lPi5zY3JvbGwtZWxlbWVudCAuc2Nyb2xsLWVsZW1lbnRfdHJhY2t7YmFja2dyb3VuZDojZjFmMWYxO2JvcmRlcjoxcHggc29saWQgI2RiZGJkYn0uc2Nyb2xsYmFyLWNocm9tZT4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXh7Ym90dG9tOjA7aGVpZ2h0OjE2cHg7bGVmdDowO21pbi13aWR0aDoxMDAlO3dpZHRoOjEwMCV9LnNjcm9sbGJhci1jaHJvbWU+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15e2hlaWdodDoxMDAlO21pbi1oZWlnaHQ6MTAwJTtyaWdodDowO3RvcDowO3dpZHRoOjE2cHh9LnNjcm9sbGJhci1jaHJvbWU+LnNjcm9sbC1lbGVtZW50IC5zY3JvbGwtYmFye2JhY2tncm91bmQtY29sb3I6I2Q5ZDlkOTtib3JkZXI6MXB4IHNvbGlkICNiZGJkYmQ7Y3Vyc29yOmRlZmF1bHQ7Ym9yZGVyLXJhZGl1czoycHh9LnNjcm9sbGJhci1jaHJvbWU+LnNjcm9sbC1lbGVtZW50IC5zY3JvbGwtYmFyOmhvdmVye2JhY2tncm91bmQtY29sb3I6I2MyYzJjMjtib3JkZXItY29sb3I6I2E5YTlhOX0uc2Nyb2xsYmFyLWNocm9tZT4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLWRyYWdnYWJsZSAuc2Nyb2xsLWJhcntiYWNrZ3JvdW5kLWNvbG9yOiM5MTkxOTE7Ym9yZGVyLWNvbG9yOiM3ZTdlN2V9LnNjcm9sbGJhci1jaHJvbWU+LnNjcm9sbC1jb250ZW50LnNjcm9sbC1zY3JvbGx5X3Zpc2libGV7bGVmdDotMTZweDttYXJnaW4tbGVmdDoxNnB4fS5zY3JvbGxiYXItY2hyb21lPi5zY3JvbGwtY29udGVudC5zY3JvbGwtc2Nyb2xseF92aXNpYmxle3RvcDotMTZweDttYXJnaW4tdG9wOjE2cHh9LnNjcm9sbGJhci1jaHJvbWU+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC14IC5zY3JvbGwtYmFye2hlaWdodDo4cHg7bWluLXdpZHRoOjEwcHg7dG9wOjNweH0uc2Nyb2xsYmFyLWNocm9tZT4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkgLnNjcm9sbC1iYXJ7bGVmdDozcHg7bWluLWhlaWdodDoxMHB4O3dpZHRoOjhweH0uc2Nyb2xsYmFyLWNocm9tZT4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXggLnNjcm9sbC1lbGVtZW50X291dGVye2JvcmRlci1sZWZ0OjFweCBzb2xpZCAjZGJkYmRifS5zY3JvbGxiYXItY2hyb21lPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteCAuc2Nyb2xsLWVsZW1lbnRfdHJhY2t7aGVpZ2h0OjE0cHg7bGVmdDotM3B4fS5zY3JvbGxiYXItY2hyb21lPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteCAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXtoZWlnaHQ6MTRweDtsZWZ0Oi00cHh9LnNjcm9sbGJhci1jaHJvbWU+LnNjcm9sbC1lbGVtZW50LnNjcm9sbC15IC5zY3JvbGwtZWxlbWVudF9vdXRlcntib3JkZXItdG9wOjFweCBzb2xpZCAjZGJkYmRifS5zY3JvbGxiYXItY2hyb21lPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteSAuc2Nyb2xsLWVsZW1lbnRfdHJhY2t7dG9wOi0zcHg7d2lkdGg6MTRweH0uc2Nyb2xsYmFyLWNocm9tZT4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkgLnNjcm9sbC1lbGVtZW50X3NpemV7dG9wOi00cHg7d2lkdGg6MTRweH0uc2Nyb2xsYmFyLWNocm9tZT4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXguc2Nyb2xsLXNjcm9sbHlfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfc2l6ZXtsZWZ0Oi0xOXB4fS5zY3JvbGxiYXItY2hyb21lPi5zY3JvbGwtZWxlbWVudC5zY3JvbGwteS5zY3JvbGwtc2Nyb2xseF92aXNpYmxlIC5zY3JvbGwtZWxlbWVudF9zaXple3RvcDotMTlweH0uc2Nyb2xsYmFyLWNocm9tZT4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXguc2Nyb2xsLXNjcm9sbHlfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfdHJhY2t7bGVmdDotMTlweH0uc2Nyb2xsYmFyLWNocm9tZT4uc2Nyb2xsLWVsZW1lbnQuc2Nyb2xsLXkuc2Nyb2xsLXNjcm9sbHhfdmlzaWJsZSAuc2Nyb2xsLWVsZW1lbnRfdHJhY2t7dG9wOi0xOXB4fVxcblwiICtcblwiLyoqXFxuXCIgK1xuXCIgKiBNaW5pZmllZCBzdHlsZS5cXG5cIiArXG5cIiAqIE9yaWdpbmFsIGZpbGVuYW1lOiBcXFxcc3JjXFxcXHN0eWxlc1xcXFxzdHlsZS5jc3NcXG5cIiArXG5cIiAqL1xcblwiICtcblwiQC13ZWJraXQta2V5ZnJhbWVzIHNwaW57MTAwJXstd2Via2l0LXRyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKTt0cmFuc2Zvcm06cm90YXRlKDM2MGRlZyl9fUBrZXlmcmFtZXMgc3BpbnsxMDAley13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO3RyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKX19I2Vtb3RlLW1lbnUtYnV0dG9ue2JhY2tncm91bmQtaW1hZ2U6dXJsKGRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQklBQUFBUUNBWUFBQUFiQmk5Y0FBQUFBWE5TUjBJQXJzNGM2UUFBQUFSblFVMUJBQUN4and2OFlRVUFBQUFKY0VoWmN3QUFEc01BQUE3REFjZHZxR1FBQUFLVVNVUkJWRGhQZlpUTmkxSlJHTVp2TUlzV1VadHM1U0lYRllLMENNRS9JR2doeFZDN1dVb1UxTkJpeEkrbVJTRDRNUXpteHppS08zWFVCaFJtVUdaS2RCRzQwWEVHVTZkMEdGR1pjVDRxeFcxaGk3Znp2TndacUt3REQ1ejd2cy92dWVlZWUrNlZNSnhPNXdVaGhkdnRmdUh6K1Q0dExTMk5oZWdmR3NNREx4aXdISUloTGk1N1BKNzVWQ3IxWTM5L240YkRJWTFHbzRsQ0R4NTR3WUNWWXpqb1ZqUWEvZHh1dHlmQ2t3U3ZZSnBnT1NRZjcwOHR1QmExeVdSeS9MK1YvQ2w0d1lCRmhoVHhmTGh1bS9lc2lpSjF1MTJLUkNKa3NWaG9mWDJkVGs1T3prSE1VVU1QSG5qQjJGNTVWcEVoUGRlL0xieDhGcUJFSWtIcGRKb01CZ05wdFZyUzZYUlVxVlRPZzdhM3QybG1ab2IwZWoycDFXcjJnZ0dMRE9uSjNRU1pINGNvSG8vVHlzb0toeWdVQ3RKb05GUXNGbWt3R0xBd1I3aFNxU1NWU3NWZU1HQ1JJVDI5RjZmWEppOFh5K1V5bWMxbW1wNmVKb2ZEUWZWNm5VNVBUMW1ZMisxMjd1SHhTcVVTaDRGRmhoUUx2cnZ0Y3JtK1lwa0hCd2RVclZacGEydUxhclVhZFRvZE9qdzhaR0dPR25yd3dBc0dMREx3MWk0dUxyelJZZU9PajQ5cGIyK1BkbmQzcWRWcThTdEdBSVE1YW8xR2d6M3dnZ0dMREQ0QzRpemNFY1dmUjBkSGJNcmxjclN4c2NHYmpWQUlLOGxtczdTNXVjbUIvWDZmWHo5WURzRVFGemRqc1ZpdDJXenlxYzFrTXJ3ZlZxdVZqRVlqemMzTmtjbGtJcHZOUm10cmEreUJWekFmQlh0RGp1R2dTOEZnY0ZiYzhRdnVoak5TS0JRb0ZBcVI2TEZFbi9MNVBQZmdnWGQ1ZVhrV3JCekRRZEMxUUNCZ0ZvZXV0N096dy90eUJwMkZRemhQd3RPRkZ3elkzNFlvNEE5d1JYemREOExoY0U0OHduY0U5bm85RnVhb2lkNTc0YmtQTHhnWi8zdUk1cFRRVmZGbFAvTDcvV21oYjdKU1hxLzNJWHJ3eUhaNVNOSXZHQ25xeWgrSjcrZ0FBQUFBU1VWT1JLNUNZSUk9KSFpbXBvcnRhbnQ7YmFja2dyb3VuZC1wb3NpdGlvbjo1MCU7YmFja2dyb3VuZC1yZXBlYXQ6bm8tcmVwZWF0O2N1cnNvcjpwb2ludGVyO2hlaWdodDozMHB4O3dpZHRoOjMwcHh9I2Vtb3RlLW1lbnUtYnV0dG9uOmZvY3Vze2JveC1zaGFkb3c6bm9uZX0jZW1vdGUtbWVudS1idXR0b24uYWN0aXZle2JveC1zaGFkb3c6MCAwIDZweCAwICM3ZDViYmUsaW5zZXQgMCAwIDAgMXB4IHJnYmEoMTAwLDY1LDE2NCwuNSl9LmVtb3RlLW1lbnV7cGFkZGluZzo1cHg7ei1pbmRleDoxMDAwO2Rpc3BsYXk6bm9uZTtiYWNrZ3JvdW5kLWNvbG9yOiMyMDIwMjA7cG9zaXRpb246YWJzb2x1dGV9LmVtb3RlLW1lbnUgYXtjb2xvcjojZmZmfS5lbW90ZS1tZW51IGE6aG92ZXJ7Y3Vyc29yOnBvaW50ZXI7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZTtjb2xvcjojY2NjfS5lbW90ZS1tZW51IC5lbW90ZXMtc3RhcnJlZHtoZWlnaHQ6MzhweH0uZW1vdGUtbWVudSAuZHJhZ2dhYmxle2JhY2tncm91bmQtaW1hZ2U6cmVwZWF0aW5nLWxpbmVhci1ncmFkaWVudCg0NWRlZyx0cmFuc3BhcmVudCx0cmFuc3BhcmVudCA1cHgscmdiYSgyNTUsMjU1LDI1NSwuMDUpIDVweCxyZ2JhKDI1NSwyNTUsMjU1LC4wNSkgMTBweCk7Y3Vyc29yOm1vdmU7aGVpZ2h0OjdweDttYXJnaW4tYm90dG9tOjNweH0uZW1vdGUtbWVudSAuZHJhZ2dhYmxlOmhvdmVye2JhY2tncm91bmQtaW1hZ2U6cmVwZWF0aW5nLWxpbmVhci1ncmFkaWVudCg0NWRlZyx0cmFuc3BhcmVudCx0cmFuc3BhcmVudCA1cHgscmdiYSgyNTUsMjU1LDI1NSwuMSkgNXB4LHJnYmEoMjU1LDI1NSwyNTUsLjEpIDEwcHgpfS5lbW90ZS1tZW51IC5oZWFkZXItaW5mb3tib3JkZXItdG9wOjFweCBzb2xpZCAjMDAwO2JveC1zaGFkb3c6MCAxcHggMCByZ2JhKDI1NSwyNTUsMjU1LC4wNSkgaW5zZXQ7YmFja2dyb3VuZC1pbWFnZTpsaW5lYXItZ3JhZGllbnQodG8gdG9wLHRyYW5zcGFyZW50LHJnYmEoMCwwLDAsLjUpKTtwYWRkaW5nOjJweDtjb2xvcjojZGRkO3RleHQtYWxpZ246Y2VudGVyO3Bvc2l0aW9uOnJlbGF0aXZlfS5lbW90ZS1tZW51IC5oZWFkZXItaW5mbyBpbWd7bWFyZ2luLXJpZ2h0OjhweH0uZW1vdGUtbWVudSAuZW1vdGV7ZGlzcGxheTppbmxpbmUtYmxvY2s7cGFkZGluZzoycHg7bWFyZ2luOjFweDtjdXJzb3I6cG9pbnRlcjtib3JkZXItcmFkaXVzOjVweDt0ZXh0LWFsaWduOmNlbnRlcjtwb3NpdGlvbjpyZWxhdGl2ZTt3aWR0aDozMHB4O2hlaWdodDozMHB4O3RyYW5zaXRpb246YWxsIC4yNXMgZWFzZTtib3JkZXI6MXB4IHNvbGlkIHRyYW5zcGFyZW50fS5lbW90ZS1tZW51LmVkaXRpbmcgLmVtb3Rle2N1cnNvcjphdXRvfS5lbW90ZS1tZW51IC5lbW90ZSBpbWd7bWF4LXdpZHRoOjEwMCU7bWF4LWhlaWdodDoxMDAlO21hcmdpbjphdXRvO3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2JvdHRvbTowO2xlZnQ6MDtyaWdodDowfS5lbW90ZS1tZW51IC5zaW5nbGUtcm93IC5lbW90ZS1jb250YWluZXJ7b3ZlcmZsb3c6aGlkZGVuO2hlaWdodDozN3B4fS5lbW90ZS1tZW51IC5zaW5nbGUtcm93IC5lbW90ZXtkaXNwbGF5OmlubGluZS1ibG9jazttYXJnaW4tYm90dG9tOjEwMHB4fS5lbW90ZS1tZW51IC5lbW90ZTpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOnJnYmEoMjU1LDI1NSwyNTUsLjEpfS5lbW90ZS1tZW51IC5wdWxsLWxlZnR7ZmxvYXQ6bGVmdH0uZW1vdGUtbWVudSAucHVsbC1yaWdodHtmbG9hdDpyaWdodH0uZW1vdGUtbWVudSAuZm9vdGVye3RleHQtYWxpZ246Y2VudGVyO2JvcmRlci10b3A6MXB4IHNvbGlkICMwMDA7Ym94LXNoYWRvdzowIDFweCAwIHJnYmEoMjU1LDI1NSwyNTUsLjA1KSBpbnNldDtwYWRkaW5nOjVweCAwIDJweDttYXJnaW4tdG9wOjVweDtoZWlnaHQ6MThweH0uZW1vdGUtbWVudSAuZm9vdGVyIC5wdWxsLWxlZnR7bWFyZ2luLXJpZ2h0OjVweH0uZW1vdGUtbWVudSAuZm9vdGVyIC5wdWxsLXJpZ2h0e21hcmdpbi1sZWZ0OjVweH0uZW1vdGUtbWVudSAuaWNvbntoZWlnaHQ6MTZweDt3aWR0aDoxNnB4O29wYWNpdHk6LjU7YmFja2dyb3VuZC1zaXplOmNvbnRhaW4haW1wb3J0YW50fS5lbW90ZS1tZW51IC5pY29uOmhvdmVye29wYWNpdHk6MX0uZW1vdGUtbWVudSAuaWNvbi1ob21le2JhY2tncm91bmQ6dXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEQ5NGJXd2dkbVZ5YzJsdmJqMGlNUzR3SWlCbGJtTnZaR2x1WnowaVZWUkdMVGdpSUhOMFlXNWtZV3h2Ym1VOUltNXZJajgrRFFvOElTMHRJRU55WldGMFpXUWdkMmwwYUNCSmJtdHpZMkZ3WlNBb2FIUjBjRG92TDNkM2R5NXBibXR6WTJGd1pTNXZjbWN2S1NBdExUNE5DZzBLUEhOMlp3MEtJQ0FnZUcxc2JuTTZaR005SW1oMGRIQTZMeTl3ZFhKc0xtOXlaeTlrWXk5bGJHVnRaVzUwY3k4eExqRXZJZzBLSUNBZ2VHMXNibk02WTJNOUltaDBkSEE2THk5amNtVmhkR2wyWldOdmJXMXZibk11YjNKbkwyNXpJeUlOQ2lBZ0lIaHRiRzV6T25Ka1pqMGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNVGs1T1M4d01pOHlNaTF5WkdZdGMzbHVkR0Y0TFc1ekl5SU5DaUFnSUhodGJHNXpPbk4yWnowaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaURRb2dJQ0I0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lEUW9nSUNCMlpYSnphVzl1UFNJeExqRWlEUW9nSUNCM2FXUjBhRDBpTmpRaURRb2dJQ0JvWldsbmFIUTlJalkwSWcwS0lDQWdkbWxsZDBKdmVEMGlNQ0F3SURZMElEWTBJZzBLSUNBZ2FXUTlJa05oY0dGZk1TSU5DaUFnSUhodGJEcHpjR0ZqWlQwaWNISmxjMlZ5ZG1VaVBqeHRaWFJoWkdGMFlRMEtJQ0FnYVdROUltMWxkR0ZrWVhSaE16QXdNU0krUEhKa1pqcFNSRVkrUEdOak9sZHZjbXNOQ2lBZ0lDQWdJQ0J5WkdZNllXSnZkWFE5SWlJK1BHUmpPbVp2Y20xaGRENXBiV0ZuWlM5emRtY3JlRzFzUEM5a1l6cG1iM0p0WVhRK1BHUmpPblI1Y0dVTkNpQWdJQ0FnSUNBZ0lISmtaanB5WlhOdmRYSmpaVDBpYUhSMGNEb3ZMM0IxY213dWIzSm5MMlJqTDJSamJXbDBlWEJsTDFOMGFXeHNTVzFoWjJVaUlDOCtQR1JqT25ScGRHeGxQand2WkdNNmRHbDBiR1UrUEM5all6cFhiM0pyUGp3dmNtUm1PbEpFUmo0OEwyMWxkR0ZrWVhSaFBqeGtaV1p6RFFvZ0lDQnBaRDBpWkdWbWN6STVPVGtpSUM4K0RRbzhjR0YwYUEwS0lDQWdaRDBpYlNBMU55NHdOaklzTXpFdU16azRJR01nTUM0NU16SXNMVEV1TURJMUlEQXVPRFF5TEMweUxqVTVOaUF0TUM0eU1ERXNMVE11TlRBNElFd2dNek11T0RnMExEY3VOemcxSUVNZ016SXVPRFF4TERZdU9EY3pJRE14TGpFMk9TdzJMamc1TWlBek1DNHhORGdzTnk0NE1qZ2dUQ0EzTGpBNU15d3lPQzQ1TmpJZ1l5QXRNUzR3TWpFc01DNDVNellnTFRFdU1EY3hMREl1TlRBMUlDMHdMakV4TVN3ekxqVXdNeUJzSURBdU5UYzRMREF1TmpBeUlHTWdNQzQ1TlRrc01DNDVPVGdnTWk0MU1Ea3NNUzR4TVRjZ015NDBOaXd3TGpJMk5TQnNJREV1TnpJekxDMHhMalUwTXlCMklESXlMalU1SUdNZ01Dd3hMak00TmlBeExqRXlNeXd5TGpVd09DQXlMalV3T0N3eUxqVXdPQ0JvSURndU9UZzNJR01nTVM0ek9EVXNNQ0F5TGpVd09Dd3RNUzR4TWpJZ01pNDFNRGdzTFRJdU5UQTRJRllnTXpndU5UYzFJR2dnTVRFdU5EWXpJSFlnTVRVdU9EQTBJR01nTFRBdU1ESXNNUzR6T0RVZ01DNDVOekVzTWk0MU1EY2dNaTR6TlRZc01pNDFNRGNnYUNBNUxqVXlOQ0JqSURFdU16ZzFMREFnTWk0MU1EZ3NMVEV1TVRJeUlESXVOVEE0TEMweUxqVXdPQ0JXSURNeUxqRXdOeUJqSURBc01DQXdMalEzTml3d0xqUXhOeUF4TGpBMk15d3dMamt6TXlBd0xqVTROaXd3TGpVeE5TQXhMamd4Tnl3d0xqRXdNaUF5TGpjME9Td3RNQzQ1TWpRZ2JDQXdMalkxTXl3dE1DNDNNVGdnZWlJTkNpQWdJR2xrUFNKd1lYUm9Nams1TlNJTkNpQWdJSE4wZVd4bFBTSm1hV3hzT2lObVptWm1abVk3Wm1sc2JDMXZjR0ZqYVhSNU9qRWlJQzgrRFFvOEwzTjJaejQ9KSA1MCUgbm8tcmVwZWF0fS5lbW90ZS1tZW51IC5pY29uLWdlYXJ7YmFja2dyb3VuZDp1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW01dklqOCtEUW84SVMwdElFTnlaV0YwWldRZ2QybDBhQ0JKYm10elkyRndaU0FvYUhSMGNEb3ZMM2QzZHk1cGJtdHpZMkZ3WlM1dmNtY3ZLU0F0TFQ0TkNnMEtQSE4yWncwS0lDQWdlRzFzYm5NNlpHTTlJbWgwZEhBNkx5OXdkWEpzTG05eVp5OWtZeTlsYkdWdFpXNTBjeTh4TGpFdklnMEtJQ0FnZUcxc2JuTTZZMk05SW1oMGRIQTZMeTlqY21WaGRHbDJaV052YlcxdmJuTXViM0puTDI1ekl5SU5DaUFnSUhodGJHNXpPbkprWmowaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1UazVPUzh3TWk4eU1pMXlaR1l0YzNsdWRHRjRMVzV6SXlJTkNpQWdJSGh0Ykc1ek9uTjJaejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpRFFvZ0lDQjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaURRb2dJQ0IyWlhKemFXOXVQU0l4TGpFaURRb2dJQ0IzYVdSMGFEMGlNakV1TlRraURRb2dJQ0JvWldsbmFIUTlJakl4TGpFek5qazVPU0lOQ2lBZ0lIWnBaWGRDYjNnOUlqQWdNQ0F5TVM0MU9TQXlNUzR4TXpjaURRb2dJQ0JwWkQwaVEyRndZVjh4SWcwS0lDQWdlRzFzT25Od1lXTmxQU0p3Y21WelpYSjJaU0krUEcxbGRHRmtZWFJoRFFvZ0lDQnBaRDBpYldWMFlXUmhkR0V6T1NJK1BISmtaanBTUkVZK1BHTmpPbGR2Y21zTkNpQWdJQ0FnSUNCeVpHWTZZV0p2ZFhROUlpSStQR1JqT21admNtMWhkRDVwYldGblpTOXpkbWNyZUcxc1BDOWtZenBtYjNKdFlYUStQR1JqT25SNWNHVU5DaUFnSUNBZ0lDQWdJSEprWmpweVpYTnZkWEpqWlQwaWFIUjBjRG92TDNCMWNtd3ViM0puTDJSakwyUmpiV2wwZVhCbEwxTjBhV3hzU1cxaFoyVWlJQzgrUEdSak9uUnBkR3hsUGp3dlpHTTZkR2wwYkdVK1BDOWpZenBYYjNKclBqd3ZjbVJtT2xKRVJqNDhMMjFsZEdGa1lYUmhQanhrWldaekRRb2dJQ0JwWkQwaVpHVm1jek0zSWlBdlBnMEtQSEJoZEdnTkNpQWdJR1E5SWswZ01UZ3VOakl5TERndU1UUTFJREU0TGpBM055dzJMamcxSUdNZ01Dd3dJREV1TWpZNExDMHlMamcyTVNBeExqRTFOaXd0TWk0NU56RWdUQ0F4Tnk0MU5UUXNNaTR5TkNCRElERTNMalF6T0N3eUxqRXlOeUF4TkM0MU56WXNNeTQwTXpNZ01UUXVOVGMyTERNdU5ETXpJRXdnTVRNdU1qVTJMREl1T1NCRElERXpMakkxTml3eUxqa2dNVEl1TURrc01DQXhNUzQ1TXl3d0lFZ2dPUzQxTmpFZ1F5QTVMak01Tml3d0lEZ3VNekUzTERJdU9UQTJJRGd1TXpFM0xESXVPVEEySUV3Z05pNDVPVGtzTXk0ME5ERWdZeUF3TERBZ0xUSXVPVEl5TEMweExqSTBNaUF0TXk0d016UXNMVEV1TVRNeElFd2dNaTR5T0Rrc015NDVOVEVnUXlBeUxqRTNNeXcwTGpBMk5DQXpMalV3Tnl3MkxqZzJOeUF6TGpVd055dzJMamcyTnlCTUlESXVPVFl5TERndU1UWWdReUF5TGprMk1pdzRMakUySURBc09TNHpNREVnTUN3NUxqUTFOU0IySURJdU16SXlJR01nTUN3d0xqRTJNaUF5TGprMk9Td3hMakl4T1NBeUxqazJPU3d4TGpJeE9TQnNJREF1TlRRMUxERXVNamt4SUdNZ01Dd3dJQzB4TGpJMk9Dd3lMamcxT1NBdE1TNHhOVGNzTWk0NU5qa2diQ0F4TGpZM09Dd3hMalkwTXlCaklEQXVNVEUwTERBdU1URXhJREl1T1RjM0xDMHhMakU1TlNBeUxqazNOeXd0TVM0eE9UVWdiQ0F4TGpNeU1Td3dMalV6TlNCaklEQXNNQ0F4TGpFMk5pd3lMamc1T0NBeExqTXlOeXd5TGpnNU9DQm9JREl1TXpZNUlHTWdNQzR4TmpRc01DQXhMakkwTkN3dE1pNDVNRFlnTVM0eU5EUXNMVEl1T1RBMklHd2dNUzR6TWpJc0xUQXVOVE0xSUdNZ01Dd3dJREl1T1RFMkxERXVNalF5SURNdU1ESTVMREV1TVRNeklHd2dNUzQyTnpnc0xURXVOalF4SUdNZ01DNHhNVGNzTFRBdU1URTFJQzB4TGpJeUxDMHlMamt4TmlBdE1TNHlNaXd0TWk0NU1UWWdiQ0F3TGpVME5Dd3RNUzR5T1RNZ1l5QXdMREFnTWk0NU5qTXNMVEV1TVRReklESXVPVFl6TEMweExqSTVPU0JXSURrdU16WWdReUF5TVM0MU9TdzVMakU1T1NBeE9DNDJNaklzT0M0eE5EVWdNVGd1TmpJeUxEZ3VNVFExSUhvZ2JTQXROQzR6TmpZc01pNDBNak1nWXlBd0xERXVPRFkzSUMweExqVTFNeXd6TGpNNE55QXRNeTQwTmpFc015NHpPRGNnTFRFdU9UQTJMREFnTFRNdU5EWXhMQzB4TGpVeUlDMHpMalEyTVN3dE15NHpPRGNnTUN3dE1TNDROamNnTVM0MU5UVXNMVE11TXpnMUlETXVORFl4TEMwekxqTTROU0F4TGprd09Td3dMakF3TVNBekxqUTJNU3d4TGpVeE9DQXpMalEyTVN3ekxqTTROU0I2SWcwS0lDQWdhV1E5SW5CaGRHZ3pJZzBLSUNBZ2MzUjViR1U5SW1acGJHdzZJMFpHUmtaR1JpSWdMejROQ2p4bkRRb2dJQ0JwWkQwaVp6VWlQZzBLUEM5blBnMEtQR2NOQ2lBZ0lHbGtQU0puTnlJK0RRbzhMMmMrRFFvOFp3MEtJQ0FnYVdROUltYzVJajROQ2p3dlp6NE5DanhuRFFvZ0lDQnBaRDBpWnpFeElqNE5Dand2Wno0TkNqeG5EUW9nSUNCcFpEMGlaekV6SWo0TkNqd3ZaejROQ2p4bkRRb2dJQ0JwWkQwaVp6RTFJajROQ2p3dlp6NE5DanhuRFFvZ0lDQnBaRDBpWnpFM0lqNE5Dand2Wno0TkNqeG5EUW9nSUNCcFpEMGlaekU1SWo0TkNqd3ZaejROQ2p4bkRRb2dJQ0JwWkQwaVp6SXhJajROQ2p3dlp6NE5DanhuRFFvZ0lDQnBaRDBpWnpJeklqNE5Dand2Wno0TkNqeG5EUW9nSUNCcFpEMGlaekkxSWo0TkNqd3ZaejROQ2p4bkRRb2dJQ0JwWkQwaVp6STNJajROQ2p3dlp6NE5DanhuRFFvZ0lDQnBaRDBpWnpJNUlqNE5Dand2Wno0TkNqeG5EUW9nSUNCcFpEMGlaek14SWo0TkNqd3ZaejROQ2p4bkRRb2dJQ0JwWkQwaVp6TXpJajROQ2p3dlp6NE5Dand2YzNablBnMEspIDUwJSBuby1yZXBlYXR9LmVtb3RlLW1lbnUuZWRpdGluZyAuaWNvbi1nZWFyey13ZWJraXQtYW5pbWF0aW9uOnNwaW4gNHMgbGluZWFyIGluZmluaXRlO2FuaW1hdGlvbjpzcGluIDRzIGxpbmVhciBpbmZpbml0ZX0uZW1vdGUtbWVudSAuaWNvbi1yZXNpemUtaGFuZGxle2JhY2tncm91bmQ6dXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEQ5NGJXd2dkbVZ5YzJsdmJqMGlNUzR3SWlCbGJtTnZaR2x1WnowaVZWUkdMVGdpSUhOMFlXNWtZV3h2Ym1VOUltNXZJajgrRFFvOElTMHRJRU55WldGMFpXUWdkMmwwYUNCSmJtdHpZMkZ3WlNBb2FIUjBjRG92TDNkM2R5NXBibXR6WTJGd1pTNXZjbWN2S1NBdExUNE5DZzBLUEhOMlp3MEtJQ0FnZUcxc2JuTTZaR005SW1oMGRIQTZMeTl3ZFhKc0xtOXlaeTlrWXk5bGJHVnRaVzUwY3k4eExqRXZJZzBLSUNBZ2VHMXNibk02WTJNOUltaDBkSEE2THk5amNtVmhkR2wyWldOdmJXMXZibk11YjNKbkwyNXpJeUlOQ2lBZ0lIaHRiRzV6T25Ka1pqMGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNVGs1T1M4d01pOHlNaTF5WkdZdGMzbHVkR0Y0TFc1ekl5SU5DaUFnSUhodGJHNXpPbk4yWnowaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaURRb2dJQ0I0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lEUW9nSUNCMlpYSnphVzl1UFNJeExqRWlEUW9nSUNCM2FXUjBhRDBpTVRZaURRb2dJQ0JvWldsbmFIUTlJakUySWcwS0lDQWdkbWxsZDBKdmVEMGlNQ0F3SURFMklERTJJZzBLSUNBZ2FXUTlJa05oY0dGZk1TSU5DaUFnSUhodGJEcHpjR0ZqWlQwaWNISmxjMlZ5ZG1VaVBqeHRaWFJoWkdGMFlRMEtJQ0FnYVdROUltMWxkR0ZrWVhSaE5ETTFOeUkrUEhKa1pqcFNSRVkrUEdOak9sZHZjbXNOQ2lBZ0lDQWdJQ0J5WkdZNllXSnZkWFE5SWlJK1BHUmpPbVp2Y20xaGRENXBiV0ZuWlM5emRtY3JlRzFzUEM5a1l6cG1iM0p0WVhRK1BHUmpPblI1Y0dVTkNpQWdJQ0FnSUNBZ0lISmtaanB5WlhOdmRYSmpaVDBpYUhSMGNEb3ZMM0IxY213dWIzSm5MMlJqTDJSamJXbDBlWEJsTDFOMGFXeHNTVzFoWjJVaUlDOCtQR1JqT25ScGRHeGxQand2WkdNNmRHbDBiR1UrUEM5all6cFhiM0pyUGp3dmNtUm1PbEpFUmo0OEwyMWxkR0ZrWVhSaFBqeGtaV1p6RFFvZ0lDQnBaRDBpWkdWbWN6UXpOVFVpSUM4K0RRbzhjR0YwYUEwS0lDQWdaRDBpVFNBeE15NDFMRGdnUXlBeE15NHlNalVzT0NBeE15dzRMakl5TkNBeE15dzRMalVnZGlBekxqYzVNeUJNSURNdU56QTNMRE1nU0NBM0xqVWdReUEzTGpjM05pd3pJRGdzTWk0M056WWdPQ3d5TGpVZ09Dd3lMakl5TkNBM0xqYzNOaXd5SURjdU5Td3lJR2dnTFRVZ1RDQXlMak13T1N3eUxqQXpPU0F5TGpFMUxESXVNVFEwSURJdU1UUTJMREl1TVRRMklESXVNVFF6TERJdU1UVXlJREl1TURNNUxESXVNekE1SURJc01pNDFJSFlnTlNCRElESXNOeTQzTnpZZ01pNHlNalFzT0NBeUxqVXNPQ0F5TGpjM05pdzRJRE1zTnk0M056WWdNeXczTGpVZ1ZpQXpMamN3TnlCTUlERXlMakk1TXl3eE15QklJRGd1TlNCRElEZ3VNakkwTERFeklEZ3NNVE11TWpJMUlEZ3NNVE11TlNBNExERXpMamMzTlNBNExqSXlOQ3d4TkNBNExqVXNNVFFnYUNBMUlHd2dNQzR4T1RFc0xUQXVNRE01SUdNZ01DNHhNakVzTFRBdU1EVXhJREF1TWpJc0xUQXVNVFE0SURBdU1qY3NMVEF1TWpjZ1RDQXhOQ3d4TXk0MU1ESWdWaUE0TGpVZ1F5QXhOQ3c0TGpJeU5DQXhNeTQzTnpVc09DQXhNeTQxTERnZ2VpSU5DaUFnSUdsa1BTSndZWFJvTkRNMU1TSU5DaUFnSUhOMGVXeGxQU0ptYVd4c09pTm1abVptWm1ZN1ptbHNiQzF2Y0dGamFYUjVPakVpSUM4K0RRbzhMM04yWno0PSkgNTAlIG5vLXJlcGVhdDtjdXJzb3I6bndzZS1yZXNpemUhaW1wb3J0YW50fS5lbW90ZS1tZW51IC5pY29uLXBpbntiYWNrZ3JvdW5kOnVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbTV2SWo4K0RRbzhJUzB0SUVOeVpXRjBaV1FnZDJsMGFDQkpibXR6WTJGd1pTQW9hSFIwY0RvdkwzZDNkeTVwYm10elkyRndaUzV2Y21jdktTQXRMVDROQ2cwS1BITjJadzBLSUNBZ2VHMXNibk02WkdNOUltaDBkSEE2THk5d2RYSnNMbTl5Wnk5a1l5OWxiR1Z0Wlc1MGN5OHhMakV2SWcwS0lDQWdlRzFzYm5NNlkyTTlJbWgwZEhBNkx5OWpjbVZoZEdsMlpXTnZiVzF2Ym5NdWIzSm5MMjV6SXlJTkNpQWdJSGh0Ykc1ek9uSmtaajBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TVRrNU9TOHdNaTh5TWkxeVpHWXRjM2x1ZEdGNExXNXpJeUlOQ2lBZ0lIaHRiRzV6T25OMlp6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lEUW9nSUNCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpRFFvZ0lDQjJaWEp6YVc5dVBTSXhMakVpRFFvZ0lDQjNhV1IwYUQwaU1UWWlEUW9nSUNCb1pXbG5hSFE5SWpFMklnMEtJQ0FnYVdROUluTjJaek13TURVaVBnMEtJQ0E4YldWMFlXUmhkR0VOQ2lBZ0lDQWdhV1E5SW0xbGRHRmtZWFJoTXpBeU15SStEUW9nSUNBZ1BISmtaanBTUkVZK0RRb2dJQ0FnSUNBOFkyTTZWMjl5YXcwS0lDQWdJQ0FnSUNBZ2NtUm1PbUZpYjNWMFBTSWlQZzBLSUNBZ0lDQWdJQ0E4WkdNNlptOXliV0YwUG1sdFlXZGxMM04yWnl0NGJXdzhMMlJqT21admNtMWhkRDROQ2lBZ0lDQWdJQ0FnUEdSak9uUjVjR1VOQ2lBZ0lDQWdJQ0FnSUNBZ2NtUm1PbkpsYzI5MWNtTmxQU0pvZEhSd09pOHZjSFZ5YkM1dmNtY3ZaR012WkdOdGFYUjVjR1V2VTNScGJHeEpiV0ZuWlNJZ0x6NE5DaUFnSUNBZ0lDQWdQR1JqT25ScGRHeGxQand2WkdNNmRHbDBiR1UrRFFvZ0lDQWdJQ0E4TDJOak9sZHZjbXMrRFFvZ0lDQWdQQzl5WkdZNlVrUkdQZzBLSUNBOEwyMWxkR0ZrWVhSaFBnMEtJQ0E4WkdWbWN3MEtJQ0FnSUNCcFpEMGlaR1ZtY3pNd01qRWlJQzgrRFFvZ0lEeG5EUW9nSUNBZ0lIUnlZVzV6Wm05eWJUMGliV0YwY21sNEtEQXVOemt6TURjNE1pd3dMREFzTUM0M09UTXdOemd5TEMweUxqRTNNRGs0TlN3dE9ERTBMalk1TWprNUtTSU5DaUFnSUNBZ2FXUTlJbWN6TURBM0lqNE5DaUFnSUNBOFp3MEtJQ0FnSUNBZ0lIUnlZVzV6Wm05eWJUMGliV0YwY21sNEtEQXVOekEzTVRFc01DNDNNRGN4TVN3dE1DNDNNRGN4TVN3d0xqY3dOekV4TERjek55NDNNRGMxTlN3eU9UVXVORGc0TURncElnMEtJQ0FnSUNBZ0lHbGtQU0puTXpBd09TSStEUW9nSUNBZ0lDQThadzBLSUNBZ0lDQWdJQ0FnYVdROUltY3pOelUxSWo0TkNpQWdJQ0FnSUNBZ1BIQmhkR2dOQ2lBZ0lDQWdJQ0FnSUNBZ1pEMGlUU0E1TGpjNE1USTFMREFnUXlBNUxqUTNOREExTmpJc01DNDJPRGt4TVRJZ09TNDFNakEyT0N3eExqVXlNekE0TlRNZ09TNHpNVEkxTERJdU1UZzNOU0JNSURRdU9UTTNOU3cyTGpVNU16YzFJRU1nTXk0NU5UZzVOakE0TERZdU5ESTVORGd6SURJdU9UUTNOelUwT0N3MkxqVXpNamM0T1RrZ01pdzJMamd4TWpVZ1RDQTFMakF6TVRJMUxEa3VPRFF6TnpVZ01DNDFOakkxTERFMExqTXhNalVnTUN3eE5pQkRJREF1TlRZNU1qazJNamdzTVRVdU56azFOakkySURFdU1UWTNOek0zT0N3eE5TNDJOREF5TXpjZ01TNDNNVGczTlN3eE5TNDBNRFl5TlNCTUlEWXVNVFUyTWpVc01UQXVPVFk0TnpVZ09TNHhPRGMxTERFMElHTWdNQzR5TnprMk9ESXpMQzB3TGprME56YzRNeUF3TGpNNE16RTFNamdzTFRFdU9UVTRPVE0zSURBdU1qRTROelVzTFRJdU9UTTNOU0F4TGpVd01EQXhNU3d0TVM0ME9EazFOems0SURNdU1EQXdNREF4TEMweUxqazNPVEUxT1NBMExqVXNMVFF1TkRZNE56VWdNQzQyTURFeE1ESXNMVEF1TURNeE16WXhJREV1T0RJeU1UTTRMQzB3TGpBNU5qRXpOeUF5TEMwd0xqUTJPRGMxSUVNZ01UTXVPRGM1T0RreUxEUXVNRFk1TkRnd015QXhNUzQ0TkRJNE5qVXNNaTR3TWpBeU1qZ3lJRGt1TnpneE1qVXNNQ0I2SWcwS0lDQWdJQ0FnSUNBZ0lDQjBjbUZ1YzJadmNtMDlJbTFoZEhKcGVDZ3dMamc1TVRVNU16YzBMQzB3TGpnNU1UVTVNemMwTERBdU9Ea3hOVGt6TnpRc01DNDRPVEUxT1RNM05Dd3RNaTR5TmpVMUxERXdNemN1TVRNME5Ta2lEUW9nSUNBZ0lDQWdJQ0FnSUdsa1BTSndZWFJvTXpBeE1TSU5DaUFnSUNBZ0lDQWdJQ0FnYzNSNWJHVTlJbVpwYkd3NkkyWm1abVptWmp0bWFXeHNMVzl3WVdOcGRIazZNU0lnTHo0TkNpQWdJQ0FnSUR3dlp6NE5DaUFnSUNBOEwyYytEUW9nSUR3dlp6NE5Dand2YzNablBnMEspIDUwJSBuby1yZXBlYXQ7dHJhbnNpdGlvbjphbGwgLjI1cyBlYXNlfS5lbW90ZS1tZW51IC5pY29uLXBpbjpob3ZlciwuZW1vdGUtbWVudS5waW5uZWQgLmljb24tcGluey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgtNDVkZWcpO3RyYW5zZm9ybTpyb3RhdGUoLTQ1ZGVnKTtvcGFjaXR5OjF9LmVtb3RlLW1lbnUgLmVkaXQtdG9vbHtiYWNrZ3JvdW5kLXBvc2l0aW9uOjUwJTtiYWNrZ3JvdW5kLXJlcGVhdDpuby1yZXBlYXQ7YmFja2dyb3VuZC1zaXplOjE0cHg7Ym9yZGVyLXJhZGl1czo0cHg7Ym9yZGVyOjFweCBzb2xpZCAjMDAwO2N1cnNvcjpwb2ludGVyO2Rpc3BsYXk6bm9uZTtoZWlnaHQ6MTRweDtvcGFjaXR5Oi4yNTtwb3NpdGlvbjphYnNvbHV0ZTt0cmFuc2l0aW9uOmFsbCAuMjVzIGVhc2U7d2lkdGg6MTRweDt6LWluZGV4OjF9LmVtb3RlLW1lbnUgLmVkaXQtdG9vbDpob3ZlciwuZW1vdGUtbWVudSAuZW1vdGU6aG92ZXIgLmVkaXQtdG9vbHtvcGFjaXR5OjF9LmVtb3RlLW1lbnUgLmVkaXQtdmlzaWJpbGl0eXtiYWNrZ3JvdW5kLWNvbG9yOiMwMGM4MDA7YmFja2dyb3VuZC1pbWFnZTp1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW01dklqOCtEUW84SVMwdElFTnlaV0YwWldRZ2QybDBhQ0JKYm10elkyRndaU0FvYUhSMGNEb3ZMM2QzZHk1cGJtdHpZMkZ3WlM1dmNtY3ZLU0F0TFQ0TkNnMEtQSE4yWncwS0lDQWdlRzFzYm5NNlpHTTlJbWgwZEhBNkx5OXdkWEpzTG05eVp5OWtZeTlsYkdWdFpXNTBjeTh4TGpFdklnMEtJQ0FnZUcxc2JuTTZZMk05SW1oMGRIQTZMeTlqY21WaGRHbDJaV052YlcxdmJuTXViM0puTDI1ekl5SU5DaUFnSUhodGJHNXpPbkprWmowaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1UazVPUzh3TWk4eU1pMXlaR1l0YzNsdWRHRjRMVzV6SXlJTkNpQWdJSGh0Ykc1ek9uTjJaejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpRFFvZ0lDQjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaURRb2dJQ0IyWlhKemFXOXVQU0l4TGpFaURRb2dJQ0IzYVdSMGFEMGlNVEF3SWcwS0lDQWdhR1ZwWjJoMFBTSXhNREFpRFFvZ0lDQjJhV1YzUW05NFBTSXdJREFnTVRBd0lERXdNQ0lOQ2lBZ0lHbGtQU0pNWVhsbGNsOHhJZzBLSUNBZ2VHMXNPbk53WVdObFBTSndjbVZ6WlhKMlpTSStQRzFsZEdGa1lYUmhEUW9nSUNCcFpEMGliV1YwWVdSaGRHRTVJajQ4Y21SbU9sSkVSajQ4WTJNNlYyOXlhdzBLSUNBZ0lDQWdJSEprWmpwaFltOTFkRDBpSWo0OFpHTTZabTl5YldGMFBtbHRZV2RsTDNOMlp5dDRiV3c4TDJSak9tWnZjbTFoZEQ0OFpHTTZkSGx3WlEwS0lDQWdJQ0FnSUNBZ2NtUm1PbkpsYzI5MWNtTmxQU0pvZEhSd09pOHZjSFZ5YkM1dmNtY3ZaR012WkdOdGFYUjVjR1V2VTNScGJHeEpiV0ZuWlNJZ0x6NDhaR002ZEdsMGJHVStQQzlrWXpwMGFYUnNaVDQ4TDJOak9sZHZjbXMrUEM5eVpHWTZVa1JHUGp3dmJXVjBZV1JoZEdFK1BHUmxabk1OQ2lBZ0lHbGtQU0prWldaek55SWdMejROQ2p4d1lYUm9EUW9nSUNCa1BTSk5JRGszTGprMk5DdzBOaTQxTkRnZ1F5QTVOeTR3T1Rnc05EVXVOVEk0SURjMkxqUXlOeXd5TVM0Mk1ETWdOVEFzTWpFdU5qQXpJR01nTFRJMkxqUXlOeXd3SUMwME55NHdPVGdzTWpNdU9USTFJQzAwTnk0NU5qVXNNalF1T1RRMklDMHhMamN3TVN3eUlDMHhMamN3TVN3MExqa3dNaUF4TUdVdE5DdzJMamt3TXlBd0xqZzJOaXd4TGpBeUlESXhMalV6Tnl3eU5DNDVORFVnTkRjdU9UWTBMREkwTGprME5TQXlOaTQwTWpjc01DQTBOeTR3T1Rnc0xUSXpMamt5TmlBME55NDVOalVzTFRJMExqazBOaUF4TGpjd01Td3RNaUF4TGpjd01Td3ROQzQ1TURJZ0xUQXVNREF4TEMwMkxqa3dNeUI2SUUwZ05UZ3VNRGN6TERNMUxqazNOU0JqSURFdU56YzNMQzB3TGprM0lEUXVNalUxTERBdU1UUXpJRFV1TlRNMExESXVORGcxSURFdU1qYzVMREl1TXpReklEQXVPRGMxTERVdU1ESTVJQzB3TGprd01pdzFMams1T1NBdE1TNDNOemNzTUM0NU56RWdMVFF1TWpVMUxDMHdMakUwTXlBdE5TNDFNelVzTFRJdU5EZzFJQzB4TGpJM09Td3RNaTR6TkRNZ0xUQXVPRGMxTEMwMUxqQXlPU0F3TGprd015d3ROUzQ1T1RrZ2VpQk5JRFV3TERZNUxqY3lPU0JESURNeExqVTBMRFk1TGpjeU9TQXhOaTR3TURVc05UVXVOVFV6SURFd0xqWXlPQ3cxTUNBeE5DNHlOVGtzTkRZdU1qUTVJREl5TGpVeU5pd3pPQzQxTnpFZ016TXVNVGsxTERNekxqazNPU0F6TVM0eE1UUXNNemN1TVRRMUlESTVMamc1TkN3ME1DNDVNamdnTWprdU9EazBMRFExSUdNZ01Dd3hNUzR4TURRZ09TNHdNREVzTWpBdU1UQTFJREl3TGpFd05Td3lNQzR4TURVZ01URXVNVEEwTERBZ01qQXVNVEEyTEMwNUxqQXdNU0F5TUM0eE1EWXNMVEl3TGpFd05TQXdMQzAwTGpBM01pQXRNUzR5TVRrc0xUY3VPRFUxSUMwekxqTXNMVEV4TGpBeU1TQkRJRGMzTGpRM05Dd3pPQzQxTnpJZ09EVXVOelF4TERRMkxqSTFJRGc1TGpNM01pdzFNQ0E0TXk0NU9UVXNOVFV1TlRVMUlEWTRMalEyTERZNUxqY3lPU0ExTUN3Mk9TNDNNamtnZWlJTkNpQWdJR2xrUFNKd1lYUm9NeUlnTHo0TkNqd3ZjM1puUGc9PSl9LmVtb3RlLW1lbnUgLmVkaXQtc3RhcnJlZHtiYWNrZ3JvdW5kLWNvbG9yOiMzMjMyMzI7YmFja2dyb3VuZC1pbWFnZTp1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW01dklqOCtEUW84SVMwdElFTnlaV0YwWldRZ2QybDBhQ0JKYm10elkyRndaU0FvYUhSMGNEb3ZMM2QzZHk1cGJtdHpZMkZ3WlM1dmNtY3ZLU0F0TFQ0TkNnMEtQSE4yWncwS0lDQWdlRzFzYm5NNlpHTTlJbWgwZEhBNkx5OXdkWEpzTG05eVp5OWtZeTlsYkdWdFpXNTBjeTh4TGpFdklnMEtJQ0FnZUcxc2JuTTZZMk05SW1oMGRIQTZMeTlqY21WaGRHbDJaV052YlcxdmJuTXViM0puTDI1ekl5SU5DaUFnSUhodGJHNXpPbkprWmowaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1UazVPUzh3TWk4eU1pMXlaR1l0YzNsdWRHRjRMVzV6SXlJTkNpQWdJSGh0Ykc1ek9uTjJaejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpRFFvZ0lDQjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaURRb2dJQ0IyWlhKemFXOXVQU0l4TGpFaURRb2dJQ0IzYVdSMGFEMGlOVEFpRFFvZ0lDQm9aV2xuYUhROUlqVXdJZzBLSUNBZ2RtbGxkMEp2ZUQwaU1DQXdJRFV3SURVd0lnMEtJQ0FnYVdROUlreGhlV1Z5WHpFaURRb2dJQ0I0Yld3NmMzQmhZMlU5SW5CeVpYTmxjblpsSWo0OGJXVjBZV1JoZEdFTkNpQWdJR2xrUFNKdFpYUmhaR0YwWVRNd01ERWlQanh5WkdZNlVrUkdQanhqWXpwWGIzSnJEUW9nSUNBZ0lDQWdjbVJtT21GaWIzVjBQU0lpUGp4a1l6cG1iM0p0WVhRK2FXMWhaMlV2YzNabkszaHRiRHd2WkdNNlptOXliV0YwUGp4a1l6cDBlWEJsRFFvZ0lDQWdJQ0FnSUNCeVpHWTZjbVZ6YjNWeVkyVTlJbWgwZEhBNkx5OXdkWEpzTG05eVp5OWtZeTlrWTIxcGRIbHdaUzlUZEdsc2JFbHRZV2RsSWlBdlBqeGtZenAwYVhSc1pUNDhMMlJqT25ScGRHeGxQand2WTJNNlYyOXlhejQ4TDNKa1pqcFNSRVkrUEM5dFpYUmhaR0YwWVQ0OFpHVm1jdzBLSUNBZ2FXUTlJbVJsWm5NeU9UazVJaUF2UGcwS1BIQmhkR2dOQ2lBZ0lHUTlJbTBnTkRNdU1EUXNNakl1TmprMklDMDNMalUyT0N3M0xqTTNOeUF4TGpjNE55d3hNQzQwTVRjZ1l5QXdMakV5Tnl3d0xqYzFJQzB3TGpFNE1pd3hMalV3T1NBdE1DNDNPVGNzTVM0NU5UY2dMVEF1TXpRNExEQXVNalV6SUMwd0xqYzJNaXd3TGpNNE1pQXRNUzR4TnpZc01DNHpPRElnTFRBdU16RTRMREFnTFRBdU5qTTRMQzB3TGpBM05pQXRNQzQ1TXpFc0xUQXVNak1nVENBeU5Td3pOeTQyT0RFZ01UVXVOalExTERReUxqVTVPU0JqSUMwd0xqWTNOQ3d3TGpNMU5TQXRNUzQwT1N3d0xqSTVOU0F0TWk0eE1EY3NMVEF1TVRVeElFTWdNVEl1T1RJekxEUXlJREV5TGpZeE5DdzBNUzR5TkRJZ01USXVOelF6TERRd0xqUTVNU0JNSURFMExqVXpMRE13TGpBM05DQTJMamsyTWl3eU1pNDJPVGNnUXlBMkxqUXhOU3d5TWk0eE5qWWdOaTR5TWpFc01qRXVNemN4SURZdU5EVTBMREl3TGpZME55QTJMalk1TERFNUxqa3lNeUEzTGpNeE5Td3hPUzR6T1RZZ09DNHdOamtzTVRrdU1qZzJJR3dnTVRBdU5EVTVMQzB4TGpVeU1TQTBMalk0TEMwNUxqUTNPQ0JESURJekxqVTBNeXczTGpZd015QXlOQzR5TXprc055NHhOekVnTWpVc055NHhOekVnWXlBd0xqYzJNeXd3SURFdU5EVTJMREF1TkRNeUlERXVOemt6TERFdU1URTFJR3dnTkM0Mk56a3NPUzQwTnpnZ01UQXVORFl4TERFdU5USXhJR01nTUM0M05USXNNQzR4TURrZ01TNHpOemtzTUM0Mk16Y2dNUzQyTVRJc01TNHpOakVnTUM0eU16Y3NNQzQzTWpRZ01DNHdNemdzTVM0MU1Ua2dMVEF1TlRBMUxESXVNRFVnZWlJTkNpQWdJR2xrUFNKd1lYUm9Nams1TlNJTkNpQWdJSE4wZVd4bFBTSm1hV3hzT2lOalkyTmpZMk03Wm1sc2JDMXZjR0ZqYVhSNU9qRWlJQzgrRFFvOEwzTjJaejROQ2c9PSl9LmVtb3RlLW1lbnUgLmVtb3RlPi5lZGl0LXZpc2liaWxpdHl7Ym90dG9tOmF1dG87bGVmdDphdXRvO3JpZ2h0OjA7dG9wOjB9LmVtb3RlLW1lbnUgLmVtb3RlPi5lZGl0LXN0YXJyZWR7Ym90dG9tOmF1dG87bGVmdDowO3JpZ2h0OmF1dG87dG9wOjB9LmVtb3RlLW1lbnUgLmhlYWRlci1pbmZvPi5lZGl0LXRvb2x7bWFyZ2luLWxlZnQ6NXB4fS5lbW90ZS1tZW51LmVkaXRpbmcgLmVkaXQtdG9vbHtkaXNwbGF5OmlubGluZS1ibG9ja30uZW1vdGUtbWVudSAuZW1vdGUtbWVudS1oaWRkZW4gLmVkaXQtdmlzaWJpbGl0eXtiYWNrZ3JvdW5kLWltYWdlOnVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbTV2SWo4K0RRbzhJUzB0SUVOeVpXRjBaV1FnZDJsMGFDQkpibXR6WTJGd1pTQW9hSFIwY0RvdkwzZDNkeTVwYm10elkyRndaUzV2Y21jdktTQXRMVDROQ2cwS1BITjJadzBLSUNBZ2VHMXNibk02WkdNOUltaDBkSEE2THk5d2RYSnNMbTl5Wnk5a1l5OWxiR1Z0Wlc1MGN5OHhMakV2SWcwS0lDQWdlRzFzYm5NNlkyTTlJbWgwZEhBNkx5OWpjbVZoZEdsMlpXTnZiVzF2Ym5NdWIzSm5MMjV6SXlJTkNpQWdJSGh0Ykc1ek9uSmtaajBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TVRrNU9TOHdNaTh5TWkxeVpHWXRjM2x1ZEdGNExXNXpJeUlOQ2lBZ0lIaHRiRzV6T25OMlp6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lEUW9nSUNCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpRFFvZ0lDQjJaWEp6YVc5dVBTSXhMakVpRFFvZ0lDQjNhV1IwYUQwaU1UQXdJZzBLSUNBZ2FHVnBaMmgwUFNJeE1EQWlEUW9nSUNCMmFXVjNRbTk0UFNJd0lEQWdNVEF3SURFd01DSU5DaUFnSUdsa1BTSk1ZWGxsY2w4eklnMEtJQ0FnZUcxc09uTndZV05sUFNKd2NtVnpaWEoyWlNJK1BHMWxkR0ZrWVhSaERRb2dJQ0JwWkQwaWJXVjBZV1JoZEdFeE5TSStQSEprWmpwU1JFWStQR05qT2xkdmNtc05DaUFnSUNBZ0lDQnlaR1k2WVdKdmRYUTlJaUkrUEdSak9tWnZjbTFoZEQ1cGJXRm5aUzl6ZG1jcmVHMXNQQzlrWXpwbWIzSnRZWFErUEdSak9uUjVjR1VOQ2lBZ0lDQWdJQ0FnSUhKa1pqcHlaWE52ZFhKalpUMGlhSFIwY0RvdkwzQjFjbXd1YjNKbkwyUmpMMlJqYldsMGVYQmxMMU4wYVd4c1NXMWhaMlVpSUM4K1BHUmpPblJwZEd4bFBqd3ZaR002ZEdsMGJHVStQQzlqWXpwWGIzSnJQand2Y21SbU9sSkVSajQ4TDIxbGRHRmtZWFJoUGp4a1pXWnpEUW9nSUNCcFpEMGlaR1ZtY3pFeklpQXZQZzBLUEdjTkNpQWdJR2xrUFNKbk15SStEUW9KUEhCaGRHZ05DaUFnSUdROUlrMGdOekF1TURneUxEUTFMalEzTlNBMU1DNDBOelFzTmpVdU1EZ3lJRU1nTmpFdU1UazRMRFkwTGpnek1TQTJPUzQ0TXpFc05UWXVNVGszSURjd0xqQTRNaXcwTlM0ME56VWdlaUlOQ2lBZ0lHbGtQU0p3WVhSb05TSU5DaUFnSUhOMGVXeGxQU0ptYVd4c09pTkdSa1pHUmtZaUlDOCtEUW9KUEhCaGRHZ05DaUFnSUdROUltMGdPVGN1T1RZMExEUTJMalUwT0NCaklDMHdMalExTEMwd0xqVXlPU0F0Tmk0eU5EVXNMVGN1TWpNZ0xURTFMalF3TXl3dE1UTXVOVFUwSUd3Z0xUWXVNaXcyTGpJZ1F5QTRNaTR6TlRFc05ETXVNVFE0SURnMkxqa3lMRFEzTGpRMk9TQTRPUzR6TnpJc05UQWdPRE11T1RrMUxEVTFMalUxTlNBMk9DNDBOaXcyT1M0M01qa2dOVEFzTmprdU56STVJR01nTFRFdU16TTBMREFnTFRJdU5qVXhMQzB3TGpBNE1pQXRNeTQ1TlRJc0xUQXVNakl5SUd3Z0xUY3VORE01TERjdU5ETTVJR01nTXk0Mk16a3NNQzQ1TURrZ055NDBORGtzTVM0ME5TQXhNUzR6T1RFc01TNDBOU0F5Tmk0ME1qY3NNQ0EwTnk0d09UZ3NMVEl6TGpreU5pQTBOeTQ1TmpVc0xUSTBMamswTmlBeExqY3dNU3d0TVM0NU9Ua2dNUzQzTURFc0xUUXVPVEF4SUMwd0xqQXdNU3d0Tmk0NU1ESWdlaUlOQ2lBZ0lHbGtQU0p3WVhSb055SU5DaUFnSUhOMGVXeGxQU0ptYVd4c09pTkdSa1pHUmtZaUlDOCtEUW9KUEhCaGRHZ05DaUFnSUdROUltMGdPVEV1TkRFeExERTJMalkySUdNZ01Dd3RNQzR5TmpZZ0xUQXVNVEExTEMwd0xqVXlJQzB3TGpJNU15d3RNQzQzTURjZ2JDQXROeTR3TnpFc0xUY3VNRGNnWXlBdE1DNHpPVEVzTFRBdU16a3hJQzB4TGpBeU15d3RNQzR6T1RFZ0xURXVOREUwTERBZ1RDQTJOaTQ0TURRc01qUXVOekV4SUVNZ05qRXVOakF5TERJeUxqZ3hPQ0ExTlM0NU5Ea3NNakV1TmpBeklEVXdMREl4TGpZd015QmpJQzB5Tmk0ME1qY3NNQ0F0TkRjdU1EazRMREl6TGpreU5pQXRORGN1T1RZMUxESTBMamswTmlBdE1TNDNNREVzTWlBdE1TNDNNREVzTkM0NU1ESWdNVEJsTFRRc05pNDVNRE1nTUM0MU1UY3NNQzQyTURjZ09DNHdPRE1zT1M0ek5UUWdNVGt1TnpBM0xERTJMak15SUV3Z09DNDRPRE1zT0RJdU5qTXlJRU1nT0M0Mk9UVXNPREl1T0RJZ09DNDFPU3c0TXk0d056TWdPQzQxT1N3NE15NHpNemtnWXlBd0xEQXVNalkySURBdU1UQTFMREF1TlRJZ01DNHlPVE1zTUM0M01EY2diQ0EzTGpBM01TdzNMakEzSUdNZ01DNHhPVFVzTUM0eE9UVWdNQzQwTlRFc01DNHlPVE1nTUM0M01EY3NNQzR5T1RNZ01DNHlOVFlzTUNBd0xqVXhNaXd0TUM0d09UZ2dNQzQzTURjc0xUQXVNamt6SUd3Z056TXVOelVzTFRjekxqYzFJR01nTUM0eE9EY3NMVEF1TVRnMklEQXVNamt6TEMwd0xqUTBJREF1TWprekxDMHdMamN3TmlCNklFMGdNVEF1TmpJNExEVXdJRU1nTVRRdU1qVTVMRFEyTGpJME9TQXlNaTQxTWpZc016Z3VOVGN4SURNekxqRTVOU3d6TXk0NU56a2dNekV1TVRFMExETTNMakUwTlNBeU9TNDRPVFFzTkRBdU9USTRJREk1TGpnNU5DdzBOU0JqSURBc05DNDJOalVnTVM0Mk1ERXNPQzQ1TkRVZ05DNHlOeXd4TWk0ek5URWdUQ0F5T0M0d05DdzJNeTQwTnpVZ1F5QXhPUzQ0T0Rnc05UZ3VPVFUxSURFekxqWTBPU3cxTXk0eE1pQXhNQzQyTWpnc05UQWdlaUlOQ2lBZ0lHbGtQU0p3WVhSb09TSU5DaUFnSUhOMGVXeGxQU0ptYVd4c09pTkdSa1pHUmtZaUlDOCtEUW84TDJjK0RRbzhMM04yWno0TkNnPT0pO2JhY2tncm91bmQtY29sb3I6cmVkfS5lbW90ZS1tZW51IC5lbW90ZS1tZW51LXN0YXJyZWQgLmVkaXQtc3RhcnJlZHtiYWNrZ3JvdW5kLWltYWdlOnVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbTV2SWo4K0RRbzhJUzB0SUVOeVpXRjBaV1FnZDJsMGFDQkpibXR6WTJGd1pTQW9hSFIwY0RvdkwzZDNkeTVwYm10elkyRndaUzV2Y21jdktTQXRMVDROQ2cwS1BITjJadzBLSUNBZ2VHMXNibk02WkdNOUltaDBkSEE2THk5d2RYSnNMbTl5Wnk5a1l5OWxiR1Z0Wlc1MGN5OHhMakV2SWcwS0lDQWdlRzFzYm5NNlkyTTlJbWgwZEhBNkx5OWpjbVZoZEdsMlpXTnZiVzF2Ym5NdWIzSm5MMjV6SXlJTkNpQWdJSGh0Ykc1ek9uSmtaajBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TVRrNU9TOHdNaTh5TWkxeVpHWXRjM2x1ZEdGNExXNXpJeUlOQ2lBZ0lIaHRiRzV6T25OMlp6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lEUW9nSUNCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpRFFvZ0lDQjJaWEp6YVc5dVBTSXhMakVpRFFvZ0lDQjNhV1IwYUQwaU5UQWlEUW9nSUNCb1pXbG5hSFE5SWpVd0lnMEtJQ0FnZG1sbGQwSnZlRDBpTUNBd0lEVXdJRFV3SWcwS0lDQWdhV1E5SWt4aGVXVnlYekVpRFFvZ0lDQjRiV3c2YzNCaFkyVTlJbkJ5WlhObGNuWmxJajQ4YldWMFlXUmhkR0VOQ2lBZ0lHbGtQU0p0WlhSaFpHRjBZVE13TURFaVBqeHlaR1k2VWtSR1BqeGpZenBYYjNKckRRb2dJQ0FnSUNBZ2NtUm1PbUZpYjNWMFBTSWlQanhrWXpwbWIzSnRZWFErYVcxaFoyVXZjM1puSzNodGJEd3ZaR002Wm05eWJXRjBQanhrWXpwMGVYQmxEUW9nSUNBZ0lDQWdJQ0J5WkdZNmNtVnpiM1Z5WTJVOUltaDBkSEE2THk5d2RYSnNMbTl5Wnk5a1l5OWtZMjFwZEhsd1pTOVRkR2xzYkVsdFlXZGxJaUF2UGp4a1l6cDBhWFJzWlQ0OEwyUmpPblJwZEd4bFBqd3ZZMk02VjI5eWF6NDhMM0prWmpwU1JFWStQQzl0WlhSaFpHRjBZVDQ4WkdWbWN3MEtJQ0FnYVdROUltUmxabk15T1RrNUlpQXZQZzBLUEhCaGRHZ05DaUFnSUdROUltMGdORE11TURRc01qSXVOamsySUMwM0xqVTJPQ3czTGpNM055QXhMamM0Tnl3eE1DNDBNVGNnWXlBd0xqRXlOeXd3TGpjMUlDMHdMakU0TWl3eExqVXdPU0F0TUM0M09UY3NNUzQ1TlRjZ0xUQXVNelE0TERBdU1qVXpJQzB3TGpjMk1pd3dMak00TWlBdE1TNHhOellzTUM0ek9ESWdMVEF1TXpFNExEQWdMVEF1TmpNNExDMHdMakEzTmlBdE1DNDVNekVzTFRBdU1qTWdUQ0F5TlN3ek55NDJPREVnTVRVdU5qUTFMRFF5TGpVNU9TQmpJQzB3TGpZM05Dd3dMak0xTlNBdE1TNDBPU3d3TGpJNU5TQXRNaTR4TURjc0xUQXVNVFV4SUVNZ01USXVPVEl6TERReUlERXlMall4TkN3ME1TNHlORElnTVRJdU56UXpMRFF3TGpRNU1TQk1JREUwTGpVekxETXdMakEzTkNBMkxqazJNaXd5TWk0Mk9UY2dReUEyTGpReE5Td3lNaTR4TmpZZ05pNHlNakVzTWpFdU16Y3hJRFl1TkRVMExESXdMalkwTnlBMkxqWTVMREU1TGpreU15QTNMak14TlN3eE9TNHpPVFlnT0M0d05qa3NNVGt1TWpnMklHd2dNVEF1TkRVNUxDMHhMalV5TVNBMExqWTRMQzA1TGpRM09DQkRJREl6TGpVME15dzNMall3TXlBeU5DNHlNemtzTnk0eE56RWdNalVzTnk0eE56RWdZeUF3TGpjMk15d3dJREV1TkRVMkxEQXVORE15SURFdU56a3pMREV1TVRFMUlHd2dOQzQyTnprc09TNDBOemdnTVRBdU5EWXhMREV1TlRJeElHTWdNQzQzTlRJc01DNHhNRGtnTVM0ek56a3NNQzQyTXpjZ01TNDJNVElzTVM0ek5qRWdNQzR5TXpjc01DNDNNalFnTUM0d016Z3NNUzQxTVRrZ0xUQXVOVEExTERJdU1EVWdlaUlOQ2lBZ0lHbGtQU0p3WVhSb01qazVOU0lOQ2lBZ0lITjBlV3hsUFNKbWFXeHNPaU5tWm1Oak1EQTdabWxzYkMxdmNHRmphWFI1T2pFaUlDOCtEUW84TDNOMlp6NE5DZz09KX0uZW1vdGUtbWVudSAuZW1vdGUuZW1vdGUtbWVudS1zdGFycmVke2JvcmRlci1jb2xvcjpyZ2JhKDIwMCwyMDAsMCwuNSl9LmVtb3RlLW1lbnUgLmVtb3RlLmVtb3RlLW1lbnUtaGlkZGVue2JvcmRlci1jb2xvcjpyZ2JhKDI1NSwwLDAsLjUpfS5lbW90ZS1tZW51ICNzdGFycmVkLWVtb3Rlcy1ncm91cCAuZW1vdGU6bm90KC5lbW90ZS1tZW51LXN0YXJyZWQpLC5lbW90ZS1tZW51Om5vdCguZWRpdGluZykgLmVtb3RlLW1lbnUtaGlkZGVue2Rpc3BsYXk6bm9uZX0uZW1vdGUtbWVudTpub3QoLmVkaXRpbmcpICNzdGFycmVkLWVtb3Rlcy1ncm91cCAuZW1vdGUtbWVudS1zdGFycmVke2JvcmRlci1jb2xvcjp0cmFuc3BhcmVudH0uZW1vdGUtbWVudSAjc3RhcnJlZC1lbW90ZXMtZ3JvdXB7dGV4dC1hbGlnbjpjZW50ZXI7Y29sb3I6IzY0NjQ2NH0uZW1vdGUtbWVudSAjc3RhcnJlZC1lbW90ZXMtZ3JvdXA6ZW1wdHk6YmVmb3Jle2NvbnRlbnQ6XFxcIlVzZSB0aGUgZWRpdCBtb2RlIHRvIHN0YXIgYW4gZW1vdGUhXFxcIjtwb3NpdGlvbjpyZWxhdGl2ZTt0b3A6OHB4fS5lbW90ZS1tZW51IC5zY3JvbGxhYmxle2hlaWdodDpjYWxjKDEwMCUgLSAxMDFweCk7b3ZlcmZsb3cteTphdXRvfS5lbW90ZS1tZW51IC5zdGlja3l7cG9zaXRpb246YWJzb2x1dGU7Ym90dG9tOjA7d2lkdGg6MTAwJX0uZW1vdGUtbWVudSAuZW1vdGUtbWVudS1pbm5lcntwb3NpdGlvbjpyZWxhdGl2ZTttYXgtaGVpZ2h0OjEwMCU7aGVpZ2h0OjEwMCV9XCIpKTtcbiIsIm1vZHVsZS5leHBvcnRzID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBIb2dhbiA9IHJlcXVpcmUoJ2hvZ2FuLmpzL2xpYi90ZW1wbGF0ZS5qcycpO1xuICAgIHZhciB0ZW1wbGF0ZXMgPSB7fTtcbiAgICB0ZW1wbGF0ZXNbJ2Vtb3RlJ10gPSBuZXcgSG9nYW4uVGVtcGxhdGUoe2NvZGU6IGZ1bmN0aW9uIChjLHAsaSkgeyB2YXIgdD10aGlzO3QuYihpPWl8fFwiXCIpO3QuYihcIjxkaXYgY2xhc3M9XFxcImVtb3RlXCIpO2lmKHQucyh0LmYoXCJ0aGlyZFBhcnR5XCIsYyxwLDEpLGMscCwwLDMyLDQ0LFwie3sgfX1cIikpe3QucnMoYyxwLGZ1bmN0aW9uKGMscCx0KXt0LmIoXCIgdGhpcmQtcGFydHlcIik7fSk7Yy5wb3AoKTt9aWYoIXQucyh0LmYoXCJpc1Zpc2libGVcIixjLHAsMSksYyxwLDEsMCwwLFwiXCIpKXt0LmIoXCIgZW1vdGUtbWVudS1oaWRkZW5cIik7fTtpZih0LnModC5mKFwiaXNTdGFycmVkXCIsYyxwLDEpLGMscCwwLDExOSwxMzgsXCJ7eyB9fVwiKSl7dC5ycyhjLHAsZnVuY3Rpb24oYyxwLHQpe3QuYihcIiBlbW90ZS1tZW51LXN0YXJyZWRcIik7fSk7Yy5wb3AoKTt9dC5iKFwiXFxcIiBkYXRhLWVtb3RlPVxcXCJcIik7dC5iKHQudih0LmYoXCJ0ZXh0XCIsYyxwLDApKSk7dC5iKFwiXFxcIiB0aXRsZT1cXFwiXCIpO3QuYih0LnYodC5mKFwidGV4dFwiLGMscCwwKSkpO2lmKHQucyh0LmYoXCJ0aGlyZFBhcnR5XCIsYyxwLDEpLGMscCwwLDIwNiwyMjksXCJ7eyB9fVwiKSl7dC5ycyhjLHAsZnVuY3Rpb24oYyxwLHQpe3QuYihcIiAoZnJvbSAzcmQgcGFydHkgYWRkb24pXCIpO30pO2MucG9wKCk7fXQuYihcIlxcXCI+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHQ8aW1nIHNyYz1cXFwiXCIpO3QuYih0LnQodC5mKFwidXJsXCIsYyxwLDApKSk7dC5iKFwiXFxcIj5cXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCJcdDxkaXYgY2xhc3M9XFxcImVkaXQtdG9vbCBlZGl0LXN0YXJyZWRcXFwiIGRhdGEtd2hpY2g9XFxcIlwiKTt0LmIodC52KHQuZihcInRleHRcIixjLHAsMCkpKTt0LmIoXCJcXFwiIGRhdGEtY29tbWFuZD1cXFwidG9nZ2xlLXN0YXJyZWRcXFwiIHRpdGxlPVxcXCJTdGFyL3Vuc3RhciBlbW90ZTogXCIpO3QuYih0LnYodC5mKFwidGV4dFwiLGMscCwwKSkpO3QuYihcIlxcXCI+PC9kaXY+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHQ8ZGl2IGNsYXNzPVxcXCJlZGl0LXRvb2wgZWRpdC12aXNpYmlsaXR5XFxcIiBkYXRhLXdoaWNoPVxcXCJcIik7dC5iKHQudih0LmYoXCJ0ZXh0XCIsYyxwLDApKSk7dC5iKFwiXFxcIiBkYXRhLWNvbW1hbmQ9XFxcInRvZ2dsZS12aXNpYmlsaXR5XFxcIiB0aXRsZT1cXFwiSGlkZS9zaG93IGVtb3RlOiBcIik7dC5iKHQudih0LmYoXCJ0ZXh0XCIsYyxwLDApKSk7dC5iKFwiXFxcIj48L2Rpdj5cXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCI8L2Rpdj5cXHJcIik7dC5iKFwiXFxuXCIpO3JldHVybiB0LmZsKCk7IH0scGFydGlhbHM6IHt9LCBzdWJzOiB7ICB9fSk7XG4gICAgdGVtcGxhdGVzWydlbW90ZUJ1dHRvbiddID0gbmV3IEhvZ2FuLlRlbXBsYXRlKHtjb2RlOiBmdW5jdGlvbiAoYyxwLGkpIHsgdmFyIHQ9dGhpczt0LmIoaT1pfHxcIlwiKTt0LmIoXCI8YnV0dG9uIGNsYXNzPVxcXCJidXR0b24gYnV0dG9uLS1pY29uLW9ubHkgZmxvYXQtbGVmdFxcXCIgdGl0bGU9XFxcIkVtb3RlIE1lbnVcXFwiIGlkPVxcXCJlbW90ZS1tZW51LWJ1dHRvblxcXCI+PC9idXR0b24+XFxyXCIpO3QuYihcIlxcblwiKTtyZXR1cm4gdC5mbCgpOyB9LHBhcnRpYWxzOiB7fSwgc3ViczogeyAgfX0pO1xuICAgIHRlbXBsYXRlc1snZW1vdGVHcm91cEhlYWRlciddID0gbmV3IEhvZ2FuLlRlbXBsYXRlKHtjb2RlOiBmdW5jdGlvbiAoYyxwLGkpIHsgdmFyIHQ9dGhpczt0LmIoaT1pfHxcIlwiKTt0LmIoXCI8ZGl2IGNsYXNzPVxcXCJncm91cC1oZWFkZXJcXFwiIGRhdGEtZW1vdGUtY2hhbm5lbD1cXFwiXCIpO3QuYih0LnYodC5mKFwiY2hhbm5lbFwiLGMscCwwKSkpO3QuYihcIlxcXCI+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHQ8ZGl2IGNsYXNzPVxcXCJoZWFkZXItaW5mb1xcXCI+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHRcdDxpbWcgc3JjPVxcXCJcIik7dC5iKHQudih0LmYoXCJiYWRnZVwiLGMscCwwKSkpO3QuYihcIlxcXCIgLz5cXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCJcdFx0XCIpO3QuYih0LnYodC5mKFwiY2hhbm5lbERpc3BsYXlOYW1lXCIsYyxwLDApKSk7dC5iKFwiXFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHRcdDxkaXYgY2xhc3M9XFxcImVkaXQtdG9vbCBlZGl0LXZpc2liaWxpdHlcXFwiIGRhdGEtd2hpY2g9XFxcImNoYW5uZWwtXCIpO3QuYih0LnYodC5mKFwiY2hhbm5lbFwiLGMscCwwKSkpO3QuYihcIlxcXCIgZGF0YS1jb21tYW5kPVxcXCJ0b2dnbGUtdmlzaWJpbGl0eVxcXCIgdGl0bGU9XFxcIkhpZGUvc2hvdyBjdXJyZW50IGVtb3RlcyBmb3IgXCIpO3QuYih0LnYodC5mKFwiY2hhbm5lbERpc3BsYXlOYW1lXCIsYyxwLDApKSk7dC5iKFwiIChub3RlOiBuZXcgZW1vdGVzIHdpbGwgc3RpbGwgc2hvdyB1cCBpZiB0aGV5IGFyZSBhZGRlZClcXFwiPjwvZGl2PlxcclwiKTt0LmIoXCJcXG5cIiArIGkpO3QuYihcIlx0PC9kaXY+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHQ8ZGl2IGNsYXNzPVxcXCJlbW90ZS1jb250YWluZXJcXFwiPjwvZGl2PlxcclwiKTt0LmIoXCJcXG5cIiArIGkpO3QuYihcIjwvZGl2PlxcclwiKTt0LmIoXCJcXG5cIik7cmV0dXJuIHQuZmwoKTsgfSxwYXJ0aWFsczoge30sIHN1YnM6IHsgIH19KTtcbiAgICB0ZW1wbGF0ZXNbJ21lbnUnXSA9IG5ldyBIb2dhbi5UZW1wbGF0ZSh7Y29kZTogZnVuY3Rpb24gKGMscCxpKSB7IHZhciB0PXRoaXM7dC5iKGk9aXx8XCJcIik7dC5iKFwiPGRpdiBjbGFzcz1cXFwiZW1vdGUtbWVudVxcXCIgaWQ9XFxcImVtb3RlLW1lbnUtZm9yLXR3aXRjaFxcXCI+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHQ8ZGl2IGNsYXNzPVxcXCJlbW90ZS1tZW51LWlubmVyXFxcIj5cXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCJcXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCJcdFx0PGRpdiBjbGFzcz1cXFwiZHJhZ2dhYmxlXFxcIj48L2Rpdj5cXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCJcXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCJcdFx0PGRpdiBjbGFzcz1cXFwic2Nyb2xsYWJsZSBzY3JvbGxiYXItbWFjb3N4XFxcIj5cXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCJcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJncm91cC1jb250YWluZXJcXFwiIGlkPVxcXCJhbGwtZW1vdGVzLWdyb3VwXFxcIj48L2Rpdj5cXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCJcdFx0PC9kaXY+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHRcdDxkaXYgY2xhc3M9XFxcInN0aWNreVxcXCI+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHRcdFx0PGRpdiBjbGFzcz1cXFwiZ3JvdXAtaGVhZGVyIHNpbmdsZS1yb3dcXFwiIGlkPVxcXCJzdGFycmVkLWVtb3Rlcy1ncm91cFxcXCI+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJoZWFkZXItaW5mb1xcXCI+RmF2b3JpdGUgRW1vdGVzPC9kaXY+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJlbW90ZS1jb250YWluZXJcXFwiPjwvZGl2PlxcclwiKTt0LmIoXCJcXG5cIiArIGkpO3QuYihcIlx0XHRcdDwvZGl2PlxcclwiKTt0LmIoXCJcXG5cIiArIGkpO3QuYihcIlxcclwiKTt0LmIoXCJcXG5cIiArIGkpO3QuYihcIlx0XHRcdDxkaXYgY2xhc3M9XFxcImZvb3RlclxcXCI+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHRcdFx0XHQ8YSBjbGFzcz1cXFwicHVsbC1sZWZ0IGljb24gaWNvbi1ob21lXFxcIiBocmVmPVxcXCJodHRwOi8vY2xldHVzYy5naXRodWIuaW8vVXNlcnNjcmlwdC0tVHdpdGNoLUNoYXQtRW1vdGVzXFxcIiB0YXJnZXQ9XFxcIl9ibGFua1xcXCIgdGl0bGU9XFxcIlZpc2l0IHRoZSBob21lcGFnZSB3aGVyZSB5b3UgY2FuIGRvbmF0ZSwgcG9zdCBhIHJldmlldywgb3IgY29udGFjdCB0aGUgZGV2ZWxvcGVyXFxcIj48L2E+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHRcdFx0XHQ8YSBjbGFzcz1cXFwicHVsbC1sZWZ0IGljb24gaWNvbi1nZWFyXFxcIiBkYXRhLWNvbW1hbmQ9XFxcInRvZ2dsZS1lZGl0aW5nXFxcIiB0aXRsZT1cXFwiVG9nZ2xlIGVkaXQgbW9kZVxcXCI+PC9hPlxcclwiKTt0LmIoXCJcXG5cIiArIGkpO3QuYihcIlx0XHRcdFx0PGEgY2xhc3M9XFxcInB1bGwtcmlnaHQgaWNvbiBpY29uLXJlc2l6ZS1oYW5kbGVcXFwiIGRhdGEtY29tbWFuZD1cXFwicmVzaXplLWhhbmRsZVxcXCI+PC9hPlxcclwiKTt0LmIoXCJcXG5cIiArIGkpO3QuYihcIlx0XHRcdFx0PGEgY2xhc3M9XFxcInB1bGwtcmlnaHQgaWNvbiBpY29uLXBpblxcXCIgZGF0YS1jb21tYW5kPVxcXCJ0b2dnbGUtcGlubmVkXFxcIiB0aXRsZT1cXFwiUGluL3VucGluIHRoZSBlbW90ZSBtZW51IHRvIHRoZSBzY3JlZW5cXFwiPjwvYT5cXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCJcdFx0XHQ8L2Rpdj5cXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCJcdFx0PC9kaXY+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHQ8L2Rpdj5cXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCI8L2Rpdj5cXHJcIik7dC5iKFwiXFxuXCIpO3JldHVybiB0LmZsKCk7IH0scGFydGlhbHM6IHt9LCBzdWJzOiB7ICB9fSk7XG4gICAgdGVtcGxhdGVzWyduZXdzTWVzc2FnZSddID0gbmV3IEhvZ2FuLlRlbXBsYXRlKHtjb2RlOiBmdW5jdGlvbiAoYyxwLGkpIHsgdmFyIHQ9dGhpczt0LmIoaT1pfHxcIlwiKTt0LmIoXCJcXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCI8ZGl2IGNsYXNzPVxcXCJ0d2l0Y2gtY2hhdC1lbW90ZXMtbmV3c1xcXCI+XFxyXCIpO3QuYihcIlxcblwiICsgaSk7dC5iKFwiXHRbXCIpO3QuYih0LnYodC5mKFwic2NyaXB0TmFtZVwiLGMscCwwKSkpO3QuYihcIl0gTmV3czogXCIpO3QuYih0LnQodC5mKFwibWVzc2FnZVwiLGMscCwwKSkpO3QuYihcIiAoPGEgaHJlZj1cXFwiI1xcXCIgZGF0YS1jb21tYW5kPVxcXCJ0d2l0Y2gtY2hhdC1lbW90ZXM6ZGlzbWlzcy1uZXdzXFxcIiBkYXRhLW5ld3MtaWQ9XFxcIlwiKTt0LmIodC52KHQuZihcImlkXCIsYyxwLDApKSk7dC5iKFwiXFxcIj5EaXNtaXNzPC9hPilcXHJcIik7dC5iKFwiXFxuXCIgKyBpKTt0LmIoXCI8L2Rpdj5cXHJcIik7dC5iKFwiXFxuXCIpO3JldHVybiB0LmZsKCk7IH0scGFydGlhbHM6IHt9LCBzdWJzOiB7ICB9fSk7XG4gICAgcmV0dXJuIHRlbXBsYXRlcztcbn0pKCk7IiwiLypcbiAqICBDb3B5cmlnaHQgMjAxMSBUd2l0dGVyLCBJbmMuXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG52YXIgSG9nYW4gPSB7fTtcblxuKGZ1bmN0aW9uIChIb2dhbikge1xuICBIb2dhbi5UZW1wbGF0ZSA9IGZ1bmN0aW9uIChjb2RlT2JqLCB0ZXh0LCBjb21waWxlciwgb3B0aW9ucykge1xuICAgIGNvZGVPYmogPSBjb2RlT2JqIHx8IHt9O1xuICAgIHRoaXMuciA9IGNvZGVPYmouY29kZSB8fCB0aGlzLnI7XG4gICAgdGhpcy5jID0gY29tcGlsZXI7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICB0aGlzLnRleHQgPSB0ZXh0IHx8ICcnO1xuICAgIHRoaXMucGFydGlhbHMgPSBjb2RlT2JqLnBhcnRpYWxzIHx8IHt9O1xuICAgIHRoaXMuc3VicyA9IGNvZGVPYmouc3VicyB8fCB7fTtcbiAgICB0aGlzLmJ1ZiA9ICcnO1xuICB9XG5cbiAgSG9nYW4uVGVtcGxhdGUucHJvdG90eXBlID0ge1xuICAgIC8vIHJlbmRlcjogcmVwbGFjZWQgYnkgZ2VuZXJhdGVkIGNvZGUuXG4gICAgcjogZnVuY3Rpb24gKGNvbnRleHQsIHBhcnRpYWxzLCBpbmRlbnQpIHsgcmV0dXJuICcnOyB9LFxuXG4gICAgLy8gdmFyaWFibGUgZXNjYXBpbmdcbiAgICB2OiBob2dhbkVzY2FwZSxcblxuICAgIC8vIHRyaXBsZSBzdGFjaGVcbiAgICB0OiBjb2VyY2VUb1N0cmluZyxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKGNvbnRleHQsIHBhcnRpYWxzLCBpbmRlbnQpIHtcbiAgICAgIHJldHVybiB0aGlzLnJpKFtjb250ZXh0XSwgcGFydGlhbHMgfHwge30sIGluZGVudCk7XG4gICAgfSxcblxuICAgIC8vIHJlbmRlciBpbnRlcm5hbCAtLSBhIGhvb2sgZm9yIG92ZXJyaWRlcyB0aGF0IGNhdGNoZXMgcGFydGlhbHMgdG9vXG4gICAgcmk6IGZ1bmN0aW9uIChjb250ZXh0LCBwYXJ0aWFscywgaW5kZW50KSB7XG4gICAgICByZXR1cm4gdGhpcy5yKGNvbnRleHQsIHBhcnRpYWxzLCBpbmRlbnQpO1xuICAgIH0sXG5cbiAgICAvLyBlbnN1cmVQYXJ0aWFsXG4gICAgZXA6IGZ1bmN0aW9uKHN5bWJvbCwgcGFydGlhbHMpIHtcbiAgICAgIHZhciBwYXJ0aWFsID0gdGhpcy5wYXJ0aWFsc1tzeW1ib2xdO1xuXG4gICAgICAvLyBjaGVjayB0byBzZWUgdGhhdCBpZiB3ZSd2ZSBpbnN0YW50aWF0ZWQgdGhpcyBwYXJ0aWFsIGJlZm9yZVxuICAgICAgdmFyIHRlbXBsYXRlID0gcGFydGlhbHNbcGFydGlhbC5uYW1lXTtcbiAgICAgIGlmIChwYXJ0aWFsLmluc3RhbmNlICYmIHBhcnRpYWwuYmFzZSA9PSB0ZW1wbGF0ZSkge1xuICAgICAgICByZXR1cm4gcGFydGlhbC5pbnN0YW5jZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiB0ZW1wbGF0ZSA9PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAoIXRoaXMuYykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGNvbXBpbGVyIGF2YWlsYWJsZS5cIik7XG4gICAgICAgIH1cbiAgICAgICAgdGVtcGxhdGUgPSB0aGlzLmMuY29tcGlsZSh0ZW1wbGF0ZSwgdGhpcy5vcHRpb25zKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0ZW1wbGF0ZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgLy8gV2UgdXNlIHRoaXMgdG8gY2hlY2sgd2hldGhlciB0aGUgcGFydGlhbHMgZGljdGlvbmFyeSBoYXMgY2hhbmdlZFxuICAgICAgdGhpcy5wYXJ0aWFsc1tzeW1ib2xdLmJhc2UgPSB0ZW1wbGF0ZTtcblxuICAgICAgaWYgKHBhcnRpYWwuc3Vicykge1xuICAgICAgICAvLyBNYWtlIHN1cmUgd2UgY29uc2lkZXIgcGFyZW50IHRlbXBsYXRlIG5vd1xuICAgICAgICBpZiAoIXBhcnRpYWxzLnN0YWNrVGV4dCkgcGFydGlhbHMuc3RhY2tUZXh0ID0ge307XG4gICAgICAgIGZvciAoa2V5IGluIHBhcnRpYWwuc3Vicykge1xuICAgICAgICAgIGlmICghcGFydGlhbHMuc3RhY2tUZXh0W2tleV0pIHtcbiAgICAgICAgICAgIHBhcnRpYWxzLnN0YWNrVGV4dFtrZXldID0gKHRoaXMuYWN0aXZlU3ViICE9PSB1bmRlZmluZWQgJiYgcGFydGlhbHMuc3RhY2tUZXh0W3RoaXMuYWN0aXZlU3ViXSkgPyBwYXJ0aWFscy5zdGFja1RleHRbdGhpcy5hY3RpdmVTdWJdIDogdGhpcy50ZXh0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0ZW1wbGF0ZSA9IGNyZWF0ZVNwZWNpYWxpemVkUGFydGlhbCh0ZW1wbGF0ZSwgcGFydGlhbC5zdWJzLCBwYXJ0aWFsLnBhcnRpYWxzLFxuICAgICAgICAgIHRoaXMuc3RhY2tTdWJzLCB0aGlzLnN0YWNrUGFydGlhbHMsIHBhcnRpYWxzLnN0YWNrVGV4dCk7XG4gICAgICB9XG4gICAgICB0aGlzLnBhcnRpYWxzW3N5bWJvbF0uaW5zdGFuY2UgPSB0ZW1wbGF0ZTtcblxuICAgICAgcmV0dXJuIHRlbXBsYXRlO1xuICAgIH0sXG5cbiAgICAvLyB0cmllcyB0byBmaW5kIGEgcGFydGlhbCBpbiB0aGUgY3VycmVudCBzY29wZSBhbmQgcmVuZGVyIGl0XG4gICAgcnA6IGZ1bmN0aW9uKHN5bWJvbCwgY29udGV4dCwgcGFydGlhbHMsIGluZGVudCkge1xuICAgICAgdmFyIHBhcnRpYWwgPSB0aGlzLmVwKHN5bWJvbCwgcGFydGlhbHMpO1xuICAgICAgaWYgKCFwYXJ0aWFsKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBhcnRpYWwucmkoY29udGV4dCwgcGFydGlhbHMsIGluZGVudCk7XG4gICAgfSxcblxuICAgIC8vIHJlbmRlciBhIHNlY3Rpb25cbiAgICByczogZnVuY3Rpb24oY29udGV4dCwgcGFydGlhbHMsIHNlY3Rpb24pIHtcbiAgICAgIHZhciB0YWlsID0gY29udGV4dFtjb250ZXh0Lmxlbmd0aCAtIDFdO1xuXG4gICAgICBpZiAoIWlzQXJyYXkodGFpbCkpIHtcbiAgICAgICAgc2VjdGlvbihjb250ZXh0LCBwYXJ0aWFscywgdGhpcyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWlsLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnRleHQucHVzaCh0YWlsW2ldKTtcbiAgICAgICAgc2VjdGlvbihjb250ZXh0LCBwYXJ0aWFscywgdGhpcyk7XG4gICAgICAgIGNvbnRleHQucG9wKCk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8vIG1heWJlIHN0YXJ0IGEgc2VjdGlvblxuICAgIHM6IGZ1bmN0aW9uKHZhbCwgY3R4LCBwYXJ0aWFscywgaW52ZXJ0ZWQsIHN0YXJ0LCBlbmQsIHRhZ3MpIHtcbiAgICAgIHZhciBwYXNzO1xuXG4gICAgICBpZiAoaXNBcnJheSh2YWwpICYmIHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHZhbCA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHZhbCA9IHRoaXMubXModmFsLCBjdHgsIHBhcnRpYWxzLCBpbnZlcnRlZCwgc3RhcnQsIGVuZCwgdGFncyk7XG4gICAgICB9XG5cbiAgICAgIHBhc3MgPSAhIXZhbDtcblxuICAgICAgaWYgKCFpbnZlcnRlZCAmJiBwYXNzICYmIGN0eCkge1xuICAgICAgICBjdHgucHVzaCgodHlwZW9mIHZhbCA9PSAnb2JqZWN0JykgPyB2YWwgOiBjdHhbY3R4Lmxlbmd0aCAtIDFdKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBhc3M7XG4gICAgfSxcblxuICAgIC8vIGZpbmQgdmFsdWVzIHdpdGggZG90dGVkIG5hbWVzXG4gICAgZDogZnVuY3Rpb24oa2V5LCBjdHgsIHBhcnRpYWxzLCByZXR1cm5Gb3VuZCkge1xuICAgICAgdmFyIGZvdW5kLFxuICAgICAgICAgIG5hbWVzID0ga2V5LnNwbGl0KCcuJyksXG4gICAgICAgICAgdmFsID0gdGhpcy5mKG5hbWVzWzBdLCBjdHgsIHBhcnRpYWxzLCByZXR1cm5Gb3VuZCksXG4gICAgICAgICAgZG9Nb2RlbEdldCA9IHRoaXMub3B0aW9ucy5tb2RlbEdldCxcbiAgICAgICAgICBjeCA9IG51bGw7XG5cbiAgICAgIGlmIChrZXkgPT09ICcuJyAmJiBpc0FycmF5KGN0eFtjdHgubGVuZ3RoIC0gMl0pKSB7XG4gICAgICAgIHZhbCA9IGN0eFtjdHgubGVuZ3RoIC0gMV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgZm91bmQgPSBmaW5kSW5TY29wZShuYW1lc1tpXSwgdmFsLCBkb01vZGVsR2V0KTtcbiAgICAgICAgICBpZiAoZm91bmQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY3ggPSB2YWw7XG4gICAgICAgICAgICB2YWwgPSBmb3VuZDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsID0gJyc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXR1cm5Gb3VuZCAmJiAhdmFsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFyZXR1cm5Gb3VuZCAmJiB0eXBlb2YgdmFsID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY3R4LnB1c2goY3gpO1xuICAgICAgICB2YWwgPSB0aGlzLm12KHZhbCwgY3R4LCBwYXJ0aWFscyk7XG4gICAgICAgIGN0eC5wb3AoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHZhbDtcbiAgICB9LFxuXG4gICAgLy8gZmluZCB2YWx1ZXMgd2l0aCBub3JtYWwgbmFtZXNcbiAgICBmOiBmdW5jdGlvbihrZXksIGN0eCwgcGFydGlhbHMsIHJldHVybkZvdW5kKSB7XG4gICAgICB2YXIgdmFsID0gZmFsc2UsXG4gICAgICAgICAgdiA9IG51bGwsXG4gICAgICAgICAgZm91bmQgPSBmYWxzZSxcbiAgICAgICAgICBkb01vZGVsR2V0ID0gdGhpcy5vcHRpb25zLm1vZGVsR2V0O1xuXG4gICAgICBmb3IgKHZhciBpID0gY3R4Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHYgPSBjdHhbaV07XG4gICAgICAgIHZhbCA9IGZpbmRJblNjb3BlKGtleSwgdiwgZG9Nb2RlbEdldCk7XG4gICAgICAgIGlmICh2YWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWZvdW5kKSB7XG4gICAgICAgIHJldHVybiAocmV0dXJuRm91bmQpID8gZmFsc2UgOiBcIlwiO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXJldHVybkZvdW5kICYmIHR5cGVvZiB2YWwgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YWwgPSB0aGlzLm12KHZhbCwgY3R4LCBwYXJ0aWFscyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB2YWw7XG4gICAgfSxcblxuICAgIC8vIGhpZ2hlciBvcmRlciB0ZW1wbGF0ZXNcbiAgICBsczogZnVuY3Rpb24oZnVuYywgY3gsIHBhcnRpYWxzLCB0ZXh0LCB0YWdzKSB7XG4gICAgICB2YXIgb2xkVGFncyA9IHRoaXMub3B0aW9ucy5kZWxpbWl0ZXJzO1xuXG4gICAgICB0aGlzLm9wdGlvbnMuZGVsaW1pdGVycyA9IHRhZ3M7XG4gICAgICB0aGlzLmIodGhpcy5jdChjb2VyY2VUb1N0cmluZyhmdW5jLmNhbGwoY3gsIHRleHQpKSwgY3gsIHBhcnRpYWxzKSk7XG4gICAgICB0aGlzLm9wdGlvbnMuZGVsaW1pdGVycyA9IG9sZFRhZ3M7XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9LFxuXG4gICAgLy8gY29tcGlsZSB0ZXh0XG4gICAgY3Q6IGZ1bmN0aW9uKHRleHQsIGN4LCBwYXJ0aWFscykge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5kaXNhYmxlTGFtYmRhKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTGFtYmRhIGZlYXR1cmVzIGRpc2FibGVkLicpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYy5jb21waWxlKHRleHQsIHRoaXMub3B0aW9ucykucmVuZGVyKGN4LCBwYXJ0aWFscyk7XG4gICAgfSxcblxuICAgIC8vIHRlbXBsYXRlIHJlc3VsdCBidWZmZXJpbmdcbiAgICBiOiBmdW5jdGlvbihzKSB7IHRoaXMuYnVmICs9IHM7IH0sXG5cbiAgICBmbDogZnVuY3Rpb24oKSB7IHZhciByID0gdGhpcy5idWY7IHRoaXMuYnVmID0gJyc7IHJldHVybiByOyB9LFxuXG4gICAgLy8gbWV0aG9kIHJlcGxhY2Ugc2VjdGlvblxuICAgIG1zOiBmdW5jdGlvbihmdW5jLCBjdHgsIHBhcnRpYWxzLCBpbnZlcnRlZCwgc3RhcnQsIGVuZCwgdGFncykge1xuICAgICAgdmFyIHRleHRTb3VyY2UsXG4gICAgICAgICAgY3ggPSBjdHhbY3R4Lmxlbmd0aCAtIDFdLFxuICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuY2FsbChjeCk7XG5cbiAgICAgIGlmICh0eXBlb2YgcmVzdWx0ID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgaWYgKGludmVydGVkKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGV4dFNvdXJjZSA9ICh0aGlzLmFjdGl2ZVN1YiAmJiB0aGlzLnN1YnNUZXh0ICYmIHRoaXMuc3Vic1RleHRbdGhpcy5hY3RpdmVTdWJdKSA/IHRoaXMuc3Vic1RleHRbdGhpcy5hY3RpdmVTdWJdIDogdGhpcy50ZXh0O1xuICAgICAgICAgIHJldHVybiB0aGlzLmxzKHJlc3VsdCwgY3gsIHBhcnRpYWxzLCB0ZXh0U291cmNlLnN1YnN0cmluZyhzdGFydCwgZW5kKSwgdGFncyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuXG4gICAgLy8gbWV0aG9kIHJlcGxhY2UgdmFyaWFibGVcbiAgICBtdjogZnVuY3Rpb24oZnVuYywgY3R4LCBwYXJ0aWFscykge1xuICAgICAgdmFyIGN4ID0gY3R4W2N0eC5sZW5ndGggLSAxXTtcbiAgICAgIHZhciByZXN1bHQgPSBmdW5jLmNhbGwoY3gpO1xuXG4gICAgICBpZiAodHlwZW9mIHJlc3VsdCA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmN0KGNvZXJjZVRvU3RyaW5nKHJlc3VsdC5jYWxsKGN4KSksIGN4LCBwYXJ0aWFscyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIHN1YjogZnVuY3Rpb24obmFtZSwgY29udGV4dCwgcGFydGlhbHMsIGluZGVudCkge1xuICAgICAgdmFyIGYgPSB0aGlzLnN1YnNbbmFtZV07XG4gICAgICBpZiAoZikge1xuICAgICAgICB0aGlzLmFjdGl2ZVN1YiA9IG5hbWU7XG4gICAgICAgIGYoY29udGV4dCwgcGFydGlhbHMsIHRoaXMsIGluZGVudCk7XG4gICAgICAgIHRoaXMuYWN0aXZlU3ViID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gIH07XG5cbiAgLy9GaW5kIGEga2V5IGluIGFuIG9iamVjdFxuICBmdW5jdGlvbiBmaW5kSW5TY29wZShrZXksIHNjb3BlLCBkb01vZGVsR2V0KSB7XG4gICAgdmFyIHZhbDtcblxuICAgIGlmIChzY29wZSAmJiB0eXBlb2Ygc2NvcGUgPT0gJ29iamVjdCcpIHtcblxuICAgICAgaWYgKHNjb3BlW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YWwgPSBzY29wZVtrZXldO1xuXG4gICAgICAvLyB0cnkgbG9va3VwIHdpdGggZ2V0IGZvciBiYWNrYm9uZSBvciBzaW1pbGFyIG1vZGVsIGRhdGFcbiAgICAgIH0gZWxzZSBpZiAoZG9Nb2RlbEdldCAmJiBzY29wZS5nZXQgJiYgdHlwZW9mIHNjb3BlLmdldCA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHZhbCA9IHNjb3BlLmdldChrZXkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWw7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVTcGVjaWFsaXplZFBhcnRpYWwoaW5zdGFuY2UsIHN1YnMsIHBhcnRpYWxzLCBzdGFja1N1YnMsIHN0YWNrUGFydGlhbHMsIHN0YWNrVGV4dCkge1xuICAgIGZ1bmN0aW9uIFBhcnRpYWxUZW1wbGF0ZSgpIHt9O1xuICAgIFBhcnRpYWxUZW1wbGF0ZS5wcm90b3R5cGUgPSBpbnN0YW5jZTtcbiAgICBmdW5jdGlvbiBTdWJzdGl0dXRpb25zKCkge307XG4gICAgU3Vic3RpdHV0aW9ucy5wcm90b3R5cGUgPSBpbnN0YW5jZS5zdWJzO1xuICAgIHZhciBrZXk7XG4gICAgdmFyIHBhcnRpYWwgPSBuZXcgUGFydGlhbFRlbXBsYXRlKCk7XG4gICAgcGFydGlhbC5zdWJzID0gbmV3IFN1YnN0aXR1dGlvbnMoKTtcbiAgICBwYXJ0aWFsLnN1YnNUZXh0ID0ge307ICAvL2hlaGUuIHN1YnN0ZXh0LlxuICAgIHBhcnRpYWwuYnVmID0gJyc7XG5cbiAgICBzdGFja1N1YnMgPSBzdGFja1N1YnMgfHwge307XG4gICAgcGFydGlhbC5zdGFja1N1YnMgPSBzdGFja1N1YnM7XG4gICAgcGFydGlhbC5zdWJzVGV4dCA9IHN0YWNrVGV4dDtcbiAgICBmb3IgKGtleSBpbiBzdWJzKSB7XG4gICAgICBpZiAoIXN0YWNrU3Vic1trZXldKSBzdGFja1N1YnNba2V5XSA9IHN1YnNba2V5XTtcbiAgICB9XG4gICAgZm9yIChrZXkgaW4gc3RhY2tTdWJzKSB7XG4gICAgICBwYXJ0aWFsLnN1YnNba2V5XSA9IHN0YWNrU3Vic1trZXldO1xuICAgIH1cblxuICAgIHN0YWNrUGFydGlhbHMgPSBzdGFja1BhcnRpYWxzIHx8IHt9O1xuICAgIHBhcnRpYWwuc3RhY2tQYXJ0aWFscyA9IHN0YWNrUGFydGlhbHM7XG4gICAgZm9yIChrZXkgaW4gcGFydGlhbHMpIHtcbiAgICAgIGlmICghc3RhY2tQYXJ0aWFsc1trZXldKSBzdGFja1BhcnRpYWxzW2tleV0gPSBwYXJ0aWFsc1trZXldO1xuICAgIH1cbiAgICBmb3IgKGtleSBpbiBzdGFja1BhcnRpYWxzKSB7XG4gICAgICBwYXJ0aWFsLnBhcnRpYWxzW2tleV0gPSBzdGFja1BhcnRpYWxzW2tleV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnRpYWw7XG4gIH1cblxuICB2YXIgckFtcCA9IC8mL2csXG4gICAgICByTHQgPSAvPC9nLFxuICAgICAgckd0ID0gLz4vZyxcbiAgICAgIHJBcG9zID0gL1xcJy9nLFxuICAgICAgclF1b3QgPSAvXFxcIi9nLFxuICAgICAgaENoYXJzID0gL1smPD5cXFwiXFwnXS87XG5cbiAgZnVuY3Rpb24gY29lcmNlVG9TdHJpbmcodmFsKSB7XG4gICAgcmV0dXJuIFN0cmluZygodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSA/ICcnIDogdmFsKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhvZ2FuRXNjYXBlKHN0cikge1xuICAgIHN0ciA9IGNvZXJjZVRvU3RyaW5nKHN0cik7XG4gICAgcmV0dXJuIGhDaGFycy50ZXN0KHN0cikgP1xuICAgICAgc3RyXG4gICAgICAgIC5yZXBsYWNlKHJBbXAsICcmYW1wOycpXG4gICAgICAgIC5yZXBsYWNlKHJMdCwgJyZsdDsnKVxuICAgICAgICAucmVwbGFjZShyR3QsICcmZ3Q7JylcbiAgICAgICAgLnJlcGxhY2UockFwb3MsICcmIzM5OycpXG4gICAgICAgIC5yZXBsYWNlKHJRdW90LCAnJnF1b3Q7JykgOlxuICAgICAgc3RyO1xuICB9XG5cbiAgdmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uKGEpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGEpID09PSAnW29iamVjdCBBcnJheV0nO1xuICB9O1xuXG59KSh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcgPyBleHBvcnRzIDogSG9nYW4pO1xuIiwiLyoqXG4gKiBqUXVlcnkgQ1NTIEN1c3RvbWl6YWJsZSBTY3JvbGxiYXJcbiAqXG4gKiBDb3B5cmlnaHQgMjAxNCwgWXVyaXkgS2hhYmFyb3ZcbiAqIER1YWwgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBvciBHUEwgVmVyc2lvbiAyIGxpY2Vuc2VzLlxuICpcbiAqIElmIHlvdSBmb3VuZCBidWcsIHBsZWFzZSBjb250YWN0IG1lIHZpYSBlbWFpbCA8MTNyZWFsMDA4QGdtYWlsLmNvbT5cbiAqXG4gKiBAYXV0aG9yIFl1cml5IEtoYWJhcm92IGFrYSBHcm9tb1xuICogQHZlcnNpb24gMC4yLjZcbiAqIEB1cmwgaHR0cHM6Ly9naXRodWIuY29tL2dyb21vL2pxdWVyeS5zY3JvbGxiYXIvXG4gKlxuICovXG4oZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIGgodCl7aWYoby53ZWJraXQmJiF0KXtyZXR1cm57aGVpZ2h0OjAsd2lkdGg6MH19aWYoIW8uZGF0YS5vdXRlcil7dmFyIG49e2JvcmRlcjpcIm5vbmVcIixcImJveC1zaXppbmdcIjpcImNvbnRlbnQtYm94XCIsaGVpZ2h0OlwiMjAwcHhcIixtYXJnaW46XCIwXCIscGFkZGluZzpcIjBcIix3aWR0aDpcIjIwMHB4XCJ9O28uZGF0YS5pbm5lcj1lKFwiPGRpdj5cIikuY3NzKGUuZXh0ZW5kKHt9LG4pKTtvLmRhdGEub3V0ZXI9ZShcIjxkaXY+XCIpLmNzcyhlLmV4dGVuZCh7bGVmdDpcIi0xMDAwcHhcIixvdmVyZmxvdzpcInNjcm9sbFwiLHBvc2l0aW9uOlwiYWJzb2x1dGVcIix0b3A6XCItMTAwMHB4XCJ9LG4pKS5hcHBlbmQoby5kYXRhLmlubmVyKS5hcHBlbmRUbyhcImJvZHlcIil9by5kYXRhLm91dGVyLnNjcm9sbExlZnQoMWUzKS5zY3JvbGxUb3AoMWUzKTtyZXR1cm57aGVpZ2h0Ok1hdGguY2VpbChvLmRhdGEub3V0ZXIub2Zmc2V0KCkudG9wLW8uZGF0YS5pbm5lci5vZmZzZXQoKS50b3B8fDApLHdpZHRoOk1hdGguY2VpbChvLmRhdGEub3V0ZXIub2Zmc2V0KCkubGVmdC1vLmRhdGEuaW5uZXIub2Zmc2V0KCkubGVmdHx8MCl9fWZ1bmN0aW9uIHAobixyKXtlKHQpLm9uKHtcImJsdXIuc2Nyb2xsYmFyXCI6ZnVuY3Rpb24oKXtlKHQpLmFkZChcImJvZHlcIikub2ZmKFwiLnNjcm9sbGJhclwiKTtuJiZuKCl9LFwiZHJhZ3N0YXJ0LnNjcm9sbGJhclwiOmZ1bmN0aW9uKGUpe2UucHJldmVudERlZmF1bHQoKTtyZXR1cm4gZmFsc2V9LFwibW91c2V1cC5zY3JvbGxiYXJcIjpmdW5jdGlvbigpe2UodCkuYWRkKFwiYm9keVwiKS5vZmYoXCIuc2Nyb2xsYmFyXCIpO24mJm4oKX19KTtlKFwiYm9keVwiKS5vbih7XCJzZWxlY3RzdGFydC5zY3JvbGxiYXJcIjpmdW5jdGlvbihlKXtlLnByZXZlbnREZWZhdWx0KCk7cmV0dXJuIGZhbHNlfX0pO3ImJnIucHJldmVudERlZmF1bHQoKTtyZXR1cm4gZmFsc2V9ZnVuY3Rpb24gZCgpe3ZhciBlPWgodHJ1ZSk7cmV0dXJuIShlLmhlaWdodHx8ZS53aWR0aCl9ZnVuY3Rpb24gdihlKXt2YXIgdD1lLm9yaWdpbmFsRXZlbnQ7aWYodC5heGlzJiZ0LmF4aXM9PT10LkhPUklaT05UQUxfQVhJUylyZXR1cm4gZmFsc2U7aWYodC53aGVlbERlbHRhWClyZXR1cm4gZmFsc2U7cmV0dXJuIHRydWV9dmFyIHI9ZmFsc2U7dmFyIGk9MSxzPVwicHhcIjt2YXIgbz17ZGF0YTp7fSxtYWNvc3g6bi5uYXZpZ2F0b3IucGxhdGZvcm0udG9Mb3dlckNhc2UoKS5pbmRleE9mKFwibWFjXCIpIT09LTEsbW9iaWxlOi9BbmRyb2lkfHdlYk9TfGlQaG9uZXxpUGFkfGlQb2R8QmxhY2tCZXJyeS9pLnRlc3Qobi5uYXZpZ2F0b3IudXNlckFnZW50KSxvdmVybGF5Om51bGwsc2Nyb2xsOm51bGwsc2Nyb2xsczpbXSx3ZWJraXQ6L1dlYktpdC8udGVzdChuLm5hdmlnYXRvci51c2VyQWdlbnQpLGxvZzpyP2Z1bmN0aW9uKHQscil7dmFyIGk9dDtpZihyJiZ0eXBlb2YgdCE9XCJzdHJpbmdcIil7aT1bXTtlLmVhY2godCxmdW5jdGlvbihlLHQpe2kucHVzaCgnXCInK2UrJ1wiOiAnK3QpfSk7aT1pLmpvaW4oXCIsIFwiKX1pZihuLmNvbnNvbGUmJm4uY29uc29sZS5sb2cpe24uY29uc29sZS5sb2coaSl9ZWxzZXthbGVydChpKX19OmZ1bmN0aW9uKCl7fX07dmFyIHU9e2F1dG9TY3JvbGxTaXplOnRydWUsYXV0b1VwZGF0ZTp0cnVlLGRlYnVnOmZhbHNlLGRpc2FibGVCb2R5U2Nyb2xsOmZhbHNlLGR1cmF0aW9uOjIwMCxpZ25vcmVNb2JpbGU6dHJ1ZSxpZ25vcmVPdmVybGF5OnRydWUsc2Nyb2xsU3RlcDozMCxzaG93QXJyb3dzOmZhbHNlLHN0ZXBTY3JvbGxpbmc6dHJ1ZSx0eXBlOlwic2ltcGxlXCIsc2Nyb2xseDpudWxsLHNjcm9sbHk6bnVsbCxvbkRlc3Ryb3k6bnVsbCxvbkluaXQ6bnVsbCxvblNjcm9sbDpudWxsLG9uVXBkYXRlOm51bGx9O3ZhciBhPWZ1bmN0aW9uKHQscil7aWYoIW8uc2Nyb2xsKXtvLmxvZyhcIkluaXQgalF1ZXJ5IFNjcm9sbGJhciB2MC4yLjZcIik7by5vdmVybGF5PWQoKTtvLnNjcm9sbD1oKCk7YygpO2UobikucmVzaXplKGZ1bmN0aW9uKCl7dmFyIGU9ZmFsc2U7aWYoby5zY3JvbGwmJihvLnNjcm9sbC5oZWlnaHR8fG8uc2Nyb2xsLndpZHRoKSl7dmFyIHQ9aCgpO2lmKHQuaGVpZ2h0IT1vLnNjcm9sbC5oZWlnaHR8fHQud2lkdGghPW8uc2Nyb2xsLndpZHRoKXtvLnNjcm9sbD10O2U9dHJ1ZX19YyhlKX0pfXRoaXMuY29udGFpbmVyPXQ7dGhpcy5vcHRpb25zPWUuZXh0ZW5kKHt9LHUsbi5qUXVlcnlTY3JvbGxiYXJPcHRpb25zfHx7fSk7dGhpcy5zY3JvbGxUbz1udWxsO3RoaXMuc2Nyb2xseD17fTt0aGlzLnNjcm9sbHk9e307dGhpcy5pbml0KHIpfTthLnByb3RvdHlwZT17ZGVzdHJveTpmdW5jdGlvbigpe2lmKCF0aGlzLndyYXBwZXIpe3JldHVybn12YXIgbj10aGlzLmNvbnRhaW5lci5zY3JvbGxMZWZ0KCk7dmFyIHI9dGhpcy5jb250YWluZXIuc2Nyb2xsVG9wKCk7dGhpcy5jb250YWluZXIuaW5zZXJ0QmVmb3JlKHRoaXMud3JhcHBlcikuY3NzKHtoZWlnaHQ6XCJcIixtYXJnaW46XCJcIn0pLnJlbW92ZUNsYXNzKFwic2Nyb2xsLWNvbnRlbnRcIikucmVtb3ZlQ2xhc3MoXCJzY3JvbGwtc2Nyb2xseF92aXNpYmxlXCIpLnJlbW92ZUNsYXNzKFwic2Nyb2xsLXNjcm9sbHlfdmlzaWJsZVwiKS5vZmYoXCIuc2Nyb2xsYmFyXCIpLnNjcm9sbExlZnQobikuc2Nyb2xsVG9wKHIpO3RoaXMuc2Nyb2xseC5zY3JvbGxiYXIucmVtb3ZlQ2xhc3MoXCJzY3JvbGwtc2Nyb2xseF92aXNpYmxlXCIpLmZpbmQoXCJkaXZcIikuYW5kU2VsZigpLm9mZihcIi5zY3JvbGxiYXJcIik7dGhpcy5zY3JvbGx5LnNjcm9sbGJhci5yZW1vdmVDbGFzcyhcInNjcm9sbC1zY3JvbGx5X3Zpc2libGVcIikuZmluZChcImRpdlwiKS5hbmRTZWxmKCkub2ZmKFwiLnNjcm9sbGJhclwiKTt0aGlzLndyYXBwZXIucmVtb3ZlKCk7ZSh0KS5hZGQoXCJib2R5XCIpLm9mZihcIi5zY3JvbGxiYXJcIik7aWYoZS5pc0Z1bmN0aW9uKHRoaXMub3B0aW9ucy5vbkRlc3Ryb3kpKXRoaXMub3B0aW9ucy5vbkRlc3Ryb3kuYXBwbHkodGhpcyxbdGhpcy5jb250YWluZXJdKX0sZ2V0U2Nyb2xsYmFyOmZ1bmN0aW9uKHQpe3ZhciBuPXRoaXMub3B0aW9uc1tcInNjcm9sbFwiK3RdO3ZhciByPXthZHZhbmNlZDonPGRpdiBjbGFzcz1cInNjcm9sbC1lbGVtZW50X2Nvcm5lclwiPjwvZGl2PicrJzxkaXYgY2xhc3M9XCJzY3JvbGwtYXJyb3cgc2Nyb2xsLWFycm93X2xlc3NcIj48L2Rpdj4nKyc8ZGl2IGNsYXNzPVwic2Nyb2xsLWFycm93IHNjcm9sbC1hcnJvd19tb3JlXCI+PC9kaXY+JysnPGRpdiBjbGFzcz1cInNjcm9sbC1lbGVtZW50X291dGVyXCI+JysnICAgIDxkaXYgY2xhc3M9XCJzY3JvbGwtZWxlbWVudF9zaXplXCI+PC9kaXY+JysnICAgIDxkaXYgY2xhc3M9XCJzY3JvbGwtZWxlbWVudF9pbm5lci13cmFwcGVyXCI+JysnICAgICAgICA8ZGl2IGNsYXNzPVwic2Nyb2xsLWVsZW1lbnRfaW5uZXIgc2Nyb2xsLWVsZW1lbnRfdHJhY2tcIj4nKycgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2Nyb2xsLWVsZW1lbnRfaW5uZXItYm90dG9tXCI+PC9kaXY+JytcIiAgICAgICAgPC9kaXY+XCIrXCIgICAgPC9kaXY+XCIrJyAgICA8ZGl2IGNsYXNzPVwic2Nyb2xsLWJhclwiPicrJyAgICAgICAgPGRpdiBjbGFzcz1cInNjcm9sbC1iYXJfYm9keVwiPicrJyAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzY3JvbGwtYmFyX2JvZHktaW5uZXJcIj48L2Rpdj4nK1wiICAgICAgICA8L2Rpdj5cIisnICAgICAgICA8ZGl2IGNsYXNzPVwic2Nyb2xsLWJhcl9ib3R0b21cIj48L2Rpdj4nKycgICAgICAgIDxkaXYgY2xhc3M9XCJzY3JvbGwtYmFyX2NlbnRlclwiPjwvZGl2PicrXCIgICAgPC9kaXY+XCIrXCI8L2Rpdj5cIixzaW1wbGU6JzxkaXYgY2xhc3M9XCJzY3JvbGwtZWxlbWVudF9vdXRlclwiPicrJyAgICA8ZGl2IGNsYXNzPVwic2Nyb2xsLWVsZW1lbnRfc2l6ZVwiPjwvZGl2PicrJyAgICA8ZGl2IGNsYXNzPVwic2Nyb2xsLWVsZW1lbnRfdHJhY2tcIj48L2Rpdj4nKycgICAgPGRpdiBjbGFzcz1cInNjcm9sbC1iYXJcIj48L2Rpdj4nK1wiPC9kaXY+XCJ9O3ZhciBpPXJbdGhpcy5vcHRpb25zLnR5cGVdP3RoaXMub3B0aW9ucy50eXBlOlwiYWR2YW5jZWRcIjtpZihuKXtpZih0eXBlb2Ygbj09XCJzdHJpbmdcIil7bj1lKG4pLmFwcGVuZFRvKHRoaXMud3JhcHBlcil9ZWxzZXtuPWUobil9fWVsc2V7bj1lKFwiPGRpdj5cIikuYWRkQ2xhc3MoXCJzY3JvbGwtZWxlbWVudFwiKS5odG1sKHJbaV0pLmFwcGVuZFRvKHRoaXMud3JhcHBlcil9aWYodGhpcy5vcHRpb25zLnNob3dBcnJvd3Mpe24uYWRkQ2xhc3MoXCJzY3JvbGwtZWxlbWVudF9hcnJvd3NfdmlzaWJsZVwiKX1yZXR1cm4gbi5hZGRDbGFzcyhcInNjcm9sbC1cIit0KX0saW5pdDpmdW5jdGlvbihuKXt2YXIgcj10aGlzO3ZhciB1PXRoaXMuY29udGFpbmVyO3ZhciBhPXRoaXMuY29udGFpbmVyV3JhcHBlcnx8dTt2YXIgZj1lLmV4dGVuZCh0aGlzLm9wdGlvbnMsbnx8e30pO3ZhciBsPXt4OnRoaXMuc2Nyb2xseCx5OnRoaXMuc2Nyb2xseX07dmFyIGM9dGhpcy53cmFwcGVyO3ZhciBoPXtzY3JvbGxMZWZ0OnUuc2Nyb2xsTGVmdCgpLHNjcm9sbFRvcDp1LnNjcm9sbFRvcCgpfTtpZihvLm1vYmlsZSYmZi5pZ25vcmVNb2JpbGV8fG8ub3ZlcmxheSYmZi5pZ25vcmVPdmVybGF5fHxvLm1hY29zeCYmIW8ud2Via2l0KXtyZXR1cm4gZmFsc2V9aWYoIWMpe3RoaXMud3JhcHBlcj1jPWUoXCI8ZGl2PlwiKS5hZGRDbGFzcyhcInNjcm9sbC13cmFwcGVyXCIpLmFkZENsYXNzKHUuYXR0cihcImNsYXNzXCIpKS5jc3MoXCJwb3NpdGlvblwiLHUuY3NzKFwicG9zaXRpb25cIik9PVwiYWJzb2x1dGVcIj9cImFic29sdXRlXCI6XCJyZWxhdGl2ZVwiKS5pbnNlcnRCZWZvcmUodSkuYXBwZW5kKHUpO2lmKHUuaXMoXCJ0ZXh0YXJlYVwiKSl7dGhpcy5jb250YWluZXJXcmFwcGVyPWE9ZShcIjxkaXY+XCIpLmluc2VydEJlZm9yZSh1KS5hcHBlbmQodSk7Yy5hZGRDbGFzcyhcInNjcm9sbC10ZXh0YXJlYVwiKX1hLmFkZENsYXNzKFwic2Nyb2xsLWNvbnRlbnRcIikuY3NzKHtoZWlnaHQ6XCJcIixcIm1hcmdpbi1ib3R0b21cIjpvLnNjcm9sbC5oZWlnaHQqLTErcyxcIm1hcmdpbi1yaWdodFwiOm8uc2Nyb2xsLndpZHRoKi0xK3N9KTt1Lm9uKFwic2Nyb2xsLnNjcm9sbGJhclwiLGZ1bmN0aW9uKHQpe2lmKGUuaXNGdW5jdGlvbihmLm9uU2Nyb2xsKSl7Zi5vblNjcm9sbC5jYWxsKHIse21heFNjcm9sbDpsLnkubWF4U2Nyb2xsT2Zmc2V0LHNjcm9sbDp1LnNjcm9sbFRvcCgpLHNpemU6bC55LnNpemUsdmlzaWJsZTpsLnkudmlzaWJsZX0se21heFNjcm9sbDpsLngubWF4U2Nyb2xsT2Zmc2V0LHNjcm9sbDp1LnNjcm9sbExlZnQoKSxzaXplOmwueC5zaXplLHZpc2libGU6bC54LnZpc2libGV9KX1sLnguaXNWaXNpYmxlJiZsLnguc2Nyb2xsZXIuY3NzKFwibGVmdFwiLHUuc2Nyb2xsTGVmdCgpKmwueC5reCtzKTtsLnkuaXNWaXNpYmxlJiZsLnkuc2Nyb2xsZXIuY3NzKFwidG9wXCIsdS5zY3JvbGxUb3AoKSpsLnkua3grcyl9KTtjLm9uKFwic2Nyb2xsXCIsZnVuY3Rpb24oKXtjLnNjcm9sbFRvcCgwKS5zY3JvbGxMZWZ0KDApfSk7aWYoZi5kaXNhYmxlQm9keVNjcm9sbCl7dmFyIGQ9ZnVuY3Rpb24oZSl7dihlKT9sLnkuaXNWaXNpYmxlJiZsLnkubW91c2V3aGVlbChlKTpsLnguaXNWaXNpYmxlJiZsLngubW91c2V3aGVlbChlKX07Yy5vbih7XCJNb3pNb3VzZVBpeGVsU2Nyb2xsLnNjcm9sbGJhclwiOmQsXCJtb3VzZXdoZWVsLnNjcm9sbGJhclwiOmR9KTtpZihvLm1vYmlsZSl7Yy5vbihcInRvdWNoc3RhcnQuc2Nyb2xsYmFyXCIsZnVuY3Rpb24obil7dmFyIHI9bi5vcmlnaW5hbEV2ZW50LnRvdWNoZXMmJm4ub3JpZ2luYWxFdmVudC50b3VjaGVzWzBdfHxuO3ZhciBpPXtwYWdlWDpyLnBhZ2VYLHBhZ2VZOnIucGFnZVl9O3ZhciBzPXtsZWZ0OnUuc2Nyb2xsTGVmdCgpLHRvcDp1LnNjcm9sbFRvcCgpfTtlKHQpLm9uKHtcInRvdWNobW92ZS5zY3JvbGxiYXJcIjpmdW5jdGlvbihlKXt2YXIgdD1lLm9yaWdpbmFsRXZlbnQudGFyZ2V0VG91Y2hlcyYmZS5vcmlnaW5hbEV2ZW50LnRhcmdldFRvdWNoZXNbMF18fGU7dS5zY3JvbGxMZWZ0KHMubGVmdCtpLnBhZ2VYLXQucGFnZVgpO3Uuc2Nyb2xsVG9wKHMudG9wK2kucGFnZVktdC5wYWdlWSk7ZS5wcmV2ZW50RGVmYXVsdCgpfSxcInRvdWNoZW5kLnNjcm9sbGJhclwiOmZ1bmN0aW9uKCl7ZSh0KS5vZmYoXCIuc2Nyb2xsYmFyXCIpfX0pfSl9fWlmKGUuaXNGdW5jdGlvbihmLm9uSW5pdCkpZi5vbkluaXQuYXBwbHkodGhpcyxbdV0pfWVsc2V7YS5jc3Moe2hlaWdodDpcIlwiLFwibWFyZ2luLWJvdHRvbVwiOm8uc2Nyb2xsLmhlaWdodCotMStzLFwibWFyZ2luLXJpZ2h0XCI6by5zY3JvbGwud2lkdGgqLTErc30pfWUuZWFjaChsLGZ1bmN0aW9uKG4scyl7dmFyIG89bnVsbDt2YXIgYT0xO3ZhciBjPW49PVwieFwiP1wic2Nyb2xsTGVmdFwiOlwic2Nyb2xsVG9wXCI7dmFyIGg9Zi5zY3JvbGxTdGVwO3ZhciBkPWZ1bmN0aW9uKCl7dmFyIGU9dVtjXSgpO3VbY10oZStoKTtpZihhPT0xJiZlK2g+PW0pZT11W2NdKCk7aWYoYT09LTEmJmUraDw9bSllPXVbY10oKTtpZih1W2NdKCk9PWUmJm8pe28oKX19O3ZhciBtPTA7aWYoIXMuc2Nyb2xsYmFyKXtzLnNjcm9sbGJhcj1yLmdldFNjcm9sbGJhcihuKTtzLnNjcm9sbGVyPXMuc2Nyb2xsYmFyLmZpbmQoXCIuc2Nyb2xsLWJhclwiKTtzLm1vdXNld2hlZWw9ZnVuY3Rpb24oZSl7aWYoIXMuaXNWaXNpYmxlfHxuPT1cInhcIiYmdihlKSl7cmV0dXJuIHRydWV9aWYobj09XCJ5XCImJiF2KGUpKXtsLngubW91c2V3aGVlbChlKTtyZXR1cm4gdHJ1ZX12YXIgdD1lLm9yaWdpbmFsRXZlbnQud2hlZWxEZWx0YSotMXx8ZS5vcmlnaW5hbEV2ZW50LmRldGFpbDt2YXIgaT1zLnNpemUtcy52aXNpYmxlLXMub2Zmc2V0O2lmKCEobTw9MCYmdDwwfHxtPj1pJiZ0PjApKXttPW0rdDtpZihtPDApbT0wO2lmKG0+aSltPWk7ci5zY3JvbGxUbz1yLnNjcm9sbFRvfHx7fTtyLnNjcm9sbFRvW2NdPW07c2V0VGltZW91dChmdW5jdGlvbigpe2lmKHIuc2Nyb2xsVG8pe3Uuc3RvcCgpLmFuaW1hdGUoci5zY3JvbGxUbywyNDAsXCJsaW5lYXJcIixmdW5jdGlvbigpe209dVtjXSgpfSk7ci5zY3JvbGxUbz1udWxsfX0sMSl9ZS5wcmV2ZW50RGVmYXVsdCgpO3JldHVybiBmYWxzZX07cy5zY3JvbGxiYXIub24oe1wiTW96TW91c2VQaXhlbFNjcm9sbC5zY3JvbGxiYXJcIjpzLm1vdXNld2hlZWwsXCJtb3VzZXdoZWVsLnNjcm9sbGJhclwiOnMubW91c2V3aGVlbCxcIm1vdXNlZW50ZXIuc2Nyb2xsYmFyXCI6ZnVuY3Rpb24oKXttPXVbY10oKX19KTtzLnNjcm9sbGJhci5maW5kKFwiLnNjcm9sbC1hcnJvdywgLnNjcm9sbC1lbGVtZW50X3RyYWNrXCIpLm9uKFwibW91c2Vkb3duLnNjcm9sbGJhclwiLGZ1bmN0aW9uKHQpe2lmKHQud2hpY2ghPWkpcmV0dXJuIHRydWU7YT0xO3ZhciBsPXtldmVudE9mZnNldDp0W249PVwieFwiP1wicGFnZVhcIjpcInBhZ2VZXCJdLG1heFNjcm9sbFZhbHVlOnMuc2l6ZS1zLnZpc2libGUtcy5vZmZzZXQsc2Nyb2xsYmFyT2Zmc2V0OnMuc2Nyb2xsZXIub2Zmc2V0KClbbj09XCJ4XCI/XCJsZWZ0XCI6XCJ0b3BcIl0sc2Nyb2xsYmFyU2l6ZTpzLnNjcm9sbGVyW249PVwieFwiP1wib3V0ZXJXaWR0aFwiOlwib3V0ZXJIZWlnaHRcIl0oKX07dmFyIHY9MCxnPTA7aWYoZSh0aGlzKS5oYXNDbGFzcyhcInNjcm9sbC1hcnJvd1wiKSl7YT1lKHRoaXMpLmhhc0NsYXNzKFwic2Nyb2xsLWFycm93X21vcmVcIik/MTotMTtoPWYuc2Nyb2xsU3RlcCphO209YT4wP2wubWF4U2Nyb2xsVmFsdWU6MH1lbHNle2E9bC5ldmVudE9mZnNldD5sLnNjcm9sbGJhck9mZnNldCtsLnNjcm9sbGJhclNpemU/MTpsLmV2ZW50T2Zmc2V0PGwuc2Nyb2xsYmFyT2Zmc2V0Py0xOjA7aD1NYXRoLnJvdW5kKHMudmlzaWJsZSouNzUpKmE7bT1sLmV2ZW50T2Zmc2V0LWwuc2Nyb2xsYmFyT2Zmc2V0LShmLnN0ZXBTY3JvbGxpbmc/YT09MT9sLnNjcm9sbGJhclNpemU6MDpNYXRoLnJvdW5kKGwuc2Nyb2xsYmFyU2l6ZS8yKSk7bT11W2NdKCkrbS9zLmt4fXIuc2Nyb2xsVG89ci5zY3JvbGxUb3x8e307ci5zY3JvbGxUb1tjXT1mLnN0ZXBTY3JvbGxpbmc/dVtjXSgpK2g6bTtpZihmLnN0ZXBTY3JvbGxpbmcpe289ZnVuY3Rpb24oKXttPXVbY10oKTtjbGVhckludGVydmFsKGcpO2NsZWFyVGltZW91dCh2KTt2PTA7Zz0wfTt2PXNldFRpbWVvdXQoZnVuY3Rpb24oKXtnPXNldEludGVydmFsKGQsNDApfSxmLmR1cmF0aW9uKzEwMCl9c2V0VGltZW91dChmdW5jdGlvbigpe2lmKHIuc2Nyb2xsVG8pe3UuYW5pbWF0ZShyLnNjcm9sbFRvLGYuZHVyYXRpb24pO3Iuc2Nyb2xsVG89bnVsbH19LDEpO3JldHVybiBwKG8sdCl9KTtzLnNjcm9sbGVyLm9uKFwibW91c2Vkb3duLnNjcm9sbGJhclwiLGZ1bmN0aW9uKHIpe2lmKHIud2hpY2ghPWkpcmV0dXJuIHRydWU7dmFyIG89cltuPT1cInhcIj9cInBhZ2VYXCI6XCJwYWdlWVwiXTt2YXIgYT11W2NdKCk7cy5zY3JvbGxiYXIuYWRkQ2xhc3MoXCJzY3JvbGwtZHJhZ2dhYmxlXCIpO2UodCkub24oXCJtb3VzZW1vdmUuc2Nyb2xsYmFyXCIsZnVuY3Rpb24oZSl7dmFyIHQ9cGFyc2VJbnQoKGVbbj09XCJ4XCI/XCJwYWdlWFwiOlwicGFnZVlcIl0tbykvcy5reCwxMCk7dVtjXShhK3QpfSk7cmV0dXJuIHAoZnVuY3Rpb24oKXtzLnNjcm9sbGJhci5yZW1vdmVDbGFzcyhcInNjcm9sbC1kcmFnZ2FibGVcIik7bT11W2NdKCl9LHIpfSl9fSk7ZS5lYWNoKGwsZnVuY3Rpb24oZSx0KXt2YXIgbj1cInNjcm9sbC1zY3JvbGxcIitlK1wiX3Zpc2libGVcIjt2YXIgcj1lPT1cInhcIj9sLnk6bC54O3Quc2Nyb2xsYmFyLnJlbW92ZUNsYXNzKG4pO3Iuc2Nyb2xsYmFyLnJlbW92ZUNsYXNzKG4pO2EucmVtb3ZlQ2xhc3Mobil9KTtlLmVhY2gobCxmdW5jdGlvbih0LG4pe2UuZXh0ZW5kKG4sdD09XCJ4XCI/e29mZnNldDpwYXJzZUludCh1LmNzcyhcImxlZnRcIiksMTApfHwwLHNpemU6dS5wcm9wKFwic2Nyb2xsV2lkdGhcIiksdmlzaWJsZTpjLndpZHRoKCl9OntvZmZzZXQ6cGFyc2VJbnQodS5jc3MoXCJ0b3BcIiksMTApfHwwLHNpemU6dS5wcm9wKFwic2Nyb2xsSGVpZ2h0XCIpLHZpc2libGU6Yy5oZWlnaHQoKX0pfSk7dmFyIG09ZnVuY3Rpb24odCxuKXt2YXIgcj1cInNjcm9sbC1zY3JvbGxcIit0K1wiX3Zpc2libGVcIjt2YXIgaT10PT1cInhcIj9sLnk6bC54O3ZhciBmPXBhcnNlSW50KHUuY3NzKHQ9PVwieFwiP1wibGVmdFwiOlwidG9wXCIpLDEwKXx8MDt2YXIgaD1uLnNpemU7dmFyIHA9bi52aXNpYmxlK2Y7bi5pc1Zpc2libGU9aC1wPjE7aWYobi5pc1Zpc2libGUpe24uc2Nyb2xsYmFyLmFkZENsYXNzKHIpO2kuc2Nyb2xsYmFyLmFkZENsYXNzKHIpO2EuYWRkQ2xhc3Mocil9ZWxzZXtuLnNjcm9sbGJhci5yZW1vdmVDbGFzcyhyKTtpLnNjcm9sbGJhci5yZW1vdmVDbGFzcyhyKTthLnJlbW92ZUNsYXNzKHIpfWlmKHQ9PVwieVwiJiYobi5pc1Zpc2libGV8fG4uc2l6ZTxuLnZpc2libGUpKXthLmNzcyhcImhlaWdodFwiLHArby5zY3JvbGwuaGVpZ2h0K3MpfWlmKGwueC5zaXplIT11LnByb3AoXCJzY3JvbGxXaWR0aFwiKXx8bC55LnNpemUhPXUucHJvcChcInNjcm9sbEhlaWdodFwiKXx8bC54LnZpc2libGUhPWMud2lkdGgoKXx8bC55LnZpc2libGUhPWMuaGVpZ2h0KCl8fGwueC5vZmZzZXQhPShwYXJzZUludCh1LmNzcyhcImxlZnRcIiksMTApfHwwKXx8bC55Lm9mZnNldCE9KHBhcnNlSW50KHUuY3NzKFwidG9wXCIpLDEwKXx8MCkpe2UuZWFjaChsLGZ1bmN0aW9uKHQsbil7ZS5leHRlbmQobix0PT1cInhcIj97b2Zmc2V0OnBhcnNlSW50KHUuY3NzKFwibGVmdFwiKSwxMCl8fDAsc2l6ZTp1LnByb3AoXCJzY3JvbGxXaWR0aFwiKSx2aXNpYmxlOmMud2lkdGgoKX06e29mZnNldDpwYXJzZUludCh1LmNzcyhcInRvcFwiKSwxMCl8fDAsc2l6ZTp1LnByb3AoXCJzY3JvbGxIZWlnaHRcIiksdmlzaWJsZTpjLmhlaWdodCgpfSl9KTttKHQ9PVwieFwiP1wieVwiOlwieFwiLGkpfX07ZS5lYWNoKGwsbSk7aWYoZS5pc0Z1bmN0aW9uKGYub25VcGRhdGUpKWYub25VcGRhdGUuYXBwbHkodGhpcyxbdV0pO2UuZWFjaChsLGZ1bmN0aW9uKGUsdCl7dmFyIG49ZT09XCJ4XCI/XCJsZWZ0XCI6XCJ0b3BcIjt2YXIgcj1lPT1cInhcIj9cIm91dGVyV2lkdGhcIjpcIm91dGVySGVpZ2h0XCI7dmFyIGk9ZT09XCJ4XCI/XCJ3aWR0aFwiOlwiaGVpZ2h0XCI7dmFyIG89cGFyc2VJbnQodS5jc3MobiksMTApfHwwO3ZhciBhPXQuc2l6ZTt2YXIgbD10LnZpc2libGUrbzt2YXIgYz10LnNjcm9sbGJhci5maW5kKFwiLnNjcm9sbC1lbGVtZW50X3NpemVcIik7Yz1jW3JdKCkrKHBhcnNlSW50KGMuY3NzKG4pLDEwKXx8MCk7aWYoZi5hdXRvU2Nyb2xsU2l6ZSl7dC5zY3JvbGxiYXJTaXplPXBhcnNlSW50KGMqbC9hLDEwKTt0LnNjcm9sbGVyLmNzcyhpLHQuc2Nyb2xsYmFyU2l6ZStzKX10LnNjcm9sbGJhclNpemU9dC5zY3JvbGxlcltyXSgpO3Qua3g9KGMtdC5zY3JvbGxiYXJTaXplKS8oYS1sKXx8MTt0Lm1heFNjcm9sbE9mZnNldD1hLWx9KTt1LnNjcm9sbExlZnQoaC5zY3JvbGxMZWZ0KS5zY3JvbGxUb3AoaC5zY3JvbGxUb3ApLnRyaWdnZXIoXCJzY3JvbGxcIil9fTtlLmZuLnNjcm9sbGJhcj1mdW5jdGlvbih0LG4pe3ZhciByPXRoaXM7aWYodD09PVwiZ2V0XCIpcj1udWxsO3RoaXMuZWFjaChmdW5jdGlvbigpe3ZhciBpPWUodGhpcyk7aWYoaS5oYXNDbGFzcyhcInNjcm9sbC13cmFwcGVyXCIpfHxpLmdldCgwKS5ub2RlTmFtZT09XCJib2R5XCIpe3JldHVybiB0cnVlfXZhciBzPWkuZGF0YShcInNjcm9sbGJhclwiKTtpZihzKXtpZih0PT09XCJnZXRcIil7cj1zO3JldHVybiBmYWxzZX12YXIgdT10eXBlb2YgdD09XCJzdHJpbmdcIiYmc1t0XT90OlwiaW5pdFwiO3NbdV0uYXBwbHkocyxlLmlzQXJyYXkobik/bjpbXSk7aWYodD09PVwiZGVzdHJveVwiKXtpLnJlbW92ZURhdGEoXCJzY3JvbGxiYXJcIik7d2hpbGUoZS5pbkFycmF5KHMsby5zY3JvbGxzKT49MClvLnNjcm9sbHMuc3BsaWNlKGUuaW5BcnJheShzLG8uc2Nyb2xscyksMSl9fWVsc2V7aWYodHlwZW9mIHQhPVwic3RyaW5nXCIpe3M9bmV3IGEoaSx0KTtpLmRhdGEoXCJzY3JvbGxiYXJcIixzKTtvLnNjcm9sbHMucHVzaChzKX19cmV0dXJuIHRydWV9KTtyZXR1cm4gcn07ZS5mbi5zY3JvbGxiYXIub3B0aW9ucz11O2lmKG4uYW5ndWxhcil7KGZ1bmN0aW9uKGUpe3ZhciB0PWUubW9kdWxlKFwialF1ZXJ5U2Nyb2xsYmFyXCIsW10pO3QuZGlyZWN0aXZlKFwianF1ZXJ5U2Nyb2xsYmFyXCIsZnVuY3Rpb24oKXtyZXR1cm57bGluazpmdW5jdGlvbihlLHQpe3Quc2Nyb2xsYmFyKGUub3B0aW9ucykub24oXCIkZGVzdHJveVwiLGZ1bmN0aW9uKCl7dC5zY3JvbGxiYXIoXCJkZXN0cm95XCIpfSl9LHJlc3RyaW5nOlwiQUNcIixzY29wZTp7b3B0aW9uczpcIj1qcXVlcnlTY3JvbGxiYXJcIn19fSl9KShuLmFuZ3VsYXIpfXZhciBmPTAsbD0wO3ZhciBjPWZ1bmN0aW9uKGUpe3ZhciB0LG4saSxzLHUsYSxoO2Zvcih0PTA7dDxvLnNjcm9sbHMubGVuZ3RoO3QrKyl7cz1vLnNjcm9sbHNbdF07bj1zLmNvbnRhaW5lcjtpPXMub3B0aW9uczt1PXMud3JhcHBlcjthPXMuc2Nyb2xseDtoPXMuc2Nyb2xseTtpZihlfHxpLmF1dG9VcGRhdGUmJnUmJnUuaXMoXCI6dmlzaWJsZVwiKSYmKG4ucHJvcChcInNjcm9sbFdpZHRoXCIpIT1hLnNpemV8fG4ucHJvcChcInNjcm9sbEhlaWdodFwiKSE9aC5zaXplfHx1LndpZHRoKCkhPWEudmlzaWJsZXx8dS5oZWlnaHQoKSE9aC52aXNpYmxlKSl7cy5pbml0KCk7aWYocil7by5sb2coe3Njcm9sbEhlaWdodDpuLnByb3AoXCJzY3JvbGxIZWlnaHRcIikrXCI6XCIrcy5zY3JvbGx5LnNpemUsc2Nyb2xsV2lkdGg6bi5wcm9wKFwic2Nyb2xsV2lkdGhcIikrXCI6XCIrcy5zY3JvbGx4LnNpemUsdmlzaWJsZUhlaWdodDp1LmhlaWdodCgpK1wiOlwiK3Muc2Nyb2xseS52aXNpYmxlLHZpc2libGVXaWR0aDp1LndpZHRoKCkrXCI6XCIrcy5zY3JvbGx4LnZpc2libGV9LHRydWUpO2wrK319fWlmKHImJmw+MTApe28ubG9nKFwiU2Nyb2xsIHVwZGF0ZXMgZXhjZWVkIDEwXCIpO2M9ZnVuY3Rpb24oKXt9fWVsc2V7Y2xlYXJUaW1lb3V0KGYpO2Y9c2V0VGltZW91dChjLDMwMCl9fX0pKGpRdWVyeSxkb2N1bWVudCx3aW5kb3cpOyIsIi8vIFN0b3JhZ2UgY2FjaGUuXHJcbnZhciBjYWNoZSA9IHt9O1xyXG4vLyBUaGUgc3RvcmUgaGFuZGxpbmcgZXhwaXJhdGlvbiBvZiBkYXRhLlxyXG52YXIgZXhwaXJlc1N0b3JlID0gbmV3IFN0b3JlKHtcclxuXHRuYW1lc3BhY2U6ICdfX3N0b3JhZ2Utd3JhcHBlcjpleHBpcmVzJ1xyXG59KTtcclxuXHJcbi8qKlxyXG4gKiBTdG9yYWdlIHdyYXBwZXIgZm9yIG1ha2luZyByb3V0aW5lIHN0b3JhZ2UgY2FsbHMgc3VwZXIgZWFzeS5cclxuICogQGNsYXNzIFN0b3JlXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdICAgICAgICAgICAgICAgICAgICAgVGhlIG9wdGlvbnMgZm9yIHRoZSBzdG9yZS4gT3B0aW9ucyBub3Qgb3ZlcnJpZGRlbiB3aWxsIHVzZSB0aGUgZGVmYXVsdHMuXHJcbiAqIEBwYXJhbSB7bWl4ZWR9ICBbb3B0aW9ucy5uYW1lc3BhY2U9JyddICAgICAgICBTZWUge3sjY3Jvc3NMaW5rIFwiU3RvcmUvc2V0TmFtZXNwYWNlXCJ9fVN0b3JlI3NldE5hbWVzcGFjZXt7L2Nyb3NzTGlua319XHJcbiAqIEBwYXJhbSB7bWl4ZWR9ICBbb3B0aW9ucy5zdG9yYWdlVHlwZT0nbG9jYWwnXSBTZWUge3sjY3Jvc3NMaW5rIFwiU3RvcmUvc2V0U3RvcmFnZVR5cGVcIn19U3RvcmUjc2V0U3RvcmFnZVR5cGV7ey9jcm9zc0xpbmt9fVxyXG4gKi9cclxuZnVuY3Rpb24gU3RvcmUob3B0aW9ucykge1xyXG5cdHZhciBzZXR0aW5ncyA9IHtcclxuXHRcdG5hbWVzcGFjZTogJycsXHJcblx0XHRzdG9yYWdlVHlwZTogJ2xvY2FsJ1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldHMgdGhlIHN0b3JhZ2UgbmFtZXNwYWNlLlxyXG5cdCAqIEBtZXRob2Qgc2V0TmFtZXNwYWNlXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8ZmFsc2V8bnVsbH0gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2UgdG8gd29yayB1bmRlci4gVG8gdXNlIG5vIG5hbWVzcGFjZSAoZS5nLiBnbG9iYWwgbmFtZXNwYWNlKSwgcGFzcyBpbiBgZmFsc2VgIG9yIGBudWxsYCBvciBhbiBlbXB0eSBzdHJpbmcuXHJcblx0ICovXHJcblx0dGhpcy5zZXROYW1lc3BhY2UgPSBmdW5jdGlvbiAobmFtZXNwYWNlKSB7XHJcblx0XHR2YXIgdmFsaWROYW1lc3BhY2UgPSAvXltcXHctOl0rJC87XHJcblx0XHQvLyBObyBuYW1lc3BhY2UuXHJcblx0XHRpZiAobmFtZXNwYWNlID09PSBmYWxzZSB8fCBuYW1lc3BhY2UgPT0gbnVsbCB8fCBuYW1lc3BhY2UgPT09ICcnKSB7XHJcblx0XHRcdHNldHRpbmdzLm5hbWVzcGFjZSA9ICcnO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRpZiAodHlwZW9mIG5hbWVzcGFjZSAhPT0gJ3N0cmluZycgfHwgIXZhbGlkTmFtZXNwYWNlLnRlc3QobmFtZXNwYWNlKSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbmFtZXNwYWNlLicpO1xyXG5cdFx0fVxyXG5cdFx0c2V0dGluZ3MubmFtZXNwYWNlID0gbmFtZXNwYWNlO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldHMgdGhlIGN1cnJlbnQgc3RvcmFnZSBuYW1lc3BhY2UuXHJcblx0ICogQG1ldGhvZCBnZXROYW1lc3BhY2VcclxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBjdXJyZW50IG5hbWVzcGFjZS5cclxuXHQgKi9cclxuXHR0aGlzLmdldE5hbWVzcGFjZSA9IGZ1bmN0aW9uIChpbmNsdWRlU2VwYXJhdG9yKSB7XHJcblx0XHRpZiAoaW5jbHVkZVNlcGFyYXRvciAmJiBzZXR0aW5ncy5uYW1lc3BhY2UgIT09ICcnKSB7XHJcblx0XHRcdHJldHVybiBzZXR0aW5ncy5uYW1lc3BhY2UgKyAnOic7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gc2V0dGluZ3MubmFtZXNwYWNlO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogU2V0cyB0aGUgdHlwZSBvZiBzdG9yYWdlIHRvIHVzZS5cclxuXHQgKiBAbWV0aG9kIHNldFN0b3JhZ2VUeXBlXHJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVGhlIHR5cGUgb2Ygc3RvcmFnZSB0byB1c2UuIFVzZSBgc2Vzc2lvbmAgZm9yIGBzZXNzaW9uU3RvcmFnZWAgYW5kIGBsb2NhbGAgZm9yIGBsb2NhbFN0b3JhZ2VgLlxyXG5cdCAqL1xyXG5cdHRoaXMuc2V0U3RvcmFnZVR5cGUgPSBmdW5jdGlvbiAodHlwZSkge1xyXG5cdFx0aWYgKFsnc2Vzc2lvbicsICdsb2NhbCddLmluZGV4T2YodHlwZSkgPCAwKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdG9yYWdlIHR5cGUuJyk7XHJcblx0XHR9XHJcblx0XHRzZXR0aW5ncy5zdG9yYWdlVHlwZSA9IHR5cGU7XHJcblx0fTtcclxuXHQvKipcclxuXHQgKiBHZXQgdGhlIHR5cGUgb2Ygc3RvcmFnZSBiZWluZyB1c2VkLlxyXG5cdCAqIEBtZXRob2QgZ2V0U3RvcmFnZVR5cGVcclxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSB0eXBlIG9mIHN0b3JhZ2UgYmVpbmcgdXNlZC5cclxuXHQgKi9cclxuXHR0aGlzLmdldFN0b3JhZ2VUeXBlID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0cmV0dXJuIHNldHRpbmdzLnN0b3JhZ2VUeXBlO1xyXG5cdH07XHJcblxyXG5cdC8vIE92ZXJyaWRlIGRlZmF1bHQgc2V0dGluZ3MuXHJcblx0aWYgKG9wdGlvbnMpIHtcclxuXHRcdGZvciAodmFyIGtleSBpbiBvcHRpb25zKSB7XHJcblx0XHRcdHN3aXRjaCAoa2V5KSB7XHJcblx0XHRcdFx0Y2FzZSAnbmFtZXNwYWNlJzpcclxuXHRcdFx0XHRcdHRoaXMuc2V0TmFtZXNwYWNlKG9wdGlvbnNba2V5XSk7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRjYXNlICdzdG9yYWdlVHlwZSc6XHJcblx0XHRcdFx0XHR0aGlzLnNldFN0b3JhZ2VUeXBlKG9wdGlvbnNba2V5XSk7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIGFjdHVhbCBoYW5kbGVyIHRvIHVzZVxyXG4gKiBAbWV0aG9kIGdldFN0b3JhZ2VIYW5kbGVyXHJcbiAqIEByZXR1cm4ge21peGVkfSBUaGUgc3RvcmFnZSBoYW5kbGVyLlxyXG4gKi9cclxuU3RvcmUucHJvdG90eXBlLmdldFN0b3JhZ2VIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xyXG5cdHZhciBoYW5kbGVycyA9IHtcclxuXHRcdCdsb2NhbCc6IGxvY2FsU3RvcmFnZSxcclxuXHRcdCdzZXNzaW9uJzogc2Vzc2lvblN0b3JhZ2VcclxuXHR9O1xyXG5cdHJldHVybiBoYW5kbGVyc1t0aGlzLmdldFN0b3JhZ2VUeXBlKCldO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgZnVsbCBzdG9yYWdlIG5hbWUgZm9yIGEga2V5LCBpbmNsdWRpbmcgdGhlIG5hbWVzcGFjZSwgaWYgYW55LlxyXG4gKiBAbWV0aG9kIGdldFN0b3JhZ2VLZXlcclxuICogQHBhcmFtICB7c3RyaW5nfSBrZXkgVGhlIHN0b3JhZ2Uga2V5IG5hbWUuXHJcbiAqIEByZXR1cm4ge3N0cmluZ30gICAgIFRoZSBmdWxsIHN0b3JhZ2UgbmFtZSB0aGF0IGlzIHVzZWQgYnkgdGhlIHN0b3JhZ2UgbWV0aG9kcy5cclxuICovXHJcblN0b3JlLnByb3RvdHlwZS5nZXRTdG9yYWdlS2V5ID0gZnVuY3Rpb24gKGtleSkge1xyXG5cdGlmICgha2V5IHx8IHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnIHx8IGtleS5sZW5ndGggPCAxKSB7XHJcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ0tleSBtdXN0IGJlIGEgc3RyaW5nLicpO1xyXG5cdH1cclxuXHRyZXR1cm4gdGhpcy5nZXROYW1lc3BhY2UodHJ1ZSkgKyBrZXk7XHJcbn07XHJcblxyXG4vKipcclxuICogR2V0cyBhIHN0b3JhZ2UgaXRlbSBmcm9tIHRoZSBjdXJyZW50IG5hbWVzcGFjZS5cclxuICogQG1ldGhvZCBnZXRcclxuICogQHBhcmFtICB7c3RyaW5nfSBrZXkgICAgICAgICAgVGhlIGtleSB0aGF0IHRoZSBkYXRhIGNhbiBiZSBhY2Nlc3NlZCB1bmRlci5cclxuICogQHBhcmFtICB7bWl4ZWR9ICBkZWZhdWx0VmFsdWUgVGhlIGRlZmF1bHQgdmFsdWUgdG8gcmV0dXJuIGluIGNhc2UgdGhlIHN0b3JhZ2UgdmFsdWUgaXMgbm90IHNldCBvciBgbnVsbGAuXHJcbiAqIEByZXR1cm4ge21peGVkfSAgICAgICAgICAgICAgIFRoZSBkYXRhIGZvciB0aGUgc3RvcmFnZS5cclxuICovXHJcblN0b3JlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5LCBkZWZhdWx0VmFsdWUpIHtcclxuXHQvLyBQcmV2ZW50IHJlY3Vyc2lvbi4gT25seSBjaGVjayBleHBpcmUgZGF0ZSBpZiBpdCBpc24ndCBjYWxsZWQgZnJvbSBgZXhwaXJlc1N0b3JlYC5cclxuXHRpZiAodGhpcyAhPT0gZXhwaXJlc1N0b3JlKSB7XHJcblx0XHQvLyBDaGVjayBpZiBrZXkgaXMgZXhwaXJlZC5cclxuXHRcdHZhciBleHBpcmVEYXRlID0gZXhwaXJlc1N0b3JlLmdldCh0aGlzLmdldFN0b3JhZ2VLZXkoa2V5KSk7XHJcblx0XHRpZiAoZXhwaXJlRGF0ZSAhPT0gbnVsbCAmJiBleHBpcmVEYXRlLmdldFRpbWUoKSA8IERhdGUubm93KCkpIHtcclxuXHRcdFx0Ly8gRXhwaXJlZCwgcmVtb3ZlIGl0LlxyXG5cdFx0XHR0aGlzLnJlbW92ZShrZXkpO1xyXG5cdFx0XHRleHBpcmVzU3RvcmUucmVtb3ZlKHRoaXMuZ2V0U3RvcmFnZUtleShrZXkpKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIENhY2hlZCwgcmVhZCBmcm9tIG1lbW9yeS5cclxuXHRpZiAoY2FjaGVbdGhpcy5nZXRTdG9yYWdlS2V5KGtleSldICE9IG51bGwpIHtcclxuXHRcdHJldHVybiBjYWNoZVt0aGlzLmdldFN0b3JhZ2VLZXkoa2V5KV07XHJcblx0fVxyXG5cclxuXHR2YXIgdmFsID0gdGhpcy5nZXRTdG9yYWdlSGFuZGxlcigpLmdldEl0ZW0odGhpcy5nZXRTdG9yYWdlS2V5KGtleSkpO1xyXG5cclxuXHQvLyBWYWx1ZSBkb2Vzbid0IGV4aXN0IGFuZCB3ZSBoYXZlIGEgZGVmYXVsdCwgcmV0dXJuIGRlZmF1bHQuXHJcblx0aWYgKHZhbCA9PT0gbnVsbCAmJiB0eXBlb2YgZGVmYXVsdFZhbHVlICE9PSAndW5kZWZpbmVkJykge1xyXG5cdFx0cmV0dXJuIGRlZmF1bHRWYWx1ZTtcclxuXHR9XHJcblxyXG5cdC8vIE9ubHkgcHJlLXByb2Nlc3Mgc3RyaW5ncy5cclxuXHRpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcclxuXHRcdC8vIEhhbmRsZSBSZWdFeHBzLlxyXG5cdFx0aWYgKHZhbC5pbmRleE9mKCd+UmVnRXhwOicpID09PSAwKSB7XHJcblx0XHRcdHZhciBtYXRjaGVzID0gL15+UmVnRXhwOihbZ2ltXSo/KTooLiopLy5leGVjKHZhbCk7XHJcblx0XHRcdHZhbCA9IG5ldyBSZWdFeHAobWF0Y2hlc1syXSwgbWF0Y2hlc1sxXSk7XHJcblx0XHR9XHJcblx0XHQvLyBIYW5kbGUgRGF0ZXMuXHJcblx0XHRlbHNlIGlmICh2YWwuaW5kZXhPZignfkRhdGU6JykgPT09IDApIHtcclxuXHRcdFx0dmFsID0gbmV3IERhdGUodmFsLnJlcGxhY2UoL15+RGF0ZTovLCAnJykpO1xyXG5cdFx0fVxyXG5cdFx0Ly8gSGFuZGxlIG51bWJlcnMuXHJcblx0XHRlbHNlIGlmICh2YWwuaW5kZXhPZignfk51bWJlcjonKSA9PT0gMCkge1xyXG5cdFx0XHR2YWwgPSBwYXJzZUludCh2YWwucmVwbGFjZSgvXn5OdW1iZXI6LywgJycpLCAxMCk7XHJcblx0XHR9XHJcblx0XHQvLyBIYW5kbGUgYm9vbGVhbnMuXHJcblx0XHRlbHNlIGlmICh2YWwuaW5kZXhPZignfkJvb2xlYW46JykgPT09IDApIHtcclxuXHRcdFx0dmFsID0gdmFsLnJlcGxhY2UoL15+Qm9vbGVhbjovLCAnJykgPT09ICd0cnVlJztcclxuXHRcdH1cclxuXHRcdC8vIEhhbmRsZSBvYmplY3RzLlxyXG5cdFx0ZWxzZSBpZiAodmFsLmluZGV4T2YoJ35KU09OOicpID09PSAwKSB7XHJcblx0XHRcdHZhbCA9IHZhbC5yZXBsYWNlKC9efkpTT046LywgJycpO1xyXG5cdFx0XHQvLyBUcnkgcGFyc2luZyBpdC5cclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHR2YWwgPSBKU09OLnBhcnNlKHZhbCk7XHJcblx0XHRcdH1cclxuXHRcdFx0Ly8gUGFyc2luZyB3ZW50IHdyb25nIChpbnZhbGlkIEpTT04pLCByZXR1cm4gZGVmYXVsdCBvciBudWxsLlxyXG5cdFx0XHRjYXRjaCAoZSkge1xyXG5cdFx0XHRcdGlmICh0eXBlb2YgZGVmYXVsdFZhbHVlICE9PSAndW5kZWZpbmVkJykge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGRlZmF1bHRWYWx1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIG51bGw7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIFJldHVybiBpdC5cclxuXHRjYWNoZVt0aGlzLmdldFN0b3JhZ2VLZXkoa2V5KV0gPSB2YWw7XHJcblx0cmV0dXJuIHZhbDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBTZXRzIGEgc3RvcmFnZSBpdGVtIG9uIHRoZSBjdXJyZW50IG5hbWVzcGFjZS5cclxuICogQG1ldGhvZCBzZXRcclxuICogQHBhcmFtIHtzdHJpbmd9ICAgICAga2V5ICAgICAgIFRoZSBrZXkgdGhhdCB0aGUgZGF0YSBjYW4gYmUgYWNjZXNzZWQgdW5kZXIuXHJcbiAqIEBwYXJhbSB7bWl4ZWR9ICAgICAgIHZhbCAgICAgICBUaGUgdmFsdWUgdG8gc3RvcmUuIE1heSBiZSB0aGUgZm9sbG93aW5nIHR5cGVzIG9mIGRhdGE6IGBSZWdFeHBgLCBgRGF0ZWAsIGBPYmplY3RgLCBgU3RyaW5nYCwgYEJvb2xlYW5gLCBgTnVtYmVyYFxyXG4gKiBAcGFyYW0ge0RhdGV8bnVtYmVyfSBbZXhwaXJlc10gVGhlIGRhdGUgaW4gdGhlIGZ1dHVyZSB0byBleHBpcmUsIG9yIHJlbGF0aXZlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgZnJvbSBgRGF0ZSNub3dgIHRvIGV4cGlyZS5cclxuICpcclxuICogTm90ZTogVGhpcyBjb252ZXJ0cyBzcGVjaWFsIGRhdGEgdHlwZXMgdGhhdCBub3JtYWxseSBjYW4ndCBiZSBzdG9yZWQgaW4gdGhlIGZvbGxvd2luZyB3YXk6XHJcbiAqIFxyXG4gKiAtIGBSZWdFeHBgOiBwcmVmaXhlZCB3aXRoIHR5cGUsIGZsYWdzIHN0b3JlZCwgYW5kIHNvdXJjZSBzdG9yZWQgYXMgc3RyaW5nLlxyXG4gKiAtIGBEYXRlYDogcHJlZml4ZWQgd2l0aCB0eXBlLCBzdG9yZWQgYXMgc3RyaW5nIHVzaW5nIGBEYXRlI3RvU3RyaW5nYC5cclxuICogLSBgT2JqZWN0YDogcHJlZml4ZWQgd2l0aCBcIkpTT05cIiBpbmRpY2F0b3IsIHN0b3JlZCBhcyBzdHJpbmcgdXNpbmcgYEpTT04jc3RyaW5naWZ5YC5cclxuICovXHJcblN0b3JlLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWwsIGV4cGlyZXMpIHtcclxuXHR2YXIgcGFyc2VkVmFsID0gbnVsbDtcclxuXHQvLyBIYW5kbGUgUmVnRXhwcy5cclxuXHRpZiAodmFsIGluc3RhbmNlb2YgUmVnRXhwKSB7XHJcblx0XHR2YXIgZmxhZ3MgPSBbXHJcblx0XHRcdHZhbC5nbG9iYWwgPyAnZycgOiAnJyxcclxuXHRcdFx0dmFsLmlnbm9yZUNhc2UgPyAnaScgOiAnJyxcclxuXHRcdFx0dmFsLm11bHRpbGluZSA/ICdtJyA6ICcnLFxyXG5cdFx0XS5qb2luKCcnKTtcclxuXHRcdHBhcnNlZFZhbCA9ICd+UmVnRXhwOicgKyBmbGFncyArICc6JyArIHZhbC5zb3VyY2U7XHJcblx0fVxyXG5cdC8vIEhhbmRsZSBEYXRlcy5cclxuXHRlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBEYXRlKSB7XHJcblx0XHRwYXJzZWRWYWwgPSAnfkRhdGU6JyArIHZhbC50b1N0cmluZygpO1xyXG5cdH1cclxuXHQvLyBIYW5kbGUgb2JqZWN0cy5cclxuXHRlbHNlIGlmICh2YWwgPT09IE9iamVjdCh2YWwpKSB7XHJcblx0XHRwYXJzZWRWYWwgPSAnfkpTT046JyArIEpTT04uc3RyaW5naWZ5KHZhbCk7XHJcblx0fVxyXG5cdC8vIEhhbmRsZSBudW1iZXJzLlxyXG5cdGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XHJcblx0XHRwYXJzZWRWYWwgPSAnfk51bWJlcjonICsgdmFsLnRvU3RyaW5nKCk7XHJcblx0fVxyXG5cdC8vIEhhbmRsZSBib29sZWFucy5cclxuXHRlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnYm9vbGVhbicpIHtcclxuXHRcdHBhcnNlZFZhbCA9ICd+Qm9vbGVhbjonICsgdmFsLnRvU3RyaW5nKCk7XHJcblx0fVxyXG5cdC8vIEhhbmRsZSBzdHJpbmdzLlxyXG5cdGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XHJcblx0XHRwYXJzZWRWYWwgPSB2YWw7XHJcblx0fVxyXG5cdC8vIFRocm93IGlmIHdlIGRvbid0IGtub3cgd2hhdCBpdCBpcy5cclxuXHRlbHNlIHtcclxuXHRcdHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIHN0b3JlIHRoaXMgdmFsdWU7IHdyb25nIHZhbHVlIHR5cGUuJyk7XHJcblx0fVxyXG5cdC8vIFNldCBleHBpcmUgZGF0ZSBpZiBuZWVkZWQuXHJcblx0aWYgKHR5cGVvZiBleHBpcmVzICE9PSAndW5kZWZpbmVkJykge1xyXG5cdFx0Ly8gQ29udmVydCB0byBhIHJlbGF0aXZlIGRhdGUuXHJcblx0XHRpZiAodHlwZW9mIGV4cGlyZXMgPT09ICdudW1iZXInKSB7XHJcblx0XHRcdGV4cGlyZXMgPSBuZXcgRGF0ZShEYXRlLm5vdygpICsgZXhwaXJlcyk7XHJcblx0XHR9XHJcblx0XHQvLyBNYWtlIHN1cmUgaXQgaXMgYSBkYXRlLlxyXG5cdFx0aWYgKGV4cGlyZXMgaW5zdGFuY2VvZiBEYXRlKSB7XHJcblx0XHRcdGV4cGlyZXNTdG9yZS5zZXQodGhpcy5nZXRTdG9yYWdlS2V5KGtleSksIGV4cGlyZXMpO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcignS2V5IGV4cGlyZSBtdXN0IGJlIGEgdmFsaWQgZGF0ZSBvciB0aW1lc3RhbXAuJyk7XHJcblx0XHR9XHJcblx0fVxyXG5cdC8vIFNhdmUgaXQuXHJcblx0Y2FjaGVbdGhpcy5nZXRTdG9yYWdlS2V5KGtleSldID0gdmFsO1xyXG5cdHRoaXMuZ2V0U3RvcmFnZUhhbmRsZXIoKS5zZXRJdGVtKHRoaXMuZ2V0U3RvcmFnZUtleShrZXkpLCBwYXJzZWRWYWwpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEdldHMgYWxsIGRhdGEgZm9yIHRoZSBjdXJyZW50IG5hbWVzcGFjZS5cclxuICogQG1ldGhvZCBnZXRBbGxcclxuICogQHJldHVybiB7b2JqZWN0fSBBbiBvYmplY3QgY29udGFpbmluZyBhbGwgZGF0YSBpbiB0aGUgZm9ybSBvZiBge3RoZUtleTogdGhlRGF0YX1gIHdoZXJlIGB0aGVEYXRhYCBpcyBwYXJzZWQgdXNpbmcge3sjY3Jvc3NMaW5rIFwiU3RvcmUvZ2V0XCJ9fVN0b3JlI2dldHt7L2Nyb3NzTGlua319LlxyXG4gKi9cclxuU3RvcmUucHJvdG90eXBlLmdldEFsbCA9IGZ1bmN0aW9uICgpIHtcclxuXHR2YXIga2V5cyA9IHRoaXMubGlzdEtleXMoKTtcclxuXHR2YXIgZGF0YSA9IHt9O1xyXG5cdGtleXMuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XHJcblx0XHRkYXRhW2tleV0gPSB0aGlzLmdldChrZXkpO1xyXG5cdH0sIHRoaXMpO1xyXG5cdHJldHVybiBkYXRhO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIExpc3QgYWxsIGtleXMgdGhhdCBhcmUgdGllZCB0byB0aGUgY3VycmVudCBuYW1lc3BhY2UuXHJcbiAqIEBtZXRob2QgbGlzdEtleXNcclxuICogQHJldHVybiB7YXJyYXl9IFRoZSBzdG9yYWdlIGtleXMuXHJcbiAqL1xyXG5TdG9yZS5wcm90b3R5cGUubGlzdEtleXMgPSBmdW5jdGlvbiAoKSB7XHJcblx0dmFyIGtleXMgPSBbXTtcclxuXHR2YXIga2V5ID0gbnVsbDtcclxuXHR2YXIgc3RvcmFnZUxlbmd0aCA9IHRoaXMuZ2V0U3RvcmFnZUhhbmRsZXIoKS5sZW5ndGg7XHJcblx0dmFyIHByZWZpeCA9IG5ldyBSZWdFeHAoJ14nICsgdGhpcy5nZXROYW1lc3BhY2UodHJ1ZSkpO1xyXG5cdGZvciAodmFyIGkgPSAwOyBpIDwgc3RvcmFnZUxlbmd0aDsgaSsrKSB7XHJcblx0XHRrZXkgPSB0aGlzLmdldFN0b3JhZ2VIYW5kbGVyKCkua2V5KGkpXHJcblx0XHRpZiAocHJlZml4LnRlc3Qoa2V5KSkge1xyXG5cdFx0XHRrZXlzLnB1c2goa2V5LnJlcGxhY2UocHJlZml4LCAnJykpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRyZXR1cm4ga2V5cztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZW1vdmVzIGEgc3BlY2lmaWMga2V5IGFuZCBkYXRhIGZyb20gdGhlIGN1cnJlbnQgbmFtZXNwYWNlLlxyXG4gKiBAbWV0aG9kIHJlbW92ZVxyXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgdG8gcmVtb3ZlIHRoZSBkYXRhIGZvci5cclxuICovXHJcblN0b3JlLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoa2V5KSB7XHJcblx0Y2FjaGVbdGhpcy5nZXRTdG9yYWdlS2V5KGtleSldID0gbnVsbDtcclxuXHR0aGlzLmdldFN0b3JhZ2VIYW5kbGVyKCkucmVtb3ZlSXRlbSh0aGlzLmdldFN0b3JhZ2VLZXkoa2V5KSk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmVtb3ZlcyBhbGwgZGF0YSBhbmQga2V5cyBmcm9tIHRoZSBjdXJyZW50IG5hbWVzcGFjZS5cclxuICogQG1ldGhvZCByZW1vdmVBbGxcclxuICovXHJcblN0b3JlLnByb3RvdHlwZS5yZW1vdmVBbGwgPSBmdW5jdGlvbiAoKSB7XHJcblx0dGhpcy5saXN0S2V5cygpLmZvckVhY2godGhpcy5yZW1vdmUsIHRoaXMpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJlbW92ZXMgbmFtZXNwYWNlZCBpdGVtcyBmcm9tIHRoZSBjYWNoZSBzbyB5b3VyIG5leHQge3sjY3Jvc3NMaW5rIFwiU3RvcmUvZ2V0XCJ9fVN0b3JlI2dldHt7L2Nyb3NzTGlua319IHdpbGwgYmUgZnJlc2ggZnJvbSB0aGUgc3RvcmFnZS5cclxuICogQG1ldGhvZCBmcmVzaGVuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSB0byByZW1vdmUgdGhlIGNhY2hlIGRhdGEgZm9yLlxyXG4gKi9cclxuU3RvcmUucHJvdG90eXBlLmZyZXNoZW4gPSBmdW5jdGlvbiAoa2V5KSB7XHJcblx0dmFyIGtleXMgPSBrZXkgPyBba2V5XSA6IHRoaXMubGlzdEtleXMoKTtcclxuXHRrZXlzLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xyXG5cdFx0Y2FjaGVbdGhpcy5nZXRTdG9yYWdlS2V5KGtleSldID0gbnVsbDtcclxuXHR9LCB0aGlzKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBNaWdyYXRlIGRhdGEgZnJvbSBhIGRpZmZlcmVudCBuYW1lc3BhY2UgdG8gY3VycmVudCBuYW1lc3BhY2UuXHJcbiAqIEBtZXRob2QgbWlncmF0ZVxyXG4gKiBAcGFyYW0ge29iamVjdH0gICBtaWdyYXRpb24gICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBtaWdyYXRpb24gb2JqZWN0LlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gICBtaWdyYXRpb24udG9LZXkgICAgICAgICAgICAgICAgICAgIFRoZSBrZXkgbmFtZSB1bmRlciB5b3VyIGN1cnJlbnQgbmFtZXNwYWNlIHRoZSBvbGQgZGF0YSBzaG91bGQgY2hhbmdlIHRvLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gICBtaWdyYXRpb24uZnJvbU5hbWVzcGFjZSAgICAgICAgICAgIFRoZSBvbGQgbmFtZXNwYWNlIHRoYXQgdGhlIG9sZCBrZXkgYmVsb25ncyB0by5cclxuICogQHBhcmFtIHtzdHJpbmd9ICAgbWlncmF0aW9uLmZyb21LZXkgICAgICAgICAgICAgICAgICBUaGUgb2xkIGtleSBuYW1lIHRvIG1pZ3JhdGUgZnJvbS5cclxuICogQHBhcmFtIHtzdHJpbmd9ICAgW21pZ3JhdGlvbi5mcm9tU3RvcmFnZVR5cGVdICAgICAgICBUaGUgc3RvcmFnZSB0eXBlIHRvIG1pZ3JhdGUgZnJvbS4gRGVmYXVsdHMgdG8gc2FtZSB0eXBlIGFzIHdoZXJlIHlvdSBhcmUgbWlncmF0aW5nIHRvLlxyXG4gKiBAcGFyYW0ge2Jvb2xlYW59ICBbbWlncmF0aW9uLmtlZXBPbGREYXRhPWZhbHNlXSAgICAgIFdoZXRoZXIgb2xkIGRhdGEgc2hvdWxkIGJlIGtlcHQgYWZ0ZXIgaXQgaGFzIGJlZW4gbWlncmF0ZWQuXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gIFttaWdyYXRpb24ub3ZlcndyaXRlTmV3RGF0YT1mYWxzZV0gV2hldGhlciBvbGQgZGF0YSBzaG91bGQgb3ZlcndyaXRlIGN1cnJlbnRseSBzdG9yZWQgZGF0YSBpZiBpdCBleGlzdHMuXHJcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IFttaWdyYXRpb24udHJhbnNmb3JtXSAgICAgICAgICAgICAgVGhlIGZ1bmN0aW9uIHRvIHBhc3MgdGhlIG9sZCBrZXkgZGF0YSB0aHJvdWdoIGJlZm9yZSBtaWdyYXRpbmcuXHJcbiAqIEBleGFtcGxlXHJcbiAqIFxyXG4gKiAgICAgdmFyIFN0b3JlID0gcmVxdWlyZSgnc3RvcmFnZS13cmFwcGVyJyk7XHJcbiAqICAgICB2YXIgc3RvcmUgPSBuZXcgU3RvcmUoe1xyXG4gKiAgICAgICAgIG5hbWVzcGFjZTogJ215TmV3QXBwJ1xyXG4gKiAgICAgfSk7XHJcbiAqXHJcbiAqICAgICAvLyBNaWdyYXRlIGZyb20gdGhlIG9sZCBhcHAuXHJcbiAqICAgICBzdG9yZS5taWdyYXRlKHtcclxuICogICAgICAgICB0b0tleTogJ25ldy1rZXknLFxyXG4gKiAgICAgICAgIGZyb21OYW1lc3BhY2U6ICdteU9sZEFwcCcsXHJcbiAqICAgICAgICAgZnJvbUtleTogJ29sZC1rZXknXHJcbiAqICAgICB9KTtcclxuICogICAgIFxyXG4gKiAgICAgLy8gTWlncmF0ZSBmcm9tIGdsb2JhbCBkYXRhLiBVc2VmdWwgd2hlbiBtb3ZpbmcgZnJvbSBvdGhlciBzdG9yYWdlIHdyYXBwZXJzIG9yIHJlZ3VsYXIgb2wnIGBsb2NhbFN0b3JhZ2VgLlxyXG4gKiAgICAgc3RvcmUubWlncmF0ZSh7XHJcbiAqICAgICAgICAgdG9LZXk6ICdvdGhlci1uZXcta2V5JyxcclxuICogICAgICAgICBmcm9tTmFtZXNwYWNlOiAnJyxcclxuICogICAgICAgICBmcm9tS2V5OiAnb3RoZXItb2xkLWtleS1vbi1nbG9iYWwnXHJcbiAqICAgICB9KTtcclxuICogICAgIFxyXG4gKiAgICAgLy8gTWlncmF0ZSBzb21lIEpTT04gZGF0YSB0aGF0IHdhcyBzdG9yZWQgYXMgYSBzdHJpbmcuXHJcbiAqICAgICBzdG9yZS5taWdyYXRlKHtcclxuICogICAgICAgICB0b0tleTogJ25ldy1qc29uLWtleScsXHJcbiAqICAgICAgICAgZnJvbU5hbWVzcGFjZTogJ215T2xkQXBwJyxcclxuICogICAgICAgICBmcm9tS2V5OiAnb2xkLWpzb24ta2V5JyxcclxuICogICAgICAgICAvLyBUcnkgY29udmVydGluZyBzb21lIG9sZCBKU09OIGRhdGEuXHJcbiAqICAgICAgICAgdHJhbnNmb3JtOiBmdW5jdGlvbiAoZGF0YSkge1xyXG4gKiAgICAgICAgICAgICB0cnkge1xyXG4gKiAgICAgICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZGF0YSk7XHJcbiAqICAgICAgICAgICAgIH1cclxuICogICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICogICAgICAgICAgICAgICAgIHJldHVybiBkYXRhO1xyXG4gKiAgICAgICAgICAgICB9XHJcbiAqICAgICAgICAgfVxyXG4gKiAgICAgfSk7XHJcbiAqL1xyXG5cclxuU3RvcmUucHJvdG90eXBlLm1pZ3JhdGUgPSBmdW5jdGlvbiAobWlncmF0aW9uKSB7XHJcblx0Ly8gU2F2ZSBvdXIgY3VycmVudCBuYW1lc3BhY2UuXHJcblx0dmFyIHRvTmFtZXNwYWNlID0gdGhpcy5nZXROYW1lc3BhY2UoKTtcclxuXHR2YXIgdG9TdG9yYWdlVHlwZSA9IHRoaXMuZ2V0U3RvcmFnZVR5cGUoKTtcclxuXHJcblx0Ly8gQ3JlYXRlIGEgdGVtcG9yYXJ5IHN0b3JlIHRvIGF2b2lkIGNoYW5naW5nIG5hbWVzcGFjZSBkdXJpbmcgYWN0dWFsIGdldC9zZXRzLlxyXG5cdHZhciBzdG9yZSA9IG5ldyBTdG9yZSh7XHJcblx0XHRuYW1lc3BhY2U6IHRvTmFtZXNwYWNlLFxyXG5cdFx0c3RvcmFnZVR5cGU6IHRvU3RvcmFnZVR5cGVcclxuXHR9KTtcclxuXHJcblx0dmFyIGRhdGEgPSBudWxsO1xyXG5cclxuXHQvLyBHZXQgZGF0YSBmcm9tIG9sZCBuYW1lc3BhY2UuXHJcblx0c3RvcmUuc2V0TmFtZXNwYWNlKG1pZ3JhdGlvbi5mcm9tTmFtZXNwYWNlKTtcclxuXHRpZiAodHlwZW9mIG1pZ3JhdGlvbi5mcm9tU3RvcmFnZVR5cGUgIT09ICd1bmRlZmluZWQnKSB7XHJcblx0XHRzdG9yZS5zZXRTdG9yYWdlVHlwZShtaWdyYXRpb24uZnJvbVN0b3JhZ2VUeXBlKTtcclxuXHR9XHJcblx0ZGF0YSA9IHN0b3JlLmdldChtaWdyYXRpb24uZnJvbUtleSk7XHJcblxyXG5cdC8vIFJlbW92ZSBvbGQgaWYgbmVlZGVkLlxyXG5cdGlmICghbWlncmF0aW9uLmtlZXBPbGREYXRhKSB7XHJcblx0XHRzdG9yZS5yZW1vdmUobWlncmF0aW9uLmZyb21LZXkpO1xyXG5cdH1cclxuXHRcclxuXHQvLyBObyBkYXRhLCBpZ25vcmUgdGhpcyBtaWdyYXRpb24uXHJcblx0aWYgKGRhdGEgPT09IG51bGwpIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblxyXG5cdC8vIFRyYW5zZm9ybSBkYXRhIGlmIG5lZWRlZC5cclxuXHRpZiAodHlwZW9mIG1pZ3JhdGlvbi50cmFuc2Zvcm0gPT09ICdmdW5jdGlvbicpIHtcclxuXHRcdGRhdGEgPSBtaWdyYXRpb24udHJhbnNmb3JtKGRhdGEpO1xyXG5cdH1cclxuXHRlbHNlIGlmICh0eXBlb2YgbWlncmF0aW9uLnRyYW5zZm9ybSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuXHRcdHRocm93IG5ldyBFcnJvcignSW52YWxpZCB0cmFuc2Zvcm0gY2FsbGJhY2suJyk7XHJcblx0fVxyXG5cclxuXHQvLyBHbyBiYWNrIHRvIGN1cnJlbnQgbmFtZXNwYWNlLlxyXG5cdHN0b3JlLnNldE5hbWVzcGFjZSh0b05hbWVzcGFjZSk7XHJcblx0c3RvcmUuc2V0U3RvcmFnZVR5cGUodG9TdG9yYWdlVHlwZSk7XHJcblxyXG5cdC8vIE9ubHkgb3ZlcndyaXRlIG5ldyBkYXRhIGlmIGl0IGRvZXNuJ3QgZXhpc3Qgb3IgaXQncyByZXF1ZXN0ZWQuXHJcblx0aWYgKHN0b3JlLmdldChtaWdyYXRpb24udG9LZXkpID09PSBudWxsIHx8IG1pZ3JhdGlvbi5vdmVyd3JpdGVOZXdEYXRhKSB7XHJcblx0XHRzdG9yZS5zZXQobWlncmF0aW9uLnRvS2V5LCBkYXRhKTtcclxuXHR9XHJcbn07XHJcblxyXG4vKipcclxuICogQ3JlYXRlcyBhIHN1YnN0b3JlIHRoYXQgaXMgbmVzdGVkIGluIHRoZSBjdXJyZW50IG5hbWVzcGFjZS5cclxuICogQG1ldGhvZCBjcmVhdGVTdWJzdG9yZVxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG5hbWVzcGFjZSBUaGUgc3Vic3RvcmUncyBuYW1lc3BhY2UuXHJcbiAqIEByZXR1cm4ge1N0b3JlfSAgICAgICAgICAgIFRoZSBzdWJzdG9yZS5cclxuICogQGV4YW1wbGVcclxuICogXHJcbiAqICAgICB2YXIgU3RvcmUgPSByZXF1aXJlKCdzdG9yYWdlLXdyYXBwZXInKTtcclxuICogICAgIC8vIENyZWF0ZSBtYWluIHN0b3JlLlxyXG4gKiAgICAgdmFyIHN0b3JlID0gbmV3IFN0b3JlKHtcclxuICogICAgICAgICBuYW1lc3BhY2U6ICdteWFwcCdcclxuICogICAgIH0pO1xyXG4gKlxyXG4gKiAgICAgLy8gQ3JlYXRlIHN1YnN0b3JlLlxyXG4gKiAgICAgdmFyIHN1YnN0b3JlID0gc3RvcmUuY3JlYXRlU3Vic3RvcmUoJ3RoaW5ncycpO1xyXG4gKiAgICAgc3Vic3RvcmUuc2V0KCdmb28nLCAnYmFyJyk7XHJcbiAqXHJcbiAqICAgICBzdWJzdG9yZS5nZXQoJ2ZvbycpID09PSBzdG9yZS5nZXQoJ3RoaW5nczpmb28nKTtcclxuICogICAgIC8vIHRydWVcclxuICovXHJcblN0b3JlLnByb3RvdHlwZS5jcmVhdGVTdWJzdG9yZSA9IGZ1bmN0aW9uIChuYW1lc3BhY2UpIHtcclxuXHRyZXR1cm4gbmV3IFN0b3JlKHtcclxuXHRcdG5hbWVzcGFjZTogdGhpcy5nZXROYW1lc3BhY2UodHJ1ZSkgKyBuYW1lc3BhY2UsXHJcblx0XHRzdG9yYWdlVHlwZTogdGhpcy5nZXRTdG9yYWdlVHlwZSgpXHJcblx0fSk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFN0b3JlO1xyXG4iLCJtb2R1bGUuZXhwb3J0cz17XHJcbiAgXCJuYW1lXCI6IFwidHdpdGNoLWNoYXQtZW1vdGVzXCIsXHJcbiAgXCJ2ZXJzaW9uXCI6IFwiMi4xLjVcIixcclxuICBcImhvbWVwYWdlXCI6IFwiaHR0cDovL2NsZXR1c2MuZ2l0aHViLmlvL1VzZXJzY3JpcHQtLVR3aXRjaC1DaGF0LUVtb3Rlcy9cIixcclxuICBcImJ1Z3NcIjogXCJodHRwczovL2dpdGh1Yi5jb20vY2xldHVzYy9Vc2Vyc2NyaXB0LS1Ud2l0Y2gtQ2hhdC1FbW90ZXMvaXNzdWVzXCIsXHJcbiAgXCJhdXRob3JcIjogXCJSeWFuIENoYXRoYW0gPHJ5YW4uYi5jaGF0aGFtQGdtYWlsLmNvbT4gKGh0dHBzOi8vZ2l0aHViLmNvbS9jbGV0dXNjKVwiLFxyXG4gIFwicmVwb3NpdG9yeVwiOiB7XHJcbiAgICBcInR5cGVcIjogXCJnaXRcIixcclxuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2NsZXR1c2MvVXNlcnNjcmlwdC0tVHdpdGNoLUNoYXQtRW1vdGVzLmdpdFwiXHJcbiAgfSxcclxuICBcInVzZXJzY3JpcHRcIjoge1xyXG4gICAgXCJuYW1lXCI6IFwiVHdpdGNoIENoYXQgRW1vdGVzXCIsXHJcbiAgICBcIm5hbWVzcGFjZVwiOiBcIiNDbGV0dXNcIixcclxuICAgIFwidmVyc2lvblwiOiBcInt7e3BrZy52ZXJzaW9ufX19XCIsXHJcbiAgICBcImRlc2NyaXB0aW9uXCI6IFwiQWRkcyBhIGJ1dHRvbiB0byBUd2l0Y2ggdGhhdCBhbGxvd3MgeW91IHRvIFxcXCJjbGljay10by1pbnNlcnRcXFwiIGFuIGVtb3RlLlwiLFxyXG4gICAgXCJjb3B5cmlnaHRcIjogXCIyMDExKywge3t7cGtnLmF1dGhvcn19fVwiLFxyXG4gICAgXCJhdXRob3JcIjogXCJ7e3twa2cuYXV0aG9yfX19XCIsXHJcbiAgICBcImljb25cIjogXCJodHRwOi8vd3d3LmdyYXZhdGFyLmNvbS9hdmF0YXIucGhwP2dyYXZhdGFyX2lkPTY4NzVlODNhYTZjNTYzNzkwY2IyZGE5MTRhYWJhOGIzJnI9UEcmcz00OCZkZWZhdWx0PWlkZW50aWNvblwiLFxyXG4gICAgXCJsaWNlbnNlXCI6IFtcclxuICAgICAgXCJNSVQ7IGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVRcIixcclxuICAgICAgXCJDQyBCWS1OQy1TQSAzLjA7IGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LW5jLXNhLzMuMC9cIlxyXG4gICAgXSxcclxuICAgIFwiaG9tZXBhZ2VcIjogXCJ7e3twa2cuaG9tZXBhZ2V9fX1cIixcclxuICAgIFwic3VwcG9ydFVSTFwiOiBcInt7e3BrZy5idWdzfX19XCIsXHJcbiAgICBcImNvbnRyaWJ1dGlvblVSTFwiOiBcImh0dHA6Ly9jbGV0dXNjLmdpdGh1Yi5pby9Vc2Vyc2NyaXB0LS1Ud2l0Y2gtQ2hhdC1FbW90ZXMvI2RvbmF0ZVwiLFxyXG4gICAgXCJncmFudFwiOiBcIm5vbmVcIixcclxuICAgIFwiaW5jbHVkZVwiOiBbXHJcbiAgICAgIFwiaHR0cDovLyoudHdpdGNoLnR2LypcIixcclxuICAgICAgXCJodHRwczovLyoudHdpdGNoLnR2LypcIlxyXG4gICAgXSxcclxuICAgIFwiZXhjbHVkZVwiOiBbXHJcbiAgICAgIFwiaHR0cDovL2FwaS50d2l0Y2gudHYvKlwiLFxyXG4gICAgICBcImh0dHBzOi8vYXBpLnR3aXRjaC50di8qXCIsXHJcbiAgICAgIFwiaHR0cDovL3RtaS50d2l0Y2gudHYvKlwiLFxyXG4gICAgICBcImh0dHBzOi8vdG1pLnR3aXRjaC50di8qXCIsXHJcbiAgICAgIFwiaHR0cDovLyoudHdpdGNoLnR2LyovZGFzaGJvYXJkXCIsXHJcbiAgICAgIFwiaHR0cHM6Ly8qLnR3aXRjaC50di8qL2Rhc2hib2FyZFwiLFxyXG4gICAgICBcImh0dHA6Ly9jaGF0ZGVwb3QudHdpdGNoLnR2LypcIixcclxuICAgICAgXCJodHRwczovL2NoYXRkZXBvdC50d2l0Y2gudHYvKlwiLFxyXG4gICAgICBcImh0dHA6Ly9pbS50d2l0Y2gudHYvKlwiLFxyXG4gICAgICBcImh0dHBzOi8vaW0udHdpdGNoLnR2LypcIixcclxuICAgICAgXCJodHRwOi8vcGxhdGZvcm0udHdpdHRlci5jb20vKlwiLFxyXG4gICAgICBcImh0dHBzOi8vcGxhdGZvcm0udHdpdHRlci5jb20vKlwiLFxyXG4gICAgICBcImh0dHA6Ly93d3cuZmFjZWJvb2suY29tLypcIixcclxuICAgICAgXCJodHRwczovL3d3dy5mYWNlYm9vay5jb20vKlwiXHJcbiAgICBdXHJcbiAgfSxcclxuICBcImRldkRlcGVuZGVuY2llc1wiOiB7XHJcbiAgICBcImJyb3dzZXItc3luY1wiOiBcIl4xLjMuMlwiLFxyXG4gICAgXCJicm93c2VyaWZ5XCI6IFwiXjUuOS4xXCIsXHJcbiAgICBcImdlbmVyYXRlLXVzZXJzY3JpcHQtaGVhZGVyXCI6IFwiXjEuMC4wXCIsXHJcbiAgICBcImd1bHBcIjogXCJeMy44LjNcIixcclxuICAgIFwiZ3VscC1hdXRvcHJlZml4ZXJcIjogXCIwLjAuOFwiLFxyXG4gICAgXCJndWxwLWJlYXV0aWZ5XCI6IFwiMS4xLjBcIixcclxuICAgIFwiZ3VscC1jaGFuZ2VkXCI6IFwiXjAuNC4xXCIsXHJcbiAgICBcImd1bHAtY29uY2F0XCI6IFwiXjIuMi4wXCIsXHJcbiAgICBcImd1bHAtY29uZmxpY3RcIjogXCJeMC4xLjJcIixcclxuICAgIFwiZ3VscC1jc3MtYmFzZTY0XCI6IFwiXjEuMS4wXCIsXHJcbiAgICBcImd1bHAtY3NzMmpzXCI6IFwiXjEuMC4yXCIsXHJcbiAgICBcImd1bHAtaGVhZGVyXCI6IFwiXjEuMC4yXCIsXHJcbiAgICBcImd1bHAtaG9nYW4tY29tcGlsZVwiOiBcIl4wLjIuMVwiLFxyXG4gICAgXCJndWxwLW1pbmlmeS1jc3NcIjogXCJeMC4zLjVcIixcclxuICAgIFwiZ3VscC1ub3RpZnlcIjogXCJeMS40LjFcIixcclxuICAgIFwiZ3VscC1yZW5hbWVcIjogXCJeMS4yLjBcIixcclxuICAgIFwiZ3VscC11Z2xpZnlcIjogXCJeMC4zLjFcIixcclxuICAgIFwiZ3VscC11dGlsXCI6IFwiXjMuMC4wXCIsXHJcbiAgICBcImhvZ2FuLmpzXCI6IFwiXjMuMC4yXCIsXHJcbiAgICBcImpxdWVyeS11aVwiOiBcIl4xLjEwLjVcIixcclxuICAgIFwianF1ZXJ5LnNjcm9sbGJhclwiOiBcIl4wLjIuN1wiLFxyXG4gICAgXCJwcmV0dHktaHJ0aW1lXCI6IFwiXjAuMi4xXCIsXHJcbiAgICBcInN0b3JhZ2Utd3JhcHBlclwiOiBcImNsZXR1c2Mvc3RvcmFnZS13cmFwcGVyI3YwLjEuMVwiLFxyXG4gICAgXCJ2aW55bC1tYXBcIjogXCJeMS4wLjFcIixcclxuICAgIFwidmlueWwtc291cmNlLXN0cmVhbVwiOiBcIl4wLjEuMVwiLFxyXG4gICAgXCJ3YXRjaGlmeVwiOiBcIl4xLjAuMVwiXHJcbiAgfVxyXG59XHJcbiIsInZhciBsb2dnZXIgPSByZXF1aXJlKCcuL2xvZ2dlcicpO1xyXG52YXIgYXBpID0ge307XHJcbnZhciBlbWJlciA9IG51bGw7XHJcbnZhciBob29rZWRGYWN0b3JpZXMgPSB7fTtcclxuXHJcbmFwaS5nZXRFbWJlciA9IGZ1bmN0aW9uICgpIHtcclxuXHRpZiAoZW1iZXIpIHtcclxuXHRcdHJldHVybiBlbWJlcjtcclxuXHR9XHJcblx0aWYgKHdpbmRvdy5BcHAgJiYgd2luZG93LkFwcC5fX2NvbnRhaW5lcl9fKSB7XHJcblx0XHRlbWJlciA9IHdpbmRvdy5BcHAuX19jb250YWluZXJfXztcclxuXHRcdHJldHVybiBlbWJlcjtcclxuXHR9XHJcblx0cmV0dXJuIGZhbHNlO1xyXG59O1xyXG5cclxuYXBpLmlzTG9hZGVkID0gZnVuY3Rpb24gKCkge1xyXG5cdHJldHVybiBCb29sZWFuKGFwaS5nZXRFbWJlcigpKTtcclxufTtcclxuXHJcbmFwaS5sb29rdXAgPSBmdW5jdGlvbiAobG9va3VwRmFjdG9yeSkge1xyXG5cdGlmICghYXBpLmlzTG9hZGVkKCkpIHtcclxuXHRcdGxvZ2dlci5kZWJ1ZygnRmFjdG9yeSBsb29rdXAgZmFpbHVyZSwgRW1iZXIgbm90IGxvYWRlZC4nKTtcclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9XHJcblx0cmV0dXJuIGFwaS5nZXRFbWJlcigpLmxvb2t1cChsb29rdXBGYWN0b3J5KTtcclxufTtcclxuXHJcbmFwaS5ob29rID0gZnVuY3Rpb24gKGxvb2t1cEZhY3RvcnksIGFjdGl2YXRlQ2IsIGRlYWN0aXZhdGVDYikge1xyXG5cdGlmICghYXBpLmlzTG9hZGVkKCkpIHtcclxuXHRcdGxvZ2dlci5kZWJ1ZygnRmFjdG9yeSBob29rIGZhaWx1cmUsIEVtYmVyIG5vdCBsb2FkZWQuJyk7XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cdGlmIChob29rZWRGYWN0b3JpZXNbbG9va3VwRmFjdG9yeV0pIHtcclxuXHRcdGxvZ2dlci5kZWJ1ZygnRmFjdG9yeSBhbHJlYWR5IGhvb2tlZDogJyArIGxvb2t1cEZhY3RvcnkpO1xyXG5cdFx0cmV0dXJuIHRydWU7XHJcblx0fVxyXG5cdHZhciByZW9wZW5PcHRpb25zID0ge307XHJcblx0dmFyIGZhY3RvcnkgPSBhcGkubG9va3VwKGxvb2t1cEZhY3RvcnkpO1xyXG5cclxuXHRpZiAoIWZhY3RvcnkpIHtcclxuXHRcdGxvZ2dlci5kZWJ1ZygnRmFjdG9yeSBob29rIGZhaWx1cmUsIGZhY3Rvcnkgbm90IGZvdW5kOiAnICsgbG9va3VwRmFjdG9yeSk7XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cclxuXHRpZiAoYWN0aXZhdGVDYikge1xyXG5cdFx0cmVvcGVuT3B0aW9ucy5hY3RpdmF0ZSA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0dGhpcy5fc3VwZXIoKTtcclxuXHRcdFx0YWN0aXZhdGVDYi5jYWxsKHRoaXMpO1xyXG5cdFx0XHRsb2dnZXIuZGVidWcoJ0hvb2sgcnVuIG9uIGFjdGl2YXRlOiAnICsgbG9va3VwRmFjdG9yeSk7XHJcblx0XHR9O1xyXG5cdH1cclxuXHRpZiAoZGVhY3RpdmF0ZUNiKSB7XHJcblx0XHRyZW9wZW5PcHRpb25zLmRlYWN0aXZhdGUgPSBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdHRoaXMuX3N1cGVyKCk7XHJcblx0XHRcdGRlYWN0aXZhdGVDYi5jYWxsKHRoaXMpO1xyXG5cdFx0XHRsb2dnZXIuZGVidWcoJ0hvb2sgcnVuIG9uIGRlYWN0aXZhdGU6ICcgKyBsb29rdXBGYWN0b3J5KTtcclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHR0cnkge1xyXG5cdFx0ZmFjdG9yeS5yZW9wZW4ocmVvcGVuT3B0aW9ucyk7XHJcblx0XHRob29rZWRGYWN0b3JpZXNbbG9va3VwRmFjdG9yeV0gPSB0cnVlO1xyXG5cdFx0bG9nZ2VyLmRlYnVnKCdGYWN0b3J5IGhvb2tlZDogJyArIGxvb2t1cEZhY3RvcnkpO1xyXG5cdFx0cmV0dXJuIHRydWU7XHJcblx0fVxyXG5cdGNhdGNoIChlcnIpIHtcclxuXHRcdGxvZ2dlci5kZWJ1ZygnRmFjdG9yeSBob29rIGZhaWx1cmUsIHVuZXhwZWN0ZWQgZXJyb3I6ICcgKyBsb29rdXBGYWN0b3J5KTtcclxuXHRcdGxvZ2dlci5kZWJ1ZyhlcnIpO1xyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxufTtcclxuXHJcbmFwaS5nZXQgPSBmdW5jdGlvbiAobG9va3VwRmFjdG9yeSwgcHJvcGVydHkpIHtcclxuXHRpZiAoIWFwaS5pc0xvYWRlZCgpKSB7XHJcblx0XHRsb2dnZXIuZGVidWcoJ0ZhY3RvcnkgZ2V0IGZhaWx1cmUsIEVtYmVyIG5vdCBsb2FkZWQuJyk7XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cdHZhciBwcm9wZXJ0aWVzID0gcHJvcGVydHkuc3BsaXQoJy4nKTtcclxuXHR2YXIgZ2V0dGVyID0gYXBpLmxvb2t1cChsb29rdXBGYWN0b3J5KTtcclxuXHJcblx0cHJvcGVydGllcy5zb21lKGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xyXG5cdFx0Ly8gSWYgZ2V0dGVyIGZhaWxzLCBqdXN0IGV4aXQsIG90aGVyd2lzZSwga2VlcCBsb29waW5nLlxyXG5cdFx0aWYgKGdldHRlciA9PSBudWxsIHx8IHR5cGVvZiBnZXR0ZXIgPT09ICd1bmRlZmluZWQnKSB7XHJcblx0XHRcdGdldHRlciA9IG51bGw7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fVxyXG5cdFx0aWYgKGdldHRlcltwcm9wZXJ0eV0gPT0gbnVsbCB8fCB0eXBlb2YgZ2V0dGVyW3Byb3BlcnR5XSA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuXHRcdFx0Z2V0dGVyID0gbnVsbDtcclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9XHJcblx0XHRpZiAodHlwZW9mIGdldHRlci5nZXQgPT09ICdmdW5jdGlvbicpIHtcclxuXHRcdFx0Z2V0dGVyID0gZ2V0dGVyLmdldChwcm9wZXJ0eSk7XHJcblx0XHRcdGlmIChnZXR0ZXIgPT0gbnVsbCB8fCB0eXBlb2YgZ2V0dGVyID09PSAndW5kZWZpbmVkJykge1xyXG5cdFx0XHRcdGdldHRlciA9IG51bGw7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdFx0Z2V0dGVyID0gZ2V0dGVyW3Byb3BlcnR5XTtcclxuXHR9KTtcclxuXHJcblx0cmV0dXJuIGdldHRlcjtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYXBpO1xyXG4iLCJ2YXIgc3RvcmFnZSA9IHJlcXVpcmUoJy4vc3RvcmFnZScpO1xyXG52YXIgbG9nZ2VyID0gcmVxdWlyZSgnLi9sb2dnZXInKTtcclxudmFyIHVpID0gcmVxdWlyZSgnLi91aScpO1xyXG52YXIgYXBpID0ge307XHJcbnZhciBlbW90ZVN0b3JlID0gbmV3IEVtb3RlU3RvcmUoKTtcclxudmFyICQgPSB3aW5kb3cualF1ZXJ5O1xyXG5cclxuLyoqXHJcbiAqIFRoZSBlbnRpcmUgZW1vdGUgc3RvcmluZyBzeXN0ZW0uXHJcbiAqL1xyXG5mdW5jdGlvbiBFbW90ZVN0b3JlKCkge1xyXG5cdHZhciBnZXR0ZXJzID0ge307XHJcblx0dmFyIG5hdGl2ZUVtb3RlcyA9IHt9O1xyXG5cdHZhciBoYXNJbml0aWFsaXplZCA9IGZhbHNlO1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgYSBsaXN0IG9mIHVzYWJsZSBlbW90aWNvbnMuXHJcblx0ICogQHBhcmFtICB7ZnVuY3Rpb259IFtmaWx0ZXJzXSAgICAgICBBIGZpbHRlciBtZXRob2QgdG8gbGltaXQgd2hhdCBlbW90ZXMgYXJlIHJldHVybmVkLiBQYXNzZWQgdG8gQXJyYXkjZmlsdGVyLlxyXG5cdCAqIEBwYXJhbSAge2Z1bmN0aW9ufHN0cmluZ30gW3NvcnRCeV0gSG93IHRoZSBlbW90ZXMgc2hvdWxkIGJlIHNvcnRlZC4gYGZ1bmN0aW9uYCB3aWxsIGJlIHBhc3NlZCB0byBzb3J0IHZpYSBBcnJheSNzb3J0LiBgJ2NoYW5uZWwnYCBzb3J0cyBieSBjaGFubmVsIG5hbWUsIGdsb2JhbHMgZmlyc3QuIEFsbCBvdGhlciB2YWx1ZXMgKG9yIG9taXR0ZWQpIHNvcnQgYWxwaGFudW1lcmljYWxseS5cclxuXHQgKiBAcGFyYW0gIHtzdHJpbmd9IFtyZXR1cm5UeXBlXSAgICAgIGAnb2JqZWN0J2Agd2lsbCByZXR1cm4gaW4gb2JqZWN0IGZvcm1hdCwgZS5nLiBgeydLYXBwYSc6IEVtb3RlKC4uLiksIC4uLn1gLiBBbGwgb3RoZXIgdmFsdWVzIChvciBvbWl0dGVkKSByZXR1cm4gYW4gYXJyYXkgZm9ybWF0LCBlLmcuIGBbRW1vdGUoLi4uKSwgLi4uXWAuXHJcblx0ICogQHJldHVybiB7b2JqZWN0fGFycmF5fSAgICAgICAgICAgICBTZWUgYHJldHVyblR5cGVgIHBhcmFtLlxyXG5cdCAqL1xyXG5cdHRoaXMuZ2V0RW1vdGVzID0gZnVuY3Rpb24gKGZpbHRlcnMsIHNvcnRCeSwgcmV0dXJuVHlwZSkge1xyXG5cdFx0dmFyIHR3aXRjaEFwaSA9IHJlcXVpcmUoJy4vdHdpdGNoLWFwaScpO1xyXG5cclxuXHRcdC8vIEdldCBuYXRpdmUgZW1vdGVzLlxyXG5cdFx0dmFyIGVtb3RlcyA9ICQuZXh0ZW5kKHt9LCBuYXRpdmVFbW90ZXMpO1xyXG5cclxuXHRcdC8vIFBhcnNlIHRoZSBjdXN0b20gZW1vdGVzIHByb3ZpZGVkIGJ5IHRoaXJkIHBhcnR5IGFkZG9ucy5cclxuXHRcdE9iamVjdC5rZXlzKGdldHRlcnMpLmZvckVhY2goZnVuY3Rpb24gKGdldHRlck5hbWUpIHtcclxuXHRcdFx0Ly8gVHJ5IHRoZSBnZXR0ZXIuXHJcblx0XHRcdHZhciByZXN1bHRzID0gbnVsbDtcclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHRyZXN1bHRzID0gZ2V0dGVyc1tnZXR0ZXJOYW1lXSgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGNhdGNoIChlcnIpIHtcclxuXHRcdFx0XHRsb2dnZXIuZGVidWcoJ0Vtb3RlIGdldHRlciBgJyArIGdldHRlck5hbWUgKyAnYCBmYWlsZWQgdW5leHBlY3RlZGx5LCBza2lwcGluZy4nLCBlcnIudG9TdHJpbmcoKSk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmICghQXJyYXkuaXNBcnJheShyZXN1bHRzKSkge1xyXG5cdFx0XHRcdGxvZ2dlci5kZWJ1ZygnRW1vdGUgZ2V0dGVyIGAnICsgZ2V0dGVyTmFtZSArICdgIG11c3QgcmV0dXJuIGFuIGFycmF5LCBza2lwcGluZy4nKTtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIE92ZXJyaWRlIG5hdGl2ZXMgYW5kIHByZXZpb3VzIGdldHRlcnMuXHJcblx0XHRcdHJlc3VsdHMuZm9yRWFjaChmdW5jdGlvbiAoZW1vdGUpIHtcclxuXHRcdFx0XHR0cnkge1xyXG5cdFx0XHRcdFx0Ly8gQ3JlYXRlIHRoZSBlbW90ZS5cclxuXHRcdFx0XHRcdHZhciBpbnN0YW5jZSA9IG5ldyBFbW90ZShlbW90ZSk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gRm9yY2UgdGhlIGdldHRlci5cclxuXHRcdFx0XHRcdGluc3RhbmNlLnNldEdldHRlck5hbWUoZ2V0dGVyTmFtZSk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gRm9yY2UgZW1vdGVzIHdpdGhvdXQgY2hhbm5lbHMgdG8gdGhlIGdldHRlcidzIG5hbWUuXHJcblx0XHRcdFx0XHRpZiAoIWVtb3RlLmNoYW5uZWwpIHtcclxuXHRcdFx0XHRcdFx0aW5zdGFuY2Uuc2V0Q2hhbm5lbE5hbWUoZ2V0dGVyTmFtZSk7XHJcblx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0Ly8gQWRkL292ZXJyaWRlIGl0LlxyXG5cdFx0XHRcdFx0ZW1vdGVzW2luc3RhbmNlLmdldFRleHQoKV0gPSBpbnN0YW5jZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0Y2F0Y2ggKGVycikge1xyXG5cdFx0XHRcdFx0bG9nZ2VyLmRlYnVnKCdFbW90ZSBwYXJzaW5nIGZvciBnZXR0ZXIgYCcgKyBnZXR0ZXJOYW1lICsgJ2AgZmFpbGVkLCBza2lwcGluZy4nLCBlcnIudG9TdHJpbmcoKSwgZW1vdGUpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyBDb3ZlcnQgdG8gYXJyYXkuXHJcblx0XHRlbW90ZXMgPSBPYmplY3Qua2V5cyhlbW90ZXMpLm1hcChmdW5jdGlvbiAoZW1vdGUpIHtcclxuXHRcdFx0cmV0dXJuIGVtb3Rlc1tlbW90ZV07XHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyBGaWx0ZXIgcmVzdWx0cy5cclxuXHRcdGlmICh0eXBlb2YgZmlsdGVycyA9PT0gJ2Z1bmN0aW9uJykge1xyXG5cdFx0XHRlbW90ZXMgPSBlbW90ZXMuZmlsdGVyKGZpbHRlcnMpO1xyXG5cdFx0fVxyXG5cdFx0XHJcblx0XHQvLyBSZXR1cm4gYXMgYW4gb2JqZWN0IGlmIHJlcXVlc3RlZC5cclxuXHRcdGlmIChyZXR1cm5UeXBlID09PSAnb2JqZWN0Jykge1xyXG5cdFx0XHR2YXIgYXNPYmplY3QgPSB7fTtcclxuXHRcdFx0ZW1vdGVzLmZvckVhY2goZnVuY3Rpb24gKGVtb3RlKSB7XHJcblx0XHRcdFx0YXNPYmplY3RbZW1vdGUuZ2V0VGV4dCgpXSA9IGVtb3RlO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0cmV0dXJuIGFzT2JqZWN0O1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNvcnQgcmVzdWx0cy5cclxuXHRcdGlmICh0eXBlb2Ygc29ydEJ5ID09PSAnZnVuY3Rpb24nKSB7XHJcblx0XHRcdGVtb3Rlcy5zb3J0KHNvcnRCeSk7XHJcblx0XHR9XHJcblx0XHRlbHNlIGlmIChzb3J0QnkgPT09ICdjaGFubmVsJykge1xyXG5cdFx0XHRlbW90ZXMuc29ydChzb3J0aW5nLmFsbEVtb3Rlc0NhdGVnb3J5KTtcclxuXHRcdH1cclxuXHRcdGVsc2Uge1xyXG5cdFx0XHRlbW90ZXMuc29ydChzb3J0aW5nLmJ5VGV4dCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmV0dXJuIHRoZSBlbW90ZXMgaW4gYXJyYXkgZm9ybWF0LlxyXG5cdFx0cmV0dXJuIGVtb3RlcztcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBSZWdpc3RlcnMgYSAzcmQgcGFydHkgZW1vdGUgaG9vay5cclxuXHQgKiBAcGFyYW0gIHtzdHJpbmd9IG5hbWUgICBUaGUgbmFtZSBvZiB0aGUgM3JkIHBhcnR5IHJlZ2lzdGVyaW5nIHRoZSBob29rLlxyXG5cdCAqIEBwYXJhbSAge2Z1bmN0aW9ufSBnZXR0ZXIgVGhlIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIGxvb2tpbmcgZm9yIGVtb3Rlcy4gTXVzdCByZXR1cm4gYW4gYXJyYXkgb2YgZW1vdGUgb2JqZWN0cywgZS5nLiBgW2Vtb3RlLCAuLi5dYC4gU2VlIEVtb3RlIGNsYXNzLlxyXG5cdCAqL1xyXG5cdHRoaXMucmVnaXN0ZXJHZXR0ZXIgPSBmdW5jdGlvbiAobmFtZSwgZ2V0dGVyKSB7XHJcblx0XHRpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcignTmFtZSBtdXN0IGJlIGEgc3RyaW5nLicpO1xyXG5cdFx0fVxyXG5cdFx0aWYgKGdldHRlcnNbbmFtZV0pIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdHZXR0ZXIgYWxyZWFkeSBleGlzdHMuJyk7XHJcblx0XHR9XHJcblx0XHRpZiAodHlwZW9mIGdldHRlciAhPT0gJ2Z1bmN0aW9uJykge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0dldHRlciBtdXN0IGJlIGEgZnVuY3Rpb24uJyk7XHJcblx0XHR9XHJcblx0XHRsb2dnZXIuZGVidWcoJ0dldHRlciByZWdpc3RlcmVkOiAnICsgbmFtZSk7XHJcblx0XHRnZXR0ZXJzW25hbWVdID0gZ2V0dGVyO1xyXG5cdFx0dWkudXBkYXRlRW1vdGVzKCk7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogUmVnaXN0ZXJzIGEgM3JkIHBhcnR5IGVtb3RlIGhvb2suXHJcblx0ICogQHBhcmFtICB7c3RyaW5nfSBuYW1lICAgVGhlIG5hbWUgb2YgdGhlIDNyZCBwYXJ0eSBob29rIHRvIGRlcmVnaXN0ZXIuXHJcblx0ICovXHJcblx0dGhpcy5kZXJlZ2lzdGVyR2V0dGVyID0gZnVuY3Rpb24gKG5hbWUpIHtcclxuXHRcdGxvZ2dlci5kZWJ1ZygnR2V0dGVyIHVucmVnaXN0ZXJlZDogJyArIG5hbWUpO1xyXG5cdFx0ZGVsZXRlIGdldHRlcnNbbmFtZV07XHJcblx0XHR1aS51cGRhdGVFbW90ZXMoKTtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBJbml0aWFsaXplcyB0aGUgcmF3IGRhdGEgZnJvbSB0aGUgQVBJIGVuZHBvaW50cy4gU2hvdWxkIGJlIGNhbGxlZCBhdCBsb2FkIGFuZC9vciB3aGVuZXZlciB0aGUgQVBJIG1heSBoYXZlIGNoYW5nZWQuIFBvcHVsYXRlcyBpbnRlcm5hbCBvYmplY3RzIHdpdGggdXBkYXRlZCBkYXRhLlxyXG5cdCAqL1xyXG5cdHRoaXMuaW5pdCA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdGlmIChoYXNJbml0aWFsaXplZCkge1xyXG5cdFx0XHRsb2dnZXIuZGVidWcoJ0FscmVhZHkgaW5pdGlhbGl6ZWQgRW1vdGVTdG9yZSwgc3RvcHBpbmcgaW5pdC4nKTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGxvZ2dlci5kZWJ1ZygnU3RhcnRpbmcgaW5pdGlhbGl6YXRpb24uJyk7XHJcblxyXG5cdFx0dmFyIHR3aXRjaEFwaSA9IHJlcXVpcmUoJy4vdHdpdGNoLWFwaScpO1xyXG5cdFx0dmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuXHRcdC8vIEhhc2ggb2YgZW1vdGUgc2V0IHRvIGZvcmNlZCBjaGFubmVsLlxyXG5cdFx0dmFyIGZvcmNlZFNldHNUb0NoYW5uZWxzID0ge1xyXG5cdFx0XHQvLyBHbG9iYWxzLlxyXG5cdFx0XHQwOiAnfmdsb2JhbCcsXHJcblx0XHRcdC8vIEJ1YmJsZSBlbW90ZXMuXHJcblx0XHRcdDMzOiAndHVyYm8nLFxyXG5cdFx0XHQvLyBNb25rZXkgZW1vdGVzLlxyXG5cdFx0XHQ0MjogJ3R1cmJvJyxcclxuXHRcdFx0Ly8gSGlkZGVuIHR1cmJvIGVtb3Rlcy5cclxuXHRcdFx0NDU3OiAndHVyYm8nLFxyXG5cdFx0XHQ3OTM6ICd0dXJibycsXHJcblx0XHRcdDE5MTUxOiAndHdpdGNoX3ByaW1lJyxcclxuXHRcdFx0MTkxOTQ6ICd0d2l0Y2hfcHJpbWUnXHJcblxyXG5cdFx0fTtcclxuXHJcblx0XHRsb2dnZXIuZGVidWcoJ0luaXRpYWxpemluZyBlbW90ZSBzZXQgY2hhbmdlIGxpc3RlbmVyLicpO1xyXG5cclxuXHRcdHR3aXRjaEFwaS5nZXRFbW90ZXMoZnVuY3Rpb24gKGVtb3RlU2V0cykge1xyXG5cdFx0XHRsb2dnZXIuZGVidWcoJ1BhcnNpbmcgZW1vdGUgc2V0cy4nKTtcclxuXHJcblx0XHRcdE9iamVjdC5rZXlzKGVtb3RlU2V0cykuZm9yRWFjaChmdW5jdGlvbiAoc2V0KSB7XHJcblx0XHRcdFx0dmFyIGVtb3RlcyA9IGVtb3RlU2V0c1tzZXRdO1xyXG5cdFx0XHRcdHNldCA9IE51bWJlcihzZXQpO1xyXG5cdFx0XHRcdGVtb3Rlcy5mb3JFYWNoKGZ1bmN0aW9uIChlbW90ZSkge1xyXG5cdFx0XHRcdFx0Ly8gU2V0IHNvbWUgcmVxdWlyZWQgaW5mby5cclxuXHRcdFx0XHRcdGVtb3RlLnVybCA9ICcvL3N0YXRpYy1jZG4uanR2bncubmV0L2Vtb3RpY29ucy92MS8nICsgZW1vdGUuaWQgKyAnLzEuMCc7XHJcblx0XHRcdFx0XHRlbW90ZS50ZXh0ID0gZ2V0RW1vdGVGcm9tUmVnRXgoZW1vdGUuY29kZSk7XHJcblx0XHRcdFx0XHRlbW90ZS5zZXQgPSBzZXQ7XHJcblxyXG5cdFx0XHRcdFx0Ly8gSGFyZGNvZGUgdGhlIGNoYW5uZWxzIG9mIGNlcnRhaW4gc2V0cy5cclxuXHRcdFx0XHRcdGlmIChmb3JjZWRTZXRzVG9DaGFubmVsc1tzZXRdKSB7XHJcblx0XHRcdFx0XHRcdGVtb3RlLmNoYW5uZWwgPSBmb3JjZWRTZXRzVG9DaGFubmVsc1tzZXRdO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdHZhciBpbnN0YW5jZSA9IG5ldyBFbW90ZShlbW90ZSk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gU2F2ZSB0aGUgZW1vdGUgZm9yIHVzZSBsYXRlci5cclxuXHRcdFx0XHRcdG5hdGl2ZUVtb3Rlc1tlbW90ZS50ZXh0XSA9IGluc3RhbmNlO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdGxvZ2dlci5kZWJ1ZygnTG9hZGluZyBzdWJzY3JpcHRpb24gZGF0YS4nKTtcclxuXHJcblx0XHRcdC8vIEdldCBhY3RpdmUgc3Vic2NyaXB0aW9ucyB0byBmaW5kIHRoZSBjaGFubmVscy5cclxuXHRcdFx0dHdpdGNoQXBpLmdldFRpY2tldHMoZnVuY3Rpb24gKHRpY2tldHMpIHtcclxuXHRcdFx0XHQvLyBJbnN0YW5jZXMgZnJvbSBlYWNoIGNoYW5uZWwgdG8gcHJlbG9hZCBjaGFubmVsIGRhdGEuXHJcblx0XHRcdFx0dmFyIGRlZmVycmVkQ2hhbm5lbEdldHMgPSB7fTtcclxuXHJcblx0XHRcdFx0bG9nZ2VyLmRlYnVnKCdUaWNrZXRzIGxvYWRlZCBmcm9tIHRoZSBBUEkuJywgdGlja2V0cyk7XHJcblx0XHRcdFx0dGlja2V0cy5mb3JFYWNoKGZ1bmN0aW9uICh0aWNrZXQpIHtcclxuXHRcdFx0XHRcdHZhciBwcm9kdWN0ID0gdGlja2V0LnByb2R1Y3Q7XHJcblx0XHRcdFx0XHR2YXIgY2hhbm5lbCA9IHByb2R1Y3Qub3duZXJfbmFtZSB8fCBwcm9kdWN0LnNob3J0X25hbWU7XHJcblxyXG5cdFx0XHRcdFx0Ly8gR2V0IHN1YnNjcmlwdGlvbnMgd2l0aCBlbW90ZXMgb25seS5cclxuXHRcdFx0XHRcdGlmICghcHJvZHVjdC5lbW90aWNvbnMgfHwgIXByb2R1Y3QuZW1vdGljb25zLmxlbmd0aCkge1xyXG5cdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdC8vIFNldCB0aGUgY2hhbm5lbCBvbiB0aGUgZW1vdGVzLlxyXG5cdFx0XHRcdFx0cHJvZHVjdC5lbW90aWNvbnMuZm9yRWFjaChmdW5jdGlvbiAoZW1vdGUpIHtcclxuXHRcdFx0XHRcdFx0dmFyIGluc3RhbmNlID0gbmF0aXZlRW1vdGVzW2dldEVtb3RlRnJvbVJlZ0V4KGVtb3RlLnJlZ2V4KV07XHJcblx0XHRcdFx0XHRcdGluc3RhbmNlLnNldENoYW5uZWxOYW1lKGNoYW5uZWwpO1xyXG5cclxuXHRcdFx0XHRcdFx0Ly8gU2F2ZSBpbnN0YW5jZSBmb3IgbGF0ZXIsIGJ1dCBvbmx5IG9uZSBpbnN0YW5jZSBwZXIgY2hhbm5lbC5cclxuXHRcdFx0XHRcdFx0aWYgKCFkZWZlcnJlZENoYW5uZWxHZXRzW2NoYW5uZWxdKSB7XHJcblx0XHRcdFx0XHRcdFx0ZGVmZXJyZWRDaGFubmVsR2V0c1tjaGFubmVsXSA9IGluc3RhbmNlO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0Ly8gUHJlbG9hZCBjaGFubmVsIGRhdGEuXHJcblx0XHRcdFx0T2JqZWN0LmtleXMoZGVmZXJyZWRDaGFubmVsR2V0cykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XHJcblx0XHRcdFx0XHR2YXIgaW5zdGFuY2UgPSBkZWZlcnJlZENoYW5uZWxHZXRzW2tleV07XHJcblx0XHRcdFx0XHRpbnN0YW5jZS5nZXRDaGFubmVsQmFkZ2UoKTtcclxuXHRcdFx0XHRcdGluc3RhbmNlLmdldENoYW5uZWxEaXNwbGF5TmFtZSgpO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdHVpLnVwZGF0ZUVtb3RlcygpO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0dWkudXBkYXRlRW1vdGVzKCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRoYXNJbml0aWFsaXplZCA9IHRydWU7XHJcblx0XHRsb2dnZXIuZGVidWcoJ0ZpbmlzaGVkIEVtb3RlU3RvcmUgaW5pdGlhbGl6YXRpb24uJyk7XHJcblx0fTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIGEgc3BlY2lmaWMgZW1vdGUsIGlmIGF2YWlsYWJsZS5cclxuICogQHBhcmFtICB7c3RyaW5nfSAgICAgdGV4dCBUaGUgdGV4dCBvZiB0aGUgZW1vdGUgdG8gZ2V0LlxyXG4gKiBAcmV0dXJuIHtFbW90ZXxudWxsfSAgICAgIFRoZSBFbW90ZSBpbnN0YW5jZSBvZiB0aGUgZW1vdGUgb3IgYG51bGxgIGlmIGl0IGNvdWxkbid0IGJlIGZvdW5kLlxyXG4gKi9cclxuRW1vdGVTdG9yZS5wcm90b3R5cGUuZ2V0RW1vdGUgPSBmdW5jdGlvbiAodGV4dCkge1xyXG5cdHJldHVybiB0aGlzLmdldEVtb3RlcyhudWxsLCBudWxsLCAnb2JqZWN0JylbdGV4dF0gfHwgbnVsbDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBFbW90ZSBvYmplY3QuXHJcbiAqIEBwYXJhbSB7b2JqZWN0fSBkZXRhaWxzICAgICAgICAgICAgICBPYmplY3QgZGVzY3JpYmluZyB0aGUgZW1vdGUuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXRhaWxzLnRleHQgICAgICAgICBUaGUgdGV4dCB0byB1c2UgaW4gdGhlIGNoYXQgYm94IHdoZW4gZW1vdGUgaXMgY2xpY2tlZC5cclxuICogQHBhcmFtIHtzdHJpbmd9IGRldGFpbHMudXJsICAgICAgICAgIFRoZSBVUkwgb2YgdGhlIGltYWdlIGZvciB0aGUgZW1vdGUuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBbZGV0YWlscy5iYWRnZV0gICAgICBUaGUgVVJMIG9mIHRoZSBiYWRnZSBmb3IgdGhlIGVtb3RlLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gW2RldGFpbHMuY2hhbm5lbF0gICAgVGhlIGNoYW5uZWwgdGhlIGVtb3RlIHNob3VsZCBiZSBjYXRlZ29yaXplZCB1bmRlci5cclxuICogQHBhcmFtIHtzdHJpbmd9IFtkZXRhaWxzLmdldHRlck5hbWVdIFRoZSAzcmQgcGFydHkgZ2V0dGVyIHRoYXQgcmVnaXN0ZXJlZCB0aGUgZW1vdGUuIFVzZWQgaW50ZXJuYWxseSBvbmx5LlxyXG4gKi9cclxuZnVuY3Rpb24gRW1vdGUoZGV0YWlscykge1xyXG5cdHZhciB0ZXh0ID0gbnVsbDtcclxuXHR2YXIgdXJsID0gbnVsbDtcclxuXHR2YXIgZ2V0dGVyTmFtZSA9IG51bGw7XHJcblx0dmFyIGNoYW5uZWwgPSB7XHJcblx0XHRuYW1lOiBudWxsLFxyXG5cdFx0ZGlzcGxheU5hbWU6IG51bGwsXHJcblx0XHRiYWRnZTogbnVsbFxyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldHMgdGhlIHRleHQgb2YgdGhlIGVtb3RlLlxyXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGVtb3RlIHRleHQuXHJcblx0ICovXHJcblx0dGhpcy5nZXRUZXh0ID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0cmV0dXJuIHRleHQ7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogU2V0cyB0aGUgdGV4dCBvZiB0aGUgZW1vdGUuXHJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHRoZVRleHQgVGhlIHRleHQgdG8gc2V0LlxyXG5cdCAqL1xyXG5cdHRoaXMuc2V0VGV4dCA9IGZ1bmN0aW9uICh0aGVUZXh0KSB7XHJcblx0XHRpZiAodHlwZW9mIHRoZVRleHQgIT09ICdzdHJpbmcnIHx8IHRoZVRleHQubGVuZ3RoIDwgMSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdGV4dCcpO1xyXG5cdFx0fVxyXG5cdFx0dGV4dCA9IHRoZVRleHQ7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogR2V0cyB0aGUgZ2V0dGVyIG5hbWUgdGhpcyBlbW90ZSBiZWxvbmdzIHRvLlxyXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGdldHRlcidzIG5hbWUuXHJcblx0ICovXHJcblx0dGhpcy5nZXRHZXR0ZXJOYW1lID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0cmV0dXJuIGdldHRlck5hbWU7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogU2V0cyB0aGUgZ2V0dGVyIG5hbWUgdGhpcyBlbW90ZSBiZWxvbmdzIHRvLlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0aGVHZXR0ZXJOYW1lIFRoZSBnZXR0ZXIncyBuYW1lLlxyXG5cdCAqL1xyXG5cdHRoaXMuc2V0R2V0dGVyTmFtZSA9IGZ1bmN0aW9uICh0aGVHZXR0ZXJOYW1lKSB7XHJcblx0XHRpZiAodHlwZW9mIHRoZUdldHRlck5hbWUgIT09ICdzdHJpbmcnIHx8IHRoZUdldHRlck5hbWUubGVuZ3RoIDwgMSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZ2V0dGVyIG5hbWUnKTtcclxuXHRcdH1cclxuXHRcdGdldHRlck5hbWUgPSB0aGVHZXR0ZXJOYW1lO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldHMgdGhlIGVtb3RlJ3MgaW1hZ2UgVVJMLlxyXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGVtb3RlIGltYWdlIFVSTC5cclxuXHQgKi9cclxuXHR0aGlzLmdldFVybCA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdHJldHVybiB1cmw7XHJcblx0fTtcclxuXHQvKipcclxuXHQgKiBTZXRzIHRoZSBlbW90ZSdzIGltYWdlIFVSTC5cclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGhlVXJsIFRoZSBpbWFnZSBVUkwgdG8gc2V0LlxyXG5cdCAqL1xyXG5cdHRoaXMuc2V0VXJsID0gZnVuY3Rpb24gKHRoZVVybCkge1xyXG5cdFx0aWYgKHR5cGVvZiB0aGVVcmwgIT09ICdzdHJpbmcnIHx8IHRoZVVybC5sZW5ndGggPCAxKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcignSW52YWxpZCBVUkwnKTtcclxuXHRcdH1cclxuXHRcdHVybCA9IHRoZVVybDtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXRzIHRoZSBlbW90ZSdzIGNoYW5uZWwgbmFtZS5cclxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBlbW90ZSdzIGNoYW5uZWwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmUuXHJcblx0ICovXHJcblx0dGhpcy5nZXRDaGFubmVsTmFtZSA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdGlmICghY2hhbm5lbC5uYW1lKSB7XHJcblx0XHRcdGNoYW5uZWwubmFtZSA9IHN0b3JhZ2UuY2hhbm5lbE5hbWVzLmdldCh0aGlzLmdldFRleHQoKSk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gY2hhbm5lbC5uYW1lIHx8ICcnO1xyXG5cdH07XHJcblx0LyoqXHJcblx0ICogU2V0cyB0aGUgZW1vdGUncyBjaGFubmVsIG5hbWUuXHJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHRoZUNoYW5uZWwgVGhlIGNoYW5uZWwgbmFtZSB0byBzZXQuXHJcblx0ICovXHJcblx0dGhpcy5zZXRDaGFubmVsTmFtZSA9IGZ1bmN0aW9uICh0aGVDaGFubmVsKSB7XHJcblx0XHRpZiAodHlwZW9mIHRoZUNoYW5uZWwgIT09ICdzdHJpbmcnIHx8IHRoZUNoYW5uZWwubGVuZ3RoIDwgMSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY2hhbm5lbCcpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIE9ubHkgc2F2ZSB0aGUgY2hhbm5lbCB0byBzdG9yYWdlIGlmIGl0J3MgZHluYW1pYy5cclxuXHRcdGlmICh0aGVDaGFubmVsICE9PSAnfmdsb2JhbCcgJiYgdGhlQ2hhbm5lbCAhPT0gJ3R1cmJvJyAmJiB0aGVDaGFubmVsICE9PSAndHdpdGNoX3ByaW1lJykge1xyXG5cdFx0XHRzdG9yYWdlLmNoYW5uZWxOYW1lcy5zZXQodGhpcy5nZXRUZXh0KCksIHRoZUNoYW5uZWwpO1xyXG5cdFx0fVxyXG5cdFx0Y2hhbm5lbC5uYW1lID0gdGhlQ2hhbm5lbDtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXRzIHRoZSBlbW90ZSBjaGFubmVsJ3MgYmFkZ2UgaW1hZ2UgVVJMLlxyXG5cdCAqIEByZXR1cm4ge3N0cmluZ3xudWxsfSBUaGUgVVJMIG9mIHRoZSBiYWRnZSBpbWFnZSBmb3IgdGhlIGVtb3RlJ3MgY2hhbm5lbCBvciBgbnVsbGAgaWYgaXQgZG9lc24ndCBoYXZlIGEgY2hhbm5lbC5cclxuXHQgKi9cclxuXHR0aGlzLmdldENoYW5uZWxCYWRnZSA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdHZhciB0d2l0Y2hBcGkgPSByZXF1aXJlKCcuL3R3aXRjaC1hcGknKTtcclxuXHRcdHZhciBjaGFubmVsTmFtZSA9IHRoaXMuZ2V0Q2hhbm5lbE5hbWUoKTtcclxuXHRcdHZhciBkZWZhdWx0QmFkZ2UgPSAnLy9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy9zdWJzY3JpYmVyLXN0YXIucG5nJztcclxuXHJcblx0XHQvLyBObyBjaGFubmVsLlxyXG5cdFx0aWYgKCFjaGFubmVsTmFtZSkge1xyXG5cdFx0XHRyZXR1cm4gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBHaXZlIGdsb2JhbHMgYSBkZWZhdWx0IGJhZGdlLlxyXG5cdFx0aWYgKGNoYW5uZWxOYW1lID09PSAnfmdsb2JhbCcpIHtcclxuXHRcdFx0cmV0dXJuICcvZmF2aWNvbi5pY28nO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEFscmVhZHkgaGF2ZSBvbmUgcHJlc2V0LlxyXG5cdFx0aWYgKGNoYW5uZWwuYmFkZ2UpIHtcclxuXHRcdFx0cmV0dXJuIGNoYW5uZWwuYmFkZ2U7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ2hlY2sgc3RvcmFnZS5cclxuXHRcdGNoYW5uZWwuYmFkZ2UgPSBzdG9yYWdlLmJhZGdlcy5nZXQoY2hhbm5lbE5hbWUpO1xyXG5cdFx0aWYgKGNoYW5uZWwuYmFkZ2UgIT09IG51bGwpIHtcclxuXHRcdFx0cmV0dXJuIGNoYW5uZWwuYmFkZ2U7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU2V0IGRlZmF1bHQgdW50aWwgQVBJIHJldHVybnMgc29tZXRoaW5nLlxyXG5cdFx0Y2hhbm5lbC5iYWRnZSA9IGRlZmF1bHRCYWRnZTtcclxuXHJcblx0XHQvLyBHZXQgZnJvbSBBUEkuXHJcblx0XHRsb2dnZXIuZGVidWcoJ0dldHRpbmcgZnJlc2ggYmFkZ2UgZm9yOiAnICsgY2hhbm5lbE5hbWUpO1xyXG5cdFx0dHdpdGNoQXBpLmdldEJhZGdlcyhjaGFubmVsTmFtZSwgZnVuY3Rpb24gKGJhZGdlcykge1xyXG5cdFx0XHR2YXIgYmFkZ2UgPSBudWxsO1xyXG5cclxuXHRcdFx0Ly8gU2F2ZSB0dXJibyBiYWRnZSB3aGlsZSB3ZSBhcmUgaGVyZS5cclxuXHRcdFx0aWYgKGJhZGdlcy50dXJibyAmJiBiYWRnZXMudHVyYm8uaW1hZ2UpIHtcclxuXHRcdFx0XHRiYWRnZSA9IGJhZGdlcy50dXJiby5pbWFnZTtcclxuXHRcdFx0XHRzdG9yYWdlLmJhZGdlcy5zZXQoJ3R1cmJvJywgYmFkZ2UsIDg2NDAwMDAwKTtcclxuXHJcblx0XHRcdFx0Ly8gVHVyYm8gaXMgYWN0dWFsbHkgd2hhdCB3ZSB3YW50ZWQsIHNvIHdlIGFyZSBkb25lLlxyXG5cdFx0XHRcdGlmIChjaGFubmVsTmFtZSA9PT0gJ3R1cmJvJykge1xyXG5cdFx0XHRcdFx0Y2hhbm5lbC5iYWRnZSA9IGJhZGdlO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gU2F2ZSB0dXJibyBiYWRnZSB3aGlsZSB3ZSBhcmUgaGVyZS5cclxuXHRcdFx0aWYgKGJhZGdlcy5wcmVtaXVtICYmIGJhZGdlcy5wcmVtaXVtLmltYWdlKSB7XHJcblx0XHRcdFx0YmFkZ2UgPSBiYWRnZXMucHJlbWl1bS5pbWFnZTtcclxuXHRcdFx0XHRzdG9yYWdlLmJhZGdlcy5zZXQoJ3R3aXRjaF9wcmltZScsIGJhZGdlLCA4NjQwMDAwMCk7XHJcblxyXG5cdFx0XHRcdC8vIFR1cmJvIGlzIGFjdHVhbGx5IHdoYXQgd2Ugd2FudGVkLCBzbyB3ZSBhcmUgZG9uZS5cclxuXHRcdFx0XHRpZiAoY2hhbm5lbE5hbWUgPT09ICd0d2l0Y2hfcHJpbWUnKSB7XHJcblx0XHRcdFx0XHRjaGFubmVsLmJhZGdlID0gYmFkZ2U7XHJcblx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTYXZlIHN1YnNjcmliZXIgYmFkZ2UgaW4gc3RvcmFnZS5cclxuXHRcdFx0aWYgKGJhZGdlcy5zdWJzY3JpYmVyICYmIGJhZGdlcy5zdWJzY3JpYmVyLmltYWdlKSB7XHJcblx0XHRcdFx0Y2hhbm5lbC5iYWRnZSA9IGJhZGdlcy5zdWJzY3JpYmVyLmltYWdlO1xyXG5cdFx0XHRcdHN0b3JhZ2UuYmFkZ2VzLnNldChjaGFubmVsTmFtZSwgY2hhbm5lbC5iYWRnZSwgODY0MDAwMDApO1xyXG5cdFx0XHRcdHVpLnVwZGF0ZUVtb3RlcygpO1xyXG5cdFx0XHR9XHJcblx0XHRcdC8vIE5vIHN1YnNjcmliZXIgYmFkZ2UuXHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdGNoYW5uZWwuYmFkZ2UgPSBkZWZhdWx0QmFkZ2U7XHJcblx0XHRcdFx0bG9nZ2VyLmRlYnVnKCdGYWlsZWQgdG8gZ2V0IHN1YnNjcmliZXIgYmFkZ2UgZm9yOiAnICsgY2hhbm5lbE5hbWUpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHRcdFxyXG5cdFx0cmV0dXJuIGNoYW5uZWwuYmFkZ2UgfHwgZGVmYXVsdEJhZGdlO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldHMgdGhlIGVtb3RlJ3MgY2hhbm5lbCBiYWRnZSBpbWFnZSBVUkwuXHJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHRoZUJhZGdlIFRoZSBiYWRnZSBpbWFnZSBVUkwgdG8gc2V0LlxyXG5cdCAqL1xyXG5cdHRoaXMuc2V0Q2hhbm5lbEJhZGdlID0gZnVuY3Rpb24gKHRoZUJhZGdlKSB7XHJcblx0XHRpZiAodHlwZW9mIHRoZUJhZGdlICE9PSAnc3RyaW5nJyB8fCB0aGVCYWRnZS5sZW5ndGggPCAxKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcignSW52YWxpZCBiYWRnZScpO1xyXG5cdFx0fVxyXG5cdFx0Y2hhbm5lbC5iYWRnZSA9IHRoZUJhZGdlO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBhIGNoYW5uZWwncyBkaXNwbGF5IG5hbWUuXHJcblx0ICogQHJldHVybiB7c3RyaW5nfSBUaGUgY2hhbm5lbCdzIGRpc3BsYXkgbmFtZS4gTWF5IGJlIGVxdWl2YWxlbnQgdG8gdGhlIGNoYW5uZWwgdGhlIGZpcnN0IHRpbWUgdGhlIEFQSSBuZWVkcyB0byBiZSBjYWxsZWQuXHJcblx0ICovXHJcblx0dGhpcy5nZXRDaGFubmVsRGlzcGxheU5hbWUgPSBmdW5jdGlvbiAoKSB7XHJcblx0XHR2YXIgdHdpdGNoQXBpID0gcmVxdWlyZSgnLi90d2l0Y2gtYXBpJyk7XHJcblx0XHR2YXIgY2hhbm5lbE5hbWUgPSB0aGlzLmdldENoYW5uZWxOYW1lKCk7XHJcblx0XHR2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG5cdFx0dmFyIGZvcmNlZENoYW5uZWxUb0Rpc3BsYXlOYW1lcyA9IHtcclxuXHRcdFx0J35nbG9iYWwnOiAnR2xvYmFsJyxcclxuXHRcdFx0J3R1cmJvJzogJ1R3aXRjaCBUdXJibycsXHJcblx0XHRcdCd0d2l0Y2hfcHJpbWUnOiAnVHdpdGNoIFByaW1lJ1xyXG5cdFx0fTtcclxuXHJcblx0XHQvLyBObyBjaGFubmVsLlxyXG5cdFx0aWYgKCFjaGFubmVsTmFtZSkge1xyXG5cdFx0XHRyZXR1cm4gJyc7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRm9yY2VkIGRpc3BsYXkgbmFtZS5cclxuXHRcdGlmIChmb3JjZWRDaGFubmVsVG9EaXNwbGF5TmFtZXNbY2hhbm5lbE5hbWVdKSB7XHJcblx0XHRcdHJldHVybiBmb3JjZWRDaGFubmVsVG9EaXNwbGF5TmFtZXNbY2hhbm5lbE5hbWVdO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEFscmVhZHkgaGF2ZSBvbmUgcHJlc2V0LlxyXG5cdFx0aWYgKGNoYW5uZWwuZGlzcGxheU5hbWUpIHtcclxuXHRcdFx0cmV0dXJuIGNoYW5uZWwuZGlzcGxheU5hbWU7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gTG9vayBmb3Igb2J2aW91cyBiYWQgY2hhbm5lbCBuYW1lcyB0aGF0IHNob3VsZG4ndCBoaXQgdGhlIEFQSSBvciBzdG9yYWdlLiBVc2UgY2hhbm5lbCBuYW1lIGluc3RlYWQuXHJcblx0XHRpZiAoL1teYS16MC05X10vLnRlc3QoY2hhbm5lbE5hbWUpKSB7XHJcblx0XHRcdGxvZ2dlci5kZWJ1ZygnVW5hYmxlIHRvIGdldCBkaXNwbGF5IG5hbWUgZHVlIHRvIG9idmlvdXMgbm9uLXN0YW5kYXJkIGNoYW5uZWwgbmFtZSBmb3I6ICcgKyBjaGFubmVsTmFtZSk7XHJcblx0XHRcdHJldHVybiBjaGFubmVsTmFtZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDaGVjayBzdG9yYWdlLlxyXG5cdFx0Y2hhbm5lbC5kaXNwbGF5TmFtZSA9IHN0b3JhZ2UuZGlzcGxheU5hbWVzLmdldChjaGFubmVsTmFtZSk7XHJcblx0XHRpZiAoY2hhbm5lbC5kaXNwbGF5TmFtZSAhPT0gbnVsbCkge1xyXG5cdFx0XHRyZXR1cm4gY2hhbm5lbC5kaXNwbGF5TmFtZTtcclxuXHRcdH1cclxuXHRcdC8vIEdldCBmcm9tIEFQSS5cclxuXHRcdGVsc2Uge1xyXG5cdFx0XHQvLyBTZXQgZGVmYXVsdCB1bnRpbCBBUEkgcmV0dXJucyBzb21ldGhpbmcuXHJcblx0XHRcdGNoYW5uZWwuZGlzcGxheU5hbWUgPSBjaGFubmVsTmFtZTtcclxuXHJcblx0XHRcdGxvZ2dlci5kZWJ1ZygnR2V0dGluZyBmcmVzaCBkaXNwbGF5IG5hbWUgZm9yOiAnICsgY2hhbm5lbE5hbWUpO1xyXG5cdFx0XHR0d2l0Y2hBcGkuZ2V0VXNlcihjaGFubmVsTmFtZSwgZnVuY3Rpb24gKHVzZXIpIHtcclxuXHRcdFx0XHRpZiAoIXVzZXIgfHwgIXVzZXIuZGlzcGxheV9uYW1lKSB7XHJcblx0XHRcdFx0XHRsb2dnZXIuZGVidWcoJ0ZhaWxlZCB0byBnZXQgZGlzcGxheSBuYW1lIGZvcjogJyArIGNoYW5uZWxOYW1lKTtcclxuXHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIFNhdmUgaXQuXHJcblx0XHRcdFx0c2VsZi5zZXRDaGFubmVsRGlzcGxheU5hbWUodXNlci5kaXNwbGF5X25hbWUpO1xyXG5cdFx0XHRcdHVpLnVwZGF0ZUVtb3RlcygpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHRcdFxyXG5cdFx0cmV0dXJuIGNoYW5uZWwuZGlzcGxheU5hbWU7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogU2V0cyB0aGUgZW1vdGUncyBjaGFubmVsIGJhZGdlIGltYWdlIFVSTC5cclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGhlQmFkZ2UgVGhlIGJhZGdlIGltYWdlIFVSTCB0byBzZXQuXHJcblx0ICovXHJcblx0dGhpcy5zZXRDaGFubmVsRGlzcGxheU5hbWUgPSBmdW5jdGlvbiAoZGlzcGxheU5hbWUpIHtcclxuXHRcdGlmICh0eXBlb2YgZGlzcGxheU5hbWUgIT09ICdzdHJpbmcnIHx8IGRpc3BsYXlOYW1lLmxlbmd0aCA8IDEpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRpc3BsYXlOYW1lJyk7XHJcblx0XHR9XHJcblx0XHRjaGFubmVsLmRpc3BsYXlOYW1lID0gZGlzcGxheU5hbWU7XHJcblx0XHRzdG9yYWdlLmRpc3BsYXlOYW1lcy5zZXQodGhpcy5nZXRDaGFubmVsTmFtZSgpLCBkaXNwbGF5TmFtZSwgODY0MDAwMDApO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEluaXRpYWxpemUgdGhlIGRldGFpbHMuXHJcblx0ICovXHJcblx0XHJcblx0Ly8gUmVxdWlyZWQgZmllbGRzLlxyXG5cdHRoaXMuc2V0VGV4dChkZXRhaWxzLnRleHQpO1xyXG5cdHRoaXMuc2V0VXJsKGRldGFpbHMudXJsKTtcclxuXHJcblx0Ly8gT3B0aW9uYWwgZmllbGRzLlxyXG5cdGlmIChkZXRhaWxzLmdldHRlck5hbWUpIHtcclxuXHRcdHRoaXMuc2V0R2V0dGVyTmFtZShkZXRhaWxzLmdldHRlck5hbWUpO1xyXG5cdH1cclxuXHRpZiAoZGV0YWlscy5jaGFubmVsKSB7XHJcblx0XHR0aGlzLnNldENoYW5uZWxOYW1lKGRldGFpbHMuY2hhbm5lbCk7XHJcblx0fVxyXG5cdGlmIChkZXRhaWxzLmNoYW5uZWxEaXNwbGF5TmFtZSkge1xyXG5cdFx0dGhpcy5zZXRDaGFubmVsRGlzcGxheU5hbWUoZGV0YWlscy5jaGFubmVsRGlzcGxheU5hbWUpO1xyXG5cdH1cclxuXHRpZiAoZGV0YWlscy5iYWRnZSkge1xyXG5cdFx0dGhpcy5zZXRDaGFubmVsQmFkZ2UoZGV0YWlscy5iYWRnZSk7XHJcblx0fVxyXG59O1xyXG5cclxuLyoqXHJcbiAqIFN0YXRlIGNoYW5nZXJzLlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBUb2dnbGUgd2hldGhlciBhbiBlbW90ZSBzaG91bGQgYmUgYSBmYXZvcml0ZS5cclxuICogQHBhcmFtIHtib29sZWFufSBbZm9yY2VdIGB0cnVlYCBmb3JjZXMgdGhlIGVtb3RlIHRvIGJlIGEgZmF2b3JpdGUsIGBmYWxzZWAgZm9yY2VzIHRoZSBlbW90ZSB0byBub3QgYmUgYSBmYXZvcml0ZS5cclxuICovXHJcbkVtb3RlLnByb3RvdHlwZS50b2dnbGVGYXZvcml0ZSA9IGZ1bmN0aW9uIChmb3JjZSkge1xyXG5cdGlmICh0eXBlb2YgZm9yY2UgIT09ICd1bmRlZmluZWQnKSB7XHJcblx0XHRzdG9yYWdlLnN0YXJyZWQuc2V0KHRoaXMuZ2V0VGV4dCgpLCAhIWZvcmNlKTtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0c3RvcmFnZS5zdGFycmVkLnNldCh0aGlzLmdldFRleHQoKSwgIXRoaXMuaXNGYXZvcml0ZSgpKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUb2dnbGUgd2hldGhlciBhbiBlbW90ZSBzaG91bGQgYmUgdmlzaWJsZSBvdXQgb2YgZWRpdGluZyBtb2RlLlxyXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmb3JjZV0gYHRydWVgIGZvcmNlcyB0aGUgZW1vdGUgdG8gYmUgdmlzaWJsZSwgYGZhbHNlYCBmb3JjZXMgdGhlIGVtb3RlIHRvIGJlIGhpZGRlbi5cclxuICovXHJcbkVtb3RlLnByb3RvdHlwZS50b2dnbGVWaXNpYmlsaXR5ID0gZnVuY3Rpb24gKGZvcmNlKSB7XHJcblx0aWYgKHR5cGVvZiBmb3JjZSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuXHRcdHN0b3JhZ2UudmlzaWJpbGl0eS5zZXQodGhpcy5nZXRUZXh0KCksICEhZm9yY2UpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHRzdG9yYWdlLnZpc2liaWxpdHkuc2V0KHRoaXMuZ2V0VGV4dCgpLCAhdGhpcy5pc1Zpc2libGUoKSk7XHJcbn07XHJcblxyXG4vKipcclxuICogU3RhdGUgZ2V0dGVycy5cclxuICovXHJcblxyXG4vKipcclxuICogV2hldGhlciB0aGUgZW1vdGUgaXMgZnJvbSBhIDNyZCBwYXJ0eS5cclxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgZW1vdGUgaXMgZnJvbSBhIDNyZCBwYXJ0eS5cclxuICovXHJcbkVtb3RlLnByb3RvdHlwZS5pc1RoaXJkUGFydHkgPSBmdW5jdGlvbiAoKSB7XHJcblx0cmV0dXJuICEhdGhpcy5nZXRHZXR0ZXJOYW1lKCk7XHJcbn07XHJcblxyXG4vKipcclxuICogV2hldGhlciB0aGUgZW1vdGUgd2FzIGZhdm9yaXRlZC5cclxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgZW1vdGUgd2FzIGZhdm9yaXRlZC5cclxuICovXHJcbkVtb3RlLnByb3RvdHlwZS5pc0Zhdm9yaXRlID0gZnVuY3Rpb24gKCkge1xyXG5cdHJldHVybiBzdG9yYWdlLnN0YXJyZWQuZ2V0KHRoaXMuZ2V0VGV4dCgpLCBmYWxzZSk7XHJcbn07XHJcblxyXG4vKipcclxuICogV2hldGhlciB0aGUgZW1vdGUgaXMgdmlzaWJsZSBvdXRzaWRlIG9mIGVkaXRpbmcgbW9kZS5cclxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgZW1vdGUgaXMgdmlzaWJsZSBvdXRzaWRlIG9mIGVkaXRpbmcgbW9kZS5cclxuICovXHJcbkVtb3RlLnByb3RvdHlwZS5pc1Zpc2libGUgPSBmdW5jdGlvbiAoKSB7XHJcblx0cmV0dXJuIHN0b3JhZ2UudmlzaWJpbGl0eS5nZXQodGhpcy5nZXRUZXh0KCksIHRydWUpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFdoZXRoZXIgdGhlIGVtb3RlIGlzIGNvbnNpZGVyZWQgYSBzaW1wbGUgc21pbGV5LlxyXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHRoZSBlbW90ZSBpcyBjb25zaWRlcmVkIGEgc2ltcGxlIHNtaWxleS5cclxuICovXHJcbkVtb3RlLnByb3RvdHlwZS5pc1NtaWxleSA9IGZ1bmN0aW9uICgpIHtcclxuXHQvLyBUaGUgYmFzaWMgc21pbGV5IGVtb3Rlcy5cclxuXHR2YXIgZW1vdGVzID0gWyc6KCcsICc6KScsICc6LycsICc6XFxcXCcsICc6RCcsICc6bycsICc6cCcsICc6eicsICc7KScsICc7cCcsICc8MycsICc+KCcsICdCKScsICdSKScsICdvX28nLCAnT19PJywgJyMvJywgJzo3JywgJzo+JywgJzpTJywgJzxdJ107XHJcblx0cmV0dXJuIGVtb3Rlcy5pbmRleE9mKHRoaXMuZ2V0VGV4dCgpKSAhPT0gLTE7XHJcbn07XHJcblxyXG4vKipcclxuICogUHJvcGVydHkgZ2V0dGVycy9zZXR0ZXJzLlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSB1c2FibGUgZW1vdGUgdGV4dCBmcm9tIGEgcmVnZXguXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRFbW90ZUZyb21SZWdFeChyZWdleCkge1xyXG5cdGlmICh0eXBlb2YgcmVnZXggPT09ICdzdHJpbmcnKSB7XHJcblx0XHRyZWdleCA9IG5ldyBSZWdFeHAocmVnZXgpO1xyXG5cdH1cclxuXHRpZiAoIXJlZ2V4KSB7XHJcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ2ByZWdleGAgbXVzdCBiZSBhIFJlZ0V4cCBzdHJpbmcgb3Igb2JqZWN0LicpO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIGRlY29kZVVSSShyZWdleC5zb3VyY2UpXHJcblxyXG5cdFx0Ly8gUmVwbGFjZSBIVE1MIGVudGl0eSBicmFja2V0cyB3aXRoIGFjdHVhbCBicmFja2V0cy5cclxuXHRcdC5yZXBsYWNlKCcmZ3RcXFxcOycsICc+JylcclxuXHRcdC5yZXBsYWNlKCcmbHRcXFxcOycsICc8JylcclxuXHJcblx0XHQvLyBSZW1vdmUgbmVnYXRpdmUgZ3JvdXBzLlxyXG5cdFx0Ly9cclxuXHRcdC8vIC9cclxuXHRcdC8vICAgXFwoXFw/ISAgICAgICAgICAgICAgLy8gKD8hXHJcblx0XHQvLyAgIFteKV0qICAgICAgICAgICAgICAvLyBhbnkgYW1vdW50IG9mIGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90IClcclxuXHRcdC8vICAgXFwpICAgICAgICAgICAgICAgICAvLyApXHJcblx0XHQvLyAvZ1xyXG5cdFx0LnJlcGxhY2UoL1xcKFxcPyFbXildKlxcKS9nLCAnJylcclxuXHJcblx0XHQvLyBQaWNrIGZpcnN0IG9wdGlvbiBmcm9tIGEgZ3JvdXAuXHJcblx0XHQvL1xyXG5cdFx0Ly8gL1xyXG5cdFx0Ly8gICBcXCggICAgICAgICAgICAgICAgIC8vIChcclxuXHRcdC8vICAgKFtefF0pKiAgICAgICAgICAgIC8vIGFueSBhbW91bnQgb2YgY2hhcmFjdGVycyB0aGF0IGFyZSBub3QgfFxyXG5cdFx0Ly8gICBcXHw/ICAgICAgICAgICAgICAgIC8vIGFuIG9wdGlvbmFsIHwgY2hhcmFjdGVyXHJcblx0XHQvLyAgIFteKV0qICAgICAgICAgICAgICAvLyBhbnkgYW1vdW50IG9mIGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90IClcclxuXHRcdC8vICAgXFwpICAgICAgICAgICAgICAgICAvLyApXHJcblx0XHQvLyAvZ1xyXG5cdFx0LnJlcGxhY2UoL1xcKChbXnxdKSpcXHw/W14pXSpcXCkvZywgJyQxJylcclxuXHJcblx0XHQvLyBQaWNrIGZpcnN0IGNoYXJhY3RlciBmcm9tIGEgY2hhcmFjdGVyIGdyb3VwLlxyXG5cdFx0Ly9cclxuXHRcdC8vIC9cclxuXHRcdC8vICAgXFxbICAgICAgICAgICAgICAgICAvLyBbXHJcblx0XHQvLyAgIChbXnxcXF1cXFtdKSogICAgICAgIC8vIGFueSBhbW91bnQgb2YgY2hhcmFjdGVycyB0aGF0IGFyZSBub3QgfCwgWywgb3IgXVxyXG5cdFx0Ly8gICBcXHw/ICAgICAgICAgICAgICAgIC8vIGFuIG9wdGlvbmFsIHwgY2hhcmFjdGVyXHJcblx0XHQvLyAgIFteXFxdXSogICAgICAgICAgICAgLy8gYW55IGFtb3VudCBvZiBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBbLCBvciBdXHJcblx0XHQvLyAgIFxcXSAgICAgICAgICAgICAgICAgLy8gXVxyXG5cdFx0Ly8gL2dcclxuXHRcdC5yZXBsYWNlKC9cXFsoW158XFxdXFxbXSkqXFx8P1teXFxdXFxbXSpcXF0vZywgJyQxJylcclxuXHJcblx0XHQvLyBSZW1vdmUgb3B0aW9uYWwgY2hhcmFjdGVycy5cclxuXHRcdC8vXHJcblx0XHQvLyAvXHJcblx0XHQvLyAgIFteXFxcXF0gICAgICAgICAgICAgIC8vIGFueSBjaGFyYWN0ZXIgdGhhdCBpcyBub3QgXFxcclxuXHRcdC8vICAgXFw/ICAgICAgICAgICAgICAgICAvLyA/XHJcblx0XHQvLyAvZ1xyXG5cdFx0LnJlcGxhY2UoL1teXFxcXF1cXD8vZywgJycpXHJcblxyXG5cdFx0Ly8gUmVtb3ZlIGJvdW5kYXJpZXMgYXQgYmVnaW5uaW5nIGFuZCBlbmQuXHJcblx0XHQucmVwbGFjZSgvXlxcXFxifFxcXFxiJC9nLCAnJykgXHJcblxyXG5cdFx0Ly8gVW5lc2NhcGUgb25seSBzaW5nbGUgYmFja3NsYXNoLCBub3QgbXVsdGlwbGUuXHJcblx0XHQvL1xyXG5cdFx0Ly8gL1xyXG5cdFx0Ly8gICBcXFxcICAgICAgICAgICAgICAgICAvLyBcXFxyXG5cdFx0Ly8gICAoPyFcXFxcKSAgICAgICAgICAgICAvLyBsb29rLWFoZWFkLCBhbnkgY2hhcmFjdGVyIHRoYXQgaXNuJ3QgXFxcclxuXHRcdC8vIC9nXHJcblx0XHQucmVwbGFjZSgvXFxcXCg/IVxcXFwpL2csICcnKTtcclxufVxyXG5cclxudmFyIHNvcnRpbmcgPSB7fTtcclxuXHJcbi8qKlxyXG4gKiBTb3J0IGJ5IGFscGhhbnVtZXJpYyBpbiB0aGlzIG9yZGVyOiBzeW1ib2xzIC0+IG51bWJlcnMgLT4gQWFCYi4uLiAtPiBudW1iZXJzXHJcbiAqL1xyXG5zb3J0aW5nLmJ5VGV4dCA9IGZ1bmN0aW9uIChhLCBiKSB7XHJcblx0dGV4dEEgPSBhLmdldFRleHQoKS50b0xvd2VyQ2FzZSgpO1xyXG5cdHRleHRCID0gYi5nZXRUZXh0KCkudG9Mb3dlckNhc2UoKTtcclxuXHJcblx0aWYgKHRleHRBIDwgdGV4dEIpIHtcclxuXHRcdHJldHVybiAtMTtcclxuXHR9XHJcblx0aWYgKHRleHRBID4gdGV4dEIpIHtcclxuXHRcdHJldHVybiAxO1xyXG5cdH1cclxuXHRyZXR1cm4gMDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEJhc2ljIHNtaWxpZXMgYmVmb3JlIG5vbi1iYXNpYyBzbWlsaWVzLlxyXG4gKi9cclxuc29ydGluZy5ieVNtaWxleSA9IGZ1bmN0aW9uIChhLCBiKSB7XHJcblx0aWYgKGEuaXNTbWlsZXkoKSAmJlx0IWIuaXNTbWlsZXkoKSkge1xyXG5cdFx0cmV0dXJuIC0xO1xyXG5cdH1cclxuXHRpZiAoYi5pc1NtaWxleSgpICYmXHQhYS5pc1NtaWxleSgpKSB7XHJcblx0XHRyZXR1cm4gMTtcclxuXHR9XHJcblx0cmV0dXJuIDA7XHJcbn07XHJcblxyXG4vKipcclxuICogR2xvYmFscyBiZWZvcmUgc3Vic2NyaXB0aW9uIGVtb3Rlcywgc3Vic2NyaXB0aW9ucyBpbiBhbHBoYWJldGljYWwgb3JkZXIuXHJcbiAqL1xyXG5zb3J0aW5nLmJ5Q2hhbm5lbE5hbWUgPSBmdW5jdGlvbiAoYSwgYikge1xyXG5cdHZhciBjaGFubmVsQSA9IGEuZ2V0Q2hhbm5lbE5hbWUoKTtcclxuXHR2YXIgY2hhbm5lbEIgPSBiLmdldENoYW5uZWxOYW1lKCk7XHJcblxyXG5cdC8vIEJvdGggZG9uJ3QgaGF2ZSBjaGFubmVscy5cclxuXHRpZiAoIWNoYW5uZWxBICYmICFjaGFubmVsQikge1xyXG5cdFx0cmV0dXJuIDA7XHJcblx0fVxyXG5cclxuXHQvLyBcIkFcIiBoYXMgY2hhbm5lbCwgXCJCXCIgZG9lc24ndC5cclxuXHRpZiAoY2hhbm5lbEEgJiYgIWNoYW5uZWxCKSB7XHJcblx0XHRyZXR1cm4gMTtcclxuXHR9XHJcblx0Ly8gXCJCXCIgaGFzIGNoYW5uZWwsIFwiQVwiIGRvZXNuJ3QuXHJcblx0aWYgKGNoYW5uZWxCICYmICFjaGFubmVsQSkge1xyXG5cdFx0cmV0dXJuIC0xO1xyXG5cdH1cclxuXHJcblx0Y2hhbm5lbEEgPSBjaGFubmVsQS50b0xvd2VyQ2FzZSgpO1xyXG5cdGNoYW5uZWxCID0gY2hhbm5lbEIudG9Mb3dlckNhc2UoKTtcclxuXHJcblx0aWYgKGNoYW5uZWxBIDwgY2hhbm5lbEIpIHtcclxuXHRcdHJldHVybiAtMTtcclxuXHR9XHJcblx0aWYgKGNoYW5uZWxCID4gY2hhbm5lbEEpIHtcclxuXHRcdHJldHVybiAxO1xyXG5cdH1cclxuXHJcblx0Ly8gQWxsIHRoZSBzYW1lXHJcblx0cmV0dXJuIDA7XHJcbn07XHJcblxyXG4vKipcclxuICogVGhlIGdlbmVyYWwgc29ydCBvcmRlciBmb3IgdGhlIGFsbCBlbW90ZXMgY2F0ZWdvcnkuXHJcbiAqIFNtaWxleXMgLT4gQ2hhbm5lbCBncm91cGluZyAtPiBhbHBoYW51bWVyaWNcclxuICovXHJcbnNvcnRpbmcuYWxsRW1vdGVzQ2F0ZWdvcnkgPSBmdW5jdGlvbiAoYSwgYikge1xyXG5cdHZhciBieVNtaWxleSA9IHNvcnRpbmcuYnlTbWlsZXkoYSwgYik7XHJcblx0dmFyIGJ5Q2hhbm5lbE5hbWUgID0gc29ydGluZy5ieUNoYW5uZWxOYW1lKGEsIGIpO1xyXG5cdHZhciBieVRleHQgPSBzb3J0aW5nLmJ5VGV4dChhLCBiKTtcclxuXHJcblx0aWYgKGJ5U21pbGV5ICE9PSAwKSB7XHJcblx0XHRyZXR1cm4gYnlTbWlsZXk7XHJcblx0fVxyXG5cdGlmIChieUNoYW5uZWxOYW1lICE9PSAwKSB7XHJcblx0XHRyZXR1cm4gYnlDaGFubmVsTmFtZTtcclxuXHR9XHJcblx0cmV0dXJuIGJ5VGV4dDtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZW1vdGVTdG9yZTtcclxuIiwidmFyIGFwaSA9IHt9O1xyXG52YXIgaW5zdGFuY2UgPSAnW2luc3RhbmNlICcgKyAoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKDk5OSAtIDEwMCkpICsgMTAwKSArICddICc7XHJcbnZhciBwcmVmaXggPSAnW0Vtb3RlIE1lbnVdICc7XHJcbnZhciBzdG9yYWdlID0gcmVxdWlyZSgnLi9zdG9yYWdlJyk7XHJcblxyXG5hcGkubG9nID0gZnVuY3Rpb24gKCkge1xyXG5cdGlmICh0eXBlb2YgY29uc29sZS5sb2cgPT09ICd1bmRlZmluZWQnKSB7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdGFyZ3VtZW50cyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5tYXAoZnVuY3Rpb24gKGFyZykge1xyXG5cdFx0aWYgKHR5cGVvZiBhcmcgIT09ICdzdHJpbmcnKSB7XHJcblx0XHRcdHJldHVybiBKU09OLnN0cmluZ2lmeShhcmcpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGFyZztcclxuXHR9KTtcclxuXHRpZiAoc3RvcmFnZS5nbG9iYWwuZ2V0KCdkZWJ1Z01lc3NhZ2VzRW5hYmxlZCcsIGZhbHNlKSkge1xyXG5cdFx0YXJndW1lbnRzLnVuc2hpZnQoaW5zdGFuY2UpO1xyXG5cdH1cclxuXHRhcmd1bWVudHMudW5zaGlmdChwcmVmaXgpO1xyXG5cdGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIGFyZ3VtZW50cyk7XHJcbn07XHJcblxyXG5hcGkuZGVidWcgPSBmdW5jdGlvbiAoKSB7XHJcblx0aWYgKCFzdG9yYWdlLmdsb2JhbC5nZXQoJ2RlYnVnTWVzc2FnZXNFbmFibGVkJywgZmFsc2UpKSB7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdGFyZ3VtZW50cyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcclxuXHRhcmd1bWVudHMudW5zaGlmdCgnW0RFQlVHXSAnKTtcclxuXHRhcGkubG9nLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYXBpO1xyXG4iLCJ2YXIgc3RvcmFnZSA9IHJlcXVpcmUoJy4vc3RvcmFnZScpO1xyXG52YXIgbG9nZ2VyID0gcmVxdWlyZSgnLi9sb2dnZXInKTtcclxudmFyIGVtb3RlcyA9IHJlcXVpcmUoJy4vZW1vdGVzJyk7XHJcbnZhciBhcGkgPSB7fTtcclxuXHJcbmFwaS50b2dnbGVEZWJ1ZyA9IGZ1bmN0aW9uIChmb3JjZWQpIHtcclxuXHRpZiAodHlwZW9mIGZvcmNlZCA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuXHRcdGZvcmNlZCA9ICFzdG9yYWdlLmdsb2JhbC5nZXQoJ2RlYnVnTWVzc2FnZXNFbmFibGVkJywgZmFsc2UpO1xyXG5cdH1cclxuXHRlbHNlIHtcclxuXHRcdGZvcmNlZCA9ICEhZm9yY2VkO1xyXG5cdH1cclxuXHRzdG9yYWdlLmdsb2JhbC5zZXQoJ2RlYnVnTWVzc2FnZXNFbmFibGVkJywgZm9yY2VkKTtcclxuXHRsb2dnZXIubG9nKCdEZWJ1ZyBtZXNzYWdlcyBhcmUgbm93ICcgKyAoZm9yY2VkID8gJ2VuYWJsZWQnIDogJ2Rpc2FibGVkJykpO1xyXG59O1xyXG5cclxuYXBpLnJlZ2lzdGVyRW1vdGVHZXR0ZXIgPSBlbW90ZXMucmVnaXN0ZXJHZXR0ZXI7XHJcbmFwaS5kZXJlZ2lzdGVyRW1vdGVHZXR0ZXIgPSBlbW90ZXMuZGVyZWdpc3RlckdldHRlcjtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYXBpO1xyXG4iLCJ2YXIgU3RvcmUgPSByZXF1aXJlKCdzdG9yYWdlLXdyYXBwZXInKTtcclxudmFyIHN0b3JhZ2UgPSB7fTtcclxuXHJcbi8vIEdlbmVyYWwgc3RvcmFnZS5cclxuc3RvcmFnZS5nbG9iYWwgPSBuZXcgU3RvcmUoe1xyXG5cdG5hbWVzcGFjZTogJ2Vtb3RlLW1lbnUtZm9yLXR3aXRjaCdcclxufSk7XHJcblxyXG4vLyBFbW90ZSB2aXNpYmlsaXR5IHN0b3JhZ2UuXHJcbnN0b3JhZ2UudmlzaWJpbGl0eSA9IHN0b3JhZ2UuZ2xvYmFsLmNyZWF0ZVN1YnN0b3JlKCd2aXNpYmlsaXR5Jyk7XHJcbi8vIEVtb3RlIHN0YXJyZWQgc3RvcmFnZS5cclxuc3RvcmFnZS5zdGFycmVkID0gc3RvcmFnZS5nbG9iYWwuY3JlYXRlU3Vic3RvcmUoJ3N0YXJyZWQnKTtcclxuLy8gRGlzcGxheSBuYW1lIHN0b3JhZ2UuXHJcbnN0b3JhZ2UuZGlzcGxheU5hbWVzID0gc3RvcmFnZS5nbG9iYWwuY3JlYXRlU3Vic3RvcmUoJ2Rpc3BsYXlOYW1lcycpO1xyXG4vLyBDaGFubmVsIG5hbWUgc3RvcmFnZS5cclxuc3RvcmFnZS5jaGFubmVsTmFtZXMgPSBzdG9yYWdlLmdsb2JhbC5jcmVhdGVTdWJzdG9yZSgnY2hhbm5lbE5hbWVzJyk7XHJcbi8vIEJhZGdlcyBzdG9yYWdlLlxyXG5zdG9yYWdlLmJhZGdlcyA9IHN0b3JhZ2UuZ2xvYmFsLmNyZWF0ZVN1YnN0b3JlKCdiYWRnZXMnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3RvcmFnZTtcclxuIiwidmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL2J1aWxkL3RlbXBsYXRlcycpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSAoZnVuY3Rpb24gKCkge1xyXG5cdHZhciBkYXRhID0ge307XHJcblx0dmFyIGtleSA9IG51bGw7XHJcblxyXG5cdC8vIENvbnZlcnQgdGVtcGxhdGVzIHRvIHRoZWlyIHNob3J0ZXIgXCJyZW5kZXJcIiBmb3JtLlxyXG5cdGZvciAoa2V5IGluIHRlbXBsYXRlcykge1xyXG5cdFx0aWYgKCF0ZW1wbGF0ZXMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xyXG5cdFx0XHRjb250aW51ZTtcclxuXHRcdH1cclxuXHRcdGRhdGFba2V5XSA9IHJlbmRlcihrZXkpO1xyXG5cdH1cclxuXHJcblx0Ly8gU2hvcnRjdXQgdGhlIHJlbmRlciBmdW5jdGlvbi4gQWxsIHRlbXBsYXRlcyB3aWxsIGJlIHBhc3NlZCBpbiBhcyBwYXJ0aWFscyBieSBkZWZhdWx0LlxyXG5cdGZ1bmN0aW9uIHJlbmRlcih0ZW1wbGF0ZSkge1xyXG5cdFx0dGVtcGxhdGUgPSB0ZW1wbGF0ZXNbdGVtcGxhdGVdO1xyXG5cdFx0cmV0dXJuIGZ1bmN0aW9uIChjb250ZXh0LCBwYXJ0aWFscywgaW5kZW50KSB7XHJcblx0XHRcdHJldHVybiB0ZW1wbGF0ZS5yZW5kZXIoY29udGV4dCwgcGFydGlhbHMgfHwgdGVtcGxhdGVzLCBpbmRlbnQpO1xyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdHJldHVybiBkYXRhO1xyXG59KSgpO1xyXG4iLCJ2YXIgdHdpdGNoQXBpID0gd2luZG93LlR3aXRjaC5hcGk7XHJcbnZhciBqUXVlcnkgPSB3aW5kb3cualF1ZXJ5O1xyXG52YXIgbG9nZ2VyID0gcmVxdWlyZSgnLi9sb2dnZXInKTtcclxudmFyIGFwaSA9IHt9O1xyXG5cclxuYXBpLmdldEJhZGdlcyA9IGZ1bmN0aW9uICh1c2VybmFtZSwgY2FsbGJhY2spIHtcclxuXHRpZiAoXHJcblx0XHRbXHJcblx0XHRcdCd+Z2xvYmFsJyxcclxuXHRcdFx0J3R1cmJvJyxcclxuXHRcdFx0J3R3aXRjaF9wcmltZSdcclxuXHRcdF0uaW5kZXhPZih1c2VybmFtZSkgPiAtMVxyXG5cdCkge1xyXG5cdFx0aWYgKCFqUXVlcnkpIHtcclxuXHRcdFx0Y2FsbGJhY2soe30pO1xyXG5cdFx0fVxyXG5cdFx0Ly8gTm90ZTogbm90IGEgZG9jdW1lbnRlZCBBUEkgZW5kcG9pbnQuXHJcblx0XHRqUXVlcnkuZ2V0SlNPTignaHR0cHM6Ly9iYWRnZXMudHdpdGNoLnR2L3YxL2JhZGdlcy9nbG9iYWwvZGlzcGxheScpXHJcblx0XHRcdC5kb25lKGZ1bmN0aW9uIChhcGkpIHtcclxuXHRcdFx0XHR2YXIgYmFkZ2VzID0ge1xyXG5cdFx0XHRcdFx0dHVyYm86IHtcclxuXHRcdFx0XHRcdFx0aW1hZ2U6IGFwaS5iYWRnZV9zZXRzLnR1cmJvLnZlcnNpb25zWycxJ10uaW1hZ2VfdXJsXzF4XHJcblx0XHRcdFx0XHR9LFxyXG5cdFx0XHRcdFx0cHJlbWl1bToge1xyXG5cdFx0XHRcdFx0XHRpbWFnZTogYXBpLmJhZGdlX3NldHMucHJlbWl1bS52ZXJzaW9uc1snMSddLmltYWdlX3VybF8xeFxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH07XHJcblx0XHRcdFx0Y2FsbGJhY2soYmFkZ2VzKTtcclxuXHRcdFx0fSlcclxuXHRcdFx0LmZhaWwoZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdGNhbGxiYWNrKHt9KTtcclxuXHRcdFx0fSk7XHJcblx0fVxyXG5cdGVsc2Uge1xyXG5cdFx0dHdpdGNoQXBpLmdldCgnY2hhdC8nICsgdXNlcm5hbWUgKyAnL2JhZGdlcycpXHJcblx0XHRcdC5kb25lKGZ1bmN0aW9uIChhcGkpIHtcclxuXHRcdFx0XHRjYWxsYmFjayhhcGkpO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHQuZmFpbChmdW5jdGlvbiAoKSB7XHJcblx0XHRcdFx0Y2FsbGJhY2soe30pO1xyXG5cdFx0XHR9KTtcclxuXHR9XHJcbn07XHJcblxyXG5hcGkuZ2V0VXNlciA9IGZ1bmN0aW9uICh1c2VybmFtZSwgY2FsbGJhY2spIHtcclxuXHQvLyBOb3RlOiBub3QgYSBkb2N1bWVudGVkIEFQSSBlbmRwb2ludC5cclxuXHR0d2l0Y2hBcGkuZ2V0KCd1c2Vycy8nICsgdXNlcm5hbWUpXHJcblx0XHQuZG9uZShmdW5jdGlvbiAoYXBpKSB7XHJcblx0XHRcdGNhbGxiYWNrKGFwaSk7XHJcblx0XHR9KVxyXG5cdFx0LmZhaWwoZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRjYWxsYmFjayh7fSk7XHJcblx0XHR9KTtcclxufTtcclxuXHJcbmFwaS5nZXRUaWNrZXRzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XHJcblx0Ly8gTm90ZTogbm90IGEgZG9jdW1lbnRlZCBBUEkgZW5kcG9pbnQuXHJcblx0dHdpdGNoQXBpLmdldChcclxuXHRcdCcvYXBpL3VzZXJzLzpsb2dpbi90aWNrZXRzJyxcclxuXHRcdHtcclxuXHRcdFx0b2Zmc2V0OiAwLFxyXG5cdFx0XHRsaW1pdDogMTAwLFxyXG5cdFx0XHR1bmVuZGVkOiB0cnVlXHJcblx0XHR9XHJcblx0KVxyXG5cdFx0LmRvbmUoZnVuY3Rpb24gKGFwaSkge1xyXG5cdFx0XHRjYWxsYmFjayhhcGkudGlja2V0cyB8fCBbXSk7XHJcblx0XHR9KVxyXG5cdFx0LmZhaWwoZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRjYWxsYmFjayhbXSk7XHJcblx0XHR9KTtcclxufTtcclxuXHJcbmFwaS5nZXRFbW90ZXMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcclxuXHR0d2l0Y2hBcGkuZ2V0KCd1c2Vycy86bG9naW4vZW1vdGVzJylcclxuXHRcdC5kb25lKGZ1bmN0aW9uIChyZXNwb25zZSkge1xyXG5cdFx0XHRpZiAoIXJlc3BvbnNlIHx8ICFyZXNwb25zZS5lbW90aWNvbl9zZXRzKSB7XHJcblx0XHRcdFx0bG9nZ2VyLmRlYnVnKCdnZXRFbW90ZXMgZW1vdGljb25fc2V0cyBlbXB0eScpO1xyXG5cdFx0XHRcdGNhbGxiYWNrKHt9KTtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGNhbGxiYWNrKHJlc3BvbnNlLmVtb3RpY29uX3NldHMpO1xyXG5cdFx0fSlcclxuXHRcdC5mYWlsKGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0bG9nZ2VyLmRlYnVnKCdnZXRFbW90ZXMgQVBJIGNhbGwgZmFpbGVkJyk7XHJcblx0XHRcdGNhbGxiYWNrKHt9KTtcclxuXHRcdH0pO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhcGk7XHJcbiIsInZhciBhcGkgPSB7fTtcclxudmFyICQgPSBqUXVlcnkgPSB3aW5kb3cualF1ZXJ5O1xyXG52YXIgdGVtcGxhdGVzID0gcmVxdWlyZSgnLi90ZW1wbGF0ZXMnKTtcclxudmFyIHN0b3JhZ2UgPSByZXF1aXJlKCcuL3N0b3JhZ2UnKTtcclxudmFyIGVtb3RlcyA9IHJlcXVpcmUoJy4vZW1vdGVzJyk7XHJcbnZhciBsb2dnZXIgPSByZXF1aXJlKCcuL2xvZ2dlcicpO1xyXG5cclxudmFyIHRoZU1lbnUgPSBuZXcgVUlNZW51KCk7XHJcbnZhciB0aGVNZW51QnV0dG9uID0gbmV3IFVJTWVudUJ1dHRvbigpO1xyXG5cclxuYXBpLmluaXQgPSBmdW5jdGlvbiAoKSB7XHJcblx0Ly8gTG9hZCBDU1MuXHJcblx0cmVxdWlyZSgnLi4vLi4vYnVpbGQvc3R5bGVzJyk7XHJcblxyXG5cdC8vIExvYWQgalF1ZXJ5IHBsdWdpbnMuXHJcblx0cmVxdWlyZSgnLi4vcGx1Z2lucy9yZXNpemFibGUnKTtcclxuXHRyZXF1aXJlKCdqcXVlcnkuc2Nyb2xsYmFyJyk7XHJcblxyXG5cdHRoZU1lbnVCdXR0b24uaW5pdCgpO1xyXG5cdHRoZU1lbnUuaW5pdCgpO1xyXG59O1xyXG5cclxuYXBpLmhpZGVNZW51ID0gZnVuY3Rpb24gKCkge1xyXG5cdGlmICh0aGVNZW51LmRvbSAmJiB0aGVNZW51LmRvbS5sZW5ndGgpIHtcclxuXHRcdHRoZU1lbnUudG9nZ2xlRGlzcGxheShmYWxzZSk7XHJcblx0fVxyXG59O1xyXG5cclxuYXBpLnVwZGF0ZUVtb3RlcyA9IGZ1bmN0aW9uICgpIHtcclxuXHR0aGVNZW51LnVwZGF0ZUVtb3RlcygpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBVSU1lbnVCdXR0b24oKSB7XHJcblx0dGhpcy5kb20gPSBudWxsO1xyXG59XHJcblxyXG5VSU1lbnVCdXR0b24ucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAodGltZXNGYWlsZWQpIHtcclxuXHR2YXIgc2VsZiA9IHRoaXM7XHJcblx0dmFyIGNoYXRCdXR0b24gPSAkKCcuc2VuZC1jaGF0LWJ1dHRvbiwgLmNoYXQtYnV0dG9ucy1jb250YWluZXIgYnV0dG9uJyk7XHJcblx0dmFyIGZhaWxDb3VudGVyID0gdGltZXNGYWlsZWQgfHwgMDtcclxuXHR0aGlzLmRvbSA9ICQoJyNlbW90ZS1tZW51LWJ1dHRvbicpO1xyXG5cclxuXHQvLyBFbGVtZW50IGFscmVhZHkgZXhpc3RzLlxyXG5cdGlmICh0aGlzLmRvbS5sZW5ndGgpIHtcclxuXHRcdGxvZ2dlci5kZWJ1ZygnTWVudUJ1dHRvbiBhbHJlYWR5IGV4aXN0cywgc3RvcHBpbmcgaW5pdC4nKTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHJcblx0aWYgKCFjaGF0QnV0dG9uLmxlbmd0aCkge1xyXG5cdFx0ZmFpbENvdW50ZXIgKz0gMTtcclxuXHRcdGlmIChmYWlsQ291bnRlciA9PT0gMSkge1xyXG5cdFx0XHRsb2dnZXIubG9nKCdNZW51QnV0dG9uIGNvbnRhaW5lciBtaXNzaW5nLCB0cnlpbmcgYWdhaW4uJyk7XHJcblx0XHR9XHJcblx0XHRpZiAoZmFpbENvdW50ZXIgPj0gMTApIHtcclxuXHRcdFx0bG9nZ2VyLmxvZygnTWVudUJ1dHRvbiBjb250YWluZXIgbWlzc2luZywgTWVudUJ1dHRvbiB1bmFibGUgdG8gYmUgYWRkZWQsIHN0b3BwaW5nIGluaXQuJyk7XHJcblx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0fVxyXG5cdFx0c2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcblx0XHRcdHNlbGYuaW5pdChmYWlsQ291bnRlcik7XHJcblx0XHR9LCAxMDAwKTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHJcblx0Ly8gQ3JlYXRlIGVsZW1lbnQuXHJcblx0dGhpcy5kb20gPSAkKHRlbXBsYXRlcy5lbW90ZUJ1dHRvbigpKTtcclxuXHR0aGlzLmRvbS5pbnNlcnRCZWZvcmUoY2hhdEJ1dHRvbik7XHJcblxyXG5cdC8vIEhpZGUgdGhlbiBmYWRlIGl0IGluLlxyXG5cdHRoaXMuZG9tLmhpZGUoKTtcclxuXHR0aGlzLmRvbS5mYWRlSW4oKTtcclxuXHJcblx0Ly8gRW5hYmxlIGNsaWNraW5nLlxyXG5cdHRoaXMuZG9tLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcclxuXHRcdHRoZU1lbnUudG9nZ2xlRGlzcGxheSgpO1xyXG5cdH0pO1xyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcblVJTWVudUJ1dHRvbi5wcm90b3R5cGUudG9nZ2xlRGlzcGxheSA9IGZ1bmN0aW9uIChmb3JjZWQpIHtcclxuXHR2YXIgc3RhdGUgPSB0eXBlb2YgZm9yY2VkICE9PSAndW5kZWZpbmVkJyA/ICEhZm9yY2VkIDogIXRoaXMuaXNWaXNpYmxlKCk7XHJcblx0aWYgKHN0YXRlKSB7XHJcblx0XHR0aGlzLmRvbS5hZGRDbGFzcygnYWN0aXZlJyk7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0dGhpcy5kb20ucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcblVJTWVudUJ1dHRvbi5wcm90b3R5cGUuaXNWaXNpYmxlID0gZnVuY3Rpb24gKCkge1xyXG5cdHJldHVybiB0aGlzLmRvbS5oYXNDbGFzcygnYWN0aXZlJyk7XHJcbn07XHJcblxyXG5mdW5jdGlvbiBVSU1lbnUoKSB7XHJcblx0dGhpcy5kb20gPSBudWxsO1xyXG5cdHRoaXMuZ3JvdXBzID0ge307XHJcblx0dGhpcy5lbW90ZXMgPSBbXTtcclxuXHR0aGlzLm9mZnNldCA9IG51bGw7XHJcblx0dGhpcy5mYXZvcml0ZXMgPSBudWxsO1xyXG59XHJcblxyXG5VSU1lbnUucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XHJcblx0dmFyIGxvZ2dlciA9IHJlcXVpcmUoJy4vbG9nZ2VyJyk7XHJcblx0dmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuXHR0aGlzLmRvbSA9ICQoJyNlbW90ZS1tZW51LWZvci10d2l0Y2gnKTtcclxuXHJcblx0Ly8gRWxlbWVudCBhbHJlYWR5IGV4aXN0cy5cclxuXHRpZiAodGhpcy5kb20ubGVuZ3RoKSB7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblxyXG5cdC8vIENyZWF0ZSBlbGVtZW50LlxyXG5cdHRoaXMuZG9tID0gJCh0ZW1wbGF0ZXMubWVudSgpKTtcclxuXHQkKGRvY3VtZW50LmJvZHkpLmFwcGVuZCh0aGlzLmRvbSk7XHJcblxyXG5cdHRoaXMuZmF2b3JpdGVzID0gbmV3IFVJRmF2b3JpdGVzR3JvdXAoKTtcclxuXHJcblx0Ly8gRW5hYmxlIGRyYWdnaW5nLlxyXG5cdHRoaXMuZG9tLmRyYWdnYWJsZSh7XHJcblx0XHRoYW5kbGU6ICcuZHJhZ2dhYmxlJyxcclxuXHRcdHN0YXJ0OiBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdHNlbGYudG9nZ2xlUGlubmVkKHRydWUpO1xyXG5cdFx0XHRzZWxmLnRvZ2dsZU1vdmVtZW50KHRydWUpO1xyXG5cdFx0fSxcclxuXHRcdHN0b3A6IGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0c2VsZi5vZmZzZXQgPSBzZWxmLmRvbS5vZmZzZXQoKTtcclxuXHRcdH0sXHJcblx0XHRjb250YWlubWVudDogJChkb2N1bWVudC5ib2R5KVxyXG5cdH0pO1xyXG5cclxuXHQvLyBFbmFibGUgcmVzaXppbmcuXHJcblx0dGhpcy5kb20ucmVzaXphYmxlKHtcclxuXHRcdGhhbmRsZTogJ1tkYXRhLWNvbW1hbmQ9XCJyZXNpemUtaGFuZGxlXCJdJyxcclxuXHRcdHN0b3A6IGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0c2VsZi50b2dnbGVQaW5uZWQodHJ1ZSk7XHJcblx0XHRcdHNlbGYudG9nZ2xlTW92ZW1lbnQodHJ1ZSk7XHJcblx0XHR9LFxyXG5cdFx0YWxzb1Jlc2l6ZTogc2VsZi5kb20uZmluZCgnLnNjcm9sbGFibGUnKSxcclxuXHRcdGNvbnRhaW5tZW50OiAkKGRvY3VtZW50LmJvZHkpLFxyXG5cdFx0bWluSGVpZ2h0OiAxODAsXHJcblx0XHRtaW5XaWR0aDogMjAwXHJcblx0fSk7XHJcblxyXG5cdC8vIEVuYWJsZSBwaW5uaW5nLlxyXG5cdHRoaXMuZG9tLmZpbmQoJ1tkYXRhLWNvbW1hbmQ9XCJ0b2dnbGUtcGlubmVkXCJdJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xyXG5cdFx0c2VsZi50b2dnbGVQaW5uZWQoKTtcclxuXHR9KTtcclxuXHJcblx0Ly8gRW5hYmxlIGVkaXRpbmcuXHJcblx0dGhpcy5kb20uZmluZCgnW2RhdGEtY29tbWFuZD1cInRvZ2dsZS1lZGl0aW5nXCJdJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xyXG5cdFx0c2VsZi50b2dnbGVFZGl0aW5nKCk7XHJcblx0fSk7XHJcblxyXG5cdHRoaXMuZG9tLmZpbmQoJy5zY3JvbGxhYmxlJykuc2Nyb2xsYmFyKClcclxuXHJcblx0dGhpcy51cGRhdGVFbW90ZXMoKTtcclxuXHJcblx0cmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5VSU1lbnUucHJvdG90eXBlLl9kZXRlY3RPdXRzaWRlQ2xpY2sgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuXHQvLyBOb3Qgb3V0c2lkZSBvZiB0aGUgbWVudSwgaWdub3JlIHRoZSBjbGljay5cclxuXHRpZiAoJChldmVudC50YXJnZXQpLmlzKCcjZW1vdGUtbWVudS1mb3ItdHdpdGNoLCAjZW1vdGUtbWVudS1mb3ItdHdpdGNoIConKSkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0Ly8gQ2xpY2tlZCBvbiB0aGUgbWVudSBidXR0b24sIGp1c3QgcmVtb3ZlIHRoZSBsaXN0ZW5lciBhbmQgbGV0IHRoZSBub3JtYWwgbGlzdGVuZXIgaGFuZGxlIGl0LlxyXG5cdGlmICghdGhpcy5pc1Zpc2libGUoKSB8fCAkKGV2ZW50LnRhcmdldCkuaXMoJyNlbW90ZS1tZW51LWJ1dHRvbiwgI2Vtb3RlLW1lbnUtYnV0dG9uIConKSkge1xyXG5cdFx0JChkb2N1bWVudCkub2ZmKCdtb3VzZXVwJywgdGhpcy5fZGV0ZWN0T3V0c2lkZUNsaWNrLmJpbmQodGhpcykpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0Ly8gQ2xpY2tlZCBvdXRzaWRlLCBtYWtlIHN1cmUgdGhlIG1lbnUgaXNuJ3QgcGlubmVkLlxyXG5cdGlmICghdGhpcy5pc1Bpbm5lZCgpKSB7XHJcblx0XHQvLyBNZW51IHdhc24ndCBwaW5uZWQsIHJlbW92ZSBsaXN0ZW5lci5cclxuXHRcdCQoZG9jdW1lbnQpLm9mZignbW91c2V1cCcsIHRoaXMuX2RldGVjdE91dHNpZGVDbGljay5iaW5kKHRoaXMpKTtcclxuXHRcdHRoaXMudG9nZ2xlRGlzcGxheSgpO1xyXG5cdH1cclxufTtcclxuXHJcblVJTWVudS5wcm90b3R5cGUudG9nZ2xlRGlzcGxheSA9IGZ1bmN0aW9uIChmb3JjZWQpIHtcclxuXHR2YXIgc3RhdGUgPSB0eXBlb2YgZm9yY2VkICE9PSAndW5kZWZpbmVkJyA/ICEhZm9yY2VkIDogIXRoaXMuaXNWaXNpYmxlKCk7XHJcblx0dmFyIGxvZ2dlZEluID0gd2luZG93LlR3aXRjaCAmJiB3aW5kb3cuVHdpdGNoLnVzZXIuaXNMb2dnZWRJbigpO1xyXG5cclxuXHQvLyBNZW51IHNob3VsZCBiZSBzaG93bi5cclxuXHRpZiAoc3RhdGUpIHtcclxuXHRcdC8vIENoZWNrIGlmIHVzZXIgaXMgbG9nZ2VkIGluLlxyXG5cdFx0aWYgKCFsb2dnZWRJbikge1xyXG5cdFx0XHQvLyBDYWxsIG5hdGl2ZSBsb2dpbiBmb3JtLlxyXG5cdFx0XHQkLmxvZ2luKCk7XHJcblx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMudXBkYXRlRW1vdGVzKCk7XHJcblx0XHR0aGlzLmRvbS5zaG93KCk7XHJcblxyXG5cdFx0Ly8gTWVudSBtb3ZlZCwgbW92ZSBpdCBiYWNrLlxyXG5cdFx0aWYgKHRoaXMuaGFzTW92ZWQoKSkge1xyXG5cdFx0XHR0aGlzLmRvbS5vZmZzZXQodGhpcy5vZmZzZXQpO1xyXG5cdFx0fVxyXG5cdFx0Ly8gTmV2ZXIgbW92ZWQsIG1ha2UgaXQgdGhlIHNhbWUgc2l6ZSBhcyB0aGUgY2hhdCB3aW5kb3cuXHJcblx0XHRlbHNlIHtcclxuXHRcdFx0dmFyIGNoYXRDb250YWluZXIgPSAkKCcuY2hhdC1tZXNzYWdlcycpO1xyXG5cdFx0XHRcclxuXHRcdFx0Ly8gQWRqdXN0IHRoZSBzaXplIHRvIGJlIHRoZSBzYW1lIGFzIHRoZSBjaGF0IGNvbnRhaW5lci5cclxuXHRcdFx0dGhpcy5kb20uaGVpZ2h0KGNoYXRDb250YWluZXIub3V0ZXJIZWlnaHQoKSAtICh0aGlzLmRvbS5vdXRlckhlaWdodCgpIC0gdGhpcy5kb20uaGVpZ2h0KCkpKTtcclxuXHRcdFx0dGhpcy5kb20ud2lkdGgoY2hhdENvbnRhaW5lci5vdXRlcldpZHRoKCkgLSAodGhpcy5kb20ub3V0ZXJXaWR0aCgpIC0gdGhpcy5kb20ud2lkdGgoKSkpO1xyXG5cclxuXHRcdFx0Ly8gQWRqdXN0IHRoZSBvZmZzZXQgdG8gYmUgdGhlIHNhbWUgYXMgdGhlIGNoYXQgY29udGFpbmVyLlxyXG5cdFx0XHR0aGlzLm9mZnNldCA9IGNoYXRDb250YWluZXIub2Zmc2V0KCk7XHJcblx0XHRcdHRoaXMuZG9tLm9mZnNldCh0aGlzLm9mZnNldCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gTGlzdGVuIGZvciBvdXRzaWRlIGNsaWNrLlxyXG5cdFx0JChkb2N1bWVudCkub24oJ21vdXNldXAnLCB0aGlzLl9kZXRlY3RPdXRzaWRlQ2xpY2suYmluZCh0aGlzKSk7XHJcblx0fVxyXG5cdC8vIE1lbnUgc2hvdWxkIGJlIGhpZGRlbi5cclxuXHRlbHNlIHtcclxuXHRcdHRoaXMuZG9tLmhpZGUoKTtcclxuXHRcdHRoaXMudG9nZ2xlRWRpdGluZyhmYWxzZSk7XHJcblx0XHR0aGlzLnRvZ2dsZVBpbm5lZChmYWxzZSk7XHJcblx0fVxyXG5cclxuXHQvLyBBbHNvIHRvZ2dsZSB0aGUgbWVudSBidXR0b24uXHJcblx0dGhlTWVudUJ1dHRvbi50b2dnbGVEaXNwbGF5KHRoaXMuaXNWaXNpYmxlKCkpO1xyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcblVJTWVudS5wcm90b3R5cGUuaXNWaXNpYmxlID0gZnVuY3Rpb24gKCkge1xyXG5cdHJldHVybiB0aGlzLmRvbS5pcygnOnZpc2libGUnKTtcclxufTtcclxuXHJcblVJTWVudS5wcm90b3R5cGUudXBkYXRlRW1vdGVzID0gZnVuY3Rpb24gKHdoaWNoKSB7XHJcblx0dmFyIGVtb3RlID0gd2hpY2ggPyB0aGlzLmdldEVtb3RlKHdoaWNoKSA6IG51bGw7XHJcblx0dmFyIGZhdm9yaXRlRW1vdGUgPSBlbW90ZSA/IHRoaXMuZmF2b3JpdGVzLmdldEVtb3RlKHdoaWNoKSA6IG51bGw7XHJcblx0aWYgKGVtb3RlKSB7XHJcblx0XHRlbW90ZS51cGRhdGUoKTtcclxuXHRcdGlmIChmYXZvcml0ZUVtb3RlKSB7XHJcblx0XHRcdGZhdm9yaXRlRW1vdGUudXBkYXRlKCk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0dmFyIGVtb3RlcyA9IHJlcXVpcmUoJy4vZW1vdGVzJyk7XHJcblx0dmFyIHRoZUVtb3RlcyA9IGVtb3Rlcy5nZXRFbW90ZXMoKTtcclxuXHR2YXIgdGhlRW1vdGVzS2V5cyA9IFtdO1xyXG5cdHZhciBzZWxmID0gdGhpcztcclxuXHJcblx0dGhlRW1vdGVzLmZvckVhY2goZnVuY3Rpb24gKGVtb3RlSW5zdGFuY2UpIHtcclxuXHRcdHNlbGYuYWRkRW1vdGUoZW1vdGVJbnN0YW5jZSk7XHJcblx0XHR0aGVFbW90ZXNLZXlzLnB1c2goZW1vdGVJbnN0YW5jZS5nZXRUZXh0KCkpO1xyXG5cdH0pO1xyXG5cclxuXHQvLyBEaWZmZXJlbmNlIHRoZSBlbW90ZXMgYW5kIHJlbW92ZSBhbGwgbm9uLXZhbGlkIGVtb3Rlcy5cclxuXHR0aGlzLmVtb3Rlcy5mb3JFYWNoKGZ1bmN0aW9uIChvbGRFbW90ZSkge1xyXG5cdFx0dmFyIHRleHQgPSBvbGRFbW90ZS5nZXRUZXh0KClcclxuXHRcdGlmICh0aGVFbW90ZXNLZXlzLmluZGV4T2YodGV4dCkgPCAwKSB7XHJcblx0XHRcdGxvZ2dlci5kZWJ1ZygnRW1vdGUgZGlmZmVyZW5jZSBmb3VuZCwgcmVtb3ZpbmcgZW1vdGUgZnJvbSBVSTogJyArIHRleHQpO1xyXG5cdFx0XHRzZWxmLnJlbW92ZUVtb3RlKHRleHQpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cclxuXHQvLyBTYXZlIHRoZSBlbW90ZXMgZm9yIG5leHQgZGlmZmVyZW5jaW5nLlxyXG5cdHRoaXMuZW1vdGVzID0gdGhlRW1vdGVzO1xyXG5cclxuXHQvL1VwZGF0ZSBncm91cHMuXHJcblx0T2JqZWN0LmtleXModGhpcy5ncm91cHMpLmZvckVhY2goZnVuY3Rpb24gKGdyb3VwKSB7XHJcblx0XHRzZWxmLmdldEdyb3VwKGdyb3VwKS5pbml0KCk7XHJcblx0fSk7XHJcblxyXG5cdHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuVUlNZW51LnByb3RvdHlwZS50b2dnbGVFZGl0aW5nID0gZnVuY3Rpb24gKGZvcmNlZCkge1xyXG5cdHZhciBzdGF0ZSA9IHR5cGVvZiBmb3JjZWQgIT09ICd1bmRlZmluZWQnID8gISFmb3JjZWQgOiAhdGhpcy5pc0VkaXRpbmcoKTtcclxuXHR0aGlzLmRvbS50b2dnbGVDbGFzcygnZWRpdGluZycsIHN0YXRlKTtcclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcblVJTWVudS5wcm90b3R5cGUuaXNFZGl0aW5nID0gZnVuY3Rpb24gKCkge1xyXG5cdHJldHVybiB0aGlzLmRvbS5oYXNDbGFzcygnZWRpdGluZycpO1xyXG59O1xyXG5cclxuVUlNZW51LnByb3RvdHlwZS50b2dnbGVQaW5uZWQgPSBmdW5jdGlvbiAoZm9yY2VkKSB7XHJcblx0dmFyIHN0YXRlID0gdHlwZW9mIGZvcmNlZCAhPT0gJ3VuZGVmaW5lZCcgPyAhIWZvcmNlZCA6ICF0aGlzLmlzUGlubmVkKCk7XHJcblx0dGhpcy5kb20udG9nZ2xlQ2xhc3MoJ3Bpbm5lZCcsIHN0YXRlKTtcclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcblVJTWVudS5wcm90b3R5cGUuaXNQaW5uZWQgPSBmdW5jdGlvbiAoKSB7XHJcblx0cmV0dXJuIHRoaXMuZG9tLmhhc0NsYXNzKCdwaW5uZWQnKTtcclxufTtcclxuXHJcblVJTWVudS5wcm90b3R5cGUudG9nZ2xlTW92ZW1lbnQgPSBmdW5jdGlvbiAoZm9yY2VkKSB7XHJcblx0dmFyIHN0YXRlID0gdHlwZW9mIGZvcmNlZCAhPT0gJ3VuZGVmaW5lZCcgPyAhIWZvcmNlZCA6ICF0aGlzLmhhc01vdmVkKCk7XHJcblx0dGhpcy5kb20udG9nZ2xlQ2xhc3MoJ21vdmVkJywgc3RhdGUpO1xyXG5cdHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuVUlNZW51LnByb3RvdHlwZS5oYXNNb3ZlZCA9IGZ1bmN0aW9uICgpIHtcclxuXHRyZXR1cm4gdGhpcy5kb20uaGFzQ2xhc3MoJ21vdmVkJyk7XHJcbn07XHJcblxyXG5VSU1lbnUucHJvdG90eXBlLmFkZEdyb3VwID0gZnVuY3Rpb24gKGVtb3RlSW5zdGFuY2UpIHtcclxuXHR2YXIgY2hhbm5lbCA9IGVtb3RlSW5zdGFuY2UuZ2V0Q2hhbm5lbE5hbWUoKTtcclxuXHR2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG5cdC8vIEFscmVhZHkgYWRkZWQsIGRvbid0IGFkZCBhZ2Fpbi5cclxuXHRpZiAodGhpcy5nZXRHcm91cChjaGFubmVsKSkge1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cclxuXHQvLyBBZGQgdG8gY3VycmVudCBtZW51IGdyb3Vwcy5cclxuXHR2YXIgZ3JvdXAgPSBuZXcgVUlHcm91cChlbW90ZUluc3RhbmNlKTtcclxuXHR0aGlzLmdyb3Vwc1tjaGFubmVsXSA9IGdyb3VwO1xyXG5cclxuXHQvLyBTb3J0IGdyb3VwIG5hbWVzLCBnZXQgaW5kZXggb2Ygd2hlcmUgdGhpcyBncm91cCBzaG91bGQgZ28uXHJcblx0dmFyIGtleXMgPSBPYmplY3Qua2V5cyh0aGlzLmdyb3Vwcyk7XHJcblx0a2V5cy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XHJcblx0XHQvLyBHZXQgdGhlIGluc3RhbmNlcy5cclxuXHRcdGEgPSBzZWxmLmdyb3Vwc1thXS5lbW90ZUluc3RhbmNlO1xyXG5cdFx0YiA9IHNlbGYuZ3JvdXBzW2JdLmVtb3RlSW5zdGFuY2U7XHJcblxyXG5cdFx0Ly8gR2V0IHRoZSBjaGFubmVsIG5hbWUuXHJcblx0XHR2YXIgYUNoYW5uZWwgPSBhLmdldENoYW5uZWxOYW1lKCk7XHJcblx0XHR2YXIgYkNoYW5uZWwgPSBiLmdldENoYW5uZWxOYW1lKCk7XHJcblxyXG5cdFx0Ly8gR2V0IHRoZSBjaGFubmVsIGRpc3BsYXkgbmFtZS5cclxuXHRcdGEgPSBhLmdldENoYW5uZWxEaXNwbGF5TmFtZSgpLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRiID0gYi5nZXRDaGFubmVsRGlzcGxheU5hbWUoKS50b0xvd2VyQ2FzZSgpO1xyXG5cclxuXHRcdC8vIFByaW1lIGdvZXMgZmlyc3QsIGFsd2F5cy5cclxuXHRcdGlmIChhQ2hhbm5lbCA9PT0gJ3R3aXRjaF9wcmltZScgJiYgYkNoYW5uZWwgIT09ICd0d2l0Y2hfcHJpbWUnKSB7XHJcblx0XHRcdHJldHVybiAtMTtcclxuXHRcdH1cclxuXHRcdGlmIChiQ2hhbm5lbCA9PT0gJ3R3aXRjaF9wcmltZScgJiYgYUNoYW5uZWwgIT09ICd0d2l0Y2hfcHJpbWUnKSB7XHJcblx0XHRcdHJldHVybiAxO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFR1cmJvIGdvZXMgYWZ0ZXIgUHJpbWUsIGFsd2F5cy5cclxuXHRcdGlmIChhQ2hhbm5lbCA9PT0gJ3R1cmJvJyAmJiBiQ2hhbm5lbCAhPT0gJ3R1cmJvJykge1xyXG5cdFx0XHRyZXR1cm4gLTE7XHJcblx0XHR9XHJcblx0XHRpZiAoYkNoYW5uZWwgPT09ICd0dXJibycgJiYgYUNoYW5uZWwgIT09ICd0dXJibycpIHtcclxuXHRcdFx0cmV0dXJuIDE7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gR2xvYmFsIGdvZXMgYWZ0ZXIgVHVyYm8sIGFsd2F5cy5cclxuXHRcdGlmIChhQ2hhbm5lbCA9PT0gJ35nbG9iYWwnICYmIGJDaGFubmVsICE9PSAnfmdsb2JhbCcpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cdFx0aWYgKGJDaGFubmVsID09PSAnfmdsb2JhbCcgJiYgYUNoYW5uZWwgIT09ICd+Z2xvYmFsJykge1xyXG5cdFx0XHRyZXR1cm4gMTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBBIGdvZXMgZmlyc3QuXHJcblx0XHRpZiAoYSA8IGIpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cdFx0Ly8gQiBnb2VzdCBmaXJzdC5cclxuXHRcdGlmIChhID4gYikge1xyXG5cdFx0XHRyZXR1cm4gMTtcclxuXHRcdH1cclxuXHRcdC8vIEJvdGggdGhlIHNhbWUsIGRvZXNuJ3QgbWF0dGVyLlxyXG5cdFx0cmV0dXJuIDA7XHJcblx0fSk7XHJcblxyXG5cdHZhciBpbmRleCA9IGtleXMuaW5kZXhPZihjaGFubmVsKTtcclxuXHJcblx0Ly8gRmlyc3QgaW4gdGhlIHNvcnQsIHBsYWNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIG1lbnUuXHJcblx0aWYgKGluZGV4ID09PSAwKSB7XHJcblx0XHRncm91cC5kb20ucHJlcGVuZFRvKHRoaXMuZG9tLmZpbmQoJyNhbGwtZW1vdGVzLWdyb3VwJykpO1xyXG5cdH1cclxuXHQvLyBJbnNlcnQgYWZ0ZXIgdGhlIHByZXZpb3VzIGdyb3VwIGluIHRoZSBzb3J0LlxyXG5cdGVsc2Uge1xyXG5cdFx0Z3JvdXAuZG9tLmluc2VydEFmdGVyKHRoaXMuZ2V0R3JvdXAoa2V5c1tpbmRleCAtIDFdKS5kb20pO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIGdyb3VwO1xyXG59O1xyXG5cclxuVUlNZW51LnByb3RvdHlwZS5nZXRHcm91cCA9IGZ1bmN0aW9uIChuYW1lKSB7XHJcblx0cmV0dXJuIHRoaXMuZ3JvdXBzW25hbWVdIHx8IG51bGw7XHJcbn07XHJcblxyXG5VSU1lbnUucHJvdG90eXBlLmFkZEVtb3RlID0gZnVuY3Rpb24gKGVtb3RlSW5zdGFuY2UpIHtcclxuXHQvLyBHZXQgdGhlIGdyb3VwLCBvciBhZGQgaWYgbmVlZGVkLlxyXG5cdHZhciBncm91cCA9IHRoaXMuZ2V0R3JvdXAoZW1vdGVJbnN0YW5jZS5nZXRDaGFubmVsTmFtZSgpKSB8fCB0aGlzLmFkZEdyb3VwKGVtb3RlSW5zdGFuY2UpO1xyXG5cclxuXHRncm91cC5hZGRFbW90ZShlbW90ZUluc3RhbmNlKTtcclxuXHRncm91cC50b2dnbGVEaXNwbGF5KGdyb3VwLmlzVmlzaWJsZSgpLCB0cnVlKTtcclxuXHJcblx0dGhpcy5mYXZvcml0ZXMuYWRkRW1vdGUoZW1vdGVJbnN0YW5jZSk7XHJcblxyXG5cdHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuVUlNZW51LnByb3RvdHlwZS5yZW1vdmVFbW90ZSA9IGZ1bmN0aW9uIChuYW1lKSB7XHJcblx0dmFyIHNlbGYgPSB0aGlzO1xyXG5cdE9iamVjdC5rZXlzKHRoaXMuZ3JvdXBzKS5mb3JFYWNoKGZ1bmN0aW9uIChncm91cE5hbWUpIHtcclxuXHRcdHNlbGYuZ3JvdXBzW2dyb3VwTmFtZV0ucmVtb3ZlRW1vdGUobmFtZSk7XHJcblx0fSk7XHJcblx0dGhpcy5mYXZvcml0ZXMucmVtb3ZlRW1vdGUobmFtZSk7XHJcblxyXG5cdHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuVUlNZW51LnByb3RvdHlwZS5nZXRFbW90ZSA9IGZ1bmN0aW9uIChuYW1lKSB7XHJcblx0dmFyIGdyb3VwTmFtZSA9IG51bGw7XHJcblx0dmFyIGdyb3VwID0gbnVsbDtcclxuXHR2YXIgZW1vdGUgPSBudWxsO1xyXG5cclxuXHRmb3IgKGdyb3VwTmFtZSBpbiB0aGlzLmdyb3Vwcykge1xyXG5cdFx0Z3JvdXAgPSB0aGlzLmdyb3Vwc1tncm91cE5hbWVdO1xyXG5cdFx0ZW1vdGUgPSBncm91cC5nZXRFbW90ZShuYW1lKTtcclxuXHJcblx0XHRpZiAoZW1vdGUpIHtcclxuXHRcdFx0cmV0dXJuIGVtb3RlO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIG51bGw7XHJcbn07XHJcblxyXG5mdW5jdGlvbiBVSUdyb3VwKGVtb3RlSW5zdGFuY2UpIHtcclxuXHR0aGlzLmRvbSA9IG51bGw7XHJcblx0dGhpcy5lbW90ZXMgPSB7fTtcclxuXHR0aGlzLmVtb3RlSW5zdGFuY2UgPSBlbW90ZUluc3RhbmNlO1xyXG5cclxuXHR0aGlzLmluaXQoKTtcclxufVxyXG5cclxuVUlHcm91cC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcclxuXHR2YXIgc2VsZiA9IHRoaXM7XHJcblx0dmFyIGVtb3RlSW5zdGFuY2UgPSB0aGlzLmVtb3RlSW5zdGFuY2U7XHJcblxyXG5cdC8vIEZpcnN0IGluaXQsIGNyZWF0ZSBuZXcgRE9NLlxyXG5cdGlmICh0aGlzLmRvbSA9PT0gbnVsbCkge1xyXG5cdFx0dGhpcy5kb20gPSAkKHRlbXBsYXRlcy5lbW90ZUdyb3VwSGVhZGVyKHtcclxuXHRcdFx0YmFkZ2U6IGVtb3RlSW5zdGFuY2UuZ2V0Q2hhbm5lbEJhZGdlKCksXHJcblx0XHRcdGNoYW5uZWw6IGVtb3RlSW5zdGFuY2UuZ2V0Q2hhbm5lbE5hbWUoKSxcclxuXHRcdFx0Y2hhbm5lbERpc3BsYXlOYW1lOiBlbW90ZUluc3RhbmNlLmdldENoYW5uZWxEaXNwbGF5TmFtZSgpXHJcblx0XHR9KSk7XHJcblx0fVxyXG5cdC8vIFVwZGF0ZSBET00gaW5zdGVhZC5cclxuXHRlbHNlIHtcclxuXHRcdHRoaXMuZG9tLmZpbmQoJy5oZWFkZXItaW5mbycpLnJlcGxhY2VXaXRoKFxyXG5cdFx0XHQkKHRlbXBsYXRlcy5lbW90ZUdyb3VwSGVhZGVyKHtcclxuXHRcdFx0XHRiYWRnZTogZW1vdGVJbnN0YW5jZS5nZXRDaGFubmVsQmFkZ2UoKSxcclxuXHRcdFx0XHRjaGFubmVsOiBlbW90ZUluc3RhbmNlLmdldENoYW5uZWxOYW1lKCksXHJcblx0XHRcdFx0Y2hhbm5lbERpc3BsYXlOYW1lOiBlbW90ZUluc3RhbmNlLmdldENoYW5uZWxEaXNwbGF5TmFtZSgpXHJcblx0XHRcdH0pKVxyXG5cdFx0XHQuZmluZCgnLmhlYWRlci1pbmZvJylcclxuXHRcdCk7XHJcblx0fVxyXG5cclxuXHQvLyBFbmFibGUgZW1vdGUgaGlkaW5nLlxyXG5cdHRoaXMuZG9tLmZpbmQoJy5oZWFkZXItaW5mbyBbZGF0YS1jb21tYW5kPVwidG9nZ2xlLXZpc2liaWxpdHlcIl0nKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XHJcblx0XHRpZiAoIXRoZU1lbnUuaXNFZGl0aW5nKCkpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0c2VsZi50b2dnbGVEaXNwbGF5KCk7XHJcblx0fSk7XHJcblxyXG5cdHRoaXMudG9nZ2xlRGlzcGxheSh0aGlzLmlzVmlzaWJsZSgpLCB0cnVlKTtcclxufTtcclxuXHJcblVJR3JvdXAucHJvdG90eXBlLnRvZ2dsZURpc3BsYXkgPSBmdW5jdGlvbiAoZm9yY2VkLCBza2lwVXBkYXRpbmdFbW90ZURpc3BsYXkpIHtcclxuXHR2YXIgc2VsZiA9IHRoaXM7XHJcblx0dmFyIHN0YXRlID0gdHlwZW9mIGZvcmNlZCAhPT0gJ3VuZGVmaW5lZCcgPyAhZm9yY2VkIDogdGhpcy5pc1Zpc2libGUoKTtcclxuXHJcblx0dGhpcy5kb20udG9nZ2xlQ2xhc3MoJ2Vtb3RlLW1lbnUtaGlkZGVuJywgc3RhdGUpO1xyXG5cclxuXHQvLyBVcGRhdGUgdGhlIGRpc3BsYXkgb2YgYWxsIGVtb3Rlcy5cclxuXHRpZiAoIXNraXBVcGRhdGluZ0Vtb3RlRGlzcGxheSkge1xyXG5cdFx0T2JqZWN0LmtleXModGhpcy5lbW90ZXMpLmZvckVhY2goZnVuY3Rpb24gKGVtb3RlTmFtZSkge1xyXG5cdFx0XHRzZWxmLmVtb3Rlc1tlbW90ZU5hbWVdLnRvZ2dsZURpc3BsYXkoIXN0YXRlKTtcclxuXHRcdFx0dGhlTWVudS51cGRhdGVFbW90ZXMoc2VsZi5lbW90ZXNbZW1vdGVOYW1lXS5pbnN0YW5jZS5nZXRUZXh0KCkpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcblVJR3JvdXAucHJvdG90eXBlLmlzVmlzaWJsZSA9IGZ1bmN0aW9uICgpIHtcclxuXHR2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG5cdC8vIElmIGFueSBlbW90ZSBpcyB2aXNpYmxlLCB0aGUgZ3JvdXAgc2hvdWxkIGJlIHZpc2libGUuXHJcblx0cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZW1vdGVzKS5zb21lKGZ1bmN0aW9uIChlbW90ZU5hbWUpIHtcclxuXHRcdHJldHVybiBzZWxmLmVtb3Rlc1tlbW90ZU5hbWVdLmlzVmlzaWJsZSgpO1xyXG5cdH0pO1xyXG59O1xyXG5cclxuVUlHcm91cC5wcm90b3R5cGUuYWRkRW1vdGUgPSBmdW5jdGlvbiAoZW1vdGVJbnN0YW5jZSkge1xyXG5cdHZhciBzZWxmID0gdGhpcztcclxuXHR2YXIgZW1vdGUgPSB0aGlzLmdldEVtb3RlKGVtb3RlSW5zdGFuY2UuZ2V0VGV4dCgpKTtcclxuXHJcblx0Ly8gQWxyZWFkeSBhZGRlZCwgdXBkYXRlIGluc3RlYWQuXHJcblx0aWYgKGVtb3RlKSB7XHJcblx0XHRlbW90ZS51cGRhdGUoKTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHJcblx0Ly8gQWRkIHRvIGN1cnJlbnQgZW1vdGVzLlxyXG5cdGVtb3RlID0gbmV3IFVJRW1vdGUoZW1vdGVJbnN0YW5jZSk7XHJcblx0dGhpcy5lbW90ZXNbZW1vdGVJbnN0YW5jZS5nZXRUZXh0KCldID0gZW1vdGU7XHJcblxyXG5cdHZhciBrZXlzID0gT2JqZWN0LmtleXModGhpcy5lbW90ZXMpO1xyXG5cclxuXHRrZXlzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcclxuXHRcdC8vIEdldCB0aGUgZW1vdGUgaW5zdGFuY2VzLlxyXG5cdFx0YSA9IHNlbGYuZW1vdGVzW2FdLmluc3RhbmNlO1xyXG5cdFx0YiA9IHNlbGYuZW1vdGVzW2JdLmluc3RhbmNlO1xyXG5cclxuXHRcdC8vIEEgaXMgYSBzbWlsZXksIEIgaXNuJ3QuIEEgZ29lcyBmaXJzdC5cclxuXHRcdGlmIChhLmlzU21pbGV5KCkgJiZcdCFiLmlzU21pbGV5KCkpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cdFx0Ly8gQiBpcyBhIHNtaWxleSwgQSBpc24ndC4gQiBnb2VzIGZpcnN0LlxyXG5cdFx0aWYgKGIuaXNTbWlsZXkoKSAmJlx0IWEuaXNTbWlsZXkoKSkge1xyXG5cdFx0XHRyZXR1cm4gMTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBHZXQgdGhlIHRleHQgb2YgdGhlIGVtb3Rlcy5cclxuXHRcdGEgPSBhLmdldFRleHQoKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0YiA9IGIuZ2V0VGV4dCgpLnRvTG93ZXJDYXNlKCk7XHJcblxyXG5cdFx0Ly8gQSBnb2VzIGZpcnN0LlxyXG5cdFx0aWYgKGEgPCBiKSB7XHJcblx0XHRcdHJldHVybiAtMTtcclxuXHRcdH1cclxuXHRcdC8vIEIgZ29lc3QgZmlyc3QuXHJcblx0XHRpZiAoYSA+IGIpIHtcclxuXHRcdFx0cmV0dXJuIDE7XHJcblx0XHR9XHJcblx0XHQvLyBCb3RoIHRoZSBzYW1lLCBkb2Vzbid0IG1hdHRlci5cclxuXHRcdHJldHVybiAwO1xyXG5cdH0pO1xyXG5cclxuXHR2YXIgaW5kZXggPSBrZXlzLmluZGV4T2YoZW1vdGVJbnN0YW5jZS5nZXRUZXh0KCkpO1xyXG5cclxuXHQvLyBGaXJzdCBpbiB0aGUgc29ydCwgcGxhY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZ3JvdXAuXHJcblx0aWYgKGluZGV4ID09PSAwKSB7XHJcblx0XHRlbW90ZS5kb20ucHJlcGVuZFRvKHRoaXMuZG9tLmZpbmQoJy5lbW90ZS1jb250YWluZXInKSk7XHJcblx0fVxyXG5cdC8vIEluc2VydCBhZnRlciB0aGUgcHJldmlvdXMgZW1vdGUgaW4gdGhlIHNvcnQuXHJcblx0ZWxzZSB7XHJcblx0XHRlbW90ZS5kb20uaW5zZXJ0QWZ0ZXIodGhpcy5nZXRFbW90ZShrZXlzW2luZGV4IC0gMV0pLmRvbSk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcblVJR3JvdXAucHJvdG90eXBlLmdldEVtb3RlID0gZnVuY3Rpb24gKG5hbWUpIHtcclxuXHRyZXR1cm4gdGhpcy5lbW90ZXNbbmFtZV0gfHwgbnVsbDtcclxufTtcclxuXHJcblVJR3JvdXAucHJvdG90eXBlLnJlbW92ZUVtb3RlID0gZnVuY3Rpb24gKG5hbWUpIHtcclxuXHR2YXIgZW1vdGUgPSB0aGlzLmdldEVtb3RlKG5hbWUpO1xyXG5cdGlmICghZW1vdGUpIHtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHRlbW90ZS5kb20ucmVtb3ZlKCk7XHJcblx0ZGVsZXRlIHRoaXMuZW1vdGVzW25hbWVdO1xyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcbmZ1bmN0aW9uIFVJRmF2b3JpdGVzR3JvdXAoKSB7XHJcblx0dGhpcy5kb20gPSAkKCcjc3RhcnJlZC1lbW90ZXMtZ3JvdXAnKTtcclxuXHR0aGlzLmVtb3RlcyA9IHt9O1xyXG59XHJcblxyXG5VSUZhdm9yaXRlc0dyb3VwLnByb3RvdHlwZS5hZGRFbW90ZSA9IFVJR3JvdXAucHJvdG90eXBlLmFkZEVtb3RlO1xyXG5VSUZhdm9yaXRlc0dyb3VwLnByb3RvdHlwZS5nZXRFbW90ZSA9IFVJR3JvdXAucHJvdG90eXBlLmdldEVtb3RlO1xyXG5VSUZhdm9yaXRlc0dyb3VwLnByb3RvdHlwZS5yZW1vdmVFbW90ZSA9IFVJR3JvdXAucHJvdG90eXBlLnJlbW92ZUVtb3RlO1xyXG5cclxuZnVuY3Rpb24gVUlFbW90ZShlbW90ZUluc3RhbmNlKSB7XHJcblx0dGhpcy5kb20gPSBudWxsO1xyXG5cdHRoaXMuaW5zdGFuY2UgPSBlbW90ZUluc3RhbmNlO1xyXG5cdHRoaXMuaW5pdCgpO1xyXG59XHJcblxyXG5VSUVtb3RlLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xyXG5cdHZhciBzZWxmID0gdGhpcztcclxuXHJcblx0Ly8gQ3JlYXRlIGVsZW1lbnQuXHJcblx0dGhpcy5kb20gPSAkKHRlbXBsYXRlcy5lbW90ZSh7XHJcblx0XHR1cmw6IHRoaXMuaW5zdGFuY2UuZ2V0VXJsKCksXHJcblx0XHR0ZXh0OiB0aGlzLmluc3RhbmNlLmdldFRleHQoKSxcclxuXHRcdHRoaXJkUGFydHk6IHRoaXMuaW5zdGFuY2UuaXNUaGlyZFBhcnR5KCksXHJcblx0XHRpc1Zpc2libGU6IHRoaXMuaW5zdGFuY2UuaXNWaXNpYmxlKCksXHJcblx0XHRpc1N0YXJyZWQ6IHRoaXMuaW5zdGFuY2UuaXNGYXZvcml0ZSgpXHJcblx0fSkpO1xyXG5cclxuXHQvLyBFbmFibGUgY2xpY2tpbmcuXHJcblx0dGhpcy5kb20ub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xyXG5cdFx0aWYgKCF0aGVNZW51LmlzRWRpdGluZygpKSB7XHJcblx0XHRcdHNlbGYuYWRkVG9DaGF0KCk7XHJcblxyXG5cdFx0XHQvLyBDbG9zZSB0aGUgbWVudSBpZiBub3QgcGlubmVkLlxyXG5cdFx0XHRpZiAoIXRoZU1lbnUuaXNQaW5uZWQoKSkge1xyXG5cdFx0XHRcdHRoZU1lbnUudG9nZ2xlRGlzcGxheSgpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fSk7XHJcblxyXG5cdC8vIEVuYWJsZSBlbW90ZSBoaWRpbmcuXHJcblx0dGhpcy5kb20uZmluZCgnW2RhdGEtY29tbWFuZD1cInRvZ2dsZS12aXNpYmlsaXR5XCJdJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xyXG5cdFx0aWYgKCF0aGVNZW51LmlzRWRpdGluZygpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdHNlbGYudG9nZ2xlRGlzcGxheSgpO1xyXG5cdFx0dGhlTWVudS51cGRhdGVFbW90ZXMoc2VsZi5pbnN0YW5jZS5nZXRUZXh0KCkpO1xyXG5cdH0pO1xyXG5cclxuXHQvLyBFbmFibGUgZW1vdGUgZmF2b3JpdGluZy5cclxuXHR0aGlzLmRvbS5maW5kKCdbZGF0YS1jb21tYW5kPVwidG9nZ2xlLXN0YXJyZWRcIl0nKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XHJcblx0XHRpZiAoIXRoZU1lbnUuaXNFZGl0aW5nKCkpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0c2VsZi50b2dnbGVGYXZvcml0ZSgpO1xyXG5cdFx0dGhlTWVudS51cGRhdGVFbW90ZXMoc2VsZi5pbnN0YW5jZS5nZXRUZXh0KCkpO1xyXG5cdH0pO1xyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcblVJRW1vdGUucHJvdG90eXBlLnRvZ2dsZURpc3BsYXkgPSBmdW5jdGlvbiAoZm9yY2VkLCBza2lwSW5zdGFuY2VVcGRhdGUpIHtcclxuXHR2YXIgc3RhdGUgPSB0eXBlb2YgZm9yY2VkICE9PSAndW5kZWZpbmVkJyA/ICFmb3JjZWQgOiB0aGlzLmlzVmlzaWJsZSgpO1xyXG5cdHRoaXMuZG9tLnRvZ2dsZUNsYXNzKCdlbW90ZS1tZW51LWhpZGRlbicsIHN0YXRlKTtcclxuXHRpZiAoIXNraXBJbnN0YW5jZVVwZGF0ZSkge1xyXG5cdFx0dGhpcy5pbnN0YW5jZS50b2dnbGVWaXNpYmlsaXR5KCFzdGF0ZSk7XHJcblx0fVxyXG5cclxuXHR2YXIgZ3JvdXAgPSB0aGlzLmdldEdyb3VwKCk7XHJcblx0Z3JvdXAudG9nZ2xlRGlzcGxheShncm91cC5pc1Zpc2libGUoKSwgdHJ1ZSk7XHJcblxyXG5cdHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuVUlFbW90ZS5wcm90b3R5cGUuaXNWaXNpYmxlID0gZnVuY3Rpb24gKCkge1xyXG5cdHJldHVybiAhdGhpcy5kb20uaGFzQ2xhc3MoJ2Vtb3RlLW1lbnUtaGlkZGVuJyk7XHJcbn07XHJcblxyXG5VSUVtb3RlLnByb3RvdHlwZS50b2dnbGVGYXZvcml0ZSA9IGZ1bmN0aW9uIChmb3JjZWQsIHNraXBJbnN0YW5jZVVwZGF0ZSkge1xyXG5cdHZhciBzdGF0ZSA9IHR5cGVvZiBmb3JjZWQgIT09ICd1bmRlZmluZWQnID8gISFmb3JjZWQgOiAhdGhpcy5pc0Zhdm9yaXRlKCk7XHJcblx0dGhpcy5kb20udG9nZ2xlQ2xhc3MoJ2Vtb3RlLW1lbnUtc3RhcnJlZCcsIHN0YXRlKTtcclxuXHRpZiAoIXNraXBJbnN0YW5jZVVwZGF0ZSkge1xyXG5cdFx0dGhpcy5pbnN0YW5jZS50b2dnbGVGYXZvcml0ZShzdGF0ZSk7XHJcblx0fVxyXG5cdHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuVUlFbW90ZS5wcm90b3R5cGUuaXNGYXZvcml0ZSA9IGZ1bmN0aW9uICgpIHtcclxuXHRyZXR1cm4gdGhpcy5kb20uaGFzQ2xhc3MoJ2Vtb3RlLW1lbnUtc3RhcnJlZCcpO1xyXG59O1xyXG5cclxuVUlFbW90ZS5wcm90b3R5cGUuYWRkVG9DaGF0ID0gZnVuY3Rpb24gKCkge1xyXG5cdHZhciBlbWJlciA9IHJlcXVpcmUoJy4vZW1iZXItYXBpJyk7XHJcblx0Ly8gR2V0IHRleHRhcmVhIGVsZW1lbnQuXHJcblx0dmFyIGVsZW1lbnQgPSAkKCcuY2hhdC1pbnRlcmZhY2UgdGV4dGFyZWEnKS5nZXQoMCk7XHJcblx0dmFyIHRleHQgPSB0aGlzLmluc3RhbmNlLmdldFRleHQoKTtcclxuXHJcblx0Ly8gSW5zZXJ0IGF0IGN1cnNvciAvIHJlcGxhY2Ugc2VsZWN0aW9uLlxyXG5cdC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvQ29kZV9zbmlwcGV0cy9NaXNjZWxsYW5lb3VzXHJcblx0dmFyIHNlbGVjdGlvbkVuZCA9IGVsZW1lbnQuc2VsZWN0aW9uU3RhcnQgKyB0ZXh0Lmxlbmd0aDtcclxuXHR2YXIgY3VycmVudFZhbHVlID0gZWxlbWVudC52YWx1ZTtcclxuXHR2YXIgYmVmb3JlVGV4dCA9IGN1cnJlbnRWYWx1ZS5zdWJzdHJpbmcoMCwgZWxlbWVudC5zZWxlY3Rpb25TdGFydCk7XHJcblx0dmFyIGFmdGVyVGV4dCA9IGN1cnJlbnRWYWx1ZS5zdWJzdHJpbmcoZWxlbWVudC5zZWxlY3Rpb25FbmQsIGN1cnJlbnRWYWx1ZS5sZW5ndGgpO1xyXG5cdC8vIFNtYXJ0IHBhZGRpbmcsIG9ubHkgcHV0IHNwYWNlIGF0IHN0YXJ0IGlmIG5lZWRlZC5cclxuXHRpZiAoXHJcblx0XHRiZWZvcmVUZXh0ICE9PSAnJyAmJlxyXG5cdFx0YmVmb3JlVGV4dC5zdWJzdHIoLTEpICE9PSAnICdcclxuXHQpIHtcclxuXHRcdHRleHQgPSAnICcgKyB0ZXh0O1xyXG5cdH1cclxuXHQvLyBBbHdheXMgcHV0IHNwYWNlIGF0IGVuZC5cclxuXHR0ZXh0ID0gYmVmb3JlVGV4dCArIHRleHQgKyAnICcgKyBhZnRlclRleHQ7XHJcblx0Ly8gU2V0IHRoZSB0ZXh0LlxyXG5cdGVtYmVyLmdldCgnY29udHJvbGxlcjpjaGF0JywgJ2N1cnJlbnRSb29tJykuc2V0KCdtZXNzYWdlVG9TZW5kJywgdGV4dCk7XHJcblx0ZWxlbWVudC5mb2N1cygpO1xyXG5cdC8vIFB1dCBjdXJzb3IgYXQgZW5kLlxyXG5cdHNlbGVjdGlvbkVuZCA9IGVsZW1lbnQuc2VsZWN0aW9uU3RhcnQgKyB0ZXh0Lmxlbmd0aDtcclxuXHRlbGVtZW50LnNldFNlbGVjdGlvblJhbmdlKHNlbGVjdGlvbkVuZCwgc2VsZWN0aW9uRW5kKTtcclxuXHJcblx0cmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5VSUVtb3RlLnByb3RvdHlwZS5nZXRHcm91cCA9IGZ1bmN0aW9uICgpIHtcclxuXHRyZXR1cm4gdGhlTWVudS5nZXRHcm91cCh0aGlzLmluc3RhbmNlLmdldENoYW5uZWxOYW1lKCkpO1xyXG59O1xyXG5cclxuVUlFbW90ZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKCkge1xyXG5cdHRoaXMudG9nZ2xlRGlzcGxheSh0aGlzLmluc3RhbmNlLmlzVmlzaWJsZSgpLCB0cnVlKTtcclxuXHR0aGlzLnRvZ2dsZUZhdm9yaXRlKHRoaXMuaW5zdGFuY2UuaXNGYXZvcml0ZSgpLCB0cnVlKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYXBpO1xyXG4iLCIoZnVuY3Rpb24gKCQpIHtcclxuXHQkLmZuLnJlc2l6YWJsZSA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcblx0XHR2YXIgc2V0dGluZ3MgPSAkLmV4dGVuZCh7XHJcblx0XHRcdGFsc29SZXNpemU6IG51bGwsXHJcblx0XHRcdGFsc29SZXNpemVUeXBlOiAnYm90aCcsIC8vIGBoZWlnaHRgLCBgd2lkdGhgLCBgYm90aGBcclxuXHRcdFx0Y29udGFpbm1lbnQ6IG51bGwsXHJcblx0XHRcdGNyZWF0ZTogbnVsbCxcclxuXHRcdFx0ZGVzdHJveTogbnVsbCxcclxuXHRcdFx0aGFuZGxlOiAnLnJlc2l6ZS1oYW5kbGUnLFxyXG5cdFx0XHRtYXhIZWlnaHQ6IDk5OTksXHJcblx0XHRcdG1heFdpZHRoOiA5OTk5LFxyXG5cdFx0XHRtaW5IZWlnaHQ6IDAsXHJcblx0XHRcdG1pbldpZHRoOiAwLFxyXG5cdFx0XHRyZXNpemU6IG51bGwsXHJcblx0XHRcdHJlc2l6ZU9uY2U6IG51bGwsXHJcblx0XHRcdHNuYXBTaXplOiAxLFxyXG5cdFx0XHRzdGFydDogbnVsbCxcclxuXHRcdFx0c3RvcDogbnVsbFxyXG5cdFx0fSwgb3B0aW9ucyk7XHJcblxyXG5cdFx0c2V0dGluZ3MuZWxlbWVudCA9ICQodGhpcyk7XHJcblxyXG5cdFx0ZnVuY3Rpb24gcmVjYWxjdWxhdGVTaXplKGV2dCkge1xyXG5cdFx0XHR2YXIgZGF0YSA9IGV2dC5kYXRhLFxyXG5cdFx0XHRcdHJlc2l6ZWQgPSB7fTtcclxuXHRcdFx0ZGF0YS5kaWZmWCA9IE1hdGgucm91bmQoKGV2dC5wYWdlWCAtIGRhdGEucGFnZVgpIC8gc2V0dGluZ3Muc25hcFNpemUpICogc2V0dGluZ3Muc25hcFNpemU7XHJcblx0XHRcdGRhdGEuZGlmZlkgPSBNYXRoLnJvdW5kKChldnQucGFnZVkgLSBkYXRhLnBhZ2VZKSAvIHNldHRpbmdzLnNuYXBTaXplKSAqIHNldHRpbmdzLnNuYXBTaXplO1xyXG5cdFx0XHRpZiAoTWF0aC5hYnMoZGF0YS5kaWZmWCkgPiAwIHx8IE1hdGguYWJzKGRhdGEuZGlmZlkpID4gMCkge1xyXG5cdFx0XHRcdGlmIChcclxuXHRcdFx0XHRcdHNldHRpbmdzLmVsZW1lbnQuaGVpZ2h0KCkgIT09IGRhdGEuaGVpZ2h0ICsgZGF0YS5kaWZmWSAmJlxyXG5cdFx0XHRcdFx0ZGF0YS5oZWlnaHQgKyBkYXRhLmRpZmZZID49IHNldHRpbmdzLm1pbkhlaWdodCAmJlxyXG5cdFx0XHRcdFx0ZGF0YS5oZWlnaHQgKyBkYXRhLmRpZmZZIDw9IHNldHRpbmdzLm1heEhlaWdodCAmJlxyXG5cdFx0XHRcdFx0KHNldHRpbmdzLmNvbnRhaW5tZW50ID8gZGF0YS5vdXRlckhlaWdodCArIGRhdGEuZGlmZlkgKyBkYXRhLm9mZnNldC50b3AgPD0gc2V0dGluZ3MuY29udGFpbm1lbnQub2Zmc2V0KCkudG9wICsgc2V0dGluZ3MuY29udGFpbm1lbnQub3V0ZXJIZWlnaHQoKSA6IHRydWUpXHJcblx0XHRcdFx0KSB7XHJcblx0XHRcdFx0XHRzZXR0aW5ncy5lbGVtZW50LmhlaWdodChkYXRhLmhlaWdodCArIGRhdGEuZGlmZlkpO1xyXG5cdFx0XHRcdFx0cmVzaXplZC5oZWlnaHQgPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoXHJcblx0XHRcdFx0XHRzZXR0aW5ncy5lbGVtZW50LndpZHRoKCkgIT09IGRhdGEud2lkdGggKyBkYXRhLmRpZmZYICYmXHJcblx0XHRcdFx0XHRkYXRhLndpZHRoICsgZGF0YS5kaWZmWCA+PSBzZXR0aW5ncy5taW5XaWR0aCAmJlxyXG5cdFx0XHRcdFx0ZGF0YS53aWR0aCArIGRhdGEuZGlmZlggPD0gc2V0dGluZ3MubWF4V2lkdGggJiZcclxuXHRcdFx0XHRcdChzZXR0aW5ncy5jb250YWlubWVudCA/IGRhdGEub3V0ZXJXaWR0aCArIGRhdGEuZGlmZlggKyBkYXRhLm9mZnNldC5sZWZ0IDw9IHNldHRpbmdzLmNvbnRhaW5tZW50Lm9mZnNldCgpLmxlZnQgKyBzZXR0aW5ncy5jb250YWlubWVudC5vdXRlcldpZHRoKCkgOiB0cnVlKVxyXG5cdFx0XHRcdCkge1xyXG5cdFx0XHRcdFx0c2V0dGluZ3MuZWxlbWVudC53aWR0aChkYXRhLndpZHRoICsgZGF0YS5kaWZmWCk7XHJcblx0XHRcdFx0XHRyZXNpemVkLndpZHRoID0gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKHJlc2l6ZWQuaGVpZ2h0IHx8IHJlc2l6ZWQud2lkdGgpIHtcclxuXHRcdFx0XHRcdGlmIChzZXR0aW5ncy5yZXNpemVPbmNlKSB7XHJcblx0XHRcdFx0XHRcdHNldHRpbmdzLnJlc2l6ZU9uY2UuYmluZChzZXR0aW5ncy5lbGVtZW50KShldnQuZGF0YSk7XHJcblx0XHRcdFx0XHRcdHNldHRpbmdzLnJlc2l6ZU9uY2UgPSBudWxsO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYgKHNldHRpbmdzLnJlc2l6ZSkge1xyXG5cdFx0XHRcdFx0XHRzZXR0aW5ncy5yZXNpemUuYmluZChzZXR0aW5ncy5lbGVtZW50KShldnQuZGF0YSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRpZiAoc2V0dGluZ3MuYWxzb1Jlc2l6ZSkge1xyXG5cdFx0XHRcdFx0XHRpZiAocmVzaXplZC5oZWlnaHQgJiYgKHNldHRpbmdzLmFsc29SZXNpemVUeXBlID09PSAnaGVpZ2h0JyB8fCBzZXR0aW5ncy5hbHNvUmVzaXplVHlwZSA9PT0gJ2JvdGgnKSkge1xyXG5cdFx0XHRcdFx0XHRcdHNldHRpbmdzLmFsc29SZXNpemUuaGVpZ2h0KGRhdGEuYWxzb1Jlc2l6ZUhlaWdodCArIGRhdGEuZGlmZlkpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGlmIChyZXNpemVkLndpZHRoICYmIChzZXR0aW5ncy5hbHNvUmVzaXplVHlwZSA9PT0gJ3dpZHRoJyB8fCBzZXR0aW5ncy5hbHNvUmVzaXplVHlwZSA9PT0gJ2JvdGgnKSkge1xyXG5cdFx0XHRcdFx0XHRcdHNldHRpbmdzLmFsc29SZXNpemUud2lkdGgoZGF0YS5hbHNvUmVzaXplV2lkdGggKyBkYXRhLmRpZmZYKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGZ1bmN0aW9uIHN0YXJ0KGV2dCkge1xyXG5cdFx0XHRldnQucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0aWYgKHNldHRpbmdzLnN0YXJ0KSB7XHJcblx0XHRcdFx0c2V0dGluZ3Muc3RhcnQuYmluZChzZXR0aW5ncy5lbGVtZW50KSgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHZhciBkYXRhID0ge1xyXG5cdFx0XHRcdGFsc29SZXNpemVIZWlnaHQ6IHNldHRpbmdzLmFsc29SZXNpemUgPyBzZXR0aW5ncy5hbHNvUmVzaXplLmhlaWdodCgpIDogMCxcclxuXHRcdFx0XHRhbHNvUmVzaXplV2lkdGg6IHNldHRpbmdzLmFsc29SZXNpemUgPyBzZXR0aW5ncy5hbHNvUmVzaXplLndpZHRoKCkgOiAwLFxyXG5cdFx0XHRcdGhlaWdodDogc2V0dGluZ3MuZWxlbWVudC5oZWlnaHQoKSxcclxuXHRcdFx0XHRvZmZzZXQ6IHNldHRpbmdzLmVsZW1lbnQub2Zmc2V0KCksXHJcblx0XHRcdFx0b3V0ZXJIZWlnaHQ6IHNldHRpbmdzLmVsZW1lbnQub3V0ZXJIZWlnaHQoKSxcclxuXHRcdFx0XHRvdXRlcldpZHRoOiBzZXR0aW5ncy5lbGVtZW50Lm91dGVyV2lkdGgoKSxcclxuXHRcdFx0XHRwYWdlWDogZXZ0LnBhZ2VYLFxyXG5cdFx0XHRcdHBhZ2VZOiBldnQucGFnZVksXHJcblx0XHRcdFx0d2lkdGg6IHNldHRpbmdzLmVsZW1lbnQud2lkdGgoKVxyXG5cdFx0XHR9O1xyXG5cdFx0XHQkKGRvY3VtZW50KS5vbignbW91c2Vtb3ZlJywgJyonLCBkYXRhLCByZWNhbGN1bGF0ZVNpemUpO1xyXG5cdFx0XHQkKGRvY3VtZW50KS5vbignbW91c2V1cCcsICcqJywgc3RvcCk7XHJcblx0XHR9XHJcblxyXG5cdFx0ZnVuY3Rpb24gc3RvcCgpIHtcclxuXHRcdFx0aWYgKHNldHRpbmdzLnN0b3ApIHtcclxuXHRcdFx0XHRzZXR0aW5ncy5zdG9wLmJpbmQoc2V0dGluZ3MuZWxlbWVudCkoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHQkKGRvY3VtZW50KS5vZmYoJ21vdXNlbW92ZScsICcqJywgcmVjYWxjdWxhdGVTaXplKTtcclxuXHRcdFx0JChkb2N1bWVudCkub2ZmKCdtb3VzZXVwJywgJyonLCBzdG9wKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoc2V0dGluZ3MuaGFuZGxlKSB7XHJcblx0XHRcdGlmIChzZXR0aW5ncy5hbHNvUmVzaXplICYmIFsnYm90aCcsICdoZWlnaHQnLCAnd2lkdGgnXS5pbmRleE9mKHNldHRpbmdzLmFsc29SZXNpemVUeXBlKSA+PSAwKSB7XHJcblx0XHRcdFx0c2V0dGluZ3MuYWxzb1Jlc2l6ZSA9ICQoc2V0dGluZ3MuYWxzb1Jlc2l6ZSk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKHNldHRpbmdzLmNvbnRhaW5tZW50KSB7XHJcblx0XHRcdFx0c2V0dGluZ3MuY29udGFpbm1lbnQgPSAkKHNldHRpbmdzLmNvbnRhaW5tZW50KTtcclxuXHRcdFx0fVxyXG5cdFx0XHRzZXR0aW5ncy5oYW5kbGUgPSAkKHNldHRpbmdzLmhhbmRsZSk7XHJcblx0XHRcdHNldHRpbmdzLnNuYXBTaXplID0gc2V0dGluZ3Muc25hcFNpemUgPCAxID8gMSA6IHNldHRpbmdzLnNuYXBTaXplO1xyXG5cclxuXHRcdFx0aWYgKG9wdGlvbnMgPT09ICdkZXN0cm95Jykge1xyXG5cdFx0XHRcdHNldHRpbmdzLmhhbmRsZS5vZmYoJ21vdXNlZG93bicsIHN0YXJ0KTtcclxuXHJcblx0XHRcdFx0aWYgKHNldHRpbmdzLmRlc3Ryb3kpIHtcclxuXHRcdFx0XHRcdHNldHRpbmdzLmRlc3Ryb3kuYmluZCh0aGlzKSgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0c2V0dGluZ3MuaGFuZGxlLm9uKCdtb3VzZWRvd24nLCBzdGFydCk7XHJcblxyXG5cdFx0XHRpZiAoc2V0dGluZ3MuY3JlYXRlKSB7XHJcblx0XHRcdFx0c2V0dGluZ3MuY3JlYXRlLmJpbmQodGhpcykoKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fTtcclxufSkoalF1ZXJ5KTtcclxuIl19