| /** |
| * swagger-ui - Swagger UI is a dependency-free collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API |
| * @version v2.2.9 |
| * @link http://swagger.io |
| * @license Apache-2.0 |
| */ |
| (function(){/* jshint ignore:start */ |
| {(function() { |
| var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; |
| templates['apikey_auth'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " <span class=\"key_auth__value\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</span>\n"; |
| },"3":function(container,depth0,helpers,partials,data) { |
| return " <input placeholder=\"api_key\" class=\"auth_input input_apiKey_entry\" name=\"apiKey\" type=\"text\"/>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<div class=\"key_input_container\">\n <h3 class=\"auth__title\">Api key authorization</h3>\n <div class=\"auth__description\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</div>\n <div>\n <div class=\"key_auth__field\">\n <span class=\"key_auth__label\">name:</span>\n <span class=\"key_auth__value\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</span>\n </div>\n <div class=\"key_auth__field\">\n <span class=\"key_auth__label\">in:</span>\n <span class=\"key_auth__value\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0["in"] : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</span>\n </div>\n <div class=\"key_auth__field\">\n <span class=\"key_auth__label\">value:</span>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "") |
| + " </div>\n </div>\n</div>\n"; |
| },"useData":true}); |
| templates['auth_button'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| return "<a class='authorize__btn' href=\"#\">Authorize</a>\n"; |
| },"useData":true}); |
| templates['auth_button_operation'] = template({"1":function(container,depth0,helpers,partials,data) { |
| return " authorize__btn_operation_login\n"; |
| },"3":function(container,depth0,helpers,partials,data) { |
| return " authorize__btn_operation_logout\n"; |
| },"5":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " <ul class=\"authorize-scopes\">\n" |
| + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.scopes : depth0),{"name":"each","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </ul>\n"; |
| },"6":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <li class=\"authorize__scope\" title=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</li>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}; |
| |
| return "<div class=\"authorize__btn authorize__btn_operation\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "") |
| + "\">\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.scopes : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "</div>\n"; |
| },"useData":true}); |
| templates['auth_view'] = template({"1":function(container,depth0,helpers,partials,data) { |
| return " <button type=\"button\" class=\"auth__button auth_submit__button\" data-sw-translate>Authorize</button>\n"; |
| },"3":function(container,depth0,helpers,partials,data) { |
| return " <button type=\"button\" class=\"auth__button auth_logout__button\" data-sw-translate>Logout</button>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}; |
| |
| return "<div class=\"auth_container\">\n\n <div class=\"auth_inner\"></div>\n <div class=\"auth_submit\">\n" |
| + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"unless","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isAuthorized : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </div>\n\n</div>\n"; |
| },"useData":true}); |
| templates['basic_auth'] = template({"1":function(container,depth0,helpers,partials,data) { |
| return " - authorized"; |
| },"3":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " <span class=\"basic_auth__value\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.username : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</span>\n"; |
| },"5":function(container,depth0,helpers,partials,data) { |
| return " <input required placeholder=\"username\" class=\"basic_auth__username auth_input\" name=\"username\" type=\"text\"/>\n"; |
| },"7":function(container,depth0,helpers,partials,data) { |
| return " <div class=\"auth_label\">\n <span class=\"basic_auth__label\" data-sw-translate>password:</span>\n <input required placeholder=\"password\" class=\"basic_auth__password auth_input\" name=\"password\" type=\"password\"/></label>\n </div>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}; |
| |
| return "<div class='basic_auth_container'>\n <h3 class=\"auth__title\">Basic authentication" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "</h3>\n <form class=\"basic_input_container\">\n <div class=\"auth__description\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</div>\n <div class=\"auth_label\">\n <span class=\"basic_auth__label\" data-sw-translate>username:</span>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.program(5, data, 0),"data":data})) != null ? stack1 : "") |
| + " </div>\n" |
| + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"unless","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </form>\n</div>\n"; |
| },"useData":true}); |
| templates['content_type'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.produces : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); |
| },"2":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <option value=\"" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</option>\n"; |
| },"4":function(container,depth0,helpers,partials,data) { |
| return " <option value=\"application/json\">application/json</option>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<label data-sw-translate for=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.contentTypeId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">Response Content Type</label>\n<select name=\"contentType\" id=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.contentTypeId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.produces : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "") |
| + "</select>\n"; |
| },"useData":true}); |
| templates['main'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <div class=\"info_title\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</div>\n <div class=\"info_description markdown\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.description : stack1),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</div>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.externalDocs : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " " |
| + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n " |
| + ((stack1 = helpers["if"].call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n " |
| + ((stack1 = helpers["if"].call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n " |
| + ((stack1 = helpers["if"].call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n " |
| + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1),{"name":"if","hash":{},"fn":container.program(12, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n"; |
| },"2":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <p>" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.description : stack1),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</p>\n <a href=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\" target=\"_blank\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</a>\n"; |
| },"4":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return "<div class=\"info_tos\"><a target=\"_blank\" href=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\" data-sw-translate>Terms of service</a></div>"; |
| },"6":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return "<div><div class='info_name' style=\"display: inline\" data-sw-translate>Created by </div> " |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</div>"; |
| },"8":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<div class='info_url' data-sw-translate>See more at <a href=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</a></div>"; |
| },"10":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<div class='info_email'><a target=\"_parent\" href=\"mailto:" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "?subject=" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\" data-sw-translate>Contact the developer</a></div>"; |
| },"12":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<div class='info_license'><a target=\"_blank\" href='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.name : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</a></div>"; |
| },"14":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " , <span style=\"font-variant: small-caps\" data-sw-translate>api version</span>: " |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\n "; |
| },"16":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <span style=\"float:right\"><a target=\"_blank\" href=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "/debug?url=" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\"><img id=\"validator\" src=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "?url=" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\"></a>\n </span>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}; |
| |
| return "<div class='info' id='api_info'>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.info : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "</div>\n<div class='container' id='resources_container'>\n <div class='authorize-wrapper'></div>\n\n <ul id='resources'></ul>\n\n <div class=\"footer\">\n <h4 style=\"color: #999\">[ <span style=\"font-variant: small-caps\">base url</span>: " |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.basePath : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\n" |
| + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1),{"name":"if","hash":{},"fn":container.program(14, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "]\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"if","hash":{},"fn":container.program(16, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </h4>\n </div>\n</div>\n"; |
| },"useData":true}); |
| templates['oauth2'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return "<p>Authorization URL: " |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.authorizationUrl : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</p>"; |
| },"3":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return "<p>Token URL: " |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.tokenUrl : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</p>"; |
| },"5":function(container,depth0,helpers,partials,data) { |
| return " <p>Please input username and password for password flow authorization</p>\n <fieldset>\n <div><label>Username: <input class=\"oauth-username\" type=\"text\" name=\"username\"></label></div>\n <div><label>Password: <input class=\"oauth-password\" type=\"password\" name=\"password\"></label></div>\n </fieldset>\n"; |
| },"7":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " <p>Setup client authentication." |
| + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.requireClientAuthenticaiton : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "</p>\n <fieldset>\n <div><label>Type:\n <select class=\"oauth-client-authentication-type\" name=\"client-authentication-type\">\n <option value=\"none\" selected>None or other</option>\n <option value=\"basic\">Basic auth</option>\n <option value=\"request-body\">Request body</option>\n </select>\n </label></div>\n <div class=\"oauth-client-authentication\" hidden>\n <div><label>ClientId: <input class=\"oauth-client-id\" type=\"text\" name=\"client-id\"></label></div>\n <div><label>Secret: <input class=\"oauth-client-secret\" type=\"text\" name=\"client-secret\"></label></div>\n </div>\n </fieldset>\n"; |
| },"8":function(container,depth0,helpers,partials,data) { |
| return "(Required)"; |
| },"10":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <li>\n <input class=\"oauth-scope\" type=\"checkbox\" data-scope=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\" oauthtype=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\"/>\n <label>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</label><br/>\n <span class=\"api-scope-desc\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"if","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </span>\n </li>\n"; |
| },"11":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " (" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + ")\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<div>\n <h3 class=\"auth__title\">OAuth2.0</h3>\n <p>" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</p>\n " |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.authorizationUrl : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n " |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.tokenUrl : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n <p>flow: " |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.flow : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</p>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordFlow : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.clientAuthentication : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " <p><strong> " |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.appName : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + " </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n <p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n <a href=\"#\">Learn how to use</a>\n </p>\n <ul class=\"api-popup-scopes\">\n" |
| + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.scopes : depth0),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </ul>\n</div>"; |
| },"useData":true}); |
| templates['operation'] = template({"1":function(container,depth0,helpers,partials,data) { |
| return "deprecated"; |
| },"3":function(container,depth0,helpers,partials,data) { |
| return " <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n"; |
| },"5":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " <h4><span data-sw-translate>Implementation Notes</span></h4>\n <div class=\"markdown\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</div>\n"; |
| },"7":function(container,depth0,helpers,partials,data) { |
| return " <div class='authorize-wrapper authorize-wrapper_operation'></div>\n"; |
| },"9":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}; |
| |
| return " <div class=\"response-class\">\n <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> " |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.successCode : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + ")</h4>\n " |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.successDescription : depth0),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n <p><span class=\"model-signature\" /></p>\n <br/>\n <div class=\"response-content-type\" />\n </div>\n"; |
| },"10":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return "<div class=\"markdown\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.successDescription : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</div>"; |
| },"12":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " <h4 data-sw-translate>Headers</h4>\n <table class=\"headers\">\n <thead>\n <tr>\n <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Header</th>\n <th style=\"width: 310px; max-width: 310px\" data-sw-translate>Description</th>\n <th style=\"width: 200px; max-width: 200px\" data-sw-translate>Type</th>\n <th style=\"width: 320px; max-width: 320px\" data-sw-translate>Other</th>\n </tr>\n </thead>\n <tbody>\n" |
| + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.headers : depth0),{"name":"each","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </tbody>\n </table>\n"; |
| },"13":function(container,depth0,helpers,partials,data) { |
| var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <tr>\n <td>" |
| + container.escapeExpression(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"key","hash":{},"data":data}) : helper))) |
| + "</td>\n <td>" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n <td>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n <td>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.other : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n </tr>\n"; |
| },"15":function(container,depth0,helpers,partials,data) { |
| return " <h4 data-sw-translate>Parameters</h4>\n <table class='fullwidth parameters'>\n <thead>\n <tr>\n <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Parameter</th>\n <th style=\"width: 310px; max-width: 310px\" data-sw-translate>Value</th>\n <th style=\"width: 200px; max-width: 200px\" data-sw-translate>Description</th>\n <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Parameter Type</th>\n <th style=\"width: 220px; max-width: 230px\" data-sw-translate>Data Type</th>\n </tr>\n </thead>\n <tbody class=\"operation-params\">\n\n </tbody>\n </table>\n"; |
| },"17":function(container,depth0,helpers,partials,data) { |
| return " <div style='margin:0;padding:0;display:inline'></div>\n <h4 data-sw-translate>Response Messages</h4>\n <table class='fullwidth response-messages'>\n <thead>\n <tr>\n <th data-sw-translate>HTTP Status Code</th>\n <th data-sw-translate>Reason</th>\n <th data-sw-translate>Response Model</th>\n <th data-sw-translate>Headers</th>\n </tr>\n </thead>\n <tbody class=\"operation-status\">\n </tbody>\n </table>\n"; |
| },"19":function(container,depth0,helpers,partials,data) { |
| return ""; |
| },"21":function(container,depth0,helpers,partials,data) { |
| return " <div class='sandbox_header'>\n <input class='submit' type='submit' value='Try it out!' data-sw-translate/>\n <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n <span class='response_throbber' style='display:none'></span>\n </div>\n"; |
| },"23":function(container,depth0,helpers,partials,data) { |
| return " <h4 data-sw-translate>Request Headers</h4>\n <div class='block request_headers'></div>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3=container.escapeExpression; |
| |
| return " <ul class='operations' >\n <li class='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.method : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + " operation' id='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.parentId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "_" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'>\n <div class='heading'>\n <h3>\n <span class='http_method'>\n <a href='#!/" |
| + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data})) |
| + "/" |
| + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data})) |
| + "' class=\"toggleOperation\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.method : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</a>\n </span>\n <span class='path'>\n <a href='#!/" |
| + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data})) |
| + "/" |
| + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data})) |
| + "' class=\"toggleOperation " |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.deprecated : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.path : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</a>\n </span>\n </h3>\n <ul class='options'>\n <li>\n <a href='#!/" |
| + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data})) |
| + "/" |
| + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data})) |
| + "' class=\"toggleOperation\"><span class=\"markdown\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.summary : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</span></a>\n </li>\n </ul>\n </div>\n <div class='content' id='" |
| + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data})) |
| + "_" |
| + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data})) |
| + "_content' style='display:none'>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.deprecated : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.security : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"if","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.headers : depth0),{"name":"if","hash":{},"fn":container.program(12, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n <form accept-charset='UTF-8' class='sandbox'>\n <div style='margin:0;padding:0;display:inline'></div>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.parameters : depth0),{"name":"if","hash":{},"fn":container.program(15, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.responseMessages : depth0),{"name":"if","hash":{},"fn":container.program(17, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isReadOnly : depth0),{"name":"if","hash":{},"fn":container.program(19, data, 0),"inverse":container.program(21, data, 0),"data":data})) != null ? stack1 : "") |
| + " </form>\n <div class='response' style='display:none'>\n <h4 class='curl'>Curl</h4>\n <div class='block curl'></div>\n <h4 data-sw-translate>Request URL</h4>\n <div class='block request_url'></div>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showRequestHeaders : depth0),{"name":"if","hash":{},"fn":container.program(23, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " <h4 data-sw-translate>Response Body</h4>\n <div class='block response_body'></div>\n <h4 data-sw-translate>Response Code</h4>\n <div class='block response_code'></div>\n <h4 data-sw-translate>Response Headers</h4>\n <div class='block response_headers'></div>\n </div>\n </div>\n </li>\n </ul>\n"; |
| },"useData":true}); |
| templates['param'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : ""); |
| },"2":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <input type=\"file\" name='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "' id='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'/>\n <div class=\"parameter-content-type\" />\n"; |
| },"4":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : ""); |
| },"5":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <div class=\"editor_holder\"></div>\n <textarea class='body-textarea' name='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "' id='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</textarea>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
| },"7":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <textarea class='body-textarea' name='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "' id='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'></textarea>\n <div class=\"editor_holder\"></div>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
| },"9":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(10, data, 0),"data":data})) != null ? stack1 : ""); |
| },"10":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = (helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helpers.helperMissing).call(depth0 != null ? depth0 : {},depth0,{"name":"renderTextParam","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); |
| },"11":function(container,depth0,helpers,partials,data) { |
| return ""; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<td class='code'><label for='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</label></td>\n<td>\n\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(9, data, 0),"data":data})) != null ? stack1 : "") |
| + "\n</td>\n<td class=\"markdown\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n<td>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n<td>\n <span class=\"model-signature\"></span>\n</td>\n"; |
| },"useData":true}); |
| templates['param_list'] = template({"1":function(container,depth0,helpers,partials,data) { |
| return " required"; |
| },"3":function(container,depth0,helpers,partials,data) { |
| return " multiple=\"multiple\""; |
| },"5":function(container,depth0,helpers,partials,data) { |
| return " required "; |
| },"7":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " <option " |
| + ((stack1 = helpers.unless.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.hasDefault : depth0),{"name":"unless","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " value=''></option>\n"; |
| },"8":function(container,depth0,helpers,partials,data) { |
| return " selected=\"\" "; |
| },"10":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "\n <option " |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isDefault : depth0),{"name":"if","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " value='" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "'> " |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + " " |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isDefault : depth0),{"name":"if","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </option>\n\n"; |
| },"11":function(container,depth0,helpers,partials,data) { |
| return " selected=\"\" "; |
| },"13":function(container,depth0,helpers,partials,data) { |
| return " (default) "; |
| },"15":function(container,depth0,helpers,partials,data) { |
| return "<strong>"; |
| },"17":function(container,depth0,helpers,partials,data) { |
| return "</strong>"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<td class='code" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "'><label for='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'>" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</label></td>\n<td>\n <select " |
| + ((stack1 = (helpers.isArray || (depth0 && depth0.isArray) || alias2).call(alias1,depth0,{"name":"isArray","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " class=\"parameter " |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\" name=\"" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\" id=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">\n\n" |
| + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"unless","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n" |
| + ((stack1 = helpers.each.call(alias1,((stack1 = (depth0 != null ? depth0.allowableValues : depth0)) != null ? stack1.descriptiveValues : stack1),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n </select>\n</td>\n<td class=\"markdown\">" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(15, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + ((stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"description","hash":{},"data":data}) : helper))) != null ? stack1 : "") |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(17, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "</td>\n<td>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| },"useData":true}); |
| templates['param_readonly'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <textarea class='body-textarea' readonly='readonly' name='" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "' id='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'>" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</textarea>\n <div class=\"parameter-content-type\" />\n"; |
| },"3":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.program(6, data, 0),"data":data})) != null ? stack1 : ""); |
| },"4":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " " |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\n"; |
| },"6":function(container,depth0,helpers,partials,data) { |
| return " (empty)\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<td class='code'><label for='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'>" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</label></td>\n<td>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "") |
| + "</td>\n<td class=\"markdown\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n<td>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| },"useData":true}); |
| templates['param_readonly_required'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "' id='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'>" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</textarea>\n"; |
| },"3":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.program(6, data, 0),"data":data})) != null ? stack1 : ""); |
| },"4":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " " |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\n"; |
| },"6":function(container,depth0,helpers,partials,data) { |
| return " (empty)\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<td class='code required'><label for='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'>" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</label></td>\n<td>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "") |
| + "</td>\n<td class=\"markdown\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n<td>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| },"useData":true}); |
| templates['param_required'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : ""); |
| },"2":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <input type=\"file\" name='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "' id='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'/>\n"; |
| },"4":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : ""); |
| },"5":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <div class=\"editor_holder\"></div>\n <textarea class='body-textarea required' placeholder='(required)' name='" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "' id=\"" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</textarea>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
| },"7":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <textarea class='body-textarea required' placeholder='(required)' name='" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "' id='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'></textarea>\n <div class=\"editor_holder\"></div>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
| },"9":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.program(12, data, 0),"data":data})) != null ? stack1 : ""); |
| },"10":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <input class='parameter required' type='file' name='" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "' id='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'/>\n"; |
| },"12":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = (helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helpers.helperMissing).call(depth0 != null ? depth0 : {},depth0,{"name":"renderTextParam","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); |
| },"13":function(container,depth0,helpers,partials,data) { |
| return ""; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<td class='code required'><label for='" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "'>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</label></td>\n<td>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(9, data, 0),"data":data})) != null ? stack1 : "") |
| + "</td>\n<td>\n <strong><span class=\"markdown\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</span></strong>\n</td>\n<td>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| },"useData":true}); |
| templates['parameter_content_type'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.consumes : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); |
| },"2":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <option value=\"" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</option>\n"; |
| },"4":function(container,depth0,helpers,partials,data) { |
| return " <option value=\"application/json\">application/json</option>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<label for=\"" |
| + container.escapeExpression(((helper = (helper = helpers.parameterContentTypeId || (depth0 != null ? depth0.parameterContentTypeId : depth0)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"parameterContentTypeId","hash":{},"data":data}) : helper))) |
| + "\" data-sw-translate>Parameter content type:</label>\n<select name=\"parameterContentType\" id=\"" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.parameterContentTypeId : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.consumes : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "") |
| + "</select>\n"; |
| },"useData":true}); |
| templates['popup'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var helper; |
| |
| return "<div class=\"api-popup-dialog-wrapper\">\n <div class=\"api-popup-title\">" |
| + container.escapeExpression(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : {},{"name":"title","hash":{},"data":data}) : helper))) |
| + "</div>\n <div class=\"api-popup-content\"></div>\n <p class=\"error-msg\"></p>\n <div class=\"api-popup-actions\">\n <button class=\"api-popup-cancel api-button gray\" type=\"button\">Cancel</button>\n </div>\n</div>\n<div class=\"api-popup-dialog-shadow\"></div>"; |
| },"useData":true}); |
| templates['resource'] = template({"1":function(container,depth0,helpers,partials,data) { |
| return " : "; |
| },"3":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " <li>\n <a href='" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.url : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "' data-sw-translate>Raw</a>\n </li>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, helper, options, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, buffer = |
| "<div class='heading'>\n <h2>\n <a href='#!/" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "' class=\"toggleEndpointList\" data-id=\"" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</a> "; |
| stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : alias2),(options={"name":"summary","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data}),(typeof helper === "function" ? helper.call(alias1,options) : helper)); |
| if (!helpers.summary) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)} |
| if (stack1 != null) { buffer += stack1; } |
| return buffer + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.summary : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\n </h2>\n <ul class='options'>\n <li>\n <a href='#!/" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "' id='endpointListTogger_" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "' class=\"toggleEndpointList\" data-id=\"" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\" data-sw-translate>Show/Hide</a>\n </li>\n <li>\n <a href='#' class=\"collapseResource\" data-id=\"" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\" data-sw-translate>\n List Operations\n </a>\n </li>\n <li>\n <a href='#' class=\"expandResource\" data-id=\"" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\" data-sw-translate>\n Expand Operations\n </a>\n </li>\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </ul>\n</div>\n<ul class='endpoints' id='" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "_endpoint_list' style='display:none'>\n\n</ul>\n"; |
| },"useData":true}); |
| templates['response_content_type'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.produces : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); |
| },"2":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <option value=\"" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "\">" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</option>\n"; |
| },"4":function(container,depth0,helpers,partials,data) { |
| return " <option value=\"application/json\">application/json</option>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; |
| |
| return "<label data-sw-translate for=\"" |
| + alias4(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"responseContentTypeId","hash":{},"data":data}) : helper))) |
| + "\">Response Content Type</label>\n<select name=\"responseContentType\" id=\"" |
| + alias4(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"responseContentTypeId","hash":{},"data":data}) : helper))) |
| + "\">\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.produces : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "") |
| + "</select>\n"; |
| },"useData":true}); |
| templates['signature'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}; |
| |
| return "\n<div>\n<ul class=\"signature-nav\">\n <li><a class=\"description-link\" href=\"#\" data-sw-translate>Model</a></li>\n <li><a class=\"snippet-link\" href=\"#\" data-sw-translate>Example Value</a></li>\n</ul>\n<div>\n\n<div class=\"signature-container\">\n <div class=\"description\">\n " |
| + container.escapeExpression((helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.signature : depth0),{"name":"sanitize","hash":{},"data":data})) |
| + "\n </div>\n\n <div class=\"snippet\">\n" |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.sampleJSON : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.sampleXML : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </div>\n</div>\n"; |
| },"2":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}; |
| |
| return " <div class=\"snippet_json\">\n <pre><code>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.sampleJSON : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</code></pre>\n " |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isParam : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n </div>\n"; |
| },"3":function(container,depth0,helpers,partials,data) { |
| return "<small class=\"notice\" data-sw-translate></small>"; |
| },"5":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}; |
| |
| return " <div class=\"snippet_xml\">\n <pre><code>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.sampleXML : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</code></pre>\n " |
| + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isParam : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + "\n </div>\n"; |
| },"7":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return " " |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.signature : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1; |
| |
| return ((stack1 = (helpers.ifCond || (depth0 && depth0.ifCond) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.sampleJSON : depth0),"||",(depth0 != null ? depth0.sampleXML : depth0),{"name":"ifCond","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : ""); |
| },"useData":true}); |
| templates['status_code'] = template({"1":function(container,depth0,helpers,partials,data) { |
| var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return " <tr>\n <td>" |
| + container.escapeExpression(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"key","hash":{},"data":data}) : helper))) |
| + "</td>\n <td>" |
| + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n <td>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n </tr>\n"; |
| },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { |
| var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing; |
| |
| return "<td width='15%' class='code'>" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.code : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n<td class=\"markdown\">" |
| + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.message : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "") |
| + "</td>\n<td width='50%'><span class=\"model-signature\" /></td>\n<td class=\"headers\">\n <table>\n <tbody>\n" |
| + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.headers : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") |
| + " </tbody>\n </table>\n</td>"; |
| },"useData":true}); |
| })();} |
| /* jshint ignore:end */ |
| 'use strict'; |
| |
| |
| $(function() { |
| |
| // Helper function for vertically aligning DOM elements |
| // http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/ |
| $.fn.vAlign = function() { |
| return this.each(function(){ |
| var ah = $(this).height(); |
| var ph = $(this).parent().height(); |
| var mh = (ph - ah) / 2; |
| $(this).css('margin-top', mh); |
| }); |
| }; |
| |
| $.fn.stretchFormtasticInputWidthToParent = function() { |
| return this.each(function(){ |
| var p_width = $(this).closest("form").innerWidth(); |
| var p_padding = parseInt($(this).closest("form").css('padding-left') ,10) + parseInt($(this).closest('form').css('padding-right'), 10); |
| var this_padding = parseInt($(this).css('padding-left'), 10) + parseInt($(this).css('padding-right'), 10); |
| $(this).css('width', p_width - p_padding - this_padding); |
| }); |
| }; |
| |
| $('form.formtastic li.string input, form.formtastic textarea').stretchFormtasticInputWidthToParent(); |
| |
| // Vertically center these paragraphs |
| // Parent may need a min-height for this to work.. |
| $('ul.downplayed li div.content p').vAlign(); |
| |
| // When a sandbox form is submitted.. |
| $("form.sandbox").submit(function(){ |
| |
| var error_free = true; |
| |
| // Cycle through the forms required inputs |
| $(this).find("input.required").each(function() { |
| |
| // Remove any existing error styles from the input |
| $(this).removeClass('error'); |
| |
| // Tack the error style on if the input is empty.. |
| if ($(this).val() === '') { |
| $(this).addClass('error'); |
| $(this).wiggle(); |
| error_free = false; |
| } |
| |
| }); |
| |
| return error_free; |
| }); |
| |
| }); |
| |
| function clippyCopiedCallback() { |
| $('#api_key_copied').fadeIn().delay(1000).fadeOut(); |
| |
| // var b = $("#clippy_tooltip_" + a); |
| // b.length != 0 && (b.attr("title", "copied!").trigger("tipsy.reload"), setTimeout(function() { |
| // b.attr("title", "copy to clipboard") |
| // }, |
| // 500)) |
| } |
| |
| // Logging function that accounts for browsers that don't have window.console |
| function log(){ |
| log.history = log.history || []; |
| log.history.push(arguments); |
| if(this.console){ |
| console.log( Array.prototype.slice.call(arguments)[0] ); |
| } |
| } |
| |
| // Handle browsers that do console incorrectly (IE9 and below, see http://stackoverflow.com/a/5539378/7913) |
| if (Function.prototype.bind && console && typeof console.log === "object") { |
| [ |
| "log","info","warn","error","assert","dir","clear","profile","profileEnd" |
| ].forEach(function (method) { |
| console[method] = this.bind(console[method], console); |
| }, Function.prototype.call); |
| } |
| |
| window.Docs = { |
| |
| shebang: function() { |
| |
| // If shebang has an operation nickname in it.. |
| // e.g. /docs/#!/words/get_search |
| var fragments = $.param.fragment().split('/'); |
| fragments.shift(); // get rid of the bang |
| |
| switch (fragments.length) { |
| case 1: |
| if (fragments[0].length > 0) { // prevent matching "#/" |
| // Expand all operations for the resource and scroll to it |
| var dom_id = 'resource_' + fragments[0]; |
| |
| Docs.expandEndpointListForResource(fragments[0]); |
| $("#"+dom_id).slideto({highlight: false}); |
| } |
| break; |
| case 2: |
| // Refer to the endpoint DOM element, e.g. #words_get_search |
| |
| // Expand Resource |
| Docs.expandEndpointListForResource(fragments[0]); |
| $("#"+dom_id).slideto({highlight: false}); |
| |
| // Expand operation |
| var li_dom_id = fragments.join('_'); |
| var li_content_dom_id = li_dom_id + "_content"; |
| |
| |
| Docs.expandOperation($('#'+li_content_dom_id)); |
| $('#'+li_dom_id).slideto({highlight: false}); |
| break; |
| } |
| }, |
| |
| toggleEndpointListForResource: function(resource) { |
| var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints'); |
| if (elem.is(':visible')) { |
| $.bbq.pushState('#/', 2); |
| Docs.collapseEndpointListForResource(resource); |
| } else { |
| $.bbq.pushState('#/' + resource, 2); |
| Docs.expandEndpointListForResource(resource); |
| } |
| }, |
| |
| // Expand resource |
| expandEndpointListForResource: function(resource) { |
| var resource = Docs.escapeResourceName(resource); |
| if (resource == '') { |
| $('.resource ul.endpoints').slideDown(); |
| return; |
| } |
| |
| $('li#resource_' + resource).addClass('active'); |
| |
| var elem = $('li#resource_' + resource + ' ul.endpoints'); |
| elem.slideDown(); |
| }, |
| |
| // Collapse resource and mark as explicitly closed |
| collapseEndpointListForResource: function(resource) { |
| var resource = Docs.escapeResourceName(resource); |
| if (resource == '') { |
| $('.resource ul.endpoints').slideUp(); |
| return; |
| } |
| |
| $('li#resource_' + resource).removeClass('active'); |
| |
| var elem = $('li#resource_' + resource + ' ul.endpoints'); |
| elem.slideUp(); |
| }, |
| |
| expandOperationsForResource: function(resource) { |
| // Make sure the resource container is open.. |
| Docs.expandEndpointListForResource(resource); |
| |
| if (resource == '') { |
| $('.resource ul.endpoints li.operation div.content').slideDown(); |
| return; |
| } |
| |
| $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() { |
| Docs.expandOperation($(this)); |
| }); |
| }, |
| |
| collapseOperationsForResource: function(resource) { |
| // Make sure the resource container is open.. |
| Docs.expandEndpointListForResource(resource); |
| |
| if (resource == '') { |
| $('.resource ul.endpoints li.operation div.content').slideUp(); |
| return; |
| } |
| |
| $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() { |
| Docs.collapseOperation($(this)); |
| }); |
| }, |
| |
| escapeResourceName: function(resource) { |
| return resource.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g, "\\$&"); |
| }, |
| |
| expandOperation: function(elem) { |
| elem.slideDown(); |
| }, |
| |
| collapseOperation: function(elem) { |
| elem.slideUp(); |
| } |
| }; |
| |
| /*! |
| * https://github.com/es-shims/es5-shim |
| * @license es5-shim Copyright 2009-2015 by contributors, MIT License |
| * see https://github.com/es-shims/es5-shim/blob/master/LICENSE |
| */ |
| |
| // vim: ts=4 sts=4 sw=4 expandtab |
| |
| // Add semicolon to prevent IIFE from being passed as argument to concatenated code. |
| ; |
| |
| // UMD (Universal Module Definition) |
| // see https://github.com/umdjs/umd/blob/master/templates/returnExports.js |
| (function (root, factory) { |
| 'use strict'; |
| |
| /* global define, exports, module */ |
| if (typeof define === 'function' && define.amd) { |
| // AMD. Register as an anonymous module. |
| define(factory); |
| } else if (typeof exports === 'object') { |
| // Node. Does not work with strict CommonJS, but |
| // only CommonJS-like enviroments that support module.exports, |
| // like Node. |
| module.exports = factory(); |
| } else { |
| // Browser globals (root is window) |
| root.returnExports = factory(); |
| } |
| }(this, function () { |
| /** |
| * Brings an environment as close to ECMAScript 5 compliance |
| * as is possible with the facilities of erstwhile engines. |
| * |
| * Annotated ES5: http://es5.github.com/ (specific links below) |
| * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf |
| * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/ |
| */ |
| |
| // Shortcut to an often accessed properties, in order to avoid multiple |
| // dereference that costs universally. This also holds a reference to known-good |
| // functions. |
| var $Array = Array; |
| var ArrayPrototype = $Array.prototype; |
| var $Object = Object; |
| var ObjectPrototype = $Object.prototype; |
| var $Function = Function; |
| var FunctionPrototype = $Function.prototype; |
| var $String = String; |
| var StringPrototype = $String.prototype; |
| var $Number = Number; |
| var NumberPrototype = $Number.prototype; |
| var array_slice = ArrayPrototype.slice; |
| var array_splice = ArrayPrototype.splice; |
| var array_push = ArrayPrototype.push; |
| var array_unshift = ArrayPrototype.unshift; |
| var array_concat = ArrayPrototype.concat; |
| var array_join = ArrayPrototype.join; |
| var call = FunctionPrototype.call; |
| var apply = FunctionPrototype.apply; |
| var max = Math.max; |
| var min = Math.min; |
| |
| // Having a toString local variable name breaks in Opera so use to_string. |
| var to_string = ObjectPrototype.toString; |
| |
| /* global Symbol */ |
| /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */ |
| var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; |
| var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, constructorRegex = /^\s*class /, isES6ClassFn = function isES6ClassFn(value) { try { var fnStr = fnToStr.call(value); var singleStripped = fnStr.replace(/\/\/.*\n/g, ''); var multiStripped = singleStripped.replace(/\/\*[.\s\S]*\*\//g, ''); var spaceStripped = multiStripped.replace(/\n/mg, ' ').replace(/ {2}/g, ' '); return constructorRegex.test(spaceStripped); } catch (e) { return false; /* not a function */ } }, tryFunctionObject = function tryFunctionObject(value) { try { if (isES6ClassFn(value)) { return false; } fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]', isCallable = function isCallable(value) { if (!value) { return false; } if (typeof value !== 'function' && typeof value !== 'object') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } if (isES6ClassFn(value)) { return false; } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; }; |
| |
| var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; }; |
| var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; }; |
| /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */ |
| |
| /* inlined from http://npmjs.com/define-properties */ |
| var supportsDescriptors = $Object.defineProperty && (function () { |
| try { |
| var obj = {}; |
| $Object.defineProperty(obj, 'x', { enumerable: false, value: obj }); |
| for (var _ in obj) { // jscs:ignore disallowUnusedVariables |
| return false; |
| } |
| return obj.x === obj; |
| } catch (e) { /* this is ES3 */ |
| return false; |
| } |
| }()); |
| var defineProperties = (function (has) { |
| // Define configurable, writable, and non-enumerable props |
| // if they don't exist. |
| var defineProperty; |
| if (supportsDescriptors) { |
| defineProperty = function (object, name, method, forceAssign) { |
| if (!forceAssign && (name in object)) { |
| return; |
| } |
| $Object.defineProperty(object, name, { |
| configurable: true, |
| enumerable: false, |
| writable: true, |
| value: method |
| }); |
| }; |
| } else { |
| defineProperty = function (object, name, method, forceAssign) { |
| if (!forceAssign && (name in object)) { |
| return; |
| } |
| object[name] = method; |
| }; |
| } |
| return function defineProperties(object, map, forceAssign) { |
| for (var name in map) { |
| if (has.call(map, name)) { |
| defineProperty(object, name, map[name], forceAssign); |
| } |
| } |
| }; |
| }(ObjectPrototype.hasOwnProperty)); |
| |
| // |
| // Util |
| // ====== |
| // |
| |
| /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */ |
| var isPrimitive = function isPrimitive(input) { |
| var type = typeof input; |
| return input === null || (type !== 'object' && type !== 'function'); |
| }; |
| |
| var isActualNaN = $Number.isNaN || function isActualNaN(x) { |
| return x !== x; |
| }; |
| |
| var ES = { |
| // ES5 9.4 |
| // http://es5.github.com/#x9.4 |
| // http://jsperf.com/to-integer |
| /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */ |
| ToInteger: function ToInteger(num) { |
| var n = +num; |
| if (isActualNaN(n)) { |
| n = 0; |
| } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { |
| n = (n > 0 || -1) * Math.floor(Math.abs(n)); |
| } |
| return n; |
| }, |
| |
| /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */ |
| ToPrimitive: function ToPrimitive(input) { |
| var val, valueOf, toStr; |
| if (isPrimitive(input)) { |
| return input; |
| } |
| valueOf = input.valueOf; |
| if (isCallable(valueOf)) { |
| val = valueOf.call(input); |
| if (isPrimitive(val)) { |
| return val; |
| } |
| } |
| toStr = input.toString; |
| if (isCallable(toStr)) { |
| val = toStr.call(input); |
| if (isPrimitive(val)) { |
| return val; |
| } |
| } |
| throw new TypeError(); |
| }, |
| |
| // ES5 9.9 |
| // http://es5.github.com/#x9.9 |
| /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */ |
| ToObject: function (o) { |
| if (o == null) { // this matches both null and undefined |
| throw new TypeError("can't convert " + o + ' to object'); |
| } |
| return $Object(o); |
| }, |
| |
| /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */ |
| ToUint32: function ToUint32(x) { |
| return x >>> 0; |
| } |
| }; |
| |
| // |
| // Function |
| // ======== |
| // |
| |
| // ES-5 15.3.4.5 |
| // http://es5.github.com/#x15.3.4.5 |
| |
| var Empty = function Empty() {}; |
| |
| defineProperties(FunctionPrototype, { |
| bind: function bind(that) { // .length is 1 |
| // 1. Let Target be the this value. |
| var target = this; |
| // 2. If IsCallable(Target) is false, throw a TypeError exception. |
| if (!isCallable(target)) { |
| throw new TypeError('Function.prototype.bind called on incompatible ' + target); |
| } |
| // 3. Let A be a new (possibly empty) internal list of all of the |
| // argument values provided after thisArg (arg1, arg2 etc), in order. |
| // XXX slicedArgs will stand in for "A" if used |
| var args = array_slice.call(arguments, 1); // for normal call |
| // 4. Let F be a new native ECMAScript object. |
| // 11. Set the [[Prototype]] internal property of F to the standard |
| // built-in Function prototype object as specified in 15.3.3.1. |
| // 12. Set the [[Call]] internal property of F as described in |
| // 15.3.4.5.1. |
| // 13. Set the [[Construct]] internal property of F as described in |
| // 15.3.4.5.2. |
| // 14. Set the [[HasInstance]] internal property of F as described in |
| // 15.3.4.5.3. |
| var bound; |
| var binder = function () { |
| |
| if (this instanceof bound) { |
| // 15.3.4.5.2 [[Construct]] |
| // When the [[Construct]] internal method of a function object, |
| // F that was created using the bind function is called with a |
| // list of arguments ExtraArgs, the following steps are taken: |
| // 1. Let target be the value of F's [[TargetFunction]] |
| // internal property. |
| // 2. If target has no [[Construct]] internal method, a |
| // TypeError exception is thrown. |
| // 3. Let boundArgs be the value of F's [[BoundArgs]] internal |
| // property. |
| // 4. Let args be a new list containing the same values as the |
| // list boundArgs in the same order followed by the same |
| // values as the list ExtraArgs in the same order. |
| // 5. Return the result of calling the [[Construct]] internal |
| // method of target providing args as the arguments. |
| |
| var result = apply.call( |
| target, |
| this, |
| array_concat.call(args, array_slice.call(arguments)) |
| ); |
| if ($Object(result) === result) { |
| return result; |
| } |
| return this; |
| |
| } else { |
| // 15.3.4.5.1 [[Call]] |
| // When the [[Call]] internal method of a function object, F, |
| // which was created using the bind function is called with a |
| // this value and a list of arguments ExtraArgs, the following |
| // steps are taken: |
| // 1. Let boundArgs be the value of F's [[BoundArgs]] internal |
| // property. |
| // 2. Let boundThis be the value of F's [[BoundThis]] internal |
| // property. |
| // 3. Let target be the value of F's [[TargetFunction]] internal |
| // property. |
| // 4. Let args be a new list containing the same values as the |
| // list boundArgs in the same order followed by the same |
| // values as the list ExtraArgs in the same order. |
| // 5. Return the result of calling the [[Call]] internal method |
| // of target providing boundThis as the this value and |
| // providing args as the arguments. |
| |
| // equiv: target.call(this, ...boundArgs, ...args) |
| return apply.call( |
| target, |
| that, |
| array_concat.call(args, array_slice.call(arguments)) |
| ); |
| |
| } |
| |
| }; |
| |
| // 15. If the [[Class]] internal property of Target is "Function", then |
| // a. Let L be the length property of Target minus the length of A. |
| // b. Set the length own property of F to either 0 or L, whichever is |
| // larger. |
| // 16. Else set the length own property of F to 0. |
| |
| var boundLength = max(0, target.length - args.length); |
| |
| // 17. Set the attributes of the length own property of F to the values |
| // specified in 15.3.5.1. |
| var boundArgs = []; |
| for (var i = 0; i < boundLength; i++) { |
| array_push.call(boundArgs, '$' + i); |
| } |
| |
| // XXX Build a dynamic function with desired amount of arguments is the only |
| // way to set the length property of a function. |
| // In environments where Content Security Policies enabled (Chrome extensions, |
| // for ex.) all use of eval or Function costructor throws an exception. |
| // However in all of these environments Function.prototype.bind exists |
| // and so this code will never be executed. |
| bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder); |
| |
| if (target.prototype) { |
| Empty.prototype = target.prototype; |
| bound.prototype = new Empty(); |
| // Clean up dangling references. |
| Empty.prototype = null; |
| } |
| |
| // TODO |
| // 18. Set the [[Extensible]] internal property of F to true. |
| |
| // TODO |
| // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). |
| // 20. Call the [[DefineOwnProperty]] internal method of F with |
| // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: |
| // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and |
| // false. |
| // 21. Call the [[DefineOwnProperty]] internal method of F with |
| // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, |
| // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, |
| // and false. |
| |
| // TODO |
| // NOTE Function objects created using Function.prototype.bind do not |
| // have a prototype property or the [[Code]], [[FormalParameters]], and |
| // [[Scope]] internal properties. |
| // XXX can't delete prototype in pure-js. |
| |
| // 22. Return F. |
| return bound; |
| } |
| }); |
| |
| // _Please note: Shortcuts are defined after `Function.prototype.bind` as we |
| // use it in defining shortcuts. |
| var owns = call.bind(ObjectPrototype.hasOwnProperty); |
| var toStr = call.bind(ObjectPrototype.toString); |
| var arraySlice = call.bind(array_slice); |
| var arraySliceApply = apply.bind(array_slice); |
| var strSlice = call.bind(StringPrototype.slice); |
| var strSplit = call.bind(StringPrototype.split); |
| var strIndexOf = call.bind(StringPrototype.indexOf); |
| var pushCall = call.bind(array_push); |
| var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable); |
| var arraySort = call.bind(ArrayPrototype.sort); |
| |
| // |
| // Array |
| // ===== |
| // |
| |
| var isArray = $Array.isArray || function isArray(obj) { |
| return toStr(obj) === '[object Array]'; |
| }; |
| |
| // ES5 15.4.4.12 |
| // http://es5.github.com/#x15.4.4.13 |
| // Return len+argCount. |
| // [bugfix, ielt8] |
| // IE < 8 bug: [].unshift(0) === undefined but should be "1" |
| var hasUnshiftReturnValueBug = [].unshift(0) !== 1; |
| defineProperties(ArrayPrototype, { |
| unshift: function () { |
| array_unshift.apply(this, arguments); |
| return this.length; |
| } |
| }, hasUnshiftReturnValueBug); |
| |
| // ES5 15.4.3.2 |
| // http://es5.github.com/#x15.4.3.2 |
| // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray |
| defineProperties($Array, { isArray: isArray }); |
| |
| // The IsCallable() check in the Array functions |
| // has been replaced with a strict check on the |
| // internal class of the object to trap cases where |
| // the provided function was actually a regular |
| // expression literal, which in V8 and |
| // JavaScriptCore is a typeof "function". Only in |
| // V8 are regular expression literals permitted as |
| // reduce parameters, so it is desirable in the |
| // general case for the shim to match the more |
| // strict and common behavior of rejecting regular |
| // expressions. |
| |
| // ES5 15.4.4.18 |
| // http://es5.github.com/#x15.4.4.18 |
| // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach |
| |
| // Check failure of by-index access of string characters (IE < 9) |
| // and failure of `0 in boxedString` (Rhino) |
| var boxedString = $Object('a'); |
| var splitString = boxedString[0] !== 'a' || !(0 in boxedString); |
| |
| var properlyBoxesContext = function properlyBoxed(method) { |
| // Check node 0.6.21 bug where third parameter is not boxed |
| var properlyBoxesNonStrict = true; |
| var properlyBoxesStrict = true; |
| var threwException = false; |
| if (method) { |
| try { |
| method.call('foo', function (_, __, context) { |
| if (typeof context !== 'object') { |
| properlyBoxesNonStrict = false; |
| } |
| }); |
| |
| method.call([1], function () { |
| 'use strict'; |
| |
| properlyBoxesStrict = typeof this === 'string'; |
| }, 'x'); |
| } catch (e) { |
| threwException = true; |
| } |
| } |
| return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict; |
| }; |
| |
| defineProperties(ArrayPrototype, { |
| forEach: function forEach(callbackfn/*, thisArg*/) { |
| var object = ES.ToObject(this); |
| var self = splitString && isString(this) ? strSplit(this, '') : object; |
| var i = -1; |
| var length = ES.ToUint32(self.length); |
| var T; |
| if (arguments.length > 1) { |
| T = arguments[1]; |
| } |
| |
| // If no callback function or if callback is not a callable function |
| if (!isCallable(callbackfn)) { |
| throw new TypeError('Array.prototype.forEach callback must be a function'); |
| } |
| |
| while (++i < length) { |
| if (i in self) { |
| // Invoke the callback function with call, passing arguments: |
| // context, property value, property key, thisArg object |
| if (typeof T === 'undefined') { |
| callbackfn(self[i], i, object); |
| } else { |
| callbackfn.call(T, self[i], i, object); |
| } |
| } |
| } |
| } |
| }, !properlyBoxesContext(ArrayPrototype.forEach)); |
| |
| // ES5 15.4.4.19 |
| // http://es5.github.com/#x15.4.4.19 |
| // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map |
| defineProperties(ArrayPrototype, { |
| map: function map(callbackfn/*, thisArg*/) { |
| var object = ES.ToObject(this); |
| var self = splitString && isString(this) ? strSplit(this, '') : object; |
| var length = ES.ToUint32(self.length); |
| var result = $Array(length); |
| var T; |
| if (arguments.length > 1) { |
| T = arguments[1]; |
| } |
| |
| // If no callback function or if callback is not a callable function |
| if (!isCallable(callbackfn)) { |
| throw new TypeError('Array.prototype.map callback must be a function'); |
| } |
| |
| for (var i = 0; i < length; i++) { |
| if (i in self) { |
| if (typeof T === 'undefined') { |
| result[i] = callbackfn(self[i], i, object); |
| } else { |
| result[i] = callbackfn.call(T, self[i], i, object); |
| } |
| } |
| } |
| return result; |
| } |
| }, !properlyBoxesContext(ArrayPrototype.map)); |
| |
| // ES5 15.4.4.20 |
| // http://es5.github.com/#x15.4.4.20 |
| // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter |
| defineProperties(ArrayPrototype, { |
| filter: function filter(callbackfn/*, thisArg*/) { |
| var object = ES.ToObject(this); |
| var self = splitString && isString(this) ? strSplit(this, '') : object; |
| var length = ES.ToUint32(self.length); |
| var result = []; |
| var value; |
| var T; |
| if (arguments.length > 1) { |
| T = arguments[1]; |
| } |
| |
| // If no callback function or if callback is not a callable function |
| if (!isCallable(callbackfn)) { |
| throw new TypeError('Array.prototype.filter callback must be a function'); |
| } |
| |
| for (var i = 0; i < length; i++) { |
| if (i in self) { |
| value = self[i]; |
| if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) { |
| pushCall(result, value); |
| } |
| } |
| } |
| return result; |
| } |
| }, !properlyBoxesContext(ArrayPrototype.filter)); |
| |
| // ES5 15.4.4.16 |
| // http://es5.github.com/#x15.4.4.16 |
| // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every |
| defineProperties(ArrayPrototype, { |
| every: function every(callbackfn/*, thisArg*/) { |
| var object = ES.ToObject(this); |
| var self = splitString && isString(this) ? strSplit(this, '') : object; |
| var length = ES.ToUint32(self.length); |
| var T; |
| if (arguments.length > 1) { |
| T = arguments[1]; |
| } |
| |
| // If no callback function or if callback is not a callable function |
| if (!isCallable(callbackfn)) { |
| throw new TypeError('Array.prototype.every callback must be a function'); |
| } |
| |
| for (var i = 0; i < length; i++) { |
| if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) { |
| return false; |
| } |
| } |
| return true; |
| } |
| }, !properlyBoxesContext(ArrayPrototype.every)); |
| |
| // ES5 15.4.4.17 |
| // http://es5.github.com/#x15.4.4.17 |
| // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some |
| defineProperties(ArrayPrototype, { |
| some: function some(callbackfn/*, thisArg */) { |
| var object = ES.ToObject(this); |
| var self = splitString && isString(this) ? strSplit(this, '') : object; |
| var length = ES.ToUint32(self.length); |
| var T; |
| if (arguments.length > 1) { |
| T = arguments[1]; |
| } |
| |
| // If no callback function or if callback is not a callable function |
| if (!isCallable(callbackfn)) { |
| throw new TypeError('Array.prototype.some callback must be a function'); |
| } |
| |
| for (var i = 0; i < length; i++) { |
| if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) { |
| return true; |
| } |
| } |
| return false; |
| } |
| }, !properlyBoxesContext(ArrayPrototype.some)); |
| |
| // ES5 15.4.4.21 |
| // http://es5.github.com/#x15.4.4.21 |
| // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce |
| var reduceCoercesToObject = false; |
| if (ArrayPrototype.reduce) { |
| reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { |
| return list; |
| }) === 'object'; |
| } |
| defineProperties(ArrayPrototype, { |
| reduce: function reduce(callbackfn/*, initialValue*/) { |
| var object = ES.ToObject(this); |
| var self = splitString && isString(this) ? strSplit(this, '') : object; |
| var length = ES.ToUint32(self.length); |
| |
| // If no callback function or if callback is not a callable function |
| if (!isCallable(callbackfn)) { |
| throw new TypeError('Array.prototype.reduce callback must be a function'); |
| } |
| |
| // no value to return if no initial value and an empty array |
| if (length === 0 && arguments.length === 1) { |
| throw new TypeError('reduce of empty array with no initial value'); |
| } |
| |
| var i = 0; |
| var result; |
| if (arguments.length >= 2) { |
| result = arguments[1]; |
| } else { |
| do { |
| if (i in self) { |
| result = self[i++]; |
| break; |
| } |
| |
| // if array contains no values, no initial value to return |
| if (++i >= length) { |
| throw new TypeError('reduce of empty array with no initial value'); |
| } |
| } while (true); |
| } |
| |
| for (; i < length; i++) { |
| if (i in self) { |
| result = callbackfn(result, self[i], i, object); |
| } |
| } |
| |
| return result; |
| } |
| }, !reduceCoercesToObject); |
| |
| // ES5 15.4.4.22 |
| // http://es5.github.com/#x15.4.4.22 |
| // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight |
| var reduceRightCoercesToObject = false; |
| if (ArrayPrototype.reduceRight) { |
| reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { |
| return list; |
| }) === 'object'; |
| } |
| defineProperties(ArrayPrototype, { |
| reduceRight: function reduceRight(callbackfn/*, initial*/) { |
| var object = ES.ToObject(this); |
| var self = splitString && isString(this) ? strSplit(this, '') : object; |
| var length = ES.ToUint32(self.length); |
| |
| // If no callback function or if callback is not a callable function |
| if (!isCallable(callbackfn)) { |
| throw new TypeError('Array.prototype.reduceRight callback must be a function'); |
| } |
| |
| // no value to return if no initial value, empty array |
| if (length === 0 && arguments.length === 1) { |
| throw new TypeError('reduceRight of empty array with no initial value'); |
| } |
| |
| var result; |
| var i = length - 1; |
| if (arguments.length >= 2) { |
| result = arguments[1]; |
| } else { |
| do { |
| if (i in self) { |
| result = self[i--]; |
| break; |
| } |
| |
| // if array contains no values, no initial value to return |
| if (--i < 0) { |
| throw new TypeError('reduceRight of empty array with no initial value'); |
| } |
| } while (true); |
| } |
| |
| if (i < 0) { |
| return result; |
| } |
| |
| do { |
| if (i in self) { |
| result = callbackfn(result, self[i], i, object); |
| } |
| } while (i--); |
| |
| return result; |
| } |
| }, !reduceRightCoercesToObject); |
| |
| // ES5 15.4.4.14 |
| // http://es5.github.com/#x15.4.4.14 |
| // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf |
| var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1; |
| defineProperties(ArrayPrototype, { |
| indexOf: function indexOf(searchElement/*, fromIndex */) { |
| var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this); |
| var length = ES.ToUint32(self.length); |
| |
| if (length === 0) { |
| return -1; |
| } |
| |
| var i = 0; |
| if (arguments.length > 1) { |
| i = ES.ToInteger(arguments[1]); |
| } |
| |
| // handle negative indices |
| i = i >= 0 ? i : max(0, length + i); |
| for (; i < length; i++) { |
| if (i in self && self[i] === searchElement) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| }, hasFirefox2IndexOfBug); |
| |
| // ES5 15.4.4.15 |
| // http://es5.github.com/#x15.4.4.15 |
| // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf |
| var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1; |
| defineProperties(ArrayPrototype, { |
| lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) { |
| var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this); |
| var length = ES.ToUint32(self.length); |
| |
| if (length === 0) { |
| return -1; |
| } |
| var i = length - 1; |
| if (arguments.length > 1) { |
| i = min(i, ES.ToInteger(arguments[1])); |
| } |
| // handle negative indices |
| i = i >= 0 ? i : length - Math.abs(i); |
| for (; i >= 0; i--) { |
| if (i in self && searchElement === self[i]) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| }, hasFirefox2LastIndexOfBug); |
| |
| // ES5 15.4.4.12 |
| // http://es5.github.com/#x15.4.4.12 |
| var spliceNoopReturnsEmptyArray = (function () { |
| var a = [1, 2]; |
| var result = a.splice(); |
| return a.length === 2 && isArray(result) && result.length === 0; |
| }()); |
| defineProperties(ArrayPrototype, { |
| // Safari 5.0 bug where .splice() returns undefined |
| splice: function splice(start, deleteCount) { |
| if (arguments.length === 0) { |
| return []; |
| } else { |
| return array_splice.apply(this, arguments); |
| } |
| } |
| }, !spliceNoopReturnsEmptyArray); |
| |
| var spliceWorksWithEmptyObject = (function () { |
| var obj = {}; |
| ArrayPrototype.splice.call(obj, 0, 0, 1); |
| return obj.length === 1; |
| }()); |
| defineProperties(ArrayPrototype, { |
| splice: function splice(start, deleteCount) { |
| if (arguments.length === 0) { |
| return []; |
| } |
| var args = arguments; |
| this.length = max(ES.ToInteger(this.length), 0); |
| if (arguments.length > 0 && typeof deleteCount !== 'number') { |
| args = arraySlice(arguments); |
| if (args.length < 2) { |
| pushCall(args, this.length - start); |
| } else { |
| args[1] = ES.ToInteger(deleteCount); |
| } |
| } |
| return array_splice.apply(this, args); |
| } |
| }, !spliceWorksWithEmptyObject); |
| var spliceWorksWithLargeSparseArrays = (function () { |
| // Per https://github.com/es-shims/es5-shim/issues/295 |
| // Safari 7/8 breaks with sparse arrays of size 1e5 or greater |
| var arr = new $Array(1e5); |
| // note: the index MUST be 8 or larger or the test will false pass |
| arr[8] = 'x'; |
| arr.splice(1, 1); |
| // note: this test must be defined *after* the indexOf shim |
| // per https://github.com/es-shims/es5-shim/issues/313 |
| return arr.indexOf('x') === 7; |
| }()); |
| var spliceWorksWithSmallSparseArrays = (function () { |
| // Per https://github.com/es-shims/es5-shim/issues/295 |
| // Opera 12.15 breaks on this, no idea why. |
| var n = 256; |
| var arr = []; |
| arr[n] = 'a'; |
| arr.splice(n + 1, 0, 'b'); |
| return arr[n] === 'a'; |
| }()); |
| defineProperties(ArrayPrototype, { |
| splice: function splice(start, deleteCount) { |
| var O = ES.ToObject(this); |
| var A = []; |
| var len = ES.ToUint32(O.length); |
| var relativeStart = ES.ToInteger(start); |
| var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len); |
| var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart); |
| |
| var k = 0; |
| var from; |
| while (k < actualDeleteCount) { |
| from = $String(actualStart + k); |
| if (owns(O, from)) { |
| A[k] = O[from]; |
| } |
| k += 1; |
| } |
| |
| var items = arraySlice(arguments, 2); |
| var itemCount = items.length; |
| var to; |
| if (itemCount < actualDeleteCount) { |
| k = actualStart; |
| var maxK = len - actualDeleteCount; |
| while (k < maxK) { |
| from = $String(k + actualDeleteCount); |
| to = $String(k + itemCount); |
| if (owns(O, from)) { |
| O[to] = O[from]; |
| } else { |
| delete O[to]; |
| } |
| k += 1; |
| } |
| k = len; |
| var minK = len - actualDeleteCount + itemCount; |
| while (k > minK) { |
| delete O[k - 1]; |
| k -= 1; |
| } |
| } else if (itemCount > actualDeleteCount) { |
| k = len - actualDeleteCount; |
| while (k > actualStart) { |
| from = $String(k + actualDeleteCount - 1); |
| to = $String(k + itemCount - 1); |
| if (owns(O, from)) { |
| O[to] = O[from]; |
| } else { |
| delete O[to]; |
| } |
| k -= 1; |
| } |
| } |
| k = actualStart; |
| for (var i = 0; i < items.length; ++i) { |
| O[k] = items[i]; |
| k += 1; |
| } |
| O.length = len - actualDeleteCount + itemCount; |
| |
| return A; |
| } |
| }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays); |
| |
| var originalJoin = ArrayPrototype.join; |
| var hasStringJoinBug; |
| try { |
| hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3'; |
| } catch (e) { |
| hasStringJoinBug = true; |
| } |
| if (hasStringJoinBug) { |
| defineProperties(ArrayPrototype, { |
| join: function join(separator) { |
| var sep = typeof separator === 'undefined' ? ',' : separator; |
| return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep); |
| } |
| }, hasStringJoinBug); |
| } |
| |
| var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2'; |
| if (hasJoinUndefinedBug) { |
| defineProperties(ArrayPrototype, { |
| join: function join(separator) { |
| var sep = typeof separator === 'undefined' ? ',' : separator; |
| return originalJoin.call(this, sep); |
| } |
| }, hasJoinUndefinedBug); |
| } |
| |
| var pushShim = function push(item) { |
| var O = ES.ToObject(this); |
| var n = ES.ToUint32(O.length); |
| var i = 0; |
| while (i < arguments.length) { |
| O[n + i] = arguments[i]; |
| i += 1; |
| } |
| O.length = n + i; |
| return n + i; |
| }; |
| |
| var pushIsNotGeneric = (function () { |
| var obj = {}; |
| var result = Array.prototype.push.call(obj, undefined); |
| return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0); |
| }()); |
| defineProperties(ArrayPrototype, { |
| push: function push(item) { |
| if (isArray(this)) { |
| return array_push.apply(this, arguments); |
| } |
| return pushShim.apply(this, arguments); |
| } |
| }, pushIsNotGeneric); |
| |
| // This fixes a very weird bug in Opera 10.6 when pushing `undefined |
| var pushUndefinedIsWeird = (function () { |
| var arr = []; |
| var result = arr.push(undefined); |
| return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0); |
| }()); |
| defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird); |
| |
| // ES5 15.2.3.14 |
| // http://es5.github.io/#x15.4.4.10 |
| // Fix boxed string bug |
| defineProperties(ArrayPrototype, { |
| slice: function (start, end) { |
| var arr = isString(this) ? strSplit(this, '') : this; |
| return arraySliceApply(arr, arguments); |
| } |
| }, splitString); |
| |
| var sortIgnoresNonFunctions = (function () { |
| try { |
| [1, 2].sort(null); |
| [1, 2].sort({}); |
| return true; |
| } catch (e) {} |
| return false; |
| }()); |
| var sortThrowsOnRegex = (function () { |
| // this is a problem in Firefox 4, in which `typeof /a/ === 'function'` |
| try { |
| [1, 2].sort(/a/); |
| return false; |
| } catch (e) {} |
| return true; |
| }()); |
| var sortIgnoresUndefined = (function () { |
| // applies in IE 8, for one. |
| try { |
| [1, 2].sort(undefined); |
| return true; |
| } catch (e) {} |
| return false; |
| }()); |
| defineProperties(ArrayPrototype, { |
| sort: function sort(compareFn) { |
| if (typeof compareFn === 'undefined') { |
| return arraySort(this); |
| } |
| if (!isCallable(compareFn)) { |
| throw new TypeError('Array.prototype.sort callback must be a function'); |
| } |
| return arraySort(this, compareFn); |
| } |
| }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex); |
| |
| // |
| // Object |
| // ====== |
| // |
| |
| // ES5 15.2.3.14 |
| // http://es5.github.com/#x15.2.3.14 |
| |
| // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation |
| var hasDontEnumBug = !isEnum({ 'toString': null }, 'toString'); |
| var hasProtoEnumBug = isEnum(function () {}, 'prototype'); |
| var hasStringEnumBug = !owns('x', '0'); |
| var equalsConstructorPrototype = function (o) { |
| var ctor = o.constructor; |
| return ctor && ctor.prototype === o; |
| }; |
| var blacklistedKeys = { |
| $window: true, |
| $console: true, |
| $parent: true, |
| $self: true, |
| $frame: true, |
| $frames: true, |
| $frameElement: true, |
| $webkitIndexedDB: true, |
| $webkitStorageInfo: true, |
| $external: true |
| }; |
| var hasAutomationEqualityBug = (function () { |
| /* globals window */ |
| if (typeof window === 'undefined') { |
| return false; |
| } |
| for (var k in window) { |
| try { |
| if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') { |
| equalsConstructorPrototype(window[k]); |
| } |
| } catch (e) { |
| return true; |
| } |
| } |
| return false; |
| }()); |
| var equalsConstructorPrototypeIfNotBuggy = function (object) { |
| if (typeof window === 'undefined' || !hasAutomationEqualityBug) { |
| return equalsConstructorPrototype(object); |
| } |
| try { |
| return equalsConstructorPrototype(object); |
| } catch (e) { |
| return false; |
| } |
| }; |
| var dontEnums = [ |
| 'toString', |
| 'toLocaleString', |
| 'valueOf', |
| 'hasOwnProperty', |
| 'isPrototypeOf', |
| 'propertyIsEnumerable', |
| 'constructor' |
| ]; |
| var dontEnumsLength = dontEnums.length; |
| |
| // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js |
| // can be replaced with require('is-arguments') if we ever use a build process instead |
| var isStandardArguments = function isArguments(value) { |
| return toStr(value) === '[object Arguments]'; |
| }; |
| var isLegacyArguments = function isArguments(value) { |
| return value !== null && |
| typeof value === 'object' && |
| typeof value.length === 'number' && |
| value.length >= 0 && |
| !isArray(value) && |
| isCallable(value.callee); |
| }; |
| var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments; |
| |
| defineProperties($Object, { |
| keys: function keys(object) { |
| var isFn = isCallable(object); |
| var isArgs = isArguments(object); |
| var isObject = object !== null && typeof object === 'object'; |
| var isStr = isObject && isString(object); |
| |
| if (!isObject && !isFn && !isArgs) { |
| throw new TypeError('Object.keys called on a non-object'); |
| } |
| |
| var theKeys = []; |
| var skipProto = hasProtoEnumBug && isFn; |
| if ((isStr && hasStringEnumBug) || isArgs) { |
| for (var i = 0; i < object.length; ++i) { |
| pushCall(theKeys, $String(i)); |
| } |
| } |
| |
| if (!isArgs) { |
| for (var name in object) { |
| if (!(skipProto && name === 'prototype') && owns(object, name)) { |
| pushCall(theKeys, $String(name)); |
| } |
| } |
| } |
| |
| if (hasDontEnumBug) { |
| var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object); |
| for (var j = 0; j < dontEnumsLength; j++) { |
| var dontEnum = dontEnums[j]; |
| if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) { |
| pushCall(theKeys, dontEnum); |
| } |
| } |
| } |
| return theKeys; |
| } |
| }); |
| |
| var keysWorksWithArguments = $Object.keys && (function () { |
| // Safari 5.0 bug |
| return $Object.keys(arguments).length === 2; |
| }(1, 2)); |
| var keysHasArgumentsLengthBug = $Object.keys && (function () { |
| var argKeys = $Object.keys(arguments); |
| return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1; |
| }(1)); |
| var originalKeys = $Object.keys; |
| defineProperties($Object, { |
| keys: function keys(object) { |
| if (isArguments(object)) { |
| return originalKeys(arraySlice(object)); |
| } else { |
| return originalKeys(object); |
| } |
| } |
| }, !keysWorksWithArguments || keysHasArgumentsLengthBug); |
| |
| // |
| // Date |
| // ==== |
| // |
| |
| var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0; |
| var aNegativeTestDate = new Date(-1509842289600292); |
| var aPositiveTestDate = new Date(1449662400000); |
| var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT'; |
| var hasToDateStringFormatBug; |
| var hasToStringFormatBug; |
| var timeZoneOffset = aNegativeTestDate.getTimezoneOffset(); |
| if (timeZoneOffset < -720) { |
| hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875'; |
| hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString()); |
| } else { |
| hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875'; |
| hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString()); |
| } |
| |
| var originalGetFullYear = call.bind(Date.prototype.getFullYear); |
| var originalGetMonth = call.bind(Date.prototype.getMonth); |
| var originalGetDate = call.bind(Date.prototype.getDate); |
| var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear); |
| var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth); |
| var originalGetUTCDate = call.bind(Date.prototype.getUTCDate); |
| var originalGetUTCDay = call.bind(Date.prototype.getUTCDay); |
| var originalGetUTCHours = call.bind(Date.prototype.getUTCHours); |
| var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes); |
| var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds); |
| var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds); |
| var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; |
| var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; |
| var daysInMonth = function daysInMonth(month, year) { |
| return originalGetDate(new Date(year, month, 0)); |
| }; |
| |
| defineProperties(Date.prototype, { |
| getFullYear: function getFullYear() { |
| if (!this || !(this instanceof Date)) { |
| throw new TypeError('this is not a Date object.'); |
| } |
| var year = originalGetFullYear(this); |
| if (year < 0 && originalGetMonth(this) > 11) { |
| return year + 1; |
| } |
| return year; |
| }, |
| getMonth: function getMonth() { |
| if (!this || !(this instanceof Date)) { |
| throw new TypeError('this is not a Date object.'); |
| } |
| var year = originalGetFullYear(this); |
| var month = originalGetMonth(this); |
| if (year < 0 && month > 11) { |
| return 0; |
| } |
| return month; |
| }, |
| getDate: function getDate() { |
| if (!this || !(this instanceof Date)) { |
| throw new TypeError('this is not a Date object.'); |
| } |
| var year = originalGetFullYear(this); |
| var month = originalGetMonth(this); |
| var date = originalGetDate(this); |
| if (year < 0 && month > 11) { |
| if (month === 12) { |
| return date; |
| } |
| var days = daysInMonth(0, year + 1); |
| return (days - date) + 1; |
| } |
| return date; |
| }, |
| getUTCFullYear: function getUTCFullYear() { |
| if (!this || !(this instanceof Date)) { |
| throw new TypeError('this is not a Date object.'); |
| } |
| var year = originalGetUTCFullYear(this); |
| if (year < 0 && originalGetUTCMonth(this) > 11) { |
| return year + 1; |
| } |
| return year; |
| }, |
| getUTCMonth: function getUTCMonth() { |
| if (!this || !(this instanceof Date)) { |
| throw new TypeError('this is not a Date object.'); |
| } |
| var year = originalGetUTCFullYear(this); |
| var month = originalGetUTCMonth(this); |
| if (year < 0 && month > 11) { |
| return 0; |
| } |
| return month; |
| }, |
| getUTCDate: function getUTCDate() { |
| if (!this || !(this instanceof Date)) { |
| throw new TypeError('this is not a Date object.'); |
| } |
| var year = originalGetUTCFullYear(this); |
| var month = originalGetUTCMonth(this); |
| var date = originalGetUTCDate(this); |
| if (year < 0 && month > 11) { |
| if (month === 12) { |
| return date; |
| } |
| var days = daysInMonth(0, year + 1); |
| return (days - date) + 1; |
| } |
| return date; |
| } |
| }, hasNegativeMonthYearBug); |
| |
| defineProperties(Date.prototype, { |
| toUTCString: function toUTCString() { |
| if (!this || !(this instanceof Date)) { |
| throw new TypeError('this is not a Date object.'); |
| } |
| var day = originalGetUTCDay(this); |
| var date = originalGetUTCDate(this); |
| var month = originalGetUTCMonth(this); |
| var year = originalGetUTCFullYear(this); |
| var hour = originalGetUTCHours(this); |
| var minute = originalGetUTCMinutes(this); |
| var second = originalGetUTCSeconds(this); |
| return dayName[day] + ', ' + |
| (date < 10 ? '0' + date : date) + ' ' + |
| monthName[month] + ' ' + |
| year + ' ' + |
| (hour < 10 ? '0' + hour : hour) + ':' + |
| (minute < 10 ? '0' + minute : minute) + ':' + |
| (second < 10 ? '0' + second : second) + ' GMT'; |
| } |
| }, hasNegativeMonthYearBug || hasToUTCStringFormatBug); |
| |
| // Opera 12 has `,` |
| defineProperties(Date.prototype, { |
| toDateString: function toDateString() { |
| if (!this || !(this instanceof Date)) { |
| throw new TypeError('this is not a Date object.'); |
| } |
| var day = this.getDay(); |
| var date = this.getDate(); |
| var month = this.getMonth(); |
| var year = this.getFullYear(); |
| return dayName[day] + ' ' + |
| monthName[month] + ' ' + |
| (date < 10 ? '0' + date : date) + ' ' + |
| year; |
| } |
| }, hasNegativeMonthYearBug || hasToDateStringFormatBug); |
| |
| // can't use defineProperties here because of toString enumeration issue in IE <= 8 |
| if (hasNegativeMonthYearBug || hasToStringFormatBug) { |
| Date.prototype.toString = function toString() { |
| if (!this || !(this instanceof Date)) { |
| throw new TypeError('this is not a Date object.'); |
| } |
| var day = this.getDay(); |
| var date = this.getDate(); |
| var month = this.getMonth(); |
| var year = this.getFullYear(); |
| var hour = this.getHours(); |
| var minute = this.getMinutes(); |
| var second = this.getSeconds(); |
| var timezoneOffset = this.getTimezoneOffset(); |
| var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60); |
| var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60); |
| return dayName[day] + ' ' + |
| monthName[month] + ' ' + |
| (date < 10 ? '0' + date : date) + ' ' + |
| year + ' ' + |
| (hour < 10 ? '0' + hour : hour) + ':' + |
| (minute < 10 ? '0' + minute : minute) + ':' + |
| (second < 10 ? '0' + second : second) + ' GMT' + |
| (timezoneOffset > 0 ? '-' : '+') + |
| (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) + |
| (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset); |
| }; |
| if (supportsDescriptors) { |
| $Object.defineProperty(Date.prototype, 'toString', { |
| configurable: true, |
| enumerable: false, |
| writable: true |
| }); |
| } |
| } |
| |
| // ES5 15.9.5.43 |
| // http://es5.github.com/#x15.9.5.43 |
| // This function returns a String value represent the instance in time |
| // represented by this Date object. The format of the String is the Date Time |
| // string format defined in 15.9.1.15. All fields are present in the String. |
| // The time zone is always UTC, denoted by the suffix Z. If the time value of |
| // this object is not a finite Number a RangeError exception is thrown. |
| var negativeDate = -62198755200000; |
| var negativeYearString = '-000001'; |
| var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1; |
| var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z'; |
| |
| var getTime = call.bind(Date.prototype.getTime); |
| |
| defineProperties(Date.prototype, { |
| toISOString: function toISOString() { |
| if (!isFinite(this) || !isFinite(getTime(this))) { |
| // Adope Photoshop requires the second check. |
| throw new RangeError('Date.prototype.toISOString called on non-finite value.'); |
| } |
| |
| var year = originalGetUTCFullYear(this); |
| |
| var month = originalGetUTCMonth(this); |
| // see https://github.com/es-shims/es5-shim/issues/111 |
| year += Math.floor(month / 12); |
| month = (month % 12 + 12) % 12; |
| |
| // the date time string format is specified in 15.9.1.15. |
| var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)]; |
| year = ( |
| (year < 0 ? '-' : (year > 9999 ? '+' : '')) + |
| strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6) |
| ); |
| |
| for (var i = 0; i < result.length; ++i) { |
| // pad months, days, hours, minutes, and seconds to have two digits. |
| result[i] = strSlice('00' + result[i], -2); |
| } |
| // pad milliseconds to have three digits. |
| return ( |
| year + '-' + arraySlice(result, 0, 2).join('-') + |
| 'T' + arraySlice(result, 2).join(':') + '.' + |
| strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z' |
| ); |
| } |
| }, hasNegativeDateBug || hasSafari51DateBug); |
| |
| // ES5 15.9.5.44 |
| // http://es5.github.com/#x15.9.5.44 |
| // This function provides a String representation of a Date object for use by |
| // JSON.stringify (15.12.3). |
| var dateToJSONIsSupported = (function () { |
| try { |
| return Date.prototype.toJSON && |
| new Date(NaN).toJSON() === null && |
| new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 && |
| Date.prototype.toJSON.call({ // generic |
| toISOString: function () { return true; } |
| }); |
| } catch (e) { |
| return false; |
| } |
| }()); |
| if (!dateToJSONIsSupported) { |
| Date.prototype.toJSON = function toJSON(key) { |
| // When the toJSON method is called with argument key, the following |
| // steps are taken: |
| |
| // 1. Let O be the result of calling ToObject, giving it the this |
| // value as its argument. |
| // 2. Let tv be ES.ToPrimitive(O, hint Number). |
| var O = $Object(this); |
| var tv = ES.ToPrimitive(O); |
| // 3. If tv is a Number and is not finite, return null. |
| if (typeof tv === 'number' && !isFinite(tv)) { |
| return null; |
| } |
| // 4. Let toISO be the result of calling the [[Get]] internal method of |
| // O with argument "toISOString". |
| var toISO = O.toISOString; |
| // 5. If IsCallable(toISO) is false, throw a TypeError exception. |
| if (!isCallable(toISO)) { |
| throw new TypeError('toISOString property is not callable'); |
| } |
| // 6. Return the result of calling the [[Call]] internal method of |
| // toISO with O as the this value and an empty argument list. |
| return toISO.call(O); |
| |
| // NOTE 1 The argument is ignored. |
| |
| // NOTE 2 The toJSON function is intentionally generic; it does not |
| // require that its this value be a Date object. Therefore, it can be |
| // transferred to other kinds of objects for use as a method. However, |
| // it does require that any such object have a toISOString method. An |
| // object is free to use the argument key to filter its |
| // stringification. |
| }; |
| } |
| |
| // ES5 15.9.4.2 |
| // http://es5.github.com/#x15.9.4.2 |
| // based on work shared by Daniel Friesen (dantman) |
| // http://gist.github.com/303249 |
| var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15; |
| var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z')); |
| var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z')); |
| if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) { |
| // XXX global assignment won't work in embeddings that use |
| // an alternate object for the context. |
| /* global Date: true */ |
| /* eslint-disable no-undef */ |
| var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1; |
| var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime()); |
| /* eslint-disable no-implicit-globals */ |
| Date = (function (NativeDate) { |
| /* eslint-enable no-implicit-globals */ |
| /* eslint-enable no-undef */ |
| // Date.length === 7 |
| var DateShim = function Date(Y, M, D, h, m, s, ms) { |
| var length = arguments.length; |
| var date; |
| if (this instanceof NativeDate) { |
| var seconds = s; |
| var millis = ms; |
| if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) { |
| // work around a Safari 8/9 bug where it treats the seconds as signed |
| var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit; |
| var sToShift = Math.floor(msToShift / 1e3); |
| seconds += sToShift; |
| millis -= sToShift * 1e3; |
| } |
| date = length === 1 && $String(Y) === Y ? // isString(Y) |
| // We explicitly pass it through parse: |
| new NativeDate(DateShim.parse(Y)) : |
| // We have to manually make calls depending on argument |
| // length here |
| length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) : |
| length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) : |
| length >= 5 ? new NativeDate(Y, M, D, h, m) : |
| length >= 4 ? new NativeDate(Y, M, D, h) : |
| length >= 3 ? new NativeDate(Y, M, D) : |
| length >= 2 ? new NativeDate(Y, M) : |
| length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y) : |
| new NativeDate(); |
| } else { |
| date = NativeDate.apply(this, arguments); |
| } |
| if (!isPrimitive(date)) { |
| // Prevent mixups with unfixed Date object |
| defineProperties(date, { constructor: DateShim }, true); |
| } |
| return date; |
| }; |
| |
| // 15.9.1.15 Date Time String Format. |
| var isoDateExpression = new RegExp('^' + |
| '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign + |
| // 6-digit extended year |
| '(?:-(\\d{2})' + // optional month capture |
| '(?:-(\\d{2})' + // optional day capture |
| '(?:' + // capture hours:minutes:seconds.milliseconds |
| 'T(\\d{2})' + // hours capture |
| ':(\\d{2})' + // minutes capture |
| '(?:' + // optional :seconds.milliseconds |
| ':(\\d{2})' + // seconds capture |
| '(?:(\\.\\d{1,}))?' + // milliseconds capture |
| ')?' + |
| '(' + // capture UTC offset component |
| 'Z|' + // UTC capture |
| '(?:' + // offset specifier +/-hours:minutes |
| '([-+])' + // sign capture |
| '(\\d{2})' + // hours offset capture |
| ':(\\d{2})' + // minutes offset capture |
| ')' + |
| ')?)?)?)?' + |
| '$'); |
| |
| var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; |
| |
| var dayFromMonth = function dayFromMonth(year, month) { |
| var t = month > 1 ? 1 : 0; |
| return ( |
| months[month] + |
| Math.floor((year - 1969 + t) / 4) - |
| Math.floor((year - 1901 + t) / 100) + |
| Math.floor((year - 1601 + t) / 400) + |
| 365 * (year - 1970) |
| ); |
| }; |
| |
| var toUTC = function toUTC(t) { |
| var s = 0; |
| var ms = t; |
| if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) { |
| // work around a Safari 8/9 bug where it treats the seconds as signed |
| var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit; |
| var sToShift = Math.floor(msToShift / 1e3); |
| s += sToShift; |
| ms -= sToShift * 1e3; |
| } |
| return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms)); |
| }; |
| |
| // Copy any custom methods a 3rd party library may have added |
| for (var key in NativeDate) { |
| if (owns(NativeDate, key)) { |
| DateShim[key] = NativeDate[key]; |
| } |
| } |
| |
| // Copy "native" methods explicitly; they may be non-enumerable |
| defineProperties(DateShim, { |
| now: NativeDate.now, |
| UTC: NativeDate.UTC |
| }, true); |
| DateShim.prototype = NativeDate.prototype; |
| defineProperties(DateShim.prototype, { |
| constructor: DateShim |
| }, true); |
| |
| // Upgrade Date.parse to handle simplified ISO 8601 strings |
| var parseShim = function parse(string) { |
| var match = isoDateExpression.exec(string); |
| if (match) { |
| // parse months, days, hours, minutes, seconds, and milliseconds |
| // provide default values if necessary |
| // parse the UTC offset component |
| var year = $Number(match[1]), |
| month = $Number(match[2] || 1) - 1, |
| day = $Number(match[3] || 1) - 1, |
| hour = $Number(match[4] || 0), |
| minute = $Number(match[5] || 0), |
| second = $Number(match[6] || 0), |
| millisecond = Math.floor($Number(match[7] || 0) * 1000), |
| // When time zone is missed, local offset should be used |
| // (ES 5.1 bug) |
| // see https://bugs.ecmascript.org/show_bug.cgi?id=112 |
| isLocalTime = Boolean(match[4] && !match[8]), |
| signOffset = match[9] === '-' ? 1 : -1, |
| hourOffset = $Number(match[10] || 0), |
| minuteOffset = $Number(match[11] || 0), |
| result; |
| var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0; |
| if ( |
| hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) && |
| minute < 60 && second < 60 && millisecond < 1000 && |
| month > -1 && month < 12 && hourOffset < 24 && |
| minuteOffset < 60 && // detect invalid offsets |
| day > -1 && |
| day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month)) |
| ) { |
| result = ( |
| (dayFromMonth(year, month) + day) * 24 + |
| hour + |
| hourOffset * signOffset |
| ) * 60; |
| result = ( |
| (result + minute + minuteOffset * signOffset) * 60 + |
| second |
| ) * 1000 + millisecond; |
| if (isLocalTime) { |
| result = toUTC(result); |
| } |
| if (-8.64e15 <= result && result <= 8.64e15) { |
| return result; |
| } |
| } |
| return NaN; |
| } |
| return NativeDate.parse.apply(this, arguments); |
| }; |
| defineProperties(DateShim, { parse: parseShim }); |
| |
| return DateShim; |
| }(Date)); |
| /* global Date: false */ |
| } |
| |
| // ES5 15.9.4.4 |
| // http://es5.github.com/#x15.9.4.4 |
| if (!Date.now) { |
| Date.now = function now() { |
| return new Date().getTime(); |
| }; |
| } |
| |
| // |
| // Number |
| // ====== |
| // |
| |
| // ES5.1 15.7.4.5 |
| // http://es5.github.com/#x15.7.4.5 |
| var hasToFixedBugs = NumberPrototype.toFixed && ( |
| (0.00008).toFixed(3) !== '0.000' || |
| (0.9).toFixed(0) !== '1' || |
| (1.255).toFixed(2) !== '1.25' || |
| (1000000000000000128).toFixed(0) !== '1000000000000000128' |
| ); |
| |
| var toFixedHelpers = { |
| base: 1e7, |
| size: 6, |
| data: [0, 0, 0, 0, 0, 0], |
| multiply: function multiply(n, c) { |
| var i = -1; |
| var c2 = c; |
| while (++i < toFixedHelpers.size) { |
| c2 += n * toFixedHelpers.data[i]; |
| toFixedHelpers.data[i] = c2 % toFixedHelpers.base; |
| c2 = Math.floor(c2 / toFixedHelpers.base); |
| } |
| }, |
| divide: function divide(n) { |
| var i = toFixedHelpers.size; |
| var c = 0; |
| while (--i >= 0) { |
| c += toFixedHelpers.data[i]; |
| toFixedHelpers.data[i] = Math.floor(c / n); |
| c = (c % n) * toFixedHelpers.base; |
| } |
| }, |
| numToString: function numToString() { |
| var i = toFixedHelpers.size; |
| var s = ''; |
| while (--i >= 0) { |
| if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) { |
| var t = $String(toFixedHelpers.data[i]); |
| if (s === '') { |
| s = t; |
| } else { |
| s += strSlice('0000000', 0, 7 - t.length) + t; |
| } |
| } |
| } |
| return s; |
| }, |
| pow: function pow(x, n, acc) { |
| return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc))); |
| }, |
| log: function log(x) { |
| var n = 0; |
| var x2 = x; |
| while (x2 >= 4096) { |
| n += 12; |
| x2 /= 4096; |
| } |
| while (x2 >= 2) { |
| n += 1; |
| x2 /= 2; |
| } |
| return n; |
| } |
| }; |
| |
| var toFixedShim = function toFixed(fractionDigits) { |
| var f, x, s, m, e, z, j, k; |
| |
| // Test for NaN and round fractionDigits down |
| f = $Number(fractionDigits); |
| f = isActualNaN(f) ? 0 : Math.floor(f); |
| |
| if (f < 0 || f > 20) { |
| throw new RangeError('Number.toFixed called with invalid number of decimals'); |
| } |
| |
| x = $Number(this); |
| |
| if (isActualNaN(x)) { |
| return 'NaN'; |
| } |
| |
| // If it is too big or small, return the string value of the number |
| if (x <= -1e21 || x >= 1e21) { |
| return $String(x); |
| } |
| |
| s = ''; |
| |
| if (x < 0) { |
| s = '-'; |
| x = -x; |
| } |
| |
| m = '0'; |
| |
| if (x > 1e-21) { |
| // 1e-21 < x < 1e21 |
| // -70 < log2(x) < 70 |
| e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69; |
| z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1)); |
| z *= 0x10000000000000; // Math.pow(2, 52); |
| e = 52 - e; |
| |
| // -18 < e < 122 |
| // x = z / 2 ^ e |
| if (e > 0) { |
| toFixedHelpers.multiply(0, z); |
| j = f; |
| |
| while (j >= 7) { |
| toFixedHelpers.multiply(1e7, 0); |
| j -= 7; |
| } |
| |
| toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0); |
| j = e - 1; |
| |
| while (j >= 23) { |
| toFixedHelpers.divide(1 << 23); |
| j -= 23; |
| } |
| |
| toFixedHelpers.divide(1 << j); |
| toFixedHelpers.multiply(1, 1); |
| toFixedHelpers.divide(2); |
| m = toFixedHelpers.numToString(); |
| } else { |
| toFixedHelpers.multiply(0, z); |
| toFixedHelpers.multiply(1 << (-e), 0); |
| m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f); |
| } |
| } |
| |
| if (f > 0) { |
| k = m.length; |
| |
| if (k <= f) { |
| m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m; |
| } else { |
| m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f); |
| } |
| } else { |
| m = s + m; |
| } |
| |
| return m; |
| }; |
| defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs); |
| |
| var hasToPrecisionUndefinedBug = (function () { |
| try { |
| return 1.0.toPrecision(undefined) === '1'; |
| } catch (e) { |
| return true; |
| } |
| }()); |
| var originalToPrecision = NumberPrototype.toPrecision; |
| defineProperties(NumberPrototype, { |
| toPrecision: function toPrecision(precision) { |
| return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision); |
| } |
| }, hasToPrecisionUndefinedBug); |
| |
| // |
| // String |
| // ====== |
| // |
| |
| // ES5 15.5.4.14 |
| // http://es5.github.com/#x15.5.4.14 |
| |
| // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers] |
| // Many browsers do not split properly with regular expressions or they |
| // do not perform the split correctly under obscure conditions. |
| // See http://blog.stevenlevithan.com/archives/cross-browser-split |
| // I've tested in many browsers and this seems to cover the deviant ones: |
| // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""] |
| // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""] |
| // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not |
| // [undefined, "t", undefined, "e", ...] |
| // ''.split(/.?/) should be [], not [""] |
| // '.'.split(/()()/) should be ["."], not ["", "", "."] |
| |
| if ( |
| 'ab'.split(/(?:ab)*/).length !== 2 || |
| '.'.split(/(.?)(.?)/).length !== 4 || |
| 'tesst'.split(/(s)*/)[1] === 't' || |
| 'test'.split(/(?:)/, -1).length !== 4 || |
| ''.split(/.?/).length || |
| '.'.split(/()()/).length > 1 |
| ) { |
| (function () { |
| var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group |
| var maxSafe32BitInt = Math.pow(2, 32) - 1; |
| |
| StringPrototype.split = function (separator, limit) { |
| var string = String(this); |
| if (typeof separator === 'undefined' && limit === 0) { |
| return []; |
| } |
| |
| // If `separator` is not a regex, use native split |
| if (!isRegex(separator)) { |
| return strSplit(this, separator, limit); |
| } |
| |
| var output = []; |
| var flags = (separator.ignoreCase ? 'i' : '') + |
| (separator.multiline ? 'm' : '') + |
| (separator.unicode ? 'u' : '') + // in ES6 |
| (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6 |
| lastLastIndex = 0, |
| // Make `global` and avoid `lastIndex` issues by working with a copy |
| separator2, match, lastIndex, lastLength; |
| var separatorCopy = new RegExp(separator.source, flags + 'g'); |
| if (!compliantExecNpcg) { |
| // Doesn't need flags gy, but they don't hurt |
| separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags); |
| } |
| /* Values for `limit`, per the spec: |
| * If undefined: 4294967295 // maxSafe32BitInt |
| * If 0, Infinity, or NaN: 0 |
| * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; |
| * If negative number: 4294967296 - Math.floor(Math.abs(limit)) |
| * If other: Type-convert, then use the above rules |
| */ |
| var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit); |
| match = separatorCopy.exec(string); |
| while (match) { |
| // `separatorCopy.lastIndex` is not reliable cross-browser |
| lastIndex = match.index + match[0].length; |
| if (lastIndex > lastLastIndex) { |
| pushCall(output, strSlice(string, lastLastIndex, match.index)); |
| // Fix browsers whose `exec` methods don't consistently return `undefined` for |
| // nonparticipating capturing groups |
| if (!compliantExecNpcg && match.length > 1) { |
| /* eslint-disable no-loop-func */ |
| match[0].replace(separator2, function () { |
| for (var i = 1; i < arguments.length - 2; i++) { |
| if (typeof arguments[i] === 'undefined') { |
| match[i] = void 0; |
| } |
| } |
| }); |
| /* eslint-enable no-loop-func */ |
| } |
| if (match.length > 1 && match.index < string.length) { |
| array_push.apply(output, arraySlice(match, 1)); |
| } |
| lastLength = match[0].length; |
| lastLastIndex = lastIndex; |
| if (output.length >= splitLimit) { |
| break; |
| } |
| } |
| if (separatorCopy.lastIndex === match.index) { |
| separatorCopy.lastIndex++; // Avoid an infinite loop |
| } |
| match = separatorCopy.exec(string); |
| } |
| if (lastLastIndex === string.length) { |
| if (lastLength || !separatorCopy.test('')) { |
| pushCall(output, ''); |
| } |
| } else { |
| pushCall(output, strSlice(string, lastLastIndex)); |
| } |
| return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output; |
| }; |
| }()); |
| |
| // [bugfix, chrome] |
| // If separator is undefined, then the result array contains just one String, |
| // which is the this value (converted to a String). If limit is not undefined, |
| // then the output array is truncated so that it contains no more than limit |
| // elements. |
| // "0".split(undefined, 0) -> [] |
| } else if ('0'.split(void 0, 0).length) { |
| StringPrototype.split = function split(separator, limit) { |
| if (typeof separator === 'undefined' && limit === 0) { |
| return []; |
| } |
| return strSplit(this, separator, limit); |
| }; |
| } |
| |
| var str_replace = StringPrototype.replace; |
| var replaceReportsGroupsCorrectly = (function () { |
| var groups = []; |
| 'x'.replace(/x(.)?/g, function (match, group) { |
| pushCall(groups, group); |
| }); |
| return groups.length === 1 && typeof groups[0] === 'undefined'; |
| }()); |
| |
| if (!replaceReportsGroupsCorrectly) { |
| StringPrototype.replace = function replace(searchValue, replaceValue) { |
| var isFn = isCallable(replaceValue); |
| var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source); |
| if (!isFn || !hasCapturingGroups) { |
| return str_replace.call(this, searchValue, replaceValue); |
| } else { |
| var wrappedReplaceValue = function (match) { |
| var length = arguments.length; |
| var originalLastIndex = searchValue.lastIndex; |
| searchValue.lastIndex = 0; |
| var args = searchValue.exec(match) || []; |
| searchValue.lastIndex = originalLastIndex; |
| pushCall(args, arguments[length - 2], arguments[length - 1]); |
| return replaceValue.apply(this, args); |
| }; |
| return str_replace.call(this, searchValue, wrappedReplaceValue); |
| } |
| }; |
| } |
| |
| // ECMA-262, 3rd B.2.3 |
| // Not an ECMAScript standard, although ECMAScript 3rd Edition has a |
| // non-normative section suggesting uniform semantics and it should be |
| // normalized across all browsers |
| // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE |
| var string_substr = StringPrototype.substr; |
| var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b'; |
| defineProperties(StringPrototype, { |
| substr: function substr(start, length) { |
| var normalizedStart = start; |
| if (start < 0) { |
| normalizedStart = max(this.length + start, 0); |
| } |
| return string_substr.call(this, normalizedStart, length); |
| } |
| }, hasNegativeSubstrBug); |
| |
| // ES5 15.5.4.20 |
| // whitespace from: http://es5.github.io/#x15.5.4.20 |
| var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + |
| '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + |
| '\u2029\uFEFF'; |
| var zeroWidth = '\u200b'; |
| var wsRegexChars = '[' + ws + ']'; |
| var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*'); |
| var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$'); |
| var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim()); |
| defineProperties(StringPrototype, { |
| // http://blog.stevenlevithan.com/archives/faster-trim-javascript |
| // http://perfectionkills.com/whitespace-deviations/ |
| trim: function trim() { |
| if (typeof this === 'undefined' || this === null) { |
| throw new TypeError("can't convert " + this + ' to object'); |
| } |
| return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, ''); |
| } |
| }, hasTrimWhitespaceBug); |
| var trim = call.bind(String.prototype.trim); |
| |
| var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1; |
| defineProperties(StringPrototype, { |
| lastIndexOf: function lastIndexOf(searchString) { |
| if (typeof this === 'undefined' || this === null) { |
| throw new TypeError("can't convert " + this + ' to object'); |
| } |
| var S = $String(this); |
| var searchStr = $String(searchString); |
| var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN; |
| var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos); |
| var start = min(max(pos, 0), S.length); |
| var searchLen = searchStr.length; |
| var k = start + searchLen; |
| while (k > 0) { |
| k = max(0, k - searchLen); |
| var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr); |
| if (index !== -1) { |
| return k + index; |
| } |
| } |
| return -1; |
| } |
| }, hasLastIndexBug); |
| |
| var originalLastIndexOf = StringPrototype.lastIndexOf; |
| defineProperties(StringPrototype, { |
| lastIndexOf: function lastIndexOf(searchString) { |
| return originalLastIndexOf.apply(this, arguments); |
| } |
| }, StringPrototype.lastIndexOf.length !== 1); |
| |
| // ES-5 15.1.2.2 |
| /* eslint-disable radix */ |
| if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) { |
| /* eslint-enable radix */ |
| /* global parseInt: true */ |
| parseInt = (function (origParseInt) { |
| var hexRegex = /^[\-+]?0[xX]/; |
| return function parseInt(str, radix) { |
| var string = trim(String(str)); |
| var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10); |
| return origParseInt(string, defaultedRadix); |
| }; |
| }(parseInt)); |
| } |
| |
| // https://es5.github.io/#x15.1.2.3 |
| if (1 / parseFloat('-0') !== -Infinity) { |
| /* global parseFloat: true */ |
| parseFloat = (function (origParseFloat) { |
| return function parseFloat(string) { |
| var inputString = trim(String(string)); |
| var result = origParseFloat(inputString); |
| return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result; |
| }; |
| }(parseFloat)); |
| } |
| |
| if (String(new RangeError('test')) !== 'RangeError: test') { |
| var errorToStringShim = function toString() { |
| if (typeof this === 'undefined' || this === null) { |
| throw new TypeError("can't convert " + this + ' to object'); |
| } |
| var name = this.name; |
| if (typeof name === 'undefined') { |
| name = 'Error'; |
| } else if (typeof name !== 'string') { |
| name = $String(name); |
| } |
| var msg = this.message; |
| if (typeof msg === 'undefined') { |
| msg = ''; |
| } else if (typeof msg !== 'string') { |
| msg = $String(msg); |
| } |
| if (!name) { |
| return msg; |
| } |
| if (!msg) { |
| return name; |
| } |
| return name + ': ' + msg; |
| }; |
| // can't use defineProperties here because of toString enumeration issue in IE <= 8 |
| Error.prototype.toString = errorToStringShim; |
| } |
| |
| if (supportsDescriptors) { |
| var ensureNonEnumerable = function (obj, prop) { |
| if (isEnum(obj, prop)) { |
| var desc = Object.getOwnPropertyDescriptor(obj, prop); |
| if (desc.configurable) { |
| desc.enumerable = false; |
| Object.defineProperty(obj, prop, desc); |
| } |
| } |
| }; |
| ensureNonEnumerable(Error.prototype, 'message'); |
| if (Error.prototype.message !== '') { |
| Error.prototype.message = ''; |
| } |
| ensureNonEnumerable(Error.prototype, 'name'); |
| } |
| |
| if (String(/a/mig) !== '/a/gim') { |
| var regexToString = function toString() { |
| var str = '/' + this.source + '/'; |
| if (this.global) { |
| str += 'g'; |
| } |
| if (this.ignoreCase) { |
| str += 'i'; |
| } |
| if (this.multiline) { |
| str += 'm'; |
| } |
| return str; |
| }; |
| // can't use defineProperties here because of toString enumeration issue in IE <= 8 |
| RegExp.prototype.toString = regexToString; |
| } |
| })); |
| |
| 'use strict'; |
| /*jslint eqeq: true*/ |
| |
| Handlebars.registerHelper('sanitize', function (text) { |
| var result; |
| |
| if (text === undefined) { return ''; } |
| |
| result = sanitizeHtml(text, { |
| allowedTags: [ 'div', 'span', 'b', 'i', 'em', 'strong', 'a', 'br', 'table', 'tbody', 'tr', 'th', 'td' ], |
| allowedAttributes: { |
| 'div': [ 'class' ], |
| 'span': [ 'class' ], |
| 'table': [ 'class' ], |
| 'td': [ 'class' ], |
| 'th': [ 'colspan' ], |
| 'a': [ 'href' ] |
| } |
| }); |
| |
| return new Handlebars.SafeString(result); |
| }); |
| |
| Handlebars.registerHelper('renderTextParam', function(param) { |
| var result, type = 'text', idAtt = ''; |
| var paramType = param.type || param.schema && param.schema.type || ''; |
| var isArray = paramType.toLowerCase() === 'array' || param.allowMultiple; |
| var defaultValue = isArray && Array.isArray(param.default) ? param.default.join('\n') : param.default; |
| var name = Handlebars.Utils.escapeExpression(param.name); |
| var valueId = Handlebars.Utils.escapeExpression(param.valueId); |
| paramType = Handlebars.Utils.escapeExpression(paramType); |
| |
| var dataVendorExtensions = Object.keys(param).filter(function(property) { |
| // filter X-data- properties |
| return property.match(/^X-data-/i) !== null; |
| }).reduce(function(result, property) { |
| // remove X- from property name, so it results in html attributes like data-foo='bar' |
| return result += ' ' + property.substring(2, property.length) + '=\'' + param[property] + '\''; |
| }, ''); |
| |
| if(param.format && param.format === 'password') { |
| type = 'password'; |
| } |
| |
| if(valueId) { |
| idAtt = ' id=\'' + valueId + '\''; |
| } |
| |
| if (defaultValue) { |
| defaultValue = sanitizeHtml(defaultValue); |
| } else { |
| defaultValue = ''; |
| } |
| |
| if(isArray) { |
| result = '<textarea class=\'body-textarea' + (param.required ? ' required' : '') + '\' name=\'' + name + '\'' + idAtt + dataVendorExtensions; |
| result += ' placeholder=\'Provide multiple values in new lines' + (param.required ? ' (at least one required).' : '.') + '\'>'; |
| result += defaultValue + '</textarea>'; |
| } else { |
| var parameterClass = 'parameter'; |
| if(param.required) { |
| parameterClass += ' required'; |
| } |
| result = '<input class=\'' + parameterClass + '\' minlength=\'' + (param.required ? 1 : 0) + '\''; |
| result += ' name=\'' + name +'\' placeholder=\'' + (param.required ? '(required)' : '') + '\'' + idAtt + dataVendorExtensions; |
| result += ' type=\'' + type + '\' value=\'' + defaultValue + '\'/>'; |
| } |
| return new Handlebars.SafeString(result); |
| }); |
| |
| Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) { |
| |
| switch (operator) { |
| case '==': |
| return (v1 == v2) ? options.fn(this) : options.inverse(this); |
| case '===': |
| return (v1 === v2) ? options.fn(this) : options.inverse(this); |
| case '<': |
| return (v1 < v2) ? options.fn(this) : options.inverse(this); |
| case '<=': |
| return (v1 <= v2) ? options.fn(this) : options.inverse(this); |
| case '>': |
| return (v1 > v2) ? options.fn(this) : options.inverse(this); |
| case '>=': |
| return (v1 >= v2) ? options.fn(this) : options.inverse(this); |
| case '&&': |
| return (v1 && v2) ? options.fn(this) : options.inverse(this); |
| case '||': |
| return (v1 || v2) ? options.fn(this) : options.inverse(this); |
| default: |
| return options.inverse(this); |
| } |
| }); |
| |
| Handlebars.registerHelper('escape', function (value) { |
| var text = Handlebars.Utils.escapeExpression(value); |
| |
| return new Handlebars.SafeString(text); |
| }); |
| |
| (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.sanitizeHtml=f()}})(function(){var define,module,exports;return 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 htmlparser=require("htmlparser2");var extend=require("xtend");var quoteRegexp=require("regexp-quote");function each(obj,cb){if(obj)Object.keys(obj).forEach(function(key){cb(obj[key],key)})}function has(obj,key){return{}.hasOwnProperty.call(obj,key)}module.exports=sanitizeHtml;function sanitizeHtml(html,options,_recursing){var result="";function Frame(tag,attribs){var that=this;this.tag=tag;this.attribs=attribs||{};this.tagPosition=result.length;this.text="";this.updateParentNodeText=function(){if(stack.length){var parentFrame=stack[stack.length-1];parentFrame.text+=that.text}}}if(!options){options=sanitizeHtml.defaults;options.parser=htmlParserDefaults}else{options=extend(sanitizeHtml.defaults,options);if(options.parser){options.parser=extend(htmlParserDefaults,options.parser)}else{options.parser=htmlParserDefaults}}var nonTextTagsArray=options.nonTextTags||["script","style","textarea"];var allowedAttributesMap;var allowedAttributesGlobMap;if(options.allowedAttributes){allowedAttributesMap={};allowedAttributesGlobMap={};each(options.allowedAttributes,function(attributes,tag){allowedAttributesMap[tag]=[];var globRegex=[];attributes.forEach(function(name){if(name.indexOf("*")>=0){globRegex.push(quoteRegexp(name).replace(/\\\*/g,".*"))}else{allowedAttributesMap[tag].push(name)}});allowedAttributesGlobMap[tag]=new RegExp("^("+globRegex.join("|")+")$")})}var allowedClassesMap={};each(options.allowedClasses,function(classes,tag){if(allowedAttributesMap){if(!has(allowedAttributesMap,tag)){allowedAttributesMap[tag]=[]}allowedAttributesMap[tag].push("class")}allowedClassesMap[tag]=classes});var transformTagsMap={};var transformTagsAll;each(options.transformTags,function(transform,tag){var transFun;if(typeof transform==="function"){transFun=transform}else if(typeof transform==="string"){transFun=sanitizeHtml.simpleTransform(transform)}if(tag==="*"){transformTagsAll=transFun}else{transformTagsMap[tag]=transFun}});var depth=0;var stack=[];var skipMap={};var transformMap={};var skipText=false;var skipTextDepth=0;var parser=new htmlparser.Parser({onopentag:function(name,attribs){if(skipText){skipTextDepth++;return}var frame=new Frame(name,attribs);stack.push(frame);var skip=false;var hasText=frame.text?true:false;var transformedTag;if(has(transformTagsMap,name)){transformedTag=transformTagsMap[name](name,attribs);frame.attribs=attribs=transformedTag.attribs;if(transformedTag.text!==undefined){frame.innerText=transformedTag.text}if(name!==transformedTag.tagName){frame.name=name=transformedTag.tagName;transformMap[depth]=transformedTag.tagName}}if(transformTagsAll){transformedTag=transformTagsAll(name,attribs);frame.attribs=attribs=transformedTag.attribs;if(name!==transformedTag.tagName){frame.name=name=transformedTag.tagName;transformMap[depth]=transformedTag.tagName}}if(options.allowedTags&&options.allowedTags.indexOf(name)===-1){skip=true;if(nonTextTagsArray.indexOf(name)!==-1){skipText=true;skipTextDepth=1}skipMap[depth]=true}depth++;if(skip){return}result+="<"+name;if(!allowedAttributesMap||has(allowedAttributesMap,name)||allowedAttributesMap["*"]){each(attribs,function(value,a){if(!allowedAttributesMap||has(allowedAttributesMap,name)&&allowedAttributesMap[name].indexOf(a)!==-1||allowedAttributesMap["*"]&&allowedAttributesMap["*"].indexOf(a)!==-1||has(allowedAttributesGlobMap,name)&&allowedAttributesGlobMap[name].test(a)||allowedAttributesGlobMap["*"]&&allowedAttributesGlobMap["*"].test(a)){if(a==="href"||a==="src"){if(naughtyHref(name,value)){delete frame.attribs[a];return}}if(a==="class"){value=filterClasses(value,allowedClassesMap[name]);if(!value.length){delete frame.attribs[a];return}}result+=" "+a;if(value.length){result+='="'+escapeHtml(value)+'"'}}else{delete frame.attribs[a]}})}if(options.selfClosing.indexOf(name)!==-1){result+=" />"}else{result+=">";if(frame.innerText&&!hasText&&!options.textFilter){result+=frame.innerText}}},ontext:function(text){if(skipText){return}var lastFrame=stack[stack.length-1];var tag;if(lastFrame){tag=lastFrame.tag;text=lastFrame.innerText!==undefined?lastFrame.innerText:text}if(tag==="script"||tag==="style"){result+=text}else{var escaped=escapeHtml(text);if(options.textFilter){result+=options.textFilter(escaped)}else{result+=escaped}}if(stack.length){var frame=stack[stack.length-1];frame.text+=text}},onclosetag:function(name){if(skipText){skipTextDepth--;if(!skipTextDepth){skipText=false}else{return}}var frame=stack.pop();if(!frame){return}skipText=false;depth--;if(skipMap[depth]){delete skipMap[depth];frame.updateParentNodeText();return}if(transformMap[depth]){name=transformMap[depth];delete transformMap[depth]}if(options.exclusiveFilter&&options.exclusiveFilter(frame)){result=result.substr(0,frame.tagPosition);return}frame.updateParentNodeText();if(options.selfClosing.indexOf(name)!==-1){return}result+="</"+name+">"}},options.parser);parser.write(html);parser.end();return result;function escapeHtml(s){if(typeof s!=="string"){s=s+""}return s.replace(/\&/g,"&").replace(/</g,"<").replace(/\>/g,">").replace(/\"/g,""")}function naughtyHref(name,href){href=href.replace(/[\x00-\x20]+/g,"");href=href.replace(/<\!\-\-.*?\-\-\>/g,"");var matches=href.match(/^([a-zA-Z]+)\:/);if(!matches){return false}var scheme=matches[1].toLowerCase();if(has(options.allowedSchemesByTag,name)){return options.allowedSchemesByTag[name].indexOf(scheme)===-1}return!options.allowedSchemes||options.allowedSchemes.indexOf(scheme)===-1}function filterClasses(classes,allowed){if(!allowed){return classes}classes=classes.split(/\s+/);return classes.filter(function(clss){return allowed.indexOf(clss)!==-1}).join(" ")}}var htmlParserDefaults={decodeEntities:true};sanitizeHtml.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre"],allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{}};sanitizeHtml.simpleTransform=function(newTagName,newAttribs,merge){merge=merge===undefined?true:merge;newAttribs=newAttribs||{};return function(tagName,attribs){var attrib;if(merge){for(attrib in newAttribs){attribs[attrib]=newAttribs[attrib]}}else{attribs=newAttribs}return{tagName:newTagName,attribs:attribs}}}},{htmlparser2:36,"regexp-quote":54,xtend:58}],2:[function(require,module,exports){"use strict";exports.toByteArray=toByteArray;exports.fromByteArray=fromByteArray;var lookup=[];var revLookup=[];var Arr=typeof Uint8Array!=="undefined"?Uint8Array:Array;function init(){var code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(var i=0,len=code.length;i<len;++i){lookup[i]=code[i];revLookup[code.charCodeAt(i)]=i}revLookup["-".charCodeAt(0)]=62;revLookup["_".charCodeAt(0)]=63}init();function toByteArray(b64){var i,j,l,tmp,placeHolders,arr;var len=b64.length;if(len%4>0){throw new Error("Invalid string. Length must be a multiple of 4")}placeHolders=b64[len-2]==="="?2:b64[len-1]==="="?1:0;arr=new Arr(len*3/4-placeHolders);l=placeHolders>0?len-4:len;var L=0;for(i=0,j=0;i<l;i+=4,j+=3){tmp=revLookup[b64.charCodeAt(i)]<<18|revLookup[b64.charCodeAt(i+1)]<<12|revLookup[b64.charCodeAt(i+2)]<<6|revLookup[b64.charCodeAt(i+3)];arr[L++]=tmp>>16&255;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}if(placeHolders===2){tmp=revLookup[b64.charCodeAt(i)]<<2|revLookup[b64.charCodeAt(i+1)]>>4;arr[L++]=tmp&255}else if(placeHolders===1){tmp=revLookup[b64.charCodeAt(i)]<<10|revLookup[b64.charCodeAt(i+1)]<<4|revLookup[b64.charCodeAt(i+2)]>>2;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}return arr}function tripletToBase64(num){return lookup[num>>18&63]+lookup[num>>12&63]+lookup[num>>6&63]+lookup[num&63]}function encodeChunk(uint8,start,end){var tmp;var output=[];for(var i=start;i<end;i+=3){tmp=(uint8[i]<<16)+(uint8[i+1]<<8)+uint8[i+2];output.push(tripletToBase64(tmp))}return output.join("")}function fromByteArray(uint8){var tmp;var len=uint8.length;var extraBytes=len%3;var output="";var parts=[];var maxChunkLength=16383;for(var i=0,len2=len-extraBytes;i<len2;i+=maxChunkLength){parts.push(encodeChunk(uint8,i,i+maxChunkLength>len2?len2:i+maxChunkLength))}if(extraBytes===1){tmp=uint8[len-1];output+=lookup[tmp>>2];output+=lookup[tmp<<4&63];output+="=="}else if(extraBytes===2){tmp=(uint8[len-2]<<8)+uint8[len-1];output+=lookup[tmp>>10];output+=lookup[tmp>>4&63];output+=lookup[tmp<<2&63];output+="="}parts.push(output);return parts.join("")}},{}],3:[function(require,module,exports){},{}],4:[function(require,module,exports){(function(global){"use strict";var buffer=require("buffer");var Buffer=buffer.Buffer;var SlowBuffer=buffer.SlowBuffer;var MAX_LEN=buffer.kMaxLength||2147483647;exports.alloc=function alloc(size,fill,encoding){if(typeof Buffer.alloc==="function"){return Buffer.alloc(size,fill,encoding)}if(typeof encoding==="number"){throw new TypeError("encoding must not be number")}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>MAX_LEN){throw new RangeError("size is too large")}var enc=encoding;var _fill=fill;if(_fill===undefined){enc=undefined;_fill=0}var buf=new Buffer(size);if(typeof _fill==="string"){var fillBuf=new Buffer(_fill,enc);var flen=fillBuf.length;var i=-1;while(++i<size){buf[i]=fillBuf[i%flen]}}else{buf.fill(_fill)}return buf};exports.allocUnsafe=function allocUnsafe(size){if(typeof Buffer.allocUnsafe==="function"){return Buffer.allocUnsafe(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>MAX_LEN){throw new RangeError("size is too large")}return new Buffer(size)};exports.from=function from(value,encodingOrOffset,length){if(typeof Buffer.from==="function"&&(!global.Uint8Array||Uint8Array.from!==Buffer.from)){return Buffer.from(value,encodingOrOffset,length)}if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof value==="string"){return new Buffer(value,encodingOrOffset)}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){var offset=encodingOrOffset;if(arguments.length===1){return new Buffer(value)}if(typeof offset==="undefined"){offset=0}var len=length;if(typeof len==="undefined"){len=value.byteLength-offset}if(offset>=value.byteLength){throw new RangeError("'offset' is out of bounds")}if(len>value.byteLength-offset){throw new RangeError("'length' is out of bounds")}return new Buffer(value.slice(offset,offset+len))}if(Buffer.isBuffer(value)){var out=new Buffer(value.length);value.copy(out,0,0,value.length);return out}if(value){if(Array.isArray(value)||typeof ArrayBuffer!=="undefined"&&value.buffer instanceof ArrayBuffer||"length"in value){return new Buffer(value)}if(value.type==="Buffer"&&Array.isArray(value.data)){return new Buffer(value.data)}}throw new TypeError("First argument must be a string, Buffer, "+"ArrayBuffer, Array, or array-like object.")};exports.allocUnsafeSlow=function allocUnsafeSlow(size){if(typeof Buffer.allocUnsafeSlow==="function"){return Buffer.allocUnsafeSlow(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>=MAX_LEN){throw new RangeError("size is too large")}return new SlowBuffer(size)}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{buffer:5}],5:[function(require,module,exports){(function(global){"use strict";var base64=require("base64-js");var ieee754=require("ieee754");var isArray=require("isarray");exports.Buffer=Buffer;exports.SlowBuffer=SlowBuffer;exports.INSPECT_MAX_BYTES=50;Buffer.TYPED_ARRAY_SUPPORT=global.TYPED_ARRAY_SUPPORT!==undefined?global.TYPED_ARRAY_SUPPORT:typedArraySupport();exports.kMaxLength=kMaxLength();function typedArraySupport(){try{var arr=new Uint8Array(1);arr.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}};return arr.foo()===42&&typeof arr.subarray==="function"&&arr.subarray(1,1).byteLength===0}catch(e){return false}}function kMaxLength(){return Buffer.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function createBuffer(that,length){if(kMaxLength()<length){throw new RangeError("Invalid typed array length")}if(Buffer.TYPED_ARRAY_SUPPORT){that=new Uint8Array(length);that.__proto__=Buffer.prototype}else{if(that===null){that=new Buffer(length)}that.length=length}return that}function Buffer(arg,encodingOrOffset,length){if(!Buffer.TYPED_ARRAY_SUPPORT&&!(this instanceof Buffer)){return new Buffer(arg,encodingOrOffset,length)}if(typeof arg==="number"){if(typeof encodingOrOffset==="string"){throw new Error("If encoding is specified then the first argument must be a string")}return allocUnsafe(this,arg)}return from(this,arg,encodingOrOffset,length)}Buffer.poolSize=8192;Buffer._augment=function(arr){arr.__proto__=Buffer.prototype;return arr};function from(that,value,encodingOrOffset,length){if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){return fromArrayBuffer(that,value,encodingOrOffset,length)}if(typeof value==="string"){return fromString(that,value,encodingOrOffset)}return fromObject(that,value)}Buffer.from=function(value,encodingOrOffset,length){return from(null,value,encodingOrOffset,length)};if(Buffer.TYPED_ARRAY_SUPPORT){Buffer.prototype.__proto__=Uint8Array.prototype;Buffer.__proto__=Uint8Array;if(typeof Symbol!=="undefined"&&Symbol.species&&Buffer[Symbol.species]===Buffer){Object.defineProperty(Buffer,Symbol.species,{value:null,configurable:true})}}function assertSize(size){if(typeof size!=="number"){throw new TypeError('"size" argument must be a number')}else if(size<0){throw new RangeError('"size" argument must not be negative')}}function alloc(that,size,fill,encoding){assertSize(size);if(size<=0){return createBuffer(that,size)}if(fill!==undefined){return typeof encoding==="string"?createBuffer(that,size).fill(fill,encoding):createBuffer(that,size).fill(fill)}return createBuffer(that,size)}Buffer.alloc=function(size,fill,encoding){return alloc(null,size,fill,encoding)};function allocUnsafe(that,size){assertSize(size);that=createBuffer(that,size<0?0:checked(size)|0);if(!Buffer.TYPED_ARRAY_SUPPORT){for(var i=0;i<size;++i){that[i]=0}}return that}Buffer.allocUnsafe=function(size){return allocUnsafe(null,size)};Buffer.allocUnsafeSlow=function(size){return allocUnsafe(null,size)};function fromString(that,string,encoding){if(typeof encoding!=="string"||encoding===""){encoding="utf8"}if(!Buffer.isEncoding(encoding)){throw new TypeError('"encoding" must be a valid string encoding')}var length=byteLength(string,encoding)|0;that=createBuffer(that,length);var actual=that.write(string,encoding);if(actual!==length){that=that.slice(0,actual)}return that}function fromArrayLike(that,array){var length=array.length<0?0:checked(array.length)|0;that=createBuffer(that,length);for(var i=0;i<length;i+=1){that[i]=array[i]&255}return that}function fromArrayBuffer(that,array,byteOffset,length){array.byteLength;if(byteOffset<0||array.byteLength<byteOffset){throw new RangeError("'offset' is out of bounds")}if(array.byteLength<byteOffset+(length||0)){throw new RangeError("'length' is out of bounds")}if(byteOffset===undefined&&length===undefined){array=new Uint8Array(array)}else if(length===undefined){array=new Uint8Array(array,byteOffset)}else{array=new Uint8Array(array,byteOffset,length)}if(Buffer.TYPED_ARRAY_SUPPORT){that=array;that.__proto__=Buffer.prototype}else{that=fromArrayLike(that,array)}return that}function fromObject(that,obj){if(Buffer.isBuffer(obj)){var len=checked(obj.length)|0;that=createBuffer(that,len);if(that.length===0){return that}obj.copy(that,0,0,len);return that}if(obj){if(typeof ArrayBuffer!=="undefined"&&obj.buffer instanceof ArrayBuffer||"length"in obj){if(typeof obj.length!=="number"||isnan(obj.length)){return createBuffer(that,0)}return fromArrayLike(that,obj)}if(obj.type==="Buffer"&&isArray(obj.data)){return fromArrayLike(that,obj.data)}}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function checked(length){if(length>=kMaxLength()){throw new RangeError("Attempt to allocate Buffer larger than maximum "+"size: 0x"+kMaxLength().toString(16)+" bytes")}return length|0}function SlowBuffer(length){if(+length!=length){length=0}return Buffer.alloc(+length)}Buffer.isBuffer=function isBuffer(b){return!!(b!=null&&b._isBuffer)};Buffer.compare=function compare(a,b){if(!Buffer.isBuffer(a)||!Buffer.isBuffer(b)){throw new TypeError("Arguments must be Buffers")}if(a===b)return 0;var x=a.length;var y=b.length;for(var i=0,len=Math.min(x,y);i<len;++i){if(a[i]!==b[i]){x=a[i];y=b[i];break}}if(x<y)return-1;if(y<x)return 1;return 0};Buffer.isEncoding=function isEncoding(encoding){switch(String(encoding).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return true;default:return false}};Buffer.concat=function concat(list,length){if(!isArray(list)){throw new TypeError('"list" argument must be an Array of Buffers')}if(list.length===0){return Buffer.alloc(0)}var i;if(length===undefined){length=0;for(i=0;i<list.length;++i){length+=list[i].length}}var buffer=Buffer.allocUnsafe(length);var pos=0;for(i=0;i<list.length;++i){var buf=list[i];if(!Buffer.isBuffer(buf)){throw new TypeError('"list" argument must be an Array of Buffers')}buf.copy(buffer,pos);pos+=buf.length}return buffer};function byteLength(string,encoding){if(Buffer.isBuffer(string)){return string.length}if(typeof ArrayBuffer!=="undefined"&&typeof ArrayBuffer.isView==="function"&&(ArrayBuffer.isView(string)||string instanceof ArrayBuffer)){return string.byteLength}if(typeof string!=="string"){string=""+string}var len=string.length;if(len===0)return 0;var loweredCase=false;for(;;){switch(encoding){case"ascii":case"latin1":case"binary":return len;case"utf8":case"utf-8":case undefined:return utf8ToBytes(string).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return len*2;case"hex":return len>>>1;case"base64":return base64ToBytes(string).length;default:if(loweredCase)return utf8ToBytes(string).length;encoding=(""+encoding).toLowerCase();loweredCase=true}}}Buffer.byteLength=byteLength;function slowToString(encoding,start,end){var loweredCase=false;if(start===undefined||start<0){start=0}if(start>this.length){return""}if(end===undefined||end>this.length){end=this.length}if(end<=0){return""}end>>>=0;start>>>=0;if(end<=start){return""}if(!encoding)encoding="utf8";while(true){switch(encoding){case"hex":return hexSlice(this,start,end);case"utf8":case"utf-8":return utf8Slice(this,start,end);case"ascii":return asciiSlice(this,start,end);case"latin1":case"binary":return latin1Slice(this,start,end);case"base64":return base64Slice(this,start,end);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,start,end);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(encoding+"").toLowerCase();loweredCase=true}}}Buffer.prototype._isBuffer=true;function swap(b,n,m){var i=b[n];b[n]=b[m];b[m]=i}Buffer.prototype.swap16=function swap16(){var len=this.length;if(len%2!==0){throw new RangeError("Buffer size must be a multiple of 16-bits")}for(var i=0;i<len;i+=2){swap(this,i,i+1)}return this};Buffer.prototype.swap32=function swap32(){var len=this.length;if(len%4!==0){throw new RangeError("Buffer size must be a multiple of 32-bits")}for(var i=0;i<len;i+=4){swap(this,i,i+3);swap(this,i+1,i+2)}return this};Buffer.prototype.swap64=function swap64(){var len=this.length;if(len%8!==0){throw new RangeError("Buffer size must be a multiple of 64-bits")}for(var i=0;i<len;i+=8){swap(this,i,i+7);swap(this,i+1,i+6);swap(this,i+2,i+5);swap(this,i+3,i+4)}return this};Buffer.prototype.toString=function toString(){var length=this.length|0;if(length===0)return"";if(arguments.length===0)return utf8Slice(this,0,length);return slowToString.apply(this,arguments)};Buffer.prototype.equals=function equals(b){if(!Buffer.isBuffer(b))throw new TypeError("Argument must be a Buffer");if(this===b)return true;return Buffer.compare(this,b)===0};Buffer.prototype.inspect=function inspect(){var str="";var max=exports.INSPECT_MAX_BYTES;if(this.length>0){str=this.toString("hex",0,max).match(/.{2}/g).join(" ");if(this.length>max)str+=" ... "}return"<Buffer "+str+">"};Buffer.prototype.compare=function compare(target,start,end,thisStart,thisEnd){if(!Buffer.isBuffer(target)){throw new TypeError("Argument must be a Buffer")}if(start===undefined){start=0}if(end===undefined){end=target?target.length:0}if(thisStart===undefined){thisStart=0}if(thisEnd===undefined){thisEnd=this.length}if(start<0||end>target.length||thisStart<0||thisEnd>this.length){throw new RangeError("out of range index")}if(thisStart>=thisEnd&&start>=end){return 0}if(thisStart>=thisEnd){return-1}if(start>=end){return 1}start>>>=0;end>>>=0;thisStart>>>=0;thisEnd>>>=0;if(this===target)return 0;var x=thisEnd-thisStart;var y=end-start;var len=Math.min(x,y);var thisCopy=this.slice(thisStart,thisEnd);var targetCopy=target.slice(start,end);for(var i=0;i<len;++i){if(thisCopy[i]!==targetCopy[i]){x=thisCopy[i];y=targetCopy[i];break}}if(x<y)return-1;if(y<x)return 1;return 0};function bidirectionalIndexOf(buffer,val,byteOffset,encoding,dir){if(buffer.length===0)return-1;if(typeof byteOffset==="string"){encoding=byteOffset;byteOffset=0}else if(byteOffset>2147483647){byteOffset=2147483647}else if(byteOffset<-2147483648){byteOffset=-2147483648}byteOffset=+byteOffset;if(isNaN(byteOffset)){byteOffset=dir?0:buffer.length-1}if(byteOffset<0)byteOffset=buffer.length+byteOffset;if(byteOffset>=buffer.length){if(dir)return-1;else byteOffset=buffer.length-1}else if(byteOffset<0){if(dir)byteOffset=0;else return-1}if(typeof val==="string"){val=Buffer.from(val,encoding)}if(Buffer.isBuffer(val)){if(val.length===0){return-1}return arrayIndexOf(buffer,val,byteOffset,encoding,dir)}else if(typeof val==="number"){val=val&255;if(Buffer.TYPED_ARRAY_SUPPORT&&typeof Uint8Array.prototype.indexOf==="function"){if(dir){return Uint8Array.prototype.indexOf.call(buffer,val,byteOffset)}else{return Uint8Array.prototype.lastIndexOf.call(buffer,val,byteOffset)}}return arrayIndexOf(buffer,[val],byteOffset,encoding,dir)}throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(arr,val,byteOffset,encoding,dir){var indexSize=1;var arrLength=arr.length;var valLength=val.length;if(encoding!==undefined){encoding=String(encoding).toLowerCase();if(encoding==="ucs2"||encoding==="ucs-2"||encoding==="utf16le"||encoding==="utf-16le"){if(arr.length<2||val.length<2){return-1}indexSize=2;arrLength/=2;valLength/=2;byteOffset/=2}}function read(buf,i){if(indexSize===1){return buf[i]}else{return buf.readUInt16BE(i*indexSize)}}var i;if(dir){var foundIndex=-1;for(i=byteOffset;i<arrLength;i++){if(read(arr,i)===read(val,foundIndex===-1?0:i-foundIndex)){if(foundIndex===-1)foundIndex=i;if(i-foundIndex+1===valLength)return foundIndex*indexSize}else{if(foundIndex!==-1)i-=i-foundIndex;foundIndex=-1}}}else{if(byteOffset+valLength>arrLength)byteOffset=arrLength-valLength;for(i=byteOffset;i>=0;i--){var found=true;for(var j=0;j<valLength;j++){if(read(arr,i+j)!==read(val,j)){found=false;break}}if(found)return i}}return-1}Buffer.prototype.includes=function includes(val,byteOffset,encoding){return this.indexOf(val,byteOffset,encoding)!==-1};Buffer.prototype.indexOf=function indexOf(val,byteOffset,encoding){return bidirectionalIndexOf(this,val,byteOffset,encoding,true)};Buffer.prototype.lastIndexOf=function lastIndexOf(val,byteOffset,encoding){return bidirectionalIndexOf(this,val,byteOffset,encoding,false)};function hexWrite(buf,string,offset,length){offset=Number(offset)||0;var remaining=buf.length-offset;if(!length){length=remaining}else{length=Number(length);if(length>remaining){length=remaining}}var strLen=string.length;if(strLen%2!==0)throw new TypeError("Invalid hex string");if(length>strLen/2){length=strLen/2}for(var i=0;i<length;++i){var parsed=parseInt(string.substr(i*2,2),16);if(isNaN(parsed))return i;buf[offset+i]=parsed}return i}function utf8Write(buf,string,offset,length){return blitBuffer(utf8ToBytes(string,buf.length-offset),buf,offset,length)}function asciiWrite(buf,string,offset,length){return blitBuffer(asciiToBytes(string),buf,offset,length)}function latin1Write(buf,string,offset,length){return asciiWrite(buf,string,offset,length)}function base64Write(buf,string,offset,length){return blitBuffer(base64ToBytes(string),buf,offset,length)}function ucs2Write(buf,string,offset,length){return blitBuffer(utf16leToBytes(string,buf.length-offset),buf,offset,length)}Buffer.prototype.write=function write(string,offset,length,encoding){if(offset===undefined){encoding="utf8";length=this.length;offset=0}else if(length===undefined&&typeof offset==="string"){encoding=offset;length=this.length;offset=0}else if(isFinite(offset)){offset=offset|0;if(isFinite(length)){length=length|0;if(encoding===undefined)encoding="utf8"}else{encoding=length;length=undefined}}else{throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported")}var remaining=this.length-offset;if(length===undefined||length>remaining)length=remaining;if(string.length>0&&(length<0||offset<0)||offset>this.length){throw new RangeError("Attempt to write outside buffer bounds")}if(!encoding)encoding="utf8";var loweredCase=false;for(;;){switch(encoding){case"hex":return hexWrite(this,string,offset,length);case"utf8":case"utf-8":return utf8Write(this,string,offset,length);case"ascii":return asciiWrite(this,string,offset,length);case"latin1":case"binary":return latin1Write(this,string,offset,length);case"base64":return base64Write(this,string,offset,length);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,string,offset,length);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(""+encoding).toLowerCase();loweredCase=true}}};Buffer.prototype.toJSON=function toJSON(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function base64Slice(buf,start,end){if(start===0&&end===buf.length){return base64.fromByteArray(buf)}else{return base64.fromByteArray(buf.slice(start,end))}}function utf8Slice(buf,start,end){end=Math.min(buf.length,end);var res=[];var i=start;while(i<end){var firstByte=buf[i];var codePoint=null;var bytesPerSequence=firstByte>239?4:firstByte>223?3:firstByte>191?2:1;if(i+bytesPerSequence<=end){var secondByte,thirdByte,fourthByte,tempCodePoint;switch(bytesPerSequence){case 1:if(firstByte<128){codePoint=firstByte}break;case 2:secondByte=buf[i+1];if((secondByte&192)===128){tempCodePoint=(firstByte&31)<<6|secondByte&63;if(tempCodePoint>127){codePoint=tempCodePoint}}break;case 3:secondByte=buf[i+1];thirdByte=buf[i+2];if((secondByte&192)===128&&(thirdByte&192)===128){tempCodePoint=(firstByte&15)<<12|(secondByte&63)<<6|thirdByte&63;if(tempCodePoint>2047&&(tempCodePoint<55296||tempCodePoint>57343)){codePoint=tempCodePoint}}break;case 4:secondByte=buf[i+1];thirdByte=buf[i+2];fourthByte=buf[i+3];if((secondByte&192)===128&&(thirdByte&192)===128&&(fourthByte&192)===128){tempCodePoint=(firstByte&15)<<18|(secondByte&63)<<12|(thirdByte&63)<<6|fourthByte&63;if(tempCodePoint>65535&&tempCodePoint<1114112){codePoint=tempCodePoint}}}}if(codePoint===null){codePoint=65533;bytesPerSequence=1}else if(codePoint>65535){codePoint-=65536;res.push(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}res.push(codePoint);i+=bytesPerSequence}return decodeCodePointsArray(res)}var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(codePoints){var len=codePoints.length;if(len<=MAX_ARGUMENTS_LENGTH){return String.fromCharCode.apply(String,codePoints)}var res="";var i=0;while(i<len){res+=String.fromCharCode.apply(String,codePoints.slice(i,i+=MAX_ARGUMENTS_LENGTH))}return res}function asciiSlice(buf,start,end){var ret="";end=Math.min(buf.length,end);for(var i=start;i<end;++i){ret+=String.fromCharCode(buf[i]&127)}return ret}function latin1Slice(buf,start,end){var ret="";end=Math.min(buf.length,end);for(var i=start;i<end;++i){ret+=String.fromCharCode(buf[i])}return ret}function hexSlice(buf,start,end){var len=buf.length;if(!start||start<0)start=0;if(!end||end<0||end>len)end=len;var out="";for(var i=start;i<end;++i){out+=toHex(buf[i])}return out}function utf16leSlice(buf,start,end){var bytes=buf.slice(start,end);var res="";for(var i=0;i<bytes.length;i+=2){res+=String.fromCharCode(bytes[i]+bytes[i+1]*256)}return res}Buffer.prototype.slice=function slice(start,end){var len=this.length;start=~~start;end=end===undefined?len:~~end;if(start<0){start+=len;if(start<0)start=0}else if(start>len){start=len}if(end<0){end+=len;if(end<0)end=0}else if(end>len){end=len}if(end<start)end=start;var newBuf;if(Buffer.TYPED_ARRAY_SUPPORT){newBuf=this.subarray(start,end);newBuf.__proto__=Buffer.prototype}else{var sliceLen=end-start;newBuf=new Buffer(sliceLen,undefined);for(var i=0;i<sliceLen;++i){newBuf[i]=this[i+start]}}return newBuf};function checkOffset(offset,ext,length){if(offset%1!==0||offset<0)throw new RangeError("offset is not uint");if(offset+ext>length)throw new RangeError("Trying to access beyond buffer length")}Buffer.prototype.readUIntLE=function readUIntLE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i<byteLength&&(mul*=256)){val+=this[offset+i]*mul}return val};Buffer.prototype.readUIntBE=function readUIntBE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert){checkOffset(offset,byteLength,this.length)}var val=this[offset+--byteLength];var mul=1;while(byteLength>0&&(mul*=256)){val+=this[offset+--byteLength]*mul}return val};Buffer.prototype.readUInt8=function readUInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);return this[offset]};Buffer.prototype.readUInt16LE=function readUInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]|this[offset+1]<<8};Buffer.prototype.readUInt16BE=function readUInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]<<8|this[offset+1]};Buffer.prototype.readUInt32LE=function readUInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return(this[offset]|this[offset+1]<<8|this[offset+2]<<16)+this[offset+3]*16777216};Buffer.prototype.readUInt32BE=function readUInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]*16777216+(this[offset+1]<<16|this[offset+2]<<8|this[offset+3])};Buffer.prototype.readIntLE=function readIntLE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i<byteLength&&(mul*=256)){val+=this[offset+i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readIntBE=function readIntBE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length); |
| var i=byteLength;var mul=1;var val=this[offset+--i];while(i>0&&(mul*=256)){val+=this[offset+--i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readInt8=function readInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);if(!(this[offset]&128))return this[offset];return(255-this[offset]+1)*-1};Buffer.prototype.readInt16LE=function readInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset]|this[offset+1]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt16BE=function readInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset+1]|this[offset]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt32LE=function readInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]|this[offset+1]<<8|this[offset+2]<<16|this[offset+3]<<24};Buffer.prototype.readInt32BE=function readInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]<<24|this[offset+1]<<16|this[offset+2]<<8|this[offset+3]};Buffer.prototype.readFloatLE=function readFloatLE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,true,23,4)};Buffer.prototype.readFloatBE=function readFloatBE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,false,23,4)};Buffer.prototype.readDoubleLE=function readDoubleLE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,true,52,8)};Buffer.prototype.readDoubleBE=function readDoubleBE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,false,52,8)};function checkInt(buf,value,offset,ext,max,min){if(!Buffer.isBuffer(buf))throw new TypeError('"buffer" argument must be a Buffer instance');if(value>max||value<min)throw new RangeError('"value" argument is out of bounds');if(offset+ext>buf.length)throw new RangeError("Index out of range")}Buffer.prototype.writeUIntLE=function writeUIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;byteLength=byteLength|0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength)-1;checkInt(this,value,offset,byteLength,maxBytes,0)}var mul=1;var i=0;this[offset]=value&255;while(++i<byteLength&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength};Buffer.prototype.writeUIntBE=function writeUIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;byteLength=byteLength|0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength)-1;checkInt(this,value,offset,byteLength,maxBytes,0)}var i=byteLength-1;var mul=1;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength};Buffer.prototype.writeUInt8=function writeUInt8(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,1,255,0);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);this[offset]=value&255;return offset+1};function objectWriteUInt16(buf,value,offset,littleEndian){if(value<0)value=65535+value+1;for(var i=0,j=Math.min(buf.length-offset,2);i<j;++i){buf[offset+i]=(value&255<<8*(littleEndian?i:1-i))>>>(littleEndian?i:1-i)*8}}Buffer.prototype.writeUInt16LE=function writeUInt16LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeUInt16BE=function writeUInt16BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value&255}else{objectWriteUInt16(this,value,offset,false)}return offset+2};function objectWriteUInt32(buf,value,offset,littleEndian){if(value<0)value=4294967295+value+1;for(var i=0,j=Math.min(buf.length-offset,4);i<j;++i){buf[offset+i]=value>>>(littleEndian?i:3-i)*8&255}}Buffer.prototype.writeUInt32LE=function writeUInt32LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset+3]=value>>>24;this[offset+2]=value>>>16;this[offset+1]=value>>>8;this[offset]=value&255}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeUInt32BE=function writeUInt32BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255}else{objectWriteUInt32(this,value,offset,false)}return offset+4};Buffer.prototype.writeIntLE=function writeIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;if(!noAssert){var limit=Math.pow(2,8*byteLength-1);checkInt(this,value,offset,byteLength,limit-1,-limit)}var i=0;var mul=1;var sub=0;this[offset]=value&255;while(++i<byteLength&&(mul*=256)){if(value<0&&sub===0&&this[offset+i-1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeIntBE=function writeIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;if(!noAssert){var limit=Math.pow(2,8*byteLength-1);checkInt(this,value,offset,byteLength,limit-1,-limit)}var i=byteLength-1;var mul=1;var sub=0;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){if(value<0&&sub===0&&this[offset+i+1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeInt8=function writeInt8(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,1,127,-128);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);if(value<0)value=255+value+1;this[offset]=value&255;return offset+1};Buffer.prototype.writeInt16LE=function writeInt16LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeInt16BE=function writeInt16BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value&255}else{objectWriteUInt16(this,value,offset,false)}return offset+2};Buffer.prototype.writeInt32LE=function writeInt32LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8;this[offset+2]=value>>>16;this[offset+3]=value>>>24}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeInt32BE=function writeInt32BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(value<0)value=4294967295+value+1;if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255}else{objectWriteUInt32(this,value,offset,false)}return offset+4};function checkIEEE754(buf,value,offset,ext,max,min){if(offset+ext>buf.length)throw new RangeError("Index out of range");if(offset<0)throw new RangeError("Index out of range")}function writeFloat(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,4,3.4028234663852886e38,-3.4028234663852886e38)}ieee754.write(buf,value,offset,littleEndian,23,4);return offset+4}Buffer.prototype.writeFloatLE=function writeFloatLE(value,offset,noAssert){return writeFloat(this,value,offset,true,noAssert)};Buffer.prototype.writeFloatBE=function writeFloatBE(value,offset,noAssert){return writeFloat(this,value,offset,false,noAssert)};function writeDouble(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,8,1.7976931348623157e308,-1.7976931348623157e308)}ieee754.write(buf,value,offset,littleEndian,52,8);return offset+8}Buffer.prototype.writeDoubleLE=function writeDoubleLE(value,offset,noAssert){return writeDouble(this,value,offset,true,noAssert)};Buffer.prototype.writeDoubleBE=function writeDoubleBE(value,offset,noAssert){return writeDouble(this,value,offset,false,noAssert)};Buffer.prototype.copy=function copy(target,targetStart,start,end){if(!start)start=0;if(!end&&end!==0)end=this.length;if(targetStart>=target.length)targetStart=target.length;if(!targetStart)targetStart=0;if(end>0&&end<start)end=start;if(end===start)return 0;if(target.length===0||this.length===0)return 0;if(targetStart<0){throw new RangeError("targetStart out of bounds")}if(start<0||start>=this.length)throw new RangeError("sourceStart out of bounds");if(end<0)throw new RangeError("sourceEnd out of bounds");if(end>this.length)end=this.length;if(target.length-targetStart<end-start){end=target.length-targetStart+start}var len=end-start;var i;if(this===target&&start<targetStart&&targetStart<end){for(i=len-1;i>=0;--i){target[i+targetStart]=this[i+start]}}else if(len<1e3||!Buffer.TYPED_ARRAY_SUPPORT){for(i=0;i<len;++i){target[i+targetStart]=this[i+start]}}else{Uint8Array.prototype.set.call(target,this.subarray(start,start+len),targetStart)}return len};Buffer.prototype.fill=function fill(val,start,end,encoding){if(typeof val==="string"){if(typeof start==="string"){encoding=start;start=0;end=this.length}else if(typeof end==="string"){encoding=end;end=this.length}if(val.length===1){var code=val.charCodeAt(0);if(code<256){val=code}}if(encoding!==undefined&&typeof encoding!=="string"){throw new TypeError("encoding must be a string")}if(typeof encoding==="string"&&!Buffer.isEncoding(encoding)){throw new TypeError("Unknown encoding: "+encoding)}}else if(typeof val==="number"){val=val&255}if(start<0||this.length<start||this.length<end){throw new RangeError("Out of range index")}if(end<=start){return this}start=start>>>0;end=end===undefined?this.length:end>>>0;if(!val)val=0;var i;if(typeof val==="number"){for(i=start;i<end;++i){this[i]=val}}else{var bytes=Buffer.isBuffer(val)?val:utf8ToBytes(new Buffer(val,encoding).toString());var len=bytes.length;for(i=0;i<end-start;++i){this[i+start]=bytes[i%len]}}return this};var INVALID_BASE64_RE=/[^+\/0-9A-Za-z-_]/g;function base64clean(str){str=stringtrim(str).replace(INVALID_BASE64_RE,"");if(str.length<2)return"";while(str.length%4!==0){str=str+"="}return str}function stringtrim(str){if(str.trim)return str.trim();return str.replace(/^\s+|\s+$/g,"")}function toHex(n){if(n<16)return"0"+n.toString(16);return n.toString(16)}function utf8ToBytes(string,units){units=units||Infinity;var codePoint;var length=string.length;var leadSurrogate=null;var bytes=[];for(var i=0;i<length;++i){codePoint=string.charCodeAt(i);if(codePoint>55295&&codePoint<57344){if(!leadSurrogate){if(codePoint>56319){if((units-=3)>-1)bytes.push(239,191,189);continue}else if(i+1===length){if((units-=3)>-1)bytes.push(239,191,189);continue}leadSurrogate=codePoint;continue}if(codePoint<56320){if((units-=3)>-1)bytes.push(239,191,189);leadSurrogate=codePoint;continue}codePoint=(leadSurrogate-55296<<10|codePoint-56320)+65536}else if(leadSurrogate){if((units-=3)>-1)bytes.push(239,191,189)}leadSurrogate=null;if(codePoint<128){if((units-=1)<0)break;bytes.push(codePoint)}else if(codePoint<2048){if((units-=2)<0)break;bytes.push(codePoint>>6|192,codePoint&63|128)}else if(codePoint<65536){if((units-=3)<0)break;bytes.push(codePoint>>12|224,codePoint>>6&63|128,codePoint&63|128)}else if(codePoint<1114112){if((units-=4)<0)break;bytes.push(codePoint>>18|240,codePoint>>12&63|128,codePoint>>6&63|128,codePoint&63|128)}else{throw new Error("Invalid code point")}}return bytes}function asciiToBytes(str){var byteArray=[];for(var i=0;i<str.length;++i){byteArray.push(str.charCodeAt(i)&255)}return byteArray}function utf16leToBytes(str,units){var c,hi,lo;var byteArray=[];for(var i=0;i<str.length;++i){if((units-=2)<0)break;c=str.charCodeAt(i);hi=c>>8;lo=c%256;byteArray.push(lo);byteArray.push(hi)}return byteArray}function base64ToBytes(str){return base64.toByteArray(base64clean(str))}function blitBuffer(src,dst,offset,length){for(var i=0;i<length;++i){if(i+offset>=dst.length||i>=src.length)break;dst[i+offset]=src[i]}return i}function isnan(val){return val!==val}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"base64-js":2,ieee754:37,isarray:40}],6:[function(require,module,exports){(function(Buffer){function isArray(arg){if(Array.isArray){return Array.isArray(arg)}return objectToString(arg)==="[object Array]"}exports.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports.isBoolean=isBoolean;function isNull(arg){return arg===null}exports.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports.isUndefined=isUndefined;function isRegExp(re){return objectToString(re)==="[object RegExp]"}exports.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports.isObject=isObject;function isDate(d){return objectToString(d)==="[object Date]"}exports.isDate=isDate;function isError(e){return objectToString(e)==="[object Error]"||e instanceof Error}exports.isError=isError;function isFunction(arg){return typeof arg==="function"}exports.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports.isPrimitive=isPrimitive;exports.isBuffer=Buffer.isBuffer;function objectToString(o){return Object.prototype.toString.call(o)}}).call(this,{isBuffer:require("../../is-buffer/index.js")})},{"../../is-buffer/index.js":39}],7:[function(require,module,exports){var ElementType=require("domelementtype");var entities=require("entities");var booleanAttributes={__proto__:null,allowfullscreen:true,async:true,autofocus:true,autoplay:true,checked:true,controls:true,default:true,defer:true,disabled:true,hidden:true,ismap:true,loop:true,multiple:true,muted:true,open:true,readonly:true,required:true,reversed:true,scoped:true,seamless:true,selected:true,typemustmatch:true};var unencodedElements={__proto__:null,style:true,script:true,xmp:true,iframe:true,noembed:true,noframes:true,plaintext:true,noscript:true};function formatAttrs(attributes,opts){if(!attributes)return;var output="",value;for(var key in attributes){value=attributes[key];if(output){output+=" "}if(!value&&booleanAttributes[key]){output+=key}else{output+=key+'="'+(opts.decodeEntities?entities.encodeXML(value):value)+'"'}}return output}var singleTag={__proto__:null,area:true,base:true,basefont:true,br:true,col:true,command:true,embed:true,frame:true,hr:true,img:true,input:true,isindex:true,keygen:true,link:true,meta:true,param:true,source:true,track:true,wbr:true};var render=module.exports=function(dom,opts){if(!Array.isArray(dom)&&!dom.cheerio)dom=[dom];opts=opts||{};var output="";for(var i=0;i<dom.length;i++){var elem=dom[i];if(elem.type==="root")output+=render(elem.children,opts);else if(ElementType.isTag(elem))output+=renderTag(elem,opts);else if(elem.type===ElementType.Directive)output+=renderDirective(elem);else if(elem.type===ElementType.Comment)output+=renderComment(elem);else if(elem.type===ElementType.CDATA)output+=renderCdata(elem);else output+=renderText(elem,opts)}return output};function renderTag(elem,opts){if(elem.name==="svg")opts={decodeEntities:opts.decodeEntities,xmlMode:true};var tag="<"+elem.name,attribs=formatAttrs(elem.attribs,opts);if(attribs){tag+=" "+attribs}if(opts.xmlMode&&(!elem.children||elem.children.length===0)){tag+="/>"}else{tag+=">";if(elem.children){tag+=render(elem.children,opts)}if(!singleTag[elem.name]||opts.xmlMode){tag+="</"+elem.name+">"}}return tag}function renderDirective(elem){return"<"+elem.data+">"}function renderText(elem,opts){var data=elem.data||"";if(opts.decodeEntities&&!(elem.parent&&elem.parent.name in unencodedElements)){data=entities.encodeXML(data)}return data}function renderCdata(elem){return"<![CDATA["+elem.children[0].data+"]]>"}function renderComment(elem){return"<!--"+elem.data+"-->"}},{domelementtype:8,entities:20}],8:[function(require,module,exports){module.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(elem){return elem.type==="tag"||elem.type==="script"||elem.type==="style"}}},{}],9:[function(require,module,exports){module.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",Doctype:"doctype",isTag:function(elem){return elem.type==="tag"||elem.type==="script"||elem.type==="style"}}},{}],10:[function(require,module,exports){var ElementType=require("domelementtype");var re_whitespace=/\s+/g;var NodePrototype=require("./lib/node");var ElementPrototype=require("./lib/element");function DomHandler(callback,options,elementCB){if(typeof callback==="object"){elementCB=options;options=callback;callback=null}else if(typeof options==="function"){elementCB=options;options=defaultOpts}this._callback=callback;this._options=options||defaultOpts;this._elementCB=elementCB;this.dom=[];this._done=false;this._tagStack=[];this._parser=this._parser||null}var defaultOpts={normalizeWhitespace:false,withStartIndices:false};DomHandler.prototype.onparserinit=function(parser){this._parser=parser};DomHandler.prototype.onreset=function(){DomHandler.call(this,this._callback,this._options,this._elementCB)};DomHandler.prototype.onend=function(){if(this._done)return;this._done=true;this._parser=null;this._handleCallback(null)};DomHandler.prototype._handleCallback=DomHandler.prototype.onerror=function(error){if(typeof this._callback==="function"){this._callback(error,this.dom)}else{if(error)throw error}};DomHandler.prototype.onclosetag=function(){var elem=this._tagStack.pop();if(this._elementCB)this._elementCB(elem)};DomHandler.prototype._addDomElement=function(element){var parent=this._tagStack[this._tagStack.length-1];var siblings=parent?parent.children:this.dom;var previousSibling=siblings[siblings.length-1];element.next=null;if(this._options.withStartIndices){element.startIndex=this._parser.startIndex}if(this._options.withDomLvl1){element.__proto__=element.type==="tag"?ElementPrototype:NodePrototype}if(previousSibling){element.prev=previousSibling;previousSibling.next=element}else{element.prev=null}siblings.push(element);element.parent=parent||null};DomHandler.prototype.onopentag=function(name,attribs){var element={type:name==="script"?ElementType.Script:name==="style"?ElementType.Style:ElementType.Tag,name:name,attribs:attribs,children:[]};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.ontext=function(data){var normalize=this._options.normalizeWhitespace||this._options.ignoreWhitespace;var lastTag;if(!this._tagStack.length&&this.dom.length&&(lastTag=this.dom[this.dom.length-1]).type===ElementType.Text){if(normalize){lastTag.data=(lastTag.data+data).replace(re_whitespace," ")}else{lastTag.data+=data}}else{if(this._tagStack.length&&(lastTag=this._tagStack[this._tagStack.length-1])&&(lastTag=lastTag.children[lastTag.children.length-1])&&lastTag.type===ElementType.Text){if(normalize){lastTag.data=(lastTag.data+data).replace(re_whitespace," ")}else{lastTag.data+=data}}else{if(normalize){data=data.replace(re_whitespace," ")}this._addDomElement({data:data,type:ElementType.Text})}}};DomHandler.prototype.oncomment=function(data){var lastTag=this._tagStack[this._tagStack.length-1];if(lastTag&&lastTag.type===ElementType.Comment){lastTag.data+=data;return}var element={data:data,type:ElementType.Comment};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.oncdatastart=function(){var element={children:[{data:"",type:ElementType.Text}],type:ElementType.CDATA};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.oncommentend=DomHandler.prototype.oncdataend=function(){this._tagStack.pop()};DomHandler.prototype.onprocessinginstruction=function(name,data){this._addDomElement({name:name,data:data,type:ElementType.Directive})};module.exports=DomHandler},{"./lib/element":11,"./lib/node":12,domelementtype:9}],11:[function(require,module,exports){var NodePrototype=require("./node");var ElementPrototype=module.exports=Object.create(NodePrototype);var domLvl1={tagName:"name"};Object.keys(domLvl1).forEach(function(key){var shorthand=domLvl1[key];Object.defineProperty(ElementPrototype,key,{get:function(){return this[shorthand]||null},set:function(val){this[shorthand]=val;return val}})})},{"./node":12}],12:[function(require,module,exports){var NodePrototype=module.exports={get firstChild(){var children=this.children;return children&&children[0]||null},get lastChild(){var children=this.children;return children&&children[children.length-1]||null},get nodeType(){return nodeTypes[this.type]||nodeTypes.element}};var domLvl1={tagName:"name",childNodes:"children",parentNode:"parent",previousSibling:"prev",nextSibling:"next",nodeValue:"data"};var nodeTypes={element:1,text:3,cdata:4,comment:8};Object.keys(domLvl1).forEach(function(key){var shorthand=domLvl1[key];Object.defineProperty(NodePrototype,key,{get:function(){return this[shorthand]||null},set:function(val){this[shorthand]=val;return val}})})},{}],13:[function(require,module,exports){var DomUtils=module.exports;[require("./lib/stringify"),require("./lib/traversal"),require("./lib/manipulation"),require("./lib/querying"),require("./lib/legacy"),require("./lib/helpers")].forEach(function(ext){Object.keys(ext).forEach(function(key){DomUtils[key]=ext[key].bind(DomUtils)})})},{"./lib/helpers":14,"./lib/legacy":15,"./lib/manipulation":16,"./lib/querying":17,"./lib/stringify":18,"./lib/traversal":19}],14:[function(require,module,exports){exports.removeSubsets=function(nodes){var idx=nodes.length,node,ancestor,replace;while(--idx>-1){node=ancestor=nodes[idx];nodes[idx]=null;replace=true;while(ancestor){if(nodes.indexOf(ancestor)>-1){replace=false;nodes.splice(idx,1);break}ancestor=ancestor.parent}if(replace){nodes[idx]=node}}return nodes};var POSITION={DISCONNECTED:1,PRECEDING:2,FOLLOWING:4,CONTAINS:8,CONTAINED_BY:16};var comparePos=exports.compareDocumentPosition=function(nodeA,nodeB){var aParents=[];var bParents=[];var current,sharedParent,siblings,aSibling,bSibling,idx;if(nodeA===nodeB){return 0}current=nodeA;while(current){aParents.unshift(current);current=current.parent}current=nodeB;while(current){bParents.unshift(current);current=current.parent}idx=0;while(aParents[idx]===bParents[idx]){idx++}if(idx===0){return POSITION.DISCONNECTED}sharedParent=aParents[idx-1];siblings=sharedParent.children;aSibling=aParents[idx];bSibling=bParents[idx];if(siblings.indexOf(aSibling)>siblings.indexOf(bSibling)){if(sharedParent===nodeB){return POSITION.FOLLOWING|POSITION.CONTAINED_BY}return POSITION.FOLLOWING}else{if(sharedParent===nodeA){return POSITION.PRECEDING|POSITION.CONTAINS}return POSITION.PRECEDING}};exports.uniqueSort=function(nodes){var idx=nodes.length,node,position;nodes=nodes.slice();while(--idx>-1){node=nodes[idx];position=nodes.indexOf(node);if(position>-1&&position<idx){nodes.splice(idx,1)}}nodes.sort(function(a,b){var relative=comparePos(a,b);if(relative&POSITION.PRECEDING){return-1}else if(relative&POSITION.FOLLOWING){return 1}return 0});return nodes}},{}],15:[function(require,module,exports){var ElementType=require("domelementtype");var isTag=exports.isTag=ElementType.isTag;exports.testElement=function(options,element){for(var key in options){if(!options.hasOwnProperty(key));else if(key==="tag_name"){if(!isTag(element)||!options.tag_name(element.name)){return false}}else if(key==="tag_type"){if(!options.tag_type(element.type))return false}else if(key==="tag_contains"){if(isTag(element)||!options.tag_contains(element.data)){return false}}else if(!element.attribs||!options[key](element.attribs[key])){return false}}return true};var Checks={tag_name:function(name){if(typeof name==="function"){return function(elem){return isTag(elem)&&name(elem.name)}}else if(name==="*"){return isTag}else{return function(elem){return isTag(elem)&&elem.name===name}}},tag_type:function(type){if(typeof type==="function"){return function(elem){return type(elem.type)}}else{return function(elem){return elem.type===type}}},tag_contains:function(data){if(typeof data==="function"){return function(elem){return!isTag(elem)&&data(elem.data)}}else{return function(elem){return!isTag(elem)&&elem.data===data}}}};function getAttribCheck(attrib,value){if(typeof value==="function"){return function(elem){return elem.attribs&&value(elem.attribs[attrib])}}else{return function(elem){return elem.attribs&&elem.attribs[attrib]===value}}}function combineFuncs(a,b){return function(elem){return a(elem)||b(elem)}}exports.getElements=function(options,element,recurse,limit){var funcs=Object.keys(options).map(function(key){var value=options[key];return key in Checks?Checks[key](value):getAttribCheck(key,value)});return funcs.length===0?[]:this.filter(funcs.reduce(combineFuncs),element,recurse,limit)};exports.getElementById=function(id,element,recurse){if(!Array.isArray(element))element=[element];return this.findOne(getAttribCheck("id",id),element,recurse!==false)};exports.getElementsByTagName=function(name,element,recurse,limit){return this.filter(Checks.tag_name(name),element,recurse,limit)};exports.getElementsByTagType=function(type,element,recurse,limit){return this.filter(Checks.tag_type(type),element,recurse,limit)}},{domelementtype:9}],16:[function(require,module,exports){exports.removeElement=function(elem){if(elem.prev)elem.prev.next=elem.next;if(elem.next)elem.next.prev=elem.prev;if(elem.parent){var childs=elem.parent.children;childs.splice(childs.lastIndexOf(elem),1)}};exports.replaceElement=function(elem,replacement){var prev=replacement.prev=elem.prev;if(prev){prev.next=replacement}var next=replacement.next=elem.next;if(next){next.prev=replacement}var parent=replacement.parent=elem.parent;if(parent){var childs=parent.children;childs[childs.lastIndexOf(elem)]=replacement}};exports.appendChild=function(elem,child){child.parent=elem;if(elem.children.push(child)!==1){var sibling=elem.children[elem.children.length-2];sibling.next=child;child.prev=sibling;child.next=null}};exports.append=function(elem,next){var parent=elem.parent,currNext=elem.next;next.next=currNext;next.prev=elem;elem.next=next;next.parent=parent;if(currNext){currNext.prev=next;if(parent){var childs=parent.children;childs.splice(childs.lastIndexOf(currNext),0,next)}}else if(parent){parent.children.push(next)}};exports.prepend=function(elem,prev){var parent=elem.parent;if(parent){var childs=parent.children;childs.splice(childs.lastIndexOf(elem),0,prev)}if(elem.prev){elem.prev.next=prev}prev.parent=parent;prev.prev=elem.prev;prev.next=elem;elem.prev=prev}},{}],17:[function(require,module,exports){var isTag=require("domelementtype").isTag;module.exports={filter:filter,find:find,findOneChild:findOneChild,findOne:findOne,existsOne:existsOne,findAll:findAll};function filter(test,element,recurse,limit){if(!Array.isArray(element))element=[element];if(typeof limit!=="number"||!isFinite(limit)){limit=Infinity}return find(test,element,recurse!==false,limit)}function find(test,elems,recurse,limit){var result=[],childs;for(var i=0,j=elems.length;i<j;i++){if(test(elems[i])){result.push(elems[i]);if(--limit<=0)break}childs=elems[i].children;if(recurse&&childs&&childs.length>0){childs=find(test,childs,recurse,limit);result=result.concat(childs);limit-=childs.length;if(limit<=0)break}}return result}function findOneChild(test,elems){for(var i=0,l=elems.length;i<l;i++){if(test(elems[i]))return elems[i]}return null}function findOne(test,elems){var elem=null;for(var i=0,l=elems.length;i<l&&!elem;i++){if(!isTag(elems[i])){continue}else if(test(elems[i])){elem=elems[i]}else if(elems[i].children.length>0){elem=findOne(test,elems[i].children)}}return elem}function existsOne(test,elems){for(var i=0,l=elems.length;i<l;i++){if(isTag(elems[i])&&(test(elems[i])||elems[i].children.length>0&&existsOne(test,elems[i].children))){return true}}return false}function findAll(test,elems){var result=[];for(var i=0,j=elems.length;i<j;i++){if(!isTag(elems[i]))continue;if(test(elems[i]))result.push(elems[i]);if(elems[i].children.length>0){result=result.concat(findAll(test,elems[i].children))}}return result}},{domelementtype:9}],18:[function(require,module,exports){var ElementType=require("domelementtype"),getOuterHTML=require("dom-serializer"),isTag=ElementType.isTag;module.exports={getInnerHTML:getInnerHTML,getOuterHTML:getOuterHTML,getText:getText};function getInnerHTML(elem,opts){return elem.children?elem.children.map(function(elem){return getOuterHTML(elem,opts)}).join(""):""}function getText(elem){if(Array.isArray(elem))return elem.map(getText).join("");if(isTag(elem)||elem.type===ElementType.CDATA)return getText(elem.children);if(elem.type===ElementType.Text)return elem.data;return""}},{"dom-serializer":7,domelementtype:9}],19:[function(require,module,exports){var getChildren=exports.getChildren=function(elem){return elem.children};var getParent=exports.getParent=function(elem){return elem.parent};exports.getSiblings=function(elem){var parent=getParent(elem);return parent?getChildren(parent):[elem]};exports.getAttributeValue=function(elem,name){return elem.attribs&&elem.attribs[name]};exports.hasAttrib=function(elem,name){return!!elem.attribs&&hasOwnProperty.call(elem.attribs,name)};exports.getName=function(elem){return elem.name}},{}],20:[function(require,module,exports){var encode=require("./lib/encode.js"),decode=require("./lib/decode.js");exports.decode=function(data,level){return(!level||level<=0?decode.XML:decode.HTML)(data)};exports.decodeStrict=function(data,level){return(!level||level<=0?decode.XML:decode.HTMLStrict)(data)};exports.encode=function(data,level){return(!level||level<=0?encode.XML:encode.HTML)(data)};exports.encodeXML=encode.XML;exports.encodeHTML4=exports.encodeHTML5=exports.encodeHTML=encode.HTML;exports.decodeXML=exports.decodeXMLStrict=decode.XML;exports.decodeHTML4=exports.decodeHTML5=exports.decodeHTML=decode.HTML;exports.decodeHTML4Strict=exports.decodeHTML5Strict=exports.decodeHTMLStrict=decode.HTMLStrict;exports.escape=encode.escape},{"./lib/decode.js":21,"./lib/encode.js":23}],21:[function(require,module,exports){var entityMap=require("../maps/entities.json"),legacyMap=require("../maps/legacy.json"),xmlMap=require("../maps/xml.json"),decodeCodePoint=require("./decode_codepoint.js");var decodeXMLStrict=getStrictDecoder(xmlMap),decodeHTMLStrict=getStrictDecoder(entityMap);function getStrictDecoder(map){var keys=Object.keys(map).join("|"),replace=getReplacer(map);keys+="|#[xX][\\da-fA-F]+|#\\d+";var re=new RegExp("&(?:"+keys+");","g");return function(str){return String(str).replace(re,replace)}}var decodeHTML=function(){var legacy=Object.keys(legacyMap).sort(sorter);var keys=Object.keys(entityMap).sort(sorter);for(var i=0,j=0;i<keys.length;i++){if(legacy[j]===keys[i]){keys[i]+=";?";j++}else{keys[i]+=";"}}var re=new RegExp("&(?:"+keys.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),replace=getReplacer(entityMap);function replacer(str){if(str.substr(-1)!==";")str+=";";return replace(str)}return function(str){return String(str).replace(re,replacer)}}();function sorter(a,b){return a<b?1:-1}function getReplacer(map){return function replace(str){if(str.charAt(1)==="#"){if(str.charAt(2)==="X"||str.charAt(2)==="x"){return decodeCodePoint(parseInt(str.substr(3),16))}return decodeCodePoint(parseInt(str.substr(2),10))}return map[str.slice(1,-1)]; |
| }}module.exports={XML:decodeXMLStrict,HTML:decodeHTML,HTMLStrict:decodeHTMLStrict}},{"../maps/entities.json":25,"../maps/legacy.json":26,"../maps/xml.json":27,"./decode_codepoint.js":22}],22:[function(require,module,exports){var decodeMap=require("../maps/decode.json");module.exports=decodeCodePoint;function decodeCodePoint(codePoint){if(codePoint>=55296&&codePoint<=57343||codePoint>1114111){return"�"}if(codePoint in decodeMap){codePoint=decodeMap[codePoint]}var output="";if(codePoint>65535){codePoint-=65536;output+=String.fromCharCode(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}output+=String.fromCharCode(codePoint);return output}},{"../maps/decode.json":24}],23:[function(require,module,exports){var inverseXML=getInverseObj(require("../maps/xml.json")),xmlReplacer=getInverseReplacer(inverseXML);exports.XML=getInverse(inverseXML,xmlReplacer);var inverseHTML=getInverseObj(require("../maps/entities.json")),htmlReplacer=getInverseReplacer(inverseHTML);exports.HTML=getInverse(inverseHTML,htmlReplacer);function getInverseObj(obj){return Object.keys(obj).sort().reduce(function(inverse,name){inverse[obj[name]]="&"+name+";";return inverse},{})}function getInverseReplacer(inverse){var single=[],multiple=[];Object.keys(inverse).forEach(function(k){if(k.length===1){single.push("\\"+k)}else{multiple.push(k)}});multiple.unshift("["+single.join("")+"]");return new RegExp(multiple.join("|"),"g")}var re_nonASCII=/[^\0-\x7F]/g,re_astralSymbols=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;function singleCharReplacer(c){return"&#x"+c.charCodeAt(0).toString(16).toUpperCase()+";"}function astralReplacer(c){var high=c.charCodeAt(0);var low=c.charCodeAt(1);var codePoint=(high-55296)*1024+low-56320+65536;return"&#x"+codePoint.toString(16).toUpperCase()+";"}function getInverse(inverse,re){function func(name){return inverse[name]}return function(data){return data.replace(re,func).replace(re_astralSymbols,astralReplacer).replace(re_nonASCII,singleCharReplacer)}}var re_xmlChars=getInverseReplacer(inverseXML);function escapeXML(data){return data.replace(re_xmlChars,singleCharReplacer).replace(re_astralSymbols,astralReplacer).replace(re_nonASCII,singleCharReplacer)}exports.escape=escapeXML},{"../maps/entities.json":25,"../maps/xml.json":27}],24:[function(require,module,exports){module.exports={0:65533,128:8364,130:8218,131:402,132:8222,133:8230,134:8224,135:8225,136:710,137:8240,138:352,139:8249,140:338,142:381,145:8216,146:8217,147:8220,148:8221,149:8226,150:8211,151:8212,152:732,153:8482,154:353,155:8250,156:339,158:382,159:376}},{}],25:[function(require,module,exports){module.exports={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅",in:"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺",int:"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"",InvisibleTimes:"",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"",NegativeThickSpace:"",NegativeThinSpace:"",NegativeVeryThinSpace:"",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:" ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"",zwnj:""}},{}],26:[function(require,module,exports){module.exports={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"}},{}],27:[function(require,module,exports){module.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],28:[function(require,module,exports){function EventEmitter(){this._events=this._events||{};this._maxListeners=this._maxListeners||undefined}module.exports=EventEmitter;EventEmitter.EventEmitter=EventEmitter;EventEmitter.prototype._events=undefined;EventEmitter.prototype._maxListeners=undefined;EventEmitter.defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!isNumber(n)||n<0||isNaN(n))throw TypeError("n must be a positive number");this._maxListeners=n;return this};EventEmitter.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(!this._events)this._events={};if(type==="error"){if(!this._events.error||isObject(this._events.error)&&!this._events.error.length){er=arguments[1];if(er instanceof Error){throw er}else{var err=new Error('Uncaught, unspecified "error" event. ('+er+")");err.context=er;throw err}}}handler=this._events[type];if(isUndefined(handler))return false;if(isFunction(handler)){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}}else if(isObject(handler)){args=Array.prototype.slice.call(arguments,1);listeners=handler.slice();len=listeners.length;for(i=0;i<len;i++)listeners[i].apply(this,args)}return true};EventEmitter.prototype.addListener=function(type,listener){var m;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events)this._events={};if(this._events.newListener)this.emit("newListener",type,isFunction(listener.listener)?listener.listener:listener);if(!this._events[type])this._events[type]=listener;else if(isObject(this._events[type]))this._events[type].push(listener);else this._events[type]=[this._events[type],listener];if(isObject(this._events[type])&&!this._events[type].warned){if(!isUndefined(this._maxListeners)){m=this._maxListeners}else{m=EventEmitter.defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1); |
| }if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},{}],29:[function(require,module,exports){module.exports=CollectingHandler;function CollectingHandler(cbs){this._cbs=cbs||{};this.events=[]}var EVENTS=require("./").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){name="on"+name;CollectingHandler.prototype[name]=function(){this.events.push([name]);if(this._cbs[name])this._cbs[name]()}}else if(EVENTS[name]===1){name="on"+name;CollectingHandler.prototype[name]=function(a){this.events.push([name,a]);if(this._cbs[name])this._cbs[name](a)}}else if(EVENTS[name]===2){name="on"+name;CollectingHandler.prototype[name]=function(a,b){this.events.push([name,a,b]);if(this._cbs[name])this._cbs[name](a,b)}}else{throw Error("wrong number of arguments")}});CollectingHandler.prototype.onreset=function(){this.events=[];if(this._cbs.onreset)this._cbs.onreset()};CollectingHandler.prototype.restart=function(){if(this._cbs.onreset)this._cbs.onreset();for(var i=0,len=this.events.length;i<len;i++){if(this._cbs[this.events[i][0]]){var num=this.events[i].length;if(num===1){this._cbs[this.events[i][0]]()}else if(num===2){this._cbs[this.events[i][0]](this.events[i][1])}else{this._cbs[this.events[i][0]](this.events[i][1],this.events[i][2])}}}}},{"./":36}],30:[function(require,module,exports){var index=require("./index.js"),DomHandler=index.DomHandler,DomUtils=index.DomUtils;function FeedHandler(callback,options){this.init(callback,options)}require("inherits")(FeedHandler,DomHandler);FeedHandler.prototype.init=DomHandler;function getElements(what,where){return DomUtils.getElementsByTagName(what,where,true)}function getOneElement(what,where){return DomUtils.getElementsByTagName(what,where,true,1)[0]}function fetch(what,where,recurse){return DomUtils.getText(DomUtils.getElementsByTagName(what,where,recurse,1)).trim()}function addConditionally(obj,prop,what,where,recurse){var tmp=fetch(what,where,recurse);if(tmp)obj[prop]=tmp}var isValidFeed=function(value){return value==="rss"||value==="feed"||value==="rdf:RDF"};FeedHandler.prototype.onend=function(){var feed={},feedRoot=getOneElement(isValidFeed,this.dom),tmp,childs;if(feedRoot){if(feedRoot.name==="feed"){childs=feedRoot.children;feed.type="atom";addConditionally(feed,"id","id",childs);addConditionally(feed,"title","title",childs);if((tmp=getOneElement("link",childs))&&(tmp=tmp.attribs)&&(tmp=tmp.href))feed.link=tmp;addConditionally(feed,"description","subtitle",childs);if(tmp=fetch("updated",childs))feed.updated=new Date(tmp);addConditionally(feed,"author","email",childs,true);feed.items=getElements("entry",childs).map(function(item){var entry={},tmp;item=item.children;addConditionally(entry,"id","id",item);addConditionally(entry,"title","title",item);if((tmp=getOneElement("link",item))&&(tmp=tmp.attribs)&&(tmp=tmp.href))entry.link=tmp;if(tmp=fetch("summary",item)||fetch("content",item))entry.description=tmp;if(tmp=fetch("updated",item))entry.pubDate=new Date(tmp);return entry})}else{childs=getOneElement("channel",feedRoot.children).children;feed.type=feedRoot.name.substr(0,3);feed.id="";addConditionally(feed,"title","title",childs);addConditionally(feed,"link","link",childs);addConditionally(feed,"description","description",childs);if(tmp=fetch("lastBuildDate",childs))feed.updated=new Date(tmp);addConditionally(feed,"author","managingEditor",childs,true);feed.items=getElements("item",feedRoot.children).map(function(item){var entry={},tmp;item=item.children;addConditionally(entry,"id","guid",item);addConditionally(entry,"title","title",item);addConditionally(entry,"link","link",item);addConditionally(entry,"description","description",item);if(tmp=fetch("pubDate",item))entry.pubDate=new Date(tmp);return entry})}}this.dom=feed;DomHandler.prototype._handleCallback.call(this,feedRoot?null:Error("couldn't find root of feed"))};module.exports=FeedHandler},{"./index.js":36,inherits:38}],31:[function(require,module,exports){var Tokenizer=require("./Tokenizer.js");var formTags={input:true,option:true,optgroup:true,select:true,button:true,datalist:true,textarea:true};var openImpliesClose={tr:{tr:true,th:true,td:true},th:{th:true},td:{thead:true,th:true,td:true},body:{head:true,link:true,script:true},li:{li:true},p:{p:true},h1:{p:true},h2:{p:true},h3:{p:true},h4:{p:true},h5:{p:true},h6:{p:true},select:formTags,input:formTags,output:formTags,button:formTags,datalist:formTags,textarea:formTags,option:{option:true},optgroup:{optgroup:true}};var voidElements={__proto__:null,area:true,base:true,basefont:true,br:true,col:true,command:true,embed:true,frame:true,hr:true,img:true,input:true,isindex:true,keygen:true,link:true,meta:true,param:true,source:true,track:true,wbr:true,path:true,circle:true,ellipse:true,line:true,rect:true,use:true,stop:true,polyline:true,polygon:true};var re_nameEnd=/\s|\//;function Parser(cbs,options){this._options=options||{};this._cbs=cbs||{};this._tagname="";this._attribname="";this._attribvalue="";this._attribs=null;this._stack=[];this.startIndex=0;this.endIndex=null;this._lowerCaseTagNames="lowerCaseTags"in this._options?!!this._options.lowerCaseTags:!this._options.xmlMode;this._lowerCaseAttributeNames="lowerCaseAttributeNames"in this._options?!!this._options.lowerCaseAttributeNames:!this._options.xmlMode;if(this._options.Tokenizer){Tokenizer=this._options.Tokenizer}this._tokenizer=new Tokenizer(this._options,this);if(this._cbs.onparserinit)this._cbs.onparserinit(this)}require("inherits")(Parser,require("events").EventEmitter);Parser.prototype._updatePosition=function(initialOffset){if(this.endIndex===null){if(this._tokenizer._sectionStart<=initialOffset){this.startIndex=0}else{this.startIndex=this._tokenizer._sectionStart-initialOffset}}else this.startIndex=this.endIndex+1;this.endIndex=this._tokenizer.getAbsoluteIndex()};Parser.prototype.ontext=function(data){this._updatePosition(1);this.endIndex--;if(this._cbs.ontext)this._cbs.ontext(data)};Parser.prototype.onopentagname=function(name){if(this._lowerCaseTagNames){name=name.toLowerCase()}this._tagname=name;if(!this._options.xmlMode&&name in openImpliesClose){for(var el;(el=this._stack[this._stack.length-1])in openImpliesClose[name];this.onclosetag(el));}if(this._options.xmlMode||!(name in voidElements)){this._stack.push(name)}if(this._cbs.onopentagname)this._cbs.onopentagname(name);if(this._cbs.onopentag)this._attribs={}};Parser.prototype.onopentagend=function(){this._updatePosition(1);if(this._attribs){if(this._cbs.onopentag)this._cbs.onopentag(this._tagname,this._attribs);this._attribs=null}if(!this._options.xmlMode&&this._cbs.onclosetag&&this._tagname in voidElements){this._cbs.onclosetag(this._tagname)}this._tagname=""};Parser.prototype.onclosetag=function(name){this._updatePosition(1);if(this._lowerCaseTagNames){name=name.toLowerCase()}if(this._stack.length&&(!(name in voidElements)||this._options.xmlMode)){var pos=this._stack.lastIndexOf(name);if(pos!==-1){if(this._cbs.onclosetag){pos=this._stack.length-pos;while(pos--)this._cbs.onclosetag(this._stack.pop())}else this._stack.length=pos}else if(name==="p"&&!this._options.xmlMode){this.onopentagname(name);this._closeCurrentTag()}}else if(!this._options.xmlMode&&(name==="br"||name==="p")){this.onopentagname(name);this._closeCurrentTag()}};Parser.prototype.onselfclosingtag=function(){if(this._options.xmlMode||this._options.recognizeSelfClosing){this._closeCurrentTag()}else{this.onopentagend()}};Parser.prototype._closeCurrentTag=function(){var name=this._tagname;this.onopentagend();if(this._stack[this._stack.length-1]===name){if(this._cbs.onclosetag){this._cbs.onclosetag(name)}this._stack.pop()}};Parser.prototype.onattribname=function(name){if(this._lowerCaseAttributeNames){name=name.toLowerCase()}this._attribname=name};Parser.prototype.onattribdata=function(value){this._attribvalue+=value};Parser.prototype.onattribend=function(){if(this._cbs.onattribute)this._cbs.onattribute(this._attribname,this._attribvalue);if(this._attribs&&!Object.prototype.hasOwnProperty.call(this._attribs,this._attribname)){this._attribs[this._attribname]=this._attribvalue}this._attribname="";this._attribvalue=""};Parser.prototype._getInstructionName=function(value){var idx=value.search(re_nameEnd),name=idx<0?value:value.substr(0,idx);if(this._lowerCaseTagNames){name=name.toLowerCase()}return name};Parser.prototype.ondeclaration=function(value){if(this._cbs.onprocessinginstruction){var name=this._getInstructionName(value);this._cbs.onprocessinginstruction("!"+name,"!"+value)}};Parser.prototype.onprocessinginstruction=function(value){if(this._cbs.onprocessinginstruction){var name=this._getInstructionName(value);this._cbs.onprocessinginstruction("?"+name,"?"+value)}};Parser.prototype.oncomment=function(value){this._updatePosition(4);if(this._cbs.oncomment)this._cbs.oncomment(value);if(this._cbs.oncommentend)this._cbs.oncommentend()};Parser.prototype.oncdata=function(value){this._updatePosition(1);if(this._options.xmlMode||this._options.recognizeCDATA){if(this._cbs.oncdatastart)this._cbs.oncdatastart();if(this._cbs.ontext)this._cbs.ontext(value);if(this._cbs.oncdataend)this._cbs.oncdataend()}else{this.oncomment("[CDATA["+value+"]]")}};Parser.prototype.onerror=function(err){if(this._cbs.onerror)this._cbs.onerror(err)};Parser.prototype.onend=function(){if(this._cbs.onclosetag){for(var i=this._stack.length;i>0;this._cbs.onclosetag(this._stack[--i]));}if(this._cbs.onend)this._cbs.onend()};Parser.prototype.reset=function(){if(this._cbs.onreset)this._cbs.onreset();this._tokenizer.reset();this._tagname="";this._attribname="";this._attribs=null;this._stack=[];if(this._cbs.onparserinit)this._cbs.onparserinit(this)};Parser.prototype.parseComplete=function(data){this.reset();this.end(data)};Parser.prototype.write=function(chunk){this._tokenizer.write(chunk)};Parser.prototype.end=function(chunk){this._tokenizer.end(chunk)};Parser.prototype.pause=function(){this._tokenizer.pause()};Parser.prototype.resume=function(){this._tokenizer.resume()};Parser.prototype.parseChunk=Parser.prototype.write;Parser.prototype.done=Parser.prototype.end;module.exports=Parser},{"./Tokenizer.js":34,events:28,inherits:38}],32:[function(require,module,exports){module.exports=ProxyHandler;function ProxyHandler(cbs){this._cbs=cbs||{}}var EVENTS=require("./").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){name="on"+name;ProxyHandler.prototype[name]=function(){if(this._cbs[name])this._cbs[name]()}}else if(EVENTS[name]===1){name="on"+name;ProxyHandler.prototype[name]=function(a){if(this._cbs[name])this._cbs[name](a)}}else if(EVENTS[name]===2){name="on"+name;ProxyHandler.prototype[name]=function(a,b){if(this._cbs[name])this._cbs[name](a,b)}}else{throw Error("wrong number of arguments")}})},{"./":36}],33:[function(require,module,exports){module.exports=Stream;var Parser=require("./WritableStream.js");function Stream(options){Parser.call(this,new Cbs(this),options)}require("inherits")(Stream,Parser);Stream.prototype.readable=true;function Cbs(scope){this.scope=scope}var EVENTS=require("../").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){Cbs.prototype["on"+name]=function(){this.scope.emit(name)}}else if(EVENTS[name]===1){Cbs.prototype["on"+name]=function(a){this.scope.emit(name,a)}}else if(EVENTS[name]===2){Cbs.prototype["on"+name]=function(a,b){this.scope.emit(name,a,b)}}else{throw Error("wrong number of arguments!")}})},{"../":36,"./WritableStream.js":35,inherits:38}],34:[function(require,module,exports){module.exports=Tokenizer;var decodeCodePoint=require("entities/lib/decode_codepoint.js"),entityMap=require("entities/maps/entities.json"),legacyMap=require("entities/maps/legacy.json"),xmlMap=require("entities/maps/xml.json"),i=0,TEXT=i++,BEFORE_TAG_NAME=i++,IN_TAG_NAME=i++,IN_SELF_CLOSING_TAG=i++,BEFORE_CLOSING_TAG_NAME=i++,IN_CLOSING_TAG_NAME=i++,AFTER_CLOSING_TAG_NAME=i++,BEFORE_ATTRIBUTE_NAME=i++,IN_ATTRIBUTE_NAME=i++,AFTER_ATTRIBUTE_NAME=i++,BEFORE_ATTRIBUTE_VALUE=i++,IN_ATTRIBUTE_VALUE_DQ=i++,IN_ATTRIBUTE_VALUE_SQ=i++,IN_ATTRIBUTE_VALUE_NQ=i++,BEFORE_DECLARATION=i++,IN_DECLARATION=i++,IN_PROCESSING_INSTRUCTION=i++,BEFORE_COMMENT=i++,IN_COMMENT=i++,AFTER_COMMENT_1=i++,AFTER_COMMENT_2=i++,BEFORE_CDATA_1=i++,BEFORE_CDATA_2=i++,BEFORE_CDATA_3=i++,BEFORE_CDATA_4=i++,BEFORE_CDATA_5=i++,BEFORE_CDATA_6=i++,IN_CDATA=i++,AFTER_CDATA_1=i++,AFTER_CDATA_2=i++,BEFORE_SPECIAL=i++,BEFORE_SPECIAL_END=i++,BEFORE_SCRIPT_1=i++,BEFORE_SCRIPT_2=i++,BEFORE_SCRIPT_3=i++,BEFORE_SCRIPT_4=i++,BEFORE_SCRIPT_5=i++,AFTER_SCRIPT_1=i++,AFTER_SCRIPT_2=i++,AFTER_SCRIPT_3=i++,AFTER_SCRIPT_4=i++,AFTER_SCRIPT_5=i++,BEFORE_STYLE_1=i++,BEFORE_STYLE_2=i++,BEFORE_STYLE_3=i++,BEFORE_STYLE_4=i++,AFTER_STYLE_1=i++,AFTER_STYLE_2=i++,AFTER_STYLE_3=i++,AFTER_STYLE_4=i++,BEFORE_ENTITY=i++,BEFORE_NUMERIC_ENTITY=i++,IN_NAMED_ENTITY=i++,IN_NUMERIC_ENTITY=i++,IN_HEX_ENTITY=i++,j=0,SPECIAL_NONE=j++,SPECIAL_SCRIPT=j++,SPECIAL_STYLE=j++;function whitespace(c){return c===" "||c==="\n"||c==="\t"||c==="\f"||c==="\r"}function characterState(char,SUCCESS){return function(c){if(c===char)this._state=SUCCESS}}function ifElseState(upper,SUCCESS,FAILURE){var lower=upper.toLowerCase();if(upper===lower){return function(c){if(c===lower){this._state=SUCCESS}else{this._state=FAILURE;this._index--}}}else{return function(c){if(c===lower||c===upper){this._state=SUCCESS}else{this._state=FAILURE;this._index--}}}}function consumeSpecialNameChar(upper,NEXT_STATE){var lower=upper.toLowerCase();return function(c){if(c===lower||c===upper){this._state=NEXT_STATE}else{this._state=IN_TAG_NAME;this._index--}}}function Tokenizer(options,cbs){this._state=TEXT;this._buffer="";this._sectionStart=0;this._index=0;this._bufferOffset=0;this._baseState=TEXT;this._special=SPECIAL_NONE;this._cbs=cbs;this._running=true;this._ended=false;this._xmlMode=!!(options&&options.xmlMode);this._decodeEntities=!!(options&&options.decodeEntities)}Tokenizer.prototype._stateText=function(c){if(c==="<"){if(this._index>this._sectionStart){this._cbs.ontext(this._getSection())}this._state=BEFORE_TAG_NAME;this._sectionStart=this._index}else if(this._decodeEntities&&this._special===SPECIAL_NONE&&c==="&"){if(this._index>this._sectionStart){this._cbs.ontext(this._getSection())}this._baseState=TEXT;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeTagName=function(c){if(c==="/"){this._state=BEFORE_CLOSING_TAG_NAME}else if(c==="<"){this._cbs.ontext(this._getSection());this._sectionStart=this._index}else if(c===">"||this._special!==SPECIAL_NONE||whitespace(c)){this._state=TEXT}else if(c==="!"){this._state=BEFORE_DECLARATION;this._sectionStart=this._index+1}else if(c==="?"){this._state=IN_PROCESSING_INSTRUCTION;this._sectionStart=this._index+1}else{this._state=!this._xmlMode&&(c==="s"||c==="S")?BEFORE_SPECIAL:IN_TAG_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInTagName=function(c){if(c==="/"||c===">"||whitespace(c)){this._emitToken("onopentagname");this._state=BEFORE_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateBeforeCloseingTagName=function(c){if(whitespace(c));else if(c===">"){this._state=TEXT}else if(this._special!==SPECIAL_NONE){if(c==="s"||c==="S"){this._state=BEFORE_SPECIAL_END}else{this._state=TEXT;this._index--}}else{this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInCloseingTagName=function(c){if(c===">"||whitespace(c)){this._emitToken("onclosetag");this._state=AFTER_CLOSING_TAG_NAME;this._index--}};Tokenizer.prototype._stateAfterCloseingTagName=function(c){if(c===">"){this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateBeforeAttributeName=function(c){if(c===">"){this._cbs.onopentagend();this._state=TEXT;this._sectionStart=this._index+1}else if(c==="/"){this._state=IN_SELF_CLOSING_TAG}else if(!whitespace(c)){this._state=IN_ATTRIBUTE_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInSelfClosingTag=function(c){if(c===">"){this._cbs.onselfclosingtag();this._state=TEXT;this._sectionStart=this._index+1}else if(!whitespace(c)){this._state=BEFORE_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateInAttributeName=function(c){if(c==="="||c==="/"||c===">"||whitespace(c)){this._cbs.onattribname(this._getSection());this._sectionStart=-1;this._state=AFTER_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateAfterAttributeName=function(c){if(c==="="){this._state=BEFORE_ATTRIBUTE_VALUE}else if(c==="/"||c===">"){this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME;this._index--}else if(!whitespace(c)){this._cbs.onattribend();this._state=IN_ATTRIBUTE_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeAttributeValue=function(c){if(c==='"'){this._state=IN_ATTRIBUTE_VALUE_DQ;this._sectionStart=this._index+1}else if(c==="'"){this._state=IN_ATTRIBUTE_VALUE_SQ;this._sectionStart=this._index+1}else if(!whitespace(c)){this._state=IN_ATTRIBUTE_VALUE_NQ;this._sectionStart=this._index;this._index--}};Tokenizer.prototype._stateInAttributeValueDoubleQuotes=function(c){if(c==='"'){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateInAttributeValueSingleQuotes=function(c){if(c==="'"){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateInAttributeValueNoQuotes=function(c){if(whitespace(c)||c===">"){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME;this._index--}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeDeclaration=function(c){this._state=c==="["?BEFORE_CDATA_1:c==="-"?BEFORE_COMMENT:IN_DECLARATION};Tokenizer.prototype._stateInDeclaration=function(c){if(c===">"){this._cbs.ondeclaration(this._getSection());this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateInProcessingInstruction=function(c){if(c===">"){this._cbs.onprocessinginstruction(this._getSection());this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateBeforeComment=function(c){if(c==="-"){this._state=IN_COMMENT;this._sectionStart=this._index+1}else{this._state=IN_DECLARATION}};Tokenizer.prototype._stateInComment=function(c){if(c==="-")this._state=AFTER_COMMENT_1};Tokenizer.prototype._stateAfterComment1=function(c){if(c==="-"){this._state=AFTER_COMMENT_2}else{this._state=IN_COMMENT}};Tokenizer.prototype._stateAfterComment2=function(c){if(c===">"){this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2));this._state=TEXT;this._sectionStart=this._index+1}else if(c!=="-"){this._state=IN_COMMENT}};Tokenizer.prototype._stateBeforeCdata1=ifElseState("C",BEFORE_CDATA_2,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata2=ifElseState("D",BEFORE_CDATA_3,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata3=ifElseState("A",BEFORE_CDATA_4,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata4=ifElseState("T",BEFORE_CDATA_5,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata5=ifElseState("A",BEFORE_CDATA_6,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata6=function(c){if(c==="["){this._state=IN_CDATA;this._sectionStart=this._index+1}else{this._state=IN_DECLARATION;this._index--}};Tokenizer.prototype._stateInCdata=function(c){if(c==="]")this._state=AFTER_CDATA_1};Tokenizer.prototype._stateAfterCdata1=characterState("]",AFTER_CDATA_2);Tokenizer.prototype._stateAfterCdata2=function(c){if(c===">"){this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2));this._state=TEXT;this._sectionStart=this._index+1}else if(c!=="]"){this._state=IN_CDATA}};Tokenizer.prototype._stateBeforeSpecial=function(c){if(c==="c"||c==="C"){this._state=BEFORE_SCRIPT_1}else if(c==="t"||c==="T"){this._state=BEFORE_STYLE_1}else{this._state=IN_TAG_NAME;this._index--}};Tokenizer.prototype._stateBeforeSpecialEnd=function(c){if(this._special===SPECIAL_SCRIPT&&(c==="c"||c==="C")){this._state=AFTER_SCRIPT_1}else if(this._special===SPECIAL_STYLE&&(c==="t"||c==="T")){this._state=AFTER_STYLE_1}else this._state=TEXT};Tokenizer.prototype._stateBeforeScript1=consumeSpecialNameChar("R",BEFORE_SCRIPT_2);Tokenizer.prototype._stateBeforeScript2=consumeSpecialNameChar("I",BEFORE_SCRIPT_3);Tokenizer.prototype._stateBeforeScript3=consumeSpecialNameChar("P",BEFORE_SCRIPT_4);Tokenizer.prototype._stateBeforeScript4=consumeSpecialNameChar("T",BEFORE_SCRIPT_5);Tokenizer.prototype._stateBeforeScript5=function(c){if(c==="/"||c===">"||whitespace(c)){this._special=SPECIAL_SCRIPT}this._state=IN_TAG_NAME;this._index--};Tokenizer.prototype._stateAfterScript1=ifElseState("R",AFTER_SCRIPT_2,TEXT);Tokenizer.prototype._stateAfterScript2=ifElseState("I",AFTER_SCRIPT_3,TEXT);Tokenizer.prototype._stateAfterScript3=ifElseState("P",AFTER_SCRIPT_4,TEXT);Tokenizer.prototype._stateAfterScript4=ifElseState("T",AFTER_SCRIPT_5,TEXT);Tokenizer.prototype._stateAfterScript5=function(c){if(c===">"||whitespace(c)){this._special=SPECIAL_NONE;this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index-6;this._index--}else this._state=TEXT};Tokenizer.prototype._stateBeforeStyle1=consumeSpecialNameChar("Y",BEFORE_STYLE_2);Tokenizer.prototype._stateBeforeStyle2=consumeSpecialNameChar("L",BEFORE_STYLE_3);Tokenizer.prototype._stateBeforeStyle3=consumeSpecialNameChar("E",BEFORE_STYLE_4);Tokenizer.prototype._stateBeforeStyle4=function(c){if(c==="/"||c===">"||whitespace(c)){this._special=SPECIAL_STYLE}this._state=IN_TAG_NAME;this._index--};Tokenizer.prototype._stateAfterStyle1=ifElseState("Y",AFTER_STYLE_2,TEXT);Tokenizer.prototype._stateAfterStyle2=ifElseState("L",AFTER_STYLE_3,TEXT);Tokenizer.prototype._stateAfterStyle3=ifElseState("E",AFTER_STYLE_4,TEXT);Tokenizer.prototype._stateAfterStyle4=function(c){if(c===">"||whitespace(c)){this._special=SPECIAL_NONE;this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index-5;this._index--}else this._state=TEXT};Tokenizer.prototype._stateBeforeEntity=ifElseState("#",BEFORE_NUMERIC_ENTITY,IN_NAMED_ENTITY);Tokenizer.prototype._stateBeforeNumericEntity=ifElseState("X",IN_HEX_ENTITY,IN_NUMERIC_ENTITY);Tokenizer.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+1<this._index){var entity=this._buffer.substring(this._sectionStart+1,this._index),map=this._xmlMode?xmlMap:entityMap;if(map.hasOwnProperty(entity)){this._emitPartial(map[entity]);this._sectionStart=this._index+1}}};Tokenizer.prototype._parseLegacyEntity=function(){var start=this._sectionStart+1,limit=this._index-start;if(limit>6)limit=6;while(limit>=2){var entity=this._buffer.substr(start,limit);if(legacyMap.hasOwnProperty(entity)){this._emitPartial(legacyMap[entity]);this._sectionStart+=limit+1;return}else{limit--}}};Tokenizer.prototype._stateInNamedEntity=function(c){if(c===";"){this._parseNamedEntityStrict();if(this._sectionStart+1<this._index&&!this._xmlMode){this._parseLegacyEntity()}this._state=this._baseState}else if((c<"a"||c>"z")&&(c<"A"||c>"Z")&&(c<"0"||c>"9")){if(this._xmlMode);else if(this._sectionStart+1===this._index);else if(this._baseState!==TEXT){if(c!=="="){this._parseNamedEntityStrict()}}else{this._parseLegacyEntity()}this._state=this._baseState;this._index--}};Tokenizer.prototype._decodeNumericEntity=function(offset,base){var sectionStart=this._sectionStart+offset;if(sectionStart!==this._index){var entity=this._buffer.substring(sectionStart,this._index);var parsed=parseInt(entity,base);this._emitPartial(decodeCodePoint(parsed));this._sectionStart=this._index}else{this._sectionStart--}this._state=this._baseState};Tokenizer.prototype._stateInNumericEntity=function(c){if(c===";"){this._decodeNumericEntity(2,10);this._sectionStart++}else if(c<"0"||c>"9"){if(!this._xmlMode){this._decodeNumericEntity(2,10)}else{this._state=this._baseState}this._index--}};Tokenizer.prototype._stateInHexEntity=function(c){if(c===";"){this._decodeNumericEntity(3,16);this._sectionStart++}else if((c<"a"||c>"f")&&(c<"A"||c>"F")&&(c<"0"||c>"9")){if(!this._xmlMode){this._decodeNumericEntity(3,16)}else{this._state=this._baseState}this._index--}};Tokenizer.prototype._cleanup=function(){if(this._sectionStart<0){this._buffer="";this._index=0;this._bufferOffset+=this._index}else if(this._running){if(this._state===TEXT){if(this._sectionStart!==this._index){this._cbs.ontext(this._buffer.substr(this._sectionStart))}this._buffer="";this._bufferOffset+=this._index;this._index=0}else if(this._sectionStart===this._index){this._buffer="";this._bufferOffset+=this._index;this._index=0}else{this._buffer=this._buffer.substr(this._sectionStart);this._index-=this._sectionStart;this._bufferOffset+=this._sectionStart}this._sectionStart=0}};Tokenizer.prototype.write=function(chunk){if(this._ended)this._cbs.onerror(Error(".write() after done!"));this._buffer+=chunk;this._parse()};Tokenizer.prototype._parse=function(){while(this._index<this._buffer.length&&this._running){var c=this._buffer.charAt(this._index);if(this._state===TEXT){this._stateText(c)}else if(this._state===BEFORE_TAG_NAME){this._stateBeforeTagName(c)}else if(this._state===IN_TAG_NAME){this._stateInTagName(c)}else if(this._state===BEFORE_CLOSING_TAG_NAME){this._stateBeforeCloseingTagName(c)}else if(this._state===IN_CLOSING_TAG_NAME){this._stateInCloseingTagName(c)}else if(this._state===AFTER_CLOSING_TAG_NAME){this._stateAfterCloseingTagName(c)}else if(this._state===IN_SELF_CLOSING_TAG){this._stateInSelfClosingTag(c)}else if(this._state===BEFORE_ATTRIBUTE_NAME){this._stateBeforeAttributeName(c)}else if(this._state===IN_ATTRIBUTE_NAME){this._stateInAttributeName(c)}else if(this._state===AFTER_ATTRIBUTE_NAME){this._stateAfterAttributeName(c)}else if(this._state===BEFORE_ATTRIBUTE_VALUE){this._stateBeforeAttributeValue(c)}else if(this._state===IN_ATTRIBUTE_VALUE_DQ){this._stateInAttributeValueDoubleQuotes(c)}else if(this._state===IN_ATTRIBUTE_VALUE_SQ){this._stateInAttributeValueSingleQuotes(c)}else if(this._state===IN_ATTRIBUTE_VALUE_NQ){this._stateInAttributeValueNoQuotes(c)}else if(this._state===BEFORE_DECLARATION){this._stateBeforeDeclaration(c)}else if(this._state===IN_DECLARATION){this._stateInDeclaration(c)}else if(this._state===IN_PROCESSING_INSTRUCTION){this._stateInProcessingInstruction(c)}else if(this._state===BEFORE_COMMENT){this._stateBeforeComment(c)}else if(this._state===IN_COMMENT){this._stateInComment(c)}else if(this._state===AFTER_COMMENT_1){this._stateAfterComment1(c)}else if(this._state===AFTER_COMMENT_2){this._stateAfterComment2(c)}else if(this._state===BEFORE_CDATA_1){this._stateBeforeCdata1(c)}else if(this._state===BEFORE_CDATA_2){this._stateBeforeCdata2(c)}else if(this._state===BEFORE_CDATA_3){this._stateBeforeCdata3(c)}else if(this._state===BEFORE_CDATA_4){this._stateBeforeCdata4(c)}else if(this._state===BEFORE_CDATA_5){this._stateBeforeCdata5(c)}else if(this._state===BEFORE_CDATA_6){this._stateBeforeCdata6(c)}else if(this._state===IN_CDATA){this._stateInCdata(c)}else if(this._state===AFTER_CDATA_1){this._stateAfterCdata1(c)}else if(this._state===AFTER_CDATA_2){this._stateAfterCdata2(c)}else if(this._state===BEFORE_SPECIAL){this._stateBeforeSpecial(c)}else if(this._state===BEFORE_SPECIAL_END){this._stateBeforeSpecialEnd(c)}else if(this._state===BEFORE_SCRIPT_1){this._stateBeforeScript1(c)}else if(this._state===BEFORE_SCRIPT_2){this._stateBeforeScript2(c)}else if(this._state===BEFORE_SCRIPT_3){this._stateBeforeScript3(c)}else if(this._state===BEFORE_SCRIPT_4){this._stateBeforeScript4(c)}else if(this._state===BEFORE_SCRIPT_5){this._stateBeforeScript5(c)}else if(this._state===AFTER_SCRIPT_1){this._stateAfterScript1(c)}else if(this._state===AFTER_SCRIPT_2){this._stateAfterScript2(c)}else if(this._state===AFTER_SCRIPT_3){this._stateAfterScript3(c)}else if(this._state===AFTER_SCRIPT_4){this._stateAfterScript4(c)}else if(this._state===AFTER_SCRIPT_5){this._stateAfterScript5(c)}else if(this._state===BEFORE_STYLE_1){this._stateBeforeStyle1(c)}else if(this._state===BEFORE_STYLE_2){this._stateBeforeStyle2(c)}else if(this._state===BEFORE_STYLE_3){this._stateBeforeStyle3(c)}else if(this._state===BEFORE_STYLE_4){this._stateBeforeStyle4(c)}else if(this._state===AFTER_STYLE_1){this._stateAfterStyle1(c)}else if(this._state===AFTER_STYLE_2){this._stateAfterStyle2(c)}else if(this._state===AFTER_STYLE_3){this._stateAfterStyle3(c)}else if(this._state===AFTER_STYLE_4){this._stateAfterStyle4(c)}else if(this._state===BEFORE_ENTITY){this._stateBeforeEntity(c)}else if(this._state===BEFORE_NUMERIC_ENTITY){this._stateBeforeNumericEntity(c)}else if(this._state===IN_NAMED_ENTITY){this._stateInNamedEntity(c)}else if(this._state===IN_NUMERIC_ENTITY){this._stateInNumericEntity(c)}else if(this._state===IN_HEX_ENTITY){this._stateInHexEntity(c)}else{this._cbs.onerror(Error("unknown _state"),this._state)}this._index++}this._cleanup()};Tokenizer.prototype.pause=function(){this._running=false};Tokenizer.prototype.resume=function(){this._running=true;if(this._index<this._buffer.length){this._parse()}if(this._ended){this._finish()}};Tokenizer.prototype.end=function(chunk){if(this._ended)this._cbs.onerror(Error(".end() after done!"));if(chunk)this.write(chunk);this._ended=true;if(this._running)this._finish()};Tokenizer.prototype._finish=function(){if(this._sectionStart<this._index){this._handleTrailingData()}this._cbs.onend()};Tokenizer.prototype._handleTrailingData=function(){var data=this._buffer.substr(this._sectionStart);if(this._state===IN_CDATA||this._state===AFTER_CDATA_1||this._state===AFTER_CDATA_2){this._cbs.oncdata(data)}else if(this._state===IN_COMMENT||this._state===AFTER_COMMENT_1||this._state===AFTER_COMMENT_2){this._cbs.oncomment(data)}else if(this._state===IN_NAMED_ENTITY&&!this._xmlMode){this._parseLegacyEntity();if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state===IN_NUMERIC_ENTITY&&!this._xmlMode){this._decodeNumericEntity(2,10);if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state===IN_HEX_ENTITY&&!this._xmlMode){this._decodeNumericEntity(3,16);if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state!==IN_TAG_NAME&&this._state!==BEFORE_ATTRIBUTE_NAME&&this._state!==BEFORE_ATTRIBUTE_VALUE&&this._state!==AFTER_ATTRIBUTE_NAME&&this._state!==IN_ATTRIBUTE_NAME&&this._state!==IN_ATTRIBUTE_VALUE_SQ&&this._state!==IN_ATTRIBUTE_VALUE_DQ&&this._state!==IN_ATTRIBUTE_VALUE_NQ&&this._state!==IN_CLOSING_TAG_NAME){ |
| this._cbs.ontext(data)}};Tokenizer.prototype.reset=function(){Tokenizer.call(this,{xmlMode:this._xmlMode,decodeEntities:this._decodeEntities},this._cbs)};Tokenizer.prototype.getAbsoluteIndex=function(){return this._bufferOffset+this._index};Tokenizer.prototype._getSection=function(){return this._buffer.substring(this._sectionStart,this._index)};Tokenizer.prototype._emitToken=function(name){this._cbs[name](this._getSection());this._sectionStart=-1};Tokenizer.prototype._emitPartial=function(value){if(this._baseState!==TEXT){this._cbs.onattribdata(value)}else{this._cbs.ontext(value)}}},{"entities/lib/decode_codepoint.js":22,"entities/maps/entities.json":25,"entities/maps/legacy.json":26,"entities/maps/xml.json":27}],35:[function(require,module,exports){module.exports=Stream;var Parser=require("./Parser.js"),WritableStream=require("stream").Writable||require("readable-stream").Writable,StringDecoder=require("string_decoder").StringDecoder,Buffer=require("buffer").Buffer;function Stream(cbs,options){var parser=this._parser=new Parser(cbs,options);var decoder=this._decoder=new StringDecoder;WritableStream.call(this,{decodeStrings:false});this.once("finish",function(){parser.end(decoder.end())})}require("inherits")(Stream,WritableStream);WritableStream.prototype._write=function(chunk,encoding,cb){if(chunk instanceof Buffer)chunk=this._decoder.write(chunk);this._parser.write(chunk);cb()}},{"./Parser.js":31,buffer:5,inherits:38,"readable-stream":3,stream:55,string_decoder:56}],36:[function(require,module,exports){var Parser=require("./Parser.js"),DomHandler=require("domhandler");function defineProp(name,value){delete module.exports[name];module.exports[name]=value;return value}module.exports={Parser:Parser,Tokenizer:require("./Tokenizer.js"),ElementType:require("domelementtype"),DomHandler:DomHandler,get FeedHandler(){return defineProp("FeedHandler",require("./FeedHandler.js"))},get Stream(){return defineProp("Stream",require("./Stream.js"))},get WritableStream(){return defineProp("WritableStream",require("./WritableStream.js"))},get ProxyHandler(){return defineProp("ProxyHandler",require("./ProxyHandler.js"))},get DomUtils(){return defineProp("DomUtils",require("domutils"))},get CollectingHandler(){return defineProp("CollectingHandler",require("./CollectingHandler.js"))},DefaultHandler:DomHandler,get RssHandler(){return defineProp("RssHandler",this.FeedHandler)},parseDOM:function(data,options){var handler=new DomHandler(options);new Parser(handler,options).end(data);return handler.dom},parseFeed:function(feed,options){var handler=new module.exports.FeedHandler(options);new Parser(handler,options).end(feed);return handler.dom},createDomStream:function(cb,options,elementCb){var handler=new DomHandler(cb,options,elementCb);return new Parser(handler,options)},EVENTS:{attribute:2,cdatastart:0,cdataend:0,text:1,processinginstruction:2,comment:1,commentend:0,closetag:1,opentag:2,opentagname:1,error:1,end:0}}},{"./CollectingHandler.js":29,"./FeedHandler.js":30,"./Parser.js":31,"./ProxyHandler.js":32,"./Stream.js":33,"./Tokenizer.js":34,"./WritableStream.js":35,domelementtype:9,domhandler:10,domutils:13}],37:[function(require,module,exports){exports.read=function(buffer,offset,isLE,mLen,nBytes){var e,m;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var nBits=-7;var i=isLE?nBytes-1:0;var d=isLE?-1:1;var s=buffer[offset+i];i+=d;e=s&(1<<-nBits)-1;s>>=-nBits;nBits+=eLen;for(;nBits>0;e=e*256+buffer[offset+i],i+=d,nBits-=8){}m=e&(1<<-nBits)-1;e>>=-nBits;nBits+=mLen;for(;nBits>0;m=m*256+buffer[offset+i],i+=d,nBits-=8){}if(e===0){e=1-eBias}else if(e===eMax){return m?NaN:(s?-1:1)*Infinity}else{m=m+Math.pow(2,mLen);e=e-eBias}return(s?-1:1)*m*Math.pow(2,e-mLen)};exports.write=function(buffer,value,offset,isLE,mLen,nBytes){var e,m,c;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var rt=mLen===23?Math.pow(2,-24)-Math.pow(2,-77):0;var i=isLE?0:nBytes-1;var d=isLE?1:-1;var s=value<0||value===0&&1/value<0?1:0;value=Math.abs(value);if(isNaN(value)||value===Infinity){m=isNaN(value)?1:0;e=eMax}else{e=Math.floor(Math.log(value)/Math.LN2);if(value*(c=Math.pow(2,-e))<1){e--;c*=2}if(e+eBias>=1){value+=rt/c}else{value+=rt*Math.pow(2,1-eBias)}if(value*c>=2){e++;c/=2}if(e+eBias>=eMax){m=0;e=eMax}else if(e+eBias>=1){m=(value*c-1)*Math.pow(2,mLen);e=e+eBias}else{m=value*Math.pow(2,eBias-1)*Math.pow(2,mLen);e=0}}for(;mLen>=8;buffer[offset+i]=m&255,i+=d,m/=256,mLen-=8){}e=e<<mLen|m;eLen+=mLen;for(;eLen>0;buffer[offset+i]=e&255,i+=d,e/=256,eLen-=8){}buffer[offset+i-d]|=s*128}},{}],38:[function(require,module,exports){if(typeof Object.create==="function"){module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:false,writable:true,configurable:true}})}}else{module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;var TempCtor=function(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor;ctor.prototype.constructor=ctor}}},{}],39:[function(require,module,exports){module.exports=function(obj){return obj!=null&&(isBuffer(obj)||isSlowBuffer(obj)||!!obj._isBuffer)};function isBuffer(obj){return!!obj.constructor&&typeof obj.constructor.isBuffer==="function"&&obj.constructor.isBuffer(obj)}function isSlowBuffer(obj){return typeof obj.readFloatLE==="function"&&typeof obj.slice==="function"&&isBuffer(obj.slice(0,0))}},{}],40:[function(require,module,exports){var toString={}.toString;module.exports=Array.isArray||function(arr){return toString.call(arr)=="[object Array]"}},{}],41:[function(require,module,exports){(function(process){"use strict";if(!process.version||process.version.indexOf("v0.")===0||process.version.indexOf("v1.")===0&&process.version.indexOf("v1.8.")!==0){module.exports=nextTick}else{module.exports=process.nextTick}function nextTick(fn,arg1,arg2,arg3){if(typeof fn!=="function"){throw new TypeError('"callback" argument must be a function')}var len=arguments.length;var args,i;switch(len){case 0:case 1:return process.nextTick(fn);case 2:return process.nextTick(function afterTickOne(){fn.call(null,arg1)});case 3:return process.nextTick(function afterTickTwo(){fn.call(null,arg1,arg2)});case 4:return process.nextTick(function afterTickThree(){fn.call(null,arg1,arg2,arg3)});default:args=new Array(len-1);i=0;while(i<args.length){args[i++]=arguments[i]}return process.nextTick(function afterTick(){fn.apply(null,args)})}}}).call(this,require("_process"))},{_process:42}],42:[function(require,module,exports){var process=module.exports={};var cachedSetTimeout;var cachedClearTimeout;function defaultSetTimout(){throw new Error("setTimeout has not been defined")}function defaultClearTimeout(){throw new Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function"){cachedSetTimeout=setTimeout}else{cachedSetTimeout=defaultSetTimout}}catch(e){cachedSetTimeout=defaultSetTimout}try{if(typeof clearTimeout==="function"){cachedClearTimeout=clearTimeout}else{cachedClearTimeout=defaultClearTimeout}}catch(e){cachedClearTimeout=defaultClearTimeout}})();function runTimeout(fun){if(cachedSetTimeout===setTimeout){return setTimeout(fun,0)}if((cachedSetTimeout===defaultSetTimout||!cachedSetTimeout)&&setTimeout){cachedSetTimeout=setTimeout;return setTimeout(fun,0)}try{return cachedSetTimeout(fun,0)}catch(e){try{return cachedSetTimeout.call(null,fun,0)}catch(e){return cachedSetTimeout.call(this,fun,0)}}}function runClearTimeout(marker){if(cachedClearTimeout===clearTimeout){return clearTimeout(marker)}if((cachedClearTimeout===defaultClearTimeout||!cachedClearTimeout)&&clearTimeout){cachedClearTimeout=clearTimeout;return clearTimeout(marker)}try{return cachedClearTimeout(marker)}catch(e){try{return cachedClearTimeout.call(null,marker)}catch(e){return cachedClearTimeout.call(this,marker)}}}var queue=[];var draining=false;var currentQueue;var queueIndex=-1;function cleanUpNextTick(){if(!draining||!currentQueue){return}draining=false;if(currentQueue.length){queue=currentQueue.concat(queue)}else{queueIndex=-1}if(queue.length){drainQueue()}}function drainQueue(){if(draining){return}var timeout=runTimeout(cleanUpNextTick);draining=true;var len=queue.length;while(len){currentQueue=queue;queue=[];while(++queueIndex<len){if(currentQueue){currentQueue[queueIndex].run()}}queueIndex=-1;len=queue.length}currentQueue=null;draining=false;runClearTimeout(timeout)}process.nextTick=function(fun){var args=new Array(arguments.length-1);if(arguments.length>1){for(var i=1;i<arguments.length;i++){args[i-1]=arguments[i]}}queue.push(new Item(fun,args));if(queue.length===1&&!draining){runTimeout(drainQueue)}};function Item(fun,array){this.fun=fun;this.array=array}Item.prototype.run=function(){this.fun.apply(null,this.array)};process.title="browser";process.browser=true;process.env={};process.argv=[];process.version="";process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")};process.umask=function(){return 0}},{}],43:[function(require,module,exports){module.exports=require("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":44}],44:[function(require,module,exports){"use strict";var objectKeys=Object.keys||function(obj){var keys=[];for(var key in obj){keys.push(key)}return keys};module.exports=Duplex;var processNextTick=require("process-nextick-args");var util=require("core-util-is");util.inherits=require("inherits");var Readable=require("./_stream_readable");var Writable=require("./_stream_writable");util.inherits(Duplex,Readable);var keys=objectKeys(Writable.prototype);for(var v=0;v<keys.length;v++){var method=keys[v];if(!Duplex.prototype[method])Duplex.prototype[method]=Writable.prototype[method]}function Duplex(options){if(!(this instanceof Duplex))return new Duplex(options);Readable.call(this,options);Writable.call(this,options);if(options&&options.readable===false)this.readable=false;if(options&&options.writable===false)this.writable=false;this.allowHalfOpen=true;if(options&&options.allowHalfOpen===false)this.allowHalfOpen=false;this.once("end",onend)}function onend(){if(this.allowHalfOpen||this._writableState.ended)return;processNextTick(onEndNT,this)}function onEndNT(self){self.end()}function forEach(xs,f){for(var i=0,l=xs.length;i<l;i++){f(xs[i],i)}}},{"./_stream_readable":46,"./_stream_writable":48,"core-util-is":6,inherits:38,"process-nextick-args":41}],45:[function(require,module,exports){"use strict";module.exports=PassThrough;var Transform=require("./_stream_transform");var util=require("core-util-is");util.inherits=require("inherits");util.inherits(PassThrough,Transform);function PassThrough(options){if(!(this instanceof PassThrough))return new PassThrough(options);Transform.call(this,options)}PassThrough.prototype._transform=function(chunk,encoding,cb){cb(null,chunk)}},{"./_stream_transform":47,"core-util-is":6,inherits:38}],46:[function(require,module,exports){(function(process){"use strict";module.exports=Readable;var processNextTick=require("process-nextick-args");var isArray=require("isarray");Readable.ReadableState=ReadableState;var EE=require("events").EventEmitter;var EElistenerCount=function(emitter,type){return emitter.listeners(type).length};var Stream;(function(){try{Stream=require("st"+"ream")}catch(_){}finally{if(!Stream)Stream=require("events").EventEmitter}})();var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");var util=require("core-util-is");util.inherits=require("inherits");var debugUtil=require("util");var debug=void 0;if(debugUtil&&debugUtil.debuglog){debug=debugUtil.debuglog("stream")}else{debug=function(){}}var BufferList=require("./internal/streams/BufferList");var StringDecoder;util.inherits(Readable,Stream);function prependListener(emitter,event,fn){if(typeof emitter.prependListener==="function"){return emitter.prependListener(event,fn)}else{if(!emitter._events||!emitter._events[event])emitter.on(event,fn);else if(isArray(emitter._events[event]))emitter._events[event].unshift(fn);else emitter._events[event]=[fn,emitter._events[event]]}}var Duplex;function ReadableState(options,stream){Duplex=Duplex||require("./_stream_duplex");options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.readableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.buffer=new BufferList;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.defaultEncoding=options.defaultEncoding||"utf8";this.ranOut=false;this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(options.encoding){if(!StringDecoder)StringDecoder=require("string_decoder/").StringDecoder;this.decoder=new StringDecoder(options.encoding);this.encoding=options.encoding}}var Duplex;function Readable(options){Duplex=Duplex||require("./_stream_duplex");if(!(this instanceof Readable))return new Readable(options);this._readableState=new ReadableState(options,this);this.readable=true;if(options&&typeof options.read==="function")this._read=options.read;Stream.call(this)}Readable.prototype.push=function(chunk,encoding){var state=this._readableState;if(!state.objectMode&&typeof chunk==="string"){encoding=encoding||state.defaultEncoding;if(encoding!==state.encoding){chunk=bufferShim.from(chunk,encoding);encoding=""}}return readableAddChunk(this,state,chunk,encoding,false)};Readable.prototype.unshift=function(chunk){var state=this._readableState;return readableAddChunk(this,state,chunk,"",true)};Readable.prototype.isPaused=function(){return this._readableState.flowing===false};function readableAddChunk(stream,state,chunk,encoding,addToFront){var er=chunkInvalid(state,chunk);if(er){stream.emit("error",er)}else if(chunk===null){state.reading=false;onEofChunk(stream,state)}else if(state.objectMode||chunk&&chunk.length>0){if(state.ended&&!addToFront){var e=new Error("stream.push() after EOF");stream.emit("error",e)}else if(state.endEmitted&&addToFront){var _e=new Error("stream.unshift() after end event");stream.emit("error",_e)}else{var skipAdd;if(state.decoder&&!addToFront&&!encoding){chunk=state.decoder.write(chunk);skipAdd=!state.objectMode&&chunk.length===0}if(!addToFront)state.reading=false;if(!skipAdd){if(state.flowing&&state.length===0&&!state.sync){stream.emit("data",chunk);stream.read(0)}else{state.length+=state.objectMode?1:chunk.length;if(addToFront)state.buffer.unshift(chunk);else state.buffer.push(chunk);if(state.needReadable)emitReadable(stream)}}maybeReadMore(stream,state)}}else if(!addToFront){state.reading=false}return needMoreData(state)}function needMoreData(state){return!state.ended&&(state.needReadable||state.length<state.highWaterMark||state.length===0)}Readable.prototype.setEncoding=function(enc){if(!StringDecoder)StringDecoder=require("string_decoder/").StringDecoder;this._readableState.decoder=new StringDecoder(enc);this._readableState.encoding=enc;return this};var MAX_HWM=8388608;function computeNewHighWaterMark(n){if(n>=MAX_HWM){n=MAX_HWM}else{n--;n|=n>>>1;n|=n>>>2;n|=n>>>4;n|=n>>>8;n|=n>>>16;n++}return n}function howMuchToRead(n,state){if(n<=0||state.length===0&&state.ended)return 0;if(state.objectMode)return 1;if(n!==n){if(state.flowing&&state.length)return state.buffer.head.data.length;else return state.length}if(n>state.highWaterMark)state.highWaterMark=computeNewHighWaterMark(n);if(n<=state.length)return n;if(!state.ended){state.needReadable=true;return 0}return state.length}Readable.prototype.read=function(n){debug("read",n);n=parseInt(n,10);var state=this._readableState;var nOrig=n;if(n!==0)state.emittedReadable=false;if(n===0&&state.needReadable&&(state.length>=state.highWaterMark||state.ended)){debug("read: emitReadable",state.length,state.ended);if(state.length===0&&state.ended)endReadable(this);else emitReadable(this);return null}n=howMuchToRead(n,state);if(n===0&&state.ended){if(state.length===0)endReadable(this);return null}var doRead=state.needReadable;debug("need readable",doRead);if(state.length===0||state.length-n<state.highWaterMark){doRead=true;debug("length less than watermark",doRead)}if(state.ended||state.reading){doRead=false;debug("reading or ended",doRead)}else if(doRead){debug("do read");state.reading=true;state.sync=true;if(state.length===0)state.needReadable=true;this._read(state.highWaterMark);state.sync=false;if(!state.reading)n=howMuchToRead(nOrig,state)}var ret;if(n>0)ret=fromList(n,state);else ret=null;if(ret===null){state.needReadable=true;n=0}else{state.length-=n}if(state.length===0){if(!state.ended)state.needReadable=true;if(nOrig!==n&&state.ended)endReadable(this)}if(ret!==null)this.emit("data",ret);return ret};function chunkInvalid(state,chunk){var er=null;if(!Buffer.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==null&&chunk!==undefined&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}return er}function onEofChunk(stream,state){if(state.ended)return;if(state.decoder){var chunk=state.decoder.end();if(chunk&&chunk.length){state.buffer.push(chunk);state.length+=state.objectMode?1:chunk.length}}state.ended=true;emitReadable(stream)}function emitReadable(stream){var state=stream._readableState;state.needReadable=false;if(!state.emittedReadable){debug("emitReadable",state.flowing);state.emittedReadable=true;if(state.sync)processNextTick(emitReadable_,stream);else emitReadable_(stream)}}function emitReadable_(stream){debug("emit readable");stream.emit("readable");flow(stream)}function maybeReadMore(stream,state){if(!state.readingMore){state.readingMore=true;processNextTick(maybeReadMore_,stream,state)}}function maybeReadMore_(stream,state){var len=state.length;while(!state.reading&&!state.flowing&&!state.ended&&state.length<state.highWaterMark){debug("maybeReadMore read 0");stream.read(0);if(len===state.length)break;else len=state.length}state.readingMore=false}Readable.prototype._read=function(n){this.emit("error",new Error("not implemented"))};Readable.prototype.pipe=function(dest,pipeOpts){var src=this;var state=this._readableState;switch(state.pipesCount){case 0:state.pipes=dest;break;case 1:state.pipes=[state.pipes,dest];break;default:state.pipes.push(dest);break}state.pipesCount+=1;debug("pipe count=%d opts=%j",state.pipesCount,pipeOpts);var doEnd=(!pipeOpts||pipeOpts.end!==false)&&dest!==process.stdout&&dest!==process.stderr;var endFn=doEnd?onend:cleanup;if(state.endEmitted)processNextTick(endFn);else src.once("end",endFn);dest.on("unpipe",onunpipe);function onunpipe(readable){debug("onunpipe");if(readable===src){cleanup()}}function onend(){debug("onend");dest.end()}var ondrain=pipeOnDrain(src);dest.on("drain",ondrain);var cleanedUp=false;function cleanup(){debug("cleanup");dest.removeListener("close",onclose);dest.removeListener("finish",onfinish);dest.removeListener("drain",ondrain);dest.removeListener("error",onerror);dest.removeListener("unpipe",onunpipe);src.removeListener("end",onend);src.removeListener("end",cleanup);src.removeListener("data",ondata);cleanedUp=true;if(state.awaitDrain&&(!dest._writableState||dest._writableState.needDrain))ondrain()}var increasedAwaitDrain=false;src.on("data",ondata);function ondata(chunk){debug("ondata");increasedAwaitDrain=false;var ret=dest.write(chunk);if(false===ret&&!increasedAwaitDrain){if((state.pipesCount===1&&state.pipes===dest||state.pipesCount>1&&indexOf(state.pipes,dest)!==-1)&&!cleanedUp){debug("false write response, pause",src._readableState.awaitDrain);src._readableState.awaitDrain++;increasedAwaitDrain=true}src.pause()}}function onerror(er){debug("onerror",er);unpipe();dest.removeListener("error",onerror);if(EElistenerCount(dest,"error")===0)dest.emit("error",er)}prependListener(dest,"error",onerror);function onclose(){dest.removeListener("finish",onfinish);unpipe()}dest.once("close",onclose);function onfinish(){debug("onfinish");dest.removeListener("close",onclose);unpipe()}dest.once("finish",onfinish);function unpipe(){debug("unpipe");src.unpipe(dest)}dest.emit("pipe",src);if(!state.flowing){debug("pipe resume");src.resume()}return dest};function pipeOnDrain(src){return function(){var state=src._readableState;debug("pipeOnDrain",state.awaitDrain);if(state.awaitDrain)state.awaitDrain--;if(state.awaitDrain===0&&EElistenerCount(src,"data")){state.flowing=true;flow(src)}}}Readable.prototype.unpipe=function(dest){var state=this._readableState;if(state.pipesCount===0)return this;if(state.pipesCount===1){if(dest&&dest!==state.pipes)return this;if(!dest)dest=state.pipes;state.pipes=null;state.pipesCount=0;state.flowing=false;if(dest)dest.emit("unpipe",this);return this}if(!dest){var dests=state.pipes;var len=state.pipesCount;state.pipes=null;state.pipesCount=0;state.flowing=false;for(var _i=0;_i<len;_i++){dests[_i].emit("unpipe",this)}return this}var i=indexOf(state.pipes,dest);if(i===-1)return this;state.pipes.splice(i,1);state.pipesCount-=1;if(state.pipesCount===1)state.pipes=state.pipes[0];dest.emit("unpipe",this);return this};Readable.prototype.on=function(ev,fn){var res=Stream.prototype.on.call(this,ev,fn);if(ev==="data"){if(this._readableState.flowing!==false)this.resume()}else if(ev==="readable"){var state=this._readableState;if(!state.endEmitted&&!state.readableListening){state.readableListening=state.needReadable=true;state.emittedReadable=false;if(!state.reading){processNextTick(nReadingNextTick,this)}else if(state.length){emitReadable(this,state)}}}return res};Readable.prototype.addListener=Readable.prototype.on;function nReadingNextTick(self){debug("readable nexttick read 0");self.read(0)}Readable.prototype.resume=function(){var state=this._readableState;if(!state.flowing){debug("resume");state.flowing=true;resume(this,state)}return this};function resume(stream,state){if(!state.resumeScheduled){state.resumeScheduled=true;processNextTick(resume_,stream,state)}}function resume_(stream,state){if(!state.reading){debug("resume read 0");stream.read(0)}state.resumeScheduled=false;state.awaitDrain=0;stream.emit("resume");flow(stream);if(state.flowing&&!state.reading)stream.read(0)}Readable.prototype.pause=function(){debug("call pause flowing=%j",this._readableState.flowing);if(false!==this._readableState.flowing){debug("pause");this._readableState.flowing=false;this.emit("pause")}return this};function flow(stream){var state=stream._readableState;debug("flow",state.flowing);while(state.flowing&&stream.read()!==null){}}Readable.prototype.wrap=function(stream){var state=this._readableState;var paused=false;var self=this;stream.on("end",function(){debug("wrapped end");if(state.decoder&&!state.ended){var chunk=state.decoder.end();if(chunk&&chunk.length)self.push(chunk)}self.push(null)});stream.on("data",function(chunk){debug("wrapped data");if(state.decoder)chunk=state.decoder.write(chunk);if(state.objectMode&&(chunk===null||chunk===undefined))return;else if(!state.objectMode&&(!chunk||!chunk.length))return;var ret=self.push(chunk);if(!ret){paused=true;stream.pause()}});for(var i in stream){if(this[i]===undefined&&typeof stream[i]==="function"){this[i]=function(method){return function(){return stream[method].apply(stream,arguments)}}(i)}}var events=["error","close","destroy","pause","resume"];forEach(events,function(ev){stream.on(ev,self.emit.bind(self,ev))});self._read=function(n){debug("wrapped _read",n);if(paused){paused=false;stream.resume()}};return self};Readable._fromList=fromList;function fromList(n,state){if(state.length===0)return null;var ret;if(state.objectMode)ret=state.buffer.shift();else if(!n||n>=state.length){if(state.decoder)ret=state.buffer.join("");else if(state.buffer.length===1)ret=state.buffer.head.data;else ret=state.buffer.concat(state.length);state.buffer.clear()}else{ret=fromListPartial(n,state.buffer,state.decoder)}return ret}function fromListPartial(n,list,hasStrings){var ret;if(n<list.head.data.length){ret=list.head.data.slice(0,n);list.head.data=list.head.data.slice(n)}else if(n===list.head.data.length){ret=list.shift()}else{ret=hasStrings?copyFromBufferString(n,list):copyFromBuffer(n,list)}return ret}function copyFromBufferString(n,list){var p=list.head;var c=1;var ret=p.data;n-=ret.length;while(p=p.next){var str=p.data;var nb=n>str.length?str.length:n;if(nb===str.length)ret+=str;else ret+=str.slice(0,n);n-=nb;if(n===0){if(nb===str.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=str.slice(nb)}break}++c}list.length-=c;return ret}function copyFromBuffer(n,list){var ret=bufferShim.allocUnsafe(n);var p=list.head;var c=1;p.data.copy(ret);n-=p.data.length;while(p=p.next){var buf=p.data;var nb=n>buf.length?buf.length:n;buf.copy(ret,ret.length-n,0,nb);n-=nb;if(n===0){if(nb===buf.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=buf.slice(nb)}break}++c}list.length-=c;return ret}function endReadable(stream){var state=stream._readableState;if(state.length>0)throw new Error('"endReadable()" called on non-empty stream');if(!state.endEmitted){state.ended=true;processNextTick(endReadableNT,state,stream)}}function endReadableNT(state,stream){if(!state.endEmitted&&state.length===0){state.endEmitted=true;stream.readable=false;stream.emit("end")}}function forEach(xs,f){for(var i=0,l=xs.length;i<l;i++){f(xs[i],i)}}function indexOf(xs,x){for(var i=0,l=xs.length;i<l;i++){if(xs[i]===x)return i}return-1}}).call(this,require("_process"))},{"./_stream_duplex":44,"./internal/streams/BufferList":49,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,isarray:40,"process-nextick-args":41,"string_decoder/":56,util:3}],47:[function(require,module,exports){"use strict";module.exports=Transform;var Duplex=require("./_stream_duplex");var util=require("core-util-is");util.inherits=require("inherits");util.inherits(Transform,Duplex);function TransformState(stream){this.afterTransform=function(er,data){return afterTransform(stream,er,data)};this.needTransform=false;this.transforming=false;this.writecb=null;this.writechunk=null;this.writeencoding=null}function afterTransform(stream,er,data){var ts=stream._transformState;ts.transforming=false;var cb=ts.writecb;if(!cb)return stream.emit("error",new Error("no writecb in Transform class"));ts.writechunk=null;ts.writecb=null;if(data!==null&&data!==undefined)stream.push(data);cb(er);var rs=stream._readableState;rs.reading=false;if(rs.needReadable||rs.length<rs.highWaterMark){stream._read(rs.highWaterMark)}}function Transform(options){if(!(this instanceof Transform))return new Transform(options);Duplex.call(this,options);this._transformState=new TransformState(this);var stream=this;this._readableState.needReadable=true;this._readableState.sync=false;if(options){if(typeof options.transform==="function")this._transform=options.transform;if(typeof options.flush==="function")this._flush=options.flush}this.once("prefinish",function(){if(typeof this._flush==="function")this._flush(function(er){done(stream,er)});else done(stream)})}Transform.prototype.push=function(chunk,encoding){this._transformState.needTransform=false;return Duplex.prototype.push.call(this,chunk,encoding)};Transform.prototype._transform=function(chunk,encoding,cb){throw new Error("Not implemented")};Transform.prototype._write=function(chunk,encoding,cb){var ts=this._transformState;ts.writecb=cb;ts.writechunk=chunk;ts.writeencoding=encoding;if(!ts.transforming){var rs=this._readableState;if(ts.needTransform||rs.needReadable||rs.length<rs.highWaterMark)this._read(rs.highWaterMark)}};Transform.prototype._read=function(n){var ts=this._transformState;if(ts.writechunk!==null&&ts.writecb&&!ts.transforming){ts.transforming=true;this._transform(ts.writechunk,ts.writeencoding,ts.afterTransform)}else{ts.needTransform=true}};function done(stream,er){if(er)return stream.emit("error",er);var ws=stream._writableState;var ts=stream._transformState;if(ws.length)throw new Error("Calling transform done when ws.length != 0");if(ts.transforming)throw new Error("Calling transform done when still transforming");return stream.push(null)}},{"./_stream_duplex":44,"core-util-is":6,inherits:38}],48:[function(require,module,exports){(function(process){"use strict";module.exports=Writable;var processNextTick=require("process-nextick-args");var asyncWrite=!process.browser&&["v0.10","v0.9."].indexOf(process.version.slice(0,5))>-1?setImmediate:processNextTick;Writable.WritableState=WritableState;var util=require("core-util-is");util.inherits=require("inherits");var internalUtil={deprecate:require("util-deprecate")};var Stream;(function(){try{Stream=require("st"+"ream")}catch(_){}finally{if(!Stream)Stream=require("events").EventEmitter}})();var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");util.inherits(Writable,Stream);function nop(){}function WriteReq(chunk,encoding,cb){this.chunk=chunk;this.encoding=encoding;this.callback=cb;this.next=null}var Duplex;function WritableState(options,stream){Duplex=Duplex||require("./_stream_duplex");options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.writableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;var noDecode=options.decodeStrings===false;this.decodeStrings=!noDecode;this.defaultEncoding=options.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(er){onwrite(stream,er)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function writableStateGetBuffer(){var current=this.bufferedRequest;var out=[];while(current){out.push(current);current=current.next}return out};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:internalUtil.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer "+"instead.")})}catch(_){}})();var Duplex;function Writable(options){Duplex=Duplex||require("./_stream_duplex");if(!(this instanceof Writable)&&!(this instanceof Duplex))return new Writable(options);this._writableState=new WritableState(options,this);this.writable=true;if(options){if(typeof options.write==="function")this._write=options.write;if(typeof options.writev==="function")this._writev=options.writev}Stream.call(this)}Writable.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))};function writeAfterEnd(stream,cb){var er=new Error("write after end");stream.emit("error",er);processNextTick(cb,er)}function validChunk(stream,state,chunk,cb){var valid=true;var er=false;if(chunk===null){er=new TypeError("May not write null values to stream")}else if(!Buffer.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==undefined&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}if(er){stream.emit("error",er);processNextTick(cb,er);valid=false}return valid}Writable.prototype.write=function(chunk,encoding,cb){var state=this._writableState;var ret=false;if(typeof encoding==="function"){cb=encoding;encoding=null}if(Buffer.isBuffer(chunk))encoding="buffer";else if(!encoding)encoding=state.defaultEncoding;if(typeof cb!=="function")cb=nop;if(state.ended)writeAfterEnd(this,cb);else if(validChunk(this,state,chunk,cb)){ |
| state.pendingcb++;ret=writeOrBuffer(this,state,chunk,encoding,cb)}return ret};Writable.prototype.cork=function(){var state=this._writableState;state.corked++};Writable.prototype.uncork=function(){var state=this._writableState;if(state.corked){state.corked--;if(!state.writing&&!state.corked&&!state.finished&&!state.bufferProcessing&&state.bufferedRequest)clearBuffer(this,state)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(encoding){if(typeof encoding==="string")encoding=encoding.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((encoding+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+encoding);this._writableState.defaultEncoding=encoding;return this};function decodeChunk(state,chunk,encoding){if(!state.objectMode&&state.decodeStrings!==false&&typeof chunk==="string"){chunk=bufferShim.from(chunk,encoding)}return chunk}function writeOrBuffer(stream,state,chunk,encoding,cb){chunk=decodeChunk(state,chunk,encoding);if(Buffer.isBuffer(chunk))encoding="buffer";var len=state.objectMode?1:chunk.length;state.length+=len;var ret=state.length<state.highWaterMark;if(!ret)state.needDrain=true;if(state.writing||state.corked){var last=state.lastBufferedRequest;state.lastBufferedRequest=new WriteReq(chunk,encoding,cb);if(last){last.next=state.lastBufferedRequest}else{state.bufferedRequest=state.lastBufferedRequest}state.bufferedRequestCount+=1}else{doWrite(stream,state,false,len,chunk,encoding,cb)}return ret}function doWrite(stream,state,writev,len,chunk,encoding,cb){state.writelen=len;state.writecb=cb;state.writing=true;state.sync=true;if(writev)stream._writev(chunk,state.onwrite);else stream._write(chunk,encoding,state.onwrite);state.sync=false}function onwriteError(stream,state,sync,er,cb){--state.pendingcb;if(sync)processNextTick(cb,er);else cb(er);stream._writableState.errorEmitted=true;stream.emit("error",er)}function onwriteStateUpdate(state){state.writing=false;state.writecb=null;state.length-=state.writelen;state.writelen=0}function onwrite(stream,er){var state=stream._writableState;var sync=state.sync;var cb=state.writecb;onwriteStateUpdate(state);if(er)onwriteError(stream,state,sync,er,cb);else{var finished=needFinish(state);if(!finished&&!state.corked&&!state.bufferProcessing&&state.bufferedRequest){clearBuffer(stream,state)}if(sync){asyncWrite(afterWrite,stream,state,finished,cb)}else{afterWrite(stream,state,finished,cb)}}}function afterWrite(stream,state,finished,cb){if(!finished)onwriteDrain(stream,state);state.pendingcb--;cb();finishMaybe(stream,state)}function onwriteDrain(stream,state){if(state.length===0&&state.needDrain){state.needDrain=false;stream.emit("drain")}}function clearBuffer(stream,state){state.bufferProcessing=true;var entry=state.bufferedRequest;if(stream._writev&&entry&&entry.next){var l=state.bufferedRequestCount;var buffer=new Array(l);var holder=state.corkedRequestsFree;holder.entry=entry;var count=0;while(entry){buffer[count]=entry;entry=entry.next;count+=1}doWrite(stream,state,true,state.length,buffer,"",holder.finish);state.pendingcb++;state.lastBufferedRequest=null;if(holder.next){state.corkedRequestsFree=holder.next;holder.next=null}else{state.corkedRequestsFree=new CorkedRequest(state)}}else{while(entry){var chunk=entry.chunk;var encoding=entry.encoding;var cb=entry.callback;var len=state.objectMode?1:chunk.length;doWrite(stream,state,false,len,chunk,encoding,cb);entry=entry.next;if(state.writing){break}}if(entry===null)state.lastBufferedRequest=null}state.bufferedRequestCount=0;state.bufferedRequest=entry;state.bufferProcessing=false}Writable.prototype._write=function(chunk,encoding,cb){cb(new Error("not implemented"))};Writable.prototype._writev=null;Writable.prototype.end=function(chunk,encoding,cb){var state=this._writableState;if(typeof chunk==="function"){cb=chunk;chunk=null;encoding=null}else if(typeof encoding==="function"){cb=encoding;encoding=null}if(chunk!==null&&chunk!==undefined)this.write(chunk,encoding);if(state.corked){state.corked=1;this.uncork()}if(!state.ending&&!state.finished)endWritable(this,state,cb)};function needFinish(state){return state.ending&&state.length===0&&state.bufferedRequest===null&&!state.finished&&!state.writing}function prefinish(stream,state){if(!state.prefinished){state.prefinished=true;stream.emit("prefinish")}}function finishMaybe(stream,state){var need=needFinish(state);if(need){if(state.pendingcb===0){prefinish(stream,state);state.finished=true;stream.emit("finish")}else{prefinish(stream,state)}}return need}function endWritable(stream,state,cb){state.ending=true;finishMaybe(stream,state);if(cb){if(state.finished)processNextTick(cb);else stream.once("finish",cb)}state.ended=true;stream.writable=false}function CorkedRequest(state){var _this=this;this.next=null;this.entry=null;this.finish=function(err){var entry=_this.entry;_this.entry=null;while(entry){var cb=entry.callback;state.pendingcb--;cb(err);entry=entry.next}if(state.corkedRequestsFree){state.corkedRequestsFree.next=_this}else{state.corkedRequestsFree=_this}}}}).call(this,require("_process"))},{"./_stream_duplex":44,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,"process-nextick-args":41,"util-deprecate":57}],49:[function(require,module,exports){"use strict";var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");module.exports=BufferList;function BufferList(){this.head=null;this.tail=null;this.length=0}BufferList.prototype.push=function(v){var entry={data:v,next:null};if(this.length>0)this.tail.next=entry;else this.head=entry;this.tail=entry;++this.length};BufferList.prototype.unshift=function(v){var entry={data:v,next:this.head};if(this.length===0)this.tail=entry;this.head=entry;++this.length};BufferList.prototype.shift=function(){if(this.length===0)return;var ret=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return ret};BufferList.prototype.clear=function(){this.head=this.tail=null;this.length=0};BufferList.prototype.join=function(s){if(this.length===0)return"";var p=this.head;var ret=""+p.data;while(p=p.next){ret+=s+p.data}return ret};BufferList.prototype.concat=function(n){if(this.length===0)return bufferShim.alloc(0);if(this.length===1)return this.head.data;var ret=bufferShim.allocUnsafe(n>>>0);var p=this.head;var i=0;while(p){p.data.copy(ret,i);i+=p.data.length;p=p.next}return ret}},{buffer:5,"buffer-shims":4}],50:[function(require,module,exports){module.exports=require("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":45}],51:[function(require,module,exports){(function(process){var Stream=function(){try{return require("st"+"ream")}catch(_){}}();exports=module.exports=require("./lib/_stream_readable.js");exports.Stream=Stream||exports;exports.Readable=exports;exports.Writable=require("./lib/_stream_writable.js");exports.Duplex=require("./lib/_stream_duplex.js");exports.Transform=require("./lib/_stream_transform.js");exports.PassThrough=require("./lib/_stream_passthrough.js");if(!process.browser&&process.env.READABLE_STREAM==="disable"&&Stream){module.exports=Stream}}).call(this,require("_process"))},{"./lib/_stream_duplex.js":44,"./lib/_stream_passthrough.js":45,"./lib/_stream_readable.js":46,"./lib/_stream_transform.js":47,"./lib/_stream_writable.js":48,_process:42}],52:[function(require,module,exports){module.exports=require("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":47}],53:[function(require,module,exports){module.exports=require("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":48}],54:[function(require,module,exports){module.exports=function(string){return string.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")}},{}],55:[function(require,module,exports){module.exports=Stream;var EE=require("events").EventEmitter;var inherits=require("inherits");inherits(Stream,EE);Stream.Readable=require("readable-stream/readable.js");Stream.Writable=require("readable-stream/writable.js");Stream.Duplex=require("readable-stream/duplex.js");Stream.Transform=require("readable-stream/transform.js");Stream.PassThrough=require("readable-stream/passthrough.js");Stream.Stream=Stream;function Stream(){EE.call(this)}Stream.prototype.pipe=function(dest,options){var source=this;function ondata(chunk){if(dest.writable){if(false===dest.write(chunk)&&source.pause){source.pause()}}}source.on("data",ondata);function ondrain(){if(source.readable&&source.resume){source.resume()}}dest.on("drain",ondrain);if(!dest._isStdio&&(!options||options.end!==false)){source.on("end",onend);source.on("close",onclose)}var didOnEnd=false;function onend(){if(didOnEnd)return;didOnEnd=true;dest.end()}function onclose(){if(didOnEnd)return;didOnEnd=true;if(typeof dest.destroy==="function")dest.destroy()}function onerror(er){cleanup();if(EE.listenerCount(this,"error")===0){throw er}}source.on("error",onerror);dest.on("error",onerror);function cleanup(){source.removeListener("data",ondata);dest.removeListener("drain",ondrain);source.removeListener("end",onend);source.removeListener("close",onclose);source.removeListener("error",onerror);dest.removeListener("error",onerror);source.removeListener("end",cleanup);source.removeListener("close",cleanup);dest.removeListener("close",cleanup)}source.on("end",cleanup);source.on("close",cleanup);dest.on("close",cleanup);dest.emit("pipe",source);return dest}},{events:28,inherits:38,"readable-stream/duplex.js":43,"readable-stream/passthrough.js":50,"readable-stream/readable.js":51,"readable-stream/transform.js":52,"readable-stream/writable.js":53}],56:[function(require,module,exports){var Buffer=require("buffer").Buffer;var isBufferEncoding=Buffer.isEncoding||function(encoding){switch(encoding&&encoding.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function assertEncoding(encoding){if(encoding&&!isBufferEncoding(encoding)){throw new Error("Unknown encoding: "+encoding)}}var StringDecoder=exports.StringDecoder=function(encoding){this.encoding=(encoding||"utf8").toLowerCase().replace(/[-_]/,"");assertEncoding(encoding);switch(this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2;this.detectIncompleteChar=utf16DetectIncompleteChar;break;case"base64":this.surrogateSize=3;this.detectIncompleteChar=base64DetectIncompleteChar;break;default:this.write=passThroughWrite;return}this.charBuffer=new Buffer(6);this.charReceived=0;this.charLength=0};StringDecoder.prototype.write=function(buffer){var charStr="";while(this.charLength){var available=buffer.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:buffer.length;buffer.copy(this.charBuffer,this.charReceived,0,available);this.charReceived+=available;if(this.charReceived<this.charLength){return""}buffer=buffer.slice(available,buffer.length);charStr=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var charCode=charStr.charCodeAt(charStr.length-1);if(charCode>=55296&&charCode<=56319){this.charLength+=this.surrogateSize;charStr="";continue}this.charReceived=this.charLength=0;if(buffer.length===0){return charStr}break}this.detectIncompleteChar(buffer);var end=buffer.length;if(this.charLength){buffer.copy(this.charBuffer,0,buffer.length-this.charReceived,end);end-=this.charReceived}charStr+=buffer.toString(this.encoding,0,end);var end=charStr.length-1;var charCode=charStr.charCodeAt(end);if(charCode>=55296&&charCode<=56319){var size=this.surrogateSize;this.charLength+=size;this.charReceived+=size;this.charBuffer.copy(this.charBuffer,size,0,size);buffer.copy(this.charBuffer,0,0,size);return charStr.substring(0,end)}return charStr};StringDecoder.prototype.detectIncompleteChar=function(buffer){var i=buffer.length>=3?3:buffer.length;for(;i>0;i--){var c=buffer[buffer.length-i];if(i==1&&c>>5==6){this.charLength=2;break}if(i<=2&&c>>4==14){this.charLength=3;break}if(i<=3&&c>>3==30){this.charLength=4;break}}this.charReceived=i};StringDecoder.prototype.end=function(buffer){var res="";if(buffer&&buffer.length)res=this.write(buffer);if(this.charReceived){var cr=this.charReceived;var buf=this.charBuffer;var enc=this.encoding;res+=buf.slice(0,cr).toString(enc)}return res};function passThroughWrite(buffer){return buffer.toString(this.encoding)}function utf16DetectIncompleteChar(buffer){this.charReceived=buffer.length%2;this.charLength=this.charReceived?2:0}function base64DetectIncompleteChar(buffer){this.charReceived=buffer.length%3;this.charLength=this.charReceived?3:0}},{buffer:5}],57:[function(require,module,exports){(function(global){module.exports=deprecate;function deprecate(fn,msg){if(config("noDeprecation")){return fn}var warned=false;function deprecated(){if(!warned){if(config("throwDeprecation")){throw new Error(msg)}else if(config("traceDeprecation")){console.trace(msg)}else{console.warn(msg)}warned=true}return fn.apply(this,arguments)}return deprecated}function config(name){try{if(!global.localStorage)return false}catch(_){return false}var val=global.localStorage[name];if(null==val)return false;return String(val).toLowerCase()==="true"}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],58:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target}},{}]},{},[1])(1)}); |
| |
| /** |
| * swagger-client - swagger-client is a javascript client for use with swaggering APIs. |
| * @version v2.1.28 |
| * @link http://swagger.io |
| * @license Apache-2.0 |
| */ |
| (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SwaggerClient = f()}})(function(){var define,module,exports;return (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){ |
| 'use strict'; |
| |
| var auth = require('./lib/auth'); |
| var helpers = require('./lib/helpers'); |
| var SwaggerClient = require('./lib/client'); |
| var deprecationWrapper = function (url, options) { |
| helpers.log('This is deprecated, use "new SwaggerClient" instead.'); |
| |
| return new SwaggerClient(url, options); |
| }; |
| |
| /* Here for IE8 Support */ |
| if (!Array.prototype.indexOf) { |
| Array.prototype.indexOf = function(obj, start) { |
| for (var i = (start || 0), j = this.length; i < j; i++) { |
| if (this[i] === obj) { return i; } |
| } |
| return -1; |
| }; |
| } |
| |
| /* Here for IE8 Support */ |
| if (!String.prototype.trim) { |
| String.prototype.trim = function () { |
| return this.replace(/^\s+|\s+$/g, ''); |
| }; |
| } |
| |
| /* Here for node 10.x support */ |
| if (!String.prototype.endsWith) { |
| String.prototype.endsWith = function(suffix) { |
| return this.indexOf(suffix, this.length - suffix.length) !== -1; |
| }; |
| } |
| |
| module.exports = SwaggerClient; |
| |
| SwaggerClient.ApiKeyAuthorization = auth.ApiKeyAuthorization; |
| SwaggerClient.PasswordAuthorization = auth.PasswordAuthorization; |
| SwaggerClient.CookieAuthorization = auth.CookieAuthorization; |
| SwaggerClient.SwaggerApi = deprecationWrapper; |
| SwaggerClient.SwaggerClient = deprecationWrapper; |
| SwaggerClient.SchemaMarkup = require('./lib/schema-markup'); |
| |
| },{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(require,module,exports){ |
| 'use strict'; |
| |
| var helpers = require('./helpers'); |
| var btoa = require('btoa'); // jshint ignore:line |
| var CookieJar = require('cookiejar').CookieJar; |
| var _ = { |
| each: require('lodash-compat/collection/each'), |
| includes: require('lodash-compat/collection/includes'), |
| isObject: require('lodash-compat/lang/isObject'), |
| isArray: require('lodash-compat/lang/isArray') |
| }; |
| |
| /** |
| * SwaggerAuthorizations applies the correct authorization to an operation being executed |
| */ |
| var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function (authz) { |
| this.authz = authz || {}; |
| }; |
| |
| /** |
| * Add auths to the hash |
| * Will overwrite any existing |
| * |
| */ |
| SwaggerAuthorizations.prototype.add = function (name, auth) { |
| if(_.isObject(name)) { |
| for (var key in name) { |
| this.authz[key] = name[key]; |
| } |
| } else if(typeof name === 'string' ){ |
| this.authz[name] = auth; |
| } |
| |
| return auth; |
| }; |
| |
| SwaggerAuthorizations.prototype.remove = function (name) { |
| return delete this.authz[name]; |
| }; |
| |
| SwaggerAuthorizations.prototype.apply = function (obj, securities) { |
| var status = true; |
| var applyAll = !securities; |
| var flattenedSecurities = []; |
| |
| // favor the object-level authorizations over global |
| var authz = obj.clientAuthorizations || this.authz; |
| |
| // Securities could be [ {} ] |
| _.each(securities, function (obj, key) { |
| |
| // Make sure we account for securities being [ str ] |
| if(typeof key === 'string') { |
| flattenedSecurities.push(key); |
| } |
| |
| // Flatten keys in to our array |
| _.each(obj, function (val, key) { |
| flattenedSecurities.push(key); |
| }); |
| }); |
| |
| _.each(authz, function (auth, authName) { |
| if(applyAll || _.includes(flattenedSecurities, authName)) { |
| var newStatus = auth.apply(obj); |
| status = status && !!newStatus; // logical ORs regarding status |
| } |
| }); |
| |
| return status; |
| }; |
| |
| /** |
| * ApiKeyAuthorization allows a query param or header to be injected |
| */ |
| var ApiKeyAuthorization = module.exports.ApiKeyAuthorization = function (name, value, type) { |
| this.name = name; |
| this.value = value; |
| this.type = type; |
| }; |
| |
| ApiKeyAuthorization.prototype.apply = function (obj) { |
| if (this.type === 'query') { |
| // see if already applied. If so, don't do it again |
| |
| var qp; |
| if (obj.url.indexOf('?') > 0) { |
| qp = obj.url.substring(obj.url.indexOf('?') + 1); |
| var parts = qp.split('&'); |
| if(parts && parts.length > 0) { |
| for(var i = 0; i < parts.length; i++) { |
| var kv = parts[i].split('='); |
| if(kv && kv.length > 0) { |
| if (kv[0] === this.name) { |
| // skip it |
| return false; |
| } |
| } |
| } |
| } |
| } |
| |
| if (obj.url.indexOf('?') > 0) { |
| obj.url = obj.url + '&' + this.name + '=' + this.value; |
| } else { |
| obj.url = obj.url + '?' + this.name + '=' + this.value; |
| } |
| |
| return true; |
| } else if (this.type === 'header') { |
| if(typeof obj.headers[this.name] === 'undefined') { |
| obj.headers[this.name] = this.value; |
| } |
| |
| return true; |
| } |
| }; |
| |
| var CookieAuthorization = module.exports.CookieAuthorization = function (cookie) { |
| this.cookie = cookie; |
| }; |
| |
| CookieAuthorization.prototype.apply = function (obj) { |
| obj.cookieJar = obj.cookieJar || new CookieJar(); |
| obj.cookieJar.setCookie(this.cookie); |
| |
| return true; |
| }; |
| |
| /** |
| * Password Authorization is a basic auth implementation |
| */ |
| var PasswordAuthorization = module.exports.PasswordAuthorization = function (username, password) { |
| if (arguments.length === 3) { |
| helpers.log('PasswordAuthorization: the \'name\' argument has been removed, pass only username and password'); |
| username = arguments[1]; |
| password = arguments[2]; |
| } |
| this.username = username; |
| this.password = password; |
| }; |
| |
| PasswordAuthorization.prototype.apply = function (obj) { |
| if(typeof obj.headers.Authorization === 'undefined') { |
| obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password); |
| } |
| |
| return true; |
| }; |
| |
| },{"./helpers":4,"btoa":13,"cookiejar":18,"lodash-compat/collection/each":52,"lodash-compat/collection/includes":55,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144}],3:[function(require,module,exports){ |
| 'use strict'; |
| |
| var _ = { |
| bind: require('lodash-compat/function/bind'), |
| cloneDeep: require('lodash-compat/lang/cloneDeep'), |
| find: require('lodash-compat/collection/find'), |
| forEach: require('lodash-compat/collection/forEach'), |
| indexOf: require('lodash-compat/array/indexOf'), |
| isArray: require('lodash-compat/lang/isArray'), |
| isObject: require('lodash-compat/lang/isObject'), |
| isFunction: require('lodash-compat/lang/isFunction'), |
| isPlainObject: require('lodash-compat/lang/isPlainObject'), |
| isUndefined: require('lodash-compat/lang/isUndefined') |
| }; |
| var auth = require('./auth'); |
| var helpers = require('./helpers'); |
| var Model = require('./types/model'); |
| var Operation = require('./types/operation'); |
| var OperationGroup = require('./types/operationGroup'); |
| var Resolver = require('./resolver'); |
| var SwaggerHttp = require('./http'); |
| var SwaggerSpecConverter = require('./spec-converter'); |
| var Q = require('q'); |
| |
| // We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the |
| // following usage: 'client.{tagName}' |
| var reservedClientTags = [ |
| 'apis', |
| 'authorizationScheme', |
| 'authorizations', |
| 'basePath', |
| 'build', |
| 'buildFrom1_1Spec', |
| 'buildFrom1_2Spec', |
| 'buildFromSpec', |
| 'clientAuthorizations', |
| 'convertInfo', |
| 'debug', |
| 'defaultErrorCallback', |
| 'defaultSuccessCallback', |
| 'enableCookies', |
| 'fail', |
| 'failure', |
| 'finish', |
| 'help', |
| 'host', |
| 'idFromOp', |
| 'info', |
| 'initialize', |
| 'isBuilt', |
| 'isValid', |
| 'modelPropertyMacro', |
| 'models', |
| 'modelsArray', |
| 'options', |
| 'parameterMacro', |
| 'parseUri', |
| 'progress', |
| 'resourceCount', |
| 'sampleModels', |
| 'selfReflect', |
| 'setConsolidatedModels', |
| 'spec', |
| 'supportedSubmitMethods', |
| 'swaggerRequestHeaders', |
| 'tagFromLabel', |
| 'title', |
| 'url', |
| 'useJQuery', |
| 'jqueryAjaxCache' |
| ]; |
| // We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the |
| // following usage: 'client.apis.{tagName}' |
| var reservedApiTags = [ |
| 'apis', |
| 'asCurl', |
| 'description', |
| 'externalDocs', |
| 'help', |
| 'label', |
| 'name', |
| 'operation', |
| 'operations', |
| 'operationsArray', |
| 'path', |
| 'tag' |
| ]; |
| var supportedOperationMethods = ['delete', 'get', 'head', 'options', 'patch', 'post', 'put']; |
| var SwaggerClient = module.exports = function (url, options) { |
| this.authorizations = null; |
| this.authorizationScheme = null; |
| this.basePath = null; |
| this.debug = false; |
| this.enableCookies = false; |
| this.info = null; |
| this.isBuilt = false; |
| this.isValid = false; |
| this.modelsArray = []; |
| this.resourceCount = 0; |
| this.url = null; |
| this.useJQuery = false; |
| this.jqueryAjaxCache = false; |
| this.swaggerObject = {}; |
| this.deferredClient = undefined; |
| |
| this.clientAuthorizations = new auth.SwaggerAuthorizations(); |
| |
| if (typeof url !== 'undefined') { |
| return this.initialize(url, options); |
| } else { |
| return this; |
| } |
| }; |
| |
| SwaggerClient.prototype.initialize = function (url, options) { |
| this.models = {}; |
| this.sampleModels = {}; |
| |
| if (typeof url === 'string') { |
| this.url = url; |
| } else if (_.isObject(url)) { |
| options = url; |
| this.url = options.url; |
| } |
| |
| if(this.url && this.url.indexOf('http:') === -1 && this.url.indexOf('https:') === -1) { |
| // no protocol, so we can only use window if it exists |
| if(typeof(window) !== 'undefined' && window && window.location) { |
| this.url = window.location.origin + this.url; |
| } |
| } |
| |
| options = options || {}; |
| this.clientAuthorizations.add(options.authorizations); |
| this.swaggerRequestHeaders = options.swaggerRequestHeaders || 'application/json;charset=utf-8,*/*'; |
| this.defaultSuccessCallback = options.defaultSuccessCallback || null; |
| this.defaultErrorCallback = options.defaultErrorCallback || null; |
| this.modelPropertyMacro = options.modelPropertyMacro || null; |
| this.connectionAgent = options.connectionAgent || null; |
| this.parameterMacro = options.parameterMacro || null; |
| this.usePromise = options.usePromise || null; |
| |
| // operation request timeout default |
| this.timeout = options.timeout || null; |
| // default to request timeout when not specified |
| this.fetchSpecTimeout = typeof options.fetchSpecTimeout !== 'undefined' ? |
| options.fetchSpecTimeout : options.timeout || null; |
| |
| if(this.usePromise) { |
| this.deferredClient = Q.defer(); |
| } |
| |
| if (typeof options.success === 'function') { |
| this.success = options.success; |
| } |
| if (options.useJQuery) { |
| this.useJQuery = options.useJQuery; |
| } |
| |
| if (options.jqueryAjaxCache) { |
| this.jqueryAjaxCache = options.jqueryAjaxCache; |
| } |
| |
| if (options.enableCookies) { |
| this.enableCookies = options.enableCookies; |
| } |
| |
| this.options = options || {}; |
| |
| // maybe don't need this? |
| this.options.timeout = this.timeout; |
| this.options.fetchSpecTimeout = this.fetchSpecTimeout; |
| |
| this.supportedSubmitMethods = options.supportedSubmitMethods || []; |
| this.failure = options.failure || function (err) { throw err; }; |
| this.progress = options.progress || function () {}; |
| this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document |
| |
| if (options.scheme) { |
| this.scheme = options.scheme; |
| } |
| |
| if (this.usePromise || typeof options.success === 'function') { |
| this.ready = true; |
| return this.build(); |
| } |
| }; |
| |
| SwaggerClient.prototype.build = function (mock) { |
| if (this.isBuilt) { |
| return this; |
| } |
| |
| var self = this; |
| |
| if (this.spec) { |
| this.progress('fetching resource list; Please wait.'); |
| } else { |
| this.progress('fetching resource list: ' + this.url + '; Please wait.'); |
| } |
| |
| var obj = { |
| useJQuery: this.useJQuery, |
| jqueryAjaxCache: this.jqueryAjaxCache, |
| connectionAgent: this.connectionAgent, |
| enableCookies: this.enableCookies, |
| url: this.url, |
| method: 'get', |
| headers: { |
| accept: this.swaggerRequestHeaders |
| }, |
| on: { |
| error: function (response) { |
| if (self.url.substring(0, 4) !== 'http') { |
| return self.fail('Please specify the protocol for ' + self.url); |
| } else if (response.errObj && (response.errObj.code === 'ECONNABORTED' || response.errObj.message.indexOf('timeout') !== -1)) { |
| return self.fail('Request timed out after ' + self.fetchSpecTimeout + 'ms'); |
| } else if (response.status === 0) { |
| return self.fail('Can\'t read from server. It may not have the appropriate access-control-origin settings.'); |
| } else if (response.status === 404) { |
| return self.fail('Can\'t read swagger JSON from ' + self.url); |
| } else { |
| return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url); |
| } |
| }, |
| response: function (resp) { |
| |
| var responseObj = resp.obj; |
| if(!responseObj) { |
| return self.fail('failed to parse JSON/YAML response'); |
| } |
| |
| self.swaggerVersion = responseObj.swaggerVersion; |
| self.swaggerObject = responseObj; |
| |
| if (responseObj.swagger && parseInt(responseObj.swagger) === 2) { |
| self.swaggerVersion = responseObj.swagger; |
| |
| new Resolver().resolve(responseObj, self.url, self.buildFromSpec, self); |
| |
| self.isValid = true; |
| } else { |
| var converter = new SwaggerSpecConverter(); |
| self.oldSwaggerObject = self.swaggerObject; |
| |
| converter.setDocumentationLocation(self.url); |
| converter.convert(responseObj, self.clientAuthorizations, self.options, function(spec) { |
| self.swaggerObject = spec; |
| new Resolver().resolve(spec, self.url, self.buildFromSpec, self); |
| self.isValid = true; |
| }); |
| } |
| } |
| } |
| }; |
| |
| // only set timeout when specified |
| if (this.fetchSpecTimeout) { |
| obj.timeout = this.fetchSpecTimeout; |
| } |
| |
| if (this.spec) { |
| self.swaggerObject = this.spec; |
| setTimeout(function () { |
| new Resolver().resolve(self.spec, self.url, self.buildFromSpec, self); |
| }, 10); |
| } else { |
| this.clientAuthorizations.apply(obj); |
| |
| if (mock) { |
| return obj; |
| } |
| |
| new SwaggerHttp().execute(obj, this.options); |
| } |
| |
| return (this.usePromise) ? this.deferredClient.promise : this; |
| }; |
| |
| SwaggerClient.prototype.buildFromSpec = function (response) { |
| if (this.isBuilt) { |
| return this; |
| } |
| |
| this.apis = {}; |
| this.apisArray = []; |
| this.basePath = response.basePath || ''; |
| this.consumes = response.consumes; |
| this.host = response.host || ''; |
| this.info = response.info || {}; |
| this.produces = response.produces; |
| this.schemes = response.schemes || []; |
| this.securityDefinitions = _.cloneDeep(response.securityDefinitions); |
| this.security = response.security; |
| this.title = response.title || ''; |
| |
| var key, definedTags = {}, k, location, self = this, i; |
| |
| if (response.externalDocs) { |
| this.externalDocs = response.externalDocs; |
| } |
| |
| // legacy support |
| this.authSchemes = this.securityDefinitions; |
| |
| if(this.securityDefinitions) { |
| for(key in this.securityDefinitions) { |
| var securityDefinition = this.securityDefinitions[key]; |
| securityDefinition.vendorExtensions = {}; |
| for(var ext in securityDefinition) { |
| helpers.extractExtensions(ext, securityDefinition); |
| if (ext === 'scopes') { |
| var scopes = securityDefinition[ext]; |
| if(typeof scopes === 'object') { |
| scopes.vendorExtensions = {}; |
| for (var s in scopes) { |
| helpers.extractExtensions(s, scopes); |
| if(s.indexOf('x-') === 0) { |
| delete scopes[s]; |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| if (Array.isArray(response.tags)) { |
| definedTags = {}; |
| |
| for (k = 0; k < response.tags.length; k++) { |
| var t = _.cloneDeep(response.tags[k]); |
| definedTags[t.name] = t; |
| for(i in t) { |
| if(i === 'externalDocs' && typeof t[i] === 'object') { |
| for(var j in t[i]) { |
| helpers.extractExtensions(j, t[i]); |
| } |
| } |
| helpers.extractExtensions(i, t); |
| } |
| } |
| } |
| |
| |
| if (typeof this.url === 'string') { |
| location = this.parseUri(this.url); |
| if (typeof this.scheme === 'undefined' && typeof this.schemes === 'undefined' || this.schemes.length === 0) { |
| if(typeof window !== 'undefined') { |
| // use the window scheme |
| this.scheme = window.location.protocol.replace(':',''); |
| } |
| else { |
| this.scheme = location.scheme || 'http'; |
| } |
| } else if (typeof window !== 'undefined' && window.location.protocol.indexOf('chrome-extension') === 0) { |
| // if it is chrome swagger ui extension scheme then let swagger doc url scheme decide the protocol |
| this.scheme = location.scheme; |
| } else if (typeof this.scheme === 'undefined') { |
| if(typeof window !== 'undefined') { |
| var scheme = window.location.protocol.replace(':',''); |
| if(scheme === 'https' && this.schemes.indexOf(scheme) === -1) { |
| // can't call http from https served page in a browser! |
| helpers.log('Cannot call a http server from https inside a browser!'); |
| this.scheme = 'http'; |
| } |
| else if(this.schemes.indexOf(scheme) !== -1) { |
| this.scheme = scheme; |
| } |
| else { |
| if(this.schemes.indexOf('https') !== -1) { |
| this.scheme = 'https'; |
| } |
| else { |
| this.scheme = 'http'; |
| } |
| } |
| } |
| else { |
| this.scheme = this.schemes[0] || location.scheme; |
| } |
| } |
| |
| if (typeof this.host === 'undefined' || this.host === '') { |
| this.host = location.host; |
| |
| if (location.port) { |
| this.host = this.host + ':' + location.port; |
| } |
| } |
| } |
| else { |
| if (typeof this.schemes === 'undefined' || this.schemes.length === 0) { |
| this.scheme = 'http'; |
| } |
| else if (typeof this.scheme === 'undefined') { |
| this.scheme = this.schemes[0]; |
| } |
| } |
| |
| this.definitions = response.definitions; |
| |
| for (key in this.definitions) { |
| var model = new Model(key, this.definitions[key], this.models, this.modelPropertyMacro); |
| |
| if (model) { |
| this.models[key] = model; |
| } |
| } |
| |
| // get paths, create functions for each operationId |
| |
| // Bind help to 'client.apis' |
| self.apis.help = _.bind(self.help, self); |
| |
| _.forEach(response.paths, function (pathObj, path) { |
| // Only process a path if it's an object |
| if (!_.isPlainObject(pathObj)) { |
| return; |
| } |
| |
| _.forEach(supportedOperationMethods, function (method) { |
| var operation = pathObj[method]; |
| |
| if (_.isUndefined(operation)) { |
| // Operation does not exist |
| return; |
| } else if (!_.isPlainObject(operation)) { |
| // Operation exists but it is not an Operation Object. Since this is invalid, log it. |
| helpers.log('The \'' + method + '\' operation for \'' + path + '\' path is not an Operation Object'); |
| |
| return; |
| } |
| |
| var tags = operation.tags; |
| |
| if (_.isUndefined(tags) || !_.isArray(tags) || tags.length === 0) { |
| tags = operation.tags = [ 'default' ]; |
| } |
| |
| var operationId = self.idFromOp(path, method, operation); |
| |
| var operationObject = new Operation(self, |
| operation.scheme, |
| operationId, |
| method, |
| path, |
| operation, |
| self.definitions, |
| self.models, |
| self.clientAuthorizations); |
| |
| operationObject.connectionAgent = self.connectionAgent; |
| operationObject.vendorExtensions = {}; |
| for(i in operation) { |
| helpers.extractExtensions(i, operationObject, operation[i]); |
| } |
| operationObject.externalDocs = operation.externalDocs; |
| if(operationObject.externalDocs) { |
| operationObject.externalDocs = _.cloneDeep(operationObject.externalDocs); |
| operationObject.externalDocs.vendorExtensions = {}; |
| for(i in operationObject.externalDocs) { |
| helpers.extractExtensions(i, operationObject.externalDocs); |
| } |
| } |
| |
| // bind self operation's execute command to the api |
| _.forEach(tags, function (tag) { |
| var clientProperty = _.indexOf(reservedClientTags, tag) > -1 ? '_' + tag : tag; |
| var apiProperty = _.indexOf(reservedApiTags, tag) > -1 ? '_' + tag : tag; |
| var operationGroup = self[clientProperty]; |
| |
| if (clientProperty !== tag) { |
| helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name. Use \'client.' + |
| clientProperty + '\' or \'client.apis.' + tag + '\' instead of \'client.' + tag + '\'.'); |
| } |
| |
| if (apiProperty !== tag) { |
| helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name. Use ' + |
| '\'client.apis.' + apiProperty + '\' instead of \'client.apis.' + tag + '\'.'); |
| } |
| |
| if (_.indexOf(reservedApiTags, operationId) > -1) { |
| helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' + |
| 'function/property name. Use \'client.apis.' + apiProperty + '._' + operationId + |
| '\' instead of \'client.apis.' + apiProperty + '.' + operationId + '\'.'); |
| |
| operationId = '_' + operationId; |
| operationObject.nickname = operationId; // So 'client.apis.[tag].operationId.help() works properly |
| } |
| |
| if (_.isUndefined(operationGroup)) { |
| operationGroup = self[clientProperty] = self.apis[apiProperty] = {}; |
| |
| operationGroup.operations = {}; |
| operationGroup.label = apiProperty; |
| operationGroup.apis = {}; |
| |
| var tagDef = definedTags[tag]; |
| |
| if (!_.isUndefined(tagDef)) { |
| operationGroup.description = tagDef.description; |
| operationGroup.externalDocs = tagDef.externalDocs; |
| operationGroup.vendorExtensions = tagDef.vendorExtensions; |
| } |
| |
| self[clientProperty].help = _.bind(self.help, operationGroup); |
| self.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject)); |
| } |
| |
| operationId = self.makeUniqueOperationId(operationId, self.apis[apiProperty]); |
| |
| // Bind tag help |
| if (!_.isFunction(operationGroup.help)) { |
| operationGroup.help = _.bind(self.help, operationGroup); |
| } |
| |
| // bind to the apis object |
| self.apis[apiProperty][operationId] = operationGroup[operationId] = _.bind(operationObject.execute, |
| operationObject); |
| self.apis[apiProperty][operationId].help = operationGroup[operationId].help = _.bind(operationObject.help, |
| operationObject); |
| self.apis[apiProperty][operationId].asCurl = operationGroup[operationId].asCurl = _.bind(operationObject.asCurl, |
| operationObject); |
| |
| operationGroup.apis[operationId] = operationGroup.operations[operationId] = operationObject; |
| |
| // legacy UI feature |
| var api = _.find(self.apisArray, function (api) { |
| return api.tag === tag; |
| }); |
| |
| if (api) { |
| api.operationsArray.push(operationObject); |
| } |
| }); |
| }); |
| }); |
| |
| // sort the apisArray according to the tags |
| var sortedApis = []; |
| _.forEach(Object.keys(definedTags), function (tag) { |
| var pos; |
| for(pos in self.apisArray) { |
| var _api = self.apisArray[pos]; |
| if(_api && tag === _api.name) { |
| sortedApis.push(_api); |
| self.apisArray[pos] = null; |
| } |
| } |
| }); |
| // add anything left |
| _.forEach(self.apisArray, function (api) { |
| if(api) { |
| sortedApis.push(api); |
| } |
| }); |
| self.apisArray = sortedApis; |
| |
| _.forEach(response.definitions, function (definitionObj, definition) { |
| definitionObj.id = definition.toLowerCase(); |
| definitionObj.name = definition; |
| self.modelsArray.push(definitionObj); |
| }); |
| |
| this.isBuilt = true; |
| |
| if (this.usePromise) { |
| this.isValid = true; |
| this.isBuilt = true; |
| this.deferredClient.resolve(this); |
| |
| return this.deferredClient.promise; |
| } |
| |
| if (this.success) { |
| this.success(); |
| } |
| |
| return this; |
| }; |
| |
| SwaggerClient.prototype.makeUniqueOperationId = function(operationId, api) { |
| var count = 0; |
| var name = operationId; |
| |
| // make unique across this operation group |
| while(true) { |
| var matched = false; |
| _.forEach(api.operations, function (operation) { |
| if(operation.nickname === name) { |
| matched = true; |
| } |
| }); |
| if(!matched) { |
| return name; |
| } |
| name = operationId + '_' + count; |
| count ++; |
| } |
| |
| return operationId; |
| }; |
| |
| SwaggerClient.prototype.parseUri = function (uri) { |
| var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/; |
| var parts = urlParseRE.exec(uri); |
| |
| return { |
| scheme: parts[4] ? parts[4].replace(':','') : undefined, |
| host: parts[11], |
| port: parts[12], |
| path: parts[15] |
| }; |
| }; |
| |
| SwaggerClient.prototype.help = function (dontPrint) { |
| var output = ''; |
| |
| if (this instanceof SwaggerClient) { |
| _.forEach(this.apis, function (api, name) { |
| if (_.isPlainObject(api)) { |
| output += 'operations for the \'' + name + '\' tag\n'; |
| |
| _.forEach(api.operations, function (operation, name) { |
| output += ' * ' + name + ': ' + operation.summary + '\n'; |
| }); |
| } |
| }); |
| } else if (this instanceof OperationGroup || _.isPlainObject(this)) { |
| output += 'operations for the \'' + this.label + '\' tag\n'; |
| |
| _.forEach(this.apis, function (operation, name) { |
| output += ' * ' + name + ': ' + operation.summary + '\n'; |
| }); |
| } |
| |
| if (dontPrint) { |
| return output; |
| } else { |
| helpers.log(output); |
| |
| return output; |
| } |
| }; |
| |
| SwaggerClient.prototype.tagFromLabel = function (label) { |
| return label; |
| }; |
| |
| SwaggerClient.prototype.idFromOp = function (path, httpMethod, op) { |
| if(!op || !op.operationId) { |
| op = op || {}; |
| op.operationId = httpMethod + '_' + path; |
| } |
| var opId = op.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_') || (path.substring(1) + '_' + httpMethod); |
| |
| opId = opId.replace(/((_){2,})/g, '_'); |
| opId = opId.replace(/^(_)*/g, ''); |
| opId = opId.replace(/([_])*$/g, ''); |
| |
| return opId; |
| }; |
| |
| SwaggerClient.prototype.setHost = function (host) { |
| this.host = host; |
| |
| if(this.apis) { |
| _.forEach(this.apis, function(api) { |
| if(api.operations) { |
| _.forEach(api.operations, function(operation) { |
| operation.host = host; |
| }); |
| } |
| }); |
| } |
| }; |
| |
| SwaggerClient.prototype.setBasePath = function (basePath) { |
| this.basePath = basePath; |
| |
| if(this.apis) { |
| _.forEach(this.apis, function(api) { |
| if(api.operations) { |
| _.forEach(api.operations, function(operation) { |
| operation.basePath = basePath; |
| }); |
| } |
| }); |
| } |
| }; |
| |
| SwaggerClient.prototype.setSchemes = function (schemes) { |
| this.schemes = schemes; |
| |
| if(schemes && schemes.length > 0) { |
| if(this.apis) { |
| _.forEach(this.apis, function (api) { |
| if (api.operations) { |
| _.forEach(api.operations, function (operation) { |
| operation.scheme = schemes[0]; |
| }); |
| } |
| }); |
| } |
| } |
| }; |
| |
| SwaggerClient.prototype.fail = function (message) { |
| if (this.usePromise) { |
| this.deferredClient.reject(message); |
| return this.deferredClient.promise; |
| } else { |
| if (this.failure) { |
| this.failure(message); |
| } |
| else { |
| this.failure(message); |
| } |
| } |
| }; |
| |
| },{"./auth":2,"./helpers":4,"./http":5,"./resolver":6,"./spec-converter":8,"./types/model":9,"./types/operation":10,"./types/operationGroup":11,"lodash-compat/array/indexOf":49,"lodash-compat/collection/find":53,"lodash-compat/collection/forEach":54,"lodash-compat/function/bind":58,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isFunction":142,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,"q":157}],4:[function(require,module,exports){ |
| (function (process){ |
| 'use strict'; |
| |
| var _ = { |
| isPlainObject: require('lodash-compat/lang/isPlainObject'), |
| indexOf: require('lodash-compat/array/indexOf') |
| }; |
| |
| module.exports.__bind = function (fn, me) { |
| return function(){ |
| return fn.apply(me, arguments); |
| }; |
| }; |
| |
| var log = module.exports.log = function() { |
| // Only log if available and we're not testing |
| if (console && process.env.NODE_ENV !== 'test') { |
| console.log(Array.prototype.slice.call(arguments)[0]); |
| } |
| }; |
| |
| module.exports.fail = function (message) { |
| log(message); |
| }; |
| |
| module.exports.optionHtml = function (label, value) { |
| return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>'; |
| }; |
| |
| var resolveSchema = module.exports.resolveSchema = function (schema) { |
| if (_.isPlainObject(schema.schema)) { |
| schema = resolveSchema(schema.schema); |
| } |
| |
| return schema; |
| }; |
| |
| module.exports.simpleRef = function (name) { |
| if (typeof name === 'undefined') { |
| return null; |
| } |
| |
| if (name.indexOf('#/definitions/') === 0) { |
| return name.substring('#/definitions/'.length); |
| } else { |
| return name; |
| } |
| }; |
| |
| /** |
| * helper to remove extensions and add them to an object |
| * |
| * @param keyname |
| * @param obj |
| */ |
| module.exports.extractExtensions = function (keyname, obj, value) { |
| if(!keyname || !obj) { |
| return; |
| } |
| |
| if (typeof keyname === 'string' && keyname.indexOf('x-') === 0) { |
| obj.vendorExtensions = obj.vendorExtensions || {}; |
| if(value) { |
| obj.vendorExtensions[keyname] = value; |
| } |
| else { |
| obj.vendorExtensions[keyname] = obj[keyname]; |
| } |
| } |
| }; |
| }).call(this,require('_process')) |
| |
| },{"_process":12,"lodash-compat/array/indexOf":49,"lodash-compat/lang/isPlainObject":145}],5:[function(require,module,exports){ |
| (function (Buffer){ |
| 'use strict'; |
| |
| var helpers = require('./helpers'); |
| var request = require('superagent'); |
| var jsyaml = require('js-yaml'); |
| var _ = { |
| isObject: require('lodash-compat/lang/isObject'), |
| keys: require('lodash-compat/object/keys') |
| }; |
| |
| /* |
| * JQueryHttpClient is a light-weight, node or browser HTTP client |
| */ |
| var JQueryHttpClient = function () { |
| this.type = 'JQueryHttpClient'; |
| }; |
| |
| /* |
| * SuperagentHttpClient is a light-weight, node or browser HTTP client |
| */ |
| var SuperagentHttpClient = function () { |
| this.type = 'SuperagentHttpClient'; |
| }; |
| |
| /** |
| * SwaggerHttp is a wrapper for executing requests |
| */ |
| var SwaggerHttp = module.exports = function () {}; |
| |
| SwaggerHttp.prototype.execute = function (obj, opts) { |
| var client; |
| |
| if(opts && opts.client) { |
| client = opts.client; |
| } |
| else { |
| client = new SuperagentHttpClient(opts); |
| } |
| client.opts = opts || {}; |
| |
| if (opts && opts.requestAgent) { |
| request = opts.requestAgent; |
| } |
| |
| // legacy support |
| var hasJQuery = false; |
| if(typeof window !== 'undefined') { |
| if(typeof window.jQuery !== 'undefined') { |
| hasJQuery = true; |
| } |
| } |
| // OPTIONS support |
| if(obj.method.toLowerCase() === 'options' && client.type === 'SuperagentHttpClient') { |
| log('forcing jQuery as OPTIONS are not supported by SuperAgent'); |
| obj.useJQuery = true; |
| } |
| if(this.isInternetExplorer() && (obj.useJQuery === false || !hasJQuery )) { |
| throw new Error('Unsupported configuration! JQuery is required but not available'); |
| } |
| if ((obj && obj.useJQuery === true) || this.isInternetExplorer() && hasJQuery) { |
| client = new JQueryHttpClient(opts); |
| } |
| |
| var success = obj.on.response; |
| var error = obj.on.error; |
| |
| var requestInterceptor = function(data) { |
| if(opts && opts.requestInterceptor) { |
| data = opts.requestInterceptor.apply(data); |
| } |
| return data; |
| }; |
| |
| var responseInterceptor = function(data) { |
| if(opts && opts.responseInterceptor) { |
| data = opts.responseInterceptor.apply(data, [obj]); |
| } |
| return success(data); |
| }; |
| |
| var errorInterceptor = function(data) { |
| if(opts && opts.responseInterceptor) { |
| data = opts.responseInterceptor.apply(data, [obj]); |
| } |
| error(data); |
| }; |
| |
| obj.on.error = function(data) { |
| errorInterceptor(data); |
| }; |
| |
| obj.on.response = function(data) { |
| if(data && data.status >= 400) { |
| errorInterceptor(data); |
| } |
| else { |
| responseInterceptor(data); |
| } |
| }; |
| |
| if (_.isObject(obj) && _.isObject(obj.body)) { |
| // special processing for file uploads via jquery |
| if (obj.body.type && obj.body.type === 'formData'){ |
| if(opts.useJQuery) { |
| obj.contentType = false; |
| obj.processData = false; |
| delete obj.headers['Content-Type']; |
| } |
| } |
| } |
| |
| obj = requestInterceptor(obj) || obj; |
| if (obj.beforeSend) { |
| obj.beforeSend(function(_obj) { |
| client.execute(_obj || obj); |
| }); |
| } else { |
| client.execute(obj); |
| } |
| |
| return (obj.deferred) ? obj.deferred.promise : obj; |
| }; |
| |
| SwaggerHttp.prototype.isInternetExplorer = function () { |
| var detectedIE = false; |
| |
| if (typeof navigator !== 'undefined' && navigator.userAgent) { |
| var nav = navigator.userAgent.toLowerCase(); |
| |
| if (nav.indexOf('msie') !== -1) { |
| var version = parseInt(nav.split('msie')[1]); |
| |
| if (version <= 8) { |
| detectedIE = true; |
| } |
| } |
| } |
| |
| return detectedIE; |
| }; |
| |
| JQueryHttpClient.prototype.execute = function (obj) { |
| var jq = this.jQuery || (typeof window !== 'undefined' && window.jQuery); |
| var cb = obj.on; |
| var request = obj; |
| |
| if(typeof jq === 'undefined' || jq === false) { |
| throw new Error('Unsupported configuration! JQuery is required but not available'); |
| } |
| |
| obj.type = obj.method; |
| obj.cache = obj.jqueryAjaxCache; |
| obj.data = obj.body; |
| delete obj.jqueryAjaxCache; |
| delete obj.useJQuery; |
| delete obj.body; |
| |
| obj.complete = function (response) { |
| var headers = {}; |
| var headerArray = response.getAllResponseHeaders().split('\n'); |
| |
| for (var i = 0; i < headerArray.length; i++) { |
| var toSplit = headerArray[i].trim(); |
| |
| if (toSplit.length === 0) { |
| continue; |
| } |
| |
| var separator = toSplit.indexOf(':'); |
| |
| if (separator === -1) { |
| // Name but no value in the header |
| headers[toSplit] = null; |
| |
| continue; |
| } |
| |
| var name = toSplit.substring(0, separator).trim(); |
| var value = toSplit.substring(separator + 1).trim(); |
| |
| headers[name] = value; |
| } |
| |
| var out = { |
| url: request.url, |
| method: request.method, |
| status: response.status, |
| statusText: response.statusText, |
| data: response.responseText, |
| headers: headers |
| }; |
| |
| try { |
| var possibleObj = response.responseJSON || jsyaml.safeLoad(response.responseText); |
| out.obj = (typeof possibleObj === 'string') ? {} : possibleObj; |
| } catch (ex) { |
| // do not set out.obj |
| helpers.log('unable to parse JSON/YAML content'); |
| } |
| |
| // I can throw, or parse null? |
| out.obj = out.obj || null; |
| |
| if (response.status >= 200 && response.status < 300) { |
| cb.response(out); |
| } else if (response.status === 0 || (response.status >= 400 && response.status < 599)) { |
| cb.error(out); |
| } else { |
| return cb.response(out); |
| } |
| }; |
| |
| jq.support.cors = true; |
| |
| return jq.ajax(obj); |
| }; |
| |
| SuperagentHttpClient.prototype.execute = function (obj) { |
| var method = obj.method.toLowerCase(); |
| var timeout = obj.timeout; |
| |
| if (method === 'delete') { |
| method = 'del'; |
| } |
| var headers = obj.headers || {}; |
| |
| var r = request[method](obj.url); |
| |
| if (obj.connectionAgent) { |
| r.agent(obj.connectionAgent); |
| } |
| |
| if (timeout) { |
| r.timeout(timeout); |
| } |
| |
| if (obj.enableCookies) { |
| r.withCredentials(); |
| } |
| |
| var accept = obj.headers.Accept; |
| |
| if(this.binaryRequest(accept)) { |
| r.on('request', function () { |
| if(this.xhr) { |
| this.xhr.responseType = 'blob'; |
| } |
| }); |
| } |
| |
| if(obj.body) { |
| if(_.isObject(obj.body)) { |
| var contentType = obj.headers['Content-Type'] || ''; |
| if (contentType.indexOf('multipart/form-data') === 0) { |
| delete headers['Content-Type']; |
| if({}.toString.apply(obj.body) === '[object FormData]') { |
| r.send(obj.body); |
| } |
| else { |
| var keyname, value, v; |
| for (keyname in obj.body) { |
| value = obj.body[keyname]; |
| if(Array.isArray(value)) { |
| for(v in value) { |
| r.field(keyname, v); |
| } |
| } |
| else { |
| r.field(keyname, value); |
| } |
| } |
| } |
| } |
| else if (_.isObject(obj.body)) { |
| // non multipart/form-data |
| obj.body = JSON.stringify(obj.body); |
| r.send(obj.body); |
| } |
| } |
| else { |
| r.send(obj.body); |
| } |
| } |
| |
| var name; |
| for (name in headers) { |
| r.set(name, headers[name]); |
| } |
| |
| if(typeof r.buffer === 'function') { |
| r.buffer(); // force superagent to populate res.text with the raw response data |
| } |
| |
| r.end(function (err, res) { |
| res = res || { |
| status: 0, |
| headers: {error: 'no response from server'} |
| }; |
| var response = { |
| url: obj.url, |
| method: obj.method, |
| headers: res.headers |
| }; |
| var cb; |
| |
| if (!err && res.error) { |
| err = res.error; |
| } |
| |
| if (err && obj.on && obj.on.error) { |
| response.errObj = err; |
| response.status = res ? res.status : 500; |
| response.statusText = res ? res.text : err.message; |
| if (res.headers && res.headers['content-type']) { |
| if (res.headers['content-type'].indexOf('application/json') >= 0) { |
| try { |
| response.obj = JSON.parse(response.statusText); |
| } |
| catch (e) { |
| response.obj = null; |
| } |
| } |
| } |
| cb = obj.on.error; |
| } else if (res && obj.on && obj.on.response) { |
| var possibleObj; |
| |
| // Already parsed by by superagent? |
| if (res.body && _.keys(res.body).length > 0) { |
| possibleObj = res.body; |
| } else { |
| try { |
| possibleObj = jsyaml.safeLoad(res.text); |
| // can parse into a string... which we don't need running around in the system |
| possibleObj = (typeof possibleObj === 'string') ? null : possibleObj; |
| } catch (e) { |
| helpers.log('cannot parse JSON/YAML content'); |
| } |
| } |
| |
| // null means we can't parse into object |
| if(typeof Buffer === 'function' && Buffer.isBuffer(possibleObj)) { |
| response.data = possibleObj; |
| } |
| else { |
| response.obj = (typeof possibleObj === 'object') ? possibleObj : null; |
| } |
| |
| response.status = res.status; |
| response.statusText = res.text; |
| cb = obj.on.response; |
| } |
| if (res.xhr && res.xhr.response) { |
| response.data = res.xhr.response; |
| } |
| else if(!response.data) { |
| response.data = response.statusText; |
| } |
| |
| if (cb) { |
| cb(response); |
| } |
| }); |
| }; |
| |
| SuperagentHttpClient.prototype. binaryRequest = function (accept) { |
| if(!accept) { |
| return false; |
| } |
| return (/^image/i).test(accept) |
| || (/^application\/pdf/).test(accept) |
| || (/^application\/octet-stream/).test(accept); |
| }; |
| |
| }).call(this,require("buffer").Buffer) |
| |
| },{"./helpers":4,"buffer":14,"js-yaml":19,"lodash-compat/lang/isObject":144,"lodash-compat/object/keys":149,"superagent":158}],6:[function(require,module,exports){ |
| 'use strict'; |
| |
| var SwaggerHttp = require('./http'); |
| var _ = { |
| isObject: require('lodash-compat/lang/isObject'), |
| cloneDeep: require('lodash-compat/lang/cloneDeep'), |
| isArray: require('lodash-compat/lang/isArray'), |
| isString: require('lodash-compat/lang/isString') |
| }; |
| |
| |
| /** |
| * Resolves a spec's remote references |
| */ |
| var Resolver = module.exports = function () { |
| this.failedUrls = []; |
| this.resolverCache = {}; |
| this.pendingUrls = {}; |
| }; |
| |
| Resolver.prototype.processAllOf = function(root, name, definition, resolutionTable, unresolvedRefs, spec) { |
| var i, location, property; |
| |
| definition['x-resolved-from'] = [ '#/definitions/' + name ]; |
| var allOf = definition.allOf; |
| // the refs go first |
| allOf.sort(function(a, b) { |
| if(a.$ref && b.$ref) { return 0; } |
| else if(a.$ref) { return -1; } |
| else { return 1; } |
| }); |
| for (i = 0; i < allOf.length; i++) { |
| property = allOf[i]; |
| location = '/definitions/' + name + '/allOf'; |
| this.resolveInline(root, spec, property, resolutionTable, unresolvedRefs, location); |
| } |
| }; |
| |
| Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) { |
| this.spec = spec; |
| var root = arg1, callback = arg2, scope = arg3, opts = {}, location, i; |
| if(typeof arg1 === 'function') { |
| root = null; |
| callback = arg1; |
| scope = arg2; |
| } |
| var _root = root, modelName; |
| this.scope = (scope || this); |
| this.iteration = this.iteration || 0; |
| |
| if(this.scope.options && this.scope.options.requestInterceptor){ |
| opts.requestInterceptor = this.scope.options.requestInterceptor; |
| } |
| |
| if(this.scope.options && this.scope.options.responseInterceptor){ |
| opts.responseInterceptor = this.scope.options.responseInterceptor; |
| } |
| |
| var name, path, property, propertyName, parameter, done, counter; |
| var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {}; |
| var resolutionTable = []; // store objects for dereferencing |
| |
| spec.definitions = spec.definitions || {}; |
| // definitions |
| for (name in spec.definitions) { |
| var definition = spec.definitions[name]; |
| if(definition.$ref) { |
| this.resolveInline(root, spec, definition, resolutionTable, unresolvedRefs, definition); |
| } |
| else { |
| for (propertyName in definition.properties) { |
| property = definition.properties[propertyName]; |
| if (_.isArray(property.allOf)) { |
| this.processAllOf(root, name, property, resolutionTable, unresolvedRefs, spec); |
| } |
| else { |
| this.resolveTo(root, property, resolutionTable, '/definitions'); |
| } |
| } |
| |
| if (definition.allOf) { |
| this.processAllOf(root, name, definition, resolutionTable, unresolvedRefs, spec); |
| } |
| } |
| } |
| |
| // shared parameters |
| spec.parameters = spec.parameters || {}; |
| for(name in spec.parameters) { |
| parameter = spec.parameters[name]; |
| if (parameter.in === 'body' && parameter.schema) { |
| if(_.isArray(parameter.schema.allOf)) { |
| // move to a definition |
| modelName = 'inline_model'; |
| var _name = modelName; |
| done = false; counter = 0; |
| while(!done) { |
| if(typeof spec.definitions[_name] === 'undefined') { |
| done = true; |
| break; |
| } |
| _name = modelName + '_' + counter; |
| counter ++; |
| } |
| spec.definitions[_name] = { allOf: parameter.schema.allOf }; |
| delete parameter.schema.allOf; |
| parameter.schema.$ref = '#/definitions/' + _name; |
| this.processAllOf(root, _name, spec.definitions[_name], resolutionTable, unresolvedRefs, spec); |
| } |
| else { |
| this.resolveTo(root, parameter.schema, resolutionTable, location); |
| } |
| } |
| |
| if (parameter.$ref) { |
| // parameter reference |
| this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref); |
| } |
| } |
| |
| // operations |
| for (name in spec.paths) { |
| var method, operation, responseCode; |
| path = spec.paths[name]; |
| |
| if(typeof path === 'object') { |
| for (method in path) { |
| // operation reference |
| if (method === '$ref') { |
| // location = path[method]; |
| location = '/paths' + name; |
| this.resolveInline(root, spec, path, resolutionTable, unresolvedRefs, location); |
| } |
| else { |
| operation = path[method]; |
| var sharedParameters = path.parameters || []; |
| var parameters = operation.parameters || []; |
| |
| sharedParameters.forEach(function(parameter) { |
| parameters.unshift(parameter); |
| }); |
| |
| if (method !== 'parameters' && _.isObject(operation)) { |
| operation.parameters = operation.parameters || parameters; |
| } |
| |
| for (i in parameters) { |
| parameter = parameters[i]; |
| location = '/paths' + name + '/' + method + '/parameters'; |
| |
| if (parameter.in === 'body' && parameter.schema) { |
| if (_.isArray(parameter.schema.allOf)) { |
| // move to a definition |
| modelName = 'inline_model'; |
| name = modelName; |
| done = false; |
| counter = 0; |
| while (!done) { |
| if (typeof spec.definitions[name] === 'undefined') { |
| done = true; |
| break; |
| } |
| name = modelName + '_' + counter; |
| counter++; |
| } |
| spec.definitions[name] = {allOf: parameter.schema.allOf}; |
| delete parameter.schema.allOf; |
| parameter.schema.$ref = '#/definitions/' + name; |
| this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec); |
| } |
| else { |
| this.resolveTo(root, parameter.schema, resolutionTable, location); |
| } |
| } |
| |
| if (parameter.$ref) { |
| // parameter reference |
| this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref); |
| } |
| } |
| |
| for (responseCode in operation.responses) { |
| var response = operation.responses[responseCode]; |
| location = '/paths' + name + '/' + method + '/responses/' + responseCode; |
| |
| if (_.isObject(response)) { |
| if (response.$ref) { |
| // response reference |
| this.resolveInline(root, spec, response, resolutionTable, unresolvedRefs, location); |
| } |
| if (response.schema) { |
| var responseObj = response; |
| if (_.isArray(responseObj.schema.allOf)) { |
| // move to a definition |
| modelName = 'inline_model'; |
| name = modelName; |
| done = false; |
| counter = 0; |
| while (!done) { |
| if (typeof spec.definitions[name] === 'undefined') { |
| done = true; |
| break; |
| } |
| name = modelName + '_' + counter; |
| counter++; |
| } |
| spec.definitions[name] = {allOf: responseObj.schema.allOf}; |
| delete responseObj.schema.allOf; |
| delete responseObj.schema.type; |
| responseObj.schema.$ref = '#/definitions/' + name; |
| this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec); |
| } |
| else if ('array' === responseObj.schema.type) { |
| if (responseObj.schema.items && responseObj.schema.items.$ref) { |
| // response reference |
| this.resolveInline(root, spec, responseObj.schema.items, resolutionTable, unresolvedRefs, location); |
| } |
| } |
| else { |
| this.resolveTo(root, response.schema, resolutionTable, location); |
| } |
| } |
| } |
| } |
| } |
| } |
| // clear them out to avoid multiple resolutions |
| path.parameters = []; |
| } |
| } |
| |
| var expectedCalls = 0, toResolve = []; |
| // if the root is same as obj[i].root we can resolve locally |
| var all = resolutionTable; |
| |
| var parts; |
| for(i = 0; i < all.length; i++) { |
| var a = all[i]; |
| if(root === a.root) { |
| if(a.resolveAs === 'ref') { |
| // resolve any path walking |
| var joined = ((a.root || '') + '/' + a.key).split('/'); |
| var normalized = []; |
| var url = ''; |
| var k; |
| |
| if(a.key.indexOf('../') >= 0) { |
| for(var j = 0; j < joined.length; j++) { |
| if(joined[j] === '..') { |
| normalized = normalized.slice(0, normalized.length-1); |
| } |
| else { |
| normalized.push(joined[j]); |
| } |
| } |
| for(k = 0; k < normalized.length; k ++) { |
| if(k > 0) { |
| url += '/'; |
| } |
| url += normalized[k]; |
| } |
| // we now have to remote resolve this because the path has changed |
| a.root = url; |
| toResolve.push(a); |
| } |
| else { |
| parts = a.key.split('#'); |
| if(parts.length === 2) { |
| if(parts[0].indexOf('http:') === 0 || parts[0].indexOf('https:') === 0) { |
| a.root = parts[0]; |
| } |
| location = parts[1].split('/'); |
| var r; |
| var s = spec; |
| for(k = 0; k < location.length; k++) { |
| var part = location[k]; |
| if(part !== '') { |
| s = s[part]; |
| if(typeof s !== 'undefined') { |
| r = s; |
| } |
| else { |
| r = null; |
| break; |
| } |
| } |
| } |
| if(r === null) { |
| // must resolve this too |
| toResolve.push(a); |
| } |
| } |
| } |
| } |
| else { |
| if (a.resolveAs === 'inline') { |
| if(a.key && a.key.indexOf('#') === -1 && a.key.charAt(0) !== '/') { |
| // handle relative schema |
| parts = a.root.split('/'); |
| location = ''; |
| for(i = 0; i < parts.length - 1; i++) { |
| location += parts[i] + '/'; |
| } |
| location += a.key; |
| a.root = location; |
| a.location = ''; |
| } |
| toResolve.push(a); |
| } |
| } |
| } |
| else { |
| toResolve.push(a); |
| } |
| } |
| expectedCalls = toResolve.length; |
| |
| // resolve anything that is local |
| |
| var lock = {}; |
| for(var ii = 0; ii < toResolve.length; ii++) { |
| (function(item, spec, self, lock, ii) { |
| if(!item.root || item.root === root) { |
| // local resolve |
| self.resolveItem(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, item); |
| processedCalls += 1; |
| |
| if(processedCalls === expectedCalls) { |
| self.finish(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, true); |
| } |
| } |
| else if(self.failedUrls.indexOf(item.root) === -1) { |
| var obj = { |
| useJQuery: false, // TODO |
| url: item.root, |
| method: 'get', |
| headers: { |
| accept: self.scope.swaggerRequestHeaders || 'application/json' |
| }, |
| on: { |
| error: function (error) { |
| processedCalls += 1; |
| console.log('failed url: ' + obj.url); |
| self.failedUrls.push(obj.url); |
| if (lock) { |
| delete lock[item.root]; |
| } |
| unresolvedRefs[item.key] = { |
| root: item.root, |
| location: item.location |
| }; |
| |
| if (processedCalls === expectedCalls) { |
| self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| } |
| }, // jshint ignore:line |
| response: function (response) { |
| var swagger = response.obj; |
| if (lock) { |
| delete lock[item.root]; |
| } |
| if (self.resolverCache) { |
| self.resolverCache[item.root] = swagger; |
| } |
| self.resolveItem(swagger, item.root, resolutionTable, resolvedRefs, unresolvedRefs, item); |
| processedCalls += 1; |
| |
| if (processedCalls === expectedCalls) { |
| self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| } |
| } |
| } // jshint ignore:line |
| }; |
| |
| // apply timeout only when specified |
| if (scope && scope.fetchSpecTimeout) { |
| obj.timeout = scope.fetchSpecTimeout; |
| } |
| |
| if (scope && scope.clientAuthorizations) { |
| scope.clientAuthorizations.apply(obj); |
| } |
| |
| (function waitForUnlock() { |
| setTimeout(function() { |
| if (lock[obj.url]) { |
| waitForUnlock(); |
| } |
| else { |
| var cached = self.resolverCache[obj.url]; |
| if (_.isObject(cached)) { |
| obj.on.response({obj: cached}); |
| } |
| else { |
| lock[obj.url] = true; |
| new SwaggerHttp().execute(obj, opts); |
| } |
| } |
| }, 0); |
| })(); |
| } |
| |
| else { |
| processedCalls += 1; |
| unresolvedRefs[item.key] = { |
| root: item.root, |
| location: item.location |
| }; |
| if (processedCalls === expectedCalls) { |
| self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| } |
| } |
| }(toResolve[ii], spec, this, lock, ii)); |
| } |
| |
| if (Object.keys(toResolve).length === 0) { |
| this.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| } |
| }; |
| |
| Resolver.prototype.resolveItem = function(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, item) { |
| var path = item.location; |
| var location = spec, parts = path.split('/'); |
| if(path !== '') { |
| for (var j = 0; j < parts.length; j++) { |
| var segment = parts[j]; |
| if (segment.indexOf('~1') !== -1) { |
| segment = parts[j].replace(/~0/g, '~').replace(/~1/g, '/'); |
| if (segment.charAt(0) !== '/') { |
| segment = '/' + segment; |
| } |
| } |
| if (typeof location === 'undefined' || location === null) { |
| break; |
| } |
| if (segment === '' && j === (parts.length - 1) && parts.length > 1) { |
| location = null; |
| break; |
| } |
| if (segment.length > 0) { |
| location = location[segment]; |
| } |
| } |
| } |
| var resolved = item.key; |
| parts = item.key.split('/'); |
| var resolvedName = parts[parts.length-1]; |
| |
| if(resolvedName.indexOf('#') >= 0) { |
| resolvedName = resolvedName.split('#')[1]; |
| } |
| |
| if (location !== null && typeof location !== 'undefined') { |
| resolvedRefs[resolved] = { |
| name: resolvedName, |
| obj: location, |
| key: item.key, |
| root: item.root |
| }; |
| } else { |
| unresolvedRefs[resolved] = { |
| root: item.root, |
| location: item.location |
| }; |
| } |
| }; |
| |
| Resolver.prototype.finish = function (spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, localResolve) { |
| // walk resolution table and replace with resolved refs |
| var ref, abs; |
| for (ref in resolutionTable) { |
| var item = resolutionTable[ref]; |
| |
| var key = item.key; |
| var resolvedTo = resolvedRefs[key]; |
| if (resolvedTo) { |
| spec.definitions = spec.definitions || {}; |
| if (item.resolveAs === 'ref') { |
| if (localResolve !== true) { |
| // don't retain root for local definitions |
| for (key in resolvedTo.obj) { |
| abs = this.retainRoot(key, resolvedTo.obj[key], item.root); |
| resolvedTo.obj[key] = abs; |
| } |
| } |
| spec.definitions[resolvedTo.name] = resolvedTo.obj; |
| item.obj.$ref = '#/definitions/' + resolvedTo.name; |
| } else if (item.resolveAs === 'inline') { |
| var targetObj = item.obj; |
| targetObj['x-resolved-from'] = [ item.key ]; |
| delete targetObj.$ref; |
| |
| for (key in resolvedTo.obj) { |
| abs = resolvedTo.obj[key]; |
| |
| if (localResolve !== true) { |
| // don't retain root for local definitions |
| abs = this.retainRoot(key, resolvedTo.obj[key], item.root); |
| } |
| targetObj[key] = abs; |
| } |
| } |
| } |
| } |
| var existingUnresolved = this.countUnresolvedRefs(spec); |
| |
| if(existingUnresolved === 0 || this.iteration > 5) { |
| this.resolveAllOf(spec.definitions); |
| this.resolverCache = null; |
| callback.call(this.scope, spec, unresolvedRefs); |
| } |
| else { |
| this.iteration += 1; |
| this.resolve(spec, root, callback, this.scope); |
| } |
| }; |
| |
| Resolver.prototype.countUnresolvedRefs = function(spec) { |
| var i; |
| var refs = this.getRefs(spec); |
| var keys = []; |
| var unresolvedKeys = []; |
| for(i in refs) { |
| if(i.indexOf('#') === 0) { |
| keys.push(i.substring(1)); |
| } |
| else { |
| unresolvedKeys.push(i); |
| } |
| } |
| |
| // verify possible keys |
| for (i = 0; i < keys.length; i++) { |
| var part = keys[i]; |
| var parts = part.split('/'); |
| var obj = spec; |
| |
| for (var k = 0; k < parts.length; k++) { |
| var key = parts[k]; |
| if(key !== '') { |
| obj = obj[key]; |
| if(typeof obj === 'undefined') { |
| unresolvedKeys.push(part); |
| break; |
| } |
| } |
| } |
| } |
| return unresolvedKeys.length; |
| }; |
| |
| Resolver.prototype.getRefs = function(spec, obj) { |
| obj = obj || spec; |
| var output = {}; |
| for(var key in obj) { |
| if (!obj.hasOwnProperty(key)) { |
| continue; |
| } |
| var item = obj[key]; |
| if(key === '$ref' && typeof item === 'string') { |
| output[item] = null; |
| } |
| else if(_.isObject(item)) { |
| var o = this.getRefs(item); |
| for(var k in o) { |
| output[k] = null; |
| } |
| } |
| } |
| return output; |
| }; |
| |
| function splitUrl(url) { |
| var result = {}; |
| var proto = /[a-z]+:\/\//i.exec(url); |
| if (proto) { |
| result.proto = proto[0].slice(0, -3); |
| url = url.slice(result.proto.length + 1); |
| } |
| if (url.slice(0, 2) === '//') { |
| result.domain = url.slice(2).split('/')[0]; |
| url = url.slice(2 + result.domain.length); |
| } |
| var p = url.split('#'); |
| if (p[0].length) { |
| result.path = p[0]; |
| } |
| if (p.length > 1) { |
| result.fragment = p.slice(1).join('#'); |
| } |
| return result; |
| } |
| |
| function unsplitUrl(url) { |
| var result = url.path; |
| if (result === undefined) { |
| result = ''; |
| } |
| if (url.fragment !== undefined) { |
| result += '#' + url.fragment; |
| } |
| if (url.domain !== undefined) { |
| if (result.slice(0, 1) === '/') { |
| result = result.slice(1); |
| } |
| result = '//' + url.domain + '/' + result; |
| if (url.proto !== undefined) { |
| result = url.proto + ':' + result; |
| } |
| } |
| return result; |
| } |
| |
| function joinUrl(base, rel) { |
| var relsp = splitUrl(rel); |
| if (relsp.domain !== undefined) { |
| return rel; |
| } |
| var result = splitUrl(base); |
| if (relsp.path === undefined) { |
| // change only fragment part |
| result.fragment = relsp.fragment; |
| } else if (relsp.path.slice(0, 1) === '/') { |
| // relative to domain |
| result.path = relsp.path; |
| result.fragment = relsp.fragment; |
| } else { |
| // relative to path |
| var path = result.path === undefined ? [] : result.path.split('/'); |
| var relpath = relsp.path.split('/'); |
| if (path.length) { |
| path.pop(); |
| } |
| while (relpath[0] === '..' || relpath[0] === '.') { |
| if (relpath[0] === '..') { |
| path.pop(); |
| } |
| relpath.shift(); |
| } |
| result.path = path.concat(relpath).join('/'); |
| result.fragment = relsp.fragment; |
| } |
| return unsplitUrl(result); |
| } |
| |
| Resolver.prototype.retainRoot = function(origKey, obj, root) { |
| // walk object and look for relative $refs |
| if(_.isObject(obj)) { |
| for(var key in obj) { |
| var item = obj[key]; |
| if (key === '$ref' && typeof item === 'string') { |
| obj[key] = joinUrl(root, item); |
| } |
| else if (_.isObject(item)) { |
| this.retainRoot(key, item, root); |
| } |
| } |
| } |
| else if(_.isString(obj) && origKey === '$ref') { |
| obj = joinUrl(root, obj); |
| } |
| return obj; |
| }; |
| |
| /** |
| * immediately in-lines local refs, queues remote refs |
| * for inline resolution |
| */ |
| Resolver.prototype.resolveInline = function (root, spec, property, resolutionTable, unresolvedRefs, location) { |
| var key = property.$ref, ref = property.$ref, i, p, p2, rs; |
| var rootTrimmed = false; |
| |
| root = root || ''; // Guard against .split. @fehguy, you'll need to check if this logic fits |
| // More imporantly is how do we gracefully handle relative urls, when provided just a 'spec', not a 'url' ? |
| |
| if (ref) { |
| if(ref.indexOf('../') === 0) { |
| // reset root |
| p = ref.split('../'); |
| p2 = root.split('/'); |
| ref = ''; |
| for(i = 0; i < p.length; i++) { |
| if(p[i] === '') { |
| p2 = p2.slice(0, p2.length-1); |
| } |
| else { |
| ref += p[i]; |
| } |
| } |
| root = ''; |
| for(i = 0; i < p2.length - 1; i++) { |
| if(i > 0) { root += '/'; } |
| root += p2[i]; |
| } |
| rootTrimmed = true; |
| } |
| if(ref.indexOf('#') >= 0) { |
| if(ref.indexOf('/') === 0) { |
| rs = ref.split('#'); |
| p = root.split('//'); |
| p2 = p[1].split('/'); |
| root = p[0] + '//' + p2[0] + rs[0]; |
| location = rs[1]; |
| } |
| else { |
| rs = ref.split('#'); |
| if(rs[0] !== '') { |
| p2 = root.split('/'); |
| p2 = p2.slice(0, p2.length - 1); |
| if(!rootTrimmed) { |
| root = ''; |
| for (var k = 0; k < p2.length; k++) { |
| if(k > 0) { root += '/'; } |
| root += p2[k]; |
| } |
| } |
| root += '/' + ref.split('#')[0]; |
| } |
| location = rs[1]; |
| } |
| } |
| if (ref.indexOf('http:') === 0 || ref.indexOf('https:') === 0) { |
| if(ref.indexOf('#') >= 0) { |
| root = ref.split('#')[0]; |
| location = ref.split('#')[1]; |
| } |
| else { |
| root = ref; |
| location = ''; |
| } |
| resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
| } else if (ref.indexOf('#') === 0) { |
| location = ref.split('#')[1]; |
| resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
| } else if (ref.indexOf('/') === 0 && ref.indexOf('#') === -1) { |
| location = ref; |
| var matches = root.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); |
| if(matches) { |
| root = matches[0] + ref.substring(1); |
| location = ''; |
| } |
| resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
| } |
| else { |
| resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
| } |
| } |
| else if (property.type === 'array') { |
| this.resolveTo(root, property.items, resolutionTable, location); |
| } |
| }; |
| |
| Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) { |
| var sp, i; |
| var ref = property.$ref; |
| var lroot = root; |
| if ((typeof ref !== 'undefined') && (ref !== null)) { |
| if(ref.indexOf('#') >= 0) { |
| var parts = ref.split('#'); |
| |
| // #/definitions/foo |
| // foo.json#/bar |
| if(parts[0] && ref.indexOf('/') === 0) { |
| |
| } |
| else if(parts[0] && (parts[0].indexOf('http:') === 0 || parts[0].indexOf('https:') === 0)) { |
| lroot = parts[0]; |
| ref = parts[1]; |
| } |
| else if(parts[0] && parts[0].length > 0) { |
| // relative file |
| sp = root.split('/'); |
| lroot = ''; |
| for(i = 0; i < sp.length - 1; i++) { |
| lroot += sp[i] + '/'; |
| } |
| lroot += parts[0]; |
| } |
| else { |
| |
| } |
| |
| location = parts[1]; |
| } |
| else if (ref.indexOf('http:') === 0 || ref.indexOf('https:') === 0) { |
| lroot = ref; |
| location = ''; |
| } |
| else { |
| // relative file |
| sp = root.split('/'); |
| lroot = ''; |
| for(i = 0; i < sp.length - 1; i++) { |
| lroot += sp[i] + '/'; |
| } |
| lroot += ref; |
| location = ''; |
| } |
| resolutionTable.push({ |
| obj: property, resolveAs: 'ref', root: lroot, key: ref, location: location |
| }); |
| } else if (property.type === 'array') { |
| var items = property.items; |
| this.resolveTo(root, items, resolutionTable, location); |
| } else { |
| if(property && (property.properties || property.additionalProperties)) { |
| var name = this.uniqueName('inline_model'); |
| if (property.title) { |
| name = this.uniqueName(property.title); |
| } |
| delete property.title; |
| this.spec.definitions[name] = _.cloneDeep(property); |
| property.$ref = '#/definitions/' + name; |
| delete property.type; |
| delete property.properties; |
| } |
| } |
| }; |
| |
| Resolver.prototype.uniqueName = function(base) { |
| var name = base; |
| var count = 0; |
| while(true) { |
| if(!_.isObject(this.spec.definitions[name])) { |
| return name; |
| } |
| name = base + '_' + count; |
| count++; |
| } |
| }; |
| |
| Resolver.prototype.resolveAllOf = function(spec, obj, depth) { |
| depth = depth || 0; |
| obj = obj || spec; |
| var name; |
| for(var key in obj) { |
| if (!obj.hasOwnProperty(key)) { |
| continue; |
| } |
| var item = obj[key]; |
| if(item === null) { |
| throw new TypeError('Swagger 2.0 does not support null types (' + obj + '). See https://github.com/swagger-api/swagger-spec/issues/229.'); |
| } |
| if(typeof item === 'object') { |
| this.resolveAllOf(spec, item, depth + 1); |
| } |
| if(item && typeof item.allOf !== 'undefined') { |
| var allOf = item.allOf; |
| if(_.isArray(allOf)) { |
| var output = _.cloneDeep(item); |
| delete output.allOf; |
| |
| output['x-composed'] = true; |
| if (typeof item['x-resolved-from'] !== 'undefined') { |
| output['x-resolved-from'] = item['x-resolved-from']; |
| } |
| |
| for(var i = 0; i < allOf.length; i++) { |
| var component = allOf[i]; |
| var source = 'self'; |
| if(typeof component['x-resolved-from'] !== 'undefined') { |
| source = component['x-resolved-from'][0]; |
| } |
| |
| for(var part in component) { |
| if(!output.hasOwnProperty(part)) { |
| output[part] = _.cloneDeep(component[part]); |
| if(part === 'properties') { |
| for(name in output[part]) { |
| output[part][name]['x-resolved-from'] = source; |
| } |
| } |
| } |
| else { |
| if(part === 'properties') { |
| var properties = component[part]; |
| for(name in properties) { |
| output.properties[name] = _.cloneDeep(properties[name]); |
| var resolvedFrom = properties[name]['x-resolved-from']; |
| if (typeof resolvedFrom === 'undefined' || resolvedFrom === 'self') { |
| resolvedFrom = source; |
| } |
| output.properties[name]['x-resolved-from'] = resolvedFrom; |
| } |
| } |
| else if(part === 'required') { |
| // merge & dedup the required array |
| var a = output.required.concat(component[part]); |
| for(var k = 0; k < a.length; ++k) { |
| for(var j = k + 1; j < a.length; ++j) { |
| if(a[k] === a[j]) { a.splice(j--, 1); } |
| } |
| } |
| output.required = a; |
| } |
| else if(part === 'x-resolved-from') { |
| output['x-resolved-from'].push(source); |
| } |
| else { |
| // TODO: need to merge this property |
| // console.log('what to do with ' + part) |
| } |
| } |
| } |
| } |
| obj[key] = output; |
| } |
| } |
| } |
| }; |
| |
| },{"./http":5,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isString":146}],7:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Helpers = require('./helpers'); |
| |
| var _ = { |
| isPlainObject: require('lodash-compat/lang/isPlainObject'), |
| isUndefined: require('lodash-compat/lang/isUndefined'), |
| isArray: require('lodash-compat/lang/isArray'), |
| isObject: require('lodash-compat/lang/isObject'), |
| isEmpty: require('lodash-compat/lang/isEmpty'), |
| map: require('lodash-compat/collection/map'), |
| indexOf: require('lodash-compat/array/indexOf'), |
| cloneDeep: require('lodash-compat/lang/cloneDeep'), |
| keys: require('lodash-compat/object/keys'), |
| forEach: require('lodash-compat/collection/forEach') |
| }; |
| |
| var optionHtml = module.exports.optionHtml = function (label, value) { |
| return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>'; |
| }; |
| |
| module.exports.typeFromJsonSchema = function (type, format) { |
| var str; |
| |
| if (type === 'integer' && format === 'int32') { |
| str = 'integer'; |
| } else if (type === 'integer' && format === 'int64') { |
| str = 'long'; |
| } else if (type === 'integer' && typeof format === 'undefined') { |
| str = 'long'; |
| } else if (type === 'string' && format === 'date-time') { |
| str = 'date-time'; |
| } else if (type === 'string' && format === 'date') { |
| str = 'date'; |
| } else if (type === 'number' && format === 'float') { |
| str = 'float'; |
| } else if (type === 'number' && format === 'double') { |
| str = 'double'; |
| } else if (type === 'number' && typeof format === 'undefined') { |
| str = 'double'; |
| } else if (type === 'boolean') { |
| str = 'boolean'; |
| } else if (type === 'string') { |
| str = 'string'; |
| } |
| |
| return str; |
| }; |
| |
| var getStringSignature = module.exports.getStringSignature = function (obj, baseComponent) { |
| var str = ''; |
| |
| if (typeof obj.$ref !== 'undefined') { |
| str += Helpers.simpleRef(obj.$ref); |
| } else if (typeof obj.type === 'undefined') { |
| str += 'object'; |
| } else if (obj.type === 'array') { |
| if (baseComponent) { |
| str += getStringSignature((obj.items || obj.$ref || {})); |
| } else { |
| str += 'Array['; |
| str += getStringSignature((obj.items || obj.$ref || {})); |
| str += ']'; |
| } |
| } else if (obj.type === 'integer' && obj.format === 'int32') { |
| str += 'integer'; |
| } else if (obj.type === 'integer' && obj.format === 'int64') { |
| str += 'long'; |
| } else if (obj.type === 'integer' && typeof obj.format === 'undefined') { |
| str += 'long'; |
| } else if (obj.type === 'string' && obj.format === 'date-time') { |
| str += 'date-time'; |
| } else if (obj.type === 'string' && obj.format === 'date') { |
| str += 'date'; |
| } else if (obj.type === 'string' && typeof obj.format === 'undefined') { |
| str += 'string'; |
| } else if (obj.type === 'number' && obj.format === 'float') { |
| str += 'float'; |
| } else if (obj.type === 'number' && obj.format === 'double') { |
| str += 'double'; |
| } else if (obj.type === 'number' && typeof obj.format === 'undefined') { |
| str += 'double'; |
| } else if (obj.type === 'boolean') { |
| str += 'boolean'; |
| } else if (obj.$ref) { |
| str += Helpers.simpleRef(obj.$ref); |
| } else { |
| str += obj.type; |
| } |
| |
| return str; |
| }; |
| |
| var schemaToJSON = module.exports.schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) { |
| // Resolve the schema (Handle nested schemas) |
| schema = Helpers.resolveSchema(schema); |
| |
| if(typeof modelPropertyMacro !== 'function') { |
| modelPropertyMacro = function(prop){ |
| return (prop || {}).default; |
| }; |
| } |
| |
| modelsToIgnore= modelsToIgnore || {}; |
| |
| var type = schema.type || 'object'; |
| var format = schema.format; |
| var model; |
| var output; |
| |
| if (!_.isUndefined(schema.example)) { |
| output = schema.example; |
| } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) { |
| output = schema.enum[0]; |
| } |
| |
| if (_.isUndefined(output)) { |
| if (schema.$ref) { |
| model = models[Helpers.simpleRef(schema.$ref)]; |
| |
| if (!_.isUndefined(model)) { |
| if (_.isUndefined(modelsToIgnore[model.name])) { |
| modelsToIgnore[model.name] = model; |
| output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro); |
| delete modelsToIgnore[model.name]; |
| } else { |
| if (model.type === 'array') { |
| output = []; |
| } else { |
| output = {}; |
| } |
| } |
| } |
| } else if (!_.isUndefined(schema.default)) { |
| output = schema.default; |
| } else if (type === 'string') { |
| if (format === 'date-time') { |
| output = new Date().toISOString(); |
| } else if (format === 'date') { |
| output = new Date().toISOString().split('T')[0]; |
| } else { |
| output = 'string'; |
| } |
| } else if (type === 'integer') { |
| output = 0; |
| } else if (type === 'number') { |
| output = 0.0; |
| } else if (type === 'boolean') { |
| output = true; |
| } else if (type === 'object') { |
| output = {}; |
| |
| _.forEach(schema.properties, function (property, name) { |
| var cProperty = _.cloneDeep(property); |
| |
| // Allow macro to set the default value |
| cProperty.default = modelPropertyMacro(property); |
| |
| output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro); |
| }); |
| } else if (type === 'array') { |
| output = []; |
| |
| if (_.isArray(schema.items)) { |
| _.forEach(schema.items, function (item) { |
| output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro)); |
| }); |
| } else if (_.isPlainObject(schema.items)) { |
| output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro)); |
| } else if (_.isUndefined(schema.items)) { |
| output.push({}); |
| } else { |
| Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process'); |
| } |
| } |
| } |
| |
| return output; |
| }; |
| |
| module.exports.schemaToHTML =function (name, schema, models, modelPropertyMacro) { |
| var strongOpen = '<span class="strong">'; |
| var strongClose = '</span>'; |
| |
| // Allow for ignoring the 'name' argument.... shifting the rest |
| if(_.isObject(arguments[0])) { |
| name = void 0; |
| schema = arguments[0]; |
| models = arguments[1]; |
| modelPropertyMacro = arguments[2]; |
| } |
| |
| models = models || {}; |
| |
| // Resolve the schema (Handle nested schemas) |
| schema = Helpers.resolveSchema(schema); |
| |
| // Return for empty object |
| if(_.isEmpty(schema)) { |
| return strongOpen + 'Empty' + strongClose; |
| } |
| |
| // Dereference $ref from 'models' |
| if(typeof schema.$ref === 'string') { |
| name = Helpers.simpleRef(schema.$ref); |
| schema = models[name]; |
| if(typeof schema === 'undefined') |
| { |
| return strongOpen + name + ' is not defined!' + strongClose; |
| } |
| } |
| |
| if(typeof name !== 'string') { |
| name = schema.title || 'Inline Model'; |
| } |
| |
| // If we are a Model object... adjust accordingly |
| if(schema.definition) { |
| schema = schema.definition; |
| } |
| |
| if(typeof modelPropertyMacro !== 'function') { |
| modelPropertyMacro = function(prop){ |
| return (prop || {}).default; |
| }; |
| } |
| |
| var references = {}; |
| var seenModels = []; |
| var inlineModels = 0; |
| |
| |
| |
| // Generate current HTML |
| var html = processModel(schema, name); |
| |
| // Generate references HTML |
| while (_.keys(references).length > 0) { |
| /* jshint ignore:start */ |
| _.forEach(references, function (schema, name) { |
| var seenModel = _.indexOf(seenModels, name) > -1; |
| |
| delete references[name]; |
| |
| if (!seenModel) { |
| seenModels.push(name); |
| |
| html += '<br />' + processModel(schema, name); |
| } |
| }); |
| /* jshint ignore:end */ |
| } |
| |
| return html; |
| |
| ///////////////////////////////// |
| |
| function addReference(schema, name, skipRef) { |
| var modelName = name; |
| var model; |
| |
| if (schema.$ref) { |
| modelName = schema.title || Helpers.simpleRef(schema.$ref); |
| model = models[modelName]; |
| } else if (_.isUndefined(name)) { |
| modelName = schema.title || 'Inline Model ' + (++inlineModels); |
| model = {definition: schema}; |
| } |
| |
| if (skipRef !== true) { |
| references[modelName] = _.isUndefined(model) ? {} : model.definition; |
| } |
| |
| return modelName; |
| } |
| |
| function primitiveToHTML(schema) { |
| var html = '<span class="propType">'; |
| var type = schema.type || 'object'; |
| |
| if (schema.$ref) { |
| html += addReference(schema, Helpers.simpleRef(schema.$ref)); |
| } else if (type === 'object') { |
| if (!_.isUndefined(schema.properties)) { |
| html += addReference(schema); |
| } else { |
| html += 'object'; |
| } |
| } else if (type === 'array') { |
| html += 'Array['; |
| |
| if (_.isArray(schema.items)) { |
| html += _.map(schema.items, addReference).join(','); |
| } else if (_.isPlainObject(schema.items)) { |
| if (_.isUndefined(schema.items.$ref)) { |
| if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) { |
| html += schema.items.type; |
| } else { |
| html += addReference(schema.items); |
| } |
| } else { |
| html += addReference(schema.items, Helpers.simpleRef(schema.items.$ref)); |
| } |
| } else { |
| Helpers.log('Array type\'s \'items\' schema is not an array or an object, cannot process'); |
| html += 'object'; |
| } |
| |
| html += ']'; |
| } else { |
| html += schema.type; |
| } |
| |
| html += '</span>'; |
| |
| return html; |
| } |
| |
| function primitiveToOptionsHTML(schema, html) { |
| var options = ''; |
| var type = schema.type || 'object'; |
| var isArray = type === 'array'; |
| |
| if (isArray) { |
| if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) { |
| type = schema.items.type; |
| } else { |
| type = 'object'; |
| } |
| } |
| |
| if (!_.isUndefined(schema.default)) { |
| options += optionHtml('Default', schema.default); |
| } |
| |
| switch (type) { |
| case 'string': |
| if (schema.minLength) { |
| options += optionHtml('Min. Length', schema.minLength); |
| } |
| |
| if (schema.maxLength) { |
| options += optionHtml('Max. Length', schema.maxLength); |
| } |
| |
| if (schema.pattern) { |
| options += optionHtml('Reg. Exp.', schema.pattern); |
| } |
| break; |
| case 'integer': |
| case 'number': |
| if (schema.minimum) { |
| options += optionHtml('Min. Value', schema.minimum); |
| } |
| |
| if (schema.exclusiveMinimum) { |
| options += optionHtml('Exclusive Min.', 'true'); |
| } |
| |
| if (schema.maximum) { |
| options += optionHtml('Max. Value', schema.maximum); |
| } |
| |
| if (schema.exclusiveMaximum) { |
| options += optionHtml('Exclusive Max.', 'true'); |
| } |
| |
| if (schema.multipleOf) { |
| options += optionHtml('Multiple Of', schema.multipleOf); |
| } |
| |
| break; |
| } |
| |
| if (isArray) { |
| if (schema.minItems) { |
| options += optionHtml('Min. Items', schema.minItems); |
| } |
| |
| if (schema.maxItems) { |
| options += optionHtml('Max. Items', schema.maxItems); |
| } |
| |
| if (schema.uniqueItems) { |
| options += optionHtml('Unique Items', 'true'); |
| } |
| |
| if (schema.collectionFormat) { |
| options += optionHtml('Coll. Format', schema.collectionFormat); |
| } |
| } |
| |
| if (_.isUndefined(schema.items)) { |
| if (_.isArray(schema.enum)) { |
| var enumString; |
| |
| if (type === 'number' || type === 'integer') { |
| enumString = schema.enum.join(', '); |
| } else { |
| enumString = '"' + schema.enum.join('", "') + '"'; |
| } |
| |
| options += optionHtml('Enum', enumString); |
| } |
| } |
| |
| if (options.length > 0) { |
| html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>'; |
| } |
| |
| return html; |
| } |
| |
| function processModel(schema, name) { |
| var type = schema.type || 'object'; |
| var isArray = schema.type === 'array'; |
| var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose; |
| |
| if (name) { |
| seenModels.push(name); |
| } |
| |
| if (isArray) { |
| if (_.isArray(schema.items)) { |
| html += '<div>' + _.map(schema.items, function (item) { |
| var type = item.type || 'object'; |
| |
| if (_.isUndefined(item.$ref)) { |
| if (_.indexOf(['array', 'object'], type) > -1) { |
| if (type === 'object' && _.isUndefined(item.properties)) { |
| return 'object'; |
| } else { |
| return addReference(item); |
| } |
| } else { |
| return primitiveToOptionsHTML(item, type); |
| } |
| } else { |
| return addReference(item, Helpers.simpleRef(item.$ref)); |
| } |
| }).join(',</div><div>'); |
| } else if (_.isPlainObject(schema.items)) { |
| if (_.isUndefined(schema.items.$ref)) { |
| if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) { |
| if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) { |
| html += '<div>object</div>'; |
| } else { |
| html += '<div>' + addReference(schema.items) + '</div>'; |
| } |
| } else { |
| html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>'; |
| } |
| } else { |
| html += '<div>' + addReference(schema.items, Helpers.simpleRef(schema.items.$ref)) + '</div>'; |
| } |
| } else { |
| Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process'); |
| html += '<div>object</div>'; |
| } |
| } else { |
| if (schema.$ref) { |
| html += '<div>' + addReference(schema, name) + '</div>'; |
| } else if (type === 'object') { |
| if (_.isPlainObject(schema.properties)) { |
| var contents = _.map(schema.properties, function (property, name) { |
| var propertyIsRequired = (_.indexOf(schema.required, name) >= 0); |
| var cProperty = _.cloneDeep(property); |
| |
| var requiredClass = propertyIsRequired ? 'required' : ''; |
| var html = '<span class="propName ' + requiredClass + '">' + name + '</span> ('; |
| var model; |
| var propDescription; |
| |
| // Allow macro to set the default value |
| cProperty.default = modelPropertyMacro(cProperty); |
| |
| // Resolve the schema (Handle nested schemas) |
| cProperty = Helpers.resolveSchema(cProperty); |
| |
| propDescription = property.description || cProperty.description; |
| |
| // We need to handle property references to primitives (Issue 339) |
| if (!_.isUndefined(cProperty.$ref)) { |
| model = models[Helpers.simpleRef(cProperty.$ref)]; |
| |
| if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) { |
| // Use referenced schema |
| cProperty = Helpers.resolveSchema(model.definition); |
| } |
| } |
| |
| html += primitiveToHTML(cProperty); |
| |
| if(!propertyIsRequired) { |
| html += ', <span class="propOptKey">optional</span>'; |
| } |
| |
| if(property.readOnly) { |
| html += ', <span class="propReadOnly">read only</span>'; |
| } |
| |
| html += ')'; |
| |
| if (!_.isUndefined(propDescription)) { |
| html += ': ' + '<span class="propDesc">' + propDescription + '</span>'; |
| } |
| |
| if (cProperty.enum) { |
| html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>'; |
| } |
| |
| return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html); |
| }).join(',</div>'); |
| |
| if (contents) { |
| html += contents + '</div>'; |
| } |
| } |
| } else { |
| html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>'; |
| } |
| } |
| |
| return html + strongOpen + (isArray ? ']' : '}') + strongClose; |
| } |
| }; |
| },{"./helpers":4,"lodash-compat/array/indexOf":49,"lodash-compat/collection/forEach":54,"lodash-compat/collection/map":56,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,"lodash-compat/object/keys":149}],8:[function(require,module,exports){ |
| 'use strict'; |
| |
| var SwaggerHttp = require('./http'); |
| var _ = { |
| isObject: require('lodash-compat/lang/isObject') |
| }; |
| |
| var SwaggerSpecConverter = module.exports = function () { |
| this.errors = []; |
| this.warnings = []; |
| this.modelMap = {}; |
| }; |
| |
| SwaggerSpecConverter.prototype.setDocumentationLocation = function (location) { |
| this.docLocation = location; |
| }; |
| |
| /** |
| * converts a resource listing OR api declaration |
| **/ |
| SwaggerSpecConverter.prototype.convert = function (obj, clientAuthorizations, opts, callback) { |
| // not a valid spec |
| if(!obj || !Array.isArray(obj.apis)) { |
| return this.finish(callback, null); |
| } |
| this.clientAuthorizations = clientAuthorizations; |
| |
| // create a new swagger object to return |
| var swagger = { swagger: '2.0' }; |
| |
| swagger.originalVersion = obj.swaggerVersion; |
| |
| // add the info |
| this.apiInfo(obj, swagger); |
| |
| // add security definitions |
| this.securityDefinitions(obj, swagger); |
| |
| // take basePath into account |
| if (obj.basePath) { |
| this.setDocumentationLocation(obj.basePath); |
| } |
| |
| // see if this is a single-file swagger definition |
| var isSingleFileSwagger = false; |
| var i; |
| for(i = 0; i < obj.apis.length; i++) { |
| var api = obj.apis[i]; |
| if(Array.isArray(api.operations)) { |
| isSingleFileSwagger = true; |
| } |
| } |
| if(isSingleFileSwagger) { |
| this.declaration(obj, swagger); |
| this.finish(callback, swagger); |
| } |
| else { |
| this.resourceListing(obj, swagger, opts, callback); |
| } |
| }; |
| |
| SwaggerSpecConverter.prototype.declaration = function(obj, swagger) { |
| var name, i, p, pos; |
| if(!obj.apis) { |
| return; |
| } |
| |
| if (obj.basePath.indexOf('http://') === 0) { |
| p = obj.basePath.substring('http://'.length); |
| pos = p.indexOf('/'); |
| if (pos > 0) { |
| swagger.host = p.substring(0, pos); |
| swagger.basePath = p.substring(pos); |
| } |
| else { |
| swagger.host = p; |
| swagger.basePath = '/'; |
| } |
| } else if (obj.basePath.indexOf('https://') === 0) { |
| p = obj.basePath.substring('https://'.length); |
| pos = p.indexOf('/'); |
| if (pos > 0) { |
| swagger.host = p.substring(0, pos); |
| swagger.basePath = p.substring(pos); |
| } |
| else { |
| swagger.host = p; |
| swagger.basePath = '/'; |
| } |
| } else { |
| swagger.basePath = obj.basePath; |
| } |
| |
| var resourceLevelAuth; |
| if(obj.authorizations) { |
| resourceLevelAuth = obj.authorizations; |
| } |
| if(obj.consumes) { |
| swagger.consumes = obj.consumes; |
| } |
| if(obj.produces) { |
| swagger.produces = obj.produces; |
| } |
| |
| // build a mapping of id to name for 1.0 model resolutions |
| if(_.isObject(obj)) { |
| for(name in obj.models) { |
| var existingModel = obj.models[name]; |
| var key = (existingModel.id || name); |
| this.modelMap[key] = name; |
| } |
| } |
| |
| for(i = 0; i < obj.apis.length; i++) { |
| var api = obj.apis[i]; |
| var path = api.path; |
| var operations = api.operations; |
| this.operations(path, obj.resourcePath, operations, resourceLevelAuth, swagger); |
| } |
| |
| var models = obj.models || {}; |
| this.models(models, swagger); |
| }; |
| |
| SwaggerSpecConverter.prototype.models = function(obj, swagger) { |
| if(!_.isObject(obj)) { |
| return; |
| } |
| var name; |
| |
| swagger.definitions = swagger.definitions || {}; |
| for(name in obj) { |
| var existingModel = obj[name]; |
| var _required = []; |
| var schema = { properties: {}}; |
| var propertyName; |
| for(propertyName in existingModel.properties) { |
| var existingProperty = existingModel.properties[propertyName]; |
| var property = {}; |
| this.dataType(existingProperty, property); |
| if(existingProperty.description) { |
| property.description = existingProperty.description; |
| } |
| if(existingProperty['enum']) { |
| property['enum'] = existingProperty['enum']; |
| } |
| if(typeof existingProperty.required === 'boolean' && existingProperty.required === true) { |
| _required.push(propertyName); |
| } |
| if(typeof existingProperty.required === 'string' && existingProperty.required === 'true') { |
| _required.push(propertyName); |
| } |
| schema.properties[propertyName] = property; |
| } |
| if(_required.length > 0) { |
| schema.required = _required; |
| } else { |
| schema.required = existingModel.required; |
| } |
| swagger.definitions[name] = schema; |
| } |
| }; |
| |
| SwaggerSpecConverter.prototype.extractTag = function(resourcePath) { |
| var pathString = resourcePath || 'default'; |
| if(pathString.indexOf('http:') === 0 || pathString.indexOf('https:') === 0) { |
| pathString = pathString.split(['/']); |
| pathString = pathString[pathString.length -1].substring(); |
| } |
| if(pathString.endsWith('.json')) { |
| pathString = pathString.substring(0, pathString.length - '.json'.length); |
| } |
| return pathString.replace('/',''); |
| }; |
| |
| SwaggerSpecConverter.prototype.operations = function(path, resourcePath, obj, resourceLevelAuth, swagger) { |
| if(!Array.isArray(obj)) { |
| return; |
| } |
| var i; |
| |
| if(!swagger.paths) { |
| swagger.paths = {}; |
| } |
| |
| var pathObj = swagger.paths[path] || {}; |
| var tag = this.extractTag(resourcePath); |
| swagger.tags = swagger.tags || []; |
| var matched = false; |
| for(i = 0; i < swagger.tags.length; i++) { |
| var tagObject = swagger.tags[i]; |
| if(tagObject.name === tag) { |
| matched = true; |
| } |
| } |
| if(!matched) { |
| swagger.tags.push({name: tag}); |
| } |
| |
| for(i = 0; i < obj.length; i++) { |
| var existingOperation = obj[i]; |
| var method = (existingOperation.method || existingOperation.httpMethod).toLowerCase(); |
| var operation = {tags: [tag]}; |
| var existingAuthorizations = existingOperation.authorizations; |
| |
| if(existingAuthorizations && Object.keys(existingAuthorizations).length === 0) { |
| existingAuthorizations = resourceLevelAuth; |
| } |
| |
| if(typeof existingAuthorizations !== 'undefined') { |
| var scopesObject; |
| for(var key in existingAuthorizations) { |
| operation.security = operation.security || []; |
| var scopes = existingAuthorizations[key]; |
| if(scopes) { |
| var securityScopes = []; |
| for(var j in scopes) { |
| securityScopes.push(scopes[j].scope); |
| } |
| scopesObject = {}; |
| scopesObject[key] = securityScopes; |
| operation.security.push(scopesObject); |
| } |
| else { |
| scopesObject = {}; |
| scopesObject[key] = []; |
| operation.security.push(scopesObject); |
| } |
| } |
| } |
| |
| if(existingOperation.consumes) { |
| operation.consumes = existingOperation.consumes; |
| } |
| else if(swagger.consumes) { |
| operation.consumes = swagger.consumes; |
| } |
| if(existingOperation.produces) { |
| operation.produces = existingOperation.produces; |
| } |
| else if(swagger.produces) { |
| operation.produces = swagger.produces; |
| } |
| if(existingOperation.summary) { |
| operation.summary = existingOperation.summary; |
| } |
| if(existingOperation.notes) { |
| operation.description = existingOperation.notes; |
| } |
| if(existingOperation.nickname) { |
| operation.operationId = existingOperation.nickname; |
| } |
| if(existingOperation.deprecated) { |
| operation.deprecated = existingOperation.deprecated; |
| } |
| |
| this.authorizations(existingAuthorizations, swagger); |
| this.parameters(operation, existingOperation.parameters, swagger); |
| this.responseMessages(operation, existingOperation, swagger); |
| |
| pathObj[method] = operation; |
| } |
| |
| swagger.paths[path] = pathObj; |
| }; |
| |
| SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation) { |
| if(!_.isObject(existingOperation)) { |
| return; |
| } |
| // build default response from the operation (1.x) |
| var defaultResponse = {}; |
| this.dataType(existingOperation, defaultResponse); |
| // TODO: look into the real problem of rendering responses in swagger-ui |
| // ....should reponseType have an implicit schema? |
| if(!defaultResponse.schema && defaultResponse.type) { |
| defaultResponse = {schema: defaultResponse}; |
| } |
| |
| operation.responses = operation.responses || {}; |
| |
| // grab from responseMessages (1.2) |
| var has200 = false; |
| if(Array.isArray(existingOperation.responseMessages)) { |
| var i; |
| var existingResponses = existingOperation.responseMessages; |
| for(i = 0; i < existingResponses.length; i++) { |
| var existingResponse = existingResponses[i]; |
| var response = { description: existingResponse.message }; |
| if(existingResponse.code === 200) { |
| has200 = true; |
| } |
| // Convert responseModel -> schema{$ref: responseModel} |
| if(existingResponse.responseModel) { |
| response.schema = {'$ref': '#/definitions/' + existingResponse.responseModel}; |
| } |
| operation.responses['' + existingResponse.code] = response; |
| } |
| } |
| |
| if(has200) { |
| operation.responses['default'] = defaultResponse; |
| } |
| else { |
| operation.responses['200'] = defaultResponse; |
| } |
| }; |
| |
| SwaggerSpecConverter.prototype.authorizations = function(obj) { |
| // TODO |
| if(!_.isObject(obj)) { |
| return; |
| } |
| }; |
| |
| SwaggerSpecConverter.prototype.parameters = function(operation, obj) { |
| if(!Array.isArray(obj)) { |
| return; |
| } |
| var i; |
| for(i = 0; i < obj.length; i++) { |
| var existingParameter = obj[i]; |
| var parameter = {}; |
| parameter.name = existingParameter.name; |
| parameter.description = existingParameter.description; |
| parameter.required = existingParameter.required; |
| parameter.in = existingParameter.paramType; |
| |
| // per #168 |
| if(parameter.in === 'body') { |
| parameter.name = 'body'; |
| } |
| if(parameter.in === 'form') { |
| parameter.in = 'formData'; |
| } |
| |
| if(existingParameter.enum) { |
| parameter.enum = existingParameter.enum; |
| } |
| |
| if(existingParameter.allowMultiple === true || existingParameter.allowMultiple === 'true') { |
| var innerType = {}; |
| this.dataType(existingParameter, innerType); |
| parameter.type = 'array'; |
| parameter.items = innerType; |
| |
| if(existingParameter.allowableValues) { |
| var av = existingParameter.allowableValues; |
| if(av.valueType === 'LIST') { |
| parameter['enum'] = av.values; |
| } |
| } |
| } |
| else { |
| this.dataType(existingParameter, parameter); |
| } |
| if(typeof existingParameter.defaultValue !== 'undefined') { |
| parameter.default = existingParameter.defaultValue; |
| } |
| |
| operation.parameters = operation.parameters || []; |
| operation.parameters.push(parameter); |
| } |
| }; |
| |
| SwaggerSpecConverter.prototype.dataType = function(source, target) { |
| if(!_.isObject(source)) { |
| return; |
| } |
| |
| if(source.minimum) { |
| target.minimum = source.minimum; |
| } |
| if(source.maximum) { |
| target.maximum = source.maximum; |
| } |
| if (source.format) { |
| target.format = source.format; |
| } |
| |
| // default can be 'false' |
| if(typeof source.defaultValue !== 'undefined') { |
| target.default = source.defaultValue; |
| } |
| |
| var jsonSchemaType = this.toJsonSchema(source); |
| if(jsonSchemaType) { |
| target = target || {}; |
| if(jsonSchemaType.type) { |
| target.type = jsonSchemaType.type; |
| } |
| if(jsonSchemaType.format) { |
| target.format = jsonSchemaType.format; |
| } |
| if(jsonSchemaType.$ref) { |
| target.schema = {$ref: jsonSchemaType.$ref}; |
| } |
| if(jsonSchemaType.items) { |
| target.items = jsonSchemaType.items; |
| } |
| } |
| }; |
| |
| SwaggerSpecConverter.prototype.toJsonSchema = function(source) { |
| if(!source) { |
| return 'object'; |
| } |
| var detectedType = (source.type || source.dataType || source.responseClass || ''); |
| var lcType = detectedType.toLowerCase(); |
| var format = (source.format || '').toLowerCase(); |
| |
| if(lcType.indexOf('list[') === 0) { |
| var innerType = detectedType.substring(5, detectedType.length - 1); |
| var jsonType = this.toJsonSchema({type: innerType}); |
| return {type: 'array', items: jsonType}; |
| } else if(lcType === 'int' || (lcType === 'integer' && format === 'int32')) { |
| {return {type: 'integer', format: 'int32'};} |
| } else if(lcType === 'long' || (lcType === 'integer' && format === 'int64')) { |
| {return {type: 'integer', format: 'int64'};} |
| } else if(lcType === 'integer') { |
| {return {type: 'integer', format: 'int64'};} |
| } else if(lcType === 'float' || (lcType === 'number' && format === 'float')) { |
| {return {type: 'number', format: 'float'};} |
| } else if(lcType === 'double' || (lcType === 'number' && format === 'double')) { |
| {return {type: 'number', format: 'double'};} |
| } else if((lcType === 'string' && format === 'date-time') || (lcType === 'date')) { |
| {return {type: 'string', format: 'date-time'};} |
| } else if(lcType === 'string') { |
| {return {type: 'string'};} |
| } else if(lcType === 'file') { |
| {return {type: 'file'};} |
| } else if(lcType === 'boolean') { |
| {return {type: 'boolean'};} |
| } else if(lcType === 'boolean') { |
| {return {type: 'boolean'};} |
| } else if(lcType === 'array' || lcType === 'list') { |
| if(source.items) { |
| var it = this.toJsonSchema(source.items); |
| return {type: 'array', items: it}; |
| } |
| else { |
| return {type: 'array', items: {type: 'object'}}; |
| } |
| } else if(source.$ref) { |
| return {$ref: this.modelMap[source.$ref] ? '#/definitions/' + this.modelMap[source.$ref] : source.$ref}; |
| } else if(lcType === 'void' || lcType === '') { |
| {return {};} |
| } else if (this.modelMap[source.type]) { |
| // If this a model using `type` instead of `$ref`, that's fine. |
| return {$ref: '#/definitions/' + this.modelMap[source.type]}; |
| } else { |
| // Unknown model type or 'object', pass it along. |
| return {type: source.type}; |
| } |
| }; |
| |
| SwaggerSpecConverter.prototype.resourceListing = function(obj, swagger, opts, callback) { |
| var i; |
| var processedCount = 0; // jshint ignore:line |
| var self = this; // jshint ignore:line |
| var expectedCount = obj.apis.length; |
| var _swagger = swagger; // jshint ignore:line |
| var _opts = {}; |
| |
| if(opts && opts.requestInterceptor){ |
| _opts.requestInterceptor = opts.requestInterceptor; |
| } |
| |
| if(opts && opts.responseInterceptor){ |
| _opts.responseInterceptor = opts.responseInterceptor; |
| } |
| |
| var swaggerRequestHeaders = 'application/json'; |
| |
| if(opts && opts.swaggerRequestHeaders) { |
| swaggerRequestHeaders = opts.swaggerRequestHeaders; |
| } |
| |
| if(expectedCount === 0) { |
| this.finish(callback, swagger); |
| } |
| |
| for(i = 0; i < expectedCount; i++) { |
| var api = obj.apis[i]; |
| var path = api.path; |
| var absolutePath = this.getAbsolutePath(obj.swaggerVersion, this.docLocation, path); |
| |
| if(api.description) { |
| swagger.tags = swagger.tags || []; |
| swagger.tags.push({ |
| name : this.extractTag(api.path), |
| description : api.description || '' |
| }); |
| } |
| var http = { |
| url: absolutePath, |
| headers: { accept: swaggerRequestHeaders }, |
| on: {}, |
| method: 'get', |
| timeout: opts.timeout |
| }; |
| /* jshint ignore:start */ |
| http.on.response = function(data) { |
| processedCount += 1; |
| var obj = data.obj; |
| if(obj) { |
| self.declaration(obj, _swagger); |
| } |
| if(processedCount === expectedCount) { |
| self.finish(callback, _swagger); |
| } |
| }; |
| http.on.error = function(data) { |
| console.error(data); |
| processedCount += 1; |
| if(processedCount === expectedCount) { |
| self.finish(callback, _swagger); |
| } |
| }; |
| /* jshint ignore:end */ |
| |
| if(this.clientAuthorizations && typeof this.clientAuthorizations.apply === 'function') { |
| this.clientAuthorizations.apply(http); |
| } |
| |
| new SwaggerHttp().execute(http, _opts); |
| } |
| }; |
| |
| SwaggerSpecConverter.prototype.getAbsolutePath = function(version, docLocation, path) { |
| if(version === '1.0') { |
| if(docLocation.endsWith('.json')) { |
| // get root path |
| var pos = docLocation.lastIndexOf('/'); |
| if(pos > 0) { |
| docLocation = docLocation.substring(0, pos); |
| } |
| } |
| } |
| |
| var location = docLocation; |
| if(path.indexOf('http:') === 0 || path.indexOf('https:') === 0) { |
| location = path; |
| } |
| else { |
| if(docLocation.endsWith('/')) { |
| location = docLocation.substring(0, docLocation.length - 1); |
| } |
| location += path; |
| } |
| location = location.replace('{format}', 'json'); |
| return location; |
| }; |
| |
| SwaggerSpecConverter.prototype.securityDefinitions = function(obj, swagger) { |
| if(obj.authorizations) { |
| var name; |
| for(name in obj.authorizations) { |
| var isValid = false; |
| var securityDefinition = { |
| vendorExtensions: {} |
| }; |
| var definition = obj.authorizations[name]; |
| if(definition.type === 'apiKey') { |
| securityDefinition.type = 'apiKey'; |
| securityDefinition.in = definition.passAs; |
| securityDefinition.name = definition.keyname || name; |
| isValid = true; |
| } |
| else if(definition.type === 'basicAuth') { |
| securityDefinition.type = 'basicAuth'; |
| isValid = true; |
| } |
| else if(definition.type === 'oauth2') { |
| var existingScopes = definition.scopes || []; |
| var scopes = {}; |
| var i; |
| for(i in existingScopes) { |
| var scope = existingScopes[i]; |
| scopes[scope.scope] = scope.description; |
| } |
| securityDefinition.type = 'oauth2'; |
| if(i > 0) { |
| securityDefinition.scopes = scopes; |
| } |
| if(definition.grantTypes) { |
| if(definition.grantTypes.implicit) { |
| var implicit = definition.grantTypes.implicit; |
| securityDefinition.flow = 'implicit'; |
| securityDefinition.authorizationUrl = implicit.loginEndpoint; |
| isValid = true; |
| } |
| /* jshint ignore:start */ |
| if(definition.grantTypes['authorization_code']) { |
| if(!securityDefinition.flow) { |
| // cannot set if flow is already defined |
| var authCode = definition.grantTypes['authorization_code']; |
| securityDefinition.flow = 'accessCode'; |
| securityDefinition.authorizationUrl = authCode.tokenRequestEndpoint.url; |
| securityDefinition.tokenUrl = authCode.tokenEndpoint.url; |
| isValid = true; |
| } |
| } |
| /* jshint ignore:end */ |
| } |
| } |
| if(isValid) { |
| swagger.securityDefinitions = swagger.securityDefinitions || {}; |
| swagger.securityDefinitions[name] = securityDefinition; |
| } |
| } |
| } |
| }; |
| |
| SwaggerSpecConverter.prototype.apiInfo = function(obj, swagger) { |
| // info section |
| if(obj.info) { |
| var info = obj.info; |
| swagger.info = {}; |
| |
| if(info.contact) { |
| swagger.info.contact = {}; |
| swagger.info.contact.email = info.contact; |
| } |
| if(info.description) { |
| swagger.info.description = info.description; |
| } |
| if(info.title) { |
| swagger.info.title = info.title; |
| } |
| if(info.termsOfServiceUrl) { |
| swagger.info.termsOfService = info.termsOfServiceUrl; |
| } |
| if(info.license || info.licenseUrl) { |
| swagger.license = {}; |
| if(info.license) { |
| swagger.license.name = info.license; |
| } |
| if(info.licenseUrl) { |
| swagger.license.url = info.licenseUrl; |
| } |
| } |
| } |
| else { |
| this.warnings.push('missing info section'); |
| } |
| }; |
| |
| SwaggerSpecConverter.prototype.finish = function (callback, obj) { |
| callback(obj); |
| }; |
| |
| },{"./http":5,"lodash-compat/lang/isObject":144}],9:[function(require,module,exports){ |
| 'use strict'; |
| |
| var log = require('../helpers').log; |
| var _ = { |
| isPlainObject: require('lodash-compat/lang/isPlainObject'), |
| isString: require('lodash-compat/lang/isString'), |
| }; |
| |
| var SchemaMarkup = require('../schema-markup.js'); |
| var jsyaml = require('js-yaml'); |
| |
| var Model = module.exports = function (name, definition, models, modelPropertyMacro) { |
| this.definition = definition || {}; |
| this.isArray = definition.type === 'array'; |
| this.models = models || {}; |
| this.name = name || definition.title || 'Inline Model'; |
| this.modelPropertyMacro = modelPropertyMacro || function (property) { |
| return property.default; |
| }; |
| |
| return this; |
| }; |
| |
| // Note! This function will be removed in 2.2.x! |
| Model.prototype.createJSONSample = Model.prototype.getSampleValue = function (modelsToIgnore) { |
| modelsToIgnore = modelsToIgnore || {}; |
| |
| modelsToIgnore[this.name] = this; |
| |
| // Response support |
| if (this.examples && _.isPlainObject(this.examples) && this.examples['application/json']) { |
| this.definition.example = this.examples['application/json']; |
| |
| if (_.isString(this.definition.example)) { |
| this.definition.example = jsyaml.safeLoad(this.definition.example); |
| } |
| } else if (!this.definition.example) { |
| this.definition.example = this.examples; |
| } |
| |
| return SchemaMarkup.schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro); |
| }; |
| |
| Model.prototype.getMockSignature = function () { |
| return SchemaMarkup.schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro); |
| }; |
| |
| },{"../helpers":4,"../schema-markup.js":7,"js-yaml":19,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isString":146}],10:[function(require,module,exports){ |
| 'use strict'; |
| |
| var _ = { |
| cloneDeep: require('lodash-compat/lang/cloneDeep'), |
| isUndefined: require('lodash-compat/lang/isUndefined'), |
| isEmpty: require('lodash-compat/lang/isEmpty'), |
| isObject: require('lodash-compat/lang/isObject') |
| }; |
| var helpers = require('../helpers'); |
| var Model = require('./model'); |
| var SwaggerHttp = require('../http'); |
| var Q = require('q'); |
| |
| var Operation = module.exports = function (parent, scheme, operationId, httpMethod, path, args, definitions, models, clientAuthorizations) { |
| var errors = []; |
| |
| parent = parent || {}; |
| args = args || {}; |
| |
| if(parent && parent.options) { |
| this.client = parent.options.client || null; |
| this.requestInterceptor = parent.options.requestInterceptor || null; |
| this.responseInterceptor = parent.options.responseInterceptor || null; |
| this.requestAgent = parent.options.requestAgent; |
| } |
| this.authorizations = args.security; |
| this.basePath = parent.basePath || '/'; |
| this.clientAuthorizations = clientAuthorizations; |
| this.consumes = args.consumes || parent.consumes || ['application/json']; |
| this.produces = args.produces || parent.produces || ['application/json']; |
| this.deprecated = args.deprecated; |
| this.description = args.description; |
| this.host = parent.host; |
| this.method = (httpMethod || errors.push('Operation ' + operationId + ' is missing method.')); |
| this.models = models || {}; |
| this.nickname = (operationId || errors.push('Operations must have a nickname.')); |
| this.operation = args; |
| this.operations = {}; |
| this.parameters = args !== null ? (args.parameters || []) : {}; |
| this.parent = parent; |
| this.path = (path || errors.push('Operation ' + this.nickname + ' is missing path.')); |
| this.responses = (args.responses || {}); |
| this.scheme = scheme || parent.scheme || 'http'; |
| this.schemes = args.schemes || parent.schemes; |
| this.security = args.security || parent.security; |
| this.summary = args.summary || ''; |
| this.timeout = parent.timeout; |
| this.type = null; |
| this.useJQuery = parent.useJQuery; |
| this.jqueryAjaxCache = parent.jqueryAjaxCache; |
| this.enableCookies = parent.enableCookies; |
| |
| var key; |
| |
| if(!this.host) { |
| if(typeof window !== 'undefined') { |
| this.host = window.location.host; |
| } |
| else { |
| this.host = 'localhost'; |
| } |
| } |
| this.parameterMacro = parent.parameterMacro || function (operation, parameter) { |
| return parameter.default; |
| }; |
| |
| this.inlineModels = []; |
| |
| if(this.basePath !== '/' && this.basePath.slice(-1) === '/') { |
| this.basePath = this.basePath.slice(0, -1); |
| } |
| |
| if (typeof this.deprecated === 'string') { |
| switch(this.deprecated.toLowerCase()) { |
| case 'true': case 'yes': case '1': { |
| this.deprecated = true; |
| break; |
| } |
| |
| case 'false': case 'no': case '0': case null: { |
| this.deprecated = false; |
| break; |
| } |
| |
| default: this.deprecated = Boolean(this.deprecated); |
| } |
| } |
| |
| var i, model; |
| |
| if (definitions) { |
| // add to global models |
| for (key in definitions) { |
| model = new Model(key, definitions[key], this.models, parent.modelPropertyMacro); |
| |
| if (model) { |
| this.models[key] = model; |
| } |
| } |
| } |
| else { |
| definitions = {}; |
| } |
| |
| for (i = 0; i < this.parameters.length; i++) { |
| var d, param = this.parameters[i]; |
| |
| // Allow macro to set the default value |
| param.default = this.parameterMacro(this, param); |
| |
| if (param.type === 'array') { |
| param.isList = true; |
| param.allowMultiple = true; |
| } |
| |
| var innerType = this.getType(param); |
| |
| if (innerType && innerType.toString().toLowerCase() === 'boolean') { |
| param.allowableValues = {}; |
| param.isList = true; |
| param['enum'] = [true, false]; // use actual primitives |
| } |
| |
| for(key in param) { |
| helpers.extractExtensions(key, param); |
| } |
| if(typeof param['x-example'] !== 'undefined') { |
| d = param['x-example']; |
| param.default = d; |
| } |
| if(param['x-examples']) { |
| d = param['x-examples'].default; |
| if(typeof d !== 'undefined') { |
| param.default = d; |
| } |
| } |
| |
| var enumValues = param['enum'] || (param.items && param.items['enum']); |
| |
| if (typeof enumValues !== 'undefined') { |
| var id; |
| |
| param.allowableValues = {}; |
| param.allowableValues.values = []; |
| param.allowableValues.descriptiveValues = []; |
| |
| for (id = 0; id < enumValues.length; id++) { |
| var value = enumValues[id]; |
| var isDefault = (value === param.default || value+'' === param.default); |
| |
| param.allowableValues.values.push(value); |
| // Always have string for descriptive values.... |
| param.allowableValues.descriptiveValues.push({value : value+'', isDefault: isDefault}); |
| } |
| } |
| |
| if (param.type === 'array') { |
| innerType = [innerType]; |
| |
| if (typeof param.allowableValues === 'undefined') { |
| // can't show as a list if no values to select from |
| delete param.isList; |
| delete param.allowMultiple; |
| } |
| } |
| |
| param.modelSignature = {type: innerType, definitions: this.models}; |
| param.signature = this.getModelSignature(innerType, this.models).toString(); |
| param.sampleJSON = this.getModelSampleJSON(innerType, this.models); |
| param.responseClassSignature = param.signature; |
| } |
| |
| var keyname, defaultResponseCode, response, responses = this.responses; |
| |
| if (responses['200']) { |
| response = responses['200']; |
| defaultResponseCode = '200'; |
| } else if (responses['201']) { |
| response = responses['201']; |
| defaultResponseCode = '201'; |
| } else if (responses['202']) { |
| response = responses['202']; |
| defaultResponseCode = '202'; |
| } else if (responses['203']) { |
| response = responses['203']; |
| defaultResponseCode = '203'; |
| } else if (responses['204']) { |
| response = responses['204']; |
| defaultResponseCode = '204'; |
| } else if (responses['205']) { |
| response = responses['205']; |
| defaultResponseCode = '205'; |
| } else if (responses['206']) { |
| response = responses['206']; |
| defaultResponseCode = '206'; |
| } else if (responses['default']) { |
| response = responses['default']; |
| defaultResponseCode = 'default'; |
| } |
| |
| for(keyname in responses) { |
| helpers.extractExtensions(keyname, responses); |
| if(typeof keyname === 'string' && keyname.indexOf('x-') === -1) { |
| var responseObject = responses[keyname]; |
| if(typeof responseObject === 'object' && typeof responseObject.headers === 'object') { |
| var headers = responseObject.headers; |
| for(var headerName in headers) { |
| var header = headers[headerName]; |
| if(typeof header === 'object') { |
| for(var headerKey in header) { |
| helpers.extractExtensions(headerKey, header); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| if (response) { |
| for(keyname in response) { |
| helpers.extractExtensions(keyname, response); |
| } |
| } |
| |
| if (response && response.schema) { |
| var resolvedModel = this.resolveModel(response.schema, definitions); |
| var successResponse; |
| |
| delete responses[defaultResponseCode]; |
| |
| if (resolvedModel) { |
| this.successResponse = {}; |
| successResponse = this.successResponse[defaultResponseCode] = resolvedModel; |
| } else if (!response.schema.type || response.schema.type === 'object' || response.schema.type === 'array') { |
| // Inline model |
| this.successResponse = {}; |
| successResponse = this.successResponse[defaultResponseCode] = new Model(undefined, response.schema || {}, this.models, parent.modelPropertyMacro); |
| } else { |
| // Primitive |
| this.successResponse = {}; |
| successResponse = this.successResponse[defaultResponseCode] = response.schema; |
| } |
| |
| if (successResponse) { |
| successResponse.vendorExtensions = response.vendorExtensions; |
| // Attach response properties |
| if (response.description) { |
| successResponse.description = response.description; |
| } |
| |
| if (response.examples) { |
| successResponse.examples = response.examples; |
| } |
| |
| if (response.headers) { |
| successResponse.headers = response.headers; |
| } |
| } |
| |
| this.type = response; |
| } |
| |
| if (errors.length > 0) { |
| if (this.resource && this.resource.api && this.resource.api.fail) { |
| this.resource.api.fail(errors); |
| } |
| } |
| |
| return this; |
| }; |
| |
| Operation.prototype.isDefaultArrayItemValue = function(value, param) { |
| if (param.default && Array.isArray(param.default)) { |
| return param.default.indexOf(value) !== -1; |
| } |
| return value === param.default; |
| }; |
| |
| Operation.prototype.getType = function (param) { |
| var type = param.type; |
| var format = param.format; |
| var isArray = false; |
| var str; |
| |
| if (type === 'integer' && format === 'int32') { |
| str = 'integer'; |
| } else if (type === 'integer' && format === 'int64') { |
| str = 'long'; |
| } else if (type === 'integer') { |
| str = 'integer'; |
| } else if (type === 'string') { |
| if (format === 'date-time') { |
| str = 'date-time'; |
| } else if (format === 'date') { |
| str = 'date'; |
| } else { |
| str = 'string'; |
| } |
| } else if (type === 'number' && format === 'float') { |
| str = 'float'; |
| } else if (type === 'number' && format === 'double') { |
| str = 'double'; |
| } else if (type === 'number') { |
| str = 'double'; |
| } else if (type === 'boolean') { |
| str = 'boolean'; |
| } else if (type === 'array') { |
| isArray = true; |
| |
| if (param.items) { |
| str = this.getType(param.items); |
| } |
| } else if (type === 'file') { |
| str = 'file'; |
| } |
| |
| if (param.$ref) { |
| str = helpers.simpleRef(param.$ref); |
| } |
| |
| var schema = param.schema; |
| |
| if (schema) { |
| var ref = schema.$ref; |
| |
| if (ref) { |
| ref = helpers.simpleRef(ref); |
| |
| if (isArray) { |
| return [ ref ]; |
| } else { |
| return ref; |
| } |
| } else { |
| // If inline schema, we add it our interal hash -> which gives us it's ID (int) |
| if(schema.type === 'object') { |
| return this.addInlineModel(schema); |
| } |
| return this.getType(schema); |
| } |
| } |
| if (isArray) { |
| return [ str ]; |
| } else { |
| return str; |
| } |
| }; |
| |
| /** |
| * adds an inline schema (model) to a hash, where we can ref it later |
| * @param {object} schema a schema |
| * @return {number} the ID of the schema being added, or null |
| **/ |
| Operation.prototype.addInlineModel = function (schema) { |
| var len = this.inlineModels.length; |
| var model = this.resolveModel(schema, {}); |
| if(model) { |
| this.inlineModels.push(model); |
| return 'Inline Model '+len; // return string ref of the inline model (used with #getInlineModel) |
| } |
| return null; // report errors? |
| }; |
| |
| /** |
| * gets the internal ref to an inline model |
| * @param {string} inline_str a string reference to an inline model |
| * @return {Model} the model being referenced. Or null |
| **/ |
| Operation.prototype.getInlineModel = function(inlineStr) { |
| if(/^Inline Model \d+$/.test(inlineStr)) { |
| var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); // |
| var model = this.inlineModels[id]; |
| return model; |
| } |
| // I'm returning null here, should I rather throw an error? |
| return null; |
| }; |
| |
| Operation.prototype.resolveModel = function (schema, definitions) { |
| if (typeof schema.$ref !== 'undefined') { |
| var ref = schema.$ref; |
| |
| if (ref.indexOf('#/definitions/') === 0) { |
| ref = ref.substring('#/definitions/'.length); |
| } |
| |
| if (definitions[ref]) { |
| return new Model(ref, definitions[ref], this.models, this.parent.modelPropertyMacro); |
| } |
| // schema must at least be an object to get resolved to an inline Model |
| } else if (schema && typeof schema === 'object' && |
| (schema.type === 'object' || _.isUndefined(schema.type))) { |
| return new Model(undefined, schema, this.models, this.parent.modelPropertyMacro); |
| } |
| |
| return null; |
| }; |
| |
| Operation.prototype.help = function (dontPrint) { |
| var out = this.nickname + ': ' + this.summary + '\n'; |
| |
| for (var i = 0; i < this.parameters.length; i++) { |
| var param = this.parameters[i]; |
| var typeInfo = param.signature; |
| |
| out += '\n * ' + param.name + ' (' + typeInfo + '): ' + param.description; |
| } |
| |
| if (typeof dontPrint === 'undefined') { |
| helpers.log(out); |
| } |
| |
| return out; |
| }; |
| |
| Operation.prototype.getModelSignature = function (type, definitions) { |
| var isPrimitive, listType; |
| |
| if (type instanceof Array) { |
| listType = true; |
| type = type[0]; |
| } |
| |
| // Convert undefined to string of 'undefined' |
| if (typeof type === 'undefined') { |
| type = 'undefined'; |
| isPrimitive = true; |
| |
| } else if (definitions[type]){ |
| // a model def exists? |
| type = definitions[type]; /* Model */ |
| isPrimitive = false; |
| |
| } else if (this.getInlineModel(type)) { |
| type = this.getInlineModel(type); /* Model */ |
| isPrimitive = false; |
| |
| } else { |
| // We default to primitive |
| isPrimitive = true; |
| } |
| |
| if (isPrimitive) { |
| if (listType) { |
| return 'Array[' + type + ']'; |
| } else { |
| return type.toString(); |
| } |
| } else { |
| if (listType) { |
| return 'Array[' + type.getMockSignature() + ']'; |
| } else { |
| return type.getMockSignature(); |
| } |
| } |
| }; |
| |
| Operation.prototype.supportHeaderParams = function () { |
| return true; |
| }; |
| |
| Operation.prototype.supportedSubmitMethods = function () { |
| return this.parent.supportedSubmitMethods; |
| }; |
| |
| Operation.prototype.getHeaderParams = function (args) { |
| var headers = this.setContentTypes(args, {}); |
| var headerParamsByLowerCase = {}; |
| |
| for (var i = 0; i < this.parameters.length; i++) { |
| var param = this.parameters[i]; |
| |
| if (param.in === 'header') { |
| headerParamsByLowerCase[param.name.toLowerCase()] = param; |
| } |
| } |
| |
| for (var arg in args) { |
| var headerParam = headerParamsByLowerCase[arg.toLowerCase()]; |
| if (typeof headerParam !== 'undefined') { |
| var value = args[arg]; |
| |
| if (Array.isArray(value)) { |
| value = value.toString(); |
| } |
| |
| headers[headerParam.name] = value; |
| } |
| } |
| |
| return headers; |
| }; |
| |
| Operation.prototype.urlify = function (args, maskPasswords) { |
| var formParams = {}; |
| var requestUrl = this.path.replace(/#.*/, ''); // remove URL fragment |
| var querystring = ''; // grab params from the args, build the querystring along the way |
| |
| for (var i = 0; i < this.parameters.length; i++) { |
| var param = this.parameters[i]; |
| |
| if (typeof args[param.name] !== 'undefined') { |
| var isPassword; |
| if(param.type === 'string' && param.format === 'password' && maskPasswords) { |
| isPassword = true; |
| } |
| |
| if (param.in === 'path') { |
| var reg = new RegExp('\{' + param.name + '\}', 'gi'); |
| var value = args[param.name]; |
| |
| if (Array.isArray(value)) { |
| value = this.encodePathCollection(param.collectionFormat, param.name, value, isPassword); |
| } else { |
| value = this.encodePathParam(value, isPassword); |
| } |
| |
| requestUrl = requestUrl.replace(reg, value); |
| } else if (param.in === 'query' && typeof args[param.name] !== 'undefined') { |
| if (querystring === '' && requestUrl.indexOf('?') < 0) { |
| querystring += '?'; |
| } else { |
| querystring += '&'; |
| } |
| |
| if (typeof param.collectionFormat !== 'undefined') { |
| var qp = args[param.name]; |
| |
| if (Array.isArray(qp)) { |
| querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp, isPassword); |
| } else { |
| querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam(args[param.name], isPassword); |
| } |
| } else { |
| querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam(args[param.name], isPassword); |
| } |
| } else if (param.in === 'formData') { |
| formParams[param.name] = args[param.name]; |
| } |
| } |
| } |
| var url = this.scheme + '://' + this.host; |
| |
| if (this.basePath !== '/') { |
| url += this.basePath; |
| } |
| return url + requestUrl + querystring; |
| }; |
| |
| Operation.prototype.getMissingParams = function (args) { |
| var missingParams = []; // check required params, track the ones that are missing |
| var i; |
| |
| for (i = 0; i < this.parameters.length; i++) { |
| var param = this.parameters[i]; |
| |
| if (param.required === true) { |
| if (typeof args[param.name] === 'undefined') { |
| missingParams = param.name; |
| } |
| } |
| } |
| |
| return missingParams; |
| }; |
| |
| Operation.prototype.getBody = function (headers, args) { |
| var formParams = {}, hasFormParams, param, body, key, value, hasBody = false; |
| |
| // look at each param and put form params in an object |
| for (var i = 0; i < this.parameters.length; i++) { |
| param = this.parameters[i]; |
| if (typeof args[param.name] !== 'undefined') { |
| var isPassword; |
| if(param.type === 'string' && param.format === 'password') { |
| isPassword = 'password'; |
| } |
| if (param.in === 'body') { |
| body = args[param.name]; |
| } else if (param.in === 'formData') { |
| formParams[param.name] = { |
| param: param, |
| value: args[param.name], |
| password: isPassword |
| }; |
| hasFormParams = true; |
| } |
| } |
| else { |
| if(param.in === 'body') { |
| hasBody = true; |
| } |
| } |
| } |
| |
| // if body is null and hasBody is true, AND a JSON body is requested, send empty {} |
| if(hasBody && typeof body === 'undefined') { |
| var contentType = headers['Content-Type']; |
| if(contentType && contentType.indexOf('application/json') === 0) { |
| body = '{}'; |
| } |
| } |
| |
| var isMultiPart = false; |
| if(headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) { |
| isMultiPart = true; |
| } |
| |
| // handle form params |
| if (hasFormParams && !isMultiPart) { |
| var encoded = ''; |
| |
| for (key in formParams) { |
| param = formParams[key].param; |
| value = formParams[key].value; |
| var password = formParams[key].password; |
| |
| if (typeof value !== 'undefined') { |
| if (Array.isArray(value)) { |
| if (encoded !== '') { |
| encoded += '&'; |
| } |
| encoded += this.encodeQueryCollection(param.collectionFormat, key, value, password); |
| } |
| else { |
| if (encoded !== '') { |
| encoded += '&'; |
| } |
| |
| encoded += encodeURIComponent(key) + '=' + mask(encodeURIComponent(value), password); |
| } |
| } |
| } |
| |
| body = encoded; |
| } else if (isMultiPart) { |
| var bodyParam; |
| if (typeof FormData === 'function') { |
| bodyParam = new FormData(); |
| |
| bodyParam.type = 'formData'; |
| |
| for (key in formParams) { |
| param = formParams[key].param; |
| value = args[key]; |
| |
| if (typeof value !== 'undefined') { |
| if({}.toString.apply(value) === '[object File]') { |
| bodyParam.append(key, value); |
| } |
| else if (value.type === 'file' && value.value) { |
| bodyParam.append(key, value.value); |
| } else { |
| if (Array.isArray(value)) { |
| if(param.collectionFormat === 'multi') { |
| bodyParam.delete(key); |
| for(var v in value) { |
| bodyParam.append(key, value[v]); |
| } |
| } |
| else { |
| bodyParam.append(key, this.encodeQueryCollection(param.collectionFormat, key, value).split('=').slice(1).join('=')); |
| } |
| } |
| else { |
| bodyParam.append(key, value); |
| } |
| } |
| } |
| } |
| body = bodyParam; |
| } |
| else { |
| bodyParam = {}; |
| for (key in formParams) { |
| value = args[key]; |
| if (Array.isArray(value)) { |
| var delimeter; |
| var format = param.collectionFormat || 'multi'; |
| if(format === 'ssv') { |
| delimeter = ' '; |
| } |
| else if(format === 'pipes') { |
| delimeter = '|'; |
| } |
| else if(format === 'tsv') { |
| delimeter = '\t'; |
| } |
| else if(format === 'multi') { |
| bodyParam[key] = value; |
| break; |
| } |
| else { |
| delimeter = ','; |
| } |
| var data; |
| value.forEach(function(v) { |
| if(data) { |
| data += delimeter; |
| } |
| else { |
| data = ''; |
| } |
| data += v; |
| }); |
| bodyParam[key] = data; |
| } |
| else { |
| bodyParam[key] = value; |
| } |
| } |
| body = bodyParam; |
| } |
| headers['Content-Type'] = 'multipart/form-data'; |
| } |
| |
| return body; |
| }; |
| |
| /** |
| * gets sample response for a single operation |
| **/ |
| Operation.prototype.getModelSampleJSON = function (type, models) { |
| var listType, sampleJson, innerType; |
| models = models || {}; |
| |
| listType = (type instanceof Array); |
| innerType = listType ? type[0] : type; |
| |
| if(models[innerType]) { |
| sampleJson = models[innerType].createJSONSample(); |
| } else if (this.getInlineModel(innerType)){ |
| sampleJson = this.getInlineModel(innerType).createJSONSample(); // may return null, if type isn't correct |
| } |
| |
| |
| if (sampleJson) { |
| sampleJson = listType ? [sampleJson] : sampleJson; |
| |
| if (typeof sampleJson === 'string') { |
| return sampleJson; |
| } else if (_.isObject(sampleJson)) { |
| var t = sampleJson; |
| |
| if (sampleJson instanceof Array && sampleJson.length > 0) { |
| t = sampleJson[0]; |
| } |
| |
| if (t.nodeName && typeof t === 'Node') { |
| var xmlString = new XMLSerializer().serializeToString(t); |
| |
| return this.formatXml(xmlString); |
| } else { |
| return JSON.stringify(sampleJson, null, 2); |
| } |
| } else { |
| return sampleJson; |
| } |
| } |
| }; |
| |
| /** |
| * legacy binding |
| **/ |
| Operation.prototype.do = function (args, opts, callback, error, parent) { |
| return this.execute(args, opts, callback, error, parent); |
| }; |
| |
| /** |
| * executes an operation |
| **/ |
| Operation.prototype.execute = function (arg1, arg2, arg3, arg4, parent) { |
| var args = arg1 || {}; |
| var opts = {}, success, error, deferred, timeout; |
| |
| if (_.isObject(arg2)) { |
| opts = arg2; |
| success = arg3; |
| error = arg4; |
| } |
| |
| timeout = typeof opts.timeout !== 'undefined' ? opts.timeout : this.timeout; |
| |
| if(this.client) { |
| opts.client = this.client; |
| } |
| |
| if(this.requestAgent) { |
| opts.requestAgent = this.requestAgent; |
| } |
| |
| // add the request interceptor from parent, if none sent from client |
| if(!opts.requestInterceptor && this.requestInterceptor ) { |
| opts.requestInterceptor = this.requestInterceptor ; |
| } |
| |
| if(!opts.responseInterceptor && this.responseInterceptor) { |
| opts.responseInterceptor = this.responseInterceptor; |
| } |
| |
| if (typeof arg2 === 'function') { |
| success = arg2; |
| error = arg3; |
| } |
| |
| if (this.parent.usePromise) { |
| deferred = Q.defer(); |
| } else { |
| success = (success || this.parent.defaultSuccessCallback || helpers.log); |
| error = (error || this.parent.defaultErrorCallback || helpers.log); |
| } |
| |
| if (typeof opts.useJQuery === 'undefined') { |
| opts.useJQuery = this.useJQuery; |
| } |
| |
| if (typeof opts.jqueryAjaxCache === 'undefined') { |
| opts.jqueryAjaxCache = this.jqueryAjaxCache; |
| } |
| |
| if (typeof opts.enableCookies === 'undefined') { |
| opts.enableCookies = this.enableCookies; |
| } |
| |
| var missingParams = this.getMissingParams(args); |
| |
| if (missingParams.length > 0) { |
| var message = 'missing required params: ' + missingParams; |
| |
| helpers.fail(message); |
| |
| if (this.parent.usePromise) { |
| deferred.reject(message); |
| return deferred.promise; |
| } else { |
| error(message, parent); |
| return {}; |
| } |
| } |
| |
| var allHeaders = this.getHeaderParams(args); |
| var contentTypeHeaders = this.setContentTypes(args, opts); |
| var headers = {}, attrname; |
| |
| for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; } |
| for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; } |
| |
| var body = this.getBody(contentTypeHeaders, args, opts); |
| var url = this.urlify(args, opts.maskPasswords); |
| |
| if(url.indexOf('.{format}') > 0) { |
| if(headers) { |
| var format = headers.Accept || headers.accept; |
| if(format && format.indexOf('json') > 0) { |
| url = url.replace('.{format}', '.json'); |
| } |
| else if(format && format.indexOf('xml') > 0) { |
| url = url.replace('.{format}', '.xml'); |
| } |
| } |
| } |
| |
| var obj = { |
| url: url, |
| method: this.method.toUpperCase(), |
| body: body, |
| enableCookies: opts.enableCookies, |
| useJQuery: opts.useJQuery, |
| jqueryAjaxCache: opts.jqueryAjaxCache, |
| deferred: deferred, |
| headers: headers, |
| clientAuthorizations: opts.clientAuthorizations, |
| operation: this, |
| connectionAgent: this.connectionAgent, |
| on: { |
| response: function (response) { |
| if (deferred) { |
| deferred.resolve(response); |
| return deferred.promise; |
| } else { |
| return success(response, parent); |
| } |
| }, |
| error: function (response) { |
| if (deferred) { |
| deferred.reject(response); |
| return deferred.promise; |
| } else { |
| return error(response, parent); |
| } |
| } |
| } |
| }; |
| |
| if (timeout) { |
| obj.timeout = timeout; |
| } |
| |
| this.clientAuthorizations.apply(obj, this.operation.security); |
| if (opts.mock === true) { |
| return obj; |
| } else { |
| return new SwaggerHttp().execute(obj, opts); |
| } |
| }; |
| |
| function itemByPriority(col, itemPriority) { |
| |
| // No priorities? return first... |
| if(_.isEmpty(itemPriority)) { |
| return col[0]; |
| } |
| |
| for (var i = 0, len = itemPriority.length; i < len; i++) { |
| if(col.indexOf(itemPriority[i]) > -1) { |
| return itemPriority[i]; |
| } |
| } |
| |
| // Otherwise return first |
| return col[0]; |
| } |
| |
| Operation.prototype.setContentTypes = function (args, opts) { |
| // default type |
| var allDefinedParams = this.parameters; |
| var body; |
| var consumes = args.parameterContentType || itemByPriority(this.consumes, ['application/json', 'application/yaml']); |
| var accepts = opts.responseContentType || itemByPriority(this.produces, ['application/json', 'application/yaml']); |
| var definedFileParams = []; |
| var definedFormParams = []; |
| var headers = {}; |
| var i; |
| |
| // get params from the operation and set them in definedFileParams, definedFormParams, headers |
| for (i = 0; i < allDefinedParams.length; i++) { |
| var param = allDefinedParams[i]; |
| |
| if (param.in === 'formData') { |
| if (param.type === 'file') { |
| definedFileParams.push(param); |
| } else { |
| definedFormParams.push(param); |
| } |
| } else if (param.in === 'header' && opts) { |
| var key = param.name; |
| var headerValue = opts[param.name]; |
| |
| if (typeof opts[param.name] !== 'undefined') { |
| headers[key] = headerValue; |
| } |
| } else if (param.in === 'body' && typeof args[param.name] !== 'undefined') { |
| body = args[param.name]; |
| } |
| } |
| |
| // if there's a body, need to set the consumes header via requestContentType |
| var hasBody = body || definedFileParams.length || definedFormParams.length; |
| if (this.method === 'post' || this.method === 'put' || this.method === 'patch' || |
| ((this.method === 'delete' || this.method === 'get') && hasBody)) { |
| if (opts.requestContentType) { |
| consumes = opts.requestContentType; |
| } |
| // if any form params, content type must be set |
| if (definedFormParams.length > 0) { |
| consumes = undefined; |
| if (opts.requestContentType) { // override if set |
| consumes = opts.requestContentType; |
| } else if (definedFileParams.length > 0) { // if a file, must be multipart/form-data |
| consumes = 'multipart/form-data'; |
| } else { |
| if (this.consumes && this.consumes.length > 0) { |
| // use the consumes setting |
| for(var c in this.consumes) { |
| var chk = this.consumes[c]; |
| if(chk.indexOf('application/x-www-form-urlencoded') === 0 || chk.indexOf('multipart/form-data') === 0) { |
| consumes = chk; |
| } |
| } |
| } |
| } |
| if(typeof consumes === 'undefined') { |
| // default to x-www-from-urlencoded |
| consumes = 'application/x-www-form-urlencoded'; |
| } |
| } |
| } |
| else { |
| consumes = null; |
| } |
| |
| if (consumes && this.consumes) { |
| if (this.consumes.indexOf(consumes) === -1) { |
| helpers.log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes)); |
| } |
| } |
| |
| if (!this.matchesAccept(accepts)) { |
| helpers.log('server can\'t produce ' + accepts); |
| } |
| |
| if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) { |
| headers['Content-Type'] = consumes; |
| } |
| else if(this.consumes && this.consumes.length > 0 && this.consumes[0] === 'application/x-www-form-urlencoded') { |
| headers['Content-Type'] = this.consumes[0]; |
| } |
| |
| if (accepts) { |
| headers.Accept = accepts; |
| } |
| |
| return headers; |
| }; |
| |
| /** |
| * Returns true if the request accepts header matches anything in this.produces. |
| * If this.produces contains * / *, ignore the accept header. |
| * @param {string=} accepts The client request accept header. |
| * @return {boolean} |
| */ |
| Operation.prototype.matchesAccept = function(accepts) { |
| // no accepts or produces, no problem! |
| if (!accepts || !this.produces) { |
| return true; |
| } |
| return this.produces.indexOf(accepts) !== -1 || this.produces.indexOf('*/*') !== -1; |
| }; |
| |
| Operation.prototype.asCurl = function (args1, args2) { |
| var opts = {mock: true, maskPasswords: true}; |
| if (typeof args2 === 'object') { |
| for (var argKey in args2) { |
| opts[argKey] = args2[argKey]; |
| } |
| } |
| var obj = this.execute(args1, opts); |
| |
| this.clientAuthorizations.apply(obj, this.operation.security); |
| |
| var results = []; |
| |
| results.push('-X ' + this.method.toUpperCase()); |
| |
| if (typeof obj.headers !== 'undefined') { |
| var key; |
| |
| for (key in obj.headers) { |
| var value = obj.headers[key]; |
| if(typeof value === 'string'){ |
| value = value.replace(/\'/g, '\\u0027'); |
| } |
| results.push('--header \'' + key + ': ' + value + '\''); |
| } |
| } |
| var isFormData = false; |
| var isMultipart = false; |
| |
| var type = obj.headers['Content-Type']; |
| if(type && type.indexOf('application/x-www-form-urlencoded') === 0) { |
| isFormData = true; |
| } |
| else if (type && type.indexOf('multipart/form-data') === 0) { |
| isFormData = true; |
| isMultipart = true; |
| } |
| |
| if (obj.body) { |
| var body; |
| if (_.isObject(obj.body)) { |
| if(isMultipart) { |
| isMultipart = true; |
| // add the form data |
| for(var i = 0; i < this.parameters.length; i++) { |
| var parameter = this.parameters[i]; |
| if(parameter.in === 'formData') { |
| if (!body) { |
| body = ''; |
| } |
| |
| var paramValue; |
| if(typeof FormData === 'function' && obj.body instanceof FormData) { |
| paramValue = obj.body.getAll(parameter.name); |
| } |
| else { |
| paramValue = obj.body[parameter.name]; |
| } |
| if (paramValue) { |
| if (parameter.type === 'file') { |
| if(paramValue.name) { |
| body += '-F ' + parameter.name + '=@"' + paramValue.name + '" '; |
| } |
| } |
| else { |
| if (Array.isArray(paramValue)) { |
| if(parameter.collectionFormat === 'multi') { |
| for(var v in paramValue) { |
| body += '-F ' + this.encodeQueryKey(parameter.name) + '=' + mask(paramValue[v], parameter.format) + ' '; |
| } |
| } |
| else { |
| body += '-F ' + this.encodeQueryCollection(parameter.collectionFormat, parameter.name, mask(paramValue, parameter.format)) + ' '; |
| } |
| } else { |
| body += '-F ' + this.encodeQueryKey(parameter.name) + '=' + mask(paramValue, parameter.format) + ' '; |
| } |
| } |
| } |
| } |
| } |
| } |
| if(!body) { |
| body = JSON.stringify(obj.body); |
| } |
| } else { |
| body = obj.body; |
| } |
| // escape @ => %40, ' => %27 |
| body = body.replace(/\'/g, '%27').replace(/\n/g, ' \\ \n '); |
| |
| if(!isFormData) { |
| // escape & => %26 |
| body = body.replace(/&/g, '%26'); |
| } |
| if(isMultipart) { |
| results.push(body); |
| } |
| else { |
| results.push('-d \'' + body.replace(/@/g, '%40') + '\''); |
| } |
| } |
| |
| return 'curl ' + (results.join(' ')) + ' \'' + obj.url + '\''; |
| }; |
| |
| Operation.prototype.encodePathCollection = function (type, name, value, maskPasswords) { |
| var encoded = ''; |
| var i; |
| var separator = ''; |
| |
| if (type === 'ssv') { |
| separator = '%20'; |
| } else if (type === 'tsv') { |
| separator = '%09'; |
| } else if (type === 'pipes') { |
| separator = '|'; |
| } else { |
| separator = ','; |
| } |
| |
| for (i = 0; i < value.length; i++) { |
| if (i === 0) { |
| encoded = this.encodeQueryParam(value[i], maskPasswords); |
| } else { |
| encoded += separator + this.encodeQueryParam(value[i], maskPasswords); |
| } |
| } |
| |
| return encoded; |
| }; |
| |
| Operation.prototype.encodeQueryCollection = function (type, name, value, maskPasswords) { |
| var encoded = ''; |
| var i; |
| |
| type = type || 'default'; |
| if (type === 'default' || type === 'multi') { |
| for (i = 0; i < value.length; i++) { |
| if (i > 0) {encoded += '&';} |
| |
| encoded += this.encodeQueryKey(name) + '=' + mask(this.encodeQueryParam(value[i]), maskPasswords); |
| } |
| } else { |
| var separator = ''; |
| |
| if (type === 'csv') { |
| separator = ','; |
| } else if (type === 'ssv') { |
| separator = '%20'; |
| } else if (type === 'tsv') { |
| separator = '%09'; |
| } else if (type === 'pipes') { |
| separator = '|'; |
| } else if (type === 'brackets') { |
| for (i = 0; i < value.length; i++) { |
| if (i !== 0) { |
| encoded += '&'; |
| } |
| encoded += this.encodeQueryKey(name) + '[]=' + mask(this.encodeQueryParam(value[i]), maskPasswords); |
| } |
| } |
| |
| if (separator !== '') { |
| for (i = 0; i < value.length; i++) { |
| if (i === 0) { |
| encoded = this.encodeQueryKey(name) + '=' + this.encodeQueryParam(value[i]); |
| } else { |
| encoded += separator + this.encodeQueryParam(value[i]); |
| } |
| } |
| } |
| } |
| |
| return encoded; |
| }; |
| |
| Operation.prototype.encodeQueryKey = function (arg) { |
| return encodeURIComponent(arg) |
| .replace('%5B','[').replace('%5D', ']').replace('%24', '$'); |
| }; |
| |
| Operation.prototype.encodeQueryParam = function (arg, maskPasswords) { |
| if(maskPasswords) { |
| return "******"; |
| } |
| return encodeURIComponent(arg); |
| }; |
| |
| /** |
| * TODO revisit, might not want to leave '/' |
| **/ |
| Operation.prototype.encodePathParam = function (pathParam, maskPasswords) { |
| return encodeURIComponent(pathParam, maskPasswords); |
| }; |
| |
| var mask = function(value, format) { |
| if(typeof format === 'string' && format === 'password') { |
| return '******'; |
| } |
| return value; |
| } |
| },{"../helpers":4,"../http":5,"./model":9,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isUndefined":148,"q":157}],11:[function(require,module,exports){ |
| 'use strict'; |
| |
| var OperationGroup = module.exports = function (tag, description, externalDocs, operation) { |
| this.description = description; |
| this.externalDocs = externalDocs; |
| this.name = tag; |
| this.operation = operation; |
| this.operationsArray = []; |
| this.path = tag; |
| this.tag = tag; |
| }; |
| |
| OperationGroup.prototype.sort = function () { |
| |
| }; |
| |
| |
| },{}],12:[function(require,module,exports){ |
| // shim for using process in browser |
| |
| var process = module.exports = {}; |
| var queue = []; |
| var draining = false; |
| |
| function drainQueue() { |
| if (draining) { |
| return; |
| } |
| draining = true; |
| var currentQueue; |
| var len = queue.length; |
| while(len) { |
| currentQueue = queue; |
| queue = []; |
| var i = -1; |
| while (++i < len) { |
| currentQueue[i](); |
| } |
| len = queue.length; |
| } |
| draining = false; |
| } |
| process.nextTick = function (fun) { |
| queue.push(fun); |
| if (!draining) { |
| setTimeout(drainQueue, 0); |
| } |
| }; |
| |
| process.title = 'browser'; |
| process.browser = true; |
| process.env = {}; |
| process.argv = []; |
| process.version = ''; // empty string to avoid regexp issues |
| process.versions = {}; |
| |
| function noop() {} |
| |
| process.on = noop; |
| process.addListener = noop; |
| process.once = noop; |
| process.off = noop; |
| process.removeListener = noop; |
| process.removeAllListeners = noop; |
| process.emit = noop; |
| |
| process.binding = function (name) { |
| throw new Error('process.binding is not supported'); |
| }; |
| |
| // TODO(shtylman) |
| process.cwd = function () { return '/' }; |
| process.chdir = function (dir) { |
| throw new Error('process.chdir is not supported'); |
| }; |
| process.umask = function() { return 0; }; |
| |
| },{}],13:[function(require,module,exports){ |
| (function (Buffer){ |
| (function () { |
| "use strict"; |
| |
| function btoa(str) { |
| var buffer |
| ; |
| |
| if (str instanceof Buffer) { |
| buffer = str; |
| } else { |
| buffer = new Buffer(str.toString(), 'binary'); |
| } |
| |
| return buffer.toString('base64'); |
| } |
| |
| module.exports = btoa; |
| }()); |
| |
| }).call(this,require("buffer").Buffer) |
| |
| },{"buffer":14}],14:[function(require,module,exports){ |
| /*! |
| * The buffer module from node.js, for the browser. |
| * |
| * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> |
| * @license MIT |
| */ |
| |
| var base64 = require('base64-js') |
| var ieee754 = require('ieee754') |
| var isArray = require('is-array') |
| |
| exports.Buffer = Buffer |
| exports.SlowBuffer = SlowBuffer |
| exports.INSPECT_MAX_BYTES = 50 |
| Buffer.poolSize = 8192 // not used by this implementation |
| |
| var rootParent = {} |
| |
| /** |
| * If `Buffer.TYPED_ARRAY_SUPPORT`: |
| * === true Use Uint8Array implementation (fastest) |
| * === false Use Object implementation (most compatible, even IE6) |
| * |
| * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, |
| * Opera 11.6+, iOS 4.2+. |
| * |
| * Due to various browser bugs, sometimes the Object implementation will be used even |
| * when the browser supports typed arrays. |
| * |
| * Note: |
| * |
| * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, |
| * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. |
| * |
| * - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property |
| * on objects. |
| * |
| * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. |
| * |
| * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of |
| * incorrect length in some situations. |
| |
| * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they |
| * get the Object implementation, which is slower but behaves correctly. |
| */ |
| Buffer.TYPED_ARRAY_SUPPORT = (function () { |
| function Bar () {} |
| try { |
| var arr = new Uint8Array(1) |
| arr.foo = function () { return 42 } |
| arr.constructor = Bar |
| return arr.foo() === 42 && // typed array instances can be augmented |
| arr.constructor === Bar && // constructor can be set |
| typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` |
| arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` |
| } catch (e) { |
| return false |
| } |
| })() |
| |
| function kMaxLength () { |
| return Buffer.TYPED_ARRAY_SUPPORT |
| ? 0x7fffffff |
| : 0x3fffffff |
| } |
| |
| /** |
| * Class: Buffer |
| * ============= |
| * |
| * The Buffer constructor returns instances of `Uint8Array` that are augmented |
| * with function properties for all the node `Buffer` API functions. We use |
| * `Uint8Array` so that square bracket notation works as expected -- it returns |
| * a single octet. |
| * |
| * By augmenting the instances, we can avoid modifying the `Uint8Array` |
| * prototype. |
| */ |
| function Buffer (arg) { |
| if (!(this instanceof Buffer)) { |
| // Avoid going through an ArgumentsAdaptorTrampoline in the common case. |
| if (arguments.length > 1) return new Buffer(arg, arguments[1]) |
| return new Buffer(arg) |
| } |
| |
| this.length = 0 |
| this.parent = undefined |
| |
| // Common case. |
| if (typeof arg === 'number') { |
| return fromNumber(this, arg) |
| } |
| |
| // Slightly less common case. |
| if (typeof arg === 'string') { |
| return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') |
| } |
| |
| // Unusual. |
| return fromObject(this, arg) |
| } |
| |
| function fromNumber (that, length) { |
| that = allocate(that, length < 0 ? 0 : checked(length) | 0) |
| if (!Buffer.TYPED_ARRAY_SUPPORT) { |
| for (var i = 0; i < length; i++) { |
| that[i] = 0 |
| } |
| } |
| return that |
| } |
| |
| function fromString (that, string, encoding) { |
| if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' |
| |
| // Assumption: byteLength() return value is always < kMaxLength. |
| var length = byteLength(string, encoding) | 0 |
| that = allocate(that, length) |
| |
| that.write(string, encoding) |
| return that |
| } |
| |
| function fromObject (that, object) { |
| if (Buffer.isBuffer(object)) return fromBuffer(that, object) |
| |
| if (isArray(object)) return fromArray(that, object) |
| |
| if (object == null) { |
| throw new TypeError('must start with number, buffer, array or string') |
| } |
| |
| if (typeof ArrayBuffer !== 'undefined') { |
| if (object.buffer instanceof ArrayBuffer) { |
| return fromTypedArray(that, object) |
| } |
| if (object instanceof ArrayBuffer) { |
| return fromArrayBuffer(that, object) |
| } |
| } |
| |
| if (object.length) return fromArrayLike(that, object) |
| |
| return fromJsonObject(that, object) |
| } |
| |
| function fromBuffer (that, buffer) { |
| var length = checked(buffer.length) | 0 |
| that = allocate(that, length) |
| buffer.copy(that, 0, 0, length) |
| return that |
| } |
| |
| function fromArray (that, array) { |
| var length = checked(array.length) | 0 |
| that = allocate(that, length) |
| for (var i = 0; i < length; i += 1) { |
| that[i] = array[i] & 255 |
| } |
| return that |
| } |
| |
| // Duplicate of fromArray() to keep fromArray() monomorphic. |
| function fromTypedArray (that, array) { |
| var length = checked(array.length) | 0 |
| that = allocate(that, length) |
| // Truncating the elements is probably not what people expect from typed |
| // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior |
| // of the old Buffer constructor. |
| for (var i = 0; i < length; i += 1) { |
| that[i] = array[i] & 255 |
| } |
| return that |
| } |
| |
| function fromArrayBuffer (that, array) { |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| // Return an augmented `Uint8Array` instance, for best performance |
| array.byteLength |
| that = Buffer._augment(new Uint8Array(array)) |
| } else { |
| // Fallback: Return an object instance of the Buffer class |
| that = fromTypedArray(that, new Uint8Array(array)) |
| } |
| return that |
| } |
| |
| function fromArrayLike (that, array) { |
| var length = checked(array.length) | 0 |
| that = allocate(that, length) |
| for (var i = 0; i < length; i += 1) { |
| that[i] = array[i] & 255 |
| } |
| return that |
| } |
| |
| // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. |
| // Returns a zero-length buffer for inputs that don't conform to the spec. |
| function fromJsonObject (that, object) { |
| var array |
| var length = 0 |
| |
| if (object.type === 'Buffer' && isArray(object.data)) { |
| array = object.data |
| length = checked(array.length) | 0 |
| } |
| that = allocate(that, length) |
| |
| for (var i = 0; i < length; i += 1) { |
| that[i] = array[i] & 255 |
| } |
| return that |
| } |
| |
| function allocate (that, length) { |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| // Return an augmented `Uint8Array` instance, for best performance |
| that = Buffer._augment(new Uint8Array(length)) |
| } else { |
| // Fallback: Return an object instance of the Buffer class |
| that.length = length |
| that._isBuffer = true |
| } |
| |
| var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 |
| if (fromPool) that.parent = rootParent |
| |
| return that |
| } |
| |
| function checked (length) { |
| // Note: cannot use `length < kMaxLength` here because that fails when |
| // length is NaN (which is otherwise coerced to zero.) |
| if (length >= kMaxLength()) { |
| throw new RangeError('Attempt to allocate Buffer larger than maximum ' + |
| 'size: 0x' + kMaxLength().toString(16) + ' bytes') |
| } |
| return length | 0 |
| } |
| |
| function SlowBuffer (subject, encoding) { |
| if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) |
| |
| var buf = new Buffer(subject, encoding) |
| delete buf.parent |
| return buf |
| } |
| |
| Buffer.isBuffer = function isBuffer (b) { |
| return !!(b != null && b._isBuffer) |
| } |
| |
| Buffer.compare = function compare (a, b) { |
| if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { |
| throw new TypeError('Arguments must be Buffers') |
| } |
| |
| if (a === b) return 0 |
| |
| var x = a.length |
| var y = b.length |
| |
| var i = 0 |
| var len = Math.min(x, y) |
| while (i < len) { |
| if (a[i] !== b[i]) break |
| |
| ++i |
| } |
| |
| if (i !== len) { |
| x = a[i] |
| y = b[i] |
| } |
| |
| if (x < y) return -1 |
| if (y < x) return 1 |
| return 0 |
| } |
| |
| Buffer.isEncoding = function isEncoding (encoding) { |
| switch (String(encoding).toLowerCase()) { |
| case 'hex': |
| case 'utf8': |
| case 'utf-8': |
| case 'ascii': |
| case 'binary': |
| case 'base64': |
| case 'raw': |
| case 'ucs2': |
| case 'ucs-2': |
| case 'utf16le': |
| case 'utf-16le': |
| return true |
| default: |
| return false |
| } |
| } |
| |
| Buffer.concat = function concat (list, length) { |
| if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') |
| |
| if (list.length === 0) { |
| return new Buffer(0) |
| } |
| |
| var i |
| if (length === undefined) { |
| length = 0 |
| for (i = 0; i < list.length; i++) { |
| length += list[i].length |
| } |
| } |
| |
| var buf = new Buffer(length) |
| var pos = 0 |
| for (i = 0; i < list.length; i++) { |
| var item = list[i] |
| item.copy(buf, pos) |
| pos += item.length |
| } |
| return buf |
| } |
| |
| function byteLength (string, encoding) { |
| if (typeof string !== 'string') string = '' + string |
| |
| var len = string.length |
| if (len === 0) return 0 |
| |
| // Use a for loop to avoid recursion |
| var loweredCase = false |
| for (;;) { |
| switch (encoding) { |
| case 'ascii': |
| case 'binary': |
| // Deprecated |
| case 'raw': |
| case 'raws': |
| return len |
| case 'utf8': |
| case 'utf-8': |
| return utf8ToBytes(string).length |
| case 'ucs2': |
| case 'ucs-2': |
| case 'utf16le': |
| case 'utf-16le': |
| return len * 2 |
| case 'hex': |
| return len >>> 1 |
| case 'base64': |
| return base64ToBytes(string).length |
| default: |
| if (loweredCase) return utf8ToBytes(string).length // assume utf8 |
| encoding = ('' + encoding).toLowerCase() |
| loweredCase = true |
| } |
| } |
| } |
| Buffer.byteLength = byteLength |
| |
| // pre-set for values that may exist in the future |
| Buffer.prototype.length = undefined |
| Buffer.prototype.parent = undefined |
| |
| function slowToString (encoding, start, end) { |
| var loweredCase = false |
| |
| start = start | 0 |
| end = end === undefined || end === Infinity ? this.length : end | 0 |
| |
| if (!encoding) encoding = 'utf8' |
| if (start < 0) start = 0 |
| if (end > this.length) end = this.length |
| if (end <= start) return '' |
| |
| while (true) { |
| switch (encoding) { |
| case 'hex': |
| return hexSlice(this, start, end) |
| |
| case 'utf8': |
| case 'utf-8': |
| return utf8Slice(this, start, end) |
| |
| case 'ascii': |
| return asciiSlice(this, start, end) |
| |
| case 'binary': |
| return binarySlice(this, start, end) |
| |
| case 'base64': |
| return base64Slice(this, start, end) |
| |
| case 'ucs2': |
| case 'ucs-2': |
| case 'utf16le': |
| case 'utf-16le': |
| return utf16leSlice(this, start, end) |
| |
| default: |
| if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) |
| encoding = (encoding + '').toLowerCase() |
| loweredCase = true |
| } |
| } |
| } |
| |
| Buffer.prototype.toString = function toString () { |
| var length = this.length | 0 |
| if (length === 0) return '' |
| if (arguments.length === 0) return utf8Slice(this, 0, length) |
| return slowToString.apply(this, arguments) |
| } |
| |
| Buffer.prototype.equals = function equals (b) { |
| if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') |
| if (this === b) return true |
| return Buffer.compare(this, b) === 0 |
| } |
| |
| Buffer.prototype.inspect = function inspect () { |
| var str = '' |
| var max = exports.INSPECT_MAX_BYTES |
| if (this.length > 0) { |
| str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') |
| if (this.length > max) str += ' ... ' |
| } |
| return '<Buffer ' + str + '>' |
| } |
| |
| Buffer.prototype.compare = function compare (b) { |
| if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') |
| if (this === b) return 0 |
| return Buffer.compare(this, b) |
| } |
| |
| Buffer.prototype.indexOf = function indexOf (val, byteOffset) { |
| if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff |
| else if (byteOffset < -0x80000000) byteOffset = -0x80000000 |
| byteOffset >>= 0 |
| |
| if (this.length === 0) return -1 |
| if (byteOffset >= this.length) return -1 |
| |
| // Negative offsets start from the end of the buffer |
| if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) |
| |
| if (typeof val === 'string') { |
| if (val.length === 0) return -1 // special case: looking for empty string always fails |
| return String.prototype.indexOf.call(this, val, byteOffset) |
| } |
| if (Buffer.isBuffer(val)) { |
| return arrayIndexOf(this, val, byteOffset) |
| } |
| if (typeof val === 'number') { |
| if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { |
| return Uint8Array.prototype.indexOf.call(this, val, byteOffset) |
| } |
| return arrayIndexOf(this, [ val ], byteOffset) |
| } |
| |
| function arrayIndexOf (arr, val, byteOffset) { |
| var foundIndex = -1 |
| for (var i = 0; byteOffset + i < arr.length; i++) { |
| if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { |
| if (foundIndex === -1) foundIndex = i |
| if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex |
| } else { |
| foundIndex = -1 |
| } |
| } |
| return -1 |
| } |
| |
| throw new TypeError('val must be string, number or Buffer') |
| } |
| |
| // `get` is deprecated |
| Buffer.prototype.get = function get (offset) { |
| console.log('.get() is deprecated. Access using array indexes instead.') |
| return this.readUInt8(offset) |
| } |
| |
| // `set` is deprecated |
| Buffer.prototype.set = function set (v, offset) { |
| console.log('.set() is deprecated. Access using array indexes instead.') |
| return this.writeUInt8(v, offset) |
| } |
| |
| function hexWrite (buf, string, offset, length) { |
| offset = Number(offset) || 0 |
| var remaining = buf.length - offset |
| if (!length) { |
| length = remaining |
| } else { |
| length = Number(length) |
| if (length > remaining) { |
| length = remaining |
| } |
| } |
| |
| // must be an even number of digits |
| var strLen = string.length |
| if (strLen % 2 !== 0) throw new Error('Invalid hex string') |
| |
| if (length > strLen / 2) { |
| length = strLen / 2 |
| } |
| for (var i = 0; i < length; i++) { |
| var parsed = parseInt(string.substr(i * 2, 2), 16) |
| if (isNaN(parsed)) throw new Error('Invalid hex string') |
| buf[offset + i] = parsed |
| } |
| return i |
| } |
| |
| function utf8Write (buf, string, offset, length) { |
| return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) |
| } |
| |
| function asciiWrite (buf, string, offset, length) { |
| return blitBuffer(asciiToBytes(string), buf, offset, length) |
| } |
| |
| function binaryWrite (buf, string, offset, length) { |
| return asciiWrite(buf, string, offset, length) |
| } |
| |
| function base64Write (buf, string, offset, length) { |
| return blitBuffer(base64ToBytes(string), buf, offset, length) |
| } |
| |
| function ucs2Write (buf, string, offset, length) { |
| return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) |
| } |
| |
| Buffer.prototype.write = function write (string, offset, length, encoding) { |
| // Buffer#write(string) |
| if (offset === undefined) { |
| encoding = 'utf8' |
| length = this.length |
| offset = 0 |
| // Buffer#write(string, encoding) |
| } else if (length === undefined && typeof offset === 'string') { |
| encoding = offset |
| length = this.length |
| offset = 0 |
| // Buffer#write(string, offset[, length][, encoding]) |
| } else if (isFinite(offset)) { |
| offset = offset | 0 |
| if (isFinite(length)) { |
| length = length | 0 |
| if (encoding === undefined) encoding = 'utf8' |
| } else { |
| encoding = length |
| length = undefined |
| } |
| // legacy write(string, encoding, offset, length) - remove in v0.13 |
| } else { |
| var swap = encoding |
| encoding = offset |
| offset = length | 0 |
| length = swap |
| } |
| |
| var remaining = this.length - offset |
| if (length === undefined || length > remaining) length = remaining |
| |
| if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { |
| throw new RangeError('attempt to write outside buffer bounds') |
| } |
| |
| if (!encoding) encoding = 'utf8' |
| |
| var loweredCase = false |
| for (;;) { |
| switch (encoding) { |
| case 'hex': |
| return hexWrite(this, string, offset, length) |
| |
| case 'utf8': |
| case 'utf-8': |
| return utf8Write(this, string, offset, length) |
| |
| case 'ascii': |
| return asciiWrite(this, string, offset, length) |
| |
| case 'binary': |
| return binaryWrite(this, string, offset, length) |
| |
| case 'base64': |
| // Warning: maxLength not taken into account in base64Write |
| return base64Write(this, string, offset, length) |
| |
| case 'ucs2': |
| case 'ucs-2': |
| case 'utf16le': |
| case 'utf-16le': |
| return ucs2Write(this, string, offset, length) |
| |
| default: |
| if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) |
| encoding = ('' + encoding).toLowerCase() |
| loweredCase = true |
| } |
| } |
| } |
| |
| Buffer.prototype.toJSON = function toJSON () { |
| return { |
| type: 'Buffer', |
| data: Array.prototype.slice.call(this._arr || this, 0) |
| } |
| } |
| |
| function base64Slice (buf, start, end) { |
| if (start === 0 && end === buf.length) { |
| return base64.fromByteArray(buf) |
| } else { |
| return base64.fromByteArray(buf.slice(start, end)) |
| } |
| } |
| |
| function utf8Slice (buf, start, end) { |
| end = Math.min(buf.length, end) |
| var res = [] |
| |
| var i = start |
| while (i < end) { |
| var firstByte = buf[i] |
| var codePoint = null |
| var bytesPerSequence = (firstByte > 0xEF) ? 4 |
| : (firstByte > 0xDF) ? 3 |
| : (firstByte > 0xBF) ? 2 |
| : 1 |
| |
| if (i + bytesPerSequence <= end) { |
| var secondByte, thirdByte, fourthByte, tempCodePoint |
| |
| switch (bytesPerSequence) { |
| case 1: |
| if (firstByte < 0x80) { |
| codePoint = firstByte |
| } |
| break |
| case 2: |
| secondByte = buf[i + 1] |
| if ((secondByte & 0xC0) === 0x80) { |
| tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) |
| if (tempCodePoint > 0x7F) { |
| codePoint = tempCodePoint |
| } |
| } |
| break |
| case 3: |
| secondByte = buf[i + 1] |
| thirdByte = buf[i + 2] |
| if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { |
| tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) |
| if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { |
| codePoint = tempCodePoint |
| } |
| } |
| break |
| case 4: |
| secondByte = buf[i + 1] |
| thirdByte = buf[i + 2] |
| fourthByte = buf[i + 3] |
| if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { |
| tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) |
| if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { |
| codePoint = tempCodePoint |
| } |
| } |
| } |
| } |
| |
| if (codePoint === null) { |
| // we did not generate a valid codePoint so insert a |
| // replacement char (U+FFFD) and advance only 1 byte |
| codePoint = 0xFFFD |
| bytesPerSequence = 1 |
| } else if (codePoint > 0xFFFF) { |
| // encode to utf16 (surrogate pair dance) |
| codePoint -= 0x10000 |
| res.push(codePoint >>> 10 & 0x3FF | 0xD800) |
| codePoint = 0xDC00 | codePoint & 0x3FF |
| } |
| |
| res.push(codePoint) |
| i += bytesPerSequence |
| } |
| |
| return decodeCodePointsArray(res) |
| } |
| |
| // Based on http://stackoverflow.com/a/22747272/680742, the browser with |
| // the lowest limit is Chrome, with 0x10000 args. |
| // We go 1 magnitude less, for safety |
| var MAX_ARGUMENTS_LENGTH = 0x1000 |
| |
| function decodeCodePointsArray (codePoints) { |
| var len = codePoints.length |
| if (len <= MAX_ARGUMENTS_LENGTH) { |
| return String.fromCharCode.apply(String, codePoints) // avoid extra slice() |
| } |
| |
| // Decode in chunks to avoid "call stack size exceeded". |
| var res = '' |
| var i = 0 |
| while (i < len) { |
| res += String.fromCharCode.apply( |
| String, |
| codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) |
| ) |
| } |
| return res |
| } |
| |
| function asciiSlice (buf, start, end) { |
| var ret = '' |
| end = Math.min(buf.length, end) |
| |
| for (var i = start; i < end; i++) { |
| ret += String.fromCharCode(buf[i] & 0x7F) |
| } |
| return ret |
| } |
| |
| function binarySlice (buf, start, end) { |
| var ret = '' |
| end = Math.min(buf.length, end) |
| |
| for (var i = start; i < end; i++) { |
| ret += String.fromCharCode(buf[i]) |
| } |
| return ret |
| } |
| |
| function hexSlice (buf, start, end) { |
| var len = buf.length |
| |
| if (!start || start < 0) start = 0 |
| if (!end || end < 0 || end > len) end = len |
| |
| var out = '' |
| for (var i = start; i < end; i++) { |
| out += toHex(buf[i]) |
| } |
| return out |
| } |
| |
| function utf16leSlice (buf, start, end) { |
| var bytes = buf.slice(start, end) |
| var res = '' |
| for (var i = 0; i < bytes.length; i += 2) { |
| res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) |
| } |
| return res |
| } |
| |
| Buffer.prototype.slice = function slice (start, end) { |
| var len = this.length |
| start = ~~start |
| end = end === undefined ? len : ~~end |
| |
| if (start < 0) { |
| start += len |
| if (start < 0) start = 0 |
| } else if (start > len) { |
| start = len |
| } |
| |
| if (end < 0) { |
| end += len |
| if (end < 0) end = 0 |
| } else if (end > len) { |
| end = len |
| } |
| |
| if (end < start) end = start |
| |
| var newBuf |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| newBuf = Buffer._augment(this.subarray(start, end)) |
| } else { |
| var sliceLen = end - start |
| newBuf = new Buffer(sliceLen, undefined) |
| for (var i = 0; i < sliceLen; i++) { |
| newBuf[i] = this[i + start] |
| } |
| } |
| |
| if (newBuf.length) newBuf.parent = this.parent || this |
| |
| return newBuf |
| } |
| |
| /* |
| * Need to make sure that buffer isn't trying to write out of bounds. |
| */ |
| function checkOffset (offset, ext, length) { |
| if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') |
| if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') |
| } |
| |
| Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { |
| offset = offset | 0 |
| byteLength = byteLength | 0 |
| if (!noAssert) checkOffset(offset, byteLength, this.length) |
| |
| var val = this[offset] |
| var mul = 1 |
| var i = 0 |
| while (++i < byteLength && (mul *= 0x100)) { |
| val += this[offset + i] * mul |
| } |
| |
| return val |
| } |
| |
| Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { |
| offset = offset | 0 |
| byteLength = byteLength | 0 |
| if (!noAssert) { |
| checkOffset(offset, byteLength, this.length) |
| } |
| |
| var val = this[offset + --byteLength] |
| var mul = 1 |
| while (byteLength > 0 && (mul *= 0x100)) { |
| val += this[offset + --byteLength] * mul |
| } |
| |
| return val |
| } |
| |
| Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 1, this.length) |
| return this[offset] |
| } |
| |
| Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 2, this.length) |
| return this[offset] | (this[offset + 1] << 8) |
| } |
| |
| Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 2, this.length) |
| return (this[offset] << 8) | this[offset + 1] |
| } |
| |
| Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 4, this.length) |
| |
| return ((this[offset]) | |
| (this[offset + 1] << 8) | |
| (this[offset + 2] << 16)) + |
| (this[offset + 3] * 0x1000000) |
| } |
| |
| Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 4, this.length) |
| |
| return (this[offset] * 0x1000000) + |
| ((this[offset + 1] << 16) | |
| (this[offset + 2] << 8) | |
| this[offset + 3]) |
| } |
| |
| Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { |
| offset = offset | 0 |
| byteLength = byteLength | 0 |
| if (!noAssert) checkOffset(offset, byteLength, this.length) |
| |
| var val = this[offset] |
| var mul = 1 |
| var i = 0 |
| while (++i < byteLength && (mul *= 0x100)) { |
| val += this[offset + i] * mul |
| } |
| mul *= 0x80 |
| |
| if (val >= mul) val -= Math.pow(2, 8 * byteLength) |
| |
| return val |
| } |
| |
| Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { |
| offset = offset | 0 |
| byteLength = byteLength | 0 |
| if (!noAssert) checkOffset(offset, byteLength, this.length) |
| |
| var i = byteLength |
| var mul = 1 |
| var val = this[offset + --i] |
| while (i > 0 && (mul *= 0x100)) { |
| val += this[offset + --i] * mul |
| } |
| mul *= 0x80 |
| |
| if (val >= mul) val -= Math.pow(2, 8 * byteLength) |
| |
| return val |
| } |
| |
| Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 1, this.length) |
| if (!(this[offset] & 0x80)) return (this[offset]) |
| return ((0xff - this[offset] + 1) * -1) |
| } |
| |
| Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 2, this.length) |
| var val = this[offset] | (this[offset + 1] << 8) |
| return (val & 0x8000) ? val | 0xFFFF0000 : val |
| } |
| |
| Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 2, this.length) |
| var val = this[offset + 1] | (this[offset] << 8) |
| return (val & 0x8000) ? val | 0xFFFF0000 : val |
| } |
| |
| Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 4, this.length) |
| |
| return (this[offset]) | |
| (this[offset + 1] << 8) | |
| (this[offset + 2] << 16) | |
| (this[offset + 3] << 24) |
| } |
| |
| Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 4, this.length) |
| |
| return (this[offset] << 24) | |
| (this[offset + 1] << 16) | |
| (this[offset + 2] << 8) | |
| (this[offset + 3]) |
| } |
| |
| Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 4, this.length) |
| return ieee754.read(this, offset, true, 23, 4) |
| } |
| |
| Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 4, this.length) |
| return ieee754.read(this, offset, false, 23, 4) |
| } |
| |
| Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 8, this.length) |
| return ieee754.read(this, offset, true, 52, 8) |
| } |
| |
| Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { |
| if (!noAssert) checkOffset(offset, 8, this.length) |
| return ieee754.read(this, offset, false, 52, 8) |
| } |
| |
| function checkInt (buf, value, offset, ext, max, min) { |
| if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') |
| if (value > max || value < min) throw new RangeError('value is out of bounds') |
| if (offset + ext > buf.length) throw new RangeError('index out of range') |
| } |
| |
| Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { |
| value = +value |
| offset = offset | 0 |
| byteLength = byteLength | 0 |
| if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) |
| |
| var mul = 1 |
| var i = 0 |
| this[offset] = value & 0xFF |
| while (++i < byteLength && (mul *= 0x100)) { |
| this[offset + i] = (value / mul) & 0xFF |
| } |
| |
| return offset + byteLength |
| } |
| |
| Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { |
| value = +value |
| offset = offset | 0 |
| byteLength = byteLength | 0 |
| if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) |
| |
| var i = byteLength - 1 |
| var mul = 1 |
| this[offset + i] = value & 0xFF |
| while (--i >= 0 && (mul *= 0x100)) { |
| this[offset + i] = (value / mul) & 0xFF |
| } |
| |
| return offset + byteLength |
| } |
| |
| Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) |
| if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) |
| this[offset] = value |
| return offset + 1 |
| } |
| |
| function objectWriteUInt16 (buf, value, offset, littleEndian) { |
| if (value < 0) value = 0xffff + value + 1 |
| for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { |
| buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> |
| (littleEndian ? i : 1 - i) * 8 |
| } |
| } |
| |
| Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| this[offset] = value |
| this[offset + 1] = (value >>> 8) |
| } else { |
| objectWriteUInt16(this, value, offset, true) |
| } |
| return offset + 2 |
| } |
| |
| Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| this[offset] = (value >>> 8) |
| this[offset + 1] = value |
| } else { |
| objectWriteUInt16(this, value, offset, false) |
| } |
| return offset + 2 |
| } |
| |
| function objectWriteUInt32 (buf, value, offset, littleEndian) { |
| if (value < 0) value = 0xffffffff + value + 1 |
| for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { |
| buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff |
| } |
| } |
| |
| Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| this[offset + 3] = (value >>> 24) |
| this[offset + 2] = (value >>> 16) |
| this[offset + 1] = (value >>> 8) |
| this[offset] = value |
| } else { |
| objectWriteUInt32(this, value, offset, true) |
| } |
| return offset + 4 |
| } |
| |
| Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| this[offset] = (value >>> 24) |
| this[offset + 1] = (value >>> 16) |
| this[offset + 2] = (value >>> 8) |
| this[offset + 3] = value |
| } else { |
| objectWriteUInt32(this, value, offset, false) |
| } |
| return offset + 4 |
| } |
| |
| Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) { |
| var limit = Math.pow(2, 8 * byteLength - 1) |
| |
| checkInt(this, value, offset, byteLength, limit - 1, -limit) |
| } |
| |
| var i = 0 |
| var mul = 1 |
| var sub = value < 0 ? 1 : 0 |
| this[offset] = value & 0xFF |
| while (++i < byteLength && (mul *= 0x100)) { |
| this[offset + i] = ((value / mul) >> 0) - sub & 0xFF |
| } |
| |
| return offset + byteLength |
| } |
| |
| Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) { |
| var limit = Math.pow(2, 8 * byteLength - 1) |
| |
| checkInt(this, value, offset, byteLength, limit - 1, -limit) |
| } |
| |
| var i = byteLength - 1 |
| var mul = 1 |
| var sub = value < 0 ? 1 : 0 |
| this[offset + i] = value & 0xFF |
| while (--i >= 0 && (mul *= 0x100)) { |
| this[offset + i] = ((value / mul) >> 0) - sub & 0xFF |
| } |
| |
| return offset + byteLength |
| } |
| |
| Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) |
| if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) |
| if (value < 0) value = 0xff + value + 1 |
| this[offset] = value |
| return offset + 1 |
| } |
| |
| Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| this[offset] = value |
| this[offset + 1] = (value >>> 8) |
| } else { |
| objectWriteUInt16(this, value, offset, true) |
| } |
| return offset + 2 |
| } |
| |
| Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| this[offset] = (value >>> 8) |
| this[offset + 1] = value |
| } else { |
| objectWriteUInt16(this, value, offset, false) |
| } |
| return offset + 2 |
| } |
| |
| Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| this[offset] = value |
| this[offset + 1] = (value >>> 8) |
| this[offset + 2] = (value >>> 16) |
| this[offset + 3] = (value >>> 24) |
| } else { |
| objectWriteUInt32(this, value, offset, true) |
| } |
| return offset + 4 |
| } |
| |
| Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { |
| value = +value |
| offset = offset | 0 |
| if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) |
| if (value < 0) value = 0xffffffff + value + 1 |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| this[offset] = (value >>> 24) |
| this[offset + 1] = (value >>> 16) |
| this[offset + 2] = (value >>> 8) |
| this[offset + 3] = value |
| } else { |
| objectWriteUInt32(this, value, offset, false) |
| } |
| return offset + 4 |
| } |
| |
| function checkIEEE754 (buf, value, offset, ext, max, min) { |
| if (value > max || value < min) throw new RangeError('value is out of bounds') |
| if (offset + ext > buf.length) throw new RangeError('index out of range') |
| if (offset < 0) throw new RangeError('index out of range') |
| } |
| |
| function writeFloat (buf, value, offset, littleEndian, noAssert) { |
| if (!noAssert) { |
| checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) |
| } |
| ieee754.write(buf, value, offset, littleEndian, 23, 4) |
| return offset + 4 |
| } |
| |
| Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { |
| return writeFloat(this, value, offset, true, noAssert) |
| } |
| |
| Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { |
| return writeFloat(this, value, offset, false, noAssert) |
| } |
| |
| function writeDouble (buf, value, offset, littleEndian, noAssert) { |
| if (!noAssert) { |
| checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) |
| } |
| ieee754.write(buf, value, offset, littleEndian, 52, 8) |
| return offset + 8 |
| } |
| |
| Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { |
| return writeDouble(this, value, offset, true, noAssert) |
| } |
| |
| Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { |
| return writeDouble(this, value, offset, false, noAssert) |
| } |
| |
| // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) |
| Buffer.prototype.copy = function copy (target, targetStart, start, end) { |
| if (!start) start = 0 |
| if (!end && end !== 0) end = this.length |
| if (targetStart >= target.length) targetStart = target.length |
| if (!targetStart) targetStart = 0 |
| if (end > 0 && end < start) end = start |
| |
| // Copy 0 bytes; we're done |
| if (end === start) return 0 |
| if (target.length === 0 || this.length === 0) return 0 |
| |
| // Fatal error conditions |
| if (targetStart < 0) { |
| throw new RangeError('targetStart out of bounds') |
| } |
| if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') |
| if (end < 0) throw new RangeError('sourceEnd out of bounds') |
| |
| // Are we oob? |
| if (end > this.length) end = this.length |
| if (target.length - targetStart < end - start) { |
| end = target.length - targetStart + start |
| } |
| |
| var len = end - start |
| var i |
| |
| if (this === target && start < targetStart && targetStart < end) { |
| // descending copy from end |
| for (i = len - 1; i >= 0; i--) { |
| target[i + targetStart] = this[i + start] |
| } |
| } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { |
| // ascending copy from start |
| for (i = 0; i < len; i++) { |
| target[i + targetStart] = this[i + start] |
| } |
| } else { |
| target._set(this.subarray(start, start + len), targetStart) |
| } |
| |
| return len |
| } |
| |
| // fill(value, start=0, end=buffer.length) |
| Buffer.prototype.fill = function fill (value, start, end) { |
| if (!value) value = 0 |
| if (!start) start = 0 |
| if (!end) end = this.length |
| |
| if (end < start) throw new RangeError('end < start') |
| |
| // Fill 0 bytes; we're done |
| if (end === start) return |
| if (this.length === 0) return |
| |
| if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') |
| if (end < 0 || end > this.length) throw new RangeError('end out of bounds') |
| |
| var i |
| if (typeof value === 'number') { |
| for (i = start; i < end; i++) { |
| this[i] = value |
| } |
| } else { |
| var bytes = utf8ToBytes(value.toString()) |
| var len = bytes.length |
| for (i = start; i < end; i++) { |
| this[i] = bytes[i % len] |
| } |
| } |
| |
| return this |
| } |
| |
| /** |
| * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. |
| * Added in Node 0.12. Only available in browsers that support ArrayBuffer. |
| */ |
| Buffer.prototype.toArrayBuffer = function toArrayBuffer () { |
| if (typeof Uint8Array !== 'undefined') { |
| if (Buffer.TYPED_ARRAY_SUPPORT) { |
| return (new Buffer(this)).buffer |
| } else { |
| var buf = new Uint8Array(this.length) |
| for (var i = 0, len = buf.length; i < len; i += 1) { |
| buf[i] = this[i] |
| } |
| return buf.buffer |
| } |
| } else { |
| throw new TypeError('Buffer.toArrayBuffer not supported in this browser') |
| } |
| } |
| |
| // HELPER FUNCTIONS |
| // ================ |
| |
| var BP = Buffer.prototype |
| |
| /** |
| * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods |
| */ |
| Buffer._augment = function _augment (arr) { |
| arr.constructor = Buffer |
| arr._isBuffer = true |
| |
| // save reference to original Uint8Array set method before overwriting |
| arr._set = arr.set |
| |
| // deprecated |
| arr.get = BP.get |
| arr.set = BP.set |
| |
| arr.write = BP.write |
| arr.toString = BP.toString |
| arr.toLocaleString = BP.toString |
| arr.toJSON = BP.toJSON |
| arr.equals = BP.equals |
| arr.compare = BP.compare |
| arr.indexOf = BP.indexOf |
| arr.copy = BP.copy |
| arr.slice = BP.slice |
| arr.readUIntLE = BP.readUIntLE |
| arr.readUIntBE = BP.readUIntBE |
| arr.readUInt8 = BP.readUInt8 |
| arr.readUInt16LE = BP.readUInt16LE |
| arr.readUInt16BE = BP.readUInt16BE |
| arr.readUInt32LE = BP.readUInt32LE |
| arr.readUInt32BE = BP.readUInt32BE |
| arr.readIntLE = BP.readIntLE |
| arr.readIntBE = BP.readIntBE |
| arr.readInt8 = BP.readInt8 |
| arr.readInt16LE = BP.readInt16LE |
| arr.readInt16BE = BP.readInt16BE |
| arr.readInt32LE = BP.readInt32LE |
| arr.readInt32BE = BP.readInt32BE |
| arr.readFloatLE = BP.readFloatLE |
| arr.readFloatBE = BP.readFloatBE |
| arr.readDoubleLE = BP.readDoubleLE |
| arr.readDoubleBE = BP.readDoubleBE |
| arr.writeUInt8 = BP.writeUInt8 |
| arr.writeUIntLE = BP.writeUIntLE |
| arr.writeUIntBE = BP.writeUIntBE |
| arr.writeUInt16LE = BP.writeUInt16LE |
| arr.writeUInt16BE = BP.writeUInt16BE |
| arr.writeUInt32LE = BP.writeUInt32LE |
| arr.writeUInt32BE = BP.writeUInt32BE |
| arr.writeIntLE = BP.writeIntLE |
| arr.writeIntBE = BP.writeIntBE |
| arr.writeInt8 = BP.writeInt8 |
| arr.writeInt16LE = BP.writeInt16LE |
| arr.writeInt16BE = BP.writeInt16BE |
| arr.writeInt32LE = BP.writeInt32LE |
| arr.writeInt32BE = BP.writeInt32BE |
| arr.writeFloatLE = BP.writeFloatLE |
| arr.writeFloatBE = BP.writeFloatBE |
| arr.writeDoubleLE = BP.writeDoubleLE |
| arr.writeDoubleBE = BP.writeDoubleBE |
| arr.fill = BP.fill |
| arr.inspect = BP.inspect |
| arr.toArrayBuffer = BP.toArrayBuffer |
| |
| return arr |
| } |
| |
| var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g |
| |
| function base64clean (str) { |
| // Node strips out invalid characters like \n and \t from the string, base64-js does not |
| str = stringtrim(str).replace(INVALID_BASE64_RE, '') |
| // Node converts strings with length < 2 to '' |
| if (str.length < 2) return '' |
| // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not |
| while (str.length % 4 !== 0) { |
| str = str + '=' |
| } |
| return str |
| } |
| |
| function stringtrim (str) { |
| if (str.trim) return str.trim() |
| return str.replace(/^\s+|\s+$/g, '') |
| } |
| |
| function toHex (n) { |
| if (n < 16) return '0' + n.toString(16) |
| return n.toString(16) |
| } |
| |
| function utf8ToBytes (string, units) { |
| units = units || Infinity |
| var codePoint |
| var length = string.length |
| var leadSurrogate = null |
| var bytes = [] |
| |
| for (var i = 0; i < length; i++) { |
| codePoint = string.charCodeAt(i) |
| |
| // is surrogate component |
| if (codePoint > 0xD7FF && codePoint < 0xE000) { |
| // last char was a lead |
| if (!leadSurrogate) { |
| // no lead yet |
| if (codePoint > 0xDBFF) { |
| // unexpected trail |
| if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| continue |
| } else if (i + 1 === length) { |
| // unpaired lead |
| if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| continue |
| } |
| |
| // valid lead |
| leadSurrogate = codePoint |
| |
| continue |
| } |
| |
| // 2 leads in a row |
| if (codePoint < 0xDC00) { |
| if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| leadSurrogate = codePoint |
| continue |
| } |
| |
| // valid surrogate pair |
| codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 |
| } else if (leadSurrogate) { |
| // valid bmp char, but last char was a lead |
| if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| } |
| |
| leadSurrogate = null |
| |
| // encode utf8 |
| if (codePoint < 0x80) { |
| if ((units -= 1) < 0) break |
| bytes.push(codePoint) |
| } else if (codePoint < 0x800) { |
| if ((units -= 2) < 0) break |
| bytes.push( |
| codePoint >> 0x6 | 0xC0, |
| codePoint & 0x3F | 0x80 |
| ) |
| } else if (codePoint < 0x10000) { |
| if ((units -= 3) < 0) break |
| bytes.push( |
| codePoint >> 0xC | 0xE0, |
| codePoint >> 0x6 & 0x3F | 0x80, |
| codePoint & 0x3F | 0x80 |
| ) |
| } else if (codePoint < 0x110000) { |
| if ((units -= 4) < 0) break |
| bytes.push( |
| codePoint >> 0x12 | 0xF0, |
| codePoint >> 0xC & 0x3F | 0x80, |
| codePoint >> 0x6 & 0x3F | 0x80, |
| codePoint & 0x3F | 0x80 |
| ) |
| } else { |
| throw new Error('Invalid code point') |
| } |
| } |
| |
| return bytes |
| } |
| |
| function asciiToBytes (str) { |
| var byteArray = [] |
| for (var i = 0; i < str.length; i++) { |
| // Node's code seems to be doing this and not & 0x7F.. |
| byteArray.push(str.charCodeAt(i) & 0xFF) |
| } |
| return byteArray |
| } |
| |
| function utf16leToBytes (str, units) { |
| var c, hi, lo |
| var byteArray = [] |
| for (var i = 0; i < str.length; i++) { |
| if ((units -= 2) < 0) break |
| |
| c = str.charCodeAt(i) |
| hi = c >> 8 |
| lo = c % 256 |
| byteArray.push(lo) |
| byteArray.push(hi) |
| } |
| |
| return byteArray |
| } |
| |
| function base64ToBytes (str) { |
| return base64.toByteArray(base64clean(str)) |
| } |
| |
| function blitBuffer (src, dst, offset, length) { |
| for (var i = 0; i < length; i++) { |
| if ((i + offset >= dst.length) || (i >= src.length)) break |
| dst[i + offset] = src[i] |
| } |
| return i |
| } |
| |
| },{"base64-js":15,"ieee754":16,"is-array":17}],15:[function(require,module,exports){ |
| var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; |
| |
| ;(function (exports) { |
| 'use strict'; |
| |
| var Arr = (typeof Uint8Array !== 'undefined') |
| ? Uint8Array |
| : Array |
| |
| var PLUS = '+'.charCodeAt(0) |
| var SLASH = '/'.charCodeAt(0) |
| var NUMBER = '0'.charCodeAt(0) |
| var LOWER = 'a'.charCodeAt(0) |
| var UPPER = 'A'.charCodeAt(0) |
| var PLUS_URL_SAFE = '-'.charCodeAt(0) |
| var SLASH_URL_SAFE = '_'.charCodeAt(0) |
| |
| function decode (elt) { |
| var code = elt.charCodeAt(0) |
| if (code === PLUS || |
| code === PLUS_URL_SAFE) |
| return 62 // '+' |
| if (code === SLASH || |
| code === SLASH_URL_SAFE) |
| return 63 // '/' |
| if (code < NUMBER) |
| return -1 //no match |
| if (code < NUMBER + 10) |
| return code - NUMBER + 26 + 26 |
| if (code < UPPER + 26) |
| return code - UPPER |
| if (code < LOWER + 26) |
| return code - LOWER + 26 |
| } |
| |
| function b64ToByteArray (b64) { |
| var i, j, l, tmp, placeHolders, arr |
| |
| if (b64.length % 4 > 0) { |
| throw new Error('Invalid string. Length must be a multiple of 4') |
| } |
| |
| // the number of equal signs (place holders) |
| // if there are two placeholders, than the two characters before it |
| // represent one byte |
| // if there is only one, then the three characters before it represent 2 bytes |
| // this is just a cheap hack to not do indexOf twice |
| var len = b64.length |
| placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 |
| |
| // base64 is 4/3 + up to two characters of the original data |
| arr = new Arr(b64.length * 3 / 4 - placeHolders) |
| |
| // if there are placeholders, only get up to the last complete 4 chars |
| l = placeHolders > 0 ? b64.length - 4 : b64.length |
| |
| var L = 0 |
| |
| function push (v) { |
| arr[L++] = v |
| } |
| |
| for (i = 0, j = 0; i < l; i += 4, j += 3) { |
| tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) |
| push((tmp & 0xFF0000) >> 16) |
| push((tmp & 0xFF00) >> 8) |
| push(tmp & 0xFF) |
| } |
| |
| if (placeHolders === 2) { |
| tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) |
| push(tmp & 0xFF) |
| } else if (placeHolders === 1) { |
| tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) |
| push((tmp >> 8) & 0xFF) |
| push(tmp & 0xFF) |
| } |
| |
| return arr |
| } |
| |
| function uint8ToBase64 (uint8) { |
| var i, |
| extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes |
| output = "", |
| temp, length |
| |
| function encode (num) { |
| return lookup.charAt(num) |
| } |
| |
| function tripletToBase64 (num) { |
| return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) |
| } |
| |
| // go through the array every three bytes, we'll deal with trailing stuff later |
| for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { |
| temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) |
| output += tripletToBase64(temp) |
| } |
| |
| // pad the end with zeros, but make sure to not forget the extra bytes |
| switch (extraBytes) { |
| case 1: |
| temp = uint8[uint8.length - 1] |
| output += encode(temp >> 2) |
| output += encode((temp << 4) & 0x3F) |
| output += '==' |
| break |
| case 2: |
| temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) |
| output += encode(temp >> 10) |
| output += encode((temp >> 4) & 0x3F) |
| output += encode((temp << 2) & 0x3F) |
| output += '=' |
| break |
| } |
| |
| return output |
| } |
| |
| exports.toByteArray = b64ToByteArray |
| exports.fromByteArray = uint8ToBase64 |
| }(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) |
| |
| },{}],16:[function(require,module,exports){ |
| exports.read = function (buffer, offset, isLE, mLen, nBytes) { |
| var e, m |
| var eLen = nBytes * 8 - mLen - 1 |
| var eMax = (1 << eLen) - 1 |
| var eBias = eMax >> 1 |
| var nBits = -7 |
| var i = isLE ? (nBytes - 1) : 0 |
| var d = isLE ? -1 : 1 |
| var s = buffer[offset + i] |
| |
| i += d |
| |
| e = s & ((1 << (-nBits)) - 1) |
| s >>= (-nBits) |
| nBits += eLen |
| for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} |
| |
| m = e & ((1 << (-nBits)) - 1) |
| e >>= (-nBits) |
| nBits += mLen |
| for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} |
| |
| if (e === 0) { |
| e = 1 - eBias |
| } else if (e === eMax) { |
| return m ? NaN : ((s ? -1 : 1) * Infinity) |
| } else { |
| m = m + Math.pow(2, mLen) |
| e = e - eBias |
| } |
| return (s ? -1 : 1) * m * Math.pow(2, e - mLen) |
| } |
| |
| exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { |
| var e, m, c |
| var eLen = nBytes * 8 - mLen - 1 |
| var eMax = (1 << eLen) - 1 |
| var eBias = eMax >> 1 |
| var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) |
| var i = isLE ? 0 : (nBytes - 1) |
| var d = isLE ? 1 : -1 |
| var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 |
| |
| value = Math.abs(value) |
| |
| if (isNaN(value) || value === Infinity) { |
| m = isNaN(value) ? 1 : 0 |
| e = eMax |
| } else { |
| e = Math.floor(Math.log(value) / Math.LN2) |
| if (value * (c = Math.pow(2, -e)) < 1) { |
| e-- |
| c *= 2 |
| } |
| if (e + eBias >= 1) { |
| value += rt / c |
| } else { |
| value += rt * Math.pow(2, 1 - eBias) |
| } |
| if (value * c >= 2) { |
| e++ |
| c /= 2 |
| } |
| |
| if (e + eBias >= eMax) { |
| m = 0 |
| e = eMax |
| } else if (e + eBias >= 1) { |
| m = (value * c - 1) * Math.pow(2, mLen) |
| e = e + eBias |
| } else { |
| m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) |
| e = 0 |
| } |
| } |
| |
| for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} |
| |
| e = (e << mLen) | m |
| eLen += mLen |
| for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} |
| |
| buffer[offset + i - d] |= s * 128 |
| } |
| |
| },{}],17:[function(require,module,exports){ |
| |
| /** |
| * isArray |
| */ |
| |
| var isArray = Array.isArray; |
| |
| /** |
| * toString |
| */ |
| |
| var str = Object.prototype.toString; |
| |
| /** |
| * Whether or not the given `val` |
| * is an array. |
| * |
| * example: |
| * |
| * isArray([]); |
| * // > true |
| * isArray(arguments); |
| * // > false |
| * isArray(''); |
| * // > false |
| * |
| * @param {mixed} val |
| * @return {bool} |
| */ |
| |
| module.exports = isArray || function (val) { |
| return !! val && '[object Array]' == str.call(val); |
| }; |
| |
| },{}],18:[function(require,module,exports){ |
| /* jshint node: true */ |
| (function () { |
| "use strict"; |
| |
| function CookieAccessInfo(domain, path, secure, script) { |
| if (this instanceof CookieAccessInfo) { |
| this.domain = domain || undefined; |
| this.path = path || "/"; |
| this.secure = !!secure; |
| this.script = !!script; |
| return this; |
| } |
| return new CookieAccessInfo(domain, path, secure, script); |
| } |
| exports.CookieAccessInfo = CookieAccessInfo; |
| |
| function Cookie(cookiestr, request_domain, request_path) { |
| if (cookiestr instanceof Cookie) { |
| return cookiestr; |
| } |
| if (this instanceof Cookie) { |
| this.name = null; |
| this.value = null; |
| this.expiration_date = Infinity; |
| this.path = String(request_path || "/"); |
| this.explicit_path = false; |
| this.domain = request_domain || null; |
| this.explicit_domain = false; |
| this.secure = false; //how to define default? |
| this.noscript = false; //httponly |
| if (cookiestr) { |
| this.parse(cookiestr, request_domain, request_path); |
| } |
| return this; |
| } |
| return new Cookie(cookiestr, request_domain, request_path); |
| } |
| exports.Cookie = Cookie; |
| |
| Cookie.prototype.toString = function toString() { |
| var str = [this.name + "=" + this.value]; |
| if (this.expiration_date !== Infinity) { |
| str.push("expires=" + (new Date(this.expiration_date)).toGMTString()); |
| } |
| if (this.domain) { |
| str.push("domain=" + this.domain); |
| } |
| if (this.path) { |
| str.push("path=" + this.path); |
| } |
| if (this.secure) { |
| str.push("secure"); |
| } |
| if (this.noscript) { |
| str.push("httponly"); |
| } |
| return str.join("; "); |
| }; |
| |
| Cookie.prototype.toValueString = function toValueString() { |
| return this.name + "=" + this.value; |
| }; |
| |
| var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g; |
| Cookie.prototype.parse = function parse(str, request_domain, request_path) { |
| if (this instanceof Cookie) { |
| var parts = str.split(";").filter(function (value) { |
| return !!value; |
| }), |
| pair = parts[0].match(/([^=]+)=([\s\S]*)/), |
| key = pair[1], |
| value = pair[2], |
| i; |
| this.name = key; |
| this.value = value; |
| |
| for (i = 1; i < parts.length; i += 1) { |
| pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/); |
| key = pair[1].trim().toLowerCase(); |
| value = pair[2]; |
| switch (key) { |
| case "httponly": |
| this.noscript = true; |
| break; |
| case "expires": |
| this.expiration_date = value ? |
| Number(Date.parse(value)) : |
| Infinity; |
| break; |
| case "path": |
| this.path = value ? |
| value.trim() : |
| ""; |
| this.explicit_path = true; |
| break; |
| case "domain": |
| this.domain = value ? |
| value.trim() : |
| ""; |
| this.explicit_domain = !!this.domain; |
| break; |
| case "secure": |
| this.secure = true; |
| break; |
| } |
| } |
| |
| if (!this.explicit_path) { |
| this.path = request_path || "/"; |
| } |
| if (!this.explicit_domain) { |
| this.domain = request_domain; |
| } |
| |
| return this; |
| } |
| return new Cookie().parse(str, request_domain, request_path); |
| }; |
| |
| Cookie.prototype.matches = function matches(access_info) { |
| if (this.noscript && access_info.script || |
| this.secure && !access_info.secure || |
| !this.collidesWith(access_info)) { |
| return false; |
| } |
| return true; |
| }; |
| |
| Cookie.prototype.collidesWith = function collidesWith(access_info) { |
| if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) { |
| return false; |
| } |
| if (this.path && access_info.path.indexOf(this.path) !== 0) { |
| return false; |
| } |
| if (this.explicit_path && access_info.path.indexOf( this.path ) !== 0) { |
| return false; |
| } |
| var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,''); |
| var cookie_domain = this.domain && this.domain.replace(/^[\.]/,''); |
| if (cookie_domain === access_domain) { |
| return true; |
| } |
| if (cookie_domain) { |
| if (!this.explicit_domain) { |
| return false; // we already checked if the domains were exactly the same |
| } |
| var wildcard = access_domain.indexOf(cookie_domain); |
| if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) { |
| return false; |
| } |
| return true; |
| } |
| return true; |
| }; |
| |
| function CookieJar() { |
| var cookies, cookies_list, collidable_cookie; |
| if (this instanceof CookieJar) { |
| cookies = Object.create(null); //name: [Cookie] |
| |
| this.setCookie = function setCookie(cookie, request_domain, request_path) { |
| var remove, i; |
| cookie = new Cookie(cookie, request_domain, request_path); |
| //Delete the cookie if the set is past the current time |
| remove = cookie.expiration_date <= Date.now(); |
| if (cookies[cookie.name] !== undefined) { |
| cookies_list = cookies[cookie.name]; |
| for (i = 0; i < cookies_list.length; i += 1) { |
| collidable_cookie = cookies_list[i]; |
| if (collidable_cookie.collidesWith(cookie)) { |
| if (remove) { |
| cookies_list.splice(i, 1); |
| if (cookies_list.length === 0) { |
| delete cookies[cookie.name]; |
| } |
| return false; |
| } |
| cookies_list[i] = cookie; |
| return cookie; |
| } |
| } |
| if (remove) { |
| return false; |
| } |
| cookies_list.push(cookie); |
| return cookie; |
| } |
| if (remove) { |
| return false; |
| } |
| cookies[cookie.name] = [cookie]; |
| return cookies[cookie.name]; |
| }; |
| //returns a cookie |
| this.getCookie = function getCookie(cookie_name, access_info) { |
| var cookie, i; |
| cookies_list = cookies[cookie_name]; |
| if (!cookies_list) { |
| return; |
| } |
| for (i = 0; i < cookies_list.length; i += 1) { |
| cookie = cookies_list[i]; |
| if (cookie.expiration_date <= Date.now()) { |
| if (cookies_list.length === 0) { |
| delete cookies[cookie.name]; |
| } |
| continue; |
| } |
| |
| if (cookie.matches(access_info)) { |
| return cookie; |
| } |
| } |
| }; |
| //returns a list of cookies |
| this.getCookies = function getCookies(access_info) { |
| var matches = [], cookie_name, cookie; |
| for (cookie_name in cookies) { |
| cookie = this.getCookie(cookie_name, access_info); |
| if (cookie) { |
| matches.push(cookie); |
| } |
| } |
| matches.toString = function toString() { |
| return matches.join(":"); |
| }; |
| matches.toValueString = function toValueString() { |
| return matches.map(function (c) { |
| return c.toValueString(); |
| }).join(';'); |
| }; |
| return matches; |
| }; |
| |
| return this; |
| } |
| return new CookieJar(); |
| } |
| exports.CookieJar = CookieJar; |
| |
| //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned. |
| CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) { |
| cookies = Array.isArray(cookies) ? |
| cookies : |
| cookies.split(cookie_str_splitter); |
| var successful = [], |
| i, |
| cookie; |
| cookies = cookies.map(function(item){ |
| return new Cookie(item, request_domain, request_path); |
| }); |
| for (i = 0; i < cookies.length; i += 1) { |
| cookie = cookies[i]; |
| if (this.setCookie(cookie, request_domain, request_path)) { |
| successful.push(cookie); |
| } |
| } |
| return successful; |
| }; |
| }()); |
| |
| },{}],19:[function(require,module,exports){ |
| 'use strict'; |
| |
| |
| var yaml = require('./lib/js-yaml.js'); |
| |
| |
| module.exports = yaml; |
| |
| },{"./lib/js-yaml.js":20}],20:[function(require,module,exports){ |
| 'use strict'; |
| |
| |
| var loader = require('./js-yaml/loader'); |
| var dumper = require('./js-yaml/dumper'); |
| |
| |
| function deprecated(name) { |
| return function () { |
| throw new Error('Function ' + name + ' is deprecated and cannot be used.'); |
| }; |
| } |
| |
| |
| module.exports.Type = require('./js-yaml/type'); |
| module.exports.Schema = require('./js-yaml/schema'); |
| module.exports.FAILSAFE_SCHEMA = require('./js-yaml/schema/failsafe'); |
| module.exports.JSON_SCHEMA = require('./js-yaml/schema/json'); |
| module.exports.CORE_SCHEMA = require('./js-yaml/schema/core'); |
| module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe'); |
| module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full'); |
| module.exports.load = loader.load; |
| module.exports.loadAll = loader.loadAll; |
| module.exports.safeLoad = loader.safeLoad; |
| module.exports.safeLoadAll = loader.safeLoadAll; |
| module.exports.dump = dumper.dump; |
| module.exports.safeDump = dumper.safeDump; |
| module.exports.YAMLException = require('./js-yaml/exception'); |
| |
| // Deprecated schema names from JS-YAML 2.0.x |
| module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe'); |
| module.exports.SAFE_SCHEMA = require('./js-yaml/schema/default_safe'); |
| module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full'); |
| |
| // Deprecated functions from JS-YAML 1.x.x |
| module.exports.scan = deprecated('scan'); |
| module.exports.parse = deprecated('parse'); |
| module.exports.compose = deprecated('compose'); |
| module.exports.addConstructor = deprecated('addConstructor'); |
| |
| },{"./js-yaml/dumper":22,"./js-yaml/exception":23,"./js-yaml/loader":24,"./js-yaml/schema":26,"./js-yaml/schema/core":27,"./js-yaml/schema/default_full":28,"./js-yaml/schema/default_safe":29,"./js-yaml/schema/failsafe":30,"./js-yaml/schema/json":31,"./js-yaml/type":32}],21:[function(require,module,exports){ |
| 'use strict'; |
| |
| |
| function isNothing(subject) { |
| return (typeof subject === 'undefined') || (subject === null); |
| } |
| |
| |
| function isObject(subject) { |
| return (typeof subject === 'object') && (subject !== null); |
| } |
| |
| |
| function toArray(sequence) { |
| if (Array.isArray(sequence)) return sequence; |
| else if (isNothing(sequence)) return []; |
| |
| return [ sequence ]; |
| } |
| |
| |
| function extend(target, source) { |
| var index, length, key, sourceKeys; |
| |
| if (source) { |
| sourceKeys = Object.keys(source); |
| |
| for (index = 0, length = sourceKeys.length; index < length; index += 1) { |
| key = sourceKeys[index]; |
| target[key] = source[key]; |
| } |
| } |
| |
| return target; |
| } |
| |
| |
| function repeat(string, count) { |
| var result = '', cycle; |
| |
| for (cycle = 0; cycle < count; cycle += 1) { |
| result += string; |
| } |
| |
| return result; |
| } |
| |
| |
| function isNegativeZero(number) { |
| return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number); |
| } |
| |
| |
| module.exports.isNothing = isNothing; |
| module.exports.isObject = isObject; |
| module.exports.toArray = toArray; |
| module.exports.repeat = repeat; |
| module.exports.isNegativeZero = isNegativeZero; |
| module.exports.extend = extend; |
| |
| },{}],22:[function(require,module,exports){ |
| 'use strict'; |
| |
| /*eslint-disable no-use-before-define*/ |
| |
| var common = require('./common'); |
| var YAMLException = require('./exception'); |
| var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); |
| var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); |
| |
| var _toString = Object.prototype.toString; |
| var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| |
| var CHAR_TAB = 0x09; /* Tab */ |
| var CHAR_LINE_FEED = 0x0A; /* LF */ |
| var CHAR_SPACE = 0x20; /* Space */ |
| var CHAR_EXCLAMATION = 0x21; /* ! */ |
| var CHAR_DOUBLE_QUOTE = 0x22; /* " */ |
| var CHAR_SHARP = 0x23; /* # */ |
| var CHAR_PERCENT = 0x25; /* % */ |
| var CHAR_AMPERSAND = 0x26; /* & */ |
| var CHAR_SINGLE_QUOTE = 0x27; /* ' */ |
| var CHAR_ASTERISK = 0x2A; /* * */ |
| var CHAR_COMMA = 0x2C; /* , */ |
| var CHAR_MINUS = 0x2D; /* - */ |
| var CHAR_COLON = 0x3A; /* : */ |
| var CHAR_GREATER_THAN = 0x3E; /* > */ |
| var CHAR_QUESTION = 0x3F; /* ? */ |
| var CHAR_COMMERCIAL_AT = 0x40; /* @ */ |
| var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ |
| var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ |
| var CHAR_GRAVE_ACCENT = 0x60; /* ` */ |
| var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ |
| var CHAR_VERTICAL_LINE = 0x7C; /* | */ |
| var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ |
| |
| var ESCAPE_SEQUENCES = {}; |
| |
| ESCAPE_SEQUENCES[0x00] = '\\0'; |
| ESCAPE_SEQUENCES[0x07] = '\\a'; |
| ESCAPE_SEQUENCES[0x08] = '\\b'; |
| ESCAPE_SEQUENCES[0x09] = '\\t'; |
| ESCAPE_SEQUENCES[0x0A] = '\\n'; |
| ESCAPE_SEQUENCES[0x0B] = '\\v'; |
| ESCAPE_SEQUENCES[0x0C] = '\\f'; |
| ESCAPE_SEQUENCES[0x0D] = '\\r'; |
| ESCAPE_SEQUENCES[0x1B] = '\\e'; |
| ESCAPE_SEQUENCES[0x22] = '\\"'; |
| ESCAPE_SEQUENCES[0x5C] = '\\\\'; |
| ESCAPE_SEQUENCES[0x85] = '\\N'; |
| ESCAPE_SEQUENCES[0xA0] = '\\_'; |
| ESCAPE_SEQUENCES[0x2028] = '\\L'; |
| ESCAPE_SEQUENCES[0x2029] = '\\P'; |
| |
| var DEPRECATED_BOOLEANS_SYNTAX = [ |
| 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', |
| 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' |
| ]; |
| |
| function compileStyleMap(schema, map) { |
| var result, keys, index, length, tag, style, type; |
| |
| if (map === null) return {}; |
| |
| result = {}; |
| keys = Object.keys(map); |
| |
| for (index = 0, length = keys.length; index < length; index += 1) { |
| tag = keys[index]; |
| style = String(map[tag]); |
| |
| if (tag.slice(0, 2) === '!!') { |
| tag = 'tag:yaml.org,2002:' + tag.slice(2); |
| } |
| |
| type = schema.compiledTypeMap[tag]; |
| |
| if (type && _hasOwnProperty.call(type.styleAliases, style)) { |
| style = type.styleAliases[style]; |
| } |
| |
| result[tag] = style; |
| } |
| |
| return result; |
| } |
| |
| function encodeHex(character) { |
| var string, handle, length; |
| |
| string = character.toString(16).toUpperCase(); |
| |
| if (character <= 0xFF) { |
| handle = 'x'; |
| length = 2; |
| } else if (character <= 0xFFFF) { |
| handle = 'u'; |
| length = 4; |
| } else if (character <= 0xFFFFFFFF) { |
| handle = 'U'; |
| length = 8; |
| } else { |
| throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF'); |
| } |
| |
| return '\\' + handle + common.repeat('0', length - string.length) + string; |
| } |
| |
| function State(options) { |
| this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; |
| this.indent = Math.max(1, (options['indent'] || 2)); |
| this.skipInvalid = options['skipInvalid'] || false; |
| this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); |
| this.styleMap = compileStyleMap(this.schema, options['styles'] || null); |
| this.sortKeys = options['sortKeys'] || false; |
| this.lineWidth = options['lineWidth'] || 80; |
| this.noRefs = options['noRefs'] || false; |
| this.noCompatMode = options['noCompatMode'] || false; |
| |
| this.implicitTypes = this.schema.compiledImplicit; |
| this.explicitTypes = this.schema.compiledExplicit; |
| |
| this.tag = null; |
| this.result = ''; |
| |
| this.duplicates = []; |
| this.usedDuplicates = null; |
| } |
| |
| // Indents every line in a string. Empty lines (\n only) are not indented. |
| function indentString(string, spaces) { |
| var ind = common.repeat(' ', spaces), |
| position = 0, |
| next = -1, |
| result = '', |
| line, |
| length = string.length; |
| |
| while (position < length) { |
| next = string.indexOf('\n', position); |
| if (next === -1) { |
| line = string.slice(position); |
| position = length; |
| } else { |
| line = string.slice(position, next + 1); |
| position = next + 1; |
| } |
| |
| if (line.length && line !== '\n') result += ind; |
| |
| result += line; |
| } |
| |
| return result; |
| } |
| |
| function generateNextLine(state, level) { |
| return '\n' + common.repeat(' ', state.indent * level); |
| } |
| |
| function testImplicitResolving(state, str) { |
| var index, length, type; |
| |
| for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { |
| type = state.implicitTypes[index]; |
| |
| if (type.resolve(str)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| // [33] s-white ::= s-space | s-tab |
| function isWhitespace(c) { |
| return c === CHAR_SPACE || c === CHAR_TAB; |
| } |
| |
| // Returns true if the character can be printed without escaping. |
| // From YAML 1.2: "any allowed characters known to be non-printable |
| // should also be escaped. [However,] This isn’t mandatory" |
| // Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. |
| function isPrintable(c) { |
| return (0x00020 <= c && c <= 0x00007E) |
| || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) |
| || ((0x0E000 <= c && c <= 0x00FFFD) && c !== 0xFEFF /* BOM */) |
| || (0x10000 <= c && c <= 0x10FFFF); |
| } |
| |
| // Simplified test for values allowed after the first character in plain style. |
| function isPlainSafe(c) { |
| // Uses a subset of nb-char - c-flow-indicator - ":" - "#" |
| // where nb-char ::= c-printable - b-char - c-byte-order-mark. |
| return isPrintable(c) && c !== 0xFEFF |
| // - c-flow-indicator |
| && c !== CHAR_COMMA |
| && c !== CHAR_LEFT_SQUARE_BRACKET |
| && c !== CHAR_RIGHT_SQUARE_BRACKET |
| && c !== CHAR_LEFT_CURLY_BRACKET |
| && c !== CHAR_RIGHT_CURLY_BRACKET |
| // - ":" - "#" |
| && c !== CHAR_COLON |
| && c !== CHAR_SHARP; |
| } |
| |
| // Simplified test for values allowed as the first character in plain style. |
| function isPlainSafeFirst(c) { |
| // Uses a subset of ns-char - c-indicator |
| // where ns-char = nb-char - s-white. |
| return isPrintable(c) && c !== 0xFEFF |
| && !isWhitespace(c) // - s-white |
| // - (c-indicator ::= |
| // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” |
| && c !== CHAR_MINUS |
| && c !== CHAR_QUESTION |
| && c !== CHAR_COLON |
| && c !== CHAR_COMMA |
| && c !== CHAR_LEFT_SQUARE_BRACKET |
| && c !== CHAR_RIGHT_SQUARE_BRACKET |
| && c !== CHAR_LEFT_CURLY_BRACKET |
| && c !== CHAR_RIGHT_CURLY_BRACKET |
| // | “#” | “&” | “*” | “!” | “|” | “>” | “'” | “"” |
| && c !== CHAR_SHARP |
| && c !== CHAR_AMPERSAND |
| && c !== CHAR_ASTERISK |
| && c !== CHAR_EXCLAMATION |
| && c !== CHAR_VERTICAL_LINE |
| && c !== CHAR_GREATER_THAN |
| && c !== CHAR_SINGLE_QUOTE |
| && c !== CHAR_DOUBLE_QUOTE |
| // | “%” | “@” | “`”) |
| && c !== CHAR_PERCENT |
| && c !== CHAR_COMMERCIAL_AT |
| && c !== CHAR_GRAVE_ACCENT; |
| } |
| |
| var STYLE_PLAIN = 1, |
| STYLE_SINGLE = 2, |
| STYLE_LITERAL = 3, |
| STYLE_FOLDED = 4, |
| STYLE_DOUBLE = 5; |
| |
| // Determines which scalar styles are possible and returns the preferred style. |
| // lineWidth = -1 => no limit. |
| // Pre-conditions: str.length > 0. |
| // Post-conditions: |
| // STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. |
| // STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). |
| // STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). |
| function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) { |
| var i; |
| var char; |
| var hasLineBreak = false; |
| var hasFoldableLine = false; // only checked if shouldTrackWidth |
| var shouldTrackWidth = lineWidth !== -1; |
| var previousLineBreak = -1; // count the first line correctly |
| var plain = isPlainSafeFirst(string.charCodeAt(0)) |
| && !isWhitespace(string.charCodeAt(string.length - 1)); |
| |
| if (singleLineOnly) { |
| // Case: no block styles. |
| // Check for disallowed characters to rule out plain and single. |
| for (i = 0; i < string.length; i++) { |
| char = string.charCodeAt(i); |
| if (!isPrintable(char)) { |
| return STYLE_DOUBLE; |
| } |
| plain = plain && isPlainSafe(char); |
| } |
| } else { |
| // Case: block styles permitted. |
| for (i = 0; i < string.length; i++) { |
| char = string.charCodeAt(i); |
| if (char === CHAR_LINE_FEED) { |
| hasLineBreak = true; |
| // Check if any line can be folded. |
| if (shouldTrackWidth) { |
| hasFoldableLine = hasFoldableLine || |
| // Foldable line = too long, and not more-indented. |
| (i - previousLineBreak - 1 > lineWidth && |
| string[previousLineBreak + 1] !== ' '); |
| previousLineBreak = i; |
| } |
| } else if (!isPrintable(char)) { |
| return STYLE_DOUBLE; |
| } |
| plain = plain && isPlainSafe(char); |
| } |
| // in case the end is missing a \n |
| hasFoldableLine = hasFoldableLine || (shouldTrackWidth && |
| (i - previousLineBreak - 1 > lineWidth && |
| string[previousLineBreak + 1] !== ' ')); |
| } |
| // Although every style can represent \n without escaping, prefer block styles |
| // for multiline, since they're more readable and they don't add empty lines. |
| // Also prefer folding a super-long line. |
| if (!hasLineBreak && !hasFoldableLine) { |
| // Strings interpretable as another type have to be quoted; |
| // e.g. the string 'true' vs. the boolean true. |
| return plain && !testAmbiguousType(string) |
| ? STYLE_PLAIN : STYLE_SINGLE; |
| } |
| // Edge case: block indentation indicator can only have one digit. |
| if (string[0] === ' ' && indentPerLevel > 9) { |
| return STYLE_DOUBLE; |
| } |
| // At this point we know block styles are valid. |
| // Prefer literal style unless we want to fold. |
| return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; |
| } |
| |
| // Note: line breaking/folding is implemented for only the folded style. |
| // NB. We drop the last trailing newline (if any) of a returned block scalar |
| // since the dumper adds its own newline. This always works: |
| // • No ending newline => unaffected; already using strip "-" chomping. |
| // • Ending newline => removed then restored. |
| // Importantly, this keeps the "+" chomp indicator from gaining an extra line. |
| function writeScalar(state, string, level, iskey) { |
| state.dump = (function () { |
| if (string.length === 0) { |
| return "''"; |
| } |
| if (!state.noCompatMode && |
| DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1) { |
| return "'" + string + "'"; |
| } |
| |
| var indent = state.indent * Math.max(1, level); // no 0-indent scalars |
| // As indentation gets deeper, let the width decrease monotonically |
| // to the lower bound min(state.lineWidth, 40). |
| // Note that this implies |
| // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. |
| // state.lineWidth > 40 + state.indent: width decreases until the lower bound. |
| // This behaves better than a constant minimum width which disallows narrower options, |
| // or an indent threshold which causes the width to suddenly increase. |
| var lineWidth = state.lineWidth === -1 |
| ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); |
| |
| // Without knowing if keys are implicit/explicit, assume implicit for safety. |
| var singleLineOnly = iskey |
| // No block styles in flow mode. |
| || (state.flowLevel > -1 && level >= state.flowLevel); |
| function testAmbiguity(string) { |
| return testImplicitResolving(state, string); |
| } |
| |
| switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, testAmbiguity)) { |
| case STYLE_PLAIN: |
| return string; |
| case STYLE_SINGLE: |
| return "'" + string.replace(/'/g, "''") + "'"; |
| case STYLE_LITERAL: |
| return '|' + blockHeader(string, state.indent) |
| + dropEndingNewline(indentString(string, indent)); |
| case STYLE_FOLDED: |
| return '>' + blockHeader(string, state.indent) |
| + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); |
| case STYLE_DOUBLE: |
| return '"' + escapeString(string, lineWidth) + '"'; |
| default: |
| throw new YAMLException('impossible error: invalid scalar style'); |
| } |
| }()); |
| } |
| |
| // Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. |
| function blockHeader(string, indentPerLevel) { |
| var indentIndicator = (string[0] === ' ') ? String(indentPerLevel) : ''; |
| |
| // note the special case: the string '\n' counts as a "trailing" empty line. |
| var clip = string[string.length - 1] === '\n'; |
| var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); |
| var chomp = keep ? '+' : (clip ? '' : '-'); |
| |
| return indentIndicator + chomp + '\n'; |
| } |
| |
| // (See the note for writeScalar.) |
| function dropEndingNewline(string) { |
| return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; |
| } |
| |
| // Note: a long line without a suitable break point will exceed the width limit. |
| // Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. |
| function foldString(string, width) { |
| // In folded style, $k$ consecutive newlines output as $k+1$ newlines— |
| // unless they're before or after a more-indented line, or at the very |
| // beginning or end, in which case $k$ maps to $k$. |
| // Therefore, parse each chunk as newline(s) followed by a content line. |
| var lineRe = /(\n+)([^\n]*)/g; |
| |
| // first line (possibly an empty line) |
| var result = (function () { |
| var nextLF = string.indexOf('\n'); |
| nextLF = nextLF !== -1 ? nextLF : string.length; |
| lineRe.lastIndex = nextLF; |
| return foldLine(string.slice(0, nextLF), width); |
| }()); |
| // If we haven't reached the first content line yet, don't add an extra \n. |
| var prevMoreIndented = string[0] === '\n' || string[0] === ' '; |
| var moreIndented; |
| |
| // rest of the lines |
| var match; |
| while ((match = lineRe.exec(string))) { |
| var prefix = match[1], line = match[2]; |
| moreIndented = (line[0] === ' '); |
| result += prefix |
| + (!prevMoreIndented && !moreIndented && line !== '' |
| ? '\n' : '') |
| + foldLine(line, width); |
| prevMoreIndented = moreIndented; |
| } |
| |
| return result; |
| } |
| |
| // Greedy line breaking. |
| // Picks the longest line under the limit each time, |
| // otherwise settles for the shortest line over the limit. |
| // NB. More-indented lines *cannot* be folded, as that would add an extra \n. |
| function foldLine(line, width) { |
| if (line === '' || line[0] === ' ') return line; |
| |
| // Since a more-indented line adds a \n, breaks can't be followed by a space. |
| var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. |
| var match; |
| // start is an inclusive index. end, curr, and next are exclusive. |
| var start = 0, end, curr = 0, next = 0; |
| var result = ''; |
| |
| // Invariants: 0 <= start <= length-1. |
| // 0 <= curr <= next <= max(0, length-2). curr - start <= width. |
| // Inside the loop: |
| // A match implies length >= 2, so curr and next are <= length-2. |
| while ((match = breakRe.exec(line))) { |
| next = match.index; |
| // maintain invariant: curr - start <= width |
| if (next - start > width) { |
| end = (curr > start) ? curr : next; // derive end <= length-2 |
| result += '\n' + line.slice(start, end); |
| // skip the space that was output as \n |
| start = end + 1; // derive start <= length-1 |
| } |
| curr = next; |
| } |
| |
| // By the invariants, start <= length-1, so there is something left over. |
| // It is either the whole string or a part starting from non-whitespace. |
| result += '\n'; |
| // Insert a break if the remainder is too long and there is a break available. |
| if (line.length - start > width && curr > start) { |
| result += line.slice(start, curr) + '\n' + line.slice(curr + 1); |
| } else { |
| result += line.slice(start); |
| } |
| |
| return result.slice(1); // drop extra \n joiner |
| } |
| |
| // Escapes a double-quoted string. |
| function escapeString(string) { |
| var result = ''; |
| var char; |
| var escapeSeq; |
| |
| for (var i = 0; i < string.length; i++) { |
| char = string.charCodeAt(i); |
| escapeSeq = ESCAPE_SEQUENCES[char]; |
| result += !escapeSeq && isPrintable(char) |
| ? string[i] |
| : escapeSeq || encodeHex(char); |
| } |
| |
| return result; |
| } |
| |
| function writeFlowSequence(state, level, object) { |
| var _result = '', |
| _tag = state.tag, |
| index, |
| length; |
| |
| for (index = 0, length = object.length; index < length; index += 1) { |
| // Write only valid elements. |
| if (writeNode(state, level, object[index], false, false)) { |
| if (index !== 0) _result += ', '; |
| _result += state.dump; |
| } |
| } |
| |
| state.tag = _tag; |
| state.dump = '[' + _result + ']'; |
| } |
| |
| function writeBlockSequence(state, level, object, compact) { |
| var _result = '', |
| _tag = state.tag, |
| index, |
| length; |
| |
| for (index = 0, length = object.length; index < length; index += 1) { |
| // Write only valid elements. |
| if (writeNode(state, level + 1, object[index], true, true)) { |
| if (!compact || index !== 0) { |
| _result += generateNextLine(state, level); |
| } |
| _result += '- ' + state.dump; |
| } |
| } |
| |
| state.tag = _tag; |
| state.dump = _result || '[]'; // Empty sequence if no valid values. |
| } |
| |
| function writeFlowMapping(state, level, object) { |
| var _result = '', |
| _tag = state.tag, |
| objectKeyList = Object.keys(object), |
| index, |
| length, |
| objectKey, |
| objectValue, |
| pairBuffer; |
| |
| for (index = 0, length = objectKeyList.length; index < length; index += 1) { |
| pairBuffer = ''; |
| |
| if (index !== 0) pairBuffer += ', '; |
| |
| objectKey = objectKeyList[index]; |
| objectValue = object[objectKey]; |
| |
| if (!writeNode(state, level, objectKey, false, false)) { |
| continue; // Skip this pair because of invalid key; |
| } |
| |
| if (state.dump.length > 1024) pairBuffer += '? '; |
| |
| pairBuffer += state.dump + ': '; |
| |
| if (!writeNode(state, level, objectValue, false, false)) { |
| continue; // Skip this pair because of invalid value. |
| } |
| |
| pairBuffer += state.dump; |
| |
| // Both key and value are valid. |
| _result += pairBuffer; |
| } |
| |
| state.tag = _tag; |
| state.dump = '{' + _result + '}'; |
| } |
| |
| function writeBlockMapping(state, level, object, compact) { |
| var _result = '', |
| _tag = state.tag, |
| objectKeyList = Object.keys(object), |
| index, |
| length, |
| objectKey, |
| objectValue, |
| explicitPair, |
| pairBuffer; |
| |
| // Allow sorting keys so that the output file is deterministic |
| if (state.sortKeys === true) { |
| // Default sorting |
| objectKeyList.sort(); |
| } else if (typeof state.sortKeys === 'function') { |
| // Custom sort function |
| objectKeyList.sort(state.sortKeys); |
| } else if (state.sortKeys) { |
| // Something is wrong |
| throw new YAMLException('sortKeys must be a boolean or a function'); |
| } |
| |
| for (index = 0, length = objectKeyList.length; index < length; index += 1) { |
| pairBuffer = ''; |
| |
| if (!compact || index !== 0) { |
| pairBuffer += generateNextLine(state, level); |
| } |
| |
| objectKey = objectKeyList[index]; |
| objectValue = object[objectKey]; |
| |
| if (!writeNode(state, level + 1, objectKey, true, true, true)) { |
| continue; // Skip this pair because of invalid key. |
| } |
| |
| explicitPair = (state.tag !== null && state.tag !== '?') || |
| (state.dump && state.dump.length > 1024); |
| |
| if (explicitPair) { |
| if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { |
| pairBuffer += '?'; |
| } else { |
| pairBuffer += '? '; |
| } |
| } |
| |
| pairBuffer += state.dump; |
| |
| if (explicitPair) { |
| pairBuffer += generateNextLine(state, level); |
| } |
| |
| if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { |
| continue; // Skip this pair because of invalid value. |
| } |
| |
| if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { |
| pairBuffer += ':'; |
| } else { |
| pairBuffer += ': '; |
| } |
| |
| pairBuffer += state.dump; |
| |
| // Both key and value are valid. |
| _result += pairBuffer; |
| } |
| |
| state.tag = _tag; |
| state.dump = _result || '{}'; // Empty mapping if no valid pairs. |
| } |
| |
| function detectType(state, object, explicit) { |
| var _result, typeList, index, length, type, style; |
| |
| typeList = explicit ? state.explicitTypes : state.implicitTypes; |
| |
| for (index = 0, length = typeList.length; index < length; index += 1) { |
| type = typeList[index]; |
| |
| if ((type.instanceOf || type.predicate) && |
| (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && |
| (!type.predicate || type.predicate(object))) { |
| |
| state.tag = explicit ? type.tag : '?'; |
| |
| if (type.represent) { |
| style = state.styleMap[type.tag] || type.defaultStyle; |
| |
| if (_toString.call(type.represent) === '[object Function]') { |
| _result = type.represent(object, style); |
| } else if (_hasOwnProperty.call(type.represent, style)) { |
| _result = type.represent[style](object, style); |
| } else { |
| throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); |
| } |
| |
| state.dump = _result; |
| } |
| |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| // Serializes `object` and writes it to global `result`. |
| // Returns true on success, or false on invalid object. |
| // |
| function writeNode(state, level, object, block, compact, iskey) { |
| state.tag = null; |
| state.dump = object; |
| |
| if (!detectType(state, object, false)) { |
| detectType(state, object, true); |
| } |
| |
| var type = _toString.call(state.dump); |
| |
| if (block) { |
| block = (state.flowLevel < 0 || state.flowLevel > level); |
| } |
| |
| var objectOrArray = type === '[object Object]' || type === '[object Array]', |
| duplicateIndex, |
| duplicate; |
| |
| if (objectOrArray) { |
| duplicateIndex = state.duplicates.indexOf(object); |
| duplicate = duplicateIndex !== -1; |
| } |
| |
| if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { |
| compact = false; |
| } |
| |
| if (duplicate && state.usedDuplicates[duplicateIndex]) { |
| state.dump = '*ref_' + duplicateIndex; |
| } else { |
| if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { |
| state.usedDuplicates[duplicateIndex] = true; |
| } |
| if (type === '[object Object]') { |
| if (block && (Object.keys(state.dump).length !== 0)) { |
| writeBlockMapping(state, level, state.dump, compact); |
| if (duplicate) { |
| state.dump = '&ref_' + duplicateIndex + state.dump; |
| } |
| } else { |
| writeFlowMapping(state, level, state.dump); |
| if (duplicate) { |
| state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; |
| } |
| } |
| } else if (type === '[object Array]') { |
| if (block && (state.dump.length !== 0)) { |
| writeBlockSequence(state, level, state.dump, compact); |
| if (duplicate) { |
| state.dump = '&ref_' + duplicateIndex + state.dump; |
| } |
| } else { |
| writeFlowSequence(state, level, state.dump); |
| if (duplicate) { |
| state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; |
| } |
| } |
| } else if (type === '[object String]') { |
| if (state.tag !== '?') { |
| writeScalar(state, state.dump, level, iskey); |
| } |
| } else { |
| if (state.skipInvalid) return false; |
| throw new YAMLException('unacceptable kind of an object to dump ' + type); |
| } |
| |
| if (state.tag !== null && state.tag !== '?') { |
| state.dump = '!<' + state.tag + '> ' + state.dump; |
| } |
| } |
| |
| return true; |
| } |
| |
| function getDuplicateReferences(object, state) { |
| var objects = [], |
| duplicatesIndexes = [], |
| index, |
| length; |
| |
| inspectNode(object, objects, duplicatesIndexes); |
| |
| for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { |
| state.duplicates.push(objects[duplicatesIndexes[index]]); |
| } |
| state.usedDuplicates = new Array(length); |
| } |
| |
| function inspectNode(object, objects, duplicatesIndexes) { |
| var objectKeyList, |
| index, |
| length; |
| |
| if (object !== null && typeof object === 'object') { |
| index = objects.indexOf(object); |
| if (index !== -1) { |
| if (duplicatesIndexes.indexOf(index) === -1) { |
| duplicatesIndexes.push(index); |
| } |
| } else { |
| objects.push(object); |
| |
| if (Array.isArray(object)) { |
| for (index = 0, length = object.length; index < length; index += 1) { |
| inspectNode(object[index], objects, duplicatesIndexes); |
| } |
| } else { |
| objectKeyList = Object.keys(object); |
| |
| for (index = 0, length = objectKeyList.length; index < length; index += 1) { |
| inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); |
| } |
| } |
| } |
| } |
| } |
| |
| function dump(input, options) { |
| options = options || {}; |
| |
| var state = new State(options); |
| |
| if (!state.noRefs) getDuplicateReferences(input, state); |
| |
| if (writeNode(state, 0, input, true, true)) return state.dump + '\n'; |
| |
| return ''; |
| } |
| |
| function safeDump(input, options) { |
| return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); |
| } |
| |
| module.exports.dump = dump; |
| module.exports.safeDump = safeDump; |
| |
| },{"./common":21,"./exception":23,"./schema/default_full":28,"./schema/default_safe":29}],23:[function(require,module,exports){ |
| // YAML error class. http://stackoverflow.com/questions/8458984 |
| // |
| 'use strict'; |
| |
| function YAMLException(reason, mark) { |
| // Super constructor |
| Error.call(this); |
| |
| // Include stack trace in error object |
| if (Error.captureStackTrace) { |
| // Chrome and NodeJS |
| Error.captureStackTrace(this, this.constructor); |
| } else { |
| // FF, IE 10+ and Safari 6+. Fallback for others |
| this.stack = (new Error()).stack || ''; |
| } |
| |
| this.name = 'YAMLException'; |
| this.reason = reason; |
| this.mark = mark; |
| this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : ''); |
| } |
| |
| |
| // Inherit from Error |
| YAMLException.prototype = Object.create(Error.prototype); |
| YAMLException.prototype.constructor = YAMLException; |
| |
| |
| YAMLException.prototype.toString = function toString(compact) { |
| var result = this.name + ': '; |
| |
| result += this.reason || '(unknown reason)'; |
| |
| if (!compact && this.mark) { |
| result += ' ' + this.mark.toString(); |
| } |
| |
| return result; |
| }; |
| |
| |
| module.exports = YAMLException; |
| |
| },{}],24:[function(require,module,exports){ |
| 'use strict'; |
| |
| /*eslint-disable max-len,no-use-before-define*/ |
| |
| var common = require('./common'); |
| var YAMLException = require('./exception'); |
| var Mark = require('./mark'); |
| var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); |
| var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); |
| |
| |
| var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| |
| |
| var CONTEXT_FLOW_IN = 1; |
| var CONTEXT_FLOW_OUT = 2; |
| var CONTEXT_BLOCK_IN = 3; |
| var CONTEXT_BLOCK_OUT = 4; |
| |
| |
| var CHOMPING_CLIP = 1; |
| var CHOMPING_STRIP = 2; |
| var CHOMPING_KEEP = 3; |
| |
| |
| var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; |
| var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; |
| var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; |
| var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; |
| var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; |
| |
| |
| function is_EOL(c) { |
| return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); |
| } |
| |
| function is_WHITE_SPACE(c) { |
| return (c === 0x09/* Tab */) || (c === 0x20/* Space */); |
| } |
| |
| function is_WS_OR_EOL(c) { |
| return (c === 0x09/* Tab */) || |
| (c === 0x20/* Space */) || |
| (c === 0x0A/* LF */) || |
| (c === 0x0D/* CR */); |
| } |
| |
| function is_FLOW_INDICATOR(c) { |
| return c === 0x2C/* , */ || |
| c === 0x5B/* [ */ || |
| c === 0x5D/* ] */ || |
| c === 0x7B/* { */ || |
| c === 0x7D/* } */; |
| } |
| |
| function fromHexCode(c) { |
| var lc; |
| |
| if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { |
| return c - 0x30; |
| } |
| |
| /*eslint-disable no-bitwise*/ |
| lc = c | 0x20; |
| |
| if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { |
| return lc - 0x61 + 10; |
| } |
| |
| return -1; |
| } |
| |
| function escapedHexLen(c) { |
| if (c === 0x78/* x */) { return 2; } |
| if (c === 0x75/* u */) { return 4; } |
| if (c === 0x55/* U */) { return 8; } |
| return 0; |
| } |
| |
| function fromDecimalCode(c) { |
| if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { |
| return c - 0x30; |
| } |
| |
| return -1; |
| } |
| |
| function simpleEscapeSequence(c) { |
| return (c === 0x30/* 0 */) ? '\x00' : |
| (c === 0x61/* a */) ? '\x07' : |
| (c === 0x62/* b */) ? '\x08' : |
| (c === 0x74/* t */) ? '\x09' : |
| (c === 0x09/* Tab */) ? '\x09' : |
| (c === 0x6E/* n */) ? '\x0A' : |
| (c === 0x76/* v */) ? '\x0B' : |
| (c === 0x66/* f */) ? '\x0C' : |
| (c === 0x72/* r */) ? '\x0D' : |
| (c === 0x65/* e */) ? '\x1B' : |
| (c === 0x20/* Space */) ? ' ' : |
| (c === 0x22/* " */) ? '\x22' : |
| (c === 0x2F/* / */) ? '/' : |
| (c === 0x5C/* \ */) ? '\x5C' : |
| (c === 0x4E/* N */) ? '\x85' : |
| (c === 0x5F/* _ */) ? '\xA0' : |
| (c === 0x4C/* L */) ? '\u2028' : |
| (c === 0x50/* P */) ? '\u2029' : ''; |
| } |
| |
| function charFromCodepoint(c) { |
| if (c <= 0xFFFF) { |
| return String.fromCharCode(c); |
| } |
| // Encode UTF-16 surrogate pair |
| // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF |
| return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800, |
| ((c - 0x010000) & 0x03FF) + 0xDC00); |
| } |
| |
| var simpleEscapeCheck = new Array(256); // integer, for fast access |
| var simpleEscapeMap = new Array(256); |
| for (var i = 0; i < 256; i++) { |
| simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; |
| simpleEscapeMap[i] = simpleEscapeSequence(i); |
| } |
| |
| |
| function State(input, options) { |
| this.input = input; |
| |
| this.filename = options['filename'] || null; |
| this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; |
| this.onWarning = options['onWarning'] || null; |
| this.legacy = options['legacy'] || false; |
| this.json = options['json'] || false; |
| this.listener = options['listener'] || null; |
| |
| this.implicitTypes = this.schema.compiledImplicit; |
| this.typeMap = this.schema.compiledTypeMap; |
| |
| this.length = input.length; |
| this.position = 0; |
| this.line = 0; |
| this.lineStart = 0; |
| this.lineIndent = 0; |
| |
| this.documents = []; |
| |
| /* |
| this.version; |
| this.checkLineBreaks; |
| this.tagMap; |
| this.anchorMap; |
| this.tag; |
| this.anchor; |
| this.kind; |
| this.result;*/ |
| |
| } |
| |
| |
| function generateError(state, message) { |
| return new YAMLException( |
| message, |
| new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart))); |
| } |
| |
| function throwError(state, message) { |
| throw generateError(state, message); |
| } |
| |
| function throwWarning(state, message) { |
| if (state.onWarning) { |
| state.onWarning.call(null, generateError(state, message)); |
| } |
| } |
| |
| |
| var directiveHandlers = { |
| |
| YAML: function handleYamlDirective(state, name, args) { |
| |
| var match, major, minor; |
| |
| if (state.version !== null) { |
| throwError(state, 'duplication of %YAML directive'); |
| } |
| |
| if (args.length !== 1) { |
| throwError(state, 'YAML directive accepts exactly one argument'); |
| } |
| |
| match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); |
| |
| if (match === null) { |
| throwError(state, 'ill-formed argument of the YAML directive'); |
| } |
| |
| major = parseInt(match[1], 10); |
| minor = parseInt(match[2], 10); |
| |
| if (major !== 1) { |
| throwError(state, 'unacceptable YAML version of the document'); |
| } |
| |
| state.version = args[0]; |
| state.checkLineBreaks = (minor < 2); |
| |
| if (minor !== 1 && minor !== 2) { |
| throwWarning(state, 'unsupported YAML version of the document'); |
| } |
| }, |
| |
| TAG: function handleTagDirective(state, name, args) { |
| |
| var handle, prefix; |
| |
| if (args.length !== 2) { |
| throwError(state, 'TAG directive accepts exactly two arguments'); |
| } |
| |
| handle = args[0]; |
| prefix = args[1]; |
| |
| if (!PATTERN_TAG_HANDLE.test(handle)) { |
| throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); |
| } |
| |
| if (_hasOwnProperty.call(state.tagMap, handle)) { |
| throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); |
| } |
| |
| if (!PATTERN_TAG_URI.test(prefix)) { |
| throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); |
| } |
| |
| state.tagMap[handle] = prefix; |
| } |
| }; |
| |
| |
| function captureSegment(state, start, end, checkJson) { |
| var _position, _length, _character, _result; |
| |
| if (start < end) { |
| _result = state.input.slice(start, end); |
| |
| if (checkJson) { |
| for (_position = 0, _length = _result.length; |
| _position < _length; |
| _position += 1) { |
| _character = _result.charCodeAt(_position); |
| if (!(_character === 0x09 || |
| (0x20 <= _character && _character <= 0x10FFFF))) { |
| throwError(state, 'expected valid JSON character'); |
| } |
| } |
| } else if (PATTERN_NON_PRINTABLE.test(_result)) { |
| throwError(state, 'the stream contains non-printable characters'); |
| } |
| |
| state.result += _result; |
| } |
| } |
| |
| function mergeMappings(state, destination, source, overridableKeys) { |
| var sourceKeys, key, index, quantity; |
| |
| if (!common.isObject(source)) { |
| throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); |
| } |
| |
| sourceKeys = Object.keys(source); |
| |
| for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { |
| key = sourceKeys[index]; |
| |
| if (!_hasOwnProperty.call(destination, key)) { |
| destination[key] = source[key]; |
| overridableKeys[key] = true; |
| } |
| } |
| } |
| |
| function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) { |
| var index, quantity; |
| |
| keyNode = String(keyNode); |
| |
| if (_result === null) { |
| _result = {}; |
| } |
| |
| if (keyTag === 'tag:yaml.org,2002:merge') { |
| if (Array.isArray(valueNode)) { |
| for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { |
| mergeMappings(state, _result, valueNode[index], overridableKeys); |
| } |
| } else { |
| mergeMappings(state, _result, valueNode, overridableKeys); |
| } |
| } else { |
| if (!state.json && |
| !_hasOwnProperty.call(overridableKeys, keyNode) && |
| _hasOwnProperty.call(_result, keyNode)) { |
| throwError(state, 'duplicated mapping key'); |
| } |
| _result[keyNode] = valueNode; |
| delete overridableKeys[keyNode]; |
| } |
| |
| return _result; |
| } |
| |
| function readLineBreak(state) { |
| var ch; |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (ch === 0x0A/* LF */) { |
| state.position++; |
| } else if (ch === 0x0D/* CR */) { |
| state.position++; |
| if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { |
| state.position++; |
| } |
| } else { |
| throwError(state, 'a line break is expected'); |
| } |
| |
| state.line += 1; |
| state.lineStart = state.position; |
| } |
| |
| function skipSeparationSpace(state, allowComments, checkIndent) { |
| var lineBreaks = 0, |
| ch = state.input.charCodeAt(state.position); |
| |
| while (ch !== 0) { |
| while (is_WHITE_SPACE(ch)) { |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| if (allowComments && ch === 0x23/* # */) { |
| do { |
| ch = state.input.charCodeAt(++state.position); |
| } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); |
| } |
| |
| if (is_EOL(ch)) { |
| readLineBreak(state); |
| |
| ch = state.input.charCodeAt(state.position); |
| lineBreaks++; |
| state.lineIndent = 0; |
| |
| while (ch === 0x20/* Space */) { |
| state.lineIndent++; |
| ch = state.input.charCodeAt(++state.position); |
| } |
| } else { |
| break; |
| } |
| } |
| |
| if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { |
| throwWarning(state, 'deficient indentation'); |
| } |
| |
| return lineBreaks; |
| } |
| |
| function testDocumentSeparator(state) { |
| var _position = state.position, |
| ch; |
| |
| ch = state.input.charCodeAt(_position); |
| |
| // Condition state.position === state.lineStart is tested |
| // in parent on each call, for efficiency. No needs to test here again. |
| if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && |
| ch === state.input.charCodeAt(_position + 1) && |
| ch === state.input.charCodeAt(_position + 2)) { |
| |
| _position += 3; |
| |
| ch = state.input.charCodeAt(_position); |
| |
| if (ch === 0 || is_WS_OR_EOL(ch)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| function writeFoldedLines(state, count) { |
| if (count === 1) { |
| state.result += ' '; |
| } else if (count > 1) { |
| state.result += common.repeat('\n', count - 1); |
| } |
| } |
| |
| |
| function readPlainScalar(state, nodeIndent, withinFlowCollection) { |
| var preceding, |
| following, |
| captureStart, |
| captureEnd, |
| hasPendingContent, |
| _line, |
| _lineStart, |
| _lineIndent, |
| _kind = state.kind, |
| _result = state.result, |
| ch; |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (is_WS_OR_EOL(ch) || |
| is_FLOW_INDICATOR(ch) || |
| ch === 0x23/* # */ || |
| ch === 0x26/* & */ || |
| ch === 0x2A/* * */ || |
| ch === 0x21/* ! */ || |
| ch === 0x7C/* | */ || |
| ch === 0x3E/* > */ || |
| ch === 0x27/* ' */ || |
| ch === 0x22/* " */ || |
| ch === 0x25/* % */ || |
| ch === 0x40/* @ */ || |
| ch === 0x60/* ` */) { |
| return false; |
| } |
| |
| if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { |
| following = state.input.charCodeAt(state.position + 1); |
| |
| if (is_WS_OR_EOL(following) || |
| withinFlowCollection && is_FLOW_INDICATOR(following)) { |
| return false; |
| } |
| } |
| |
| state.kind = 'scalar'; |
| state.result = ''; |
| captureStart = captureEnd = state.position; |
| hasPendingContent = false; |
| |
| while (ch !== 0) { |
| if (ch === 0x3A/* : */) { |
| following = state.input.charCodeAt(state.position + 1); |
| |
| if (is_WS_OR_EOL(following) || |
| withinFlowCollection && is_FLOW_INDICATOR(following)) { |
| break; |
| } |
| |
| } else if (ch === 0x23/* # */) { |
| preceding = state.input.charCodeAt(state.position - 1); |
| |
| if (is_WS_OR_EOL(preceding)) { |
| break; |
| } |
| |
| } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || |
| withinFlowCollection && is_FLOW_INDICATOR(ch)) { |
| break; |
| |
| } else if (is_EOL(ch)) { |
| _line = state.line; |
| _lineStart = state.lineStart; |
| _lineIndent = state.lineIndent; |
| skipSeparationSpace(state, false, -1); |
| |
| if (state.lineIndent >= nodeIndent) { |
| hasPendingContent = true; |
| ch = state.input.charCodeAt(state.position); |
| continue; |
| } else { |
| state.position = captureEnd; |
| state.line = _line; |
| state.lineStart = _lineStart; |
| state.lineIndent = _lineIndent; |
| break; |
| } |
| } |
| |
| if (hasPendingContent) { |
| captureSegment(state, captureStart, captureEnd, false); |
| writeFoldedLines(state, state.line - _line); |
| captureStart = captureEnd = state.position; |
| hasPendingContent = false; |
| } |
| |
| if (!is_WHITE_SPACE(ch)) { |
| captureEnd = state.position + 1; |
| } |
| |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| captureSegment(state, captureStart, captureEnd, false); |
| |
| if (state.result) { |
| return true; |
| } |
| |
| state.kind = _kind; |
| state.result = _result; |
| return false; |
| } |
| |
| function readSingleQuotedScalar(state, nodeIndent) { |
| var ch, |
| captureStart, captureEnd; |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (ch !== 0x27/* ' */) { |
| return false; |
| } |
| |
| state.kind = 'scalar'; |
| state.result = ''; |
| state.position++; |
| captureStart = captureEnd = state.position; |
| |
| while ((ch = state.input.charCodeAt(state.position)) !== 0) { |
| if (ch === 0x27/* ' */) { |
| captureSegment(state, captureStart, state.position, true); |
| ch = state.input.charCodeAt(++state.position); |
| |
| if (ch === 0x27/* ' */) { |
| captureStart = captureEnd = state.position; |
| state.position++; |
| } else { |
| return true; |
| } |
| |
| } else if (is_EOL(ch)) { |
| captureSegment(state, captureStart, captureEnd, true); |
| writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); |
| captureStart = captureEnd = state.position; |
| |
| } else if (state.position === state.lineStart && testDocumentSeparator(state)) { |
| throwError(state, 'unexpected end of the document within a single quoted scalar'); |
| |
| } else { |
| state.position++; |
| captureEnd = state.position; |
| } |
| } |
| |
| throwError(state, 'unexpected end of the stream within a single quoted scalar'); |
| } |
| |
| function readDoubleQuotedScalar(state, nodeIndent) { |
| var captureStart, |
| captureEnd, |
| hexLength, |
| hexResult, |
| tmp, |
| ch; |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (ch !== 0x22/* " */) { |
| return false; |
| } |
| |
| state.kind = 'scalar'; |
| state.result = ''; |
| state.position++; |
| captureStart = captureEnd = state.position; |
| |
| while ((ch = state.input.charCodeAt(state.position)) !== 0) { |
| if (ch === 0x22/* " */) { |
| captureSegment(state, captureStart, state.position, true); |
| state.position++; |
| return true; |
| |
| } else if (ch === 0x5C/* \ */) { |
| captureSegment(state, captureStart, state.position, true); |
| ch = state.input.charCodeAt(++state.position); |
| |
| if (is_EOL(ch)) { |
| skipSeparationSpace(state, false, nodeIndent); |
| |
| // TODO: rework to inline fn with no type cast? |
| } else if (ch < 256 && simpleEscapeCheck[ch]) { |
| state.result += simpleEscapeMap[ch]; |
| state.position++; |
| |
| } else if ((tmp = escapedHexLen(ch)) > 0) { |
| hexLength = tmp; |
| hexResult = 0; |
| |
| for (; hexLength > 0; hexLength--) { |
| ch = state.input.charCodeAt(++state.position); |
| |
| if ((tmp = fromHexCode(ch)) >= 0) { |
| hexResult = (hexResult << 4) + tmp; |
| |
| } else { |
| throwError(state, 'expected hexadecimal character'); |
| } |
| } |
| |
| state.result += charFromCodepoint(hexResult); |
| |
| state.position++; |
| |
| } else { |
| throwError(state, 'unknown escape sequence'); |
| } |
| |
| captureStart = captureEnd = state.position; |
| |
| } else if (is_EOL(ch)) { |
| captureSegment(state, captureStart, captureEnd, true); |
| writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); |
| captureStart = captureEnd = state.position; |
| |
| } else if (state.position === state.lineStart && testDocumentSeparator(state)) { |
| throwError(state, 'unexpected end of the document within a double quoted scalar'); |
| |
| } else { |
| state.position++; |
| captureEnd = state.position; |
| } |
| } |
| |
| throwError(state, 'unexpected end of the stream within a double quoted scalar'); |
| } |
| |
| function readFlowCollection(state, nodeIndent) { |
| var readNext = true, |
| _line, |
| _tag = state.tag, |
| _result, |
| _anchor = state.anchor, |
| following, |
| terminator, |
| isPair, |
| isExplicitPair, |
| isMapping, |
| overridableKeys = {}, |
| keyNode, |
| keyTag, |
| valueNode, |
| ch; |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (ch === 0x5B/* [ */) { |
| terminator = 0x5D;/* ] */ |
| isMapping = false; |
| _result = []; |
| } else if (ch === 0x7B/* { */) { |
| terminator = 0x7D;/* } */ |
| isMapping = true; |
| _result = {}; |
| } else { |
| return false; |
| } |
| |
| if (state.anchor !== null) { |
| state.anchorMap[state.anchor] = _result; |
| } |
| |
| ch = state.input.charCodeAt(++state.position); |
| |
| while (ch !== 0) { |
| skipSeparationSpace(state, true, nodeIndent); |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (ch === terminator) { |
| state.position++; |
| state.tag = _tag; |
| state.anchor = _anchor; |
| state.kind = isMapping ? 'mapping' : 'sequence'; |
| state.result = _result; |
| return true; |
| } else if (!readNext) { |
| throwError(state, 'missed comma between flow collection entries'); |
| } |
| |
| keyTag = keyNode = valueNode = null; |
| isPair = isExplicitPair = false; |
| |
| if (ch === 0x3F/* ? */) { |
| following = state.input.charCodeAt(state.position + 1); |
| |
| if (is_WS_OR_EOL(following)) { |
| isPair = isExplicitPair = true; |
| state.position++; |
| skipSeparationSpace(state, true, nodeIndent); |
| } |
| } |
| |
| _line = state.line; |
| composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); |
| keyTag = state.tag; |
| keyNode = state.result; |
| skipSeparationSpace(state, true, nodeIndent); |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { |
| isPair = true; |
| ch = state.input.charCodeAt(++state.position); |
| skipSeparationSpace(state, true, nodeIndent); |
| composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); |
| valueNode = state.result; |
| } |
| |
| if (isMapping) { |
| storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); |
| } else if (isPair) { |
| _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode)); |
| } else { |
| _result.push(keyNode); |
| } |
| |
| skipSeparationSpace(state, true, nodeIndent); |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (ch === 0x2C/* , */) { |
| readNext = true; |
| ch = state.input.charCodeAt(++state.position); |
| } else { |
| readNext = false; |
| } |
| } |
| |
| throwError(state, 'unexpected end of the stream within a flow collection'); |
| } |
| |
| function readBlockScalar(state, nodeIndent) { |
| var captureStart, |
| folding, |
| chomping = CHOMPING_CLIP, |
| didReadContent = false, |
| detectedIndent = false, |
| textIndent = nodeIndent, |
| emptyLines = 0, |
| atMoreIndented = false, |
| tmp, |
| ch; |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (ch === 0x7C/* | */) { |
| folding = false; |
| } else if (ch === 0x3E/* > */) { |
| folding = true; |
| } else { |
| return false; |
| } |
| |
| state.kind = 'scalar'; |
| state.result = ''; |
| |
| while (ch !== 0) { |
| ch = state.input.charCodeAt(++state.position); |
| |
| if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { |
| if (CHOMPING_CLIP === chomping) { |
| chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; |
| } else { |
| throwError(state, 'repeat of a chomping mode identifier'); |
| } |
| |
| } else if ((tmp = fromDecimalCode(ch)) >= 0) { |
| if (tmp === 0) { |
| throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); |
| } else if (!detectedIndent) { |
| textIndent = nodeIndent + tmp - 1; |
| detectedIndent = true; |
| } else { |
| throwError(state, 'repeat of an indentation width identifier'); |
| } |
| |
| } else { |
| break; |
| } |
| } |
| |
| if (is_WHITE_SPACE(ch)) { |
| do { ch = state.input.charCodeAt(++state.position); } |
| while (is_WHITE_SPACE(ch)); |
| |
| if (ch === 0x23/* # */) { |
| do { ch = state.input.charCodeAt(++state.position); } |
| while (!is_EOL(ch) && (ch !== 0)); |
| } |
| } |
| |
| while (ch !== 0) { |
| readLineBreak(state); |
| state.lineIndent = 0; |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| while ((!detectedIndent || state.lineIndent < textIndent) && |
| (ch === 0x20/* Space */)) { |
| state.lineIndent++; |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| if (!detectedIndent && state.lineIndent > textIndent) { |
| textIndent = state.lineIndent; |
| } |
| |
| if (is_EOL(ch)) { |
| emptyLines++; |
| continue; |
| } |
| |
| // End of the scalar. |
| if (state.lineIndent < textIndent) { |
| |
| // Perform the chomping. |
| if (chomping === CHOMPING_KEEP) { |
| state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); |
| } else if (chomping === CHOMPING_CLIP) { |
| if (didReadContent) { // i.e. only if the scalar is not empty. |
| state.result += '\n'; |
| } |
| } |
| |
| // Break this `while` cycle and go to the funciton's epilogue. |
| break; |
| } |
| |
| // Folded style: use fancy rules to handle line breaks. |
| if (folding) { |
| |
| // Lines starting with white space characters (more-indented lines) are not folded. |
| if (is_WHITE_SPACE(ch)) { |
| atMoreIndented = true; |
| // except for the first content line (cf. Example 8.1) |
| state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); |
| |
| // End of more-indented block. |
| } else if (atMoreIndented) { |
| atMoreIndented = false; |
| state.result += common.repeat('\n', emptyLines + 1); |
| |
| // Just one line break - perceive as the same line. |
| } else if (emptyLines === 0) { |
| if (didReadContent) { // i.e. only if we have already read some scalar content. |
| state.result += ' '; |
| } |
| |
| // Several line breaks - perceive as different lines. |
| } else { |
| state.result += common.repeat('\n', emptyLines); |
| } |
| |
| // Literal style: just add exact number of line breaks between content lines. |
| } else { |
| // Keep all line breaks except the header line break. |
| state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); |
| } |
| |
| didReadContent = true; |
| detectedIndent = true; |
| emptyLines = 0; |
| captureStart = state.position; |
| |
| while (!is_EOL(ch) && (ch !== 0)) { |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| captureSegment(state, captureStart, state.position, false); |
| } |
| |
| return true; |
| } |
| |
| function readBlockSequence(state, nodeIndent) { |
| var _line, |
| _tag = state.tag, |
| _anchor = state.anchor, |
| _result = [], |
| following, |
| detected = false, |
| ch; |
| |
| if (state.anchor !== null) { |
| state.anchorMap[state.anchor] = _result; |
| } |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| while (ch !== 0) { |
| |
| if (ch !== 0x2D/* - */) { |
| break; |
| } |
| |
| following = state.input.charCodeAt(state.position + 1); |
| |
| if (!is_WS_OR_EOL(following)) { |
| break; |
| } |
| |
| detected = true; |
| state.position++; |
| |
| if (skipSeparationSpace(state, true, -1)) { |
| if (state.lineIndent <= nodeIndent) { |
| _result.push(null); |
| ch = state.input.charCodeAt(state.position); |
| continue; |
| } |
| } |
| |
| _line = state.line; |
| composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); |
| _result.push(state.result); |
| skipSeparationSpace(state, true, -1); |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { |
| throwError(state, 'bad indentation of a sequence entry'); |
| } else if (state.lineIndent < nodeIndent) { |
| break; |
| } |
| } |
| |
| if (detected) { |
| state.tag = _tag; |
| state.anchor = _anchor; |
| state.kind = 'sequence'; |
| state.result = _result; |
| return true; |
| } |
| return false; |
| } |
| |
| function readBlockMapping(state, nodeIndent, flowIndent) { |
| var following, |
| allowCompact, |
| _line, |
| _tag = state.tag, |
| _anchor = state.anchor, |
| _result = {}, |
| overridableKeys = {}, |
| keyTag = null, |
| keyNode = null, |
| valueNode = null, |
| atExplicitKey = false, |
| detected = false, |
| ch; |
| |
| if (state.anchor !== null) { |
| state.anchorMap[state.anchor] = _result; |
| } |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| while (ch !== 0) { |
| following = state.input.charCodeAt(state.position + 1); |
| _line = state.line; // Save the current line. |
| |
| // |
| // Explicit notation case. There are two separate blocks: |
| // first for the key (denoted by "?") and second for the value (denoted by ":") |
| // |
| if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { |
| |
| if (ch === 0x3F/* ? */) { |
| if (atExplicitKey) { |
| storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); |
| keyTag = keyNode = valueNode = null; |
| } |
| |
| detected = true; |
| atExplicitKey = true; |
| allowCompact = true; |
| |
| } else if (atExplicitKey) { |
| // i.e. 0x3A/* : */ === character after the explicit key. |
| atExplicitKey = false; |
| allowCompact = true; |
| |
| } else { |
| throwError(state, 'incomplete explicit mapping pair; a key node is missed'); |
| } |
| |
| state.position += 1; |
| ch = following; |
| |
| // |
| // Implicit notation case. Flow-style node as the key first, then ":", and the value. |
| // |
| } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { |
| |
| if (state.line === _line) { |
| ch = state.input.charCodeAt(state.position); |
| |
| while (is_WHITE_SPACE(ch)) { |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| if (ch === 0x3A/* : */) { |
| ch = state.input.charCodeAt(++state.position); |
| |
| if (!is_WS_OR_EOL(ch)) { |
| throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); |
| } |
| |
| if (atExplicitKey) { |
| storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); |
| keyTag = keyNode = valueNode = null; |
| } |
| |
| detected = true; |
| atExplicitKey = false; |
| allowCompact = false; |
| keyTag = state.tag; |
| keyNode = state.result; |
| |
| } else if (detected) { |
| throwError(state, 'can not read an implicit mapping pair; a colon is missed'); |
| |
| } else { |
| state.tag = _tag; |
| state.anchor = _anchor; |
| return true; // Keep the result of `composeNode`. |
| } |
| |
| } else if (detected) { |
| throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); |
| |
| } else { |
| state.tag = _tag; |
| state.anchor = _anchor; |
| return true; // Keep the result of `composeNode`. |
| } |
| |
| } else { |
| break; // Reading is done. Go to the epilogue. |
| } |
| |
| // |
| // Common reading code for both explicit and implicit notations. |
| // |
| if (state.line === _line || state.lineIndent > nodeIndent) { |
| if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { |
| if (atExplicitKey) { |
| keyNode = state.result; |
| } else { |
| valueNode = state.result; |
| } |
| } |
| |
| if (!atExplicitKey) { |
| storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); |
| keyTag = keyNode = valueNode = null; |
| } |
| |
| skipSeparationSpace(state, true, -1); |
| ch = state.input.charCodeAt(state.position); |
| } |
| |
| if (state.lineIndent > nodeIndent && (ch !== 0)) { |
| throwError(state, 'bad indentation of a mapping entry'); |
| } else if (state.lineIndent < nodeIndent) { |
| break; |
| } |
| } |
| |
| // |
| // Epilogue. |
| // |
| |
| // Special case: last mapping's node contains only the key in explicit notation. |
| if (atExplicitKey) { |
| storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); |
| } |
| |
| // Expose the resulting mapping. |
| if (detected) { |
| state.tag = _tag; |
| state.anchor = _anchor; |
| state.kind = 'mapping'; |
| state.result = _result; |
| } |
| |
| return detected; |
| } |
| |
| function readTagProperty(state) { |
| var _position, |
| isVerbatim = false, |
| isNamed = false, |
| tagHandle, |
| tagName, |
| ch; |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (ch !== 0x21/* ! */) return false; |
| |
| if (state.tag !== null) { |
| throwError(state, 'duplication of a tag property'); |
| } |
| |
| ch = state.input.charCodeAt(++state.position); |
| |
| if (ch === 0x3C/* < */) { |
| isVerbatim = true; |
| ch = state.input.charCodeAt(++state.position); |
| |
| } else if (ch === 0x21/* ! */) { |
| isNamed = true; |
| tagHandle = '!!'; |
| ch = state.input.charCodeAt(++state.position); |
| |
| } else { |
| tagHandle = '!'; |
| } |
| |
| _position = state.position; |
| |
| if (isVerbatim) { |
| do { ch = state.input.charCodeAt(++state.position); } |
| while (ch !== 0 && ch !== 0x3E/* > */); |
| |
| if (state.position < state.length) { |
| tagName = state.input.slice(_position, state.position); |
| ch = state.input.charCodeAt(++state.position); |
| } else { |
| throwError(state, 'unexpected end of the stream within a verbatim tag'); |
| } |
| } else { |
| while (ch !== 0 && !is_WS_OR_EOL(ch)) { |
| |
| if (ch === 0x21/* ! */) { |
| if (!isNamed) { |
| tagHandle = state.input.slice(_position - 1, state.position + 1); |
| |
| if (!PATTERN_TAG_HANDLE.test(tagHandle)) { |
| throwError(state, 'named tag handle cannot contain such characters'); |
| } |
| |
| isNamed = true; |
| _position = state.position + 1; |
| } else { |
| throwError(state, 'tag suffix cannot contain exclamation marks'); |
| } |
| } |
| |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| tagName = state.input.slice(_position, state.position); |
| |
| if (PATTERN_FLOW_INDICATORS.test(tagName)) { |
| throwError(state, 'tag suffix cannot contain flow indicator characters'); |
| } |
| } |
| |
| if (tagName && !PATTERN_TAG_URI.test(tagName)) { |
| throwError(state, 'tag name cannot contain such characters: ' + tagName); |
| } |
| |
| if (isVerbatim) { |
| state.tag = tagName; |
| |
| } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) { |
| state.tag = state.tagMap[tagHandle] + tagName; |
| |
| } else if (tagHandle === '!') { |
| state.tag = '!' + tagName; |
| |
| } else if (tagHandle === '!!') { |
| state.tag = 'tag:yaml.org,2002:' + tagName; |
| |
| } else { |
| throwError(state, 'undeclared tag handle "' + tagHandle + '"'); |
| } |
| |
| return true; |
| } |
| |
| function readAnchorProperty(state) { |
| var _position, |
| ch; |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (ch !== 0x26/* & */) return false; |
| |
| if (state.anchor !== null) { |
| throwError(state, 'duplication of an anchor property'); |
| } |
| |
| ch = state.input.charCodeAt(++state.position); |
| _position = state.position; |
| |
| while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| if (state.position === _position) { |
| throwError(state, 'name of an anchor node must contain at least one character'); |
| } |
| |
| state.anchor = state.input.slice(_position, state.position); |
| return true; |
| } |
| |
| function readAlias(state) { |
| var _position, alias, |
| ch; |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (ch !== 0x2A/* * */) return false; |
| |
| ch = state.input.charCodeAt(++state.position); |
| _position = state.position; |
| |
| while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| if (state.position === _position) { |
| throwError(state, 'name of an alias node must contain at least one character'); |
| } |
| |
| alias = state.input.slice(_position, state.position); |
| |
| if (!state.anchorMap.hasOwnProperty(alias)) { |
| throwError(state, 'unidentified alias "' + alias + '"'); |
| } |
| |
| state.result = state.anchorMap[alias]; |
| skipSeparationSpace(state, true, -1); |
| return true; |
| } |
| |
| function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { |
| var allowBlockStyles, |
| allowBlockScalars, |
| allowBlockCollections, |
| indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent |
| atNewLine = false, |
| hasContent = false, |
| typeIndex, |
| typeQuantity, |
| type, |
| flowIndent, |
| blockIndent; |
| |
| if (state.listener !== null) { |
| state.listener('open', state); |
| } |
| |
| state.tag = null; |
| state.anchor = null; |
| state.kind = null; |
| state.result = null; |
| |
| allowBlockStyles = allowBlockScalars = allowBlockCollections = |
| CONTEXT_BLOCK_OUT === nodeContext || |
| CONTEXT_BLOCK_IN === nodeContext; |
| |
| if (allowToSeek) { |
| if (skipSeparationSpace(state, true, -1)) { |
| atNewLine = true; |
| |
| if (state.lineIndent > parentIndent) { |
| indentStatus = 1; |
| } else if (state.lineIndent === parentIndent) { |
| indentStatus = 0; |
| } else if (state.lineIndent < parentIndent) { |
| indentStatus = -1; |
| } |
| } |
| } |
| |
| if (indentStatus === 1) { |
| while (readTagProperty(state) || readAnchorProperty(state)) { |
| if (skipSeparationSpace(state, true, -1)) { |
| atNewLine = true; |
| allowBlockCollections = allowBlockStyles; |
| |
| if (state.lineIndent > parentIndent) { |
| indentStatus = 1; |
| } else if (state.lineIndent === parentIndent) { |
| indentStatus = 0; |
| } else if (state.lineIndent < parentIndent) { |
| indentStatus = -1; |
| } |
| } else { |
| allowBlockCollections = false; |
| } |
| } |
| } |
| |
| if (allowBlockCollections) { |
| allowBlockCollections = atNewLine || allowCompact; |
| } |
| |
| if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { |
| if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { |
| flowIndent = parentIndent; |
| } else { |
| flowIndent = parentIndent + 1; |
| } |
| |
| blockIndent = state.position - state.lineStart; |
| |
| if (indentStatus === 1) { |
| if (allowBlockCollections && |
| (readBlockSequence(state, blockIndent) || |
| readBlockMapping(state, blockIndent, flowIndent)) || |
| readFlowCollection(state, flowIndent)) { |
| hasContent = true; |
| } else { |
| if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || |
| readSingleQuotedScalar(state, flowIndent) || |
| readDoubleQuotedScalar(state, flowIndent)) { |
| hasContent = true; |
| |
| } else if (readAlias(state)) { |
| hasContent = true; |
| |
| if (state.tag !== null || state.anchor !== null) { |
| throwError(state, 'alias node should not have any properties'); |
| } |
| |
| } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { |
| hasContent = true; |
| |
| if (state.tag === null) { |
| state.tag = '?'; |
| } |
| } |
| |
| if (state.anchor !== null) { |
| state.anchorMap[state.anchor] = state.result; |
| } |
| } |
| } else if (indentStatus === 0) { |
| // Special case: block sequences are allowed to have same indentation level as the parent. |
| // http://www.yaml.org/spec/1.2/spec.html#id2799784 |
| hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); |
| } |
| } |
| |
| if (state.tag !== null && state.tag !== '!') { |
| if (state.tag === '?') { |
| for (typeIndex = 0, typeQuantity = state.implicitTypes.length; |
| typeIndex < typeQuantity; |
| typeIndex += 1) { |
| type = state.implicitTypes[typeIndex]; |
| |
| // Implicit resolving is not allowed for non-scalar types, and '?' |
| // non-specific tag is only assigned to plain scalars. So, it isn't |
| // needed to check for 'kind' conformity. |
| |
| if (type.resolve(state.result)) { // `state.result` updated in resolver if matched |
| state.result = type.construct(state.result); |
| state.tag = type.tag; |
| if (state.anchor !== null) { |
| state.anchorMap[state.anchor] = state.result; |
| } |
| break; |
| } |
| } |
| } else if (_hasOwnProperty.call(state.typeMap, state.tag)) { |
| type = state.typeMap[state.tag]; |
| |
| if (state.result !== null && type.kind !== state.kind) { |
| throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); |
| } |
| |
| if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched |
| throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); |
| } else { |
| state.result = type.construct(state.result); |
| if (state.anchor !== null) { |
| state.anchorMap[state.anchor] = state.result; |
| } |
| } |
| } else { |
| throwError(state, 'unknown tag !<' + state.tag + '>'); |
| } |
| } |
| |
| if (state.listener !== null) { |
| state.listener('close', state); |
| } |
| return state.tag !== null || state.anchor !== null || hasContent; |
| } |
| |
| function readDocument(state) { |
| var documentStart = state.position, |
| _position, |
| directiveName, |
| directiveArgs, |
| hasDirectives = false, |
| ch; |
| |
| state.version = null; |
| state.checkLineBreaks = state.legacy; |
| state.tagMap = {}; |
| state.anchorMap = {}; |
| |
| while ((ch = state.input.charCodeAt(state.position)) !== 0) { |
| skipSeparationSpace(state, true, -1); |
| |
| ch = state.input.charCodeAt(state.position); |
| |
| if (state.lineIndent > 0 || ch !== 0x25/* % */) { |
| break; |
| } |
| |
| hasDirectives = true; |
| ch = state.input.charCodeAt(++state.position); |
| _position = state.position; |
| |
| while (ch !== 0 && !is_WS_OR_EOL(ch)) { |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| directiveName = state.input.slice(_position, state.position); |
| directiveArgs = []; |
| |
| if (directiveName.length < 1) { |
| throwError(state, 'directive name must not be less than one character in length'); |
| } |
| |
| while (ch !== 0) { |
| while (is_WHITE_SPACE(ch)) { |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| if (ch === 0x23/* # */) { |
| do { ch = state.input.charCodeAt(++state.position); } |
| while (ch !== 0 && !is_EOL(ch)); |
| break; |
| } |
| |
| if (is_EOL(ch)) break; |
| |
| _position = state.position; |
| |
| while (ch !== 0 && !is_WS_OR_EOL(ch)) { |
| ch = state.input.charCodeAt(++state.position); |
| } |
| |
| directiveArgs.push(state.input.slice(_position, state.position)); |
| } |
| |
| if (ch !== 0) readLineBreak(state); |
| |
| if (_hasOwnProperty.call(directiveHandlers, directiveName)) { |
| directiveHandlers[directiveName](state, directiveName, directiveArgs); |
| } else { |
| throwWarning(state, 'unknown document directive "' + directiveName + '"'); |
| } |
| } |
| |
| skipSeparationSpace(state, true, -1); |
| |
| if (state.lineIndent === 0 && |
| state.input.charCodeAt(state.position) === 0x2D/* - */ && |
| state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && |
| state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { |
| state.position += 3; |
| skipSeparationSpace(state, true, -1); |
| |
| } else if (hasDirectives) { |
| throwError(state, 'directives end mark is expected'); |
| } |
| |
| composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); |
| skipSeparationSpace(state, true, -1); |
| |
| if (state.checkLineBreaks && |
| PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { |
| throwWarning(state, 'non-ASCII line breaks are interpreted as content'); |
| } |
| |
| state.documents.push(state.result); |
| |
| if (state.position === state.lineStart && testDocumentSeparator(state)) { |
| |
| if (state.input.charCodeAt(state.position) === 0x2E/* . */) { |
| state.position += 3; |
| skipSeparationSpace(state, true, -1); |
| } |
| return; |
| } |
| |
| if (state.position < (state.length - 1)) { |
| throwError(state, 'end of the stream or a document separator is expected'); |
| } else { |
| return; |
| } |
| } |
| |
| |
| function loadDocuments(input, options) { |
| input = String(input); |
| options = options || {}; |
| |
| if (input.length !== 0) { |
| |
| // Add tailing `\n` if not exists |
| if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && |
| input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { |
| input += '\n'; |
| } |
| |
| // Strip BOM |
| if (input.charCodeAt(0) === 0xFEFF) { |
| input = input.slice(1); |
| } |
| } |
| |
| var state = new State(input, options); |
| |
| // Use 0 as string terminator. That significantly simplifies bounds check. |
| state.input += '\0'; |
| |
| while (state.input.charCodeAt(state.position) === 0x20/* Space */) { |
| state.lineIndent += 1; |
| state.position += 1; |
| } |
| |
| while (state.position < (state.length - 1)) { |
| readDocument(state); |
| } |
| |
| return state.documents; |
| } |
| |
| |
| function loadAll(input, iterator, options) { |
| var documents = loadDocuments(input, options), index, length; |
| |
| for (index = 0, length = documents.length; index < length; index += 1) { |
| iterator(documents[index]); |
| } |
| } |
| |
| |
| function load(input, options) { |
| var documents = loadDocuments(input, options); |
| |
| if (documents.length === 0) { |
| /*eslint-disable no-undefined*/ |
| return undefined; |
| } else if (documents.length === 1) { |
| return documents[0]; |
| } |
| throw new YAMLException('expected a single document in the stream, but found more'); |
| } |
| |
| |
| function safeLoadAll(input, output, options) { |
| loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); |
| } |
| |
| |
| function safeLoad(input, options) { |
| return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); |
| } |
| |
| |
| module.exports.loadAll = loadAll; |
| module.exports.load = load; |
| module.exports.safeLoadAll = safeLoadAll; |
| module.exports.safeLoad = safeLoad; |
| |
| },{"./common":21,"./exception":23,"./mark":25,"./schema/default_full":28,"./schema/default_safe":29}],25:[function(require,module,exports){ |
| 'use strict'; |
| |
| |
| var common = require('./common'); |
| |
| |
| function Mark(name, buffer, position, line, column) { |
| this.name = name; |
| this.buffer = buffer; |
| this.position = position; |
| this.line = line; |
| this.column = column; |
| } |
| |
| |
| Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { |
| var head, start, tail, end, snippet; |
| |
| if (!this.buffer) return null; |
| |
| indent = indent || 4; |
| maxLength = maxLength || 75; |
| |
| head = ''; |
| start = this.position; |
| |
| while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) { |
| start -= 1; |
| if (this.position - start > (maxLength / 2 - 1)) { |
| head = ' ... '; |
| start += 5; |
| break; |
| } |
| } |
| |
| tail = ''; |
| end = this.position; |
| |
| while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) { |
| end += 1; |
| if (end - this.position > (maxLength / 2 - 1)) { |
| tail = ' ... '; |
| end -= 5; |
| break; |
| } |
| } |
| |
| snippet = this.buffer.slice(start, end); |
| |
| return common.repeat(' ', indent) + head + snippet + tail + '\n' + |
| common.repeat(' ', indent + this.position - start + head.length) + '^'; |
| }; |
| |
| |
| Mark.prototype.toString = function toString(compact) { |
| var snippet, where = ''; |
| |
| if (this.name) { |
| where += 'in "' + this.name + '" '; |
| } |
| |
| where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1); |
| |
| if (!compact) { |
| snippet = this.getSnippet(); |
| |
| if (snippet) { |
| where += ':\n' + snippet; |
| } |
| } |
| |
| return where; |
| }; |
| |
| |
| module.exports = Mark; |
| |
| },{"./common":21}],26:[function(require,module,exports){ |
| 'use strict'; |
| |
| /*eslint-disable max-len*/ |
| |
| var common = require('./common'); |
| var YAMLException = require('./exception'); |
| var Type = require('./type'); |
| |
| |
| function compileList(schema, name, result) { |
| var exclude = []; |
| |
| schema.include.forEach(function (includedSchema) { |
| result = compileList(includedSchema, name, result); |
| }); |
| |
| schema[name].forEach(function (currentType) { |
| result.forEach(function (previousType, previousIndex) { |
| if (previousType.tag === currentType.tag) { |
| exclude.push(previousIndex); |
| } |
| }); |
| |
| result.push(currentType); |
| }); |
| |
| return result.filter(function (type, index) { |
| return exclude.indexOf(index) === -1; |
| }); |
| } |
| |
| |
| function compileMap(/* lists... */) { |
| var result = {}, index, length; |
| |
| function collectType(type) { |
| result[type.tag] = type; |
| } |
| |
| for (index = 0, length = arguments.length; index < length; index += 1) { |
| arguments[index].forEach(collectType); |
| } |
| |
| return result; |
| } |
| |
| |
| function Schema(definition) { |
| this.include = definition.include || []; |
| this.implicit = definition.implicit || []; |
| this.explicit = definition.explicit || []; |
| |
| this.implicit.forEach(function (type) { |
| if (type.loadKind && type.loadKind !== 'scalar') { |
| throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); |
| } |
| }); |
| |
| this.compiledImplicit = compileList(this, 'implicit', []); |
| this.compiledExplicit = compileList(this, 'explicit', []); |
| this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit); |
| } |
| |
| |
| Schema.DEFAULT = null; |
| |
| |
| Schema.create = function createSchema() { |
| var schemas, types; |
| |
| switch (arguments.length) { |
| case 1: |
| schemas = Schema.DEFAULT; |
| types = arguments[0]; |
| break; |
| |
| case 2: |
| schemas = arguments[0]; |
| types = arguments[1]; |
| break; |
| |
| default: |
| throw new YAMLException('Wrong number of arguments for Schema.create function'); |
| } |
| |
| schemas = common.toArray(schemas); |
| types = common.toArray(types); |
| |
| if (!schemas.every(function (schema) { return schema instanceof Schema; })) { |
| throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.'); |
| } |
| |
| if (!types.every(function (type) { return type instanceof Type; })) { |
| throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); |
| } |
| |
| return new Schema({ |
| include: schemas, |
| explicit: types |
| }); |
| }; |
| |
| |
| module.exports = Schema; |
| |
| },{"./common":21,"./exception":23,"./type":32}],27:[function(require,module,exports){ |
| // Standard YAML's Core schema. |
| // http://www.yaml.org/spec/1.2/spec.html#id2804923 |
| // |
| // NOTE: JS-YAML does not support schema-specific tag resolution restrictions. |
| // So, Core schema has no distinctions from JSON schema is JS-YAML. |
| |
| |
| 'use strict'; |
| |
| |
| var Schema = require('../schema'); |
| |
| |
| module.exports = new Schema({ |
| include: [ |
| require('./json') |
| ] |
| }); |
| |
| },{"../schema":26,"./json":31}],28:[function(require,module,exports){ |
| // JS-YAML's default schema for `load` function. |
| // It is not described in the YAML specification. |
| // |
| // This schema is based on JS-YAML's default safe schema and includes |
| // JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function. |
| // |
| // Also this schema is used as default base schema at `Schema.create` function. |
| |
| |
| 'use strict'; |
| |
| |
| var Schema = require('../schema'); |
| |
| |
| module.exports = Schema.DEFAULT = new Schema({ |
| include: [ |
| require('./default_safe') |
| ], |
| explicit: [ |
| require('../type/js/undefined'), |
| require('../type/js/regexp'), |
| require('../type/js/function') |
| ] |
| }); |
| |
| },{"../schema":26,"../type/js/function":37,"../type/js/regexp":38,"../type/js/undefined":39,"./default_safe":29}],29:[function(require,module,exports){ |
| // JS-YAML's default schema for `safeLoad` function. |
| // It is not described in the YAML specification. |
| // |
| // This schema is based on standard YAML's Core schema and includes most of |
| // extra types described at YAML tag repository. (http://yaml.org/type/) |
| |
| |
| 'use strict'; |
| |
| |
| var Schema = require('../schema'); |
| |
| |
| module.exports = new Schema({ |
| include: [ |
| require('./core') |
| ], |
| implicit: [ |
| require('../type/timestamp'), |
| require('../type/merge') |
| ], |
| explicit: [ |
| require('../type/binary'), |
| require('../type/omap'), |
| require('../type/pairs'), |
| require('../type/set') |
| ] |
| }); |
| |
| },{"../schema":26,"../type/binary":33,"../type/merge":41,"../type/omap":43,"../type/pairs":44,"../type/set":46,"../type/timestamp":48,"./core":27}],30:[function(require,module,exports){ |
| // Standard YAML's Failsafe schema. |
| // http://www.yaml.org/spec/1.2/spec.html#id2802346 |
| |
| |
| 'use strict'; |
| |
| |
| var Schema = require('../schema'); |
| |
| |
| module.exports = new Schema({ |
| explicit: [ |
| require('../type/str'), |
| require('../type/seq'), |
| require('../type/map') |
| ] |
| }); |
| |
| },{"../schema":26,"../type/map":40,"../type/seq":45,"../type/str":47}],31:[function(require,module,exports){ |
| // Standard YAML's JSON schema. |
| // http://www.yaml.org/spec/1.2/spec.html#id2803231 |
| // |
| // NOTE: JS-YAML does not support schema-specific tag resolution restrictions. |
| // So, this schema is not such strict as defined in the YAML specification. |
| // It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc. |
| |
| |
| 'use strict'; |
| |
| |
| var Schema = require('../schema'); |
| |
| |
| module.exports = new Schema({ |
| include: [ |
| require('./failsafe') |
| ], |
| implicit: [ |
| require('../type/null'), |
| require('../type/bool'), |
| require('../type/int'), |
| require('../type/float') |
| ] |
| }); |
| |
| },{"../schema":26,"../type/bool":34,"../type/float":35,"../type/int":36,"../type/null":42,"./failsafe":30}],32:[function(require,module,exports){ |
| 'use strict'; |
| |
| var YAMLException = require('./exception'); |
| |
| var TYPE_CONSTRUCTOR_OPTIONS = [ |
| 'kind', |
| 'resolve', |
| 'construct', |
| 'instanceOf', |
| 'predicate', |
| 'represent', |
| 'defaultStyle', |
| 'styleAliases' |
| ]; |
| |
| var YAML_NODE_KINDS = [ |
| 'scalar', |
| 'sequence', |
| 'mapping' |
| ]; |
| |
| function compileStyleAliases(map) { |
| var result = {}; |
| |
| if (map !== null) { |
| Object.keys(map).forEach(function (style) { |
| map[style].forEach(function (alias) { |
| result[String(alias)] = style; |
| }); |
| }); |
| } |
| |
| return result; |
| } |
| |
| function Type(tag, options) { |
| options = options || {}; |
| |
| Object.keys(options).forEach(function (name) { |
| if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { |
| throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); |
| } |
| }); |
| |
| // TODO: Add tag format check. |
| this.tag = tag; |
| this.kind = options['kind'] || null; |
| this.resolve = options['resolve'] || function () { return true; }; |
| this.construct = options['construct'] || function (data) { return data; }; |
| this.instanceOf = options['instanceOf'] || null; |
| this.predicate = options['predicate'] || null; |
| this.represent = options['represent'] || null; |
| this.defaultStyle = options['defaultStyle'] || null; |
| this.styleAliases = compileStyleAliases(options['styleAliases'] || null); |
| |
| if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { |
| throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); |
| } |
| } |
| |
| module.exports = Type; |
| |
| },{"./exception":23}],33:[function(require,module,exports){ |
| 'use strict'; |
| |
| /*eslint-disable no-bitwise*/ |
| |
| var NodeBuffer; |
| |
| try { |
| // A trick for browserified version, to not include `Buffer` shim |
| var _require = require; |
| NodeBuffer = _require('buffer').Buffer; |
| } catch (__) {} |
| |
| var Type = require('../type'); |
| |
| |
| // [ 64, 65, 66 ] -> [ padding, CR, LF ] |
| var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; |
| |
| |
| function resolveYamlBinary(data) { |
| if (data === null) return false; |
| |
| var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; |
| |
| // Convert one by one. |
| for (idx = 0; idx < max; idx++) { |
| code = map.indexOf(data.charAt(idx)); |
| |
| // Skip CR/LF |
| if (code > 64) continue; |
| |
| // Fail on illegal characters |
| if (code < 0) return false; |
| |
| bitlen += 6; |
| } |
| |
| // If there are any bits left, source was corrupted |
| return (bitlen % 8) === 0; |
| } |
| |
| function constructYamlBinary(data) { |
| var idx, tailbits, |
| input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan |
| max = input.length, |
| map = BASE64_MAP, |
| bits = 0, |
| result = []; |
| |
| // Collect by 6*4 bits (3 bytes) |
| |
| for (idx = 0; idx < max; idx++) { |
| if ((idx % 4 === 0) && idx) { |
| result.push((bits >> 16) & 0xFF); |
| result.push((bits >> 8) & 0xFF); |
| result.push(bits & 0xFF); |
| } |
| |
| bits = (bits << 6) | map.indexOf(input.charAt(idx)); |
| } |
| |
| // Dump tail |
| |
| tailbits = (max % 4) * 6; |
| |
| if (tailbits === 0) { |
| result.push((bits >> 16) & 0xFF); |
| result.push((bits >> 8) & 0xFF); |
| result.push(bits & 0xFF); |
| } else if (tailbits === 18) { |
| result.push((bits >> 10) & 0xFF); |
| result.push((bits >> 2) & 0xFF); |
| } else if (tailbits === 12) { |
| result.push((bits >> 4) & 0xFF); |
| } |
| |
| // Wrap into Buffer for NodeJS and leave Array for browser |
| if (NodeBuffer) return new NodeBuffer(result); |
| |
| return result; |
| } |
| |
| function representYamlBinary(object /*, style*/) { |
| var result = '', bits = 0, idx, tail, |
| max = object.length, |
| map = BASE64_MAP; |
| |
| // Convert every three bytes to 4 ASCII characters. |
| |
| for (idx = 0; idx < max; idx++) { |
| if ((idx % 3 === 0) && idx) { |
| result += map[(bits >> 18) & 0x3F]; |
| result += map[(bits >> 12) & 0x3F]; |
| result += map[(bits >> 6) & 0x3F]; |
| result += map[bits & 0x3F]; |
| } |
| |
| bits = (bits << 8) + object[idx]; |
| } |
| |
| // Dump tail |
| |
| tail = max % 3; |
| |
| if (tail === 0) { |
| result += map[(bits >> 18) & 0x3F]; |
| result += map[(bits >> 12) & 0x3F]; |
| result += map[(bits >> 6) & 0x3F]; |
| result += map[bits & 0x3F]; |
| } else if (tail === 2) { |
| result += map[(bits >> 10) & 0x3F]; |
| result += map[(bits >> 4) & 0x3F]; |
| result += map[(bits << 2) & 0x3F]; |
| result += map[64]; |
| } else if (tail === 1) { |
| result += map[(bits >> 2) & 0x3F]; |
| result += map[(bits << 4) & 0x3F]; |
| result += map[64]; |
| result += map[64]; |
| } |
| |
| return result; |
| } |
| |
| function isBinary(object) { |
| return NodeBuffer && NodeBuffer.isBuffer(object); |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:binary', { |
| kind: 'scalar', |
| resolve: resolveYamlBinary, |
| construct: constructYamlBinary, |
| predicate: isBinary, |
| represent: representYamlBinary |
| }); |
| |
| },{"../type":32}],34:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../type'); |
| |
| function resolveYamlBoolean(data) { |
| if (data === null) return false; |
| |
| var max = data.length; |
| |
| return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || |
| (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); |
| } |
| |
| function constructYamlBoolean(data) { |
| return data === 'true' || |
| data === 'True' || |
| data === 'TRUE'; |
| } |
| |
| function isBoolean(object) { |
| return Object.prototype.toString.call(object) === '[object Boolean]'; |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:bool', { |
| kind: 'scalar', |
| resolve: resolveYamlBoolean, |
| construct: constructYamlBoolean, |
| predicate: isBoolean, |
| represent: { |
| lowercase: function (object) { return object ? 'true' : 'false'; }, |
| uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, |
| camelcase: function (object) { return object ? 'True' : 'False'; } |
| }, |
| defaultStyle: 'lowercase' |
| }); |
| |
| },{"../type":32}],35:[function(require,module,exports){ |
| 'use strict'; |
| |
| var common = require('../common'); |
| var Type = require('../type'); |
| |
| var YAML_FLOAT_PATTERN = new RegExp( |
| '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + |
| '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + |
| '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + |
| '|[-+]?\\.(?:inf|Inf|INF)' + |
| '|\\.(?:nan|NaN|NAN))$'); |
| |
| function resolveYamlFloat(data) { |
| if (data === null) return false; |
| |
| if (!YAML_FLOAT_PATTERN.test(data)) return false; |
| |
| return true; |
| } |
| |
| function constructYamlFloat(data) { |
| var value, sign, base, digits; |
| |
| value = data.replace(/_/g, '').toLowerCase(); |
| sign = value[0] === '-' ? -1 : 1; |
| digits = []; |
| |
| if ('+-'.indexOf(value[0]) >= 0) { |
| value = value.slice(1); |
| } |
| |
| if (value === '.inf') { |
| return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; |
| |
| } else if (value === '.nan') { |
| return NaN; |
| |
| } else if (value.indexOf(':') >= 0) { |
| value.split(':').forEach(function (v) { |
| digits.unshift(parseFloat(v, 10)); |
| }); |
| |
| value = 0.0; |
| base = 1; |
| |
| digits.forEach(function (d) { |
| value += d * base; |
| base *= 60; |
| }); |
| |
| return sign * value; |
| |
| } |
| return sign * parseFloat(value, 10); |
| } |
| |
| |
| var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; |
| |
| function representYamlFloat(object, style) { |
| var res; |
| |
| if (isNaN(object)) { |
| switch (style) { |
| case 'lowercase': return '.nan'; |
| case 'uppercase': return '.NAN'; |
| case 'camelcase': return '.NaN'; |
| } |
| } else if (Number.POSITIVE_INFINITY === object) { |
| switch (style) { |
| case 'lowercase': return '.inf'; |
| case 'uppercase': return '.INF'; |
| case 'camelcase': return '.Inf'; |
| } |
| } else if (Number.NEGATIVE_INFINITY === object) { |
| switch (style) { |
| case 'lowercase': return '-.inf'; |
| case 'uppercase': return '-.INF'; |
| case 'camelcase': return '-.Inf'; |
| } |
| } else if (common.isNegativeZero(object)) { |
| return '-0.0'; |
| } |
| |
| res = object.toString(10); |
| |
| // JS stringifier can build scientific format without dots: 5e-100, |
| // while YAML requres dot: 5.e-100. Fix it with simple hack |
| |
| return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; |
| } |
| |
| function isFloat(object) { |
| return (Object.prototype.toString.call(object) === '[object Number]') && |
| (object % 1 !== 0 || common.isNegativeZero(object)); |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:float', { |
| kind: 'scalar', |
| resolve: resolveYamlFloat, |
| construct: constructYamlFloat, |
| predicate: isFloat, |
| represent: representYamlFloat, |
| defaultStyle: 'lowercase' |
| }); |
| |
| },{"../common":21,"../type":32}],36:[function(require,module,exports){ |
| 'use strict'; |
| |
| var common = require('../common'); |
| var Type = require('../type'); |
| |
| function isHexCode(c) { |
| return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || |
| ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || |
| ((0x61/* a */ <= c) && (c <= 0x66/* f */)); |
| } |
| |
| function isOctCode(c) { |
| return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); |
| } |
| |
| function isDecCode(c) { |
| return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); |
| } |
| |
| function resolveYamlInteger(data) { |
| if (data === null) return false; |
| |
| var max = data.length, |
| index = 0, |
| hasDigits = false, |
| ch; |
| |
| if (!max) return false; |
| |
| ch = data[index]; |
| |
| // sign |
| if (ch === '-' || ch === '+') { |
| ch = data[++index]; |
| } |
| |
| if (ch === '0') { |
| // 0 |
| if (index + 1 === max) return true; |
| ch = data[++index]; |
| |
| // base 2, base 8, base 16 |
| |
| if (ch === 'b') { |
| // base 2 |
| index++; |
| |
| for (; index < max; index++) { |
| ch = data[index]; |
| if (ch === '_') continue; |
| if (ch !== '0' && ch !== '1') return false; |
| hasDigits = true; |
| } |
| return hasDigits; |
| } |
| |
| |
| if (ch === 'x') { |
| // base 16 |
| index++; |
| |
| for (; index < max; index++) { |
| ch = data[index]; |
| if (ch === '_') continue; |
| if (!isHexCode(data.charCodeAt(index))) return false; |
| hasDigits = true; |
| } |
| return hasDigits; |
| } |
| |
| // base 8 |
| for (; index < max; index++) { |
| ch = data[index]; |
| if (ch === '_') continue; |
| if (!isOctCode(data.charCodeAt(index))) return false; |
| hasDigits = true; |
| } |
| return hasDigits; |
| } |
| |
| // base 10 (except 0) or base 60 |
| |
| for (; index < max; index++) { |
| ch = data[index]; |
| if (ch === '_') continue; |
| if (ch === ':') break; |
| if (!isDecCode(data.charCodeAt(index))) { |
| return false; |
| } |
| hasDigits = true; |
| } |
| |
| if (!hasDigits) return false; |
| |
| // if !base60 - done; |
| if (ch !== ':') return true; |
| |
| // base60 almost not used, no needs to optimize |
| return /^(:[0-5]?[0-9])+$/.test(data.slice(index)); |
| } |
| |
| function constructYamlInteger(data) { |
| var value = data, sign = 1, ch, base, digits = []; |
| |
| if (value.indexOf('_') !== -1) { |
| value = value.replace(/_/g, ''); |
| } |
| |
| ch = value[0]; |
| |
| if (ch === '-' || ch === '+') { |
| if (ch === '-') sign = -1; |
| value = value.slice(1); |
| ch = value[0]; |
| } |
| |
| if (value === '0') return 0; |
| |
| if (ch === '0') { |
| if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); |
| if (value[1] === 'x') return sign * parseInt(value, 16); |
| return sign * parseInt(value, 8); |
| } |
| |
| if (value.indexOf(':') !== -1) { |
| value.split(':').forEach(function (v) { |
| digits.unshift(parseInt(v, 10)); |
| }); |
| |
| value = 0; |
| base = 1; |
| |
| digits.forEach(function (d) { |
| value += (d * base); |
| base *= 60; |
| }); |
| |
| return sign * value; |
| |
| } |
| |
| return sign * parseInt(value, 10); |
| } |
| |
| function isInteger(object) { |
| return (Object.prototype.toString.call(object)) === '[object Number]' && |
| (object % 1 === 0 && !common.isNegativeZero(object)); |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:int', { |
| kind: 'scalar', |
| resolve: resolveYamlInteger, |
| construct: constructYamlInteger, |
| predicate: isInteger, |
| represent: { |
| binary: function (object) { return '0b' + object.toString(2); }, |
| octal: function (object) { return '0' + object.toString(8); }, |
| decimal: function (object) { return object.toString(10); }, |
| hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); } |
| }, |
| defaultStyle: 'decimal', |
| styleAliases: { |
| binary: [ 2, 'bin' ], |
| octal: [ 8, 'oct' ], |
| decimal: [ 10, 'dec' ], |
| hexadecimal: [ 16, 'hex' ] |
| } |
| }); |
| |
| },{"../common":21,"../type":32}],37:[function(require,module,exports){ |
| 'use strict'; |
| |
| var esprima; |
| |
| // Browserified version does not have esprima |
| // |
| // 1. For node.js just require module as deps |
| // 2. For browser try to require mudule via external AMD system. |
| // If not found - try to fallback to window.esprima. If not |
| // found too - then fail to parse. |
| // |
| try { |
| // workaround to exclude package from browserify list. |
| var _require = require; |
| esprima = _require('esprima'); |
| } catch (_) { |
| /*global window */ |
| if (typeof window !== 'undefined') esprima = window.esprima; |
| } |
| |
| var Type = require('../../type'); |
| |
| function resolveJavascriptFunction(data) { |
| if (data === null) return false; |
| |
| try { |
| var source = '(' + data + ')', |
| ast = esprima.parse(source, { range: true }); |
| |
| if (ast.type !== 'Program' || |
| ast.body.length !== 1 || |
| ast.body[0].type !== 'ExpressionStatement' || |
| ast.body[0].expression.type !== 'FunctionExpression') { |
| return false; |
| } |
| |
| return true; |
| } catch (err) { |
| return false; |
| } |
| } |
| |
| function constructJavascriptFunction(data) { |
| /*jslint evil:true*/ |
| |
| var source = '(' + data + ')', |
| ast = esprima.parse(source, { range: true }), |
| params = [], |
| body; |
| |
| if (ast.type !== 'Program' || |
| ast.body.length !== 1 || |
| ast.body[0].type !== 'ExpressionStatement' || |
| ast.body[0].expression.type !== 'FunctionExpression') { |
| throw new Error('Failed to resolve function'); |
| } |
| |
| ast.body[0].expression.params.forEach(function (param) { |
| params.push(param.name); |
| }); |
| |
| body = ast.body[0].expression.body.range; |
| |
| // Esprima's ranges include the first '{' and the last '}' characters on |
| // function expressions. So cut them out. |
| /*eslint-disable no-new-func*/ |
| return new Function(params, source.slice(body[0] + 1, body[1] - 1)); |
| } |
| |
| function representJavascriptFunction(object /*, style*/) { |
| return object.toString(); |
| } |
| |
| function isFunction(object) { |
| return Object.prototype.toString.call(object) === '[object Function]'; |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:js/function', { |
| kind: 'scalar', |
| resolve: resolveJavascriptFunction, |
| construct: constructJavascriptFunction, |
| predicate: isFunction, |
| represent: representJavascriptFunction |
| }); |
| |
| },{"../../type":32}],38:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../../type'); |
| |
| function resolveJavascriptRegExp(data) { |
| if (data === null) return false; |
| if (data.length === 0) return false; |
| |
| var regexp = data, |
| tail = /\/([gim]*)$/.exec(data), |
| modifiers = ''; |
| |
| // if regexp starts with '/' it can have modifiers and must be properly closed |
| // `/foo/gim` - modifiers tail can be maximum 3 chars |
| if (regexp[0] === '/') { |
| if (tail) modifiers = tail[1]; |
| |
| if (modifiers.length > 3) return false; |
| // if expression starts with /, is should be properly terminated |
| if (regexp[regexp.length - modifiers.length - 1] !== '/') return false; |
| } |
| |
| return true; |
| } |
| |
| function constructJavascriptRegExp(data) { |
| var regexp = data, |
| tail = /\/([gim]*)$/.exec(data), |
| modifiers = ''; |
| |
| // `/foo/gim` - tail can be maximum 4 chars |
| if (regexp[0] === '/') { |
| if (tail) modifiers = tail[1]; |
| regexp = regexp.slice(1, regexp.length - modifiers.length - 1); |
| } |
| |
| return new RegExp(regexp, modifiers); |
| } |
| |
| function representJavascriptRegExp(object /*, style*/) { |
| var result = '/' + object.source + '/'; |
| |
| if (object.global) result += 'g'; |
| if (object.multiline) result += 'm'; |
| if (object.ignoreCase) result += 'i'; |
| |
| return result; |
| } |
| |
| function isRegExp(object) { |
| return Object.prototype.toString.call(object) === '[object RegExp]'; |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:js/regexp', { |
| kind: 'scalar', |
| resolve: resolveJavascriptRegExp, |
| construct: constructJavascriptRegExp, |
| predicate: isRegExp, |
| represent: representJavascriptRegExp |
| }); |
| |
| },{"../../type":32}],39:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../../type'); |
| |
| function resolveJavascriptUndefined() { |
| return true; |
| } |
| |
| function constructJavascriptUndefined() { |
| /*eslint-disable no-undefined*/ |
| return undefined; |
| } |
| |
| function representJavascriptUndefined() { |
| return ''; |
| } |
| |
| function isUndefined(object) { |
| return typeof object === 'undefined'; |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:js/undefined', { |
| kind: 'scalar', |
| resolve: resolveJavascriptUndefined, |
| construct: constructJavascriptUndefined, |
| predicate: isUndefined, |
| represent: representJavascriptUndefined |
| }); |
| |
| },{"../../type":32}],40:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../type'); |
| |
| module.exports = new Type('tag:yaml.org,2002:map', { |
| kind: 'mapping', |
| construct: function (data) { return data !== null ? data : {}; } |
| }); |
| |
| },{"../type":32}],41:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../type'); |
| |
| function resolveYamlMerge(data) { |
| return data === '<<' || data === null; |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:merge', { |
| kind: 'scalar', |
| resolve: resolveYamlMerge |
| }); |
| |
| },{"../type":32}],42:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../type'); |
| |
| function resolveYamlNull(data) { |
| if (data === null) return true; |
| |
| var max = data.length; |
| |
| return (max === 1 && data === '~') || |
| (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); |
| } |
| |
| function constructYamlNull() { |
| return null; |
| } |
| |
| function isNull(object) { |
| return object === null; |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:null', { |
| kind: 'scalar', |
| resolve: resolveYamlNull, |
| construct: constructYamlNull, |
| predicate: isNull, |
| represent: { |
| canonical: function () { return '~'; }, |
| lowercase: function () { return 'null'; }, |
| uppercase: function () { return 'NULL'; }, |
| camelcase: function () { return 'Null'; } |
| }, |
| defaultStyle: 'lowercase' |
| }); |
| |
| },{"../type":32}],43:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../type'); |
| |
| var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| var _toString = Object.prototype.toString; |
| |
| function resolveYamlOmap(data) { |
| if (data === null) return true; |
| |
| var objectKeys = [], index, length, pair, pairKey, pairHasKey, |
| object = data; |
| |
| for (index = 0, length = object.length; index < length; index += 1) { |
| pair = object[index]; |
| pairHasKey = false; |
| |
| if (_toString.call(pair) !== '[object Object]') return false; |
| |
| for (pairKey in pair) { |
| if (_hasOwnProperty.call(pair, pairKey)) { |
| if (!pairHasKey) pairHasKey = true; |
| else return false; |
| } |
| } |
| |
| if (!pairHasKey) return false; |
| |
| if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); |
| else return false; |
| } |
| |
| return true; |
| } |
| |
| function constructYamlOmap(data) { |
| return data !== null ? data : []; |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:omap', { |
| kind: 'sequence', |
| resolve: resolveYamlOmap, |
| construct: constructYamlOmap |
| }); |
| |
| },{"../type":32}],44:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../type'); |
| |
| var _toString = Object.prototype.toString; |
| |
| function resolveYamlPairs(data) { |
| if (data === null) return true; |
| |
| var index, length, pair, keys, result, |
| object = data; |
| |
| result = new Array(object.length); |
| |
| for (index = 0, length = object.length; index < length; index += 1) { |
| pair = object[index]; |
| |
| if (_toString.call(pair) !== '[object Object]') return false; |
| |
| keys = Object.keys(pair); |
| |
| if (keys.length !== 1) return false; |
| |
| result[index] = [ keys[0], pair[keys[0]] ]; |
| } |
| |
| return true; |
| } |
| |
| function constructYamlPairs(data) { |
| if (data === null) return []; |
| |
| var index, length, pair, keys, result, |
| object = data; |
| |
| result = new Array(object.length); |
| |
| for (index = 0, length = object.length; index < length; index += 1) { |
| pair = object[index]; |
| |
| keys = Object.keys(pair); |
| |
| result[index] = [ keys[0], pair[keys[0]] ]; |
| } |
| |
| return result; |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:pairs', { |
| kind: 'sequence', |
| resolve: resolveYamlPairs, |
| construct: constructYamlPairs |
| }); |
| |
| },{"../type":32}],45:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../type'); |
| |
| module.exports = new Type('tag:yaml.org,2002:seq', { |
| kind: 'sequence', |
| construct: function (data) { return data !== null ? data : []; } |
| }); |
| |
| },{"../type":32}],46:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../type'); |
| |
| var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| |
| function resolveYamlSet(data) { |
| if (data === null) return true; |
| |
| var key, object = data; |
| |
| for (key in object) { |
| if (_hasOwnProperty.call(object, key)) { |
| if (object[key] !== null) return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| function constructYamlSet(data) { |
| return data !== null ? data : {}; |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:set', { |
| kind: 'mapping', |
| resolve: resolveYamlSet, |
| construct: constructYamlSet |
| }); |
| |
| },{"../type":32}],47:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../type'); |
| |
| module.exports = new Type('tag:yaml.org,2002:str', { |
| kind: 'scalar', |
| construct: function (data) { return data !== null ? data : ''; } |
| }); |
| |
| },{"../type":32}],48:[function(require,module,exports){ |
| 'use strict'; |
| |
| var Type = require('../type'); |
| |
| var YAML_DATE_REGEXP = new RegExp( |
| '^([0-9][0-9][0-9][0-9])' + // [1] year |
| '-([0-9][0-9])' + // [2] month |
| '-([0-9][0-9])$'); // [3] day |
| |
| var YAML_TIMESTAMP_REGEXP = new RegExp( |
| '^([0-9][0-9][0-9][0-9])' + // [1] year |
| '-([0-9][0-9]?)' + // [2] month |
| '-([0-9][0-9]?)' + // [3] day |
| '(?:[Tt]|[ \\t]+)' + // ... |
| '([0-9][0-9]?)' + // [4] hour |
| ':([0-9][0-9])' + // [5] minute |
| ':([0-9][0-9])' + // [6] second |
| '(?:\\.([0-9]*))?' + // [7] fraction |
| '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour |
| '(?::([0-9][0-9]))?))?$'); // [11] tz_minute |
| |
| function resolveYamlTimestamp(data) { |
| if (data === null) return false; |
| if (YAML_DATE_REGEXP.exec(data) !== null) return true; |
| if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; |
| return false; |
| } |
| |
| function constructYamlTimestamp(data) { |
| var match, year, month, day, hour, minute, second, fraction = 0, |
| delta = null, tz_hour, tz_minute, date; |
| |
| match = YAML_DATE_REGEXP.exec(data); |
| if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); |
| |
| if (match === null) throw new Error('Date resolve error'); |
| |
| // match: [1] year [2] month [3] day |
| |
| year = +(match[1]); |
| month = +(match[2]) - 1; // JS month starts with 0 |
| day = +(match[3]); |
| |
| if (!match[4]) { // no hour |
| return new Date(Date.UTC(year, month, day)); |
| } |
| |
| // match: [4] hour [5] minute [6] second [7] fraction |
| |
| hour = +(match[4]); |
| minute = +(match[5]); |
| second = +(match[6]); |
| |
| if (match[7]) { |
| fraction = match[7].slice(0, 3); |
| while (fraction.length < 3) { // milli-seconds |
| fraction += '0'; |
| } |
| fraction = +fraction; |
| } |
| |
| // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute |
| |
| if (match[9]) { |
| tz_hour = +(match[10]); |
| tz_minute = +(match[11] || 0); |
| delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds |
| if (match[9] === '-') delta = -delta; |
| } |
| |
| date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); |
| |
| if (delta) date.setTime(date.getTime() - delta); |
| |
| return date; |
| } |
| |
| function representYamlTimestamp(object /*, style*/) { |
| return object.toISOString(); |
| } |
| |
| module.exports = new Type('tag:yaml.org,2002:timestamp', { |
| kind: 'scalar', |
| resolve: resolveYamlTimestamp, |
| construct: constructYamlTimestamp, |
| instanceOf: Date, |
| represent: representYamlTimestamp |
| }); |
| |
| },{"../type":32}],49:[function(require,module,exports){ |
| var baseIndexOf = require('../internal/baseIndexOf'), |
| binaryIndex = require('../internal/binaryIndex'); |
| |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeMax = Math.max; |
| |
| /** |
| * Gets the index at which the first occurrence of `value` is found in `array` |
| * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
| * for equality comparisons. If `fromIndex` is negative, it's used as the offset |
| * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` |
| * performs a faster binary search. |
| * |
| * @static |
| * @memberOf _ |
| * @category Array |
| * @param {Array} array The array to search. |
| * @param {*} value The value to search for. |
| * @param {boolean|number} [fromIndex=0] The index to search from or `true` |
| * to perform a binary search on a sorted array. |
| * @returns {number} Returns the index of the matched value, else `-1`. |
| * @example |
| * |
| * _.indexOf([1, 2, 1, 2], 2); |
| * // => 1 |
| * |
| * // using `fromIndex` |
| * _.indexOf([1, 2, 1, 2], 2, 2); |
| * // => 3 |
| * |
| * // performing a binary search |
| * _.indexOf([1, 1, 2, 2], 2, true); |
| * // => 2 |
| */ |
| function indexOf(array, value, fromIndex) { |
| var length = array ? array.length : 0; |
| if (!length) { |
| return -1; |
| } |
| if (typeof fromIndex == 'number') { |
| fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; |
| } else if (fromIndex) { |
| var index = binaryIndex(array, value); |
| if (index < length && |
| (value === value ? (value === array[index]) : (array[index] !== array[index]))) { |
| return index; |
| } |
| return -1; |
| } |
| return baseIndexOf(array, value, fromIndex || 0); |
| } |
| |
| module.exports = indexOf; |
| |
| },{"../internal/baseIndexOf":78,"../internal/binaryIndex":92}],50:[function(require,module,exports){ |
| /** |
| * Gets the last element of `array`. |
| * |
| * @static |
| * @memberOf _ |
| * @category Array |
| * @param {Array} array The array to query. |
| * @returns {*} Returns the last element of `array`. |
| * @example |
| * |
| * _.last([1, 2, 3]); |
| * // => 3 |
| */ |
| function last(array) { |
| var length = array ? array.length : 0; |
| return length ? array[length - 1] : undefined; |
| } |
| |
| module.exports = last; |
| |
| },{}],51:[function(require,module,exports){ |
| var LazyWrapper = require('../internal/LazyWrapper'), |
| LodashWrapper = require('../internal/LodashWrapper'), |
| baseLodash = require('../internal/baseLodash'), |
| isArray = require('../lang/isArray'), |
| isObjectLike = require('../internal/isObjectLike'), |
| wrapperClone = require('../internal/wrapperClone'); |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** Used to check objects for own properties. */ |
| var hasOwnProperty = objectProto.hasOwnProperty; |
| |
| /** |
| * Creates a `lodash` object which wraps `value` to enable implicit chaining. |
| * Methods that operate on and return arrays, collections, and functions can |
| * be chained together. Methods that retrieve a single value or may return a |
| * primitive value will automatically end the chain returning the unwrapped |
| * value. Explicit chaining may be enabled using `_.chain`. The execution of |
| * chained methods is lazy, that is, execution is deferred until `_#value` |
| * is implicitly or explicitly called. |
| * |
| * Lazy evaluation allows several methods to support shortcut fusion. Shortcut |
| * fusion is an optimization strategy which merge iteratee calls; this can help |
| * to avoid the creation of intermediate data structures and greatly reduce the |
| * number of iteratee executions. |
| * |
| * Chaining is supported in custom builds as long as the `_#value` method is |
| * directly or indirectly included in the build. |
| * |
| * In addition to lodash methods, wrappers have `Array` and `String` methods. |
| * |
| * The wrapper `Array` methods are: |
| * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, |
| * `splice`, and `unshift` |
| * |
| * The wrapper `String` methods are: |
| * `replace` and `split` |
| * |
| * The wrapper methods that support shortcut fusion are: |
| * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, |
| * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, |
| * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, |
| * and `where` |
| * |
| * The chainable wrapper methods are: |
| * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, |
| * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, |
| * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, |
| * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, |
| * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, |
| * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, |
| * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, |
| * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, |
| * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, |
| * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, |
| * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, |
| * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, |
| * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, |
| * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, |
| * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, |
| * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, |
| * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` |
| * |
| * The wrapper methods that are **not** chainable by default are: |
| * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, |
| * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, |
| * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, |
| * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, |
| * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, |
| * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, |
| * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, |
| * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, |
| * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, |
| * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, |
| * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, |
| * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, |
| * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, |
| * `unescape`, `uniqueId`, `value`, and `words` |
| * |
| * The wrapper method `sample` will return a wrapped value when `n` is provided, |
| * otherwise an unwrapped value is returned. |
| * |
| * @name _ |
| * @constructor |
| * @category Chain |
| * @param {*} value The value to wrap in a `lodash` instance. |
| * @returns {Object} Returns the new `lodash` wrapper instance. |
| * @example |
| * |
| * var wrapped = _([1, 2, 3]); |
| * |
| * // returns an unwrapped value |
| * wrapped.reduce(function(total, n) { |
| * return total + n; |
| * }); |
| * // => 6 |
| * |
| * // returns a wrapped value |
| * var squares = wrapped.map(function(n) { |
| * return n * n; |
| * }); |
| * |
| * _.isArray(squares); |
| * // => false |
| * |
| * _.isArray(squares.value()); |
| * // => true |
| */ |
| function lodash(value) { |
| if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { |
| if (value instanceof LodashWrapper) { |
| return value; |
| } |
| if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { |
| return wrapperClone(value); |
| } |
| } |
| return new LodashWrapper(value); |
| } |
| |
| // Ensure wrappers are instances of `baseLodash`. |
| lodash.prototype = baseLodash.prototype; |
| |
| module.exports = lodash; |
| |
| },{"../internal/LazyWrapper":60,"../internal/LodashWrapper":61,"../internal/baseLodash":82,"../internal/isObjectLike":126,"../internal/wrapperClone":137,"../lang/isArray":140}],52:[function(require,module,exports){ |
| module.exports = require('./forEach'); |
| |
| },{"./forEach":54}],53:[function(require,module,exports){ |
| var baseEach = require('../internal/baseEach'), |
| createFind = require('../internal/createFind'); |
| |
| /** |
| * Iterates over elements of `collection`, returning the first element |
| * `predicate` returns truthy for. The predicate is bound to `thisArg` and |
| * invoked with three arguments: (value, index|key, collection). |
| * |
| * If a property name is provided for `predicate` the created `_.property` |
| * style callback returns the property value of the given element. |
| * |
| * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| * style callback returns `true` for elements that have a matching property |
| * value, else `false`. |
| * |
| * If an object is provided for `predicate` the created `_.matches` style |
| * callback returns `true` for elements that have the properties of the given |
| * object, else `false`. |
| * |
| * @static |
| * @memberOf _ |
| * @alias detect |
| * @category Collection |
| * @param {Array|Object|string} collection The collection to search. |
| * @param {Function|Object|string} [predicate=_.identity] The function invoked |
| * per iteration. |
| * @param {*} [thisArg] The `this` binding of `predicate`. |
| * @returns {*} Returns the matched element, else `undefined`. |
| * @example |
| * |
| * var users = [ |
| * { 'user': 'barney', 'age': 36, 'active': true }, |
| * { 'user': 'fred', 'age': 40, 'active': false }, |
| * { 'user': 'pebbles', 'age': 1, 'active': true } |
| * ]; |
| * |
| * _.result(_.find(users, function(chr) { |
| * return chr.age < 40; |
| * }), 'user'); |
| * // => 'barney' |
| * |
| * // using the `_.matches` callback shorthand |
| * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); |
| * // => 'pebbles' |
| * |
| * // using the `_.matchesProperty` callback shorthand |
| * _.result(_.find(users, 'active', false), 'user'); |
| * // => 'fred' |
| * |
| * // using the `_.property` callback shorthand |
| * _.result(_.find(users, 'active'), 'user'); |
| * // => 'barney' |
| */ |
| var find = createFind(baseEach); |
| |
| module.exports = find; |
| |
| },{"../internal/baseEach":71,"../internal/createFind":102}],54:[function(require,module,exports){ |
| var arrayEach = require('../internal/arrayEach'), |
| baseEach = require('../internal/baseEach'), |
| createForEach = require('../internal/createForEach'); |
| |
| /** |
| * Iterates over elements of `collection` invoking `iteratee` for each element. |
| * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
| * (value, index|key, collection). Iteratee functions may exit iteration early |
| * by explicitly returning `false`. |
| * |
| * **Note:** As with other "Collections" methods, objects with a "length" property |
| * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` |
| * may be used for object iteration. |
| * |
| * @static |
| * @memberOf _ |
| * @alias each |
| * @category Collection |
| * @param {Array|Object|string} collection The collection to iterate over. |
| * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
| * @param {*} [thisArg] The `this` binding of `iteratee`. |
| * @returns {Array|Object|string} Returns `collection`. |
| * @example |
| * |
| * _([1, 2]).forEach(function(n) { |
| * console.log(n); |
| * }).value(); |
| * // => logs each value from left to right and returns the array |
| * |
| * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { |
| * console.log(n, key); |
| * }); |
| * // => logs each value-key pair and returns the object (iteration order is not guaranteed) |
| */ |
| var forEach = createForEach(arrayEach, baseEach); |
| |
| module.exports = forEach; |
| |
| },{"../internal/arrayEach":63,"../internal/baseEach":71,"../internal/createForEach":103}],55:[function(require,module,exports){ |
| var baseIndexOf = require('../internal/baseIndexOf'), |
| getLength = require('../internal/getLength'), |
| isArray = require('../lang/isArray'), |
| isIterateeCall = require('../internal/isIterateeCall'), |
| isLength = require('../internal/isLength'), |
| isString = require('../lang/isString'), |
| values = require('../object/values'); |
| |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeMax = Math.max; |
| |
| /** |
| * Checks if `target` is in `collection` using |
| * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
| * for equality comparisons. If `fromIndex` is negative, it's used as the offset |
| * from the end of `collection`. |
| * |
| * @static |
| * @memberOf _ |
| * @alias contains, include |
| * @category Collection |
| * @param {Array|Object|string} collection The collection to search. |
| * @param {*} target The value to search for. |
| * @param {number} [fromIndex=0] The index to search from. |
| * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. |
| * @returns {boolean} Returns `true` if a matching element is found, else `false`. |
| * @example |
| * |
| * _.includes([1, 2, 3], 1); |
| * // => true |
| * |
| * _.includes([1, 2, 3], 1, 2); |
| * // => false |
| * |
| * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); |
| * // => true |
| * |
| * _.includes('pebbles', 'eb'); |
| * // => true |
| */ |
| function includes(collection, target, fromIndex, guard) { |
| var length = collection ? getLength(collection) : 0; |
| if (!isLength(length)) { |
| collection = values(collection); |
| length = collection.length; |
| } |
| if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { |
| fromIndex = 0; |
| } else { |
| fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); |
| } |
| return (typeof collection == 'string' || !isArray(collection) && isString(collection)) |
| ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) |
| : (!!length && baseIndexOf(collection, target, fromIndex) > -1); |
| } |
| |
| module.exports = includes; |
| |
| },{"../internal/baseIndexOf":78,"../internal/getLength":112,"../internal/isIterateeCall":122,"../internal/isLength":125,"../lang/isArray":140,"../lang/isString":146,"../object/values":152}],56:[function(require,module,exports){ |
| var arrayMap = require('../internal/arrayMap'), |
| baseCallback = require('../internal/baseCallback'), |
| baseMap = require('../internal/baseMap'), |
| isArray = require('../lang/isArray'); |
| |
| /** |
| * Creates an array of values by running each element in `collection` through |
| * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three |
| * arguments: (value, index|key, collection). |
| * |
| * If a property name is provided for `iteratee` the created `_.property` |
| * style callback returns the property value of the given element. |
| * |
| * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| * style callback returns `true` for elements that have a matching property |
| * value, else `false`. |
| * |
| * If an object is provided for `iteratee` the created `_.matches` style |
| * callback returns `true` for elements that have the properties of the given |
| * object, else `false`. |
| * |
| * Many lodash methods are guarded to work as iteratees for methods like |
| * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. |
| * |
| * The guarded methods are: |
| * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, |
| * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, |
| * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, |
| * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, |
| * `sum`, `uniq`, and `words` |
| * |
| * @static |
| * @memberOf _ |
| * @alias collect |
| * @category Collection |
| * @param {Array|Object|string} collection The collection to iterate over. |
| * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
| * per iteration. |
| * @param {*} [thisArg] The `this` binding of `iteratee`. |
| * @returns {Array} Returns the new mapped array. |
| * @example |
| * |
| * function timesThree(n) { |
| * return n * 3; |
| * } |
| * |
| * _.map([1, 2], timesThree); |
| * // => [3, 6] |
| * |
| * _.map({ 'a': 1, 'b': 2 }, timesThree); |
| * // => [3, 6] (iteration order is not guaranteed) |
| * |
| * var users = [ |
| * { 'user': 'barney' }, |
| * { 'user': 'fred' } |
| * ]; |
| * |
| * // using the `_.property` callback shorthand |
| * _.map(users, 'user'); |
| * // => ['barney', 'fred'] |
| */ |
| function map(collection, iteratee, thisArg) { |
| var func = isArray(collection) ? arrayMap : baseMap; |
| iteratee = baseCallback(iteratee, thisArg, 3); |
| return func(collection, iteratee); |
| } |
| |
| module.exports = map; |
| |
| },{"../internal/arrayMap":64,"../internal/baseCallback":67,"../internal/baseMap":83,"../lang/isArray":140}],57:[function(require,module,exports){ |
| var getNative = require('../internal/getNative'); |
| |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeNow = getNative(Date, 'now'); |
| |
| /** |
| * Gets the number of milliseconds that have elapsed since the Unix epoch |
| * (1 January 1970 00:00:00 UTC). |
| * |
| * @static |
| * @memberOf _ |
| * @category Date |
| * @example |
| * |
| * _.defer(function(stamp) { |
| * console.log(_.now() - stamp); |
| * }, _.now()); |
| * // => logs the number of milliseconds it took for the deferred function to be invoked |
| */ |
| var now = nativeNow || function() { |
| return new Date().getTime(); |
| }; |
| |
| module.exports = now; |
| |
| },{"../internal/getNative":114}],58:[function(require,module,exports){ |
| var createWrapper = require('../internal/createWrapper'), |
| replaceHolders = require('../internal/replaceHolders'), |
| restParam = require('./restParam'); |
| |
| /** Used to compose bitmasks for wrapper metadata. */ |
| var BIND_FLAG = 1, |
| PARTIAL_FLAG = 32; |
| |
| /** |
| * Creates a function that invokes `func` with the `this` binding of `thisArg` |
| * and prepends any additional `_.bind` arguments to those provided to the |
| * bound function. |
| * |
| * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, |
| * may be used as a placeholder for partially applied arguments. |
| * |
| * **Note:** Unlike native `Function#bind` this method does not set the "length" |
| * property of bound functions. |
| * |
| * @static |
| * @memberOf _ |
| * @category Function |
| * @param {Function} func The function to bind. |
| * @param {*} thisArg The `this` binding of `func`. |
| * @param {...*} [partials] The arguments to be partially applied. |
| * @returns {Function} Returns the new bound function. |
| * @example |
| * |
| * var greet = function(greeting, punctuation) { |
| * return greeting + ' ' + this.user + punctuation; |
| * }; |
| * |
| * var object = { 'user': 'fred' }; |
| * |
| * var bound = _.bind(greet, object, 'hi'); |
| * bound('!'); |
| * // => 'hi fred!' |
| * |
| * // using placeholders |
| * var bound = _.bind(greet, object, _, '!'); |
| * bound('hi'); |
| * // => 'hi fred!' |
| */ |
| var bind = restParam(function(func, thisArg, partials) { |
| var bitmask = BIND_FLAG; |
| if (partials.length) { |
| var holders = replaceHolders(partials, bind.placeholder); |
| bitmask |= PARTIAL_FLAG; |
| } |
| return createWrapper(func, bitmask, thisArg, partials, holders); |
| }); |
| |
| // Assign default placeholders. |
| bind.placeholder = {}; |
| |
| module.exports = bind; |
| |
| },{"../internal/createWrapper":106,"../internal/replaceHolders":132,"./restParam":59}],59:[function(require,module,exports){ |
| /** Used as the `TypeError` message for "Functions" methods. */ |
| var FUNC_ERROR_TEXT = 'Expected a function'; |
| |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeMax = Math.max; |
| |
| /** |
| * Creates a function that invokes `func` with the `this` binding of the |
| * created function and arguments from `start` and beyond provided as an array. |
| * |
| * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters). |
| * |
| * @static |
| * @memberOf _ |
| * @category Function |
| * @param {Function} func The function to apply a rest parameter to. |
| * @param {number} [start=func.length-1] The start position of the rest parameter. |
| * @returns {Function} Returns the new function. |
| * @example |
| * |
| * var say = _.restParam(function(what, names) { |
| * return what + ' ' + _.initial(names).join(', ') + |
| * (_.size(names) > 1 ? ', & ' : '') + _.last(names); |
| * }); |
| * |
| * say('hello', 'fred', 'barney', 'pebbles'); |
| * // => 'hello fred, barney, & pebbles' |
| */ |
| function restParam(func, start) { |
| if (typeof func != 'function') { |
| throw new TypeError(FUNC_ERROR_TEXT); |
| } |
| start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); |
| return function() { |
| var args = arguments, |
| index = -1, |
| length = nativeMax(args.length - start, 0), |
| rest = Array(length); |
| |
| while (++index < length) { |
| rest[index] = args[start + index]; |
| } |
| switch (start) { |
| case 0: return func.call(this, rest); |
| case 1: return func.call(this, args[0], rest); |
| case 2: return func.call(this, args[0], args[1], rest); |
| } |
| var otherArgs = Array(start + 1); |
| index = -1; |
| while (++index < start) { |
| otherArgs[index] = args[index]; |
| } |
| otherArgs[start] = rest; |
| return func.apply(this, otherArgs); |
| }; |
| } |
| |
| module.exports = restParam; |
| |
| },{}],60:[function(require,module,exports){ |
| var baseCreate = require('./baseCreate'), |
| baseLodash = require('./baseLodash'); |
| |
| /** Used as references for `-Infinity` and `Infinity`. */ |
| var POSITIVE_INFINITY = Number.POSITIVE_INFINITY; |
| |
| /** |
| * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. |
| * |
| * @private |
| * @param {*} value The value to wrap. |
| */ |
| function LazyWrapper(value) { |
| this.__wrapped__ = value; |
| this.__actions__ = []; |
| this.__dir__ = 1; |
| this.__filtered__ = false; |
| this.__iteratees__ = []; |
| this.__takeCount__ = POSITIVE_INFINITY; |
| this.__views__ = []; |
| } |
| |
| LazyWrapper.prototype = baseCreate(baseLodash.prototype); |
| LazyWrapper.prototype.constructor = LazyWrapper; |
| |
| module.exports = LazyWrapper; |
| |
| },{"./baseCreate":70,"./baseLodash":82}],61:[function(require,module,exports){ |
| var baseCreate = require('./baseCreate'), |
| baseLodash = require('./baseLodash'); |
| |
| /** |
| * The base constructor for creating `lodash` wrapper objects. |
| * |
| * @private |
| * @param {*} value The value to wrap. |
| * @param {boolean} [chainAll] Enable chaining for all wrapper methods. |
| * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. |
| */ |
| function LodashWrapper(value, chainAll, actions) { |
| this.__wrapped__ = value; |
| this.__actions__ = actions || []; |
| this.__chain__ = !!chainAll; |
| } |
| |
| LodashWrapper.prototype = baseCreate(baseLodash.prototype); |
| LodashWrapper.prototype.constructor = LodashWrapper; |
| |
| module.exports = LodashWrapper; |
| |
| },{"./baseCreate":70,"./baseLodash":82}],62:[function(require,module,exports){ |
| /** |
| * Copies the values of `source` to `array`. |
| * |
| * @private |
| * @param {Array} source The array to copy values from. |
| * @param {Array} [array=[]] The array to copy values to. |
| * @returns {Array} Returns `array`. |
| */ |
| function arrayCopy(source, array) { |
| var index = -1, |
| length = source.length; |
| |
| array || (array = Array(length)); |
| while (++index < length) { |
| array[index] = source[index]; |
| } |
| return array; |
| } |
| |
| module.exports = arrayCopy; |
| |
| },{}],63:[function(require,module,exports){ |
| /** |
| * A specialized version of `_.forEach` for arrays without support for callback |
| * shorthands and `this` binding. |
| * |
| * @private |
| * @param {Array} array The array to iterate over. |
| * @param {Function} iteratee The function invoked per iteration. |
| * @returns {Array} Returns `array`. |
| */ |
| function arrayEach(array, iteratee) { |
| var index = -1, |
| length = array.length; |
| |
| while (++index < length) { |
| if (iteratee(array[index], index, array) === false) { |
| break; |
| } |
| } |
| return array; |
| } |
| |
| module.exports = arrayEach; |
| |
| },{}],64:[function(require,module,exports){ |
| /** |
| * A specialized version of `_.map` for arrays without support for callback |
| * shorthands and `this` binding. |
| * |
| * @private |
| * @param {Array} array The array to iterate over. |
| * @param {Function} iteratee The function invoked per iteration. |
| * @returns {Array} Returns the new mapped array. |
| */ |
| function arrayMap(array, iteratee) { |
| var index = -1, |
| length = array.length, |
| result = Array(length); |
| |
| while (++index < length) { |
| result[index] = iteratee(array[index], index, array); |
| } |
| return result; |
| } |
| |
| module.exports = arrayMap; |
| |
| },{}],65:[function(require,module,exports){ |
| /** |
| * A specialized version of `_.some` for arrays without support for callback |
| * shorthands and `this` binding. |
| * |
| * @private |
| * @param {Array} array The array to iterate over. |
| * @param {Function} predicate The function invoked per iteration. |
| * @returns {boolean} Returns `true` if any element passes the predicate check, |
| * else `false`. |
| */ |
| function arraySome(array, predicate) { |
| var index = -1, |
| length = array.length; |
| |
| while (++index < length) { |
| if (predicate(array[index], index, array)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| module.exports = arraySome; |
| |
| },{}],66:[function(require,module,exports){ |
| var baseCopy = require('./baseCopy'), |
| keys = require('../object/keys'); |
| |
| /** |
| * The base implementation of `_.assign` without support for argument juggling, |
| * multiple sources, and `customizer` functions. |
| * |
| * @private |
| * @param {Object} object The destination object. |
| * @param {Object} source The source object. |
| * @returns {Object} Returns `object`. |
| */ |
| function baseAssign(object, source) { |
| return source == null |
| ? object |
| : baseCopy(source, keys(source), object); |
| } |
| |
| module.exports = baseAssign; |
| |
| },{"../object/keys":149,"./baseCopy":69}],67:[function(require,module,exports){ |
| var baseMatches = require('./baseMatches'), |
| baseMatchesProperty = require('./baseMatchesProperty'), |
| bindCallback = require('./bindCallback'), |
| identity = require('../utility/identity'), |
| property = require('../utility/property'); |
| |
| /** |
| * The base implementation of `_.callback` which supports specifying the |
| * number of arguments to provide to `func`. |
| * |
| * @private |
| * @param {*} [func=_.identity] The value to convert to a callback. |
| * @param {*} [thisArg] The `this` binding of `func`. |
| * @param {number} [argCount] The number of arguments to provide to `func`. |
| * @returns {Function} Returns the callback. |
| */ |
| function baseCallback(func, thisArg, argCount) { |
| var type = typeof func; |
| if (type == 'function') { |
| return thisArg === undefined |
| ? func |
| : bindCallback(func, thisArg, argCount); |
| } |
| if (func == null) { |
| return identity; |
| } |
| if (type == 'object') { |
| return baseMatches(func); |
| } |
| return thisArg === undefined |
| ? property(func) |
| : baseMatchesProperty(func, thisArg); |
| } |
| |
| module.exports = baseCallback; |
| |
| },{"../utility/identity":154,"../utility/property":156,"./baseMatches":84,"./baseMatchesProperty":85,"./bindCallback":94}],68:[function(require,module,exports){ |
| var arrayCopy = require('./arrayCopy'), |
| arrayEach = require('./arrayEach'), |
| baseAssign = require('./baseAssign'), |
| baseForOwn = require('./baseForOwn'), |
| initCloneArray = require('./initCloneArray'), |
| initCloneByTag = require('./initCloneByTag'), |
| initCloneObject = require('./initCloneObject'), |
| isArray = require('../lang/isArray'), |
| isHostObject = require('./isHostObject'), |
| isObject = require('../lang/isObject'); |
| |
| /** `Object#toString` result references. */ |
| var argsTag = '[object Arguments]', |
| arrayTag = '[object Array]', |
| boolTag = '[object Boolean]', |
| dateTag = '[object Date]', |
| errorTag = '[object Error]', |
| funcTag = '[object Function]', |
| mapTag = '[object Map]', |
| numberTag = '[object Number]', |
| objectTag = '[object Object]', |
| regexpTag = '[object RegExp]', |
| setTag = '[object Set]', |
| stringTag = '[object String]', |
| weakMapTag = '[object WeakMap]'; |
| |
| var arrayBufferTag = '[object ArrayBuffer]', |
| float32Tag = '[object Float32Array]', |
| float64Tag = '[object Float64Array]', |
| int8Tag = '[object Int8Array]', |
| int16Tag = '[object Int16Array]', |
| int32Tag = '[object Int32Array]', |
| uint8Tag = '[object Uint8Array]', |
| uint8ClampedTag = '[object Uint8ClampedArray]', |
| uint16Tag = '[object Uint16Array]', |
| uint32Tag = '[object Uint32Array]'; |
| |
| /** Used to identify `toStringTag` values supported by `_.clone`. */ |
| var cloneableTags = {}; |
| cloneableTags[argsTag] = cloneableTags[arrayTag] = |
| cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = |
| cloneableTags[dateTag] = cloneableTags[float32Tag] = |
| cloneableTags[float64Tag] = cloneableTags[int8Tag] = |
| cloneableTags[int16Tag] = cloneableTags[int32Tag] = |
| cloneableTags[numberTag] = cloneableTags[objectTag] = |
| cloneableTags[regexpTag] = cloneableTags[stringTag] = |
| cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = |
| cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; |
| cloneableTags[errorTag] = cloneableTags[funcTag] = |
| cloneableTags[mapTag] = cloneableTags[setTag] = |
| cloneableTags[weakMapTag] = false; |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** |
| * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
| * of values. |
| */ |
| var objToString = objectProto.toString; |
| |
| /** |
| * The base implementation of `_.clone` without support for argument juggling |
| * and `this` binding `customizer` functions. |
| * |
| * @private |
| * @param {*} value The value to clone. |
| * @param {boolean} [isDeep] Specify a deep clone. |
| * @param {Function} [customizer] The function to customize cloning values. |
| * @param {string} [key] The key of `value`. |
| * @param {Object} [object] The object `value` belongs to. |
| * @param {Array} [stackA=[]] Tracks traversed source objects. |
| * @param {Array} [stackB=[]] Associates clones with source counterparts. |
| * @returns {*} Returns the cloned value. |
| */ |
| function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { |
| var result; |
| if (customizer) { |
| result = object ? customizer(value, key, object) : customizer(value); |
| } |
| if (result !== undefined) { |
| return result; |
| } |
| if (!isObject(value)) { |
| return value; |
| } |
| var isArr = isArray(value); |
| if (isArr) { |
| result = initCloneArray(value); |
| if (!isDeep) { |
| return arrayCopy(value, result); |
| } |
| } else { |
| var tag = objToString.call(value), |
| isFunc = tag == funcTag; |
| |
| if (tag == objectTag || tag == argsTag || (isFunc && !object)) { |
| if (isHostObject(value)) { |
| return object ? value : {}; |
| } |
| result = initCloneObject(isFunc ? {} : value); |
| if (!isDeep) { |
| return baseAssign(result, value); |
| } |
| } else { |
| return cloneableTags[tag] |
| ? initCloneByTag(value, tag, isDeep) |
| : (object ? value : {}); |
| } |
| } |
| // Check for circular references and return its corresponding clone. |
| stackA || (stackA = []); |
| stackB || (stackB = []); |
| |
| var length = stackA.length; |
| while (length--) { |
| if (stackA[length] == value) { |
| return stackB[length]; |
| } |
| } |
| // Add the source value to the stack of traversed objects and associate it with its clone. |
| stackA.push(value); |
| stackB.push(result); |
| |
| // Recursively populate clone (susceptible to call stack limits). |
| (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { |
| result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); |
| }); |
| return result; |
| } |
| |
| module.exports = baseClone; |
| |
| },{"../lang/isArray":140,"../lang/isObject":144,"./arrayCopy":62,"./arrayEach":63,"./baseAssign":66,"./baseForOwn":76,"./initCloneArray":116,"./initCloneByTag":117,"./initCloneObject":118,"./isHostObject":120}],69:[function(require,module,exports){ |
| /** |
| * Copies properties of `source` to `object`. |
| * |
| * @private |
| * @param {Object} source The object to copy properties from. |
| * @param {Array} props The property names to copy. |
| * @param {Object} [object={}] The object to copy properties to. |
| * @returns {Object} Returns `object`. |
| */ |
| function baseCopy(source, props, object) { |
| object || (object = {}); |
| |
| var index = -1, |
| length = props.length; |
| |
| while (++index < length) { |
| var key = props[index]; |
| object[key] = source[key]; |
| } |
| return object; |
| } |
| |
| module.exports = baseCopy; |
| |
| },{}],70:[function(require,module,exports){ |
| var isObject = require('../lang/isObject'); |
| |
| /** |
| * The base implementation of `_.create` without support for assigning |
| * properties to the created object. |
| * |
| * @private |
| * @param {Object} prototype The object to inherit from. |
| * @returns {Object} Returns the new object. |
| */ |
| var baseCreate = (function() { |
| function object() {} |
| return function(prototype) { |
| if (isObject(prototype)) { |
| object.prototype = prototype; |
| var result = new object; |
| object.prototype = undefined; |
| } |
| return result || {}; |
| }; |
| }()); |
| |
| module.exports = baseCreate; |
| |
| },{"../lang/isObject":144}],71:[function(require,module,exports){ |
| var baseForOwn = require('./baseForOwn'), |
| createBaseEach = require('./createBaseEach'); |
| |
| /** |
| * The base implementation of `_.forEach` without support for callback |
| * shorthands and `this` binding. |
| * |
| * @private |
| * @param {Array|Object|string} collection The collection to iterate over. |
| * @param {Function} iteratee The function invoked per iteration. |
| * @returns {Array|Object|string} Returns `collection`. |
| */ |
| var baseEach = createBaseEach(baseForOwn); |
| |
| module.exports = baseEach; |
| |
| },{"./baseForOwn":76,"./createBaseEach":98}],72:[function(require,module,exports){ |
| /** |
| * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, |
| * without support for callback shorthands and `this` binding, which iterates |
| * over `collection` using the provided `eachFunc`. |
| * |
| * @private |
| * @param {Array|Object|string} collection The collection to search. |
| * @param {Function} predicate The function invoked per iteration. |
| * @param {Function} eachFunc The function to iterate over `collection`. |
| * @param {boolean} [retKey] Specify returning the key of the found element |
| * instead of the element itself. |
| * @returns {*} Returns the found element or its key, else `undefined`. |
| */ |
| function baseFind(collection, predicate, eachFunc, retKey) { |
| var result; |
| eachFunc(collection, function(value, key, collection) { |
| if (predicate(value, key, collection)) { |
| result = retKey ? key : value; |
| return false; |
| } |
| }); |
| return result; |
| } |
| |
| module.exports = baseFind; |
| |
| },{}],73:[function(require,module,exports){ |
| /** |
| * The base implementation of `_.findIndex` and `_.findLastIndex` without |
| * support for callback shorthands and `this` binding. |
| * |
| * @private |
| * @param {Array} array The array to search. |
| * @param {Function} predicate The function invoked per iteration. |
| * @param {boolean} [fromRight] Specify iterating from right to left. |
| * @returns {number} Returns the index of the matched value, else `-1`. |
| */ |
| function baseFindIndex(array, predicate, fromRight) { |
| var length = array.length, |
| index = fromRight ? length : -1; |
| |
| while ((fromRight ? index-- : ++index < length)) { |
| if (predicate(array[index], index, array)) { |
| return index; |
| } |
| } |
| return -1; |
| } |
| |
| module.exports = baseFindIndex; |
| |
| },{}],74:[function(require,module,exports){ |
| var createBaseFor = require('./createBaseFor'); |
| |
| /** |
| * The base implementation of `baseForIn` and `baseForOwn` which iterates |
| * over `object` properties returned by `keysFunc` invoking `iteratee` for |
| * each property. Iteratee functions may exit iteration early by explicitly |
| * returning `false`. |
| * |
| * @private |
| * @param {Object} object The object to iterate over. |
| * @param {Function} iteratee The function invoked per iteration. |
| * @param {Function} keysFunc The function to get the keys of `object`. |
| * @returns {Object} Returns `object`. |
| */ |
| var baseFor = createBaseFor(); |
| |
| module.exports = baseFor; |
| |
| },{"./createBaseFor":99}],75:[function(require,module,exports){ |
| var baseFor = require('./baseFor'), |
| keysIn = require('../object/keysIn'); |
| |
| /** |
| * The base implementation of `_.forIn` without support for callback |
| * shorthands and `this` binding. |
| * |
| * @private |
| * @param {Object} object The object to iterate over. |
| * @param {Function} iteratee The function invoked per iteration. |
| * @returns {Object} Returns `object`. |
| */ |
| function baseForIn(object, iteratee) { |
| return baseFor(object, iteratee, keysIn); |
| } |
| |
| module.exports = baseForIn; |
| |
| },{"../object/keysIn":150,"./baseFor":74}],76:[function(require,module,exports){ |
| var baseFor = require('./baseFor'), |
| keys = require('../object/keys'); |
| |
| /** |
| * The base implementation of `_.forOwn` without support for callback |
| * shorthands and `this` binding. |
| * |
| * @private |
| * @param {Object} object The object to iterate over. |
| * @param {Function} iteratee The function invoked per iteration. |
| * @returns {Object} Returns `object`. |
| */ |
| function baseForOwn(object, iteratee) { |
| return baseFor(object, iteratee, keys); |
| } |
| |
| module.exports = baseForOwn; |
| |
| },{"../object/keys":149,"./baseFor":74}],77:[function(require,module,exports){ |
| var toObject = require('./toObject'); |
| |
| /** |
| * The base implementation of `get` without support for string paths |
| * and default values. |
| * |
| * @private |
| * @param {Object} object The object to query. |
| * @param {Array} path The path of the property to get. |
| * @param {string} [pathKey] The key representation of path. |
| * @returns {*} Returns the resolved value. |
| */ |
| function baseGet(object, path, pathKey) { |
| if (object == null) { |
| return; |
| } |
| object = toObject(object); |
| if (pathKey !== undefined && pathKey in object) { |
| path = [pathKey]; |
| } |
| var index = 0, |
| length = path.length; |
| |
| while (object != null && index < length) { |
| object = toObject(object)[path[index++]]; |
| } |
| return (index && index == length) ? object : undefined; |
| } |
| |
| module.exports = baseGet; |
| |
| },{"./toObject":135}],78:[function(require,module,exports){ |
| var indexOfNaN = require('./indexOfNaN'); |
| |
| /** |
| * The base implementation of `_.indexOf` without support for binary searches. |
| * |
| * @private |
| * @param {Array} array The array to search. |
| * @param {*} value The value to search for. |
| * @param {number} fromIndex The index to search from. |
| * @returns {number} Returns the index of the matched value, else `-1`. |
| */ |
| function baseIndexOf(array, value, fromIndex) { |
| if (value !== value) { |
| return indexOfNaN(array, fromIndex); |
| } |
| var index = fromIndex - 1, |
| length = array.length; |
| |
| while (++index < length) { |
| if (array[index] === value) { |
| return index; |
| } |
| } |
| return -1; |
| } |
| |
| module.exports = baseIndexOf; |
| |
| },{"./indexOfNaN":115}],79:[function(require,module,exports){ |
| var baseIsEqualDeep = require('./baseIsEqualDeep'), |
| isObject = require('../lang/isObject'), |
| isObjectLike = require('./isObjectLike'); |
| |
| /** |
| * The base implementation of `_.isEqual` without support for `this` binding |
| * `customizer` functions. |
| * |
| * @private |
| * @param {*} value The value to compare. |
| * @param {*} other The other value to compare. |
| * @param {Function} [customizer] The function to customize comparing values. |
| * @param {boolean} [isLoose] Specify performing partial comparisons. |
| * @param {Array} [stackA] Tracks traversed `value` objects. |
| * @param {Array} [stackB] Tracks traversed `other` objects. |
| * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
| */ |
| function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { |
| if (value === other) { |
| return true; |
| } |
| if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { |
| return value !== value && other !== other; |
| } |
| return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); |
| } |
| |
| module.exports = baseIsEqual; |
| |
| },{"../lang/isObject":144,"./baseIsEqualDeep":80,"./isObjectLike":126}],80:[function(require,module,exports){ |
| var equalArrays = require('./equalArrays'), |
| equalByTag = require('./equalByTag'), |
| equalObjects = require('./equalObjects'), |
| isArray = require('../lang/isArray'), |
| isHostObject = require('./isHostObject'), |
| isTypedArray = require('../lang/isTypedArray'); |
| |
| /** `Object#toString` result references. */ |
| var argsTag = '[object Arguments]', |
| arrayTag = '[object Array]', |
| objectTag = '[object Object]'; |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** Used to check objects for own properties. */ |
| var hasOwnProperty = objectProto.hasOwnProperty; |
| |
| /** |
| * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
| * of values. |
| */ |
| var objToString = objectProto.toString; |
| |
| /** |
| * A specialized version of `baseIsEqual` for arrays and objects which performs |
| * deep comparisons and tracks traversed objects enabling objects with circular |
| * references to be compared. |
| * |
| * @private |
| * @param {Object} object The object to compare. |
| * @param {Object} other The other object to compare. |
| * @param {Function} equalFunc The function to determine equivalents of values. |
| * @param {Function} [customizer] The function to customize comparing objects. |
| * @param {boolean} [isLoose] Specify performing partial comparisons. |
| * @param {Array} [stackA=[]] Tracks traversed `value` objects. |
| * @param {Array} [stackB=[]] Tracks traversed `other` objects. |
| * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
| */ |
| function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { |
| var objIsArr = isArray(object), |
| othIsArr = isArray(other), |
| objTag = arrayTag, |
| othTag = arrayTag; |
| |
| if (!objIsArr) { |
| objTag = objToString.call(object); |
| if (objTag == argsTag) { |
| objTag = objectTag; |
| } else if (objTag != objectTag) { |
| objIsArr = isTypedArray(object); |
| } |
| } |
| if (!othIsArr) { |
| othTag = objToString.call(other); |
| if (othTag == argsTag) { |
| othTag = objectTag; |
| } else if (othTag != objectTag) { |
| othIsArr = isTypedArray(other); |
| } |
| } |
| var objIsObj = objTag == objectTag && !isHostObject(object), |
| othIsObj = othTag == objectTag && !isHostObject(other), |
| isSameTag = objTag == othTag; |
| |
| if (isSameTag && !(objIsArr || objIsObj)) { |
| return equalByTag(object, other, objTag); |
| } |
| if (!isLoose) { |
| var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), |
| othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); |
| |
| if (objIsWrapped || othIsWrapped) { |
| return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); |
| } |
| } |
| if (!isSameTag) { |
| return false; |
| } |
| // Assume cyclic values are equal. |
| // For more information on detecting circular references see https://es5.github.io/#JO. |
| stackA || (stackA = []); |
| stackB || (stackB = []); |
| |
| var length = stackA.length; |
| while (length--) { |
| if (stackA[length] == object) { |
| return stackB[length] == other; |
| } |
| } |
| // Add `object` and `other` to the stack of traversed objects. |
| stackA.push(object); |
| stackB.push(other); |
| |
| var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); |
| |
| stackA.pop(); |
| stackB.pop(); |
| |
| return result; |
| } |
| |
| module.exports = baseIsEqualDeep; |
| |
| },{"../lang/isArray":140,"../lang/isTypedArray":147,"./equalArrays":107,"./equalByTag":108,"./equalObjects":109,"./isHostObject":120}],81:[function(require,module,exports){ |
| var baseIsEqual = require('./baseIsEqual'), |
| toObject = require('./toObject'); |
| |
| /** |
| * The base implementation of `_.isMatch` without support for callback |
| * shorthands and `this` binding. |
| * |
| * @private |
| * @param {Object} object The object to inspect. |
| * @param {Array} matchData The propery names, values, and compare flags to match. |
| * @param {Function} [customizer] The function to customize comparing objects. |
| * @returns {boolean} Returns `true` if `object` is a match, else `false`. |
| */ |
| function baseIsMatch(object, matchData, customizer) { |
| var index = matchData.length, |
| length = index, |
| noCustomizer = !customizer; |
| |
| if (object == null) { |
| return !length; |
| } |
| object = toObject(object); |
| while (index--) { |
| var data = matchData[index]; |
| if ((noCustomizer && data[2]) |
| ? data[1] !== object[data[0]] |
| : !(data[0] in object) |
| ) { |
| return false; |
| } |
| } |
| while (++index < length) { |
| data = matchData[index]; |
| var key = data[0], |
| objValue = object[key], |
| srcValue = data[1]; |
| |
| if (noCustomizer && data[2]) { |
| if (objValue === undefined && !(key in object)) { |
| return false; |
| } |
| } else { |
| var result = customizer ? customizer(objValue, srcValue, key) : undefined; |
| if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| |
| module.exports = baseIsMatch; |
| |
| },{"./baseIsEqual":79,"./toObject":135}],82:[function(require,module,exports){ |
| /** |
| * The function whose prototype all chaining wrappers inherit from. |
| * |
| * @private |
| */ |
| function baseLodash() { |
| // No operation performed. |
| } |
| |
| module.exports = baseLodash; |
| |
| },{}],83:[function(require,module,exports){ |
| var baseEach = require('./baseEach'), |
| isArrayLike = require('./isArrayLike'); |
| |
| /** |
| * The base implementation of `_.map` without support for callback shorthands |
| * and `this` binding. |
| * |
| * @private |
| * @param {Array|Object|string} collection The collection to iterate over. |
| * @param {Function} iteratee The function invoked per iteration. |
| * @returns {Array} Returns the new mapped array. |
| */ |
| function baseMap(collection, iteratee) { |
| var index = -1, |
| result = isArrayLike(collection) ? Array(collection.length) : []; |
| |
| baseEach(collection, function(value, key, collection) { |
| result[++index] = iteratee(value, key, collection); |
| }); |
| return result; |
| } |
| |
| module.exports = baseMap; |
| |
| },{"./baseEach":71,"./isArrayLike":119}],84:[function(require,module,exports){ |
| var baseIsMatch = require('./baseIsMatch'), |
| getMatchData = require('./getMatchData'), |
| toObject = require('./toObject'); |
| |
| /** |
| * The base implementation of `_.matches` which does not clone `source`. |
| * |
| * @private |
| * @param {Object} source The object of property values to match. |
| * @returns {Function} Returns the new function. |
| */ |
| function baseMatches(source) { |
| var matchData = getMatchData(source); |
| if (matchData.length == 1 && matchData[0][2]) { |
| var key = matchData[0][0], |
| value = matchData[0][1]; |
| |
| return function(object) { |
| if (object == null) { |
| return false; |
| } |
| object = toObject(object); |
| return object[key] === value && (value !== undefined || (key in object)); |
| }; |
| } |
| return function(object) { |
| return baseIsMatch(object, matchData); |
| }; |
| } |
| |
| module.exports = baseMatches; |
| |
| },{"./baseIsMatch":81,"./getMatchData":113,"./toObject":135}],85:[function(require,module,exports){ |
| var baseGet = require('./baseGet'), |
| baseIsEqual = require('./baseIsEqual'), |
| baseSlice = require('./baseSlice'), |
| isArray = require('../lang/isArray'), |
| isKey = require('./isKey'), |
| isStrictComparable = require('./isStrictComparable'), |
| last = require('../array/last'), |
| toObject = require('./toObject'), |
| toPath = require('./toPath'); |
| |
| /** |
| * The base implementation of `_.matchesProperty` which does not clone `srcValue`. |
| * |
| * @private |
| * @param {string} path The path of the property to get. |
| * @param {*} srcValue The value to compare. |
| * @returns {Function} Returns the new function. |
| */ |
| function baseMatchesProperty(path, srcValue) { |
| var isArr = isArray(path), |
| isCommon = isKey(path) && isStrictComparable(srcValue), |
| pathKey = (path + ''); |
| |
| path = toPath(path); |
| return function(object) { |
| if (object == null) { |
| return false; |
| } |
| var key = pathKey; |
| object = toObject(object); |
| if ((isArr || !isCommon) && !(key in object)) { |
| object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
| if (object == null) { |
| return false; |
| } |
| key = last(path); |
| object = toObject(object); |
| } |
| return object[key] === srcValue |
| ? (srcValue !== undefined || (key in object)) |
| : baseIsEqual(srcValue, object[key], undefined, true); |
| }; |
| } |
| |
| module.exports = baseMatchesProperty; |
| |
| },{"../array/last":50,"../lang/isArray":140,"./baseGet":77,"./baseIsEqual":79,"./baseSlice":89,"./isKey":123,"./isStrictComparable":127,"./toObject":135,"./toPath":136}],86:[function(require,module,exports){ |
| var toObject = require('./toObject'); |
| |
| /** |
| * The base implementation of `_.property` without support for deep paths. |
| * |
| * @private |
| * @param {string} key The key of the property to get. |
| * @returns {Function} Returns the new function. |
| */ |
| function baseProperty(key) { |
| return function(object) { |
| return object == null ? undefined : toObject(object)[key]; |
| }; |
| } |
| |
| module.exports = baseProperty; |
| |
| },{"./toObject":135}],87:[function(require,module,exports){ |
| var baseGet = require('./baseGet'), |
| toPath = require('./toPath'); |
| |
| /** |
| * A specialized version of `baseProperty` which supports deep paths. |
| * |
| * @private |
| * @param {Array|string} path The path of the property to get. |
| * @returns {Function} Returns the new function. |
| */ |
| function basePropertyDeep(path) { |
| var pathKey = (path + ''); |
| path = toPath(path); |
| return function(object) { |
| return baseGet(object, path, pathKey); |
| }; |
| } |
| |
| module.exports = basePropertyDeep; |
| |
| },{"./baseGet":77,"./toPath":136}],88:[function(require,module,exports){ |
| var identity = require('../utility/identity'), |
| metaMap = require('./metaMap'); |
| |
| /** |
| * The base implementation of `setData` without support for hot loop detection. |
| * |
| * @private |
| * @param {Function} func The function to associate metadata with. |
| * @param {*} data The metadata. |
| * @returns {Function} Returns `func`. |
| */ |
| var baseSetData = !metaMap ? identity : function(func, data) { |
| metaMap.set(func, data); |
| return func; |
| }; |
| |
| module.exports = baseSetData; |
| |
| },{"../utility/identity":154,"./metaMap":129}],89:[function(require,module,exports){ |
| /** |
| * The base implementation of `_.slice` without an iteratee call guard. |
| * |
| * @private |
| * @param {Array} array The array to slice. |
| * @param {number} [start=0] The start position. |
| * @param {number} [end=array.length] The end position. |
| * @returns {Array} Returns the slice of `array`. |
| */ |
| function baseSlice(array, start, end) { |
| var index = -1, |
| length = array.length; |
| |
| start = start == null ? 0 : (+start || 0); |
| if (start < 0) { |
| start = -start > length ? 0 : (length + start); |
| } |
| end = (end === undefined || end > length) ? length : (+end || 0); |
| if (end < 0) { |
| end += length; |
| } |
| length = start > end ? 0 : ((end - start) >>> 0); |
| start >>>= 0; |
| |
| var result = Array(length); |
| while (++index < length) { |
| result[index] = array[index + start]; |
| } |
| return result; |
| } |
| |
| module.exports = baseSlice; |
| |
| },{}],90:[function(require,module,exports){ |
| /** |
| * Converts `value` to a string if it's not one. An empty string is returned |
| * for `null` or `undefined` values. |
| * |
| * @private |
| * @param {*} value The value to process. |
| * @returns {string} Returns the string. |
| */ |
| function baseToString(value) { |
| return value == null ? '' : (value + ''); |
| } |
| |
| module.exports = baseToString; |
| |
| },{}],91:[function(require,module,exports){ |
| /** |
| * The base implementation of `_.values` and `_.valuesIn` which creates an |
| * array of `object` property values corresponding to the property names |
| * of `props`. |
| * |
| * @private |
| * @param {Object} object The object to query. |
| * @param {Array} props The property names to get values for. |
| * @returns {Object} Returns the array of property values. |
| */ |
| function baseValues(object, props) { |
| var index = -1, |
| length = props.length, |
| result = Array(length); |
| |
| while (++index < length) { |
| result[index] = object[props[index]]; |
| } |
| return result; |
| } |
| |
| module.exports = baseValues; |
| |
| },{}],92:[function(require,module,exports){ |
| var binaryIndexBy = require('./binaryIndexBy'), |
| identity = require('../utility/identity'); |
| |
| /** Used as references for the maximum length and index of an array. */ |
| var MAX_ARRAY_LENGTH = 4294967295, |
| HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; |
| |
| /** |
| * Performs a binary search of `array` to determine the index at which `value` |
| * should be inserted into `array` in order to maintain its sort order. |
| * |
| * @private |
| * @param {Array} array The sorted array to inspect. |
| * @param {*} value The value to evaluate. |
| * @param {boolean} [retHighest] Specify returning the highest qualified index. |
| * @returns {number} Returns the index at which `value` should be inserted |
| * into `array`. |
| */ |
| function binaryIndex(array, value, retHighest) { |
| var low = 0, |
| high = array ? array.length : low; |
| |
| if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { |
| while (low < high) { |
| var mid = (low + high) >>> 1, |
| computed = array[mid]; |
| |
| if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { |
| low = mid + 1; |
| } else { |
| high = mid; |
| } |
| } |
| return high; |
| } |
| return binaryIndexBy(array, value, identity, retHighest); |
| } |
| |
| module.exports = binaryIndex; |
| |
| },{"../utility/identity":154,"./binaryIndexBy":93}],93:[function(require,module,exports){ |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeFloor = Math.floor, |
| nativeMin = Math.min; |
| |
| /** Used as references for the maximum length and index of an array. */ |
| var MAX_ARRAY_LENGTH = 4294967295, |
| MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; |
| |
| /** |
| * This function is like `binaryIndex` except that it invokes `iteratee` for |
| * `value` and each element of `array` to compute their sort ranking. The |
| * iteratee is invoked with one argument; (value). |
| * |
| * @private |
| * @param {Array} array The sorted array to inspect. |
| * @param {*} value The value to evaluate. |
| * @param {Function} iteratee The function invoked per iteration. |
| * @param {boolean} [retHighest] Specify returning the highest qualified index. |
| * @returns {number} Returns the index at which `value` should be inserted |
| * into `array`. |
| */ |
| function binaryIndexBy(array, value, iteratee, retHighest) { |
| value = iteratee(value); |
| |
| var low = 0, |
| high = array ? array.length : 0, |
| valIsNaN = value !== value, |
| valIsNull = value === null, |
| valIsUndef = value === undefined; |
| |
| while (low < high) { |
| var mid = nativeFloor((low + high) / 2), |
| computed = iteratee(array[mid]), |
| isDef = computed !== undefined, |
| isReflexive = computed === computed; |
| |
| if (valIsNaN) { |
| var setLow = isReflexive || retHighest; |
| } else if (valIsNull) { |
| setLow = isReflexive && isDef && (retHighest || computed != null); |
| } else if (valIsUndef) { |
| setLow = isReflexive && (retHighest || isDef); |
| } else if (computed == null) { |
| setLow = false; |
| } else { |
| setLow = retHighest ? (computed <= value) : (computed < value); |
| } |
| if (setLow) { |
| low = mid + 1; |
| } else { |
| high = mid; |
| } |
| } |
| return nativeMin(high, MAX_ARRAY_INDEX); |
| } |
| |
| module.exports = binaryIndexBy; |
| |
| },{}],94:[function(require,module,exports){ |
| var identity = require('../utility/identity'); |
| |
| /** |
| * A specialized version of `baseCallback` which only supports `this` binding |
| * and specifying the number of arguments to provide to `func`. |
| * |
| * @private |
| * @param {Function} func The function to bind. |
| * @param {*} thisArg The `this` binding of `func`. |
| * @param {number} [argCount] The number of arguments to provide to `func`. |
| * @returns {Function} Returns the callback. |
| */ |
| function bindCallback(func, thisArg, argCount) { |
| if (typeof func != 'function') { |
| return identity; |
| } |
| if (thisArg === undefined) { |
| return func; |
| } |
| switch (argCount) { |
| case 1: return function(value) { |
| return func.call(thisArg, value); |
| }; |
| case 3: return function(value, index, collection) { |
| return func.call(thisArg, value, index, collection); |
| }; |
| case 4: return function(accumulator, value, index, collection) { |
| return func.call(thisArg, accumulator, value, index, collection); |
| }; |
| case 5: return function(value, other, key, object, source) { |
| return func.call(thisArg, value, other, key, object, source); |
| }; |
| } |
| return function() { |
| return func.apply(thisArg, arguments); |
| }; |
| } |
| |
| module.exports = bindCallback; |
| |
| },{"../utility/identity":154}],95:[function(require,module,exports){ |
| (function (global){ |
| /** Native method references. */ |
| var ArrayBuffer = global.ArrayBuffer, |
| Uint8Array = global.Uint8Array; |
| |
| /** |
| * Creates a clone of the given array buffer. |
| * |
| * @private |
| * @param {ArrayBuffer} buffer The array buffer to clone. |
| * @returns {ArrayBuffer} Returns the cloned array buffer. |
| */ |
| function bufferClone(buffer) { |
| var result = new ArrayBuffer(buffer.byteLength), |
| view = new Uint8Array(result); |
| |
| view.set(new Uint8Array(buffer)); |
| return result; |
| } |
| |
| module.exports = bufferClone; |
| |
| }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| |
| },{}],96:[function(require,module,exports){ |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeMax = Math.max; |
| |
| /** |
| * Creates an array that is the composition of partially applied arguments, |
| * placeholders, and provided arguments into a single array of arguments. |
| * |
| * @private |
| * @param {Array|Object} args The provided arguments. |
| * @param {Array} partials The arguments to prepend to those provided. |
| * @param {Array} holders The `partials` placeholder indexes. |
| * @returns {Array} Returns the new array of composed arguments. |
| */ |
| function composeArgs(args, partials, holders) { |
| var holdersLength = holders.length, |
| argsIndex = -1, |
| argsLength = nativeMax(args.length - holdersLength, 0), |
| leftIndex = -1, |
| leftLength = partials.length, |
| result = Array(leftLength + argsLength); |
| |
| while (++leftIndex < leftLength) { |
| result[leftIndex] = partials[leftIndex]; |
| } |
| while (++argsIndex < holdersLength) { |
| result[holders[argsIndex]] = args[argsIndex]; |
| } |
| while (argsLength--) { |
| result[leftIndex++] = args[argsIndex++]; |
| } |
| return result; |
| } |
| |
| module.exports = composeArgs; |
| |
| },{}],97:[function(require,module,exports){ |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeMax = Math.max; |
| |
| /** |
| * This function is like `composeArgs` except that the arguments composition |
| * is tailored for `_.partialRight`. |
| * |
| * @private |
| * @param {Array|Object} args The provided arguments. |
| * @param {Array} partials The arguments to append to those provided. |
| * @param {Array} holders The `partials` placeholder indexes. |
| * @returns {Array} Returns the new array of composed arguments. |
| */ |
| function composeArgsRight(args, partials, holders) { |
| var holdersIndex = -1, |
| holdersLength = holders.length, |
| argsIndex = -1, |
| argsLength = nativeMax(args.length - holdersLength, 0), |
| rightIndex = -1, |
| rightLength = partials.length, |
| result = Array(argsLength + rightLength); |
| |
| while (++argsIndex < argsLength) { |
| result[argsIndex] = args[argsIndex]; |
| } |
| var offset = argsIndex; |
| while (++rightIndex < rightLength) { |
| result[offset + rightIndex] = partials[rightIndex]; |
| } |
| while (++holdersIndex < holdersLength) { |
| result[offset + holders[holdersIndex]] = args[argsIndex++]; |
| } |
| return result; |
| } |
| |
| module.exports = composeArgsRight; |
| |
| },{}],98:[function(require,module,exports){ |
| var getLength = require('./getLength'), |
| isLength = require('./isLength'), |
| toObject = require('./toObject'); |
| |
| /** |
| * Creates a `baseEach` or `baseEachRight` function. |
| * |
| * @private |
| * @param {Function} eachFunc The function to iterate over a collection. |
| * @param {boolean} [fromRight] Specify iterating from right to left. |
| * @returns {Function} Returns the new base function. |
| */ |
| function createBaseEach(eachFunc, fromRight) { |
| return function(collection, iteratee) { |
| var length = collection ? getLength(collection) : 0; |
| if (!isLength(length)) { |
| return eachFunc(collection, iteratee); |
| } |
| var index = fromRight ? length : -1, |
| iterable = toObject(collection); |
| |
| while ((fromRight ? index-- : ++index < length)) { |
| if (iteratee(iterable[index], index, iterable) === false) { |
| break; |
| } |
| } |
| return collection; |
| }; |
| } |
| |
| module.exports = createBaseEach; |
| |
| },{"./getLength":112,"./isLength":125,"./toObject":135}],99:[function(require,module,exports){ |
| var toObject = require('./toObject'); |
| |
| /** |
| * Creates a base function for `_.forIn` or `_.forInRight`. |
| * |
| * @private |
| * @param {boolean} [fromRight] Specify iterating from right to left. |
| * @returns {Function} Returns the new base function. |
| */ |
| function createBaseFor(fromRight) { |
| return function(object, iteratee, keysFunc) { |
| var iterable = toObject(object), |
| props = keysFunc(object), |
| length = props.length, |
| index = fromRight ? length : -1; |
| |
| while ((fromRight ? index-- : ++index < length)) { |
| var key = props[index]; |
| if (iteratee(iterable[key], key, iterable) === false) { |
| break; |
| } |
| } |
| return object; |
| }; |
| } |
| |
| module.exports = createBaseFor; |
| |
| },{"./toObject":135}],100:[function(require,module,exports){ |
| (function (global){ |
| var createCtorWrapper = require('./createCtorWrapper'); |
| |
| /** |
| * Creates a function that wraps `func` and invokes it with the `this` |
| * binding of `thisArg`. |
| * |
| * @private |
| * @param {Function} func The function to bind. |
| * @param {*} [thisArg] The `this` binding of `func`. |
| * @returns {Function} Returns the new bound function. |
| */ |
| function createBindWrapper(func, thisArg) { |
| var Ctor = createCtorWrapper(func); |
| |
| function wrapper() { |
| var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func; |
| return fn.apply(thisArg, arguments); |
| } |
| return wrapper; |
| } |
| |
| module.exports = createBindWrapper; |
| |
| }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| |
| },{"./createCtorWrapper":101}],101:[function(require,module,exports){ |
| var baseCreate = require('./baseCreate'), |
| isObject = require('../lang/isObject'); |
| |
| /** |
| * Creates a function that produces an instance of `Ctor` regardless of |
| * whether it was invoked as part of a `new` expression or by `call` or `apply`. |
| * |
| * @private |
| * @param {Function} Ctor The constructor to wrap. |
| * @returns {Function} Returns the new wrapped function. |
| */ |
| function createCtorWrapper(Ctor) { |
| return function() { |
| // Use a `switch` statement to work with class constructors. |
| // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist |
| // for more details. |
| var args = arguments; |
| switch (args.length) { |
| case 0: return new Ctor; |
| case 1: return new Ctor(args[0]); |
| case 2: return new Ctor(args[0], args[1]); |
| case 3: return new Ctor(args[0], args[1], args[2]); |
| case 4: return new Ctor(args[0], args[1], args[2], args[3]); |
| case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); |
| case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); |
| case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); |
| } |
| var thisBinding = baseCreate(Ctor.prototype), |
| result = Ctor.apply(thisBinding, args); |
| |
| // Mimic the constructor's `return` behavior. |
| // See https://es5.github.io/#x13.2.2 for more details. |
| return isObject(result) ? result : thisBinding; |
| }; |
| } |
| |
| module.exports = createCtorWrapper; |
| |
| },{"../lang/isObject":144,"./baseCreate":70}],102:[function(require,module,exports){ |
| var baseCallback = require('./baseCallback'), |
| baseFind = require('./baseFind'), |
| baseFindIndex = require('./baseFindIndex'), |
| isArray = require('../lang/isArray'); |
| |
| /** |
| * Creates a `_.find` or `_.findLast` function. |
| * |
| * @private |
| * @param {Function} eachFunc The function to iterate over a collection. |
| * @param {boolean} [fromRight] Specify iterating from right to left. |
| * @returns {Function} Returns the new find function. |
| */ |
| function createFind(eachFunc, fromRight) { |
| return function(collection, predicate, thisArg) { |
| predicate = baseCallback(predicate, thisArg, 3); |
| if (isArray(collection)) { |
| var index = baseFindIndex(collection, predicate, fromRight); |
| return index > -1 ? collection[index] : undefined; |
| } |
| return baseFind(collection, predicate, eachFunc); |
| }; |
| } |
| |
| module.exports = createFind; |
| |
| },{"../lang/isArray":140,"./baseCallback":67,"./baseFind":72,"./baseFindIndex":73}],103:[function(require,module,exports){ |
| var bindCallback = require('./bindCallback'), |
| isArray = require('../lang/isArray'); |
| |
| /** |
| * Creates a function for `_.forEach` or `_.forEachRight`. |
| * |
| * @private |
| * @param {Function} arrayFunc The function to iterate over an array. |
| * @param {Function} eachFunc The function to iterate over a collection. |
| * @returns {Function} Returns the new each function. |
| */ |
| function createForEach(arrayFunc, eachFunc) { |
| return function(collection, iteratee, thisArg) { |
| return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) |
| ? arrayFunc(collection, iteratee) |
| : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); |
| }; |
| } |
| |
| module.exports = createForEach; |
| |
| },{"../lang/isArray":140,"./bindCallback":94}],104:[function(require,module,exports){ |
| (function (global){ |
| var arrayCopy = require('./arrayCopy'), |
| composeArgs = require('./composeArgs'), |
| composeArgsRight = require('./composeArgsRight'), |
| createCtorWrapper = require('./createCtorWrapper'), |
| isLaziable = require('./isLaziable'), |
| reorder = require('./reorder'), |
| replaceHolders = require('./replaceHolders'), |
| setData = require('./setData'); |
| |
| /** Used to compose bitmasks for wrapper metadata. */ |
| var BIND_FLAG = 1, |
| BIND_KEY_FLAG = 2, |
| CURRY_BOUND_FLAG = 4, |
| CURRY_FLAG = 8, |
| CURRY_RIGHT_FLAG = 16, |
| PARTIAL_FLAG = 32, |
| PARTIAL_RIGHT_FLAG = 64, |
| ARY_FLAG = 128; |
| |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeMax = Math.max; |
| |
| /** |
| * Creates a function that wraps `func` and invokes it with optional `this` |
| * binding of, partial application, and currying. |
| * |
| * @private |
| * @param {Function|string} func The function or method name to reference. |
| * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. |
| * @param {*} [thisArg] The `this` binding of `func`. |
| * @param {Array} [partials] The arguments to prepend to those provided to the new function. |
| * @param {Array} [holders] The `partials` placeholder indexes. |
| * @param {Array} [partialsRight] The arguments to append to those provided to the new function. |
| * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. |
| * @param {Array} [argPos] The argument positions of the new function. |
| * @param {number} [ary] The arity cap of `func`. |
| * @param {number} [arity] The arity of `func`. |
| * @returns {Function} Returns the new wrapped function. |
| */ |
| function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { |
| var isAry = bitmask & ARY_FLAG, |
| isBind = bitmask & BIND_FLAG, |
| isBindKey = bitmask & BIND_KEY_FLAG, |
| isCurry = bitmask & CURRY_FLAG, |
| isCurryBound = bitmask & CURRY_BOUND_FLAG, |
| isCurryRight = bitmask & CURRY_RIGHT_FLAG, |
| Ctor = isBindKey ? undefined : createCtorWrapper(func); |
| |
| function wrapper() { |
| // Avoid `arguments` object use disqualifying optimizations by |
| // converting it to an array before providing it to other functions. |
| var length = arguments.length, |
| index = length, |
| args = Array(length); |
| |
| while (index--) { |
| args[index] = arguments[index]; |
| } |
| if (partials) { |
| args = composeArgs(args, partials, holders); |
| } |
| if (partialsRight) { |
| args = composeArgsRight(args, partialsRight, holdersRight); |
| } |
| if (isCurry || isCurryRight) { |
| var placeholder = wrapper.placeholder, |
| argsHolders = replaceHolders(args, placeholder); |
| |
| length -= argsHolders.length; |
| if (length < arity) { |
| var newArgPos = argPos ? arrayCopy(argPos) : undefined, |
| newArity = nativeMax(arity - length, 0), |
| newsHolders = isCurry ? argsHolders : undefined, |
| newHoldersRight = isCurry ? undefined : argsHolders, |
| newPartials = isCurry ? args : undefined, |
| newPartialsRight = isCurry ? undefined : args; |
| |
| bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); |
| bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); |
| |
| if (!isCurryBound) { |
| bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); |
| } |
| var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], |
| result = createHybridWrapper.apply(undefined, newData); |
| |
| if (isLaziable(func)) { |
| setData(result, newData); |
| } |
| result.placeholder = placeholder; |
| return result; |
| } |
| } |
| var thisBinding = isBind ? thisArg : this, |
| fn = isBindKey ? thisBinding[func] : func; |
| |
| if (argPos) { |
| args = reorder(args, argPos); |
| } |
| if (isAry && ary < args.length) { |
| args.length = ary; |
| } |
| if (this && this !== global && this instanceof wrapper) { |
| fn = Ctor || createCtorWrapper(func); |
| } |
| return fn.apply(thisBinding, args); |
| } |
| return wrapper; |
| } |
| |
| module.exports = createHybridWrapper; |
| |
| }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| |
| },{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./createCtorWrapper":101,"./isLaziable":124,"./reorder":131,"./replaceHolders":132,"./setData":133}],105:[function(require,module,exports){ |
| (function (global){ |
| var createCtorWrapper = require('./createCtorWrapper'); |
| |
| /** Used to compose bitmasks for wrapper metadata. */ |
| var BIND_FLAG = 1; |
| |
| /** |
| * Creates a function that wraps `func` and invokes it with the optional `this` |
| * binding of `thisArg` and the `partials` prepended to those provided to |
| * the wrapper. |
| * |
| * @private |
| * @param {Function} func The function to partially apply arguments to. |
| * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. |
| * @param {*} thisArg The `this` binding of `func`. |
| * @param {Array} partials The arguments to prepend to those provided to the new function. |
| * @returns {Function} Returns the new bound function. |
| */ |
| function createPartialWrapper(func, bitmask, thisArg, partials) { |
| var isBind = bitmask & BIND_FLAG, |
| Ctor = createCtorWrapper(func); |
| |
| function wrapper() { |
| // Avoid `arguments` object use disqualifying optimizations by |
| // converting it to an array before providing it `func`. |
| var argsIndex = -1, |
| argsLength = arguments.length, |
| leftIndex = -1, |
| leftLength = partials.length, |
| args = Array(leftLength + argsLength); |
| |
| while (++leftIndex < leftLength) { |
| args[leftIndex] = partials[leftIndex]; |
| } |
| while (argsLength--) { |
| args[leftIndex++] = arguments[++argsIndex]; |
| } |
| var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func; |
| return fn.apply(isBind ? thisArg : this, args); |
| } |
| return wrapper; |
| } |
| |
| module.exports = createPartialWrapper; |
| |
| }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| |
| },{"./createCtorWrapper":101}],106:[function(require,module,exports){ |
| var baseSetData = require('./baseSetData'), |
| createBindWrapper = require('./createBindWrapper'), |
| createHybridWrapper = require('./createHybridWrapper'), |
| createPartialWrapper = require('./createPartialWrapper'), |
| getData = require('./getData'), |
| mergeData = require('./mergeData'), |
| setData = require('./setData'); |
| |
| /** Used to compose bitmasks for wrapper metadata. */ |
| var BIND_FLAG = 1, |
| BIND_KEY_FLAG = 2, |
| PARTIAL_FLAG = 32, |
| PARTIAL_RIGHT_FLAG = 64; |
| |
| /** Used as the `TypeError` message for "Functions" methods. */ |
| var FUNC_ERROR_TEXT = 'Expected a function'; |
| |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeMax = Math.max; |
| |
| /** |
| * Creates a function that either curries or invokes `func` with optional |
| * `this` binding and partially applied arguments. |
| * |
| * @private |
| * @param {Function|string} func The function or method name to reference. |
| * @param {number} bitmask The bitmask of flags. |
| * The bitmask may be composed of the following flags: |
| * 1 - `_.bind` |
| * 2 - `_.bindKey` |
| * 4 - `_.curry` or `_.curryRight` of a bound function |
| * 8 - `_.curry` |
| * 16 - `_.curryRight` |
| * 32 - `_.partial` |
| * 64 - `_.partialRight` |
| * 128 - `_.rearg` |
| * 256 - `_.ary` |
| * @param {*} [thisArg] The `this` binding of `func`. |
| * @param {Array} [partials] The arguments to be partially applied. |
| * @param {Array} [holders] The `partials` placeholder indexes. |
| * @param {Array} [argPos] The argument positions of the new function. |
| * @param {number} [ary] The arity cap of `func`. |
| * @param {number} [arity] The arity of `func`. |
| * @returns {Function} Returns the new wrapped function. |
| */ |
| function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { |
| var isBindKey = bitmask & BIND_KEY_FLAG; |
| if (!isBindKey && typeof func != 'function') { |
| throw new TypeError(FUNC_ERROR_TEXT); |
| } |
| var length = partials ? partials.length : 0; |
| if (!length) { |
| bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); |
| partials = holders = undefined; |
| } |
| length -= (holders ? holders.length : 0); |
| if (bitmask & PARTIAL_RIGHT_FLAG) { |
| var partialsRight = partials, |
| holdersRight = holders; |
| |
| partials = holders = undefined; |
| } |
| var data = isBindKey ? undefined : getData(func), |
| newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; |
| |
| if (data) { |
| mergeData(newData, data); |
| bitmask = newData[1]; |
| arity = newData[9]; |
| } |
| newData[9] = arity == null |
| ? (isBindKey ? 0 : func.length) |
| : (nativeMax(arity - length, 0) || 0); |
| |
| if (bitmask == BIND_FLAG) { |
| var result = createBindWrapper(newData[0], newData[2]); |
| } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { |
| result = createPartialWrapper.apply(undefined, newData); |
| } else { |
| result = createHybridWrapper.apply(undefined, newData); |
| } |
| var setter = data ? baseSetData : setData; |
| return setter(result, newData); |
| } |
| |
| module.exports = createWrapper; |
| |
| },{"./baseSetData":88,"./createBindWrapper":100,"./createHybridWrapper":104,"./createPartialWrapper":105,"./getData":110,"./mergeData":128,"./setData":133}],107:[function(require,module,exports){ |
| var arraySome = require('./arraySome'); |
| |
| /** |
| * A specialized version of `baseIsEqualDeep` for arrays with support for |
| * partial deep comparisons. |
| * |
| * @private |
| * @param {Array} array The array to compare. |
| * @param {Array} other The other array to compare. |
| * @param {Function} equalFunc The function to determine equivalents of values. |
| * @param {Function} [customizer] The function to customize comparing arrays. |
| * @param {boolean} [isLoose] Specify performing partial comparisons. |
| * @param {Array} [stackA] Tracks traversed `value` objects. |
| * @param {Array} [stackB] Tracks traversed `other` objects. |
| * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. |
| */ |
| function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { |
| var index = -1, |
| arrLength = array.length, |
| othLength = other.length; |
| |
| if (arrLength != othLength && !(isLoose && othLength > arrLength)) { |
| return false; |
| } |
| // Ignore non-index properties. |
| while (++index < arrLength) { |
| var arrValue = array[index], |
| othValue = other[index], |
| result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; |
| |
| if (result !== undefined) { |
| if (result) { |
| continue; |
| } |
| return false; |
| } |
| // Recursively compare arrays (susceptible to call stack limits). |
| if (isLoose) { |
| if (!arraySome(other, function(othValue) { |
| return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); |
| })) { |
| return false; |
| } |
| } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| module.exports = equalArrays; |
| |
| },{"./arraySome":65}],108:[function(require,module,exports){ |
| /** `Object#toString` result references. */ |
| var boolTag = '[object Boolean]', |
| dateTag = '[object Date]', |
| errorTag = '[object Error]', |
| numberTag = '[object Number]', |
| regexpTag = '[object RegExp]', |
| stringTag = '[object String]'; |
| |
| /** |
| * A specialized version of `baseIsEqualDeep` for comparing objects of |
| * the same `toStringTag`. |
| * |
| * **Note:** This function only supports comparing values with tags of |
| * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
| * |
| * @private |
| * @param {Object} object The object to compare. |
| * @param {Object} other The other object to compare. |
| * @param {string} tag The `toStringTag` of the objects to compare. |
| * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
| */ |
| function equalByTag(object, other, tag) { |
| switch (tag) { |
| case boolTag: |
| case dateTag: |
| // Coerce dates and booleans to numbers, dates to milliseconds and booleans |
| // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. |
| return +object == +other; |
| |
| case errorTag: |
| return object.name == other.name && object.message == other.message; |
| |
| case numberTag: |
| // Treat `NaN` vs. `NaN` as equal. |
| return (object != +object) |
| ? other != +other |
| : object == +other; |
| |
| case regexpTag: |
| case stringTag: |
| // Coerce regexes to strings and treat strings primitives and string |
| // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. |
| return object == (other + ''); |
| } |
| return false; |
| } |
| |
| module.exports = equalByTag; |
| |
| },{}],109:[function(require,module,exports){ |
| var keys = require('../object/keys'); |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** Used to check objects for own properties. */ |
| var hasOwnProperty = objectProto.hasOwnProperty; |
| |
| /** |
| * A specialized version of `baseIsEqualDeep` for objects with support for |
| * partial deep comparisons. |
| * |
| * @private |
| * @param {Object} object The object to compare. |
| * @param {Object} other The other object to compare. |
| * @param {Function} equalFunc The function to determine equivalents of values. |
| * @param {Function} [customizer] The function to customize comparing values. |
| * @param {boolean} [isLoose] Specify performing partial comparisons. |
| * @param {Array} [stackA] Tracks traversed `value` objects. |
| * @param {Array} [stackB] Tracks traversed `other` objects. |
| * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
| */ |
| function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { |
| var objProps = keys(object), |
| objLength = objProps.length, |
| othProps = keys(other), |
| othLength = othProps.length; |
| |
| if (objLength != othLength && !isLoose) { |
| return false; |
| } |
| var index = objLength; |
| while (index--) { |
| var key = objProps[index]; |
| if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { |
| return false; |
| } |
| } |
| var skipCtor = isLoose; |
| while (++index < objLength) { |
| key = objProps[index]; |
| var objValue = object[key], |
| othValue = other[key], |
| result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; |
| |
| // Recursively compare objects (susceptible to call stack limits). |
| if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { |
| return false; |
| } |
| skipCtor || (skipCtor = key == 'constructor'); |
| } |
| if (!skipCtor) { |
| var objCtor = object.constructor, |
| othCtor = other.constructor; |
| |
| // Non `Object` object instances with different constructors are not equal. |
| if (objCtor != othCtor && |
| ('constructor' in object && 'constructor' in other) && |
| !(typeof objCtor == 'function' && objCtor instanceof objCtor && |
| typeof othCtor == 'function' && othCtor instanceof othCtor)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| module.exports = equalObjects; |
| |
| },{"../object/keys":149}],110:[function(require,module,exports){ |
| var metaMap = require('./metaMap'), |
| noop = require('../utility/noop'); |
| |
| /** |
| * Gets metadata for `func`. |
| * |
| * @private |
| * @param {Function} func The function to query. |
| * @returns {*} Returns the metadata for `func`. |
| */ |
| var getData = !metaMap ? noop : function(func) { |
| return metaMap.get(func); |
| }; |
| |
| module.exports = getData; |
| |
| },{"../utility/noop":155,"./metaMap":129}],111:[function(require,module,exports){ |
| var realNames = require('./realNames'); |
| |
| /** |
| * Gets the name of `func`. |
| * |
| * @private |
| * @param {Function} func The function to query. |
| * @returns {string} Returns the function name. |
| */ |
| function getFuncName(func) { |
| var result = (func.name + ''), |
| array = realNames[result], |
| length = array ? array.length : 0; |
| |
| while (length--) { |
| var data = array[length], |
| otherFunc = data.func; |
| if (otherFunc == null || otherFunc == func) { |
| return data.name; |
| } |
| } |
| return result; |
| } |
| |
| module.exports = getFuncName; |
| |
| },{"./realNames":130}],112:[function(require,module,exports){ |
| var baseProperty = require('./baseProperty'); |
| |
| /** |
| * Gets the "length" property value of `object`. |
| * |
| * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) |
| * that affects Safari on at least iOS 8.1-8.3 ARM64. |
| * |
| * @private |
| * @param {Object} object The object to query. |
| * @returns {*} Returns the "length" value. |
| */ |
| var getLength = baseProperty('length'); |
| |
| module.exports = getLength; |
| |
| },{"./baseProperty":86}],113:[function(require,module,exports){ |
| var isStrictComparable = require('./isStrictComparable'), |
| pairs = require('../object/pairs'); |
| |
| /** |
| * Gets the propery names, values, and compare flags of `object`. |
| * |
| * @private |
| * @param {Object} object The object to query. |
| * @returns {Array} Returns the match data of `object`. |
| */ |
| function getMatchData(object) { |
| var result = pairs(object), |
| length = result.length; |
| |
| while (length--) { |
| result[length][2] = isStrictComparable(result[length][1]); |
| } |
| return result; |
| } |
| |
| module.exports = getMatchData; |
| |
| },{"../object/pairs":151,"./isStrictComparable":127}],114:[function(require,module,exports){ |
| var isNative = require('../lang/isNative'); |
| |
| /** |
| * Gets the native function at `key` of `object`. |
| * |
| * @private |
| * @param {Object} object The object to query. |
| * @param {string} key The key of the method to get. |
| * @returns {*} Returns the function if it's native, else `undefined`. |
| */ |
| function getNative(object, key) { |
| var value = object == null ? undefined : object[key]; |
| return isNative(value) ? value : undefined; |
| } |
| |
| module.exports = getNative; |
| |
| },{"../lang/isNative":143}],115:[function(require,module,exports){ |
| /** |
| * Gets the index at which the first occurrence of `NaN` is found in `array`. |
| * |
| * @private |
| * @param {Array} array The array to search. |
| * @param {number} fromIndex The index to search from. |
| * @param {boolean} [fromRight] Specify iterating from right to left. |
| * @returns {number} Returns the index of the matched `NaN`, else `-1`. |
| */ |
| function indexOfNaN(array, fromIndex, fromRight) { |
| var length = array.length, |
| index = fromIndex + (fromRight ? 0 : -1); |
| |
| while ((fromRight ? index-- : ++index < length)) { |
| var other = array[index]; |
| if (other !== other) { |
| return index; |
| } |
| } |
| return -1; |
| } |
| |
| module.exports = indexOfNaN; |
| |
| },{}],116:[function(require,module,exports){ |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** Used to check objects for own properties. */ |
| var hasOwnProperty = objectProto.hasOwnProperty; |
| |
| /** |
| * Initializes an array clone. |
| * |
| * @private |
| * @param {Array} array The array to clone. |
| * @returns {Array} Returns the initialized clone. |
| */ |
| function initCloneArray(array) { |
| var length = array.length, |
| result = new array.constructor(length); |
| |
| // Add array properties assigned by `RegExp#exec`. |
| if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { |
| result.index = array.index; |
| result.input = array.input; |
| } |
| return result; |
| } |
| |
| module.exports = initCloneArray; |
| |
| },{}],117:[function(require,module,exports){ |
| (function (global){ |
| var bufferClone = require('./bufferClone'); |
| |
| /** `Object#toString` result references. */ |
| var boolTag = '[object Boolean]', |
| dateTag = '[object Date]', |
| numberTag = '[object Number]', |
| regexpTag = '[object RegExp]', |
| stringTag = '[object String]'; |
| |
| var arrayBufferTag = '[object ArrayBuffer]', |
| float32Tag = '[object Float32Array]', |
| float64Tag = '[object Float64Array]', |
| int8Tag = '[object Int8Array]', |
| int16Tag = '[object Int16Array]', |
| int32Tag = '[object Int32Array]', |
| uint8Tag = '[object Uint8Array]', |
| uint8ClampedTag = '[object Uint8ClampedArray]', |
| uint16Tag = '[object Uint16Array]', |
| uint32Tag = '[object Uint32Array]'; |
| |
| /** Used to match `RegExp` flags from their coerced string values. */ |
| var reFlags = /\w*$/; |
| |
| /** Native method references. */ |
| var Uint8Array = global.Uint8Array; |
| |
| /** Used to lookup a type array constructors by `toStringTag`. */ |
| var ctorByTag = {}; |
| ctorByTag[float32Tag] = global.Float32Array; |
| ctorByTag[float64Tag] = global.Float64Array; |
| ctorByTag[int8Tag] = global.Int8Array; |
| ctorByTag[int16Tag] = global.Int16Array; |
| ctorByTag[int32Tag] = global.Int32Array; |
| ctorByTag[uint8Tag] = Uint8Array; |
| ctorByTag[uint8ClampedTag] = global.Uint8ClampedArray; |
| ctorByTag[uint16Tag] = global.Uint16Array; |
| ctorByTag[uint32Tag] = global.Uint32Array; |
| |
| /** |
| * Initializes an object clone based on its `toStringTag`. |
| * |
| * **Note:** This function only supports cloning values with tags of |
| * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
| * |
| * @private |
| * @param {Object} object The object to clone. |
| * @param {string} tag The `toStringTag` of the object to clone. |
| * @param {boolean} [isDeep] Specify a deep clone. |
| * @returns {Object} Returns the initialized clone. |
| */ |
| function initCloneByTag(object, tag, isDeep) { |
| var Ctor = object.constructor; |
| switch (tag) { |
| case arrayBufferTag: |
| return bufferClone(object); |
| |
| case boolTag: |
| case dateTag: |
| return new Ctor(+object); |
| |
| case float32Tag: case float64Tag: |
| case int8Tag: case int16Tag: case int32Tag: |
| case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: |
| // Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays. |
| if (Ctor instanceof Ctor) { |
| Ctor = ctorByTag[tag]; |
| } |
| var buffer = object.buffer; |
| return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); |
| |
| case numberTag: |
| case stringTag: |
| return new Ctor(object); |
| |
| case regexpTag: |
| var result = new Ctor(object.source, reFlags.exec(object)); |
| result.lastIndex = object.lastIndex; |
| } |
| return result; |
| } |
| |
| module.exports = initCloneByTag; |
| |
| }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| |
| },{"./bufferClone":95}],118:[function(require,module,exports){ |
| /** |
| * Initializes an object clone. |
| * |
| * @private |
| * @param {Object} object The object to clone. |
| * @returns {Object} Returns the initialized clone. |
| */ |
| function initCloneObject(object) { |
| var Ctor = object.constructor; |
| if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { |
| Ctor = Object; |
| } |
| return new Ctor; |
| } |
| |
| module.exports = initCloneObject; |
| |
| },{}],119:[function(require,module,exports){ |
| var getLength = require('./getLength'), |
| isLength = require('./isLength'); |
| |
| /** |
| * Checks if `value` is array-like. |
| * |
| * @private |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is array-like, else `false`. |
| */ |
| function isArrayLike(value) { |
| return value != null && isLength(getLength(value)); |
| } |
| |
| module.exports = isArrayLike; |
| |
| },{"./getLength":112,"./isLength":125}],120:[function(require,module,exports){ |
| /** |
| * Checks if `value` is a host object in IE < 9. |
| * |
| * @private |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is a host object, else `false`. |
| */ |
| var isHostObject = (function() { |
| try { |
| Object({ 'toString': 0 } + ''); |
| } catch(e) { |
| return function() { return false; }; |
| } |
| return function(value) { |
| // IE < 9 presents many host objects as `Object` objects that can coerce |
| // to strings despite having improperly defined `toString` methods. |
| return typeof value.toString != 'function' && typeof (value + '') == 'string'; |
| }; |
| }()); |
| |
| module.exports = isHostObject; |
| |
| },{}],121:[function(require,module,exports){ |
| /** Used to detect unsigned integer values. */ |
| var reIsUint = /^\d+$/; |
| |
| /** |
| * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) |
| * of an array-like value. |
| */ |
| var MAX_SAFE_INTEGER = 9007199254740991; |
| |
| /** |
| * Checks if `value` is a valid array-like index. |
| * |
| * @private |
| * @param {*} value The value to check. |
| * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. |
| * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. |
| */ |
| function isIndex(value, length) { |
| value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; |
| length = length == null ? MAX_SAFE_INTEGER : length; |
| return value > -1 && value % 1 == 0 && value < length; |
| } |
| |
| module.exports = isIndex; |
| |
| },{}],122:[function(require,module,exports){ |
| var isArrayLike = require('./isArrayLike'), |
| isIndex = require('./isIndex'), |
| isObject = require('../lang/isObject'); |
| |
| /** |
| * Checks if the provided arguments are from an iteratee call. |
| * |
| * @private |
| * @param {*} value The potential iteratee value argument. |
| * @param {*} index The potential iteratee index or key argument. |
| * @param {*} object The potential iteratee object argument. |
| * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. |
| */ |
| function isIterateeCall(value, index, object) { |
| if (!isObject(object)) { |
| return false; |
| } |
| var type = typeof index; |
| if (type == 'number' |
| ? (isArrayLike(object) && isIndex(index, object.length)) |
| : (type == 'string' && index in object)) { |
| var other = object[index]; |
| return value === value ? (value === other) : (other !== other); |
| } |
| return false; |
| } |
| |
| module.exports = isIterateeCall; |
| |
| },{"../lang/isObject":144,"./isArrayLike":119,"./isIndex":121}],123:[function(require,module,exports){ |
| var isArray = require('../lang/isArray'), |
| toObject = require('./toObject'); |
| |
| /** Used to match property names within property paths. */ |
| var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, |
| reIsPlainProp = /^\w*$/; |
| |
| /** |
| * Checks if `value` is a property name and not a property path. |
| * |
| * @private |
| * @param {*} value The value to check. |
| * @param {Object} [object] The object to query keys on. |
| * @returns {boolean} Returns `true` if `value` is a property name, else `false`. |
| */ |
| function isKey(value, object) { |
| var type = typeof value; |
| if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { |
| return true; |
| } |
| if (isArray(value)) { |
| return false; |
| } |
| var result = !reIsDeepProp.test(value); |
| return result || (object != null && value in toObject(object)); |
| } |
| |
| module.exports = isKey; |
| |
| },{"../lang/isArray":140,"./toObject":135}],124:[function(require,module,exports){ |
| var LazyWrapper = require('./LazyWrapper'), |
| getData = require('./getData'), |
| getFuncName = require('./getFuncName'), |
| lodash = require('../chain/lodash'); |
| |
| /** |
| * Checks if `func` has a lazy counterpart. |
| * |
| * @private |
| * @param {Function} func The function to check. |
| * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. |
| */ |
| function isLaziable(func) { |
| var funcName = getFuncName(func), |
| other = lodash[funcName]; |
| |
| if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { |
| return false; |
| } |
| if (func === other) { |
| return true; |
| } |
| var data = getData(other); |
| return !!data && func === data[0]; |
| } |
| |
| module.exports = isLaziable; |
| |
| },{"../chain/lodash":51,"./LazyWrapper":60,"./getData":110,"./getFuncName":111}],125:[function(require,module,exports){ |
| /** |
| * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) |
| * of an array-like value. |
| */ |
| var MAX_SAFE_INTEGER = 9007199254740991; |
| |
| /** |
| * Checks if `value` is a valid array-like length. |
| * |
| * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). |
| * |
| * @private |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. |
| */ |
| function isLength(value) { |
| return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; |
| } |
| |
| module.exports = isLength; |
| |
| },{}],126:[function(require,module,exports){ |
| /** |
| * Checks if `value` is object-like. |
| * |
| * @private |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is object-like, else `false`. |
| */ |
| function isObjectLike(value) { |
| return !!value && typeof value == 'object'; |
| } |
| |
| module.exports = isObjectLike; |
| |
| },{}],127:[function(require,module,exports){ |
| var isObject = require('../lang/isObject'); |
| |
| /** |
| * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. |
| * |
| * @private |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` if suitable for strict |
| * equality comparisons, else `false`. |
| */ |
| function isStrictComparable(value) { |
| return value === value && !isObject(value); |
| } |
| |
| module.exports = isStrictComparable; |
| |
| },{"../lang/isObject":144}],128:[function(require,module,exports){ |
| var arrayCopy = require('./arrayCopy'), |
| composeArgs = require('./composeArgs'), |
| composeArgsRight = require('./composeArgsRight'), |
| replaceHolders = require('./replaceHolders'); |
| |
| /** Used to compose bitmasks for wrapper metadata. */ |
| var BIND_FLAG = 1, |
| CURRY_BOUND_FLAG = 4, |
| CURRY_FLAG = 8, |
| ARY_FLAG = 128, |
| REARG_FLAG = 256; |
| |
| /** Used as the internal argument placeholder. */ |
| var PLACEHOLDER = '__lodash_placeholder__'; |
| |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeMin = Math.min; |
| |
| /** |
| * Merges the function metadata of `source` into `data`. |
| * |
| * Merging metadata reduces the number of wrappers required to invoke a function. |
| * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` |
| * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` |
| * augment function arguments, making the order in which they are executed important, |
| * preventing the merging of metadata. However, we make an exception for a safe |
| * common case where curried functions have `_.ary` and or `_.rearg` applied. |
| * |
| * @private |
| * @param {Array} data The destination metadata. |
| * @param {Array} source The source metadata. |
| * @returns {Array} Returns `data`. |
| */ |
| function mergeData(data, source) { |
| var bitmask = data[1], |
| srcBitmask = source[1], |
| newBitmask = bitmask | srcBitmask, |
| isCommon = newBitmask < ARY_FLAG; |
| |
| var isCombo = |
| (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || |
| (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || |
| (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); |
| |
| // Exit early if metadata can't be merged. |
| if (!(isCommon || isCombo)) { |
| return data; |
| } |
| // Use source `thisArg` if available. |
| if (srcBitmask & BIND_FLAG) { |
| data[2] = source[2]; |
| // Set when currying a bound function. |
| newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; |
| } |
| // Compose partial arguments. |
| var value = source[3]; |
| if (value) { |
| var partials = data[3]; |
| data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); |
| data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); |
| } |
| // Compose partial right arguments. |
| value = source[5]; |
| if (value) { |
| partials = data[5]; |
| data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); |
| data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); |
| } |
| // Use source `argPos` if available. |
| value = source[7]; |
| if (value) { |
| data[7] = arrayCopy(value); |
| } |
| // Use source `ary` if it's smaller. |
| if (srcBitmask & ARY_FLAG) { |
| data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); |
| } |
| // Use source `arity` if one is not provided. |
| if (data[9] == null) { |
| data[9] = source[9]; |
| } |
| // Use source `func` and merge bitmasks. |
| data[0] = source[0]; |
| data[1] = newBitmask; |
| |
| return data; |
| } |
| |
| module.exports = mergeData; |
| |
| },{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./replaceHolders":132}],129:[function(require,module,exports){ |
| (function (global){ |
| var getNative = require('./getNative'); |
| |
| /** Native method references. */ |
| var WeakMap = getNative(global, 'WeakMap'); |
| |
| /** Used to store function metadata. */ |
| var metaMap = WeakMap && new WeakMap; |
| |
| module.exports = metaMap; |
| |
| }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
| |
| },{"./getNative":114}],130:[function(require,module,exports){ |
| /** Used to lookup unminified function names. */ |
| var realNames = {}; |
| |
| module.exports = realNames; |
| |
| },{}],131:[function(require,module,exports){ |
| var arrayCopy = require('./arrayCopy'), |
| isIndex = require('./isIndex'); |
| |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeMin = Math.min; |
| |
| /** |
| * Reorder `array` according to the specified indexes where the element at |
| * the first index is assigned as the first element, the element at |
| * the second index is assigned as the second element, and so on. |
| * |
| * @private |
| * @param {Array} array The array to reorder. |
| * @param {Array} indexes The arranged array indexes. |
| * @returns {Array} Returns `array`. |
| */ |
| function reorder(array, indexes) { |
| var arrLength = array.length, |
| length = nativeMin(indexes.length, arrLength), |
| oldArray = arrayCopy(array); |
| |
| while (length--) { |
| var index = indexes[length]; |
| array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; |
| } |
| return array; |
| } |
| |
| module.exports = reorder; |
| |
| },{"./arrayCopy":62,"./isIndex":121}],132:[function(require,module,exports){ |
| /** Used as the internal argument placeholder. */ |
| var PLACEHOLDER = '__lodash_placeholder__'; |
| |
| /** |
| * Replaces all `placeholder` elements in `array` with an internal placeholder |
| * and returns an array of their indexes. |
| * |
| * @private |
| * @param {Array} array The array to modify. |
| * @param {*} placeholder The placeholder to replace. |
| * @returns {Array} Returns the new array of placeholder indexes. |
| */ |
| function replaceHolders(array, placeholder) { |
| var index = -1, |
| length = array.length, |
| resIndex = -1, |
| result = []; |
| |
| while (++index < length) { |
| if (array[index] === placeholder) { |
| array[index] = PLACEHOLDER; |
| result[++resIndex] = index; |
| } |
| } |
| return result; |
| } |
| |
| module.exports = replaceHolders; |
| |
| },{}],133:[function(require,module,exports){ |
| var baseSetData = require('./baseSetData'), |
| now = require('../date/now'); |
| |
| /** Used to detect when a function becomes hot. */ |
| var HOT_COUNT = 150, |
| HOT_SPAN = 16; |
| |
| /** |
| * Sets metadata for `func`. |
| * |
| * **Note:** If this function becomes hot, i.e. is invoked a lot in a short |
| * period of time, it will trip its breaker and transition to an identity function |
| * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) |
| * for more details. |
| * |
| * @private |
| * @param {Function} func The function to associate metadata with. |
| * @param {*} data The metadata. |
| * @returns {Function} Returns `func`. |
| */ |
| var setData = (function() { |
| var count = 0, |
| lastCalled = 0; |
| |
| return function(key, value) { |
| var stamp = now(), |
| remaining = HOT_SPAN - (stamp - lastCalled); |
| |
| lastCalled = stamp; |
| if (remaining > 0) { |
| if (++count >= HOT_COUNT) { |
| return key; |
| } |
| } else { |
| count = 0; |
| } |
| return baseSetData(key, value); |
| }; |
| }()); |
| |
| module.exports = setData; |
| |
| },{"../date/now":57,"./baseSetData":88}],134:[function(require,module,exports){ |
| var isArguments = require('../lang/isArguments'), |
| isArray = require('../lang/isArray'), |
| isIndex = require('./isIndex'), |
| isLength = require('./isLength'), |
| isString = require('../lang/isString'), |
| keysIn = require('../object/keysIn'); |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** Used to check objects for own properties. */ |
| var hasOwnProperty = objectProto.hasOwnProperty; |
| |
| /** |
| * A fallback implementation of `Object.keys` which creates an array of the |
| * own enumerable property names of `object`. |
| * |
| * @private |
| * @param {Object} object The object to query. |
| * @returns {Array} Returns the array of property names. |
| */ |
| function shimKeys(object) { |
| var props = keysIn(object), |
| propsLength = props.length, |
| length = propsLength && object.length; |
| |
| var allowIndexes = !!length && isLength(length) && |
| (isArray(object) || isArguments(object) || isString(object)); |
| |
| var index = -1, |
| result = []; |
| |
| while (++index < propsLength) { |
| var key = props[index]; |
| if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { |
| result.push(key); |
| } |
| } |
| return result; |
| } |
| |
| module.exports = shimKeys; |
| |
| },{"../lang/isArguments":139,"../lang/isArray":140,"../lang/isString":146,"../object/keysIn":150,"./isIndex":121,"./isLength":125}],135:[function(require,module,exports){ |
| var isObject = require('../lang/isObject'), |
| isString = require('../lang/isString'), |
| support = require('../support'); |
| |
| /** |
| * Converts `value` to an object if it's not one. |
| * |
| * @private |
| * @param {*} value The value to process. |
| * @returns {Object} Returns the object. |
| */ |
| function toObject(value) { |
| if (support.unindexedChars && isString(value)) { |
| var index = -1, |
| length = value.length, |
| result = Object(value); |
| |
| while (++index < length) { |
| result[index] = value.charAt(index); |
| } |
| return result; |
| } |
| return isObject(value) ? value : Object(value); |
| } |
| |
| module.exports = toObject; |
| |
| },{"../lang/isObject":144,"../lang/isString":146,"../support":153}],136:[function(require,module,exports){ |
| var baseToString = require('./baseToString'), |
| isArray = require('../lang/isArray'); |
| |
| /** Used to match property names within property paths. */ |
| var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; |
| |
| /** Used to match backslashes in property paths. */ |
| var reEscapeChar = /\\(\\)?/g; |
| |
| /** |
| * Converts `value` to property path array if it's not one. |
| * |
| * @private |
| * @param {*} value The value to process. |
| * @returns {Array} Returns the property path array. |
| */ |
| function toPath(value) { |
| if (isArray(value)) { |
| return value; |
| } |
| var result = []; |
| baseToString(value).replace(rePropName, function(match, number, quote, string) { |
| result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); |
| }); |
| return result; |
| } |
| |
| module.exports = toPath; |
| |
| },{"../lang/isArray":140,"./baseToString":90}],137:[function(require,module,exports){ |
| var LazyWrapper = require('./LazyWrapper'), |
| LodashWrapper = require('./LodashWrapper'), |
| arrayCopy = require('./arrayCopy'); |
| |
| /** |
| * Creates a clone of `wrapper`. |
| * |
| * @private |
| * @param {Object} wrapper The wrapper to clone. |
| * @returns {Object} Returns the cloned wrapper. |
| */ |
| function wrapperClone(wrapper) { |
| return wrapper instanceof LazyWrapper |
| ? wrapper.clone() |
| : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); |
| } |
| |
| module.exports = wrapperClone; |
| |
| },{"./LazyWrapper":60,"./LodashWrapper":61,"./arrayCopy":62}],138:[function(require,module,exports){ |
| var baseClone = require('../internal/baseClone'), |
| bindCallback = require('../internal/bindCallback'); |
| |
| /** |
| * Creates a deep clone of `value`. If `customizer` is provided it's invoked |
| * to produce the cloned values. If `customizer` returns `undefined` cloning |
| * is handled by the method instead. The `customizer` is bound to `thisArg` |
| * and invoked with up to three argument; (value [, index|key, object]). |
| * |
| * **Note:** This method is loosely based on the |
| * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). |
| * The enumerable properties of `arguments` objects and objects created by |
| * constructors other than `Object` are cloned to plain `Object` objects. An |
| * empty object is returned for uncloneable values such as functions, DOM nodes, |
| * Maps, Sets, and WeakMaps. |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {*} value The value to deep clone. |
| * @param {Function} [customizer] The function to customize cloning values. |
| * @param {*} [thisArg] The `this` binding of `customizer`. |
| * @returns {*} Returns the deep cloned value. |
| * @example |
| * |
| * var users = [ |
| * { 'user': 'barney' }, |
| * { 'user': 'fred' } |
| * ]; |
| * |
| * var deep = _.cloneDeep(users); |
| * deep[0] === users[0]; |
| * // => false |
| * |
| * // using a customizer callback |
| * var el = _.cloneDeep(document.body, function(value) { |
| * if (_.isElement(value)) { |
| * return value.cloneNode(true); |
| * } |
| * }); |
| * |
| * el === document.body |
| * // => false |
| * el.nodeName |
| * // => BODY |
| * el.childNodes.length; |
| * // => 20 |
| */ |
| function cloneDeep(value, customizer, thisArg) { |
| return typeof customizer == 'function' |
| ? baseClone(value, true, bindCallback(customizer, thisArg, 3)) |
| : baseClone(value, true); |
| } |
| |
| module.exports = cloneDeep; |
| |
| },{"../internal/baseClone":68,"../internal/bindCallback":94}],139:[function(require,module,exports){ |
| var isArrayLike = require('../internal/isArrayLike'), |
| isObjectLike = require('../internal/isObjectLike'); |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** Used to check objects for own properties. */ |
| var hasOwnProperty = objectProto.hasOwnProperty; |
| |
| /** Native method references. */ |
| var propertyIsEnumerable = objectProto.propertyIsEnumerable; |
| |
| /** |
| * Checks if `value` is classified as an `arguments` object. |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| * @example |
| * |
| * _.isArguments(function() { return arguments; }()); |
| * // => true |
| * |
| * _.isArguments([1, 2, 3]); |
| * // => false |
| */ |
| function isArguments(value) { |
| return isObjectLike(value) && isArrayLike(value) && |
| hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); |
| } |
| |
| module.exports = isArguments; |
| |
| },{"../internal/isArrayLike":119,"../internal/isObjectLike":126}],140:[function(require,module,exports){ |
| var getNative = require('../internal/getNative'), |
| isLength = require('../internal/isLength'), |
| isObjectLike = require('../internal/isObjectLike'); |
| |
| /** `Object#toString` result references. */ |
| var arrayTag = '[object Array]'; |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** |
| * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
| * of values. |
| */ |
| var objToString = objectProto.toString; |
| |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeIsArray = getNative(Array, 'isArray'); |
| |
| /** |
| * Checks if `value` is classified as an `Array` object. |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| * @example |
| * |
| * _.isArray([1, 2, 3]); |
| * // => true |
| * |
| * _.isArray(function() { return arguments; }()); |
| * // => false |
| */ |
| var isArray = nativeIsArray || function(value) { |
| return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; |
| }; |
| |
| module.exports = isArray; |
| |
| },{"../internal/getNative":114,"../internal/isLength":125,"../internal/isObjectLike":126}],141:[function(require,module,exports){ |
| var isArguments = require('./isArguments'), |
| isArray = require('./isArray'), |
| isArrayLike = require('../internal/isArrayLike'), |
| isFunction = require('./isFunction'), |
| isObjectLike = require('../internal/isObjectLike'), |
| isString = require('./isString'), |
| keys = require('../object/keys'); |
| |
| /** |
| * Checks if `value` is empty. A value is considered empty unless it's an |
| * `arguments` object, array, string, or jQuery-like collection with a length |
| * greater than `0` or an object with own enumerable properties. |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {Array|Object|string} value The value to inspect. |
| * @returns {boolean} Returns `true` if `value` is empty, else `false`. |
| * @example |
| * |
| * _.isEmpty(null); |
| * // => true |
| * |
| * _.isEmpty(true); |
| * // => true |
| * |
| * _.isEmpty(1); |
| * // => true |
| * |
| * _.isEmpty([1, 2, 3]); |
| * // => false |
| * |
| * _.isEmpty({ 'a': 1 }); |
| * // => false |
| */ |
| function isEmpty(value) { |
| if (value == null) { |
| return true; |
| } |
| if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || |
| (isObjectLike(value) && isFunction(value.splice)))) { |
| return !value.length; |
| } |
| return !keys(value).length; |
| } |
| |
| module.exports = isEmpty; |
| |
| },{"../internal/isArrayLike":119,"../internal/isObjectLike":126,"../object/keys":149,"./isArguments":139,"./isArray":140,"./isFunction":142,"./isString":146}],142:[function(require,module,exports){ |
| var isObject = require('./isObject'); |
| |
| /** `Object#toString` result references. */ |
| var funcTag = '[object Function]'; |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** |
| * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
| * of values. |
| */ |
| var objToString = objectProto.toString; |
| |
| /** |
| * Checks if `value` is classified as a `Function` object. |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| * @example |
| * |
| * _.isFunction(_); |
| * // => true |
| * |
| * _.isFunction(/abc/); |
| * // => false |
| */ |
| function isFunction(value) { |
| // The use of `Object#toString` avoids issues with the `typeof` operator |
| // in older versions of Chrome and Safari which return 'function' for regexes |
| // and Safari 8 which returns 'object' for typed array constructors. |
| return isObject(value) && objToString.call(value) == funcTag; |
| } |
| |
| module.exports = isFunction; |
| |
| },{"./isObject":144}],143:[function(require,module,exports){ |
| var isFunction = require('./isFunction'), |
| isHostObject = require('../internal/isHostObject'), |
| isObjectLike = require('../internal/isObjectLike'); |
| |
| /** Used to detect host constructors (Safari > 5). */ |
| var reIsHostCtor = /^\[object .+?Constructor\]$/; |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** Used to resolve the decompiled source of functions. */ |
| var fnToString = Function.prototype.toString; |
| |
| /** Used to check objects for own properties. */ |
| var hasOwnProperty = objectProto.hasOwnProperty; |
| |
| /** Used to detect if a method is native. */ |
| var reIsNative = RegExp('^' + |
| fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') |
| .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' |
| ); |
| |
| /** |
| * Checks if `value` is a native function. |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is a native function, else `false`. |
| * @example |
| * |
| * _.isNative(Array.prototype.push); |
| * // => true |
| * |
| * _.isNative(_); |
| * // => false |
| */ |
| function isNative(value) { |
| if (value == null) { |
| return false; |
| } |
| if (isFunction(value)) { |
| return reIsNative.test(fnToString.call(value)); |
| } |
| return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); |
| } |
| |
| module.exports = isNative; |
| |
| },{"../internal/isHostObject":120,"../internal/isObjectLike":126,"./isFunction":142}],144:[function(require,module,exports){ |
| /** |
| * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. |
| * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is an object, else `false`. |
| * @example |
| * |
| * _.isObject({}); |
| * // => true |
| * |
| * _.isObject([1, 2, 3]); |
| * // => true |
| * |
| * _.isObject(1); |
| * // => false |
| */ |
| function isObject(value) { |
| // Avoid a V8 JIT bug in Chrome 19-20. |
| // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. |
| var type = typeof value; |
| return !!value && (type == 'object' || type == 'function'); |
| } |
| |
| module.exports = isObject; |
| |
| },{}],145:[function(require,module,exports){ |
| var baseForIn = require('../internal/baseForIn'), |
| isArguments = require('./isArguments'), |
| isHostObject = require('../internal/isHostObject'), |
| isObjectLike = require('../internal/isObjectLike'), |
| support = require('../support'); |
| |
| /** `Object#toString` result references. */ |
| var objectTag = '[object Object]'; |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** Used to check objects for own properties. */ |
| var hasOwnProperty = objectProto.hasOwnProperty; |
| |
| /** |
| * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
| * of values. |
| */ |
| var objToString = objectProto.toString; |
| |
| /** |
| * Checks if `value` is a plain object, that is, an object created by the |
| * `Object` constructor or one with a `[[Prototype]]` of `null`. |
| * |
| * **Note:** This method assumes objects created by the `Object` constructor |
| * have no inherited enumerable properties. |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
| * @example |
| * |
| * function Foo() { |
| * this.a = 1; |
| * } |
| * |
| * _.isPlainObject(new Foo); |
| * // => false |
| * |
| * _.isPlainObject([1, 2, 3]); |
| * // => false |
| * |
| * _.isPlainObject({ 'x': 0, 'y': 0 }); |
| * // => true |
| * |
| * _.isPlainObject(Object.create(null)); |
| * // => true |
| */ |
| function isPlainObject(value) { |
| var Ctor; |
| |
| // Exit early for non `Object` objects. |
| if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) || |
| (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { |
| return false; |
| } |
| // IE < 9 iterates inherited properties before own properties. If the first |
| // iterated property is an object's own property then there are no inherited |
| // enumerable properties. |
| var result; |
| if (support.ownLast) { |
| baseForIn(value, function(subValue, key, object) { |
| result = hasOwnProperty.call(object, key); |
| return false; |
| }); |
| return result !== false; |
| } |
| // In most environments an object's own properties are iterated before |
| // its inherited properties. If the last iterated property is an object's |
| // own property then there are no inherited enumerable properties. |
| baseForIn(value, function(subValue, key) { |
| result = key; |
| }); |
| return result === undefined || hasOwnProperty.call(value, result); |
| } |
| |
| module.exports = isPlainObject; |
| |
| },{"../internal/baseForIn":75,"../internal/isHostObject":120,"../internal/isObjectLike":126,"../support":153,"./isArguments":139}],146:[function(require,module,exports){ |
| var isObjectLike = require('../internal/isObjectLike'); |
| |
| /** `Object#toString` result references. */ |
| var stringTag = '[object String]'; |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** |
| * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
| * of values. |
| */ |
| var objToString = objectProto.toString; |
| |
| /** |
| * Checks if `value` is classified as a `String` primitive or object. |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| * @example |
| * |
| * _.isString('abc'); |
| * // => true |
| * |
| * _.isString(1); |
| * // => false |
| */ |
| function isString(value) { |
| return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); |
| } |
| |
| module.exports = isString; |
| |
| },{"../internal/isObjectLike":126}],147:[function(require,module,exports){ |
| var isLength = require('../internal/isLength'), |
| isObjectLike = require('../internal/isObjectLike'); |
| |
| /** `Object#toString` result references. */ |
| var argsTag = '[object Arguments]', |
| arrayTag = '[object Array]', |
| boolTag = '[object Boolean]', |
| dateTag = '[object Date]', |
| errorTag = '[object Error]', |
| funcTag = '[object Function]', |
| mapTag = '[object Map]', |
| numberTag = '[object Number]', |
| objectTag = '[object Object]', |
| regexpTag = '[object RegExp]', |
| setTag = '[object Set]', |
| stringTag = '[object String]', |
| weakMapTag = '[object WeakMap]'; |
| |
| var arrayBufferTag = '[object ArrayBuffer]', |
| float32Tag = '[object Float32Array]', |
| float64Tag = '[object Float64Array]', |
| int8Tag = '[object Int8Array]', |
| int16Tag = '[object Int16Array]', |
| int32Tag = '[object Int32Array]', |
| uint8Tag = '[object Uint8Array]', |
| uint8ClampedTag = '[object Uint8ClampedArray]', |
| uint16Tag = '[object Uint16Array]', |
| uint32Tag = '[object Uint32Array]'; |
| |
| /** Used to identify `toStringTag` values of typed arrays. */ |
| var typedArrayTags = {}; |
| typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = |
| typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = |
| typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = |
| typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = |
| typedArrayTags[uint32Tag] = true; |
| typedArrayTags[argsTag] = typedArrayTags[arrayTag] = |
| typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = |
| typedArrayTags[dateTag] = typedArrayTags[errorTag] = |
| typedArrayTags[funcTag] = typedArrayTags[mapTag] = |
| typedArrayTags[numberTag] = typedArrayTags[objectTag] = |
| typedArrayTags[regexpTag] = typedArrayTags[setTag] = |
| typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; |
| |
| /** Used for native method references. */ |
| var objectProto = Object.prototype; |
| |
| /** |
| * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
| * of values. |
| */ |
| var objToString = objectProto.toString; |
| |
| /** |
| * Checks if `value` is classified as a typed array. |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| * @example |
| * |
| * _.isTypedArray(new Uint8Array); |
| * // => true |
| * |
| * _.isTypedArray([]); |
| * // => false |
| */ |
| function isTypedArray(value) { |
| return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; |
| } |
| |
| module.exports = isTypedArray; |
| |
| },{"../internal/isLength":125,"../internal/isObjectLike":126}],148:[function(require,module,exports){ |
| /** |
| * Checks if `value` is `undefined`. |
| * |
| * @static |
| * @memberOf _ |
| * @category Lang |
| * @param {*} value The value to check. |
| * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. |
| * @example |
| * |
| * _.isUndefined(void 0); |
| * // => true |
| * |
| * _.isUndefined(null); |
| * // => false |
| */ |
| function isUndefined(value) { |
| return value === undefined; |
| } |
| |
| module.exports = isUndefined; |
| |
| },{}],149:[function(require,module,exports){ |
| var getNative = require('../internal/getNative'), |
| isArrayLike = require('../internal/isArrayLike'), |
| isObject = require('../lang/isObject'), |
| shimKeys = require('../internal/shimKeys'), |
| support = require('../support'); |
| |
| /* Native method references for those with the same name as other `lodash` methods. */ |
| var nativeKeys = getNative(Object, 'keys'); |
| |
| /** |
| * Creates an array of the own enumerable property names of `object`. |
| * |
| * **Note:** Non-object values are coerced to objects. See the |
| * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) |
| * for more details. |
| * |
| * @static |
| * @memberOf _ |
| * @category Object |
| * @param {Object} object The object to query. |
| * @returns {Array} Returns the array of property names. |
| * @example |
| * |
| * function Foo() { |
| * this.a = 1; |
| * this.b = 2; |
| * } |
| * |
| * Foo.prototype.c = 3; |
| * |
| * _.keys(new Foo); |
| * // => ['a', 'b'] (iteration order is not guaranteed) |
| * |
| * _.keys('hi'); |
| * // => ['0', '1'] |
| */ |
| var keys = !nativeKeys ? shimKeys : function(object) { |
| var Ctor = object == null ? undefined : object.constructor; |
| if ((typeof Ctor == 'function' && Ctor.prototype === object) || |
| (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) { |
| return shimKeys(object); |
| } |
| return isObject(object) ? nativeKeys(object) : []; |
| }; |
| |
| module.exports = keys; |
| |
| },{"../internal/getNative":114,"../internal/isArrayLike":119,"../internal/shimKeys":134,"../lang/isObject":144,"../support":153}],150:[function(require,module,exports){ |
| var arrayEach = require('../internal/arrayEach'), |
| isArguments = require('../lang/isArguments'), |
| isArray = require('../lang/isArray'), |
| isFunction = require('../lang/isFunction'), |
| isIndex = require('../internal/isIndex'), |
| isLength = require('../internal/isLength'), |
| isObject = require('../lang/isObject'), |
| isString = require('../lang/isString'), |
| support = require('../support'); |
| |
| /** `Object#toString` result references. */ |
| var arrayTag = '[object Array]', |
| boolTag = '[object Boolean]', |
| dateTag = '[object Date]', |
| errorTag = '[object Error]', |
| funcTag = '[object Function]', |
| numberTag = '[object Number]', |
| objectTag = '[object Object]', |
| regexpTag = '[object RegExp]', |
| stringTag = '[object String]'; |
| |
| /** Used to fix the JScript `[[DontEnum]]` bug. */ |
| var shadowProps = [ |
| 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', |
| 'toLocaleString', 'toString', 'valueOf' |
| ]; |
| |
| /** Used for native method references. */ |
| var errorProto = Error.prototype, |
| objectProto = Object.prototype, |
| stringProto = String.prototype; |
| |
| /** Used to check objects for own properties. */ |
| var hasOwnProperty = objectProto.hasOwnProperty; |
| |
| /** |
| * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
| * of values. |
| */ |
| var objToString = objectProto.toString; |
| |
| /** Used to avoid iterating over non-enumerable properties in IE < 9. */ |
| var nonEnumProps = {}; |
| nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; |
| nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true }; |
| nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true }; |
| nonEnumProps[objectTag] = { 'constructor': true }; |
| |
| arrayEach(shadowProps, function(key) { |
| for (var tag in nonEnumProps) { |
| if (hasOwnProperty.call(nonEnumProps, tag)) { |
| var props = nonEnumProps[tag]; |
| props[key] = hasOwnProperty.call(props, key); |
| } |
| } |
| }); |
| |
| /** |
| * Creates an array of the own and inherited enumerable property names of `object`. |
| * |
| * **Note:** Non-object values are coerced to objects. |
| * |
| * @static |
| * @memberOf _ |
| * @category Object |
| * @param {Object} object The object to query. |
| * @returns {Array} Returns the array of property names. |
| * @example |
| * |
| * function Foo() { |
| * this.a = 1; |
| * this.b = 2; |
| * } |
| * |
| * Foo.prototype.c = 3; |
| * |
| * _.keysIn(new Foo); |
| * // => ['a', 'b', 'c'] (iteration order is not guaranteed) |
| */ |
| function keysIn(object) { |
| if (object == null) { |
| return []; |
| } |
| if (!isObject(object)) { |
| object = Object(object); |
| } |
| var length = object.length; |
| |
| length = (length && isLength(length) && |
| (isArray(object) || isArguments(object) || isString(object)) && length) || 0; |
| |
| var Ctor = object.constructor, |
| index = -1, |
| proto = (isFunction(Ctor) && Ctor.prototype) || objectProto, |
| isProto = proto === object, |
| result = Array(length), |
| skipIndexes = length > 0, |
| skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error), |
| skipProto = support.enumPrototypes && isFunction(object); |
| |
| while (++index < length) { |
| result[index] = (index + ''); |
| } |
| // lodash skips the `constructor` property when it infers it's iterating |
| // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]` |
| // attribute of an existing property and the `constructor` property of a |
| // prototype defaults to non-enumerable. |
| for (var key in object) { |
| if (!(skipProto && key == 'prototype') && |
| !(skipErrorProps && (key == 'message' || key == 'name')) && |
| !(skipIndexes && isIndex(key, length)) && |
| !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { |
| result.push(key); |
| } |
| } |
| if (support.nonEnumShadows && object !== objectProto) { |
| var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)), |
| nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag]; |
| |
| if (tag == objectTag) { |
| proto = objectProto; |
| } |
| length = shadowProps.length; |
| while (length--) { |
| key = shadowProps[length]; |
| var nonEnum = nonEnums[key]; |
| if (!(isProto && nonEnum) && |
| (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) { |
| result.push(key); |
| } |
| } |
| } |
| return result; |
| } |
| |
| module.exports = keysIn; |
| |
| },{"../internal/arrayEach":63,"../internal/isIndex":121,"../internal/isLength":125,"../lang/isArguments":139,"../lang/isArray":140,"../lang/isFunction":142,"../lang/isObject":144,"../lang/isString":146,"../support":153}],151:[function(require,module,exports){ |
| var keys = require('./keys'), |
| toObject = require('../internal/toObject'); |
| |
| /** |
| * Creates a two dimensional array of the key-value pairs for `object`, |
| * e.g. `[[key1, value1], [key2, value2]]`. |
| * |
| * @static |
| * @memberOf _ |
| * @category Object |
| * @param {Object} object The object to query. |
| * @returns {Array} Returns the new array of key-value pairs. |
| * @example |
| * |
| * _.pairs({ 'barney': 36, 'fred': 40 }); |
| * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) |
| */ |
| function pairs(object) { |
| object = toObject(object); |
| |
| var index = -1, |
| props = keys(object), |
| length = props.length, |
| result = Array(length); |
| |
| while (++index < length) { |
| var key = props[index]; |
| result[index] = [key, object[key]]; |
| } |
| return result; |
| } |
| |
| module.exports = pairs; |
| |
| },{"../internal/toObject":135,"./keys":149}],152:[function(require,module,exports){ |
| var baseValues = require('../internal/baseValues'), |
| keys = require('./keys'); |
| |
| /** |
| * Creates an array of the own enumerable property values of `object`. |
| * |
| * **Note:** Non-object values are coerced to objects. |
| * |
| * @static |
| * @memberOf _ |
| * @category Object |
| * @param {Object} object The object to query. |
| * @returns {Array} Returns the array of property values. |
| * @example |
| * |
| * function Foo() { |
| * this.a = 1; |
| * this.b = 2; |
| * } |
| * |
| * Foo.prototype.c = 3; |
| * |
| * _.values(new Foo); |
| * // => [1, 2] (iteration order is not guaranteed) |
| * |
| * _.values('hi'); |
| * // => ['h', 'i'] |
| */ |
| function values(object) { |
| return baseValues(object, keys(object)); |
| } |
| |
| module.exports = values; |
| |
| },{"../internal/baseValues":91,"./keys":149}],153:[function(require,module,exports){ |
| /** Used for native method references. */ |
| var arrayProto = Array.prototype, |
| errorProto = Error.prototype, |
| objectProto = Object.prototype; |
| |
| /** Native method references. */ |
| var propertyIsEnumerable = objectProto.propertyIsEnumerable, |
| splice = arrayProto.splice; |
| |
| /** |
| * An object environment feature flags. |
| * |
| * @static |
| * @memberOf _ |
| * @type Object |
| */ |
| var support = {}; |
| |
| (function(x) { |
| var Ctor = function() { this.x = x; }, |
| object = { '0': x, 'length': x }, |
| props = []; |
| |
| Ctor.prototype = { 'valueOf': x, 'y': x }; |
| for (var key in new Ctor) { props.push(key); } |
| |
| /** |
| * Detect if `name` or `message` properties of `Error.prototype` are |
| * enumerable by default (IE < 9, Safari < 5.1). |
| * |
| * @memberOf _.support |
| * @type boolean |
| */ |
| support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || |
| propertyIsEnumerable.call(errorProto, 'name'); |
| |
| /** |
| * Detect if `prototype` properties are enumerable by default. |
| * |
| * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 |
| * (if the prototype or a property on the prototype has been set) |
| * incorrectly set the `[[Enumerable]]` value of a function's `prototype` |
| * property to `true`. |
| * |
| * @memberOf _.support |
| * @type boolean |
| */ |
| support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype'); |
| |
| /** |
| * Detect if properties shadowing those on `Object.prototype` are non-enumerable. |
| * |
| * In IE < 9 an object's own properties, shadowing non-enumerable ones, |
| * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug). |
| * |
| * @memberOf _.support |
| * @type boolean |
| */ |
| support.nonEnumShadows = !/valueOf/.test(props); |
| |
| /** |
| * Detect if own properties are iterated after inherited properties (IE < 9). |
| * |
| * @memberOf _.support |
| * @type boolean |
| */ |
| support.ownLast = props[0] != 'x'; |
| |
| /** |
| * Detect if `Array#shift` and `Array#splice` augment array-like objects |
| * correctly. |
| * |
| * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array |
| * `shift()` and `splice()` functions that fail to remove the last element, |
| * `value[0]`, of array-like objects even though the "length" property is |
| * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8, |
| * while `splice()` is buggy regardless of mode in IE < 9. |
| * |
| * @memberOf _.support |
| * @type boolean |
| */ |
| support.spliceObjects = (splice.call(object, 0, 1), !object[0]); |
| |
| /** |
| * Detect lack of support for accessing string characters by index. |
| * |
| * IE < 8 can't access characters by index. IE 8 can only access characters |
| * by index on string literals, not string objects. |
| * |
| * @memberOf _.support |
| * @type boolean |
| */ |
| support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; |
| }(1, 0)); |
| |
| module.exports = support; |
| |
| },{}],154:[function(require,module,exports){ |
| /** |
| * This method returns the first argument provided to it. |
| * |
| * @static |
| * @memberOf _ |
| * @category Utility |
| * @param {*} value Any value. |
| * @returns {*} Returns `value`. |
| * @example |
| * |
| * var object = { 'user': 'fred' }; |
| * |
| * _.identity(object) === object; |
| * // => true |
| */ |
| function identity(value) { |
| return value; |
| } |
| |
| module.exports = identity; |
| |
| },{}],155:[function(require,module,exports){ |
| /** |
| * A no-operation function that returns `undefined` regardless of the |
| * arguments it receives. |
| * |
| * @static |
| * @memberOf _ |
| * @category Utility |
| * @example |
| * |
| * var object = { 'user': 'fred' }; |
| * |
| * _.noop(object) === undefined; |
| * // => true |
| */ |
| function noop() { |
| // No operation performed. |
| } |
| |
| module.exports = noop; |
| |
| },{}],156:[function(require,module,exports){ |
| var baseProperty = require('../internal/baseProperty'), |
| basePropertyDeep = require('../internal/basePropertyDeep'), |
| isKey = require('../internal/isKey'); |
| |
| /** |
| * Creates a function that returns the property value at `path` on a |
| * given object. |
| * |
| * @static |
| * @memberOf _ |
| * @category Utility |
| * @param {Array|string} path The path of the property to get. |
| * @returns {Function} Returns the new function. |
| * @example |
| * |
| * var objects = [ |
| * { 'a': { 'b': { 'c': 2 } } }, |
| * { 'a': { 'b': { 'c': 1 } } } |
| * ]; |
| * |
| * _.map(objects, _.property('a.b.c')); |
| * // => [2, 1] |
| * |
| * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); |
| * // => [1, 2] |
| */ |
| function property(path) { |
| return isKey(path) ? baseProperty(path) : basePropertyDeep(path); |
| } |
| |
| module.exports = property; |
| |
| },{"../internal/baseProperty":86,"../internal/basePropertyDeep":87,"../internal/isKey":123}],157:[function(require,module,exports){ |
| (function (process){ |
| // vim:ts=4:sts=4:sw=4: |
| /*! |
| * |
| * Copyright 2009-2012 Kris Kowal under the terms of the MIT |
| * license found at http://github.com/kriskowal/q/raw/master/LICENSE |
| * |
| * With parts by Tyler Close |
| * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found |
| * at http://www.opensource.org/licenses/mit-license.html |
| * Forked at ref_send.js version: 2009-05-11 |
| * |
| * With parts by Mark Miller |
| * Copyright (C) 2011 Google 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. |
| * |
| */ |
| |
| (function (definition) { |
| "use strict"; |
| |
| // This file will function properly as a <script> tag, or a module |
| // using CommonJS and NodeJS or RequireJS module formats. In |
| // Common/Node/RequireJS, the module exports the Q API and when |
| // executed as a simple <script>, it creates a Q global instead. |
| |
| // Montage Require |
| if (typeof bootstrap === "function") { |
| bootstrap("promise", definition); |
| |
| // CommonJS |
| } else if (typeof exports === "object" && typeof module === "object") { |
| module.exports = definition(); |
| |
| // RequireJS |
| } else if (typeof define === "function" && define.amd) { |
| define(definition); |
| |
| // SES (Secure EcmaScript) |
| } else if (typeof ses !== "undefined") { |
| if (!ses.ok()) { |
| return; |
| } else { |
| ses.makeQ = definition; |
| } |
| |
| // <script> |
| } else if (typeof window !== "undefined" || typeof self !== "undefined") { |
| // Prefer window over self for add-on scripts. Use self for |
| // non-windowed contexts. |
| var global = typeof window !== "undefined" ? window : self; |
| |
| // Get the `window` object, save the previous Q global |
| // and initialize Q as a global. |
| var previousQ = global.Q; |
| global.Q = definition(); |
| |
| // Add a noConflict function so Q can be removed from the |
| // global namespace. |
| global.Q.noConflict = function () { |
| global.Q = previousQ; |
| return this; |
| }; |
| |
| } else { |
| throw new Error("This environment was not anticipated by Q. Please file a bug."); |
| } |
| |
| })(function () { |
| "use strict"; |
| |
| var hasStacks = false; |
| try { |
| throw new Error(); |
| } catch (e) { |
| hasStacks = !!e.stack; |
| } |
| |
| // All code after this point will be filtered from stack traces reported |
| // by Q. |
| var qStartingLine = captureLine(); |
| var qFileName; |
| |
| // shims |
| |
| // used for fallback in "allResolved" |
| var noop = function () {}; |
| |
| // Use the fastest possible means to execute a task in a future turn |
| // of the event loop. |
| var nextTick =(function () { |
| // linked list of tasks (single, with head node) |
| var head = {task: void 0, next: null}; |
| var tail = head; |
| var flushing = false; |
| var requestTick = void 0; |
| var isNodeJS = false; |
| // queue for late tasks, used by unhandled rejection tracking |
| var laterQueue = []; |
| |
| function flush() { |
| /* jshint loopfunc: true */ |
| var task, domain; |
| |
| while (head.next) { |
| head = head.next; |
| task = head.task; |
| head.task = void 0; |
| domain = head.domain; |
| |
| if (domain) { |
| head.domain = void 0; |
| domain.enter(); |
| } |
| runSingle(task, domain); |
| |
| } |
| while (laterQueue.length) { |
| task = laterQueue.pop(); |
| runSingle(task); |
| } |
| flushing = false; |
| } |
| // runs a single function in the async queue |
| function runSingle(task, domain) { |
| try { |
| task(); |
| |
| } catch (e) { |
| if (isNodeJS) { |
| // In node, uncaught exceptions are considered fatal errors. |
| // Re-throw them synchronously to interrupt flushing! |
| |
| // Ensure continuation if the uncaught exception is suppressed |
| // listening "uncaughtException" events (as domains does). |
| // Continue in next event to avoid tick recursion. |
| if (domain) { |
| domain.exit(); |
| } |
| setTimeout(flush, 0); |
| if (domain) { |
| domain.enter(); |
| } |
| |
| throw e; |
| |
| } else { |
| // In browsers, uncaught exceptions are not fatal. |
| // Re-throw them asynchronously to avoid slow-downs. |
| setTimeout(function () { |
| throw e; |
| }, 0); |
| } |
| } |
| |
| if (domain) { |
| domain.exit(); |
| } |
| } |
| |
| nextTick = function (task) { |
| tail = tail.next = { |
| task: task, |
| domain: isNodeJS && process.domain, |
| next: null |
| }; |
| |
| if (!flushing) { |
| flushing = true; |
| requestTick(); |
| } |
| }; |
| |
| if (typeof process === "object" && |
| process.toString() === "[object process]" && process.nextTick) { |
| // Ensure Q is in a real Node environment, with a `process.nextTick`. |
| // To see through fake Node environments: |
| // * Mocha test runner - exposes a `process` global without a `nextTick` |
| // * Browserify - exposes a `process.nexTick` function that uses |
| // `setTimeout`. In this case `setImmediate` is preferred because |
| // it is faster. Browserify's `process.toString()` yields |
| // "[object Object]", while in a real Node environment |
| // `process.nextTick()` yields "[object process]". |
| isNodeJS = true; |
| |
| requestTick = function () { |
| process.nextTick(flush); |
| }; |
| |
| } else if (typeof setImmediate === "function") { |
| // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate |
| if (typeof window !== "undefined") { |
| requestTick = setImmediate.bind(window, flush); |
| } else { |
| requestTick = function () { |
| setImmediate(flush); |
| }; |
| } |
| |
| } else if (typeof MessageChannel !== "undefined") { |
| // modern browsers |
| // http://www.nonblocking.io/2011/06/windownexttick.html |
| var channel = new MessageChannel(); |
| // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create |
| // working message ports the first time a page loads. |
| channel.port1.onmessage = function () { |
| requestTick = requestPortTick; |
| channel.port1.onmessage = flush; |
| flush(); |
| }; |
| var requestPortTick = function () { |
| // Opera requires us to provide a message payload, regardless of |
| // whether we use it. |
| channel.port2.postMessage(0); |
| }; |
| requestTick = function () { |
| setTimeout(flush, 0); |
| requestPortTick(); |
| }; |
| |
| } else { |
| // old browsers |
| requestTick = function () { |
| setTimeout(flush, 0); |
| }; |
| } |
| // runs a task after all other tasks have been run |
| // this is useful for unhandled rejection tracking that needs to happen |
| // after all `then`d tasks have been run. |
| nextTick.runAfter = function (task) { |
| laterQueue.push(task); |
| if (!flushing) { |
| flushing = true; |
| requestTick(); |
| } |
| }; |
| return nextTick; |
| })(); |
| |
| // Attempt to make generics safe in the face of downstream |
| // modifications. |
| // There is no situation where this is necessary. |
| // If you need a security guarantee, these primordials need to be |
| // deeply frozen anyway, and if you don’t need a security guarantee, |
| // this is just plain paranoid. |
| // However, this **might** have the nice side-effect of reducing the size of |
| // the minified code by reducing x.call() to merely x() |
| // See Mark Miller’s explanation of what this does. |
| // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming |
| var call = Function.call; |
| function uncurryThis(f) { |
| return function () { |
| return call.apply(f, arguments); |
| }; |
| } |
| // This is equivalent, but slower: |
| // uncurryThis = Function_bind.bind(Function_bind.call); |
| // http://jsperf.com/uncurrythis |
| |
| var array_slice = uncurryThis(Array.prototype.slice); |
| |
| var array_reduce = uncurryThis( |
| Array.prototype.reduce || function (callback, basis) { |
| var index = 0, |
| length = this.length; |
| // concerning the initial value, if one is not provided |
| if (arguments.length === 1) { |
| // seek to the first value in the array, accounting |
| // for the possibility that is is a sparse array |
| do { |
| if (index in this) { |
| basis = this[index++]; |
| break; |
| } |
| if (++index >= length) { |
| throw new TypeError(); |
| } |
| } while (1); |
| } |
| // reduce |
| for (; index < length; index++) { |
| // account for the possibility that the array is sparse |
| if (index in this) { |
| basis = callback(basis, this[index], index); |
| } |
| } |
| return basis; |
| } |
| ); |
| |
| var array_indexOf = uncurryThis( |
| Array.prototype.indexOf || function (value) { |
| // not a very good shim, but good enough for our one use of it |
| for (var i = 0; i < this.length; i++) { |
| if (this[i] === value) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| ); |
| |
| var array_map = uncurryThis( |
| Array.prototype.map || function (callback, thisp) { |
| var self = this; |
| var collect = []; |
| array_reduce(self, function (undefined, value, index) { |
| collect.push(callback.call(thisp, value, index, self)); |
| }, void 0); |
| return collect; |
| } |
| ); |
| |
| var object_create = Object.create || function (prototype) { |
| function Type() { } |
| Type.prototype = prototype; |
| return new Type(); |
| }; |
| |
| var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty); |
| |
| var object_keys = Object.keys || function (object) { |
| var keys = []; |
| for (var key in object) { |
| if (object_hasOwnProperty(object, key)) { |
| keys.push(key); |
| } |
| } |
| return keys; |
| }; |
| |
| var object_toString = uncurryThis(Object.prototype.toString); |
| |
| function isObject(value) { |
| return value === Object(value); |
| } |
| |
| // generator related shims |
| |
| // FIXME: Remove this function once ES6 generators are in SpiderMonkey. |
| function isStopIteration(exception) { |
| return ( |
| object_toString(exception) === "[object StopIteration]" || |
| exception instanceof QReturnValue |
| ); |
| } |
| |
| // FIXME: Remove this helper and Q.return once ES6 generators are in |
| // SpiderMonkey. |
| var QReturnValue; |
| if (typeof ReturnValue !== "undefined") { |
| QReturnValue = ReturnValue; |
| } else { |
| QReturnValue = function (value) { |
| this.value = value; |
| }; |
| } |
| |
| // long stack traces |
| |
| var STACK_JUMP_SEPARATOR = "From previous event:"; |
| |
| function makeStackTraceLong(error, promise) { |
| // If possible, transform the error stack trace by removing Node and Q |
| // cruft, then concatenating with the stack trace of `promise`. See #57. |
| if (hasStacks && |
| promise.stack && |
| typeof error === "object" && |
| error !== null && |
| error.stack && |
| error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1 |
| ) { |
| var stacks = []; |
| for (var p = promise; !!p; p = p.source) { |
| if (p.stack) { |
| stacks.unshift(p.stack); |
| } |
| } |
| stacks.unshift(error.stack); |
| |
| var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n"); |
| error.stack = filterStackString(concatedStacks); |
| } |
| } |
| |
| function filterStackString(stackString) { |
| var lines = stackString.split("\n"); |
| var desiredLines = []; |
| for (var i = 0; i < lines.length; ++i) { |
| var line = lines[i]; |
| |
| if (!isInternalFrame(line) && !isNodeFrame(line) && line) { |
| desiredLines.push(line); |
| } |
| } |
| return desiredLines.join("\n"); |
| } |
| |
| function isNodeFrame(stackLine) { |
| return stackLine.indexOf("(module.js:") !== -1 || |
| stackLine.indexOf("(node.js:") !== -1; |
| } |
| |
| function getFileNameAndLineNumber(stackLine) { |
| // Named functions: "at functionName (filename:lineNumber:columnNumber)" |
| // In IE10 function name can have spaces ("Anonymous function") O_o |
| var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine); |
| if (attempt1) { |
| return [attempt1[1], Number(attempt1[2])]; |
| } |
| |
| // Anonymous functions: "at filename:lineNumber:columnNumber" |
| var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine); |
| if (attempt2) { |
| return [attempt2[1], Number(attempt2[2])]; |
| } |
| |
| // Firefox style: "function@filename:lineNumber or @filename:lineNumber" |
| var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine); |
| if (attempt3) { |
| return [attempt3[1], Number(attempt3[2])]; |
| } |
| } |
| |
| function isInternalFrame(stackLine) { |
| var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine); |
| |
| if (!fileNameAndLineNumber) { |
| return false; |
| } |
| |
| var fileName = fileNameAndLineNumber[0]; |
| var lineNumber = fileNameAndLineNumber[1]; |
| |
| return fileName === qFileName && |
| lineNumber >= qStartingLine && |
| lineNumber <= qEndingLine; |
| } |
| |
| // discover own file name and line number range for filtering stack |
| // traces |
| function captureLine() { |
| if (!hasStacks) { |
| return; |
| } |
| |
| try { |
| throw new Error(); |
| } catch (e) { |
| var lines = e.stack.split("\n"); |
| var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2]; |
| var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine); |
| if (!fileNameAndLineNumber) { |
| return; |
| } |
| |
| qFileName = fileNameAndLineNumber[0]; |
| return fileNameAndLineNumber[1]; |
| } |
| } |
| |
| function deprecate(callback, name, alternative) { |
| return function () { |
| if (typeof console !== "undefined" && |
| typeof console.warn === "function") { |
| console.warn(name + " is deprecated, use " + alternative + |
| " instead.", new Error("").stack); |
| } |
| return callback.apply(callback, arguments); |
| }; |
| } |
| |
| // end of shims |
| // beginning of real work |
| |
| /** |
| * Constructs a promise for an immediate reference, passes promises through, or |
| * coerces promises from different systems. |
| * @param value immediate reference or promise |
| */ |
| function Q(value) { |
| // If the object is already a Promise, return it directly. This enables |
| // the resolve function to both be used to created references from objects, |
| // but to tolerably coerce non-promises to promises. |
| if (value instanceof Promise) { |
| return value; |
| } |
| |
| // assimilate thenables |
| if (isPromiseAlike(value)) { |
| return coerce(value); |
| } else { |
| return fulfill(value); |
| } |
| } |
| Q.resolve = Q; |
| |
| /** |
| * Performs a task in a future turn of the event loop. |
| * @param {Function} task |
| */ |
| Q.nextTick = nextTick; |
| |
| /** |
| * Controls whether or not long stack traces will be on |
| */ |
| Q.longStackSupport = false; |
| |
| // enable long stacks if Q_DEBUG is set |
| if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) { |
| Q.longStackSupport = true; |
| } |
| |
| /** |
| * Constructs a {promise, resolve, reject} object. |
| * |
| * `resolve` is a callback to invoke with a more resolved value for the |
| * promise. To fulfill the promise, invoke `resolve` with any value that is |
| * not a thenable. To reject the promise, invoke `resolve` with a rejected |
| * thenable, or invoke `reject` with the reason directly. To resolve the |
| * promise to another thenable, thus putting it in the same state, invoke |
| * `resolve` with that other thenable. |
| */ |
| Q.defer = defer; |
| function defer() { |
| // if "messages" is an "Array", that indicates that the promise has not yet |
| // been resolved. If it is "undefined", it has been resolved. Each |
| // element of the messages array is itself an array of complete arguments to |
| // forward to the resolved promise. We coerce the resolution value to a |
| // promise using the `resolve` function because it handles both fully |
| // non-thenable values and other thenables gracefully. |
| var messages = [], progressListeners = [], resolvedPromise; |
| |
| var deferred = object_create(defer.prototype); |
| var promise = object_create(Promise.prototype); |
| |
| promise.promiseDispatch = function (resolve, op, operands) { |
| var args = array_slice(arguments); |
| if (messages) { |
| messages.push(args); |
| if (op === "when" && operands[1]) { // progress operand |
| progressListeners.push(operands[1]); |
| } |
| } else { |
| Q.nextTick(function () { |
| resolvedPromise.promiseDispatch.apply(resolvedPromise, args); |
| }); |
| } |
| }; |
| |
| // XXX deprecated |
| promise.valueOf = function () { |
| if (messages) { |
| return promise; |
| } |
| var nearerValue = nearer(resolvedPromise); |
| if (isPromise(nearerValue)) { |
| resolvedPromise = nearerValue; // shorten chain |
| } |
| return nearerValue; |
| }; |
| |
| promise.inspect = function () { |
| if (!resolvedPromise) { |
| return { state: "pending" }; |
| } |
| return resolvedPromise.inspect(); |
| }; |
| |
| if (Q.longStackSupport && hasStacks) { |
| try { |
| throw new Error(); |
| } catch (e) { |
| // NOTE: don't try to use `Error.captureStackTrace` or transfer the |
| // accessor around; that causes memory leaks as per GH-111. Just |
| // reify the stack trace as a string ASAP. |
| // |
| // At the same time, cut off the first line; it's always just |
| // "[object Promise]\n", as per the `toString`. |
| promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1); |
| } |
| } |
| |
| // NOTE: we do the checks for `resolvedPromise` in each method, instead of |
| // consolidating them into `become`, since otherwise we'd create new |
| // promises with the lines `become(whatever(value))`. See e.g. GH-252. |
| |
| function become(newPromise) { |
| resolvedPromise = newPromise; |
| promise.source = newPromise; |
| |
| array_reduce(messages, function (undefined, message) { |
| Q.nextTick(function () { |
| newPromise.promiseDispatch.apply(newPromise, message); |
| }); |
| }, void 0); |
| |
| messages = void 0; |
| progressListeners = void 0; |
| } |
| |
| deferred.promise = promise; |
| deferred.resolve = function (value) { |
| if (resolvedPromise) { |
| return; |
| } |
| |
| become(Q(value)); |
| }; |
| |
| deferred.fulfill = function (value) { |
| if (resolvedPromise) { |
| return; |
| } |
| |
| become(fulfill(value)); |
| }; |
| deferred.reject = function (reason) { |
| if (resolvedPromise) { |
| return; |
| } |
| |
| become(reject(reason)); |
| }; |
| deferred.notify = function (progress) { |
| if (resolvedPromise) { |
| return; |
| } |
| |
| array_reduce(progressListeners, function (undefined, progressListener) { |
| Q.nextTick(function () { |
| progressListener(progress); |
| }); |
| }, void 0); |
| }; |
| |
| return deferred; |
| } |
| |
| /** |
| * Creates a Node-style callback that will resolve or reject the deferred |
| * promise. |
| * @returns a nodeback |
| */ |
| defer.prototype.makeNodeResolver = function () { |
| var self = this; |
| return function (error, value) { |
| if (error) { |
| self.reject(error); |
| } else if (arguments.length > 2) { |
| self.resolve(array_slice(arguments, 1)); |
| } else { |
| self.resolve(value); |
| } |
| }; |
| }; |
| |
| /** |
| * @param resolver {Function} a function that returns nothing and accepts |
| * the resolve, reject, and notify functions for a deferred. |
| * @returns a promise that may be resolved with the given resolve and reject |
| * functions, or rejected by a thrown exception in resolver |
| */ |
| Q.Promise = promise; // ES6 |
| Q.promise = promise; |
| function promise(resolver) { |
| if (typeof resolver !== "function") { |
| throw new TypeError("resolver must be a function."); |
| } |
| var deferred = defer(); |
| try { |
| resolver(deferred.resolve, deferred.reject, deferred.notify); |
| } catch (reason) { |
| deferred.reject(reason); |
| } |
| return deferred.promise; |
| } |
| |
| promise.race = race; // ES6 |
| promise.all = all; // ES6 |
| promise.reject = reject; // ES6 |
| promise.resolve = Q; // ES6 |
| |
| // XXX experimental. This method is a way to denote that a local value is |
| // serializable and should be immediately dispatched to a remote upon request, |
| // instead of passing a reference. |
| Q.passByCopy = function (object) { |
| //freeze(object); |
| //passByCopies.set(object, true); |
| return object; |
| }; |
| |
| Promise.prototype.passByCopy = function () { |
| //freeze(object); |
| //passByCopies.set(object, true); |
| return this; |
| }; |
| |
| /** |
| * If two promises eventually fulfill to the same value, promises that value, |
| * but otherwise rejects. |
| * @param x {Any*} |
| * @param y {Any*} |
| * @returns {Any*} a promise for x and y if they are the same, but a rejection |
| * otherwise. |
| * |
| */ |
| Q.join = function (x, y) { |
| return Q(x).join(y); |
| }; |
| |
| Promise.prototype.join = function (that) { |
| return Q([this, that]).spread(function (x, y) { |
| if (x === y) { |
| // TODO: "===" should be Object.is or equiv |
| return x; |
| } else { |
| throw new Error("Can't join: not the same: " + x + " " + y); |
| } |
| }); |
| }; |
| |
| /** |
| * Returns a promise for the first of an array of promises to become settled. |
| * @param answers {Array[Any*]} promises to race |
| * @returns {Any*} the first promise to be settled |
| */ |
| Q.race = race; |
| function race(answerPs) { |
| return promise(function (resolve, reject) { |
| // Switch to this once we can assume at least ES5 |
| // answerPs.forEach(function (answerP) { |
| // Q(answerP).then(resolve, reject); |
| // }); |
| // Use this in the meantime |
| for (var i = 0, len = answerPs.length; i < len; i++) { |
| Q(answerPs[i]).then(resolve, reject); |
| } |
| }); |
| } |
| |
| Promise.prototype.race = function () { |
| return this.then(Q.race); |
| }; |
| |
| /** |
| * Constructs a Promise with a promise descriptor object and optional fallback |
| * function. The descriptor contains methods like when(rejected), get(name), |
| * set(name, value), post(name, args), and delete(name), which all |
| * return either a value, a promise for a value, or a rejection. The fallback |
| * accepts the operation name, a resolver, and any further arguments that would |
| * have been forwarded to the appropriate method above had a method been |
| * provided with the proper name. The API makes no guarantees about the nature |
| * of the returned object, apart from that it is usable whereever promises are |
| * bought and sold. |
| */ |
| Q.makePromise = Promise; |
| function Promise(descriptor, fallback, inspect) { |
| if (fallback === void 0) { |
| fallback = function (op) { |
| return reject(new Error( |
| "Promise does not support operation: " + op |
| )); |
| }; |
| } |
| if (inspect === void 0) { |
| inspect = function () { |
| return {state: "unknown"}; |
| }; |
| } |
| |
| var promise = object_create(Promise.prototype); |
| |
| promise.promiseDispatch = function (resolve, op, args) { |
| var result; |
| try { |
| if (descriptor[op]) { |
| result = descriptor[op].apply(promise, args); |
| } else { |
| result = fallback.call(promise, op, args); |
| } |
| } catch (exception) { |
| result = reject(exception); |
| } |
| if (resolve) { |
| resolve(result); |
| } |
| }; |
| |
| promise.inspect = inspect; |
| |
| // XXX deprecated `valueOf` and `exception` support |
| if (inspect) { |
| var inspected = inspect(); |
| if (inspected.state === "rejected") { |
| promise.exception = inspected.reason; |
| } |
| |
| promise.valueOf = function () { |
| var inspected = inspect(); |
| if (inspected.state === "pending" || |
| inspected.state === "rejected") { |
| return promise; |
| } |
| return inspected.value; |
| }; |
| } |
| |
| return promise; |
| } |
| |
| Promise.prototype.toString = function () { |
| return "[object Promise]"; |
| }; |
| |
| Promise.prototype.then = function (fulfilled, rejected, progressed) { |
| var self = this; |
| var deferred = defer(); |
| var done = false; // ensure the untrusted promise makes at most a |
| // single call to one of the callbacks |
| |
| function _fulfilled(value) { |
| try { |
| return typeof fulfilled === "function" ? fulfilled(value) : value; |
| } catch (exception) { |
| return reject(exception); |
| } |
| } |
| |
| function _rejected(exception) { |
| if (typeof rejected === "function") { |
| makeStackTraceLong(exception, self); |
| try { |
| return rejected(exception); |
| } catch (newException) { |
| return reject(newException); |
| } |
| } |
| return reject(exception); |
| } |
| |
| function _progressed(value) { |
| return typeof progressed === "function" ? progressed(value) : value; |
| } |
| |
| Q.nextTick(function () { |
| self.promiseDispatch(function (value) { |
| if (done) { |
| return; |
| } |
| done = true; |
| |
| deferred.resolve(_fulfilled(value)); |
| }, "when", [function (exception) { |
| if (done) { |
| return; |
| } |
| done = true; |
| |
| deferred.resolve(_rejected(exception)); |
| }]); |
| }); |
| |
| // Progress propagator need to be attached in the current tick. |
| self.promiseDispatch(void 0, "when", [void 0, function (value) { |
| var newValue; |
| var threw = false; |
| try { |
| newValue = _progressed(value); |
| } catch (e) { |
| threw = true; |
| if (Q.onerror) { |
| Q.onerror(e); |
| } else { |
| throw e; |
| } |
| } |
| |
| if (!threw) { |
| deferred.notify(newValue); |
| } |
| }]); |
| |
| return deferred.promise; |
| }; |
| |
| Q.tap = function (promise, callback) { |
| return Q(promise).tap(callback); |
| }; |
| |
| /** |
| * Works almost like "finally", but not called for rejections. |
| * Original resolution value is passed through callback unaffected. |
| * Callback may return a promise that will be awaited for. |
| * @param {Function} callback |
| * @returns {Q.Promise} |
| * @example |
| * doSomething() |
| * .then(...) |
| * .tap(console.log) |
| * .then(...); |
| */ |
| Promise.prototype.tap = function (callback) { |
| callback = Q(callback); |
| |
| return this.then(function (value) { |
| return callback.fcall(value).thenResolve(value); |
| }); |
| }; |
| |
| /** |
| * Registers an observer on a promise. |
| * |
| * Guarantees: |
| * |
| * 1. that fulfilled and rejected will be called only once. |
| * 2. that either the fulfilled callback or the rejected callback will be |
| * called, but not both. |
| * 3. that fulfilled and rejected will not be called in this turn. |
| * |
| * @param value promise or immediate reference to observe |
| * @param fulfilled function to be called with the fulfilled value |
| * @param rejected function to be called with the rejection exception |
| * @param progressed function to be called on any progress notifications |
| * @return promise for the return value from the invoked callback |
| */ |
| Q.when = when; |
| function when(value, fulfilled, rejected, progressed) { |
| return Q(value).then(fulfilled, rejected, progressed); |
| } |
| |
| Promise.prototype.thenResolve = function (value) { |
| return this.then(function () { return value; }); |
| }; |
| |
| Q.thenResolve = function (promise, value) { |
| return Q(promise).thenResolve(value); |
| }; |
| |
| Promise.prototype.thenReject = function (reason) { |
| return this.then(function () { throw reason; }); |
| }; |
| |
| Q.thenReject = function (promise, reason) { |
| return Q(promise).thenReject(reason); |
| }; |
| |
| /** |
| * If an object is not a promise, it is as "near" as possible. |
| * If a promise is rejected, it is as "near" as possible too. |
| * If it’s a fulfilled promise, the fulfillment value is nearer. |
| * If it’s a deferred promise and the deferred has been resolved, the |
| * resolution is "nearer". |
| * @param object |
| * @returns most resolved (nearest) form of the object |
| */ |
| |
| // XXX should we re-do this? |
| Q.nearer = nearer; |
| function nearer(value) { |
| if (isPromise(value)) { |
| var inspected = value.inspect(); |
| if (inspected.state === "fulfilled") { |
| return inspected.value; |
| } |
| } |
| return value; |
| } |
| |
| /** |
| * @returns whether the given object is a promise. |
| * Otherwise it is a fulfilled value. |
| */ |
| Q.isPromise = isPromise; |
| function isPromise(object) { |
| return object instanceof Promise; |
| } |
| |
| Q.isPromiseAlike = isPromiseAlike; |
| function isPromiseAlike(object) { |
| return isObject(object) && typeof object.then === "function"; |
| } |
| |
| /** |
| * @returns whether the given object is a pending promise, meaning not |
| * fulfilled or rejected. |
| */ |
| Q.isPending = isPending; |
| function isPending(object) { |
| return isPromise(object) && object.inspect().state === "pending"; |
| } |
| |
| Promise.prototype.isPending = function () { |
| return this.inspect().state === "pending"; |
| }; |
| |
| /** |
| * @returns whether the given object is a value or fulfilled |
| * promise. |
| */ |
| Q.isFulfilled = isFulfilled; |
| function isFulfilled(object) { |
| return !isPromise(object) || object.inspect().state === "fulfilled"; |
| } |
| |
| Promise.prototype.isFulfilled = function () { |
| return this.inspect().state === "fulfilled"; |
| }; |
| |
| /** |
| * @returns whether the given object is a rejected promise. |
| */ |
| Q.isRejected = isRejected; |
| function isRejected(object) { |
| return isPromise(object) && object.inspect().state === "rejected"; |
| } |
| |
| Promise.prototype.isRejected = function () { |
| return this.inspect().state === "rejected"; |
| }; |
| |
| //// BEGIN UNHANDLED REJECTION TRACKING |
| |
| // This promise library consumes exceptions thrown in handlers so they can be |
| // handled by a subsequent promise. The exceptions get added to this array when |
| // they are created, and removed when they are handled. Note that in ES6 or |
| // shimmed environments, this would naturally be a `Set`. |
| var unhandledReasons = []; |
| var unhandledRejections = []; |
| var reportedUnhandledRejections = []; |
| var trackUnhandledRejections = true; |
| |
| function resetUnhandledRejections() { |
| unhandledReasons.length = 0; |
| unhandledRejections.length = 0; |
| |
| if (!trackUnhandledRejections) { |
| trackUnhandledRejections = true; |
| } |
| } |
| |
| function trackRejection(promise, reason) { |
| if (!trackUnhandledRejections) { |
| return; |
| } |
| if (typeof process === "object" && typeof process.emit === "function") { |
| Q.nextTick.runAfter(function () { |
| if (array_indexOf(unhandledRejections, promise) !== -1) { |
| process.emit("unhandledRejection", reason, promise); |
| reportedUnhandledRejections.push(promise); |
| } |
| }); |
| } |
| |
| unhandledRejections.push(promise); |
| if (reason && typeof reason.stack !== "undefined") { |
| unhandledReasons.push(reason.stack); |
| } else { |
| unhandledReasons.push("(no stack) " + reason); |
| } |
| } |
| |
| function untrackRejection(promise) { |
| if (!trackUnhandledRejections) { |
| return; |
| } |
| |
| var at = array_indexOf(unhandledRejections, promise); |
| if (at !== -1) { |
| if (typeof process === "object" && typeof process.emit === "function") { |
| Q.nextTick.runAfter(function () { |
| var atReport = array_indexOf(reportedUnhandledRejections, promise); |
| if (atReport !== -1) { |
| process.emit("rejectionHandled", unhandledReasons[at], promise); |
| reportedUnhandledRejections.splice(atReport, 1); |
| } |
| }); |
| } |
| unhandledRejections.splice(at, 1); |
| unhandledReasons.splice(at, 1); |
| } |
| } |
| |
| Q.resetUnhandledRejections = resetUnhandledRejections; |
| |
| Q.getUnhandledReasons = function () { |
| // Make a copy so that consumers can't interfere with our internal state. |
| return unhandledReasons.slice(); |
| }; |
| |
| Q.stopUnhandledRejectionTracking = function () { |
| resetUnhandledRejections(); |
| trackUnhandledRejections = false; |
| }; |
| |
| resetUnhandledRejections(); |
| |
| //// END UNHANDLED REJECTION TRACKING |
| |
| /** |
| * Constructs a rejected promise. |
| * @param reason value describing the failure |
| */ |
| Q.reject = reject; |
| function reject(reason) { |
| var rejection = Promise({ |
| "when": function (rejected) { |
| // note that the error has been handled |
| if (rejected) { |
| untrackRejection(this); |
| } |
| return rejected ? rejected(reason) : this; |
| } |
| }, function fallback() { |
| return this; |
| }, function inspect() { |
| return { state: "rejected", reason: reason }; |
| }); |
| |
| // Note that the reason has not been handled. |
| trackRejection(rejection, reason); |
| |
| return rejection; |
| } |
| |
| /** |
| * Constructs a fulfilled promise for an immediate reference. |
| * @param value immediate reference |
| */ |
| Q.fulfill = fulfill; |
| function fulfill(value) { |
| return Promise({ |
| "when": function () { |
| return value; |
| }, |
| "get": function (name) { |
| return value[name]; |
| }, |
| "set": function (name, rhs) { |
| value[name] = rhs; |
| }, |
| "delete": function (name) { |
| delete value[name]; |
| }, |
| "post": function (name, args) { |
| // Mark Miller proposes that post with no name should apply a |
| // promised function. |
| if (name === null || name === void 0) { |
| return value.apply(void 0, args); |
| } else { |
| return value[name].apply(value, args); |
| } |
| }, |
| "apply": function (thisp, args) { |
| return value.apply(thisp, args); |
| }, |
| "keys": function () { |
| return object_keys(value); |
| } |
| }, void 0, function inspect() { |
| return { state: "fulfilled", value: value }; |
| }); |
| } |
| |
| /** |
| * Converts thenables to Q promises. |
| * @param promise thenable promise |
| * @returns a Q promise |
| */ |
| function coerce(promise) { |
| var deferred = defer(); |
| Q.nextTick(function () { |
| try { |
| promise.then(deferred.resolve, deferred.reject, deferred.notify); |
| } catch (exception) { |
| deferred.reject(exception); |
| } |
| }); |
| return deferred.promise; |
| } |
| |
| /** |
| * Annotates an object such that it will never be |
| * transferred away from this process over any promise |
| * communication channel. |
| * @param object |
| * @returns promise a wrapping of that object that |
| * additionally responds to the "isDef" message |
| * without a rejection. |
| */ |
| Q.master = master; |
| function master(object) { |
| return Promise({ |
| "isDef": function () {} |
| }, function fallback(op, args) { |
| return dispatch(object, op, args); |
| }, function () { |
| return Q(object).inspect(); |
| }); |
| } |
| |
| /** |
| * Spreads the values of a promised array of arguments into the |
| * fulfillment callback. |
| * @param fulfilled callback that receives variadic arguments from the |
| * promised array |
| * @param rejected callback that receives the exception if the promise |
| * is rejected. |
| * @returns a promise for the return value or thrown exception of |
| * either callback. |
| */ |
| Q.spread = spread; |
| function spread(value, fulfilled, rejected) { |
| return Q(value).spread(fulfilled, rejected); |
| } |
| |
| Promise.prototype.spread = function (fulfilled, rejected) { |
| return this.all().then(function (array) { |
| return fulfilled.apply(void 0, array); |
| }, rejected); |
| }; |
| |
| /** |
| * The async function is a decorator for generator functions, turning |
| * them into asynchronous generators. Although generators are only part |
| * of the newest ECMAScript 6 drafts, this code does not cause syntax |
| * errors in older engines. This code should continue to work and will |
| * in fact improve over time as the language improves. |
| * |
| * ES6 generators are currently part of V8 version 3.19 with the |
| * --harmony-generators runtime flag enabled. SpiderMonkey has had them |
| * for longer, but under an older Python-inspired form. This function |
| * works on both kinds of generators. |
| * |
| * Decorates a generator function such that: |
| * - it may yield promises |
| * - execution will continue when that promise is fulfilled |
| * - the value of the yield expression will be the fulfilled value |
| * - it returns a promise for the return value (when the generator |
| * stops iterating) |
| * - the decorated function returns a promise for the return value |
| * of the generator or the first rejected promise among those |
| * yielded. |
| * - if an error is thrown in the generator, it propagates through |
| * every following yield until it is caught, or until it escapes |
| * the generator function altogether, and is translated into a |
| * rejection for the promise returned by the decorated generator. |
| */ |
| Q.async = async; |
| function async(makeGenerator) { |
| return function () { |
| // when verb is "send", arg is a value |
| // when verb is "throw", arg is an exception |
| function continuer(verb, arg) { |
| var result; |
| |
| // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only |
| // engine that has a deployed base of browsers that support generators. |
| // However, SM's generators use the Python-inspired semantics of |
| // outdated ES6 drafts. We would like to support ES6, but we'd also |
| // like to make it possible to use generators in deployed browsers, so |
| // we also support Python-style generators. At some point we can remove |
| // this block. |
| |
| if (typeof StopIteration === "undefined") { |
| // ES6 Generators |
| try { |
| result = generator[verb](arg); |
| } catch (exception) { |
| return reject(exception); |
| } |
| if (result.done) { |
| return Q(result.value); |
| } else { |
| return when(result.value, callback, errback); |
| } |
| } else { |
| // SpiderMonkey Generators |
| // FIXME: Remove this case when SM does ES6 generators. |
| try { |
| result = generator[verb](arg); |
| } catch (exception) { |
| if (isStopIteration(exception)) { |
| return Q(exception.value); |
| } else { |
| return reject(exception); |
| } |
| } |
| return when(result, callback, errback); |
| } |
| } |
| var generator = makeGenerator.apply(this, arguments); |
| var callback = continuer.bind(continuer, "next"); |
| var errback = continuer.bind(continuer, "throw"); |
| return callback(); |
| }; |
| } |
| |
| /** |
| * The spawn function is a small wrapper around async that immediately |
| * calls the generator and also ends the promise chain, so that any |
| * unhandled errors are thrown instead of forwarded to the error |
| * handler. This is useful because it's extremely common to run |
| * generators at the top-level to work with libraries. |
| */ |
| Q.spawn = spawn; |
| function spawn(makeGenerator) { |
| Q.done(Q.async(makeGenerator)()); |
| } |
| |
| // FIXME: Remove this interface once ES6 generators are in SpiderMonkey. |
| /** |
| * Throws a ReturnValue exception to stop an asynchronous generator. |
| * |
| * This interface is a stop-gap measure to support generator return |
| * values in older Firefox/SpiderMonkey. In browsers that support ES6 |
| * generators like Chromium 29, just use "return" in your generator |
| * functions. |
| * |
| * @param value the return value for the surrounding generator |
| * @throws ReturnValue exception with the value. |
| * @example |
| * // ES6 style |
| * Q.async(function* () { |
| * var foo = yield getFooPromise(); |
| * var bar = yield getBarPromise(); |
| * return foo + bar; |
| * }) |
| * // Older SpiderMonkey style |
| * Q.async(function () { |
| * var foo = yield getFooPromise(); |
| * var bar = yield getBarPromise(); |
| * Q.return(foo + bar); |
| * }) |
| */ |
| Q["return"] = _return; |
| function _return(value) { |
| throw new QReturnValue(value); |
| } |
| |
| /** |
| * The promised function decorator ensures that any promise arguments |
| * are settled and passed as values (`this` is also settled and passed |
| * as a value). It will also ensure that the result of a function is |
| * always a promise. |
| * |
| * @example |
| * var add = Q.promised(function (a, b) { |
| * return a + b; |
| * }); |
| * add(Q(a), Q(B)); |
| * |
| * @param {function} callback The function to decorate |
| * @returns {function} a function that has been decorated. |
| */ |
| Q.promised = promised; |
| function promised(callback) { |
| return function () { |
| return spread([this, all(arguments)], function (self, args) { |
| return callback.apply(self, args); |
| }); |
| }; |
| } |
| |
| /** |
| * sends a message to a value in a future turn |
| * @param object* the recipient |
| * @param op the name of the message operation, e.g., "when", |
| * @param args further arguments to be forwarded to the operation |
| * @returns result {Promise} a promise for the result of the operation |
| */ |
| Q.dispatch = dispatch; |
| function dispatch(object, op, args) { |
| return Q(object).dispatch(op, args); |
| } |
| |
| Promise.prototype.dispatch = function (op, args) { |
| var self = this; |
| var deferred = defer(); |
| Q.nextTick(function () { |
| self.promiseDispatch(deferred.resolve, op, args); |
| }); |
| return deferred.promise; |
| }; |
| |
| /** |
| * Gets the value of a property in a future turn. |
| * @param object promise or immediate reference for target object |
| * @param name name of property to get |
| * @return promise for the property value |
| */ |
| Q.get = function (object, key) { |
| return Q(object).dispatch("get", [key]); |
| }; |
| |
| Promise.prototype.get = function (key) { |
| return this.dispatch("get", [key]); |
| }; |
| |
| /** |
| * Sets the value of a property in a future turn. |
| * @param object promise or immediate reference for object object |
| * @param name name of property to set |
| * @param value new value of property |
| * @return promise for the return value |
| */ |
| Q.set = function (object, key, value) { |
| return Q(object).dispatch("set", [key, value]); |
| }; |
| |
| Promise.prototype.set = function (key, value) { |
| return this.dispatch("set", [key, value]); |
| }; |
| |
| /** |
| * Deletes a property in a future turn. |
| * @param object promise or immediate reference for target object |
| * @param name name of property to delete |
| * @return promise for the return value |
| */ |
| Q.del = // XXX legacy |
| Q["delete"] = function (object, key) { |
| return Q(object).dispatch("delete", [key]); |
| }; |
| |
| Promise.prototype.del = // XXX legacy |
| Promise.prototype["delete"] = function (key) { |
| return this.dispatch("delete", [key]); |
| }; |
| |
| /** |
| * Invokes a method in a future turn. |
| * @param object promise or immediate reference for target object |
| * @param name name of method to invoke |
| * @param value a value to post, typically an array of |
| * invocation arguments for promises that |
| * are ultimately backed with `resolve` values, |
| * as opposed to those backed with URLs |
| * wherein the posted value can be any |
| * JSON serializable object. |
| * @return promise for the return value |
| */ |
| // bound locally because it is used by other methods |
| Q.mapply = // XXX As proposed by "Redsandro" |
| Q.post = function (object, name, args) { |
| return Q(object).dispatch("post", [name, args]); |
| }; |
| |
| Promise.prototype.mapply = // XXX As proposed by "Redsandro" |
| Promise.prototype.post = function (name, args) { |
| return this.dispatch("post", [name, args]); |
| }; |
| |
| /** |
| * Invokes a method in a future turn. |
| * @param object promise or immediate reference for target object |
| * @param name name of method to invoke |
| * @param ...args array of invocation arguments |
| * @return promise for the return value |
| */ |
| Q.send = // XXX Mark Miller's proposed parlance |
| Q.mcall = // XXX As proposed by "Redsandro" |
| Q.invoke = function (object, name /*...args*/) { |
| return Q(object).dispatch("post", [name, array_slice(arguments, 2)]); |
| }; |
| |
| Promise.prototype.send = // XXX Mark Miller's proposed parlance |
| Promise.prototype.mcall = // XXX As proposed by "Redsandro" |
| Promise.prototype.invoke = function (name /*...args*/) { |
| return this.dispatch("post", [name, array_slice(arguments, 1)]); |
| }; |
| |
| /** |
| * Applies the promised function in a future turn. |
| * @param object promise or immediate reference for target function |
| * @param args array of application arguments |
| */ |
| Q.fapply = function (object, args) { |
| return Q(object).dispatch("apply", [void 0, args]); |
| }; |
| |
| Promise.prototype.fapply = function (args) { |
| return this.dispatch("apply", [void 0, args]); |
| }; |
| |
| /** |
| * Calls the promised function in a future turn. |
| * @param object promise or immediate reference for target function |
| * @param ...args array of application arguments |
| */ |
| Q["try"] = |
| Q.fcall = function (object /* ...args*/) { |
| return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]); |
| }; |
| |
| Promise.prototype.fcall = function (/*...args*/) { |
| return this.dispatch("apply", [void 0, array_slice(arguments)]); |
| }; |
| |
| /** |
| * Binds the promised function, transforming return values into a fulfilled |
| * promise and thrown errors into a rejected one. |
| * @param object promise or immediate reference for target function |
| * @param ...args array of application arguments |
| */ |
| Q.fbind = function (object /*...args*/) { |
| var promise = Q(object); |
| var args = array_slice(arguments, 1); |
| return function fbound() { |
| return promise.dispatch("apply", [ |
| this, |
| args.concat(array_slice(arguments)) |
| ]); |
| }; |
| }; |
| Promise.prototype.fbind = function (/*...args*/) { |
| var promise = this; |
| var args = array_slice(arguments); |
| return function fbound() { |
| return promise.dispatch("apply", [ |
| this, |
| args.concat(array_slice(arguments)) |
| ]); |
| }; |
| }; |
| |
| /** |
| * Requests the names of the owned properties of a promised |
| * object in a future turn. |
| * @param object promise or immediate reference for target object |
| * @return promise for the keys of the eventually settled object |
| */ |
| Q.keys = function (object) { |
| return Q(object).dispatch("keys", []); |
| }; |
| |
| Promise.prototype.keys = function () { |
| return this.dispatch("keys", []); |
| }; |
| |
| /** |
| * Turns an array of promises into a promise for an array. If any of |
| * the promises gets rejected, the whole array is rejected immediately. |
| * @param {Array*} an array (or promise for an array) of values (or |
| * promises for values) |
| * @returns a promise for an array of the corresponding values |
| */ |
| // By Mark Miller |
| // http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled |
| Q.all = all; |
| function all(promises) { |
| return when(promises, function (promises) { |
| var pendingCount = 0; |
| var deferred = defer(); |
| array_reduce(promises, function (undefined, promise, index) { |
| var snapshot; |
| if ( |
| isPromise(promise) && |
| (snapshot = promise.inspect()).state === "fulfilled" |
| ) { |
| promises[index] = snapshot.value; |
| } else { |
| ++pendingCount; |
| when( |
| promise, |
| function (value) { |
| promises[index] = value; |
| if (--pendingCount === 0) { |
| deferred.resolve(promises); |
| } |
| }, |
| deferred.reject, |
| function (progress) { |
| deferred.notify({ index: index, value: progress }); |
| } |
| ); |
| } |
| }, void 0); |
| if (pendingCount === 0) { |
| deferred.resolve(promises); |
| } |
| return deferred.promise; |
| }); |
| } |
| |
| Promise.prototype.all = function () { |
| return all(this); |
| }; |
| |
| /** |
| * Returns the first resolved promise of an array. Prior rejected promises are |
| * ignored. Rejects only if all promises are rejected. |
| * @param {Array*} an array containing values or promises for values |
| * @returns a promise fulfilled with the value of the first resolved promise, |
| * or a rejected promise if all promises are rejected. |
| */ |
| Q.any = any; |
| |
| function any(promises) { |
| if (promises.length === 0) { |
| return Q.resolve(); |
| } |
| |
| var deferred = Q.defer(); |
| var pendingCount = 0; |
| array_reduce(promises, function (prev, current, index) { |
| var promise = promises[index]; |
| |
| pendingCount++; |
| |
| when(promise, onFulfilled, onRejected, onProgress); |
| function onFulfilled(result) { |
| deferred.resolve(result); |
| } |
| function onRejected() { |
| pendingCount--; |
| if (pendingCount === 0) { |
| deferred.reject(new Error( |
| "Can't get fulfillment value from any promise, all " + |
| "promises were rejected." |
| )); |
| } |
| } |
| function onProgress(progress) { |
| deferred.notify({ |
| index: index, |
| value: progress |
| }); |
| } |
| }, undefined); |
| |
| return deferred.promise; |
| } |
| |
| Promise.prototype.any = function () { |
| return any(this); |
| }; |
| |
| /** |
| * Waits for all promises to be settled, either fulfilled or |
| * rejected. This is distinct from `all` since that would stop |
| * waiting at the first rejection. The promise returned by |
| * `allResolved` will never be rejected. |
| * @param promises a promise for an array (or an array) of promises |
| * (or values) |
| * @return a promise for an array of promises |
| */ |
| Q.allResolved = deprecate(allResolved, "allResolved", "allSettled"); |
| function allResolved(promises) { |
| return when(promises, function (promises) { |
| promises = array_map(promises, Q); |
| return when(all(array_map(promises, function (promise) { |
| return when(promise, noop, noop); |
| })), function () { |
| return promises; |
| }); |
| }); |
| } |
| |
| Promise.prototype.allResolved = function () { |
| return allResolved(this); |
| }; |
| |
| /** |
| * @see Promise#allSettled |
| */ |
| Q.allSettled = allSettled; |
| function allSettled(promises) { |
| return Q(promises).allSettled(); |
| } |
| |
| /** |
| * Turns an array of promises into a promise for an array of their states (as |
| * returned by `inspect`) when they have all settled. |
| * @param {Array[Any*]} values an array (or promise for an array) of values (or |
| * promises for values) |
| * @returns {Array[State]} an array of states for the respective values. |
| */ |
| Promise.prototype.allSettled = function () { |
| return this.then(function (promises) { |
| return all(array_map(promises, function (promise) { |
| promise = Q(promise); |
| function regardless() { |
| return promise.inspect(); |
| } |
| return promise.then(regardless, regardless); |
| })); |
| }); |
| }; |
| |
| /** |
| * Captures the failure of a promise, giving an oportunity to recover |
| * with a callback. If the given promise is fulfilled, the returned |
| * promise is fulfilled. |
| * @param {Any*} promise for something |
| * @param {Function} callback to fulfill the returned promise if the |
| * given promise is rejected |
| * @returns a promise for the return value of the callback |
| */ |
| Q.fail = // XXX legacy |
| Q["catch"] = function (object, rejected) { |
| return Q(object).then(void 0, rejected); |
| }; |
| |
| Promise.prototype.fail = // XXX legacy |
| Promise.prototype["catch"] = function (rejected) { |
| return this.then(void 0, rejected); |
| }; |
| |
| /** |
| * Attaches a listener that can respond to progress notifications from a |
| * promise's originating deferred. This listener receives the exact arguments |
| * passed to ``deferred.notify``. |
| * @param {Any*} promise for something |
| * @param {Function} callback to receive any progress notifications |
| * @returns the given promise, unchanged |
| */ |
| Q.progress = progress; |
| function progress(object, progressed) { |
| return Q(object).then(void 0, void 0, progressed); |
| } |
| |
| Promise.prototype.progress = function (progressed) { |
| return this.then(void 0, void 0, progressed); |
| }; |
| |
| /** |
| * Provides an opportunity to observe the settling of a promise, |
| * regardless of whether the promise is fulfilled or rejected. Forwards |
| * the resolution to the returned promise when the callback is done. |
| * The callback can return a promise to defer completion. |
| * @param {Any*} promise |
| * @param {Function} callback to observe the resolution of the given |
| * promise, takes no arguments. |
| * @returns a promise for the resolution of the given promise when |
| * ``fin`` is done. |
| */ |
| Q.fin = // XXX legacy |
| Q["finally"] = function (object, callback) { |
| return Q(object)["finally"](callback); |
| }; |
| |
| Promise.prototype.fin = // XXX legacy |
| Promise.prototype["finally"] = function (callback) { |
| callback = Q(callback); |
| return this.then(function (value) { |
| return callback.fcall().then(function () { |
| return value; |
| }); |
| }, function (reason) { |
| // TODO attempt to recycle the rejection with "this". |
| return callback.fcall().then(function () { |
| throw reason; |
| }); |
| }); |
| }; |
| |
| /** |
| * Terminates a chain of promises, forcing rejections to be |
| * thrown as exceptions. |
| * @param {Any*} promise at the end of a chain of promises |
| * @returns nothing |
| */ |
| Q.done = function (object, fulfilled, rejected, progress) { |
| return Q(object).done(fulfilled, rejected, progress); |
| }; |
| |
| Promise.prototype.done = function (fulfilled, rejected, progress) { |
| var onUnhandledError = function (error) { |
| // forward to a future turn so that ``when`` |
| // does not catch it and turn it into a rejection. |
| Q.nextTick(function () { |
| makeStackTraceLong(error, promise); |
| if (Q.onerror) { |
| Q.onerror(error); |
| } else { |
| throw error; |
| } |
| }); |
| }; |
| |
| // Avoid unnecessary `nextTick`ing via an unnecessary `when`. |
| var promise = fulfilled || rejected || progress ? |
| this.then(fulfilled, rejected, progress) : |
| this; |
| |
| if (typeof process === "object" && process && process.domain) { |
| onUnhandledError = process.domain.bind(onUnhandledError); |
| } |
| |
| promise.then(void 0, onUnhandledError); |
| }; |
| |
| /** |
| * Causes a promise to be rejected if it does not get fulfilled before |
| * some milliseconds time out. |
| * @param {Any*} promise |
| * @param {Number} milliseconds timeout |
| * @param {Any*} custom error message or Error object (optional) |
| * @returns a promise for the resolution of the given promise if it is |
| * fulfilled before the timeout, otherwise rejected. |
| */ |
| Q.timeout = function (object, ms, error) { |
| return Q(object).timeout(ms, error); |
| }; |
| |
| Promise.prototype.timeout = function (ms, error) { |
| var deferred = defer(); |
| var timeoutId = setTimeout(function () { |
| if (!error || "string" === typeof error) { |
| error = new Error(error || "Timed out after " + ms + " ms"); |
| error.code = "ETIMEDOUT"; |
| } |
| deferred.reject(error); |
| }, ms); |
| |
| this.then(function (value) { |
| clearTimeout(timeoutId); |
| deferred.resolve(value); |
| }, function (exception) { |
| clearTimeout(timeoutId); |
| deferred.reject(exception); |
| }, deferred.notify); |
| |
| return deferred.promise; |
| }; |
| |
| /** |
| * Returns a promise for the given value (or promised value), some |
| * milliseconds after it resolved. Passes rejections immediately. |
| * @param {Any*} promise |
| * @param {Number} milliseconds |
| * @returns a promise for the resolution of the given promise after milliseconds |
| * time has elapsed since the resolution of the given promise. |
| * If the given promise rejects, that is passed immediately. |
| */ |
| Q.delay = function (object, timeout) { |
| if (timeout === void 0) { |
| timeout = object; |
| object = void 0; |
| } |
| return Q(object).delay(timeout); |
| }; |
| |
| Promise.prototype.delay = function (timeout) { |
| return this.then(function (value) { |
| var deferred = defer(); |
| setTimeout(function () { |
| deferred.resolve(value); |
| }, timeout); |
| return deferred.promise; |
| }); |
| }; |
| |
| /** |
| * Passes a continuation to a Node function, which is called with the given |
| * arguments provided as an array, and returns a promise. |
| * |
| * Q.nfapply(FS.readFile, [__filename]) |
| * .then(function (content) { |
| * }) |
| * |
| */ |
| Q.nfapply = function (callback, args) { |
| return Q(callback).nfapply(args); |
| }; |
| |
| Promise.prototype.nfapply = function (args) { |
| var deferred = defer(); |
| var nodeArgs = array_slice(args); |
| nodeArgs.push(deferred.makeNodeResolver()); |
| this.fapply(nodeArgs).fail(deferred.reject); |
| return deferred.promise; |
| }; |
| |
| /** |
| * Passes a continuation to a Node function, which is called with the given |
| * arguments provided individually, and returns a promise. |
| * @example |
| * Q.nfcall(FS.readFile, __filename) |
| * .then(function (content) { |
| * }) |
| * |
| */ |
| Q.nfcall = function (callback /*...args*/) { |
| var args = array_slice(arguments, 1); |
| return Q(callback).nfapply(args); |
| }; |
| |
| Promise.prototype.nfcall = function (/*...args*/) { |
| var nodeArgs = array_slice(arguments); |
| var deferred = defer(); |
| nodeArgs.push(deferred.makeNodeResolver()); |
| this.fapply(nodeArgs).fail(deferred.reject); |
| return deferred.promise; |
| }; |
| |
| /** |
| * Wraps a NodeJS continuation passing function and returns an equivalent |
| * version that returns a promise. |
| * @example |
| * Q.nfbind(FS.readFile, __filename)("utf-8") |
| * .then(console.log) |
| * .done() |
| */ |
| Q.nfbind = |
| Q.denodeify = function (callback /*...args*/) { |
| var baseArgs = array_slice(arguments, 1); |
| return function () { |
| var nodeArgs = baseArgs.concat(array_slice(arguments)); |
| var deferred = defer(); |
| nodeArgs.push(deferred.makeNodeResolver()); |
| Q(callback).fapply(nodeArgs).fail(deferred.reject); |
| return deferred.promise; |
| }; |
| }; |
| |
| Promise.prototype.nfbind = |
| Promise.prototype.denodeify = function (/*...args*/) { |
| var args = array_slice(arguments); |
| args.unshift(this); |
| return Q.denodeify.apply(void 0, args); |
| }; |
| |
| Q.nbind = function (callback, thisp /*...args*/) { |
| var baseArgs = array_slice(arguments, 2); |
| return function () { |
| var nodeArgs = baseArgs.concat(array_slice(arguments)); |
| var deferred = defer(); |
| nodeArgs.push(deferred.makeNodeResolver()); |
| function bound() { |
| return callback.apply(thisp, arguments); |
| } |
| Q(bound).fapply(nodeArgs).fail(deferred.reject); |
| return deferred.promise; |
| }; |
| }; |
| |
| Promise.prototype.nbind = function (/*thisp, ...args*/) { |
| var args = array_slice(arguments, 0); |
| args.unshift(this); |
| return Q.nbind.apply(void 0, args); |
| }; |
| |
| /** |
| * Calls a method of a Node-style object that accepts a Node-style |
| * callback with a given array of arguments, plus a provided callback. |
| * @param object an object that has the named method |
| * @param {String} name name of the method of object |
| * @param {Array} args arguments to pass to the method; the callback |
| * will be provided by Q and appended to these arguments. |
| * @returns a promise for the value or error |
| */ |
| Q.nmapply = // XXX As proposed by "Redsandro" |
| Q.npost = function (object, name, args) { |
| return Q(object).npost(name, args); |
| }; |
| |
| Promise.prototype.nmapply = // XXX As proposed by "Redsandro" |
| Promise.prototype.npost = function (name, args) { |
| var nodeArgs = array_slice(args || []); |
| var deferred = defer(); |
| nodeArgs.push(deferred.makeNodeResolver()); |
| this.dispatch("post", [name, nodeArgs]).fail(deferred.reject); |
| return deferred.promise; |
| }; |
| |
| /** |
| * Calls a method of a Node-style object that accepts a Node-style |
| * callback, forwarding the given variadic arguments, plus a provided |
| * callback argument. |
| * @param object an object that has the named method |
| * @param {String} name name of the method of object |
| * @param ...args arguments to pass to the method; the callback will |
| * be provided by Q and appended to these arguments. |
| * @returns a promise for the value or error |
| */ |
| Q.nsend = // XXX Based on Mark Miller's proposed "send" |
| Q.nmcall = // XXX Based on "Redsandro's" proposal |
| Q.ninvoke = function (object, name /*...args*/) { |
| var nodeArgs = array_slice(arguments, 2); |
| var deferred = defer(); |
| nodeArgs.push(deferred.makeNodeResolver()); |
| Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject); |
| return deferred.promise; |
| }; |
| |
| Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send" |
| Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal |
| Promise.prototype.ninvoke = function (name /*...args*/) { |
| var nodeArgs = array_slice(arguments, 1); |
| var deferred = defer(); |
| nodeArgs.push(deferred.makeNodeResolver()); |
| this.dispatch("post", [name, nodeArgs]).fail(deferred.reject); |
| return deferred.promise; |
| }; |
| |
| /** |
| * If a function would like to support both Node continuation-passing-style and |
| * promise-returning-style, it can end its internal promise chain with |
| * `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user |
| * elects to use a nodeback, the result will be sent there. If they do not |
| * pass a nodeback, they will receive the result promise. |
| * @param object a result (or a promise for a result) |
| * @param {Function} nodeback a Node.js-style callback |
| * @returns either the promise or nothing |
| */ |
| Q.nodeify = nodeify; |
| function nodeify(object, nodeback) { |
| return Q(object).nodeify(nodeback); |
| } |
| |
| Promise.prototype.nodeify = function (nodeback) { |
| if (nodeback) { |
| this.then(function (value) { |
| Q.nextTick(function () { |
| nodeback(null, value); |
| }); |
| }, function (error) { |
| Q.nextTick(function () { |
| nodeback(error); |
| }); |
| }); |
| } else { |
| return this; |
| } |
| }; |
| |
| Q.noConflict = function() { |
| throw new Error("Q.noConflict only works when Q is used as a global"); |
| }; |
| |
| // All code before this point will be filtered from stack traces. |
| var qEndingLine = captureLine(); |
| |
| return Q; |
| |
| }); |
| |
| }).call(this,require('_process')) |
| |
| },{"_process":12}],158:[function(require,module,exports){ |
| /** |
| * Root reference for iframes. |
| */ |
| |
| var root; |
| if (typeof window !== 'undefined') { // Browser window |
| root = window; |
| } else if (typeof self !== 'undefined') { // Web Worker |
| root = self; |
| } else { // Other environments |
| console.warn("Using browser-only version of superagent in non-browser environment"); |
| root = this; |
| } |
| |
| var Emitter = require('emitter'); |
| var requestBase = require('./request-base'); |
| var isObject = require('./is-object'); |
| |
| /** |
| * Noop. |
| */ |
| |
| function noop(){}; |
| |
| /** |
| * Expose `request`. |
| */ |
| |
| var request = module.exports = require('./request').bind(null, Request); |
| |
| /** |
| * Determine XHR. |
| */ |
| |
| request.getXHR = function () { |
| if (root.XMLHttpRequest |
| && (!root.location || 'file:' != root.location.protocol |
| || !root.ActiveXObject)) { |
| return new XMLHttpRequest; |
| } else { |
| try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} |
| try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} |
| try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} |
| try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} |
| } |
| throw Error("Browser-only verison of superagent could not find XHR"); |
| }; |
| |
| /** |
| * Removes leading and trailing whitespace, added to support IE. |
| * |
| * @param {String} s |
| * @return {String} |
| * @api private |
| */ |
| |
| var trim = ''.trim |
| ? function(s) { return s.trim(); } |
| : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; |
| |
| /** |
| * Serialize the given `obj`. |
| * |
| * @param {Object} obj |
| * @return {String} |
| * @api private |
| */ |
| |
| function serialize(obj) { |
| if (!isObject(obj)) return obj; |
| var pairs = []; |
| for (var key in obj) { |
| pushEncodedKeyValuePair(pairs, key, obj[key]); |
| } |
| return pairs.join('&'); |
| } |
| |
| /** |
| * Helps 'serialize' with serializing arrays. |
| * Mutates the pairs array. |
| * |
| * @param {Array} pairs |
| * @param {String} key |
| * @param {Mixed} val |
| */ |
| |
| function pushEncodedKeyValuePair(pairs, key, val) { |
| if (val != null) { |
| if (Array.isArray(val)) { |
| val.forEach(function(v) { |
| pushEncodedKeyValuePair(pairs, key, v); |
| }); |
| } else if (isObject(val)) { |
| for(var subkey in val) { |
| pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]); |
| } |
| } else { |
| pairs.push(encodeURIComponent(key) |
| + '=' + encodeURIComponent(val)); |
| } |
| } else if (val === null) { |
| pairs.push(encodeURIComponent(key)); |
| } |
| } |
| |
| /** |
| * Expose serialization method. |
| */ |
| |
| request.serializeObject = serialize; |
| |
| /** |
| * Parse the given x-www-form-urlencoded `str`. |
| * |
| * @param {String} str |
| * @return {Object} |
| * @api private |
| */ |
| |
| function parseString(str) { |
| var obj = {}; |
| var pairs = str.split('&'); |
| var pair; |
| var pos; |
| |
| for (var i = 0, len = pairs.length; i < len; ++i) { |
| pair = pairs[i]; |
| pos = pair.indexOf('='); |
| if (pos == -1) { |
| obj[decodeURIComponent(pair)] = ''; |
| } else { |
| obj[decodeURIComponent(pair.slice(0, pos))] = |
| decodeURIComponent(pair.slice(pos + 1)); |
| } |
| } |
| |
| return obj; |
| } |
| |
| /** |
| * Expose parser. |
| */ |
| |
| request.parseString = parseString; |
| |
| /** |
| * Default MIME type map. |
| * |
| * superagent.types.xml = 'application/xml'; |
| * |
| */ |
| |
| request.types = { |
| html: 'text/html', |
| json: 'application/json', |
| xml: 'application/xml', |
| urlencoded: 'application/x-www-form-urlencoded', |
| 'form': 'application/x-www-form-urlencoded', |
| 'form-data': 'application/x-www-form-urlencoded' |
| }; |
| |
| /** |
| * Default serialization map. |
| * |
| * superagent.serialize['application/xml'] = function(obj){ |
| * return 'generated xml here'; |
| * }; |
| * |
| */ |
| |
| request.serialize = { |
| 'application/x-www-form-urlencoded': serialize, |
| 'application/json': JSON.stringify |
| }; |
| |
| /** |
| * Default parsers. |
| * |
| * superagent.parse['application/xml'] = function(str){ |
| * return { object parsed from str }; |
| * }; |
| * |
| */ |
| |
| request.parse = { |
| 'application/x-www-form-urlencoded': parseString, |
| 'application/json': JSON.parse |
| }; |
| |
| /** |
| * Parse the given header `str` into |
| * an object containing the mapped fields. |
| * |
| * @param {String} str |
| * @return {Object} |
| * @api private |
| */ |
| |
| function parseHeader(str) { |
| var lines = str.split(/\r?\n/); |
| var fields = {}; |
| var index; |
| var line; |
| var field; |
| var val; |
| |
| lines.pop(); // trailing CRLF |
| |
| for (var i = 0, len = lines.length; i < len; ++i) { |
| line = lines[i]; |
| index = line.indexOf(':'); |
| field = line.slice(0, index).toLowerCase(); |
| val = trim(line.slice(index + 1)); |
| fields[field] = val; |
| } |
| |
| return fields; |
| } |
| |
| /** |
| * Check if `mime` is json or has +json structured syntax suffix. |
| * |
| * @param {String} mime |
| * @return {Boolean} |
| * @api private |
| */ |
| |
| function isJSON(mime) { |
| return /[\/+]json\b/.test(mime); |
| } |
| |
| /** |
| * Return the mime type for the given `str`. |
| * |
| * @param {String} str |
| * @return {String} |
| * @api private |
| */ |
| |
| function type(str){ |
| return str.split(/ *; */).shift(); |
| }; |
| |
| /** |
| * Return header field parameters. |
| * |
| * @param {String} str |
| * @return {Object} |
| * @api private |
| */ |
| |
| function params(str){ |
| return str.split(/ *; */).reduce(function(obj, str){ |
| var parts = str.split(/ *= */), |
| key = parts.shift(), |
| val = parts.shift(); |
| |
| if (key && val) obj[key] = val; |
| return obj; |
| }, {}); |
| }; |
| |
| /** |
| * Initialize a new `Response` with the given `xhr`. |
| * |
| * - set flags (.ok, .error, etc) |
| * - parse header |
| * |
| * Examples: |
| * |
| * Aliasing `superagent` as `request` is nice: |
| * |
| * request = superagent; |
| * |
| * We can use the promise-like API, or pass callbacks: |
| * |
| * request.get('/').end(function(res){}); |
| * request.get('/', function(res){}); |
| * |
| * Sending data can be chained: |
| * |
| * request |
| * .post('/user') |
| * .send({ name: 'tj' }) |
| * .end(function(res){}); |
| * |
| * Or passed to `.send()`: |
| * |
| * request |
| * .post('/user') |
| * .send({ name: 'tj' }, function(res){}); |
| * |
| * Or passed to `.post()`: |
| * |
| * request |
| * .post('/user', { name: 'tj' }) |
| * .end(function(res){}); |
| * |
| * Or further reduced to a single call for simple cases: |
| * |
| * request |
| * .post('/user', { name: 'tj' }, function(res){}); |
| * |
| * @param {XMLHTTPRequest} xhr |
| * @param {Object} options |
| * @api private |
| */ |
| |
| function Response(req, options) { |
| options = options || {}; |
| this.req = req; |
| this.xhr = this.req.xhr; |
| // responseText is accessible only if responseType is '' or 'text' and on older browsers |
| this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') |
| ? this.xhr.responseText |
| : null; |
| this.statusText = this.req.xhr.statusText; |
| this._setStatusProperties(this.xhr.status); |
| this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); |
| // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but |
| // getResponseHeader still works. so we get content-type even if getting |
| // other headers fails. |
| this.header['content-type'] = this.xhr.getResponseHeader('content-type'); |
| this._setHeaderProperties(this.header); |
| this.body = this.req.method != 'HEAD' |
| ? this._parseBody(this.text ? this.text : this.xhr.response) |
| : null; |
| } |
| |
| /** |
| * Get case-insensitive `field` value. |
| * |
| * @param {String} field |
| * @return {String} |
| * @api public |
| */ |
| |
| Response.prototype.get = function(field){ |
| return this.header[field.toLowerCase()]; |
| }; |
| |
| /** |
| * Set header related properties: |
| * |
| * - `.type` the content type without params |
| * |
| * A response of "Content-Type: text/plain; charset=utf-8" |
| * will provide you with a `.type` of "text/plain". |
| * |
| * @param {Object} header |
| * @api private |
| */ |
| |
| Response.prototype._setHeaderProperties = function(header){ |
| // content-type |
| var ct = this.header['content-type'] || ''; |
| this.type = type(ct); |
| |
| // params |
| var obj = params(ct); |
| for (var key in obj) this[key] = obj[key]; |
| }; |
| |
| /** |
| * Parse the given body `str`. |
| * |
| * Used for auto-parsing of bodies. Parsers |
| * are defined on the `superagent.parse` object. |
| * |
| * @param {String} str |
| * @return {Mixed} |
| * @api private |
| */ |
| |
| Response.prototype._parseBody = function(str){ |
| var parse = request.parse[this.type]; |
| if (!parse && isJSON(this.type)) { |
| parse = request.parse['application/json']; |
| } |
| return parse && str && (str.length || str instanceof Object) |
| ? parse(str) |
| : null; |
| }; |
| |
| /** |
| * Set flags such as `.ok` based on `status`. |
| * |
| * For example a 2xx response will give you a `.ok` of __true__ |
| * whereas 5xx will be __false__ and `.error` will be __true__. The |
| * `.clientError` and `.serverError` are also available to be more |
| * specific, and `.statusType` is the class of error ranging from 1..5 |
| * sometimes useful for mapping respond colors etc. |
| * |
| * "sugar" properties are also defined for common cases. Currently providing: |
| * |
| * - .noContent |
| * - .badRequest |
| * - .unauthorized |
| * - .notAcceptable |
| * - .notFound |
| * |
| * @param {Number} status |
| * @api private |
| */ |
| |
| Response.prototype._setStatusProperties = function(status){ |
| // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request |
| if (status === 1223) { |
| status = 204; |
| } |
| |
| var type = status / 100 | 0; |
| |
| // status / class |
| this.status = this.statusCode = status; |
| this.statusType = type; |
| |
| // basics |
| this.info = 1 == type; |
| this.ok = 2 == type; |
| this.clientError = 4 == type; |
| this.serverError = 5 == type; |
| this.error = (4 == type || 5 == type) |
| ? this.toError() |
| : false; |
| |
| // sugar |
| this.accepted = 202 == status; |
| this.noContent = 204 == status; |
| this.badRequest = 400 == status; |
| this.unauthorized = 401 == status; |
| this.notAcceptable = 406 == status; |
| this.notFound = 404 == status; |
| this.forbidden = 403 == status; |
| }; |
| |
| /** |
| * Return an `Error` representative of this response. |
| * |
| * @return {Error} |
| * @api public |
| */ |
| |
| Response.prototype.toError = function(){ |
| var req = this.req; |
| var method = req.method; |
| var url = req.url; |
| |
| var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; |
| var err = new Error(msg); |
| err.status = this.status; |
| err.method = method; |
| err.url = url; |
| |
| return err; |
| }; |
| |
| /** |
| * Expose `Response`. |
| */ |
| |
| request.Response = Response; |
| |
| /** |
| * Initialize a new `Request` with the given `method` and `url`. |
| * |
| * @param {String} method |
| * @param {String} url |
| * @api public |
| */ |
| |
| function Request(method, url) { |
| var self = this; |
| this._query = this._query || []; |
| this.method = method; |
| this.url = url; |
| this.header = {}; // preserves header name case |
| this._header = {}; // coerces header names to lowercase |
| this.on('end', function(){ |
| var err = null; |
| var res = null; |
| |
| try { |
| res = new Response(self); |
| } catch(e) { |
| err = new Error('Parser is unable to parse the response'); |
| err.parse = true; |
| err.original = e; |
| // issue #675: return the raw response if the response parsing fails |
| err.rawResponse = self.xhr && self.xhr.responseText ? self.xhr.responseText : null; |
| // issue #876: return the http status code if the response parsing fails |
| err.statusCode = self.xhr && self.xhr.status ? self.xhr.status : null; |
| return self.callback(err); |
| } |
| |
| self.emit('response', res); |
| |
| var new_err; |
| try { |
| if (res.status < 200 || res.status >= 300) { |
| new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); |
| new_err.original = err; |
| new_err.response = res; |
| new_err.status = res.status; |
| } |
| } catch(e) { |
| new_err = e; // #985 touching res may cause INVALID_STATE_ERR on old Android |
| } |
| |
| // #1000 don't catch errors from the callback to avoid double calling it |
| if (new_err) { |
| self.callback(new_err, res); |
| } else { |
| self.callback(null, res); |
| } |
| }); |
| } |
| |
| /** |
| * Mixin `Emitter` and `requestBase`. |
| */ |
| |
| Emitter(Request.prototype); |
| for (var key in requestBase) { |
| Request.prototype[key] = requestBase[key]; |
| } |
| |
| /** |
| * Set Content-Type to `type`, mapping values from `request.types`. |
| * |
| * Examples: |
| * |
| * superagent.types.xml = 'application/xml'; |
| * |
| * request.post('/') |
| * .type('xml') |
| * .send(xmlstring) |
| * .end(callback); |
| * |
| * request.post('/') |
| * .type('application/xml') |
| * .send(xmlstring) |
| * .end(callback); |
| * |
| * @param {String} type |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| Request.prototype.type = function(type){ |
| this.set('Content-Type', request.types[type] || type); |
| return this; |
| }; |
| |
| /** |
| * Set responseType to `val`. Presently valid responseTypes are 'blob' and |
| * 'arraybuffer'. |
| * |
| * Examples: |
| * |
| * req.get('/') |
| * .responseType('blob') |
| * .end(callback); |
| * |
| * @param {String} val |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| Request.prototype.responseType = function(val){ |
| this._responseType = val; |
| return this; |
| }; |
| |
| /** |
| * Set Accept to `type`, mapping values from `request.types`. |
| * |
| * Examples: |
| * |
| * superagent.types.json = 'application/json'; |
| * |
| * request.get('/agent') |
| * .accept('json') |
| * .end(callback); |
| * |
| * request.get('/agent') |
| * .accept('application/json') |
| * .end(callback); |
| * |
| * @param {String} accept |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| Request.prototype.accept = function(type){ |
| this.set('Accept', request.types[type] || type); |
| return this; |
| }; |
| |
| /** |
| * Set Authorization field value with `user` and `pass`. |
| * |
| * @param {String} user |
| * @param {String} pass |
| * @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic') |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| Request.prototype.auth = function(user, pass, options){ |
| if (!options) { |
| options = { |
| type: 'basic' |
| } |
| } |
| |
| switch (options.type) { |
| case 'basic': |
| var str = btoa(user + ':' + pass); |
| this.set('Authorization', 'Basic ' + str); |
| break; |
| |
| case 'auto': |
| this.username = user; |
| this.password = pass; |
| break; |
| } |
| return this; |
| }; |
| |
| /** |
| * Add query-string `val`. |
| * |
| * Examples: |
| * |
| * request.get('/shoes') |
| * .query('size=10') |
| * .query({ color: 'blue' }) |
| * |
| * @param {Object|String} val |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| Request.prototype.query = function(val){ |
| if ('string' != typeof val) val = serialize(val); |
| if (val) this._query.push(val); |
| return this; |
| }; |
| |
| /** |
| * Queue the given `file` as an attachment to the specified `field`, |
| * with optional `filename`. |
| * |
| * ``` js |
| * request.post('/upload') |
| * .attach('content', new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"})) |
| * .end(callback); |
| * ``` |
| * |
| * @param {String} field |
| * @param {Blob|File} file |
| * @param {String} filename |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| Request.prototype.attach = function(field, file, filename){ |
| this._getFormData().append(field, file, filename || file.name); |
| return this; |
| }; |
| |
| Request.prototype._getFormData = function(){ |
| if (!this._formData) { |
| this._formData = new root.FormData(); |
| } |
| return this._formData; |
| }; |
| |
| /** |
| * Invoke the callback with `err` and `res` |
| * and handle arity check. |
| * |
| * @param {Error} err |
| * @param {Response} res |
| * @api private |
| */ |
| |
| Request.prototype.callback = function(err, res){ |
| var fn = this._callback; |
| this.clearTimeout(); |
| fn(err, res); |
| }; |
| |
| /** |
| * Invoke callback with x-domain error. |
| * |
| * @api private |
| */ |
| |
| Request.prototype.crossDomainError = function(){ |
| var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.'); |
| err.crossDomain = true; |
| |
| err.status = this.status; |
| err.method = this.method; |
| err.url = this.url; |
| |
| this.callback(err); |
| }; |
| |
| /** |
| * Invoke callback with timeout error. |
| * |
| * @api private |
| */ |
| |
| Request.prototype._timeoutError = function(){ |
| var timeout = this._timeout; |
| var err = new Error('timeout of ' + timeout + 'ms exceeded'); |
| err.timeout = timeout; |
| this.callback(err); |
| }; |
| |
| /** |
| * Compose querystring to append to req.url |
| * |
| * @api private |
| */ |
| |
| Request.prototype._appendQueryString = function(){ |
| var query = this._query.join('&'); |
| if (query) { |
| this.url += ~this.url.indexOf('?') |
| ? '&' + query |
| : '?' + query; |
| } |
| }; |
| |
| /** |
| * Initiate request, invoking callback `fn(res)` |
| * with an instanceof `Response`. |
| * |
| * @param {Function} fn |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| Request.prototype.end = function(fn){ |
| var self = this; |
| var xhr = this.xhr = request.getXHR(); |
| var timeout = this._timeout; |
| var data = this._formData || this._data; |
| |
| // store callback |
| this._callback = fn || noop; |
| |
| // state change |
| xhr.onreadystatechange = function(){ |
| if (4 != xhr.readyState) return; |
| |
| // In IE9, reads to any property (e.g. status) off of an aborted XHR will |
| // result in the error "Could not complete the operation due to error c00c023f" |
| var status; |
| try { status = xhr.status } catch(e) { status = 0; } |
| |
| if (0 == status) { |
| if (self.timedout) return self._timeoutError(); |
| if (self._aborted) return; |
| return self.crossDomainError(); |
| } |
| self.emit('end'); |
| }; |
| |
| // progress |
| var handleProgress = function(e){ |
| if (e.total > 0) { |
| e.percent = e.loaded / e.total * 100; |
| } |
| e.direction = 'download'; |
| self.emit('progress', e); |
| }; |
| if (this.hasListeners('progress')) { |
| xhr.onprogress = handleProgress; |
| } |
| try { |
| if (xhr.upload && this.hasListeners('progress')) { |
| xhr.upload.onprogress = handleProgress; |
| } |
| } catch(e) { |
| // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. |
| // Reported here: |
| // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context |
| } |
| |
| // timeout |
| if (timeout && !this._timer) { |
| this._timer = setTimeout(function(){ |
| self.timedout = true; |
| self.abort(); |
| }, timeout); |
| } |
| |
| // querystring |
| this._appendQueryString(); |
| |
| // initiate request |
| if (this.username && this.password) { |
| xhr.open(this.method, this.url, true, this.username, this.password); |
| } else { |
| xhr.open(this.method, this.url, true); |
| } |
| |
| // CORS |
| if (this._withCredentials) xhr.withCredentials = true; |
| |
| // body |
| if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) { |
| // serialize stuff |
| var contentType = this._header['content-type']; |
| var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : '']; |
| if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json']; |
| if (serialize) data = serialize(data); |
| } |
| |
| // set header fields |
| for (var field in this.header) { |
| if (null == this.header[field]) continue; |
| xhr.setRequestHeader(field, this.header[field]); |
| } |
| |
| if (this._responseType) { |
| xhr.responseType = this._responseType; |
| } |
| |
| // send stuff |
| this.emit('request', this); |
| |
| // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) |
| // We need null here if data is undefined |
| xhr.send(typeof data !== 'undefined' ? data : null); |
| return this; |
| }; |
| |
| |
| /** |
| * Expose `Request`. |
| */ |
| |
| request.Request = Request; |
| |
| /** |
| * GET `url` with optional callback `fn(res)`. |
| * |
| * @param {String} url |
| * @param {Mixed|Function} [data] or fn |
| * @param {Function} [fn] |
| * @return {Request} |
| * @api public |
| */ |
| |
| request.get = function(url, data, fn){ |
| var req = request('GET', url); |
| if ('function' == typeof data) fn = data, data = null; |
| if (data) req.query(data); |
| if (fn) req.end(fn); |
| return req; |
| }; |
| |
| /** |
| * HEAD `url` with optional callback `fn(res)`. |
| * |
| * @param {String} url |
| * @param {Mixed|Function} [data] or fn |
| * @param {Function} [fn] |
| * @return {Request} |
| * @api public |
| */ |
| |
| request.head = function(url, data, fn){ |
| var req = request('HEAD', url); |
| if ('function' == typeof data) fn = data, data = null; |
| if (data) req.send(data); |
| if (fn) req.end(fn); |
| return req; |
| }; |
| |
| /** |
| * OPTIONS query to `url` with optional callback `fn(res)`. |
| * |
| * @param {String} url |
| * @param {Mixed|Function} [data] or fn |
| * @param {Function} [fn] |
| * @return {Request} |
| * @api public |
| */ |
| |
| request.options = function(url, data, fn){ |
| var req = request('OPTIONS', url); |
| if ('function' == typeof data) fn = data, data = null; |
| if (data) req.send(data); |
| if (fn) req.end(fn); |
| return req; |
| }; |
| |
| /** |
| * DELETE `url` with optional callback `fn(res)`. |
| * |
| * @param {String} url |
| * @param {Function} [fn] |
| * @return {Request} |
| * @api public |
| */ |
| |
| function del(url, fn){ |
| var req = request('DELETE', url); |
| if (fn) req.end(fn); |
| return req; |
| }; |
| |
| request['del'] = del; |
| request['delete'] = del; |
| |
| /** |
| * PATCH `url` with optional `data` and callback `fn(res)`. |
| * |
| * @param {String} url |
| * @param {Mixed} [data] |
| * @param {Function} [fn] |
| * @return {Request} |
| * @api public |
| */ |
| |
| request.patch = function(url, data, fn){ |
| var req = request('PATCH', url); |
| if ('function' == typeof data) fn = data, data = null; |
| if (data) req.send(data); |
| if (fn) req.end(fn); |
| return req; |
| }; |
| |
| /** |
| * POST `url` with optional `data` and callback `fn(res)`. |
| * |
| * @param {String} url |
| * @param {Mixed} [data] |
| * @param {Function} [fn] |
| * @return {Request} |
| * @api public |
| */ |
| |
| request.post = function(url, data, fn){ |
| var req = request('POST', url); |
| if ('function' == typeof data) fn = data, data = null; |
| if (data) req.send(data); |
| if (fn) req.end(fn); |
| return req; |
| }; |
| |
| /** |
| * PUT `url` with optional `data` and callback `fn(res)`. |
| * |
| * @param {String} url |
| * @param {Mixed|Function} [data] or fn |
| * @param {Function} [fn] |
| * @return {Request} |
| * @api public |
| */ |
| |
| request.put = function(url, data, fn){ |
| var req = request('PUT', url); |
| if ('function' == typeof data) fn = data, data = null; |
| if (data) req.send(data); |
| if (fn) req.end(fn); |
| return req; |
| }; |
| |
| },{"./is-object":159,"./request":161,"./request-base":160,"emitter":162}],159:[function(require,module,exports){ |
| /** |
| * Check if `obj` is an object. |
| * |
| * @param {Object} obj |
| * @return {Boolean} |
| * @api private |
| */ |
| |
| function isObject(obj) { |
| return null !== obj && 'object' === typeof obj; |
| } |
| |
| module.exports = isObject; |
| |
| },{}],160:[function(require,module,exports){ |
| /** |
| * Module of mixed-in functions shared between node and client code |
| */ |
| var isObject = require('./is-object'); |
| |
| /** |
| * Clear previous timeout. |
| * |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| exports.clearTimeout = function _clearTimeout(){ |
| this._timeout = 0; |
| clearTimeout(this._timer); |
| return this; |
| }; |
| |
| /** |
| * Override default response body parser |
| * |
| * This function will be called to convert incoming data into request.body |
| * |
| * @param {Function} |
| * @api public |
| */ |
| |
| exports.parse = function parse(fn){ |
| this._parser = fn; |
| return this; |
| }; |
| |
| /** |
| * Override default request body serializer |
| * |
| * This function will be called to convert data set via .send or .attach into payload to send |
| * |
| * @param {Function} |
| * @api public |
| */ |
| |
| exports.serialize = function serialize(fn){ |
| this._serializer = fn; |
| return this; |
| }; |
| |
| /** |
| * Set timeout to `ms`. |
| * |
| * @param {Number} ms |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| exports.timeout = function timeout(ms){ |
| this._timeout = ms; |
| return this; |
| }; |
| |
| /** |
| * Promise support |
| * |
| * @param {Function} resolve |
| * @param {Function} reject |
| * @return {Request} |
| */ |
| |
| exports.then = function then(resolve, reject) { |
| if (!this._fullfilledPromise) { |
| var self = this; |
| this._fullfilledPromise = new Promise(function(innerResolve, innerReject){ |
| self.end(function(err, res){ |
| if (err) innerReject(err); else innerResolve(res); |
| }); |
| }); |
| } |
| return this._fullfilledPromise.then(resolve, reject); |
| } |
| |
| /** |
| * Allow for extension |
| */ |
| |
| exports.use = function use(fn) { |
| fn(this); |
| return this; |
| } |
| |
| |
| /** |
| * Get request header `field`. |
| * Case-insensitive. |
| * |
| * @param {String} field |
| * @return {String} |
| * @api public |
| */ |
| |
| exports.get = function(field){ |
| return this._header[field.toLowerCase()]; |
| }; |
| |
| /** |
| * Get case-insensitive header `field` value. |
| * This is a deprecated internal API. Use `.get(field)` instead. |
| * |
| * (getHeader is no longer used internally by the superagent code base) |
| * |
| * @param {String} field |
| * @return {String} |
| * @api private |
| * @deprecated |
| */ |
| |
| exports.getHeader = exports.get; |
| |
| /** |
| * Set header `field` to `val`, or multiple fields with one object. |
| * Case-insensitive. |
| * |
| * Examples: |
| * |
| * req.get('/') |
| * .set('Accept', 'application/json') |
| * .set('X-API-Key', 'foobar') |
| * .end(callback); |
| * |
| * req.get('/') |
| * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) |
| * .end(callback); |
| * |
| * @param {String|Object} field |
| * @param {String} val |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| exports.set = function(field, val){ |
| if (isObject(field)) { |
| for (var key in field) { |
| this.set(key, field[key]); |
| } |
| return this; |
| } |
| this._header[field.toLowerCase()] = val; |
| this.header[field] = val; |
| return this; |
| }; |
| |
| /** |
| * Remove header `field`. |
| * Case-insensitive. |
| * |
| * Example: |
| * |
| * req.get('/') |
| * .unset('User-Agent') |
| * .end(callback); |
| * |
| * @param {String} field |
| */ |
| exports.unset = function(field){ |
| delete this._header[field.toLowerCase()]; |
| delete this.header[field]; |
| return this; |
| }; |
| |
| /** |
| * Write the field `name` and `val` for "multipart/form-data" |
| * request bodies. |
| * |
| * ``` js |
| * request.post('/upload') |
| * .field('foo', 'bar') |
| * .end(callback); |
| * ``` |
| * |
| * @param {String} name |
| * @param {String|Blob|File|Buffer|fs.ReadStream} val |
| * @return {Request} for chaining |
| * @api public |
| */ |
| exports.field = function(name, val) { |
| this._getFormData().append(name, val); |
| return this; |
| }; |
| |
| /** |
| * Abort the request, and clear potential timeout. |
| * |
| * @return {Request} |
| * @api public |
| */ |
| exports.abort = function(){ |
| if (this._aborted) { |
| return this; |
| } |
| this._aborted = true; |
| this.xhr && this.xhr.abort(); // browser |
| this.req && this.req.abort(); // node |
| this.clearTimeout(); |
| this.emit('abort'); |
| return this; |
| }; |
| |
| /** |
| * Enable transmission of cookies with x-domain requests. |
| * |
| * Note that for this to work the origin must not be |
| * using "Access-Control-Allow-Origin" with a wildcard, |
| * and also must set "Access-Control-Allow-Credentials" |
| * to "true". |
| * |
| * @api public |
| */ |
| |
| exports.withCredentials = function(){ |
| // This is browser-only functionality. Node side is no-op. |
| this._withCredentials = true; |
| return this; |
| }; |
| |
| /** |
| * Set the max redirects to `n`. Does noting in browser XHR implementation. |
| * |
| * @param {Number} n |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| exports.redirects = function(n){ |
| this._maxRedirects = n; |
| return this; |
| }; |
| |
| /** |
| * Convert to a plain javascript object (not JSON string) of scalar properties. |
| * Note as this method is designed to return a useful non-this value, |
| * it cannot be chained. |
| * |
| * @return {Object} describing method, url, and data of this request |
| * @api public |
| */ |
| |
| exports.toJSON = function(){ |
| return { |
| method: this.method, |
| url: this.url, |
| data: this._data, |
| headers: this._header |
| }; |
| }; |
| |
| /** |
| * Check if `obj` is a host object, |
| * we don't want to serialize these :) |
| * |
| * TODO: future proof, move to compoent land |
| * |
| * @param {Object} obj |
| * @return {Boolean} |
| * @api private |
| */ |
| |
| exports._isHost = function _isHost(obj) { |
| var str = {}.toString.call(obj); |
| |
| switch (str) { |
| case '[object File]': |
| case '[object Blob]': |
| case '[object FormData]': |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| /** |
| * Send `data` as the request body, defaulting the `.type()` to "json" when |
| * an object is given. |
| * |
| * Examples: |
| * |
| * // manual json |
| * request.post('/user') |
| * .type('json') |
| * .send('{"name":"tj"}') |
| * .end(callback) |
| * |
| * // auto json |
| * request.post('/user') |
| * .send({ name: 'tj' }) |
| * .end(callback) |
| * |
| * // manual x-www-form-urlencoded |
| * request.post('/user') |
| * .type('form') |
| * .send('name=tj') |
| * .end(callback) |
| * |
| * // auto x-www-form-urlencoded |
| * request.post('/user') |
| * .type('form') |
| * .send({ name: 'tj' }) |
| * .end(callback) |
| * |
| * // defaults to x-www-form-urlencoded |
| * request.post('/user') |
| * .send('name=tobi') |
| * .send('species=ferret') |
| * .end(callback) |
| * |
| * @param {String|Object} data |
| * @return {Request} for chaining |
| * @api public |
| */ |
| |
| exports.send = function(data){ |
| var obj = isObject(data); |
| var type = this._header['content-type']; |
| |
| // merge |
| if (obj && isObject(this._data)) { |
| for (var key in data) { |
| this._data[key] = data[key]; |
| } |
| } else if ('string' == typeof data) { |
| // default to x-www-form-urlencoded |
| if (!type) this.type('form'); |
| type = this._header['content-type']; |
| if ('application/x-www-form-urlencoded' == type) { |
| this._data = this._data |
| ? this._data + '&' + data |
| : data; |
| } else { |
| this._data = (this._data || '') + data; |
| } |
| } else { |
| this._data = data; |
| } |
| |
| if (!obj || this._isHost(data)) return this; |
| |
| // default to json |
| if (!type) this.type('json'); |
| return this; |
| }; |
| |
| },{"./is-object":159}],161:[function(require,module,exports){ |
| // The node and browser modules expose versions of this with the |
| // appropriate constructor function bound as first argument |
| /** |
| * Issue a request: |
| * |
| * Examples: |
| * |
| * request('GET', '/users').end(callback) |
| * request('/users').end(callback) |
| * request('/users', callback) |
| * |
| * @param {String} method |
| * @param {String|Function} url or callback |
| * @return {Request} |
| * @api public |
| */ |
| |
| function request(RequestConstructor, method, url) { |
| // callback |
| if ('function' == typeof url) { |
| return new RequestConstructor('GET', method).end(url); |
| } |
| |
| // url first |
| if (2 == arguments.length) { |
| return new RequestConstructor('GET', method); |
| } |
| |
| return new RequestConstructor(method, url); |
| } |
| |
| module.exports = request; |
| |
| },{}],162:[function(require,module,exports){ |
|
|
| /**
|
| * Expose `Emitter`.
|
| */
|
|
|
| if (typeof module !== 'undefined') {
|
| module.exports = Emitter;
|
| }
|
|
|
| /**
|
| * Initialize a new `Emitter`.
|
| *
|
| * @api public
|
| */
|
|
|
| function Emitter(obj) {
|
| if (obj) return mixin(obj);
|
| };
|
|
|
| /**
|
| * Mixin the emitter properties.
|
| *
|
| * @param {Object} obj
|
| * @return {Object}
|
| * @api private
|
| */
|
|
|
| function mixin(obj) {
|
| for (var key in Emitter.prototype) {
|
| obj[key] = Emitter.prototype[key];
|
| }
|
| return obj;
|
| }
|
|
|
| /**
|
| * Listen on the given `event` with `fn`.
|
| *
|
| * @param {String} event
|
| * @param {Function} fn
|
| * @return {Emitter}
|
| * @api public
|
| */
|
|
|
| Emitter.prototype.on =
|
| Emitter.prototype.addEventListener = function(event, fn){
|
| this._callbacks = this._callbacks || {};
|
| (this._callbacks['$' + event] = this._callbacks['$' + event] || [])
|
| .push(fn);
|
| return this;
|
| };
|
|
|
| /**
|
| * Adds an `event` listener that will be invoked a single
|
| * time then automatically removed.
|
| *
|
| * @param {String} event
|
| * @param {Function} fn
|
| * @return {Emitter}
|
| * @api public
|
| */
|
|
|
| Emitter.prototype.once = function(event, fn){
|
| function on() {
|
| this.off(event, on);
|
| fn.apply(this, arguments);
|
| }
|
|
|
| on.fn = fn;
|
| this.on(event, on);
|
| return this;
|
| };
|
|
|
| /**
|
| * Remove the given callback for `event` or all
|
| * registered callbacks.
|
| *
|
| * @param {String} event
|
| * @param {Function} fn
|
| * @return {Emitter}
|
| * @api public
|
| */
|
|
|
| Emitter.prototype.off =
|
| Emitter.prototype.removeListener =
|
| Emitter.prototype.removeAllListeners =
|
| Emitter.prototype.removeEventListener = function(event, fn){
|
| this._callbacks = this._callbacks || {};
|
|
|
| // all
|
| if (0 == arguments.length) {
|
| this._callbacks = {};
|
| return this;
|
| }
|
|
|
| // specific event
|
| var callbacks = this._callbacks['$' + event];
|
| if (!callbacks) return this;
|
|
|
| // remove all handlers
|
| if (1 == arguments.length) {
|
| delete this._callbacks['$' + event];
|
| return this;
|
| }
|
|
|
| // remove specific handler
|
| var cb;
|
| for (var i = 0; i < callbacks.length; i++) {
|
| cb = callbacks[i];
|
| if (cb === fn || cb.fn === fn) {
|
| callbacks.splice(i, 1);
|
| break;
|
| }
|
| }
|
| return this;
|
| };
|
|
|
| /**
|
| * Emit `event` with the given args.
|
| *
|
| * @param {String} event
|
| * @param {Mixed} ...
|
| * @return {Emitter}
|
| */
|
|
|
| Emitter.prototype.emit = function(event){
|
| this._callbacks = this._callbacks || {};
|
| var args = [].slice.call(arguments, 1)
|
| , callbacks = this._callbacks['$' + event];
|
|
|
| if (callbacks) {
|
| callbacks = callbacks.slice(0);
|
| for (var i = 0, len = callbacks.length; i < len; ++i) {
|
| callbacks[i].apply(this, args);
|
| }
|
| }
|
|
|
| return this;
|
| };
|
|
|
| /**
|
| * Return array of callbacks for `event`.
|
| *
|
| * @param {String} event
|
| * @return {Array}
|
| * @api public
|
| */
|
|
|
| Emitter.prototype.listeners = function(event){
|
| this._callbacks = this._callbacks || {};
|
| return this._callbacks['$' + event] || [];
|
| };
|
|
|
| /**
|
| * Check if this emitter has `event` handlers.
|
| *
|
| * @param {String} event
|
| * @return {Boolean}
|
| * @api public
|
| */
|
|
|
| Emitter.prototype.hasListeners = function(event){
|
| return !! this.listeners(event).length;
|
| };
|
| |
| },{}]},{},[1])(1) |
| }); |
| |
| |
| /*global JSONEditor*/ |
| 'use strict'; |
| |
| window.SwaggerUi = Backbone.Router.extend({ |
| |
| dom_id: 'swagger_ui', |
| |
| // Attributes |
| options: null, |
| api: null, |
| headerView: null, |
| mainView: null, |
| |
| // SwaggerUi accepts all the same options as SwaggerApi |
| initialize: function(options) { |
| options = options || {}; |
| |
| if (options.defaultModelRendering !== 'model') { |
| options.defaultModelRendering = 'schema'; |
| } |
| |
| if (!options.highlightSizeThreshold) { |
| options.highlightSizeThreshold = 100000; |
| } |
| |
| // Allow dom_id to be overridden |
| if (options.dom_id) { |
| this.dom_id = options.dom_id; |
| delete options.dom_id; |
| } |
| |
| if (!options.supportedSubmitMethods){ |
| options.supportedSubmitMethods = [ |
| 'get', |
| 'put', |
| 'post', |
| 'delete', |
| 'head', |
| 'options', |
| 'patch' |
| ]; |
| } |
| |
| if (typeof options.oauth2RedirectUrl === 'string') { |
| window.oAuthRedirectUrl = options.oauth2RedirectUrl; |
| } |
| |
| // Create an empty div which contains the dom_id |
| if (! $('#' + this.dom_id).length){ |
| $('body').append('<div id="' + this.dom_id + '"></div>') ; |
| } |
| |
| this.options = options; |
| |
| // set marked options |
| marked.setOptions({gfm: true}); |
| |
| // Set the callbacks |
| var that = this; |
| this.options.success = function() { return that.render(); }; |
| this.options.progress = function(d) { return that.showMessage(d); }; |
| this.options.failure = function(d) { return that.onLoadFailure(d); }; |
| |
| // Create view to handle the header inputs |
| this.headerView = new SwaggerUi.Views.HeaderView({el: $('#header')}); |
| |
| // Event handler for when the baseUrl/apiKey is entered by user |
| this.headerView.on('update-swagger-ui', function(data) { |
| return that.updateSwaggerUi(data); |
| }); |
| |
| // JSon Editor custom theming |
| JSONEditor.defaults.iconlibs.swagger = JSONEditor.AbstractIconLib.extend({ |
| mapping: { |
| collapse: 'collapse', |
| expand: 'expand' |
| }, |
| icon_prefix: 'swagger-' |
| }); |
| |
| }, |
| |
| // Set an option after initializing |
| setOption: function(option, value) { |
| this.options[option] = value; |
| }, |
| |
| // Get the value of a previously set option |
| getOption: function(option) { |
| return this.options[option]; |
| }, |
| |
| // Event handler for when url/key is received from user |
| updateSwaggerUi: function(data){ |
| this.options.url = data.url; |
| this.load(); |
| }, |
| |
| // Create an api and render |
| load: function(){ |
| // Initialize the API object |
| if (this.mainView) { |
| this.mainView.clear(); |
| } |
| |
| if (this.authView) { |
| this.authView.remove(); |
| } |
| var url = this.options.url; |
| if (url && url.indexOf('http') !== 0) { |
| url = this.buildUrl(window.location.href.toString(), url); |
| } |
| if(this.api) { |
| this.options.authorizations = this.api.clientAuthorizations.authz; |
| } |
| this.options.url = url; |
| this.headerView.update(url); |
| |
| this.api = new SwaggerClient(this.options); |
| }, |
| |
| // collapse all sections |
| collapseAll: function(){ |
| Docs.collapseEndpointListForResource(''); |
| }, |
| |
| // list operations for all sections |
| listAll: function(){ |
| Docs.collapseOperationsForResource(''); |
| }, |
| |
| // expand operations for all sections |
| expandAll: function(){ |
| Docs.expandOperationsForResource(''); |
| }, |
| |
| // This is bound to success handler for SwaggerApi |
| // so it gets called when SwaggerApi completes loading |
| render: function(){ |
| var authsModel; |
| this.showMessage('Finished Loading Resource Information. Rendering Swagger UI...'); |
| this.mainView = new SwaggerUi.Views.MainView({ |
| model: this.api, |
| el: $('#' + this.dom_id), |
| swaggerOptions: this.options, |
| router: this |
| }).render(); |
| if (!_.isEmpty(this.api.securityDefinitions)){ |
| authsModel = _.map(this.api.securityDefinitions, function (auth, name) { |
| var result = {}; |
| result[name] = auth; |
| return result; |
| }); |
| this.authView = new SwaggerUi.Views.AuthButtonView({ |
| data: SwaggerUi.utils.parseSecurityDefinitions(authsModel), |
| router: this |
| }); |
| $('#auth_container').append(this.authView.render().el); |
| } |
| this.showMessage(); |
| switch (this.options.docExpansion) { |
| case 'full': |
| this.expandAll(); break; |
| case 'list': |
| this.listAll(); break; |
| default: |
| break; |
| } |
| this.renderGFM(); |
| |
| if (this.options.onComplete){ |
| this.options.onComplete(this.api, this); |
| } |
| |
| setTimeout(Docs.shebang.bind(this), 100); |
| }, |
| |
| buildUrl: function(base, url){ |
| if (url.indexOf('/') === 0) { |
| var parts = base.split('/'); |
| base = parts[0] + '//' + parts[2]; |
| return base + url; |
| } else { |
| var endOfPath = base.length; |
| |
| if (base.indexOf('?') > -1){ |
| endOfPath = Math.min(endOfPath, base.indexOf('?')); |
| } |
| |
| if (base.indexOf('#') > -1){ |
| endOfPath = Math.min(endOfPath, base.indexOf('#')); |
| } |
| |
| base = base.substring(0, endOfPath); |
| |
| if (base.indexOf('/', base.length - 1 ) !== -1){ |
| return base + url; |
| } |
| |
| return base + '/' + url; |
| } |
| }, |
| |
| // Shows message on topbar of the ui |
| showMessage: function(data){ |
| if (data === undefined) { |
| data = ''; |
| } |
| var $msgbar = $('#message-bar'); |
| $msgbar.removeClass('message-fail'); |
| $msgbar.addClass('message-success'); |
| $msgbar.text(data); |
| if(window.SwaggerTranslator) { |
| window.SwaggerTranslator.translate($msgbar); |
| } |
| }, |
| |
| // shows message in red |
| onLoadFailure: function(data){ |
| if (data === undefined) { |
| data = ''; |
| } |
| $('#message-bar').removeClass('message-success'); |
| $('#message-bar').addClass('message-fail'); |
| |
| var val = $('#message-bar').text(data); |
| |
| if (this.options.onFailure) { |
| this.options.onFailure(data); |
| } |
| |
| return val; |
| }, |
| |
| // Renders GFM for elements with 'markdown' class |
| renderGFM: function(){ |
| $('.markdown').each(function(){ |
| $(this).html(marked($(this).html())); |
| }); |
| |
| $('.propDesc', '.model-signature .description').each(function () { |
| $(this).html(marked($(this).html())).addClass('markdown'); |
| }); |
| } |
| |
| }); |
| |
| window.SwaggerUi.Views = {}; |
| window.SwaggerUi.Models = {}; |
| window.SwaggerUi.Collections = {}; |
| window.SwaggerUi.partials = {}; |
| window.SwaggerUi.utils = {}; |
| |
| // don't break backward compatibility with previous versions and warn users to upgrade their code |
| (function(){ |
| window.authorizations = { |
| add: function() { |
| warn('Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add().'); |
| |
| if (typeof window.swaggerUi === 'undefined') { |
| throw new TypeError('window.swaggerUi is not defined'); |
| } |
| |
| if (window.swaggerUi instanceof SwaggerUi) { |
| window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations, arguments); |
| } |
| } |
| }; |
| |
| window.ApiKeyAuthorization = function() { |
| warn('window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization.'); |
| SwaggerClient.ApiKeyAuthorization.apply(window, arguments); |
| }; |
| |
| window.PasswordAuthorization = function() { |
| warn('window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization.'); |
| SwaggerClient.PasswordAuthorization.apply(window, arguments); |
| }; |
| |
| function warn(message) { |
| if ('console' in window && typeof window.console.warn === 'function') { |
| console.warn(message); |
| } |
| } |
| })(); |
| |
| |
| // UMD |
| (function (root, factory) { |
| if (typeof define === 'function' && define.amd) { |
| // AMD. Register as an anonymous module. |
| define(['b'], function (b) { |
| return (root.SwaggerUi = factory(b)); |
| }); |
| } else if (typeof exports === 'object') { |
| // Node. Does not work with strict CommonJS, but |
| // only CommonJS-like environments that support module.exports, |
| // like Node. |
| module.exports = factory(require('b')); |
| } else { |
| // Browser globals |
| root.SwaggerUi = factory(root.b); |
| } |
| }(this, function () { |
| return SwaggerUi; |
| })); |
| |
| 'use strict'; |
| |
| window.SwaggerUi.utils = { |
| parseSecurityDefinitions: function (security, securityDefinitions) { |
| var auths = Object.assign({}, securityDefinitions); |
| var oauth2Arr = []; |
| var authsArr = []; |
| var scopes = []; |
| var utils = window.SwaggerUi.utils; |
| |
| if (!Array.isArray(security)) { return null; } |
| |
| security.forEach(function (item) { |
| var singleSecurity = {}; |
| var singleOauth2Security = {}; |
| |
| for (var key in item) { |
| if (Array.isArray(item[key])) { |
| if (!auths[key]) { continue; } |
| auths[key] = auths[key] || {}; |
| if (auths[key].type === 'oauth2') { |
| singleOauth2Security[key] = Object.assign({}, auths[key]); |
| singleOauth2Security[key].scopes = Object.assign({}, auths[key].scopes); |
| for (var i in singleOauth2Security[key].scopes) { |
| if (item[key].indexOf(i) < 0) { |
| delete singleOauth2Security[key].scopes[i]; |
| } |
| } |
| singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes); |
| scopes = _.merge(scopes, singleOauth2Security[key].scopes); |
| } else { |
| singleSecurity[key] = Object.assign({}, auths[key]); |
| } |
| } else { |
| if (item[key].type === 'oauth2') { |
| singleOauth2Security[key] = Object.assign({}, item[key]); |
| singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes); |
| scopes = _.merge(scopes, singleOauth2Security[key].scopes); |
| } else { |
| singleSecurity[key] = item[key]; |
| } |
| } |
| } |
| |
| if (!_.isEmpty(singleSecurity)) { |
| authsArr.push(singleSecurity); |
| } |
| |
| if (!_.isEmpty(singleOauth2Security)){ |
| oauth2Arr.push(singleOauth2Security); |
| } |
| }); |
| |
| return { |
| auths : authsArr, |
| oauth2: oauth2Arr, |
| scopes: scopes |
| }; |
| }, |
| |
| parseOauth2Scopes: function (data) { |
| var scopes = Object.assign({}, data); |
| var result = []; |
| var key; |
| |
| for (key in scopes) { |
| result.push({scope: key, description: scopes[key]}); |
| } |
| |
| return result; |
| }, |
| |
| sanitize: function(html) { |
| // Strip the script tags from the html and inline evenhandlers |
| html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, ''); |
| html = html.replace(/(on\w+="[^"]*")*(on\w+='[^']*')*(on\w+=\w*\(\w*\))*/gi, ''); |
| |
| return html; |
| } |
| }; |
| 'use strict'; |
| |
| SwaggerUi.Models.ApiKeyAuthModel = Backbone.Model.extend({ |
| defaults: { |
| 'in': '', |
| name: '', |
| title: '', |
| value: '' |
| }, |
| |
| initialize: function () { |
| this.on('change', this.validate); |
| }, |
| |
| validate: function () { |
| var valid = !!this.get('value'); |
| |
| this.set('valid', valid); |
| |
| return valid; |
| } |
| }); |
| 'use strict'; |
| |
| SwaggerUi.Views.ApiKeyAuthView = Backbone.View.extend({ // TODO: append this to global SwaggerUi |
| |
| events: { |
| 'change .input_apiKey_entry': 'apiKeyChange' |
| }, |
| |
| selectors: { |
| apikeyInput: '.input_apiKey_entry' |
| }, |
| |
| template: Handlebars.templates.apikey_auth, |
| |
| initialize: function(opts) { |
| this.options = opts || {}; |
| this.router = this.options.router; |
| }, |
| |
| render: function (){ |
| this.$el.html(this.template(this.model.toJSON())); |
| |
| return this; |
| }, |
| |
| apiKeyChange: function (e) { |
| var val = $(e.target).val(); |
| if (val) { |
| this.$(this.selectors.apikeyInput).removeClass('error'); |
| } |
| |
| this.model.set('value', val); |
| }, |
| |
| isValid: function () { |
| return this.model.validate(); |
| }, |
| |
| highlightInvalid: function () { |
| if (!this.isValid()) { |
| this.$(this.selectors.apikeyInput).addClass('error'); |
| } |
| } |
| |
| }); |
| 'use strict'; |
| |
| SwaggerUi.Views.AuthButtonView = Backbone.View.extend({ |
| events: { |
| 'click .authorize__btn': 'authorizeBtnClick' |
| }, |
| |
| tpls: { |
| popup: Handlebars.templates.popup, |
| authBtn: Handlebars.templates.auth_button, |
| authBtnOperation: Handlebars.templates.auth_button_operation |
| }, |
| |
| initialize: function(opts) { |
| this.options = opts || {}; |
| this.options.data = this.options.data || {}; |
| this.isOperation = this.options.isOperation; |
| this.model = this.model || {}; |
| this.router = this.options.router; |
| this.auths = this.options.data.oauth2.concat(this.options.data.auths); |
| }, |
| |
| render: function () { |
| var tplName = this.isOperation ? 'authBtnOperation' : 'authBtn'; |
| |
| this.$authEl = this.renderAuths(this.auths); |
| this.$el.html(this.tpls[tplName](this.model)); |
| |
| return this; |
| }, |
| |
| authorizeBtnClick: function (e) { |
| var authsModel; |
| |
| e.preventDefault(); |
| |
| authsModel = { |
| title: 'Available authorizations', |
| content: this.$authEl |
| }; |
| |
| // The content of the popup is removed and all events unbound after clicking the 'Cancel' button of the popup. |
| // We'll have to re-render the contents before creating a new popup view. |
| this.render(); |
| |
| this.popup = new SwaggerUi.Views.PopupView({model: authsModel}); |
| this.popup.render(); |
| }, |
| |
| renderAuths: function (auths) { |
| var $el = $('<div>'); |
| var isLogout = false; |
| |
| auths.forEach(function (auth) { |
| var authView = new SwaggerUi.Views.AuthView({data: auth, router: this.router}); |
| var authEl = authView.render().el; |
| $el.append(authEl); |
| if (authView.isLogout) { |
| isLogout = true; |
| } |
| }, this); |
| |
| this.model.isLogout = isLogout; |
| |
| return $el; |
| } |
| |
| }); |
| |
| 'use strict'; |
| |
| SwaggerUi.Collections.AuthsCollection = Backbone.Collection.extend({ |
| constructor: function() { |
| var args = Array.prototype.slice.call(arguments); |
| |
| args[0] = this.parse(args[0]); |
| |
| Backbone.Collection.apply(this, args); |
| }, |
| |
| add: function (model) { |
| var args = Array.prototype.slice.call(arguments); |
| |
| if (Array.isArray(model)) { |
| args[0] = _.map(model, function(val) { |
| return this.handleOne(val); |
| }, this); |
| } else { |
| args[0] = this.handleOne(model); |
| } |
| |
| Backbone.Collection.prototype.add.apply(this, args); |
| }, |
| |
| handleOne: function (model) { |
| var result = model; |
| |
| if (! (model instanceof Backbone.Model) ) { |
| switch (model.type) { |
| case 'oauth2': |
| result = new SwaggerUi.Models.Oauth2Model(model); |
| break; |
| case 'basic': |
| result = new SwaggerUi.Models.BasicAuthModel(model); |
| break; |
| case 'apiKey': |
| result = new SwaggerUi.Models.ApiKeyAuthModel(model); |
| break; |
| default: |
| result = new Backbone.Model(model); |
| } |
| } |
| |
| return result; |
| }, |
| |
| isValid: function () { |
| var valid = true; |
| |
| this.models.forEach(function(model) { |
| if (!model.validate()) { |
| valid = false; |
| } |
| }); |
| |
| return valid; |
| }, |
| |
| isAuthorized: function () { |
| return this.length === this.where({ isLogout: true }).length; |
| }, |
| |
| isPartiallyAuthorized: function () { |
| return this.where({ isLogout: true }).length > 0; |
| }, |
| |
| parse: function (data) { |
| var authz = {}; |
| |
| if(typeof window.swaggerUi !== 'undefined') { |
| authz = Object.assign({}, window.swaggerUi.api.clientAuthorizations.authz); |
| } |
| |
| return _.map(data, function (auth, name) { |
| var isBasic = authz[name] && auth.type === 'basic' && authz[name].username && authz[name].password; |
| |
| _.extend(auth, { |
| title: name |
| }); |
| |
| if (authz[name] || isBasic) { |
| _.extend(auth, { |
| isLogout: true, |
| value: isBasic ? undefined : authz[name].value, |
| username: isBasic ? authz[name].username : undefined, |
| password: isBasic ? authz[name].password : undefined, |
| valid: true |
| }); |
| } |
| |
| return auth; |
| }); |
| } |
| }); |
| 'use strict'; |
| |
| SwaggerUi.Views.AuthsCollectionView = Backbone.View.extend({ |
| |
| initialize: function(opts) { |
| this.options = opts || {}; |
| this.options.data = this.options.data || {}; |
| this.router = this.options.router; |
| |
| this.collection = new SwaggerUi.Collections.AuthsCollection(opts.data); |
| |
| this.$innerEl = $('<div>'); |
| this.authViews = []; |
| }, |
| |
| render: function () { |
| this.collection.each(function (auth) { |
| this.renderOneAuth(auth); |
| }, this); |
| |
| this.$el.html(this.$innerEl.html() ? this.$innerEl : ''); |
| |
| return this; |
| }, |
| |
| renderOneAuth: function (authModel) { |
| var authViewEl, authView, authViewName; |
| var type = authModel.get('type'); |
| |
| if (type === 'apiKey') { |
| authViewName = 'ApiKeyAuthView'; |
| } else if (type === 'basic' && this.$innerEl.find('.basic_auth_container').length === 0) { |
| authViewName = 'BasicAuthView'; |
| } else if (type === 'oauth2') { |
| authViewName = 'Oauth2View'; |
| } |
| |
| if (authViewName) { |
| authView = new SwaggerUi.Views[authViewName]({model: authModel, router: this.router}); |
| authViewEl = authView.render().el; |
| this.authViews.push(authView); |
| } |
| |
| this.$innerEl.append(authViewEl); |
| }, |
| |
| highlightInvalid: function () { |
| this.authViews.forEach(function (view) { |
| view.highlightInvalid(); |
| }, this); |
| } |
| |
| }); |
| |
| 'use strict'; |
| |
| /* global redirect_uri:true */ |
| /* global clientId */ |
| /* global scopeSeparator */ |
| /* global additionalQueryStringParams */ |
| /* global clientSecret */ |
| /* global onOAuthComplete */ |
| /* global realm */ |
| /*jshint unused:false*/ |
| |
| SwaggerUi.Views.AuthView = Backbone.View.extend({ |
| events: { |
| 'click .auth_submit__button': 'authorizeClick', |
| 'click .auth_logout__button': 'logoutClick' |
| }, |
| |
| tpls: { |
| main: Handlebars.templates.auth_view |
| }, |
| |
| selectors: { |
| innerEl: '.auth_inner', |
| authBtn: '.auth_submit__button' |
| }, |
| |
| initialize: function(opts) { |
| this.options = opts || {}; |
| opts.data = opts.data || {}; |
| this.router = this.options.router; |
| |
| this.authsCollectionView = new SwaggerUi.Views.AuthsCollectionView({data: opts.data}); |
| |
| this.$el.html(this.tpls.main({ |
| isLogout: this.authsCollectionView.collection.isAuthorized(), |
| isAuthorized: this.authsCollectionView.collection.isPartiallyAuthorized() |
| })); |
| this.$innerEl = this.$(this.selectors.innerEl); |
| this.isLogout = this.authsCollectionView.collection.isPartiallyAuthorized(); |
| }, |
| |
| render: function () { |
| this.$innerEl.html(this.authsCollectionView.render().el); |
| |
| return this; |
| }, |
| |
| authorizeClick: function (e) { |
| e.preventDefault(); |
| e.stopPropagation(); |
| |
| if (this.authsCollectionView.collection.isValid()) { |
| this.authorize(); |
| } else { |
| this.authsCollectionView.highlightInvalid(); |
| } |
| }, |
| |
| authorize: function () { |
| this.authsCollectionView.collection.forEach(function (auth) { |
| var keyAuth, basicAuth; |
| var type = auth.get('type'); |
| |
| if (type === 'apiKey') { |
| keyAuth = new SwaggerClient.ApiKeyAuthorization( |
| auth.get('name'), |
| auth.get('value'), |
| auth.get('in') |
| ); |
| |
| this.router.api.clientAuthorizations.add(auth.get('title'), keyAuth); |
| } else if (type === 'basic') { |
| basicAuth = new SwaggerClient.PasswordAuthorization(auth.get('username'), auth.get('password')); |
| this.router.api.clientAuthorizations.add(auth.get('title'), basicAuth); |
| } else if (type === 'oauth2') { |
| this.handleOauth2Login(auth); |
| } |
| }, this); |
| |
| this.router.load(); |
| }, |
| |
| logoutClick: function (e) { |
| e.preventDefault(); |
| |
| this.authsCollectionView.collection.forEach(function (auth) { |
| window.swaggerUi.api.clientAuthorizations.remove(auth.get('title')); |
| }); |
| |
| this.router.load(); |
| }, |
| |
| // taken from lib/swagger-oauth.js |
| handleOauth2Login: function (auth) { |
| var host = window.location; |
| var pathname = location.pathname.substring(0, location.pathname.lastIndexOf('/')); |
| var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html'; |
| var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl; |
| var url = null; |
| var scopes = _.map(auth.get('scopes'), function (scope) { |
| if(scope.checked) { |
| return scope.scope; |
| } |
| }); |
| var container = window.swaggerUiAuth || (window.swaggerUiAuth = {}); |
| var state, dets, ep; |
| container.OAuthSchemeKey = auth.get('title'); |
| |
| window.enabledScopes = scopes; |
| var flow = auth.get('flow'); |
| |
| /** |
| * Returns the name of the access token parameter returned by the server. |
| * |
| * @param dets |
| * The authorisation scheme configuration. |
| * @return the name of the access token parameter |
| */ |
| function getTokenName(dets) { |
| return dets.vendorExtensions['x-tokenName'] || dets.tokenName; |
| } |
| |
| if(auth.get('type') === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) { |
| dets = auth.attributes; |
| url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code'); |
| container.tokenName = getTokenName(dets) || 'access_token'; |
| container.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null); |
| state = container.OAuthSchemeKey; |
| } |
| else if(auth.get('type') === 'oauth2' && flow && (flow === 'application')) { |
| dets = auth.attributes; |
| container.tokenName = getTokenName(dets) || 'access_token'; |
| this.clientCredentialsFlow(scopes, dets, container.OAuthSchemeKey); |
| return; |
| } |
| else if(auth.get('type') === 'oauth2' && flow && (flow === 'password')) { |
| dets = auth.attributes; |
| container.tokenName = getTokenName(dets) || 'access_token'; |
| this.passwordFlow(scopes, dets, container.OAuthSchemeKey); |
| return; |
| } |
| else if(auth.get('grantTypes')) { |
| // 1.2 support |
| var o = auth.get('grantTypes'); |
| for(var t in o) { |
| if(o.hasOwnProperty(t) && t === 'implicit') { |
| dets = o[t]; |
| ep = dets.loginEndpoint.url; |
| url = dets.loginEndpoint.url + '?response_type=token'; |
| container.tokenName = getTokenName(dets); |
| } |
| else if (o.hasOwnProperty(t) && t === 'accessCode') { |
| dets = o[t]; |
| ep = dets.tokenRequestEndpoint.url; |
| url = dets.tokenRequestEndpoint.url + '?response_type=code'; |
| container.tokenName = getTokenName(dets); |
| } |
| } |
| } |
| |
| redirect_uri = redirectUrl; |
| |
| url += '&redirect_uri=' + encodeURIComponent(redirectUrl); |
| url += '&realm=' + encodeURIComponent(realm); |
| url += '&client_id=' + encodeURIComponent(clientId); |
| url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator)); |
| url += '&state=' + encodeURIComponent(state); |
| for (var key in additionalQueryStringParams) { |
| url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]); |
| } |
| |
| window.open(url); |
| }, |
| |
| // taken from lib/swagger-oauth.js |
| clientCredentialsFlow: function (scopes, oauth, OAuthSchemeKey) { |
| this.accessTokenRequest(scopes, oauth, OAuthSchemeKey, 'client_credentials'); |
| }, |
| |
| passwordFlow: function (scopes, oauth, OAuthSchemeKey) { |
| this.accessTokenRequest(scopes, oauth, OAuthSchemeKey, 'password', { |
| 'username': oauth.username, |
| 'password': oauth.password |
| }); |
| }, |
| |
| accessTokenRequest: function (scopes, oauth, OAuthSchemeKey, grantType, params) { |
| params = $.extend({}, { |
| 'scope': scopes.join(' '), |
| 'grant_type': grantType |
| }, params); |
| |
| var headers= {}; |
| |
| switch (oauth.clientAuthenticationType) { |
| case 'basic': |
| headers.Authorization = 'Basic ' + btoa(oauth.clientId + ':' + oauth.clientSecret); |
| break; |
| case 'request-body': |
| params.client_id = oauth.clientId; |
| params.client_secret = oauth.clientSecret; |
| break; |
| } |
| |
| $.ajax({ |
| url : oauth.tokenUrl, |
| type: 'POST', |
| data: params, |
| headers: headers, |
| success: function (data) |
| { |
| onOAuthComplete(data, OAuthSchemeKey); |
| }, |
| error: function () |
| { |
| onOAuthComplete(''); |
| } |
| }); |
| } |
| }); |
| |
| 'use strict'; |
| |
| SwaggerUi.Models.BasicAuthModel = Backbone.Model.extend({ |
| defaults: { |
| username: '', |
| password: '', |
| title: 'basic' |
| }, |
| |
| initialize: function () { |
| this.on('change', this.validate); |
| }, |
| |
| validate: function () { |
| var valid = !!this.get('password') && !!this.get('username'); |
| |
| this.set('valid', valid); |
| |
| return valid; |
| } |
| }); |
| 'use strict'; |
| |
| SwaggerUi.Views.BasicAuthView = Backbone.View.extend({ |
| |
| initialize: function (opts) { |
| this.options = opts || {}; |
| this.router = this.options.router; |
| }, |
| |
| events: { |
| 'change .auth_input': 'inputChange' |
| }, |
| |
| selectors: { |
| usernameInput: '.basic_auth__username', |
| passwordInput: '.basic_auth__password' |
| }, |
| |
| cls: { |
| error: 'error' |
| }, |
| |
| template: Handlebars.templates.basic_auth, |
| |
| render: function(){ |
| $(this.el).html(this.template(this.model.toJSON())); |
| |
| return this; |
| }, |
| |
| inputChange: function (e) { |
| var $el = $(e.target); |
| var val = $el.val(); |
| var attr = $el.prop('name'); |
| |
| if (val) { |
| $el.removeClass(this.cls.error); |
| } |
| |
| this.model.set(attr, val); |
| }, |
| |
| isValid: function () { |
| return this.model.validate(); |
| }, |
| |
| highlightInvalid: function () { |
| if (!this.model.get('username')) { |
| this.$(this.selectors.usernameInput).addClass(this.cls.error); |
| } |
| } |
| }); |
| |
| 'use strict'; |
| |
| SwaggerUi.Views.ContentTypeView = Backbone.View.extend({ |
| initialize: function() {}, |
| |
| render: function(){ |
| this.model.contentTypeId = 'ct' + Math.random(); |
| $(this.el).html(Handlebars.templates.content_type(this.model)); |
| return this; |
| } |
| }); |
| 'use strict'; |
| |
| SwaggerUi.Views.HeaderView = Backbone.View.extend({ |
| events: { |
| 'click #show-pet-store-icon' : 'showPetStore', |
| 'click #explore' : 'showCustom', |
| 'submit #api_selector' : 'showCustom', |
| 'keyup #input_baseUrl' : 'showCustomOnKeyup', |
| 'keyup #input_apiKey' : 'showCustomOnKeyup' |
| }, |
| |
| initialize: function(){}, |
| |
| showPetStore: function(){ |
| this.trigger('update-swagger-ui', { |
| url:'http://petstore.swagger.io/v2/swagger.json' |
| }); |
| }, |
| |
| showCustomOnKeyup: function(e){ |
| if (e.keyCode === 13) { |
| this.showCustom(); |
| } |
| }, |
| |
| showCustom: function(e){ |
| if (e) { |
| e.preventDefault(); |
| } |
| |
| this.trigger('update-swagger-ui', { |
| url: $('#input_baseUrl').val() |
| }); |
| }, |
| |
| update: function(url, apiKey, trigger){ |
| if (trigger === undefined) { |
| trigger = false; |
| } |
| |
| $('#input_baseUrl').val(url); |
| |
| if (trigger) { |
| this.trigger('update-swagger-ui', {url:url}); |
| } |
| } |
| }); |
| |
| 'use strict'; |
| |
| SwaggerUi.Views.MainView = Backbone.View.extend({ |
| apisSorter : { |
| alpha : function(a,b){ return a.name.localeCompare(b.name); } |
| }, |
| operationsSorters : { |
| alpha : function(a,b){ return a.path.localeCompare(b.path); }, |
| method : function(a,b){ return a.method.localeCompare(b.method); } |
| }, |
| initialize: function(opts){ |
| var sorterOption, sorterFn, key, value; |
| opts = opts || {}; |
| |
| this.router = opts.router; |
| |
| // Sort APIs |
| if (opts.swaggerOptions.apisSorter) { |
| sorterOption = opts.swaggerOptions.apisSorter; |
| if (_.isFunction(sorterOption)) { |
| sorterFn = sorterOption; |
| } else { |
| sorterFn = this.apisSorter[sorterOption]; |
| } |
| if (_.isFunction(sorterFn)) { |
| this.model.apisArray.sort(sorterFn); |
| } |
| } |
| // Sort operations of each API |
| if (opts.swaggerOptions.operationsSorter) { |
| sorterOption = opts.swaggerOptions.operationsSorter; |
| if (_.isFunction(sorterOption)) { |
| sorterFn = sorterOption; |
| } else { |
| sorterFn = this.operationsSorters[sorterOption]; |
| } |
| if (_.isFunction(sorterFn)) { |
| for (key in this.model.apisArray) { |
| this.model.apisArray[key].operationsArray.sort(sorterFn); |
| } |
| } |
| } |
| |
| // set up the UI for input |
| this.model.auths = []; |
| |
| for (key in this.model.securityDefinitions) { |
| value = this.model.securityDefinitions[key]; |
| |
| this.model.auths.push({ |
| name: key, |
| type: value.type, |
| value: value |
| }); |
| } |
| |
| if ('validatorUrl' in opts.swaggerOptions) { |
| // Validator URL specified explicitly |
| this.model.validatorUrl = opts.swaggerOptions.validatorUrl; |
| } else if (this.model.url.indexOf('localhost') > 0 || this.model.url.indexOf('127.0.0.1') > 0) { |
| // Localhost override |
| this.model.validatorUrl = null; |
| } else { |
| this.model.validatorUrl = '//online.swagger.io/validator'; |
| } |
| |
| // JSonEditor requires type='object' to be present on defined types, we add it if it's missing |
| // is there any valid case were it should not be added ? |
| var def; |
| for(def in this.model.definitions){ |
| if (!this.model.definitions[def].type){ |
| this.model.definitions[def].type = 'object'; |
| } |
| } |
| |
| }, |
| |
| render: function () { |
| $(this.el).html(Handlebars.templates.main(this.model)); |
| this.info = this.$('.info')[0]; |
| |
| if (this.info) { |
| this.info.addEventListener('click', this.onLinkClick, true); |
| } |
| |
| this.model.securityDefinitions = this.model.securityDefinitions || {}; |
| |
| // Render each resource |
| |
| var resources = {}; |
| var counter = 0; |
| for (var i = 0; i < this.model.apisArray.length; i++) { |
| var resource = this.model.apisArray[i]; |
| var id = resource.name; |
| while (typeof resources[id] !== 'undefined') { |
| id = id + '_' + counter; |
| counter += 1; |
| } |
| resource.id = sanitizeHtml(id); |
| resources[id] = resource; |
| this.addResource(resource, this.model.auths); |
| } |
| |
| $('.propWrap').hover(function onHover(){ |
| $('.optionsWrapper', $(this)).show(); |
| }, function offhover(){ |
| $('.optionsWrapper', $(this)).hide(); |
| }); |
| return this; |
| }, |
| |
| addResource: function(resource, auths){ |
| // Render a resource and add it to resources li |
| resource.id = resource.id.replace(/[^a-zA-Z\d]/g, function(str) { return str.charCodeAt(0); }); |
| |
| // Make all definitions available at the root of the resource so that they can |
| // be loaded by the JSonEditor |
| resource.definitions = this.model.definitions; |
| |
| var resourceView = new SwaggerUi.Views.ResourceView({ |
| model: resource, |
| router: this.router, |
| tagName: 'li', |
| id: 'resource_' + resource.id, |
| className: 'resource', |
| auths: auths, |
| swaggerOptions: this.options.swaggerOptions |
| }); |
| $('#resources', this.el).append(resourceView.render().el); |
| }, |
| |
| clear: function(){ |
| $(this.el).html(''); |
| }, |
| |
| onLinkClick: function (e) { |
| var el = e.target; |
| |
| if (el.tagName === 'A' && el.href && !el.target) { |
| e.preventDefault(); |
| window.open(el.href, '_blank'); |
| } |
| } |
| }); |
| |
| 'use strict'; |
| |
| SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({ |
| defaults: { |
| scopes: {}, |
| isPasswordFlow: false, |
| clientAuthenticationType: 'none' |
| }, |
| |
| initialize: function () { |
| if(this.attributes && this.attributes.scopes) { |
| var attributes = _.cloneDeep(this.attributes); |
| var i, scopes = []; |
| for(i in attributes.scopes) { |
| var scope = attributes.scopes[i]; |
| if(typeof scope.description === 'string') { |
| scopes[scope] = attributes.scopes[i]; |
| scopes.push(attributes.scopes[i]); |
| } |
| } |
| attributes.scopes = scopes; |
| this.attributes = attributes; |
| } |
| |
| if (this.attributes && this.attributes.flow) { |
| var flow = this.attributes.flow; |
| this.set('isPasswordFlow', flow === 'password'); |
| this.set('requireClientAuthentication', flow === 'application'); |
| this.set('clientAuthentication', flow === 'password' || flow === 'application'); |
| } |
| this.on('change', this.validate); |
| }, |
| |
| setScopes: function (name, val) { |
| var auth = _.extend({}, this.attributes); |
| var index = _.findIndex(auth.scopes, function(o) { |
| return o.scope === name; |
| }); |
| auth.scopes[index].checked = val; |
| |
| this.set(auth); |
| this.validate(); |
| }, |
| |
| validate: function () { |
| var valid = false; |
| if (this.get('isPasswordFlow') && |
| (!this.get('username'))) { |
| return false; |
| } |
| |
| if (this.get('clientAuthenticationType') in ['basic', 'request-body'] && |
| (!this.get('clientId'))) { |
| return false; |
| } |
| |
| var scp = this.get('scopes'); |
| var idx = _.findIndex(scp, function (o) { |
| return o.checked === true; |
| }); |
| |
| if(scp.length > 0 && idx >= 0) { |
| valid = true; |
| } |
| |
| if(scp.length === 0) { |
| valid = true; |
| } |
| |
| this.set('valid', valid); |
| |
| return valid; |
| } |
| }); |
| |
| 'use strict'; |
| |
| SwaggerUi.Views.Oauth2View = Backbone.View.extend({ |
| events: { |
| 'change .oauth-scope': 'scopeChange', |
| 'change .oauth-username': 'setUsername', |
| 'change .oauth-password': 'setPassword', |
| 'change .oauth-client-authentication-type': 'setClientAuthenticationType', |
| 'change .oauth-client-id': 'setClientId', |
| 'change .oauth-client-secret': 'setClientSecret' |
| }, |
| |
| template: Handlebars.templates.oauth2, |
| |
| cls: { |
| error: 'error' |
| }, |
| |
| render: function () { |
| this.$el.html(this.template(this.model.toJSON())); |
| |
| return this; |
| }, |
| |
| scopeChange: function (e) { |
| var val = $(e.target).prop('checked'); |
| var scope = $(e.target).data('scope'); |
| |
| this.model.setScopes(scope, val); |
| }, |
| |
| setUsername: function (e) { |
| var val= $(e.target).val(); |
| this.model.set('username', val); |
| if (val) { |
| $(e.target).removeClass(this.cls.error); |
| } |
| }, |
| |
| setPassword: function (e) { |
| this.model.set('password', $(e.target).val()); |
| }, |
| |
| setClientAuthenticationType: function (e) { |
| var type = $(e.target).val(); |
| var $el = this.$el; |
| this.model.set('clientAuthenticationType', type); |
| |
| switch(type) { |
| case 'none': |
| $el.find('.oauth-client-authentication').hide(); |
| break; |
| case 'basic': |
| case 'request-body': |
| $el.find('.oauth-client-id').removeClass(this.cls.error); |
| $el.find('.oauth-client-authentication').show(); |
| break; |
| } |
| }, |
| |
| setClientId: function (e) { |
| var val = $(e.target).val(); |
| this.model.set('clientId', val); |
| if (val) { |
| $(e.target).removeClass(this.cls.error); |
| } |
| }, |
| |
| setClientSecret: function (e) { |
| this.model.set('clientSecret', $(e.target).val()); |
| $(e.target).removeClass('error'); |
| }, |
| |
| highlightInvalid: function () { |
| if (!this.model.get('username')) { |
| this.$el.find('.oauth-username').addClass(this.cls.error); |
| } |
| |
| if (!this.model.get('clientId')) { |
| this.$el.find('.oauth-client-id').addClass(this.cls.error); |
| } |
| } |
| }); |
| 'use strict'; |
| |
| SwaggerUi.Views.OperationView = Backbone.View.extend({ |
| invocationUrl: null, |
| |
| events: { |
| 'submit .sandbox' : 'submitOperation', |
| 'click .submit' : 'submitOperation', |
| 'click .response_hider' : 'hideResponse', |
| 'click .toggleOperation' : 'toggleOperationContent', |
| 'mouseenter .api-ic' : 'mouseEnter', |
| 'dblclick .curl' : 'selectText', |
| 'change [name=responseContentType]' : 'showSnippet' |
| }, |
| |
| initialize: function(opts) { |
| opts = opts || {}; |
| this.router = opts.router; |
| this.auths = opts.auths; |
| this.parentId = this.model.parentId; |
| this.nickname = this.model.nickname; |
| this.model.encodedParentId = encodeURIComponent(this.parentId); |
| |
| if (opts.swaggerOptions) { |
| this.model.defaultRendering = opts.swaggerOptions.defaultModelRendering; |
| |
| if (opts.swaggerOptions.showRequestHeaders) { |
| this.model.showRequestHeaders = true; |
| } |
| |
| if (opts.swaggerOptions.showOperationIds) { |
| this.model.showOperationIds = true; |
| } |
| } |
| return this; |
| }, |
| |
| selectText: function(event) { |
| var doc = document, |
| text = event.target.firstChild, |
| range, |
| selection; |
| if (doc.body.createTextRange) { |
| range = document.body.createTextRange(); |
| range.moveToElementText(text); |
| range.select(); |
| } else if (window.getSelection) { |
| selection = window.getSelection(); |
| range = document.createRange(); |
| range.selectNodeContents(text); |
| selection.removeAllRanges(); |
| selection.addRange(range); |
| } |
| }, |
| |
| mouseEnter: function(e) { |
| var elem = $(this.el).find('.content'); |
| var x = e.pageX; |
| var y = e.pageY; |
| var scX = $(window).scrollLeft(); |
| var scY = $(window).scrollTop(); |
| var scMaxX = scX + $(window).width(); |
| var scMaxY = scY + $(window).height(); |
| var wd = elem.width(); |
| var hgh = elem.height(); |
| |
| if (x + wd > scMaxX) { |
| x = scMaxX - wd; |
| } |
| |
| if (x < scX) { |
| x = scX; |
| } |
| |
| if (y + hgh > scMaxY) { |
| y = scMaxY - hgh; |
| } |
| |
| if (y < scY) { |
| y = scY; |
| } |
| |
| var pos = {}; |
| pos.top = y; |
| pos.left = x; |
| elem.css(pos); |
| }, |
| |
| // Note: copied from CoffeeScript compiled file |
| // TODO: refactor |
| render: function() { |
| var a, auth, auths, code, contentTypeModel, isMethodSubmissionSupported, k, key, l, len, len1, len2, len3, len4, m, modelAuths, n, o, p, param, q, ref, ref1, ref2, ref3, ref4, ref5, responseContentTypeView, responseSignatureView, schema, schemaObj, scopeIndex, signatureModel, statusCode, successResponse, type, v, value, produces, isXML, isJSON; |
| isMethodSubmissionSupported = jQuery.inArray(this.model.method, this.model.supportedSubmitMethods()) >= 0; |
| if (!isMethodSubmissionSupported) { |
| this.model.isReadOnly = true; |
| } |
| this.model.description = this.model.description || this.model.notes; |
| this.model.oauth = null; |
| modelAuths = this.model.authorizations || this.model.security; |
| if (modelAuths) { |
| if (Array.isArray(modelAuths)) { |
| for (l = 0, len = modelAuths.length; l < len; l++) { |
| auths = modelAuths[l]; |
| for (key in auths) { |
| for (a in this.auths) { |
| auth = this.auths[a]; |
| if (key === auth.name) { |
| if (auth.type === 'oauth2') { |
| this.model.oauth = {}; |
| this.model.oauth.scopes = []; |
| ref1 = auth.value.scopes; |
| for (k in ref1) { |
| v = ref1[k]; |
| scopeIndex = auths[key].indexOf(k); |
| if (scopeIndex >= 0) { |
| o = { |
| scope: k, |
| description: v |
| }; |
| this.model.oauth.scopes.push(o); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } else { |
| for (k in modelAuths) { |
| v = modelAuths[k]; |
| if (k === 'oauth2') { |
| if (this.model.oauth === null) { |
| this.model.oauth = {}; |
| } |
| if (this.model.oauth.scopes === void 0) { |
| this.model.oauth.scopes = []; |
| } |
| for (m = 0, len1 = v.length; m < len1; m++) { |
| o = v[m]; |
| this.model.oauth.scopes.push(o); |
| } |
| } |
| } |
| } |
| } |
| if (typeof this.model.responses !== 'undefined') { |
| this.model.responseMessages = []; |
| ref2 = this.model.responses; |
| for (code in ref2) { |
| value = ref2[code]; |
| schema = null; |
| schemaObj = this.model.responses[code].schema; |
| if (schemaObj && schemaObj.$ref) { |
| schema = schemaObj.$ref; |
| if (schema.indexOf('#/definitions/') !== -1) { |
| schema = schema.replace(/^.*#\/definitions\//, ''); |
| } |
| } |
| this.model.responseMessages.push({ |
| code: code, |
| message: value.description, |
| responseModel: schema, |
| headers: value.headers, |
| schema: schemaObj |
| }); |
| } |
| } |
| if (typeof this.model.responseMessages === 'undefined') { |
| this.model.responseMessages = []; |
| } |
| signatureModel = null; |
| produces = this.model.produces; |
| isXML = this.contains(produces, 'xml'); |
| isJSON = isXML ? this.contains(produces, 'json') : true; |
| |
| if (this.model.successResponse) { |
| successResponse = this.model.successResponse; |
| for (key in successResponse) { |
| value = successResponse[key]; |
| this.model.successCode = key; |
| if (typeof value === 'object' && typeof value.createJSONSample === 'function') { |
| this.model.successDescription = value.description; |
| this.model.headers = this.parseResponseHeaders(value.headers); |
| signatureModel = { |
| sampleJSON: isJSON ? JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2) : false, |
| isParam: false, |
| sampleXML: isXML ? SwaggerUi.partials.signature.createXMLSample(value.name, value.definition, value.models) : false, |
| signature: SwaggerUi.partials.signature.getModelSignature(value.name, value.definition, value.models, value.modelPropertyMacro) |
| }; |
| } else { |
| signatureModel = { |
| signature: SwaggerUi.partials.signature.getPrimitiveSignature(value) |
| }; |
| } |
| } |
| } else if (this.model.responseClassSignature && this.model.responseClassSignature !== 'string') { |
| signatureModel = { |
| sampleJSON: this.model.responseSampleJSON, |
| isParam: false, |
| signature: this.model.responseClassSignature |
| }; |
| } |
| $(this.el).html(Handlebars.templates.operation(this.model)); |
| if (signatureModel) { |
| signatureModel.defaultRendering = this.model.defaultRendering; |
| responseSignatureView = new SwaggerUi.Views.SignatureView({ |
| model: signatureModel, |
| router: this.router, |
| tagName: 'div' |
| }); |
| $('.model-signature', $(this.el)).append(responseSignatureView.render().el); |
| } else { |
| this.model.responseClassSignature = 'string'; |
| $('.model-signature', $(this.el)).html(this.model.type); |
| } |
| contentTypeModel = { |
| isParam: false |
| }; |
| contentTypeModel.consumes = this.model.consumes; |
| contentTypeModel.produces = this.model.produces; |
| ref3 = this.model.parameters; |
| for (n = 0, len2 = ref3.length; n < len2; n++) { |
| param = ref3[n]; |
| type = param.type || param.dataType || ''; |
| if (typeof type === 'undefined') { |
| schema = param.schema; |
| if (schema && schema.$ref) { |
| ref = schema.$ref; |
| if (ref.indexOf('#/definitions/') === 0) { |
| type = ref.substring('#/definitions/'.length); |
| } else { |
| type = ref; |
| } |
| } |
| } |
| if (type && type.toLowerCase() === 'file') { |
| if (!contentTypeModel.consumes) { |
| contentTypeModel.consumes = 'multipart/form-data'; |
| } |
| } |
| param.type = type; |
| } |
| responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({ |
| model: contentTypeModel, |
| router: this.router |
| }); |
| $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el); |
| ref4 = this.model.parameters; |
| for (p = 0, len3 = ref4.length; p < len3; p++) { |
| param = ref4[p]; |
| this.addParameter(param, contentTypeModel.consumes); |
| } |
| ref5 = this.model.responseMessages; |
| for (q = 0, len4 = ref5.length; q < len4; q++) { |
| statusCode = ref5[q]; |
| statusCode.isXML = isXML; |
| statusCode.isJSON = isJSON; |
| if (!_.isUndefined(statusCode.headers)) { |
| statusCode.headers = this.parseHeadersType(statusCode.headers); |
| } |
| this.addStatusCode(statusCode); |
| } |
| |
| if (Array.isArray(this.model.security)) { |
| var authsModel = SwaggerUi.utils.parseSecurityDefinitions(this.model.security, this.model.parent.securityDefinitions); |
| |
| authsModel.isLogout = !_.isEmpty(this.model.clientAuthorizations.authz); |
| this.authView = new SwaggerUi.Views.AuthButtonView({ |
| data: authsModel, |
| router: this.router, |
| isOperation: true, |
| model: { |
| scopes: authsModel.scopes |
| } |
| }); |
| this.$('.authorize-wrapper').append(this.authView.render().el); |
| } |
| |
| this.showSnippet(); |
| return this; |
| }, |
| |
| parseHeadersType: function (headers) { |
| var map = { |
| 'string': { |
| 'date-time': 'dateTime', |
| 'date' : 'date' |
| } |
| }; |
| |
| _.forEach(headers, function (header) { |
| var value; |
| header = header || {}; |
| value = map[header.type] && map[header.type][header.format]; |
| if (!_.isUndefined(value)) { |
| header.type = value; |
| } |
| }); |
| |
| return headers; |
| }, |
| |
| contains: function (produces, type) { |
| return produces.filter(function (val) { |
| if (val.indexOf(type) > -1) { |
| return true; |
| } |
| }).length; |
| }, |
| |
| parseResponseHeaders: function (data) { |
| var HEADERS_SEPARATOR = '; '; |
| var headers = _.clone(data); |
| |
| _.forEach(headers, function (header) { |
| var other = []; |
| _.forEach(header, function (value, key) { |
| var properties = ['type', 'description']; |
| if (properties.indexOf(key.toLowerCase()) === -1) { |
| other.push(key + ': ' + value); |
| } |
| }); |
| |
| other.join(HEADERS_SEPARATOR); |
| header.other = other; |
| }); |
| |
| return headers; |
| }, |
| |
| addParameter: function(param, consumes) { |
| // Render a parameter |
| param.consumes = consumes; |
| param.defaultRendering = this.model.defaultRendering; |
| |
| // Copy this param JSON spec so that it will be available for JsonEditor |
| if(param.schema){ |
| $.extend(true, param.schema, this.model.definitions[param.type]); |
| param.schema.definitions = this.model.definitions; |
| // This is required for JsonEditor to display the root properly |
| if(!param.schema.type){ |
| param.schema.type = 'object'; |
| } |
| // This is the title that will be used by JsonEditor for the root |
| // Since we already display the parameter's name in the Parameter column |
| // We set this to space, we can't set it to null or space otherwise JsonEditor |
| // will replace it with the text "root" which won't look good on screen |
| if(!param.schema.title){ |
| param.schema.title = ' '; |
| } |
| } |
| |
| var paramView = new SwaggerUi.Views.ParameterView({ |
| model: param, |
| tagName: 'tr', |
| readOnly: this.model.isReadOnly, |
| swaggerOptions: this.options.swaggerOptions |
| }); |
| $('.operation-params', $(this.el)).append(paramView.render().el); |
| }, |
| |
| addStatusCode: function(statusCode) { |
| // Render status codes |
| statusCode.defaultRendering = this.model.defaultRendering; |
| var statusCodeView = new SwaggerUi.Views.StatusCodeView({ |
| model: statusCode, |
| tagName: 'tr', |
| router: this.router |
| }); |
| $('.operation-status', $(this.el)).append(statusCodeView.render().el); |
| }, |
| |
| // Note: copied from CoffeeScript compiled file |
| // TODO: redactor |
| submitOperation: function(e) { |
| var error_free, form, isFileUpload, map, opts; |
| if (e !== null) { |
| e.preventDefault(); |
| } |
| form = $('.sandbox', $(this.el)); |
| error_free = true; |
| form.find('input.required').each(function() { |
| $(this).removeClass('error'); |
| if (jQuery.trim($(this).val()) === '') { |
| $(this).addClass('error'); |
| $(this).wiggle({ |
| callback: (function(_this) { |
| return function() { |
| $(_this).focus(); |
| }; |
| })(this) |
| }); |
| error_free = false; |
| } |
| }); |
| form.find('textarea.required:visible').each(function() { |
| $(this).removeClass('error'); |
| if (jQuery.trim($(this).val()) === '') { |
| $(this).addClass('error'); |
| $(this).wiggle({ |
| callback: (function(_this) { |
| return function() { |
| return $(_this).focus(); |
| }; |
| })(this) |
| }); |
| error_free = false; |
| } |
| }); |
| form.find('select.required').each(function() { |
| $(this).removeClass('error'); |
| if (this.selectedIndex === -1) { |
| $(this).addClass('error'); |
| $(this).wiggle({ |
| callback: (function(_this) { |
| return function() { |
| $(_this).focus(); |
| }; |
| })(this) |
| }); |
| error_free = false; |
| } |
| }); |
| if (error_free) { |
| map = this.getInputMap(form); |
| isFileUpload = this.isFileUpload(form); |
| opts = { |
| parent: this |
| }; |
| if (this.options.swaggerOptions) { |
| for(var key in this.options.swaggerOptions) { |
| opts[key] = this.options.swaggerOptions[key]; |
| } |
| } |
| |
| var pi; |
| for(pi = 0; pi < this.model.parameters.length; pi++){ |
| var p = this.model.parameters[pi]; |
| if( p.jsonEditor && p.jsonEditor.isEnabled()){ |
| var json = p.jsonEditor.getValue(); |
| map[p.name] = JSON.stringify(json); |
| } |
| } |
| |
| opts.responseContentType = $('div select[name=responseContentType]', $(this.el)).val(); |
| opts.requestContentType = $('div select[name=parameterContentType]', $(this.el)).val(); |
| $('.response_throbber', $(this.el)).show(); |
| if (isFileUpload) { |
| $('.request_url', $(this.el)).html('<pre></pre>'); |
| $('.request_url pre', $(this.el)).text(this.invocationUrl); |
| |
| opts.useJQuery = true; |
| map.parameterContentType = 'multipart/form-data'; |
| this.map = map; |
| return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this); |
| } else { |
| this.map = map; |
| return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this); |
| } |
| } |
| }, |
| |
| getInputMap: function (form) { |
| var map, ref1, l, len, o, ref2, m, len1, val, ref3, n, len2; |
| map = {}; |
| ref1 = form.find('input'); |
| for (l = 0, len = ref1.length; l < len; l++) { |
| o = ref1[l]; |
| if ((o.value !== null) && jQuery.trim(o.value).length > 0) { |
| map[o.name] = o.value; |
| } |
| if (o.type === 'file') { |
| map[o.name] = o.files[0]; |
| } |
| } |
| ref2 = form.find('textarea'); |
| for (m = 0, len1 = ref2.length; m < len1; m++) { |
| o = ref2[m]; |
| val = this.getTextAreaValue(o); |
| if ((val !== null) && jQuery.trim(val).length > 0) { |
| map[o.name] = val; |
| } |
| } |
| ref3 = form.find('select'); |
| for (n = 0, len2 = ref3.length; n < len2; n++) { |
| o = ref3[n]; |
| val = this.getSelectedValue(o); |
| if ((val !== null) && jQuery.trim(val).length > 0) { |
| map[o.name] = val; |
| } |
| } |
| return map; |
| }, |
| |
| isFileUpload: function (form) { |
| var ref1, l, len, o; |
| var isFileUpload = false; |
| ref1 = form.find('input'); |
| for (l = 0, len = ref1.length; l < len; l++) { |
| o = ref1[l]; |
| if (o.type === 'file') { |
| isFileUpload = true; |
| } |
| } |
| return isFileUpload; |
| }, |
| |
| success: function(response, parent) { |
| parent.showCompleteStatus(response); |
| }, |
| |
| // wraps a jquery response as a shred response |
| wrap: function(data) { |
| var h, headerArray, headers, i, l, len, o; |
| headers = {}; |
| headerArray = data.getAllResponseHeaders().split('\r'); |
| for (l = 0, len = headerArray.length; l < len; l++) { |
| i = headerArray[l]; |
| h = i.match(/^([^:]*?):(.*)$/); |
| if (!h) { |
| h = []; |
| } |
| h.shift(); |
| if (h[0] !== void 0 && h[1] !== void 0) { |
| headers[h[0].trim()] = h[1].trim(); |
| } |
| } |
| o = {}; |
| o.content = {}; |
| o.content.data = data.responseText; |
| o.headers = headers; |
| o.request = {}; |
| o.request.url = this.invocationUrl; |
| o.status = data.status; |
| return o; |
| }, |
| |
| getSelectedValue: function(select) { |
| if (!select.multiple) { |
| return select.value; |
| } else { |
| var options = []; |
| for (var l = 0, len = select.options.length; l < len; l++) { |
| var opt = select.options[l]; |
| if (opt.selected) { |
| options.push(opt.value); |
| } |
| } |
| if (options.length > 0) { |
| return options; |
| } else { |
| return null; |
| } |
| } |
| }, |
| |
| // handler for hide response link |
| hideResponse: function(e) { |
| if (e) { e.preventDefault(); } |
| $('.response', $(this.el)).slideUp(); |
| $('.response_hider', $(this.el)).fadeOut(); |
| }, |
| |
| // Show response from server |
| showResponse: function(response) { |
| var prettyJson = JSON.stringify(response, null, '\t').replace(/\n/g, '<br>'); |
| $('.response_body', $(this.el)).html(_.escape(prettyJson)); |
| }, |
| |
| // Show error from server |
| showErrorStatus: function(data, parent) { |
| parent.showStatus(data); |
| }, |
| |
| // show the status codes |
| showCompleteStatus: function(data, parent){ |
| parent.showStatus(data); |
| }, |
| |
| // Adapted from http://stackoverflow.com/a/2893259/454004 |
| // Note: directly ported from CoffeeScript |
| // TODO: Cleanup CoffeeScript artifacts |
| formatXml: function(xml) { |
| var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp; |
| reg = /(>)(<)(\/*)/g; |
| wsexp = /[ ]*(.*)[ ]+\n/g; |
| contexp = /(<.+>)(.+\n)/g; |
| xml = xml.replace(/\r\n/g, '\n').replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2'); |
| pad = 0; |
| formatted = ''; |
| lines = xml.split('\n'); |
| indent = 0; |
| lastType = 'other'; |
| transitions = { |
| 'single->single': 0, |
| 'single->closing': -1, |
| 'single->opening': 0, |
| 'single->other': 0, |
| 'closing->single': 0, |
| 'closing->closing': -1, |
| 'closing->opening': 0, |
| 'closing->other': 0, |
| 'opening->single': 1, |
| 'opening->closing': 0, |
| 'opening->opening': 1, |
| 'opening->other': 1, |
| 'other->single': 0, |
| 'other->closing': -1, |
| 'other->opening': 0, |
| 'other->other': 0 |
| }; |
| fn = function(ln) { |
| var fromTo, j, key, padding, type, types, value; |
| types = { |
| single: Boolean(ln.match(/<.+\/>/)), |
| closing: Boolean(ln.match(/<\/.+>/)), |
| opening: Boolean(ln.match(/<[^!?].*>/)) |
| }; |
| type = ((function() { |
| var results; |
| results = []; |
| for (key in types) { |
| value = types[key]; |
| if (value) { |
| results.push(key); |
| } |
| } |
| return results; |
| })())[0]; |
| type = type === void 0 ? 'other' : type; |
| fromTo = lastType + '->' + type; |
| lastType = type; |
| padding = ''; |
| indent += transitions[fromTo]; |
| padding = ((function() { |
| var m, ref1, results; |
| results = []; |
| for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) { |
| results.push(' '); |
| } |
| return results; |
| })()).join(''); |
| if (fromTo === 'opening->closing') { |
| formatted = formatted.substr(0, formatted.length - 1) + ln + '\n'; |
| } else { |
| formatted += padding + ln + '\n'; |
| } |
| }; |
| for (l = 0, len = lines.length; l < len; l++) { |
| ln = lines[l]; |
| fn(ln); |
| } |
| return formatted; |
| }, |
| |
| // puts the response data in UI |
| showStatus: function(response) { |
| var url, content; |
| if (response.content === undefined) { |
| content = response.data; |
| url = response.url; |
| } else { |
| content = response.content.data; |
| url = response.request.url; |
| } |
| var headers = response.headers; |
| if(typeof content === 'string') { |
| content = jQuery.trim(content); |
| } |
| |
| // if server is nice, and sends content-type back, we can use it |
| var contentType = null; |
| if (headers) { |
| contentType = headers['Content-Type'] || headers['content-type']; |
| if (contentType) { |
| contentType = contentType.split(';')[0].trim(); |
| } |
| } |
| |
| $('.response_body', $(this.el)).removeClass('json'); |
| $('.response_body', $(this.el)).removeClass('xml'); |
| |
| var supportsAudioPlayback = function(contentType){ |
| var audioElement = document.createElement('audio'); |
| return !!(audioElement.canPlayType && audioElement.canPlayType(contentType).replace(/no/, '')); |
| }; |
| |
| var pre; |
| var code; |
| var skipHighlight = false; |
| if (!content) { |
| code = $('<code />').text('no content'); |
| pre = $('<pre class="json" />').append(code); |
| |
| // JSON |
| } else if ( |
| contentType === 'application/octet-stream' || |
| headers['Content-Disposition'] && (/attachment/).test(headers['Content-Disposition']) || |
| headers['content-disposition'] && (/attachment/).test(headers['content-disposition']) || |
| headers['Content-Description'] && (/File Transfer/).test(headers['Content-Description']) || |
| headers['content-description'] && (/File Transfer/).test(headers['content-description'])) { |
| |
| if ('Blob' in window) { |
| var type = contentType || 'text/html'; |
| var a = document.createElement('a'); |
| var href; |
| |
| if({}.toString.apply(content) === '[object Blob]') { |
| href = window.URL.createObjectURL(content); |
| } |
| else { |
| var binaryData = []; |
| binaryData.push(content); |
| href = window.URL.createObjectURL(new Blob(binaryData, {type: type})); |
| } |
| var fileName = response.url.substr(response.url.lastIndexOf('/') + 1); |
| var download = [type, fileName, href].join(':'); |
| |
| // Use filename from response header |
| var disposition = headers['content-disposition'] || headers['Content-Disposition']; |
| if(typeof disposition !== 'undefined') { |
| var responseFilename = /filename=([^;]*);?/.exec(disposition); |
| if(responseFilename !== null && responseFilename.length > 1) { |
| download = responseFilename[1]; |
| fileName = download; |
| } |
| } |
| |
| a.setAttribute('href', href); |
| a.setAttribute('download', download); |
| a.innerText = 'Download ' + fileName; |
| |
| pre = $('<div/>').append(a); |
| skipHighlight = true; |
| } else { |
| pre = $('<pre class="json" />').append('Download headers detected but your browser does not support downloading binary via XHR (Blob).'); |
| } |
| } else if (contentType === 'application/json' || /\+json$/.test(contentType)) { |
| var json = null; |
| try { |
| json = JSON.stringify(JSON.parse(content), null, ' '); |
| } catch (_error) { |
| json = 'can\'t parse JSON. Raw result:\n\n' + content; |
| } |
| code = $('<code />').text(json); |
| pre = $('<pre class="json" />').append(code); |
| |
| // XML |
| } else if (contentType === 'application/xml' || /\+xml$/.test(contentType)) { |
| code = $('<code />').text(this.formatXml(content)); |
| pre = $('<pre class="xml" />').append(code); |
| |
| // HTML |
| } else if (contentType === 'text/html') { |
| code = $('<code />').html(_.escape(content)); |
| pre = $('<pre class="xml" />').append(code); |
| |
| // Plain Text |
| } else if (/text\/plain/.test(contentType)) { |
| code = $('<code />').text(content); |
| pre = $('<pre class="plain" />').append(code); |
| |
| // Image |
| } else if (/^image\//.test(contentType)) { |
| var urlCreator = window.URL || window.webkitURL; |
| var imageUrl = urlCreator.createObjectURL(content); |
| |
| pre = $('<img>').attr( 'src', imageUrl); |
| // Audio |
| } else if (/^audio\//.test(contentType) && supportsAudioPlayback(contentType)) { |
| pre = $('<audio controls>').append($('<source>').attr('src', url).attr('type', contentType)); |
| } else if(headers.location || headers.Location) { |
| // Location header based redirect download |
| window.location = response.url; |
| |
| // Anything else (CORS) |
| } else { |
| code = $('<code />').text(content); |
| pre = $('<pre class="json" />').append(code); |
| } |
| var response_body = pre; |
| $('.request_url', $(this.el)).html('<pre></pre>'); |
| $('.request_url pre', $(this.el)).text(url); |
| $('.response_code', $(this.el)).html('<pre>' + response.status + '</pre>'); |
| $('.response_body', $(this.el)).html(response_body); |
| $('.response_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(response.headers, null, ' ')).replace(/\n/g, '<br>') + '</pre>'); |
| $('.response', $(this.el)).slideDown(); |
| $('.response_hider', $(this.el)).show(); |
| $('.response_throbber', $(this.el)).hide(); |
| |
| |
| // adds curl output |
| var curlCommand = this.model.asCurl(this.map, {responseContentType: contentType}); |
| curlCommand = curlCommand.replace('!', '!'); |
| $( 'div.curl', $(this.el)).html('<pre>' + _.escape(curlCommand) + '</pre>'); |
| |
| // only highlight the response if response is less than threshold, default state is highlight response |
| var opts = this.options.swaggerOptions; |
| |
| if (opts.showRequestHeaders) { |
| var form = $('.sandbox', $(this.el)), |
| map = this.getInputMap(form), |
| requestHeaders = this.model.getHeaderParams(map); |
| delete requestHeaders['Content-Type']; |
| $('.request_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(requestHeaders, null, ' ')).replace(/\n/g, '<br>') + '</pre>'); |
| } |
| |
| // Call user-defined hook |
| if (opts.responseHooks && opts.responseHooks[this.nickname]) { |
| opts.responseHooks[this.nickname](response, this); |
| } |
| |
| var response_body_el = $('.response_body', $(this.el))[0]; |
| // only highlight the response if response is less than threshold, default state is highlight response |
| if (opts.highlightSizeThreshold && typeof response.data !== 'undefined' && response.data.length > opts.highlightSizeThreshold || skipHighlight) { |
| return response_body_el; |
| } else { |
| return hljs.highlightBlock(response_body_el); |
| } |
| }, |
| |
| toggleOperationContent: function (event) { |
| var elem = $('#' + Docs.escapeResourceName(this.parentId + '_' + this.nickname + '_content')); |
| if (elem.is(':visible')){ |
| $.bbq.pushState('#/', 2); |
| event.preventDefault(); |
| Docs.collapseOperation(elem); |
| } else { |
| Docs.expandOperation(elem); |
| } |
| }, |
| |
| getTextAreaValue: function(textArea) { |
| var param, parsed, result, i; |
| if (textArea.value === null || jQuery.trim(textArea.value).length === 0) { |
| return null; |
| } |
| param = this.getParamByName(textArea.name); |
| if (param && param.type && param.type.toLowerCase() === 'array') { |
| parsed = textArea.value.split('\n'); |
| result = []; |
| for (i = 0; i < parsed.length; i++) { |
| if (parsed[i] !== null && jQuery.trim(parsed[i]).length > 0) { |
| result.push(parsed[i]); |
| } |
| } |
| return result.length > 0 ? result : null; |
| } else { |
| return textArea.value; |
| } |
| }, |
| |
| showSnippet: function () { |
| var contentTypeEl = this.$('[name=responseContentType]'); |
| var xmlSnippetEl = this.$('.operation-status .snippet_xml, .response-class .snippet_xml'); |
| var jsonSnippetEl = this.$('.operation-status .snippet_json, .response-class .snippet_json'); |
| var contentType; |
| |
| if (!contentTypeEl.length) { return; } |
| contentType = contentTypeEl.val(); |
| |
| if (contentType.indexOf('xml') > -1) { |
| xmlSnippetEl.show(); |
| jsonSnippetEl.hide(); |
| } else { |
| jsonSnippetEl.show(); |
| xmlSnippetEl.hide(); |
| } |
| }, |
| |
| getParamByName: function(name) { |
| var i; |
| if (this.model.parameters) { |
| for(i = 0; i < this.model.parameters.length; i++) { |
| if (this.model.parameters[i].name === name) { |
| return this.model.parameters[i]; |
| } |
| } |
| } |
| return null; |
| } |
| |
| }); |
| |
| 'use strict'; |
| |
| SwaggerUi.Views.ParameterContentTypeView = Backbone.View.extend({ |
| initialize: function () {}, |
| |
| render: function(){ |
| this.model.parameterContentTypeId = 'pct' + Math.random(); |
| $(this.el).html(Handlebars.templates.parameter_content_type(this.model)); |
| return this; |
| } |
| |
| }); |
| 'use strict'; |
| |
| SwaggerUi.Views.ParameterView = Backbone.View.extend({ |
| events: { |
| 'change [name=parameterContentType]' : 'toggleParameterSnippet' |
| }, |
| |
| initialize: function(){ |
| Handlebars.registerHelper('isArray', function(param, opts) { |
| var paramType = param.type && param.type.toLowerCase(); |
| if (paramType === 'array' || param.allowMultiple) { |
| return opts.fn(this); |
| } else { |
| return opts.inverse(this); |
| } |
| }); |
| }, |
| |
| render: function() { |
| var type = this.model.type || this.model.dataType; |
| var modelType = this.model.modelSignature.type; |
| var modelDefinitions = this.model.modelSignature.definitions; |
| var schema = this.model.schema || {}; |
| var consumes = this.model.consumes || []; |
| var sampleJSON, signatureView; |
| |
| if (typeof type === 'undefined') { |
| if (schema.$ref) { |
| var ref = schema.$ref; |
| if (ref.indexOf('#/definitions/') === 0) { |
| type = ref.substring('#/definitions/'.length); |
| } else { |
| type = ref; |
| } |
| } |
| } |
| |
| this.model.type = type; |
| this.model.paramType = this.model.in || this.model.paramType; |
| this.model.isBody = this.model.paramType === 'body' || this.model.in === 'body'; |
| this.model.isFile = type && type.toLowerCase() === 'file'; |
| |
| // Allow for default === false |
| if(typeof this.model.default === 'undefined') { |
| this.model.default = this.model.defaultValue; |
| } |
| |
| this.model.hasDefault = (typeof this.model.default !== 'undefined'); |
| this.model.valueId = 'm' + this.model.name + Math.random(); |
| |
| if (this.model.allowableValues) { |
| this.model.isList = true; |
| } |
| |
| var isXML = this.contains(consumes, 'xml'); |
| var isJSON = isXML ? this.contains(consumes, 'json') : true; |
| sampleJSON = SwaggerUi.partials.signature.createParameterJSONSample(modelType, modelDefinitions); |
| |
| var template = this.template(); |
| $(this.el).html(template(this.model)); |
| |
| var signatureModel = { |
| sampleJSON: isJSON ? sampleJSON : false, |
| sampleXML: sampleJSON && isXML ? SwaggerUi.partials.signature.createXMLSample('', schema, modelDefinitions, true) : false, |
| isParam: true, |
| signature: SwaggerUi.partials.signature.getParameterModelSignature(modelType, modelDefinitions), |
| defaultRendering: this.model.defaultRendering |
| }; |
| |
| if (sampleJSON) { |
| signatureView = new SwaggerUi.Views.SignatureView({model: signatureModel, tagName: 'div'}); |
| $('.model-signature', $(this.el)).append(signatureView.render().el); |
| } |
| else { |
| $('.model-signature', $(this.el)).html(this.model.signature); |
| } |
| |
| var isParam = false; |
| |
| if( this.options.swaggerOptions.jsonEditor && this.model.isBody && this.model.schema){ |
| var $self = $(this.el); |
| this.model.jsonEditor = |
| /* global JSONEditor */ |
| new JSONEditor($('.editor_holder', $self)[0], |
| {schema: this.model.schema, startval : this.model.default, |
| ajax:true, |
| disable_properties:true, |
| disable_edit_json:true, |
| iconlib: 'swagger' }); |
| // This is so that the signature can send back the sample to the json editor |
| // TODO: SignatureView should expose an event "onSampleClicked" instead |
| signatureModel.jsonEditor = this.model.jsonEditor; |
| $('.body-textarea', $self).hide(); |
| $('.editor_holder', $self).show(); |
| $('.parameter-content-type', $self) |
| .change(function(e){ |
| if(e.target.value === 'application/xml'){ |
| $('.body-textarea', $self).show(); |
| $('.editor_holder', $self).hide(); |
| this.model.jsonEditor.disable(); |
| } |
| else { |
| $('.body-textarea', $self).hide(); |
| $('.editor_holder', $self).show(); |
| this.model.jsonEditor.enable(); |
| } |
| }); |
| } |
| |
| |
| if (this.model.isBody) { |
| isParam = true; |
| } |
| |
| var contentTypeModel = { |
| isParam: isParam |
| }; |
| |
| contentTypeModel.consumes = this.model.consumes; |
| |
| if (isParam) { |
| var parameterContentTypeView = new SwaggerUi.Views.ParameterContentTypeView({model: contentTypeModel}); |
| $('.parameter-content-type', $(this.el)).append(parameterContentTypeView.render().el); |
| this.toggleParameterSnippet(); |
| } |
| |
| else { |
| var responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({model: contentTypeModel}); |
| $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el); |
| this.toggleResponseSnippet(); |
| } |
| |
| return this; |
| }, |
| |
| contains: function (consumes, type) { |
| return consumes.filter(function (val) { |
| if (val.indexOf(type) > -1) { |
| return true; |
| } |
| }).length; |
| }, |
| |
| toggleParameterSnippet: function () { |
| var contentType = this.$('[name=parameterContentType]').val(); |
| |
| this.toggleSnippet(contentType); |
| }, |
| |
| toggleResponseSnippet: function () { |
| var contentEl = this.$('[name=responseContentType]'); |
| |
| if (!contentEl.length) { return; } |
| |
| this.toggleSnippet(contentEl.val()); |
| }, |
| |
| toggleSnippet: function (type) { |
| type = type || ''; |
| if (type.indexOf('xml') > -1) { |
| this.$('.snippet_xml').show(); |
| this.$('.snippet_json').hide(); |
| } else { |
| this.$('.snippet_json').show(); |
| this.$('.snippet_xml').hide(); |
| } |
| }, |
| |
| // Return an appropriate template based on if the parameter is a list, readonly, required |
| template: function(){ |
| if (this.model.isList) { |
| return Handlebars.templates.param_list; |
| } else { |
| if (this.options.readOnly) { |
| if (this.model.required) { |
| return Handlebars.templates.param_readonly_required; |
| } else { |
| return Handlebars.templates.param_readonly; |
| } |
| } else { |
| if (this.model.required) { |
| return Handlebars.templates.param_required; |
| } else { |
| return Handlebars.templates.param; |
| } |
| } |
| } |
| } |
| }); |
| |
| 'use strict'; |
| |
| /* jshint -W122 */ |
| SwaggerUi.partials.signature = (function () { |
| // copy-pasted from swagger-js |
| var resolveSchema = function (schema) { |
| if (_.isPlainObject(schema.schema)) { |
| schema = resolveSchema(schema.schema); |
| } |
| |
| return schema; |
| }; |
| |
| // copy-pasted from swagger-js |
| var simpleRef = function (name) { |
| if (typeof name === 'undefined') { |
| return null; |
| } |
| |
| if (name.indexOf('#/definitions/') === 0) { |
| return name.substring('#/definitions/'.length); |
| } else { |
| return name; |
| } |
| }; |
| |
| // copy-pasted from swagger-js |
| var getInlineModel = function(inlineStr) { |
| if(/^Inline Model \d+$/.test(inlineStr) && this.inlineModels) { |
| var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); // |
| var model = this.inlineModels[id]; |
| return model; |
| } |
| // I'm returning null here, should I rather throw an error? |
| return null; |
| }; |
| |
| // copy-pasted from swagger-js |
| var formatXml = function(xml) { |
| var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp; |
| reg = /(>)(<)(\/*)/g; |
| wsexp = /[ ]*(.*)[ ]+\n/g; |
| contexp = /(<.+>)(.+\n)/g; |
| xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2'); |
| pad = 0; |
| formatted = ''; |
| lines = xml.split('\n'); |
| indent = 0; |
| lastType = 'other'; |
| transitions = { |
| 'single->single': 0, |
| 'single->closing': -1, |
| 'single->opening': 0, |
| 'single->other': 0, |
| 'closing->single': 0, |
| 'closing->closing': -1, |
| 'closing->opening': 0, |
| 'closing->other': 0, |
| 'opening->single': 1, |
| 'opening->closing': 0, |
| 'opening->opening': 1, |
| 'opening->other': 1, |
| 'other->single': 0, |
| 'other->closing': -1, |
| 'other->opening': 0, |
| 'other->other': 0 |
| }; |
| fn = function(ln) { |
| var fromTo, j, key, padding, type, types, value; |
| types = { |
| single: Boolean(ln.match(/<.+\/>/)), |
| closing: Boolean(ln.match(/<\/.+>/)), |
| opening: Boolean(ln.match(/<[^!?].*>/)) |
| }; |
| type = ((function() { |
| var results; |
| results = []; |
| for (key in types) { |
| value = types[key]; |
| if (value) { |
| results.push(key); |
| } |
| } |
| return results; |
| })())[0]; |
| type = type === void 0 ? 'other' : type; |
| fromTo = lastType + '->' + type; |
| lastType = type; |
| padding = ''; |
| indent += transitions[fromTo]; |
| padding = ((function() { |
| var m, ref1, results; |
| results = []; |
| for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) { |
| results.push(' '); |
| } |
| return results; |
| })()).join(''); |
| if (fromTo === 'opening->closing') { |
| formatted = formatted.substr(0, formatted.length - 1) + ln + '\n'; |
| } else { |
| formatted += padding + ln + '\n'; |
| } |
| }; |
| for (l = 0, len = lines.length; l < len; l++) { |
| ln = lines[l]; |
| fn(ln); |
| } |
| return formatted; |
| }; |
| |
| // copy-pasted from swagger-js |
| var getModelSignature = function (name, schema, models, modelPropertyMacro) { |
| var strongOpen = '<span class="strong">'; |
| var strongClose = '</span>'; |
| |
| var optionHtml = function (label, value) { |
| return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>'; |
| }; |
| |
| |
| // Allow for ignoring the 'name' argument.... shifting the rest |
| if(_.isObject(arguments[0])) { |
| name = void 0; |
| schema = arguments[0]; |
| models = arguments[1]; |
| modelPropertyMacro = arguments[2]; |
| } |
| |
| models = models || {}; |
| |
| // Resolve the schema (Handle nested schemas) |
| schema = resolveSchema(schema); |
| |
| // Return for empty object |
| if(_.isEmpty(schema)) { |
| return strongOpen + 'Empty' + strongClose; |
| } |
| |
| // Dereference $ref from 'models' |
| if(typeof schema.$ref === 'string') { |
| name = simpleRef(schema.$ref); |
| schema = models[name]; |
| if(typeof schema === 'undefined') |
| { |
| return strongOpen + name + ' is not defined!' + strongClose; |
| } |
| } |
| |
| if(typeof name !== 'string') { |
| name = schema.title || 'Inline Model'; |
| } |
| |
| // If we are a Model object... adjust accordingly |
| if(schema.definition) { |
| schema = schema.definition; |
| } |
| |
| if(typeof modelPropertyMacro !== 'function') { |
| modelPropertyMacro = function(prop){ |
| return (prop || {}).default; |
| }; |
| } |
| |
| var references = {}; |
| var seenModels = []; |
| var inlineModels = 0; |
| |
| // Generate current HTML |
| var html = processModel(schema, name); |
| |
| // Generate references HTML |
| while (_.keys(references).length > 0) { |
| /* jshint ignore:start */ |
| _.forEach(references, function (schema, name) { |
| var seenModel = _.indexOf(seenModels, name) > -1; |
| |
| delete references[name]; |
| |
| if (!seenModel) { |
| seenModels.push(name); |
| |
| html += '<br />' + processModel(schema, name); |
| } |
| }); |
| /* jshint ignore:end */ |
| } |
| |
| return html; |
| |
| |
| function addReference(schema, name, skipRef) { |
| var modelName = name; |
| var model; |
| |
| if (schema.$ref) { |
| modelName = schema.title || simpleRef(schema.$ref); |
| model = models[simpleRef(schema.$ref)]; |
| } else if (_.isUndefined(name)) { |
| modelName = schema.title || 'Inline Model ' + (++inlineModels); |
| model = {definition: schema}; |
| } |
| |
| if (skipRef !== true) { |
| references[modelName] = _.isUndefined(model) ? {} : model.definition; |
| } |
| |
| return modelName; |
| } |
| |
| function primitiveToHTML(schema) { |
| var html = '<span class="propType">'; |
| var type = schema.type || 'object'; |
| |
| if (schema.$ref) { |
| html += addReference(schema, simpleRef(schema.$ref)); |
| } else if (type === 'object') { |
| if (!_.isUndefined(schema.properties)) { |
| html += addReference(schema); |
| } else { |
| html += 'object'; |
| } |
| } else if (type === 'array') { |
| html += 'Array['; |
| |
| if (_.isArray(schema.items)) { |
| html += _.map(schema.items, addReference).join(','); |
| } else if (_.isPlainObject(schema.items)) { |
| if (_.isUndefined(schema.items.$ref)) { |
| if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) { |
| html += schema.items.type; |
| } else { |
| html += addReference(schema.items); |
| } |
| } else { |
| html += addReference(schema.items, simpleRef(schema.items.$ref)); |
| } |
| } else { |
| console.log('Array type\'s \'items\' schema is not an array or an object, cannot process'); |
| html += 'object'; |
| } |
| |
| html += ']'; |
| } else { |
| html += schema.type; |
| } |
| |
| html += '</span>'; |
| |
| return html; |
| } |
| |
| function primitiveToOptionsHTML(schema, html) { |
| var options = ''; |
| var type = schema.type || 'object'; |
| var isArray = type === 'array'; |
| |
| if (!_.isUndefined(schema.description)) { |
| html += ': ' + '<span class="propDesc">' + schema.description + '</span>'; |
| } |
| |
| if (schema.enum) { |
| html += ' = <span class="propVals">[\'' + schema.enum.join('\', \'') + '\']</span>'; |
| } |
| |
| if (isArray) { |
| if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) { |
| type = schema.items.type; |
| } else { |
| type = 'object'; |
| } |
| } |
| |
| if (!_.isUndefined(schema.default)) { |
| options += optionHtml('Default', schema.default); |
| } |
| |
| switch (type) { |
| case 'string': |
| if (schema.minLength) { |
| options += optionHtml('Min. Length', schema.minLength); |
| } |
| |
| if (schema.maxLength) { |
| options += optionHtml('Max. Length', schema.maxLength); |
| } |
| |
| if (schema.pattern) { |
| options += optionHtml('Reg. Exp.', schema.pattern); |
| } |
| break; |
| case 'integer': |
| case 'number': |
| if (schema.minimum) { |
| options += optionHtml('Min. Value', schema.minimum); |
| } |
| |
| if (schema.exclusiveMinimum) { |
| options += optionHtml('Exclusive Min.', 'true'); |
| } |
| |
| if (schema.maximum) { |
| options += optionHtml('Max. Value', schema.maximum); |
| } |
| |
| if (schema.exclusiveMaximum) { |
| options += optionHtml('Exclusive Max.', 'true'); |
| } |
| |
| if (schema.multipleOf) { |
| options += optionHtml('Multiple Of', schema.multipleOf); |
| } |
| |
| break; |
| } |
| |
| if (isArray) { |
| if (schema.minItems) { |
| options += optionHtml('Min. Items', schema.minItems); |
| } |
| |
| if (schema.maxItems) { |
| options += optionHtml('Max. Items', schema.maxItems); |
| } |
| |
| if (schema.uniqueItems) { |
| options += optionHtml('Unique Items', 'true'); |
| } |
| |
| if (schema.collectionFormat) { |
| options += optionHtml('Coll. Format', schema.collectionFormat); |
| } |
| } |
| |
| if (_.isUndefined(schema.items)) { |
| if (_.isArray(schema.enum)) { |
| var enumString; |
| |
| if (type === 'number' || type === 'integer') { |
| enumString = schema.enum.join(', '); |
| } else { |
| enumString = '"' + schema.enum.join('", "') + '"'; |
| } |
| |
| options += optionHtml('Enum', enumString); |
| } |
| } |
| |
| if (options.length > 0) { |
| html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>'; |
| } |
| |
| return html; |
| } |
| |
| function processModel(schema, name) { |
| var type = schema.type || 'object'; |
| var isArray = schema.type === 'array'; |
| var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose; |
| var contents; |
| |
| if (name) { |
| seenModels.push(name); |
| } |
| |
| if (isArray) { |
| if (_.isArray(schema.items)) { |
| html += '<div>' + _.map(schema.items, function (item) { |
| var type = item.type || 'object'; |
| |
| if (_.isUndefined(item.$ref)) { |
| if (_.indexOf(['array', 'object'], type) > -1) { |
| if (type === 'object' && _.isUndefined(item.properties)) { |
| return 'object'; |
| } else { |
| return addReference(item); |
| } |
| } else { |
| return primitiveToOptionsHTML(item, type); |
| } |
| } else { |
| return addReference(item, simpleRef(item.$ref)); |
| } |
| }).join(',</div><div>'); |
| } else if (_.isPlainObject(schema.items)) { |
| if (_.isUndefined(schema.items.$ref)) { |
| if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) { |
| if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) { |
| html += '<div>object</div>'; |
| } else { |
| html += '<div>' + addReference(schema.items) + '</div>'; |
| } |
| } else { |
| html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>'; |
| } |
| } else { |
| html += '<div>' + addReference(schema.items, simpleRef(schema.items.$ref)) + '</div>'; |
| } |
| } else { |
| console.log('Array type\'s \'items\' property is not an array or an object, cannot process'); |
| html += '<div>object</div>'; |
| } |
| } else { |
| if (schema.$ref) { |
| html += '<div>' + addReference(schema, name) + '</div>'; |
| } else if (type === 'object') { |
| if (_.isPlainObject(schema.properties)) { |
| contents = _.map(schema.properties, function (property, name) { |
| var propertyIsRequired = (_.indexOf(schema.required, name) >= 0); |
| var cProperty = _.cloneDeep(property); |
| |
| var requiredClass = propertyIsRequired ? 'required' : ''; |
| var html = '<span class="propName ' + requiredClass + '">' + name + '</span> ('; |
| var model; |
| |
| // Allow macro to set the default value |
| cProperty.default = modelPropertyMacro(cProperty); |
| |
| // Resolve the schema (Handle nested schemas) |
| cProperty = resolveSchema(cProperty); |
| |
| // We need to handle property references to primitives (Issue 339) |
| if (!_.isUndefined(cProperty.$ref)) { |
| model = models[simpleRef(cProperty.$ref)]; |
| |
| if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) { |
| // Use referenced schema |
| cProperty = resolveSchema(model.definition); |
| } |
| } |
| |
| html += primitiveToHTML(cProperty); |
| |
| if(!propertyIsRequired) { |
| html += ', <span class="propOptKey">optional</span>'; |
| } |
| |
| if(property.readOnly) { |
| html += ', <span class="propReadOnly">read only</span>'; |
| } |
| |
| html += ')'; |
| |
| return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html); |
| }).join(',</div>'); |
| } |
| |
| if (contents) { |
| html += contents + '</div>'; |
| } |
| } else { |
| html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>'; |
| } |
| } |
| |
| return html + strongOpen + (isArray ? ']' : '}') + strongClose; |
| } |
| |
| }; |
| |
| // copy-pasted from swagger-js |
| var schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) { |
| // Resolve the schema (Handle nested schemas) |
| schema = resolveSchema(schema); |
| |
| if(typeof modelPropertyMacro !== 'function') { |
| modelPropertyMacro = function(prop){ |
| return (prop || {}).default; |
| }; |
| } |
| |
| modelsToIgnore= modelsToIgnore || {}; |
| |
| var type = schema.type || 'object'; |
| var format = schema.format; |
| var model; |
| var output; |
| |
| if (!_.isUndefined(schema.example)) { |
| output = schema.example; |
| } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) { |
| output = schema.enum[0]; |
| } |
| |
| if (_.isUndefined(output)) { |
| if (schema.$ref) { |
| model = models[simpleRef(schema.$ref)]; |
| |
| if (!_.isUndefined(model)) { |
| if (_.isUndefined(modelsToIgnore[model.name])) { |
| modelsToIgnore[model.name] = model; |
| output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro); |
| delete modelsToIgnore[model.name]; |
| } else { |
| if (model.type === 'array') { |
| output = []; |
| } else { |
| output = {}; |
| } |
| } |
| } |
| } else if (!_.isUndefined(schema.default)) { |
| output = schema.default; |
| } else if (type === 'string') { |
| if (format === 'date-time') { |
| output = new Date().toISOString(); |
| } else if (format === 'date') { |
| output = new Date().toISOString().split('T')[0]; |
| } else { |
| output = 'string'; |
| } |
| } else if (type === 'integer') { |
| output = 0; |
| } else if (type === 'number') { |
| output = 0.0; |
| } else if (type === 'boolean') { |
| output = true; |
| } else if (type === 'object') { |
| output = {}; |
| |
| _.forEach(schema.properties, function (property, name) { |
| var cProperty = _.cloneDeep(property); |
| |
| // Allow macro to set the default value |
| cProperty.default = modelPropertyMacro(property); |
| |
| output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro); |
| }); |
| } else if (type === 'array') { |
| output = []; |
| |
| if (_.isArray(schema.items)) { |
| _.forEach(schema.items, function (item) { |
| output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro)); |
| }); |
| } else if (_.isPlainObject(schema.items)) { |
| output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro)); |
| } else if (_.isUndefined(schema.items)) { |
| output.push({}); |
| } else { |
| console.log('Array type\'s \'items\' property is not an array or an object, cannot process'); |
| } |
| } |
| } |
| |
| return output; |
| }; |
| |
| // copy-pasted from swagger-js |
| var createJSONSample = function (value, modelsToIgnore) { |
| modelsToIgnore = modelsToIgnore || {}; |
| |
| modelsToIgnore[value.name] = value; |
| |
| // Response support |
| if (value.examples && _.isPlainObject(value.examples)) { |
| value = _.cloneDeep(value); |
| var keys = Object.keys(value.examples); |
| |
| _.forEach(keys, function(key) { |
| if(key.indexOf('application/json') === 0) { |
| var example = value.examples[key]; |
| if (_.isString(example)) { |
| example = jsyaml.safeLoad(example); |
| } |
| value.definition.example = example; |
| return schemaToJSON(value.definition, example, modelsToIgnore, value.modelPropertyMacro); |
| } |
| }); |
| } |
| |
| if (value.examples) { |
| value = _.cloneDeep(value); |
| var example = value.examples; |
| if (_.isString(example)) { |
| example = jsyaml.safeLoad(example); |
| } |
| value.definition.example = example; |
| return schemaToJSON(value.definition, example, modelsToIgnore, value.modelPropertyMacro); |
| } |
| |
| return schemaToJSON(value.definition, value.models, modelsToIgnore, value.modelPropertyMacro); |
| }; |
| |
| // copy-pasted from swagger-js |
| var getParameterModelSignature = function (type, definitions) { |
| var isPrimitive, listType; |
| |
| if (type instanceof Array) { |
| listType = true; |
| type = type[0]; |
| } |
| |
| // Convert undefined to string of 'undefined' |
| if (typeof type === 'undefined') { |
| type = 'undefined'; |
| isPrimitive = true; |
| |
| } else if (definitions[type]){ |
| // a model def exists? |
| type = definitions[type]; /* Model */ |
| isPrimitive = false; |
| |
| } else if (getInlineModel(type)) { |
| type = getInlineModel(type); /* Model */ |
| isPrimitive = false; |
| |
| } else { |
| // We default to primitive |
| isPrimitive = true; |
| } |
| |
| if (isPrimitive) { |
| if (listType) { |
| return 'Array[' + type + ']'; |
| } else { |
| return type.toString(); |
| } |
| } else { |
| if (listType) { |
| return 'Array[' + getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro) + ']'; |
| } else { |
| return getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro); |
| } |
| } |
| }; |
| |
| // copy-pasted from swagger-js |
| var createParameterJSONSample = function (type, models) { |
| var listType, sampleJson, innerType; |
| models = models || {}; |
| |
| listType = (type instanceof Array); |
| innerType = listType ? type[0] : type; |
| |
| if(models[innerType]) { |
| sampleJson = createJSONSample(models[innerType]); |
| } else if (getInlineModel(innerType)){ |
| sampleJson = createJSONSample(getInlineModel(innerType)); // may return null, if type isn't correct |
| } |
| |
| |
| if (sampleJson) { |
| sampleJson = listType ? [sampleJson] : sampleJson; |
| |
| if (typeof sampleJson === 'string') { |
| return sampleJson; |
| } else if (_.isObject(sampleJson)) { |
| var t = sampleJson; |
| |
| if (sampleJson instanceof Array && sampleJson.length > 0) { |
| t = sampleJson[0]; |
| } |
| |
| if (t.nodeName && typeof t === 'Node') { |
| var xmlString = new XMLSerializer().serializeToString(t); |
| |
| return formatXml(xmlString); |
| } else { |
| return JSON.stringify(sampleJson, null, 2); |
| } |
| } else { |
| return sampleJson; |
| } |
| } |
| }; |
| |
| var wrapTag = function (name, value, attrs) { |
| var str, attributes; |
| |
| attrs = attrs || []; |
| |
| attributes = attrs.map(function (attr) { |
| return ' ' + attr.name + '="' + attr.value + '"'; |
| }).join(''); |
| |
| if (!name) { |
| return getErrorMessage('Node name is not provided'); |
| } |
| |
| str = [ |
| '<', name, |
| attributes, |
| '>', |
| value, |
| '</', name, '>' |
| ]; |
| |
| return str.join(''); |
| }; |
| |
| // Commenting this funtion as the names are now determined beforehand and the prefix part is exposed as a separate function | https://github.com/swagger-api/swagger-ui/issues/2577 |
| /** var getName = function (name, xml) { |
| var result = name || ''; |
| |
| xml = xml || {}; |
| |
| if (xml.name) { |
| result = xml.name; |
| } |
| |
| if (xml.prefix) { |
| result = xml.prefix + ':' + result; |
| } |
| |
| return result; |
| }; |
| */ |
| |
| var getPrefix = function (name, xml) { |
| var result = name || ''; |
| |
| xml = xml || {}; |
| |
| if (xml.prefix) { |
| result = xml.prefix + ':' + result; |
| } |
| |
| return result; |
| }; |
| |
| var getNamespace = function (xml) { |
| var namespace = ''; |
| var name = 'xmlns'; |
| |
| xml = xml || {}; |
| |
| if (xml.namespace) { |
| namespace = xml.namespace; |
| } else { |
| return namespace; |
| } |
| |
| if (xml.prefix) { |
| name += ':' + xml.prefix; |
| } |
| |
| return { |
| name: name, |
| value: namespace |
| }; |
| }; |
| |
| var createArrayXML = function (descriptor) { |
| var name = descriptor.name; |
| var config = descriptor.config; |
| var definition = descriptor.definition; |
| var models = descriptor.models; |
| var value; |
| var items = definition.items; |
| var xml = definition.xml || {}; |
| var namespace = getNamespace(xml); |
| var attributes = []; |
| |
| if (!items) { return getErrorMessage(); } |
| var key = name; |
| // If there is a name specified for the array elements, use that for the array elements name | https://github.com/swagger-api/swagger-ui/issues/2577 |
| if(items.xml && items.xml.name) { |
| key = items.xml.name; |
| } |
| value = createSchemaXML(key, items, models, config); |
| if (namespace) { |
| attributes.push(namespace); |
| } |
| |
| if (xml.wrapped) { |
| value = wrapTag(name, value, attributes); |
| } |
| |
| return value; |
| }; |
| |
| var getPrimitiveSignature = function (schema) { |
| var type, items; |
| |
| schema = schema || {}; |
| items = schema.items || {}; |
| type = schema.type || ''; |
| |
| switch (type) { |
| case 'object': return 'Object is not a primitive'; |
| case 'array' : return 'Array[' + (items.format || items.type) + ']'; |
| default: return schema.format || type; |
| } |
| }; |
| |
| var createPrimitiveXML = function (descriptor) { |
| var name = descriptor.name; |
| var definition = descriptor.definition; |
| var primitivesMap = { |
| 'string': { |
| 'date': new Date(1).toISOString().split('T')[0], |
| 'date-time' : new Date(1).toISOString(), |
| 'default': 'string' |
| }, |
| 'integer': { |
| 'default': 1 |
| }, |
| 'number': { |
| 'default': 1.1 |
| }, |
| 'boolean': { |
| 'default': true |
| } |
| }; |
| var type = definition.type; |
| var format = definition.format; |
| var xml = definition.xml || {}; |
| var namespace = getNamespace(xml); |
| var attributes = []; |
| var value; |
| |
| if (_.keys(primitivesMap).indexOf(type) < 0) { return getErrorMessage(); } |
| |
| if (_.isArray(definition.enum)){ |
| value = definition.enum[0]; |
| } else { |
| value = definition.example || primitivesMap[type][format] || primitivesMap[type].default; |
| } |
| |
| if (xml.attribute) { |
| return {name: name, value: value}; |
| } |
| |
| if (namespace) { |
| attributes.push(namespace); |
| } |
| |
| return wrapTag(name, value, attributes); |
| }; |
| |
| function createObjectXML (descriptor) { |
| var name = descriptor.name; |
| var definition = descriptor.definition; |
| var config = descriptor.config; |
| var models = descriptor.models; |
| var isParam = descriptor.config.isParam; |
| var serializedProperties; |
| var attrs = []; |
| var properties = definition.properties; |
| var additionalProperties = definition.additionalProperties; |
| var xml = definition.xml; |
| var namespace = getNamespace(xml); |
| |
| if (namespace) { |
| attrs.push(namespace); |
| } |
| |
| if (!properties && !additionalProperties) { return getErrorMessage(); } |
| |
| properties = properties || {}; |
| |
| serializedProperties = _.map(properties, function (prop, key) { |
| var xml, result; |
| |
| if (isParam && prop.readOnly) { |
| return ''; |
| } |
| |
| xml = prop.xml || {}; |
| result = createSchemaXML(key, prop, models, config); |
| |
| if (xml.attribute) { |
| attrs.push(result); |
| return ''; |
| } |
| |
| return result; |
| }).join(''); |
| |
| if (additionalProperties) { |
| serializedProperties += '<!-- additional elements allowed -->'; |
| } |
| |
| return wrapTag(name, serializedProperties, attrs); |
| } |
| |
| function getInfiniteLoopMessage (name, loopTo) { |
| return wrapTag(name, '<!-- Infinite loop $ref:' + loopTo + ' -->'); |
| } |
| |
| function getErrorMessage (details) { |
| details = details ? ': ' + details : ''; |
| return '<!-- invalid XML' + details + ' -->'; |
| } |
| |
| function createSchemaXML (name, definition, models, config) { |
| var $ref = _.isObject(definition) ? definition.$ref : null; |
| var output, index; |
| config = config || {}; |
| config.modelsToIgnore = config.modelsToIgnore || []; |
| |
| var descriptor = _.isString($ref) ? getDescriptorByRef($ref, name, models, config) |
| : getDescriptor(name, definition, models, config); |
| |
| if (!descriptor) { |
| return getErrorMessage(); |
| } |
| |
| switch (descriptor.type) { |
| case 'array': |
| output = createArrayXML(descriptor); break; |
| case 'object': |
| output = createObjectXML(descriptor); break; |
| case 'loop': |
| output = getInfiniteLoopMessage(descriptor.name, descriptor.config.loopTo); break; |
| default: |
| output = createPrimitiveXML(descriptor); |
| } |
| |
| if ($ref && descriptor.type !== 'loop') { |
| index = config.modelsToIgnore.indexOf($ref); |
| if (index > -1) { |
| config.modelsToIgnore.splice(index, 1); |
| } |
| } |
| |
| return output; |
| } |
| |
| function Descriptor (name, type, definition, models, config) { |
| if (arguments.length < 4) { |
| throw new Error(); |
| } |
| this.config = config || {}; |
| this.config.modelsToIgnore = this.config.modelsToIgnore || []; |
| // name is already set by getDescriptorByRef or getDescriptor function depending on the type. Only prefix, if present is needed to be set here | https://github.com/swagger-api/swagger-ui/issues/2577 |
| this.name = getPrefix(name, definition.xml); |
| this.definition = definition; |
| this.models = models; |
| this.type = type; |
| } |
| |
| function getDescriptorByRef($ref, name, models, config) { |
| var modelType = simpleRef($ref); |
| var model = models[modelType] || {}; |
| var type = model.definition && model.definition.type ? model.definition.type : 'object'; |
| // If model definition xml name is present, then that will be preferred over model name. This is the case of preferring XmlElement name over XmlRootElement name if XmlElement name is provided | https://github.com/swagger-api/swagger-ui/issues/2577 |
| if(model.definition && model.definition.xml && model.definition.xml.name) { |
| name = name || model.definition.xml.name || model.name; |
| } |
| // else only model name will be considered for determination | https://github.com/swagger-api/swagger-ui/issues/2577 |
| else { |
| name = name || model.name; |
| } |
| |
| if (config.modelsToIgnore.indexOf($ref) > -1) { |
| type = 'loop'; |
| config.loopTo = modelType; |
| } else { |
| config.modelsToIgnore.push($ref); |
| } |
| |
| if (!model.definition) { |
| return null; |
| } |
| return new Descriptor(name, type, model.definition, models, config); |
| } |
| |
| function getDescriptor (name, definition, models, config){ |
| var type = definition.type || 'object'; |
| // If definition xml name is present, then that will be preferred over name | https://github.com/swagger-api/swagger-ui/issues/2577 |
| if(definition.xml && definition.xml.name) { |
| name = definition.xml.name || name; |
| } |
| if (!definition) { |
| return null; |
| } |
| |
| return new Descriptor(name, type, definition, models, config); |
| } |
| |
| function createXMLSample (name, definition, models, isParam) { |
| var prolog = '<?xml version="1.0"?>'; |
| |
| return formatXml(prolog + createSchemaXML(name, definition, models, { isParam: isParam } )); |
| } |
| |
| return { |
| getModelSignature: getModelSignature, |
| createJSONSample: createJSONSample, |
| getParameterModelSignature: getParameterModelSignature, |
| createParameterJSONSample: createParameterJSONSample, |
| createSchemaXML: createSchemaXML, |
| createXMLSample: createXMLSample, |
| getPrimitiveSignature: getPrimitiveSignature |
| }; |
| |
| })(); |
| |
| 'use strict'; |
| |
| SwaggerUi.Views.PopupView = Backbone.View.extend({ |
| events: { |
| 'click .api-popup-cancel': 'cancelClick' |
| }, |
| |
| template: Handlebars.templates.popup, |
| className: 'api-popup-dialog', |
| |
| selectors: { |
| content: '.api-popup-content', |
| main : '#swagger-ui-container' |
| }, |
| |
| initialize: function(){ |
| this.$el.html(this.template(this.model)); |
| }, |
| |
| render: function () { |
| this.$(this.selectors.content).append(this.model.content); |
| $(this.selectors.main).first().append(this.el); |
| this.showPopup(); |
| |
| return this; |
| }, |
| |
| showPopup: function () { |
| this.$el.show(); |
| }, |
| |
| cancelClick: function () { |
| this.remove(); |
| } |
| |
| }); |
| |
| 'use strict'; |
| |
| SwaggerUi.Views.ResourceView = Backbone.View.extend({ |
| initialize: function(opts) { |
| opts = opts || {}; |
| this.router = opts.router; |
| this.auths = opts.auths; |
| if ('' === this.model.description) { |
| this.model.description = null; |
| } |
| if (this.model.description) { |
| this.model.summary = this.model.description; |
| } |
| this.number = 0; |
| }, |
| |
| render: function(){ |
| var methods = {}; |
| |
| |
| $(this.el).html(Handlebars.templates.resource(this.model)); |
| |
| // Render each operation |
| for (var i = 0; i < this.model.operationsArray.length; i++) { |
| var operation = this.model.operationsArray[i]; |
| var counter = 0; |
| var id = operation.nickname; |
| |
| while (typeof methods[id] !== 'undefined') { |
| id = id + '_' + counter; |
| counter += 1; |
| } |
| |
| methods[id] = operation; |
| |
| operation.nickname = id; |
| operation.parentId = this.model.id; |
| operation.definitions = this.model.definitions; // make Json Schema available for JSonEditor in this operation |
| this.addOperation(operation); |
| } |
| |
| $('.toggleEndpointList', this.el).click(this.callDocs.bind(this, 'toggleEndpointListForResource')); |
| $('.collapseResource', this.el).click(this.callDocs.bind(this, 'collapseOperationsForResource')); |
| $('.expandResource', this.el).click(this.callDocs.bind(this, 'expandOperationsForResource')); |
| |
| return this; |
| }, |
| |
| addOperation: function(operation) { |
| |
| operation.number = this.number; |
| |
| // Render an operation and add it to operations li |
| var operationView = new SwaggerUi.Views.OperationView({ |
| model: operation, |
| router: this.router, |
| tagName: 'li', |
| className: 'endpoint', |
| swaggerOptions: this.options.swaggerOptions, |
| auths: this.auths |
| }); |
| |
| $('.endpoints', $(this.el)).append(operationView.render().el); |
| |
| this.number++; |
| |
| }, |
| // Generic Event handler (`Docs` is global) |
| |
| |
| callDocs: function(fnName, e) { |
| e.preventDefault(); |
| Docs[fnName](e.currentTarget.getAttribute('data-id')); |
| } |
| }); |
| |
| 'use strict'; |
| |
| SwaggerUi.Views.ResponseContentTypeView = Backbone.View.extend({ |
| initialize: function(){}, |
| |
| render: function(){ |
| this.model.responseContentTypeId = 'rct' + Math.random(); |
| $(this.el).html(Handlebars.templates.response_content_type(this.model)); |
| return this; |
| } |
| }); |
| 'use strict'; |
| |
| SwaggerUi.Views.SignatureView = Backbone.View.extend({ |
| events: { |
| 'click a.description-link' : 'switchToDescription', |
| 'click a.snippet-link' : 'switchToSnippet', |
| 'mousedown .snippet_json' : 'jsonSnippetMouseDown', |
| 'mousedown .snippet_xml' : 'xmlSnippetMouseDown' |
| }, |
| |
| initialize: function () { |
| }, |
| |
| render: function(){ |
| |
| $(this.el).html(Handlebars.templates.signature(this.model)); |
| |
| if (this.model.defaultRendering === 'model') { |
| this.switchToDescription(); |
| } else { |
| this.switchToSnippet(); |
| } |
| |
| return this; |
| }, |
| |
| // handler for show signature |
| switchToDescription: function(e){ |
| if (e) { e.preventDefault(); } |
| |
| $('.snippet', $(this.el)).hide(); |
| $('.description', $(this.el)).show(); |
| $('.description-link', $(this.el)).addClass('selected'); |
| $('.snippet-link', $(this.el)).removeClass('selected'); |
| }, |
| |
| // handler for show sample |
| switchToSnippet: function(e){ |
| if (e) { e.preventDefault(); } |
| |
| $('.snippet', $(this.el)).show(); |
| $('.description', $(this.el)).hide(); |
| $('.snippet-link', $(this.el)).addClass('selected'); |
| $('.description-link', $(this.el)).removeClass('selected'); |
| }, |
| |
| // handler for snippet to text area |
| snippetToTextArea: function(val) { |
| var textArea = $('textarea', $(this.el.parentNode.parentNode.parentNode)); |
| |
| // Fix for bug in IE 10/11 which causes placeholder text to be copied to "value" |
| if ($.trim(textArea.val()) === '' || textArea.prop('placeholder') === textArea.val()) { |
| textArea.val(val); |
| // TODO move this code outside of the view and expose an event instead |
| if( this.model.jsonEditor && this.model.jsonEditor.isEnabled()){ |
| this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON)); |
| } |
| } |
| }, |
| |
| jsonSnippetMouseDown: function (e) { |
| if (this.model.isParam) { |
| if (e) { e.preventDefault(); } |
| |
| this.snippetToTextArea(this.model.sampleJSON); |
| } |
| }, |
| |
| xmlSnippetMouseDown: function (e) { |
| if (this.model.isParam) { |
| if (e) { e.preventDefault(); } |
| |
| this.snippetToTextArea(this.model.sampleXML); |
| } |
| } |
| }); |
| 'use strict'; |
| |
| SwaggerUi.Views.StatusCodeView = Backbone.View.extend({ |
| initialize: function (opts) { |
| this.options = opts || {}; |
| this.router = this.options.router; |
| }, |
| |
| render: function(){ |
| var responseModel, responseModelView; |
| var value = this.router.api.models[this.model.responseModel]; |
| $(this.el).html(Handlebars.templates.status_code(this.model)); |
| |
| if (this.router.api.models.hasOwnProperty(this.model.responseModel)) { |
| responseModel = { |
| sampleJSON: JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2), |
| sampleXML: this.model.isXML ? SwaggerUi.partials.signature.createXMLSample('', this.model.schema, this.router.api.models) : false, |
| isParam: false, |
| signature: SwaggerUi.partials.signature.getModelSignature(this.model.responseModel, value, this.router.api.models), |
| defaultRendering: this.model.defaultRendering |
| }; |
| } else { |
| responseModel = { |
| signature: SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema) |
| }; |
| } |
| |
| responseModelView = new SwaggerUi.Views.SignatureView({model: responseModel, tagName: 'div'}); |
| $('.model-signature', this.$el).append(responseModelView.render().el); |
| return this; |
| } |
| });}).call(this); |
| //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlbXBsYXRlcy5qcyIsImRvYy5qcyIsImVzNS1zaGltLmpzIiwiaGVscGVycy9oYW5kbGViYXJzLmpzIiwic2FuaXRpemUtaHRtbC5taW4uanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwiaW5kZXguanMiLCJsaWIvYXV0aC5qcyIsImxpYi9jbGllbnQuanMiLCJsaWIvaGVscGVycy5qcyIsImxpYi9odHRwLmpzIiwibGliL3Jlc29sdmVyLmpzIiwibGliL3NjaGVtYS1tYXJrdXAuanMiLCJsaWIvc3BlYy1jb252ZXJ0ZXIuanMiLCJsaWIvdHlwZXMvbW9kZWwuanMiLCJsaWIvdHlwZXMvb3BlcmF0aW9uLmpzIiwibGliL3R5cGVzL29wZXJhdGlvbkdyb3VwLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzLWFycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Nvb2tpZWphci9jb29raWVqYXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZHVtcGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZXhjZXB0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbG9hZGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbWFyay5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvZmFpbHNhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvanNvbi5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2JpbmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvYm9vbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvZmxvYXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2ludC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvZnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2pzL3JlZ2V4cC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvdW5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9tYXAuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL21lcmdlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9udWxsLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9vbWFwLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvc2VxLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9zZXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3N0ci5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvdGltZXN0YW1wLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2FycmF5L2xhc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jaGFpbi9sb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9kYXRlL25vdy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9mdW5jdGlvbi9yZXN0UGFyYW0uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9MYXp5V3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL0xvZGFzaFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUNvcHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheU1hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5U29tZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VBc3NpZ24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ29weS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDcmVhdGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGaW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUZpbmRJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9ySW4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9yT3duLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUdldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJbmRleE9mLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUlzRXF1YWwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNNYXRjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VMb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZU1hdGNoZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5RGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VTZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVNsaWNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVRvU3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmFyeUluZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluYXJ5SW5kZXhCeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmRDYWxsYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2J1ZmZlckNsb25lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY29tcG9zZUFyZ3MuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jb21wb3NlQXJnc1JpZ2h0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmFzZUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCYXNlRm9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmluZFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVDdG9yV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlSHlicmlkV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZVBhcnRpYWxXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsQXJyYXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxCeVRhZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsT2JqZWN0cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9nZXRGdW5jTmFtZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldExlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE1hdGNoRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE5hdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luZGV4T2ZOYU4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pbml0Q2xvbmVBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5pdENsb25lT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNBcnJheUxpa2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0hvc3RPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0tleS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzTGF6aWFibGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0xlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzT2JqZWN0TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzU3RyaWN0Q29tcGFyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21lcmdlRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21ldGFNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZWFsTmFtZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZW9yZGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9zZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvc2hpbUtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC90b09iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3RvUGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3dyYXBwZXJDbG9uZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc0FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNOYXRpdmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNUeXBlZEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXNJbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC92YWx1ZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9zdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvdXRpbGl0eS9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvbm9vcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvcS9xLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL2NsaWVudC5qcyIsIm5vZGVfbW9kdWxlcy9zdXBlcmFnZW50L2xpYi9pcy1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvcmVxdWVzdC1iYXNlLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL3JlcXVlc3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanMiLCJTd2FnZ2VyVWkuanMiLCJ1dGlscy91dGlscy5qcyIsInZpZXcvQXBpS2V5QXV0aE1vZGVsLmpzIiwidmlldy9BcGlLZXlBdXRoVmlldy5qcyIsInZpZXcvQXV0aEJ1dHRvblZpZXcuanMiLCJ2aWV3L0F1dGhzQ29sbGVjdGlvbi5qcyIsInZpZXcvQXV0aHNDb2xsZWN0aW9uVmlldy5qcyIsInZpZXcvQXV0aFZpZXcuanMiLCJ2aWV3L0Jhc2ljQXV0aE1vZGVsLmpzIiwidmlldy9CYXNpY0F1dGhWaWV3LmpzIiwidmlldy9Db250ZW50VHlwZVZpZXcuanMiLCJ2aWV3L0hlYWRlclZpZXcuanMiLCJ2aWV3L01haW5WaWV3LmpzIiwidmlldy9PYXV0aDJNb2RlbC5qcyIsInZpZXcvT2F1dGgyVmlldy5qcyIsInZpZXcvT3BlcmF0aW9uVmlldy5qcyIsInZpZXcvUGFyYW1ldGVyQ29udGVudFR5cGVWaWV3LmpzIiwidmlldy9QYXJhbWV0ZXJWaWV3LmpzIiwidmlldy9wYXJ0aWFscy9zaWduYXR1cmUuanMiLCJ2aWV3L1BvcHVwVmlldy5qcyIsInZpZXcvUmVzb3VyY2VWaWV3LmpzIiwidmlldy9SZXNwb25zZUNvbnRlbnRUeXBlVmlldy5qcyIsInZpZXcvU2lnbmF0dXJlVmlldy5qcyIsInZpZXcvU3RhdHVzQ29kZVZpZXcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDMXhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2poRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNOQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4WEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5NEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM29CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5c0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3L0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNseUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdIQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuZ0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaDlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ25LQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2xUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDL0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzlGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzVOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDaEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDbEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNuM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDN0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzc5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoic3dhZ2dlci11aS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi8gXG4geyhmdW5jdGlvbigpIHtcbiAgdmFyIHRlbXBsYXRlID0gSGFuZGxlYmFycy50ZW1wbGF0ZSwgdGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyB8fCB7fTtcbnRlbXBsYXRlc1snYXBpa2V5X2F1dGgnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJrZXlfYXV0aF9fdmFsdWVcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zcGFuPlxcblwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgICAgICA8aW5wdXQgcGxhY2Vob2xkZXI9XFxcImFwaV9rZXlcXFwiIGNsYXNzPVxcXCJhdXRoX2lucHV0IGlucHV0X2FwaUtleV9lbnRyeVxcXCIgbmFtZT1cXFwiYXBpS2V5XFxcIiB0eXBlPVxcXCJ0ZXh0XFxcIi8+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz1cXFwia2V5X2lucHV0X2NvbnRhaW5lclxcXCI+XFxuICAgIDxoMyBjbGFzcz1cXFwiYXV0aF9fdGl0bGVcXFwiPkFwaSBrZXkgYXV0aG9yaXphdGlvbjwvaDM+XFxuICAgIDxkaXYgY2xhc3M9XFxcImF1dGhfX2Rlc2NyaXB0aW9uXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuICAgIDxkaXY+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJrZXlfYXV0aF9fZmllbGRcXFwiPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJrZXlfYXV0aF9fbGFiZWxcXFwiPm5hbWU6PC9zcGFuPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJrZXlfYXV0aF9fdmFsdWVcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc3Bhbj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwia2V5X2F1dGhfX2ZpZWxkXFxcIj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX2xhYmVsXFxcIj5pbjo8L3NwYW4+XFxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImtleV9hdXRoX192YWx1ZVxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJpblwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zcGFuPlxcbiAgICAgICAgPC9kaXY+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJrZXlfYXV0aF9fZmllbGRcXFwiPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJrZXlfYXV0aF9fbGFiZWxcXFwiPnZhbHVlOjwvc3Bhbj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgIDwvZGl2PlxcbiAgICA8L2Rpdj5cXG48L2Rpdj5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydhdXRoX2J1dHRvbiddID0gdGVtcGxhdGUoe1wiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiPGEgY2xhc3M9J2F1dGhvcml6ZV9fYnRuJyBocmVmPVxcXCIjXFxcIj5BdXRob3JpemU8L2E+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snYXV0aF9idXR0b25fb3BlcmF0aW9uJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgIGF1dGhvcml6ZV9fYnRuX29wZXJhdGlvbl9sb2dpblxcblwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgYXV0aG9yaXplX19idG5fb3BlcmF0aW9uX2xvZ291dFxcblwiO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICA8dWwgY2xhc3M9XFxcImF1dGhvcml6ZS1zY29wZXNcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNjb3BlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg2LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgIDwvdWw+XFxuXCI7XG59LFwiNlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cXFwiYXV0aG9yaXplX19zY29wZVxcXCIgdGl0bGU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNjb3BlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xpPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImF1dGhvcml6ZV9fYnRuIGF1dGhvcml6ZV9fYnRuX29wZXJhdGlvblxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNMb2dvdXQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ2F1dGhfdmlldyddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJhdXRoX19idXR0b24gYXV0aF9zdWJtaXRfX2J1dHRvblxcXCIgZGF0YS1zdy10cmFuc2xhdGU+QXV0aG9yaXplPC9idXR0b24+XFxuXCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJhdXRoX19idXR0b24gYXV0aF9sb2dvdXRfX2J1dHRvblxcXCIgZGF0YS1zdy10cmFuc2xhdGU+TG9nb3V0PC9idXR0b24+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge307XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz1cXFwiYXV0aF9jb250YWluZXJcXFwiPlxcblxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX2lubmVyXFxcIj48L2Rpdj5cXG4gICAgPGRpdiBjbGFzcz1cXFwiYXV0aF9zdWJtaXRcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMudW5sZXNzLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0xvZ291dCA6IGRlcHRoMCkse1wibmFtZVwiOlwidW5sZXNzXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNBdXRob3JpemVkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgPC9kaXY+XFxuXFxuPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snYmFzaWNfYXV0aCddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiIC0gYXV0aG9yaXplZFwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJiYXNpY19hdXRoX192YWx1ZVxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnVzZXJuYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NwYW4+XFxuXCI7XG59LFwiNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgICAgICAgIDxpbnB1dCByZXF1aXJlZCBwbGFjZWhvbGRlcj1cXFwidXNlcm5hbWVcXFwiIGNsYXNzPVxcXCJiYXNpY19hdXRoX191c2VybmFtZSBhdXRoX2lucHV0XFxcIiBuYW1lPVxcXCJ1c2VybmFtZVxcXCIgdHlwZT1cXFwidGV4dFxcXCIvPlxcblwiO1xufSxcIjdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImF1dGhfbGFiZWxcXFwiPlxcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fbGFiZWxcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPnBhc3N3b3JkOjwvc3Bhbj5cXG4gICAgICAgICAgICAgICAgPGlucHV0IHJlcXVpcmVkIHBsYWNlaG9sZGVyPVxcXCJwYXNzd29yZFxcXCIgY2xhc3M9XFxcImJhc2ljX2F1dGhfX3Bhc3N3b3JkIGF1dGhfaW5wdXRcXFwiIG5hbWU9XFxcInBhc3N3b3JkXFxcIiB0eXBlPVxcXCJwYXNzd29yZFxcXCIvPjwvbGFiZWw+XFxuICAgICAgICAgICAgPC9kaXY+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge307XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz0nYmFzaWNfYXV0aF9jb250YWluZXInPlxcbiAgICA8aDMgY2xhc3M9XFxcImF1dGhfX3RpdGxlXFxcIj5CYXNpYyBhdXRoZW50aWNhdGlvblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNMb2dvdXQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvaDM+XFxuICAgIDxmb3JtIGNsYXNzPVxcXCJiYXNpY19pbnB1dF9jb250YWluZXJcXFwiPlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwiYXV0aF9fZGVzY3JpcHRpb25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImF1dGhfbGFiZWxcXFwiPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJiYXNpY19hdXRoX19sYWJlbFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+dXNlcm5hbWU6PC9zcGFuPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNMb2dvdXQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICAgICAgPC9kaXY+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy51bmxlc3MuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJ1bmxlc3NcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgIDwvZm9ybT5cXG48L2Rpdj5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydjb250ZW50X3R5cGUnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucHJvZHVjZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXHQ8b3B0aW9uIHZhbHVlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvb3B0aW9uPlxcblwiO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgPG9wdGlvbiB2YWx1ZT1cXFwiYXBwbGljYXRpb24vanNvblxcXCI+YXBwbGljYXRpb24vanNvbjwvb3B0aW9uPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjxsYWJlbCBkYXRhLXN3LXRyYW5zbGF0ZSBmb3I9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvbnRlbnRUeXBlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+UmVzcG9uc2UgQ29udGVudCBUeXBlPC9sYWJlbD5cXG48c2VsZWN0IG5hbWU9XFxcImNvbnRlbnRUeXBlXFxcIiBpZD1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29udGVudFR5cGVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnByb2R1Y2VzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NlbGVjdD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydtYWluJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgIDxkaXYgY2xhc3M9XFxcImluZm9fdGl0bGVcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnRpdGxlIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcbiAgPGRpdiBjbGFzcz1cXFwiaW5mb19kZXNjcmlwdGlvbiBtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuZGVzY3JpcHRpb24gOiBzdGFjazEpLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5leHRlcm5hbERvY3MgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnRlcm1zT2ZTZXJ2aWNlVXJsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLm5hbWUgOiBzdGFjazEpLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDYsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEudXJsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg4LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLmVtYWlsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEubGljZW5zZSA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiO1xufSxcIjJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgPHA+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZXh0ZXJuYWxEb2NzIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5kZXNjcmlwdGlvbiA6IHN0YWNrMSkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3A+XFxuICA8YSBocmVmPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmV4dGVybmFsRG9jcyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudXJsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIHRhcmdldD1cXFwiX2JsYW5rXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmV4dGVybmFsRG9jcyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudXJsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2E+XFxuXCI7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJpbmZvX3Rvc1xcXCI+PGEgdGFyZ2V0PVxcXCJfYmxhbmtcXFwiIGhyZWY9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnRlcm1zT2ZTZXJ2aWNlVXJsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlRlcm1zIG9mIHNlcnZpY2U8L2E+PC9kaXY+XCI7XG59LFwiNlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCI8ZGl2PjxkaXYgY2xhc3M9J2luZm9fbmFtZScgc3R5bGU9XFxcImRpc3BsYXk6IGlubGluZVxcXCIgZGF0YS1zdy10cmFuc2xhdGU+Q3JlYXRlZCBieSA8L2Rpdj4gXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5uYW1lIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cIjtcbn0sXCI4XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdpbmZvX3VybCcgZGF0YS1zdy10cmFuc2xhdGU+U2VlIG1vcmUgYXQgPGEgaHJlZj1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEudXJsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2E+PC9kaXY+XCI7XG59LFwiMTBcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9J2luZm9fZW1haWwnPjxhIHRhcmdldD1cXFwiX3BhcmVudFxcXCIgaHJlZj1cXFwibWFpbHRvOlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5lbWFpbCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiP3N1YmplY3Q9XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS50aXRsZSA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5Db250YWN0IHRoZSBkZXZlbG9wZXI8L2E+PC9kaXY+XCI7XG59LFwiMTJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9J2luZm9fbGljZW5zZSc+PGEgdGFyZ2V0PVxcXCJfYmxhbmtcXFwiIGhyZWY9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5saWNlbnNlIDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS51cmwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmxpY2Vuc2UgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLm5hbWUgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvYT48L2Rpdj5cIjtcbn0sXCIxNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICwgPHNwYW4gc3R5bGU9XFxcImZvbnQtdmFyaWFudDogc21hbGwtY2Fwc1xcXCIgZGF0YS1zdy10cmFuc2xhdGU+YXBpIHZlcnNpb248L3NwYW4+OiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS52ZXJzaW9uIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgXCI7XG59LFwiMTZcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICA8c3BhbiBzdHlsZT1cXFwiZmxvYXQ6cmlnaHRcXFwiPjxhIHRhcmdldD1cXFwiX2JsYW5rXFxcIiBocmVmPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWxpZGF0b3JVcmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIi9kZWJ1Zz91cmw9XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPjxpbWcgaWQ9XFxcInZhbGlkYXRvclxcXCIgc3JjPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWxpZGF0b3JVcmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIj91cmw9XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPjwvYT5cXG4gICAgPC9zcGFuPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9J2luZm8nIGlkPSdhcGlfaW5mbyc+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG48ZGl2IGNsYXNzPSdjb250YWluZXInIGlkPSdyZXNvdXJjZXNfY29udGFpbmVyJz5cXG4gIDxkaXYgY2xhc3M9J2F1dGhvcml6ZS13cmFwcGVyJz48L2Rpdj5cXG5cXG4gIDx1bCBpZD0ncmVzb3VyY2VzJz48L3VsPlxcblxcbiAgPGRpdiBjbGFzcz1cXFwiZm9vdGVyXFxcIj5cXG4gICAgPGg0IHN0eWxlPVxcXCJjb2xvcjogIzk5OVxcXCI+WyA8c3BhbiBzdHlsZT1cXFwiZm9udC12YXJpYW50OiBzbWFsbC1jYXBzXFxcIj5iYXNlIHVybDwvc3Bhbj46IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmJhc2VQYXRoIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudmVyc2lvbiA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTQsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIl1cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbGlkYXRvclVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTYsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8L2g0PlxcbiAgICA8L2Rpdj5cXG48L2Rpdj5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydvYXV0aDInXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiPHA+QXV0aG9yaXphdGlvbiBVUkw6IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuYXV0aG9yaXphdGlvblVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3A+XCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCI8cD5Ub2tlbiBVUkw6IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudG9rZW5VcmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9wPlwiO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgPHA+UGxlYXNlIGlucHV0IHVzZXJuYW1lIGFuZCBwYXNzd29yZCBmb3IgcGFzc3dvcmQgZmxvdyBhdXRob3JpemF0aW9uPC9wPlxcbiAgICAgICAgPGZpZWxkc2V0PlxcbiAgICAgICAgICAgIDxkaXY+PGxhYmVsPlVzZXJuYW1lOiA8aW5wdXQgY2xhc3M9XFxcIm9hdXRoLXVzZXJuYW1lXFxcIiB0eXBlPVxcXCJ0ZXh0XFxcIiBuYW1lPVxcXCJ1c2VybmFtZVxcXCI+PC9sYWJlbD48L2Rpdj5cXG4gICAgICAgICAgICA8ZGl2PjxsYWJlbD5QYXNzd29yZDogPGlucHV0IGNsYXNzPVxcXCJvYXV0aC1wYXNzd29yZFxcXCIgdHlwZT1cXFwicGFzc3dvcmRcXFwiIG5hbWU9XFxcInBhc3N3b3JkXFxcIj48L2xhYmVsPjwvZGl2PlxcbiAgICAgICAgPC9maWVsZHNldD5cXG5cIjtcbn0sXCI3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgPHA+U2V0dXAgY2xpZW50IGF1dGhlbnRpY2F0aW9uLlwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnJlcXVpcmVDbGllbnRBdXRoZW50aWNhaXRvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oOCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9wPlxcbiAgICAgICAgPGZpZWxkc2V0PlxcbiAgICAgICAgICAgIDxkaXY+PGxhYmVsPlR5cGU6XFxuICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XFxcIm9hdXRoLWNsaWVudC1hdXRoZW50aWNhdGlvbi10eXBlXFxcIiBuYW1lPVxcXCJjbGllbnQtYXV0aGVudGljYXRpb24tdHlwZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVxcXCJub25lXFxcIiBzZWxlY3RlZD5Ob25lIG9yIG90aGVyPC9vcHRpb24+XFxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVxcXCJiYXNpY1xcXCI+QmFzaWMgYXV0aDwvb3B0aW9uPlxcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cXFwicmVxdWVzdC1ib2R5XFxcIj5SZXF1ZXN0IGJvZHk8L29wdGlvbj5cXG4gICAgICAgICAgICAgICAgPC9zZWxlY3Q+XFxuICAgICAgICAgICAgPC9sYWJlbD48L2Rpdj5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJvYXV0aC1jbGllbnQtYXV0aGVudGljYXRpb25cXFwiIGhpZGRlbj5cXG4gICAgICAgICAgICAgICAgPGRpdj48bGFiZWw+Q2xpZW50SWQ6IDxpbnB1dCBjbGFzcz1cXFwib2F1dGgtY2xpZW50LWlkXFxcIiB0eXBlPVxcXCJ0ZXh0XFxcIiBuYW1lPVxcXCJjbGllbnQtaWRcXFwiPjwvbGFiZWw+PC9kaXY+XFxuICAgICAgICAgICAgICAgIDxkaXY+PGxhYmVsPlNlY3JldDogPGlucHV0IGNsYXNzPVxcXCJvYXV0aC1jbGllbnQtc2VjcmV0XFxcIiB0eXBlPVxcXCJ0ZXh0XFxcIiBuYW1lPVxcXCJjbGllbnQtc2VjcmV0XFxcIj48L2xhYmVsPjwvZGl2PlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgPC9maWVsZHNldD5cXG5cIjtcbn0sXCI4XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIoUmVxdWlyZWQpXCI7XG59LFwiMTBcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgIDxsaT5cXG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVxcXCJvYXV0aC1zY29wZVxcXCIgdHlwZT1cXFwiY2hlY2tib3hcXFwiIGRhdGEtc2NvcGU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNjb3BlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIG9hdXRodHlwZT1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuT0F1dGhTY2hlbWVLZXkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIvPlxcbiAgICAgICAgICAgICAgICA8bGFiZWw+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2NvcGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvbGFiZWw+PGJyLz5cXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImFwaS1zY29wZS1kZXNjXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5PQXV0aFNjaGVtZUtleSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICAgICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgPC9saT5cXG5cIjtcbn0sXCIxMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgICAgICAgICAgICAgICAgICAoXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLk9BdXRoU2NoZW1lS2V5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIpXFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPGRpdj5cXG4gICAgPGgzIGNsYXNzPVxcXCJhdXRoX190aXRsZVxcXCI+T0F1dGgyLjA8L2gzPlxcbiAgICA8cD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9wPlxcbiAgICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmF1dGhvcml6YXRpb25VcmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnRva2VuVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgPHA+ZmxvdzogXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZmxvdyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9wPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNQYXNzd29yZEZsb3cgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY2xpZW50QXV0aGVudGljYXRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8cD48c3Ryb25nPiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5hcHBOYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgPC9zdHJvbmc+IEFQSSByZXF1aXJlcyB0aGUgZm9sbG93aW5nIHNjb3Blcy4gU2VsZWN0IHdoaWNoIG9uZXMgeW91IHdhbnQgdG8gZ3JhbnQgdG8gU3dhZ2dlciBVSS48L3A+XFxuICAgIDxwPlNjb3BlcyBhcmUgdXNlZCB0byBncmFudCBhbiBhcHBsaWNhdGlvbiBkaWZmZXJlbnQgbGV2ZWxzIG9mIGFjY2VzcyB0byBkYXRhIG9uIGJlaGFsZiBvZiB0aGUgZW5kIHVzZXIuIEVhY2ggQVBJIG1heSBkZWNsYXJlIG9uZSBvciBtb3JlIHNjb3Blcy5cXG4gICAgICAgIDxhIGhyZWY9XFxcIiNcXFwiPkxlYXJuIGhvdyB0byB1c2U8L2E+XFxuICAgIDwvcD5cXG4gICAgPHVsIGNsYXNzPVxcXCJhcGktcG9wdXAtc2NvcGVzXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNjb3BlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgIDwvdWw+XFxuPC9kaXY+XCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snb3BlcmF0aW9uJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCJkZXByZWNhdGVkXCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgICAgPGg0PjxzcGFuIGRhdGEtc3ctdHJhbnNsYXRlPldhcm5pbmc6IERlcHJlY2F0ZWQ8L3NwYW4+PC9oND5cXG5cIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgPGg0PjxzcGFuIGRhdGEtc3ctdHJhbnNsYXRlPkltcGxlbWVudGF0aW9uIE5vdGVzPC9zcGFuPjwvaDQ+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG5cIjtcbn0sXCI3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICA8ZGl2IGNsYXNzPSdhdXRob3JpemUtd3JhcHBlciBhdXRob3JpemUtd3JhcHBlcl9vcGVyYXRpb24nPjwvZGl2PlxcblwiO1xufSxcIjlcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIiAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJyZXNwb25zZS1jbGFzc1xcXCI+XFxuICAgICAgICAgICAgPGg0PjxzcGFuIGRhdGEtc3ctdHJhbnNsYXRlPlJlc3BvbnNlIENsYXNzPC9zcGFuPiAoPHNwYW4gZGF0YS1zdy10cmFuc2xhdGU+U3RhdHVzPC9zcGFuPiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zdWNjZXNzQ29kZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiKTwvaDQ+XFxuICAgICAgICAgICAgICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnN1Y2Nlc3NEZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgICAgICAgICAgIDxwPjxzcGFuIGNsYXNzPVxcXCJtb2RlbC1zaWduYXR1cmVcXFwiIC8+PC9wPlxcbiAgICAgICAgICAgIDxici8+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicmVzcG9uc2UtY29udGVudC10eXBlXFxcIiAvPlxcbiAgICAgICAgICAgIDwvZGl2PlxcblwiO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnN1Y2Nlc3NEZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cIjtcbn0sXCIxMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgICAgPGg0IGRhdGEtc3ctdHJhbnNsYXRlPkhlYWRlcnM8L2g0PlxcbiAgICAgICAgICA8dGFibGUgY2xhc3M9XFxcImhlYWRlcnNcXFwiPlxcbiAgICAgICAgICAgIDx0aGVhZD5cXG4gICAgICAgICAgICAgIDx0cj5cXG4gICAgICAgICAgICAgICAgPHRoIHN0eWxlPVxcXCJ3aWR0aDogMTAwcHg7IG1heC13aWR0aDogMTAwcHhcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkhlYWRlcjwvdGg+XFxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDMxMHB4OyBtYXgtd2lkdGg6IDMxMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5EZXNjcmlwdGlvbjwvdGg+XFxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDIwMHB4OyBtYXgtd2lkdGg6IDIwMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5UeXBlPC90aD5cXG4gICAgICAgICAgICAgICAgPHRoIHN0eWxlPVxcXCJ3aWR0aDogMzIwcHg7IG1heC13aWR0aDogMzIwcHhcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPk90aGVyPC90aD5cXG4gICAgICAgICAgICAgIDwvdHI+XFxuICAgICAgICAgICAgPC90aGVhZD5cXG4gICAgICAgICAgICA8dGJvZHk+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaGVhZGVycyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICAgICAgPC90Ym9keT5cXG4gICAgICAgICAgPC90YWJsZT5cXG5cIjtcbn0sXCIxM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgICAgICAgICAgIDx0cj5cXG4gICAgICAgICAgICAgICAgPHRkPlwiXG4gICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmtleSB8fCAoZGF0YSAmJiBkYXRhLmtleSkpICE9IG51bGwgPyBoZWxwZXIgOiBhbGlhczIpLCh0eXBlb2YgaGVscGVyID09PSBcImZ1bmN0aW9uXCIgPyBoZWxwZXIuY2FsbChhbGlhczEse1wibmFtZVwiOlwia2V5XCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pIDogaGVscGVyKSkpXG4gICAgKyBcIjwvdGQ+XFxuICAgICAgICAgICAgICAgIDx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG4gICAgICAgICAgICAgICAgPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnR5cGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuICAgICAgICAgICAgICAgIDx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5vdGhlciA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG4gICAgICAgICAgICAgIDwvdHI+XFxuXCI7XG59LFwiMTVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+UGFyYW1ldGVyczwvaDQ+XFxuICAgICAgICAgIDx0YWJsZSBjbGFzcz0nZnVsbHdpZHRoIHBhcmFtZXRlcnMnPlxcbiAgICAgICAgICA8dGhlYWQ+XFxuICAgICAgICAgICAgPHRyPlxcbiAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDEwMHB4OyBtYXgtd2lkdGg6IDEwMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5QYXJhbWV0ZXI8L3RoPlxcbiAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDMxMHB4OyBtYXgtd2lkdGg6IDMxMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5WYWx1ZTwvdGg+XFxuICAgICAgICAgICAgPHRoIHN0eWxlPVxcXCJ3aWR0aDogMjAwcHg7IG1heC13aWR0aDogMjAwcHhcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkRlc2NyaXB0aW9uPC90aD5cXG4gICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAxMDBweDsgbWF4LXdpZHRoOiAxMDBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+UGFyYW1ldGVyIFR5cGU8L3RoPlxcbiAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDIyMHB4OyBtYXgtd2lkdGg6IDIzMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5EYXRhIFR5cGU8L3RoPlxcbiAgICAgICAgICAgIDwvdHI+XFxuICAgICAgICAgIDwvdGhlYWQ+XFxuICAgICAgICAgIDx0Ym9keSBjbGFzcz1cXFwib3BlcmF0aW9uLXBhcmFtc1xcXCI+XFxuXFxuICAgICAgICAgIDwvdGJvZHk+XFxuICAgICAgICAgIDwvdGFibGU+XFxuXCI7XG59LFwiMTdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICA8ZGl2IHN0eWxlPSdtYXJnaW46MDtwYWRkaW5nOjA7ZGlzcGxheTppbmxpbmUnPjwvZGl2PlxcbiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+UmVzcG9uc2UgTWVzc2FnZXM8L2g0PlxcbiAgICAgICAgICA8dGFibGUgY2xhc3M9J2Z1bGx3aWR0aCByZXNwb25zZS1tZXNzYWdlcyc+XFxuICAgICAgICAgICAgPHRoZWFkPlxcbiAgICAgICAgICAgIDx0cj5cXG4gICAgICAgICAgICAgIDx0aCBkYXRhLXN3LXRyYW5zbGF0ZT5IVFRQIFN0YXR1cyBDb2RlPC90aD5cXG4gICAgICAgICAgICAgIDx0aCBkYXRhLXN3LXRyYW5zbGF0ZT5SZWFzb248L3RoPlxcbiAgICAgICAgICAgICAgPHRoIGRhdGEtc3ctdHJhbnNsYXRlPlJlc3BvbnNlIE1vZGVsPC90aD5cXG4gICAgICAgICAgICAgIDx0aCBkYXRhLXN3LXRyYW5zbGF0ZT5IZWFkZXJzPC90aD5cXG4gICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgIDwvdGhlYWQ+XFxuICAgICAgICAgICAgPHRib2R5IGNsYXNzPVxcXCJvcGVyYXRpb24tc3RhdHVzXFxcIj5cXG4gICAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICA8L3RhYmxlPlxcblwiO1xufSxcIjE5XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCJcIjtcbn0sXCIyMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgIDxkaXYgY2xhc3M9J3NhbmRib3hfaGVhZGVyJz5cXG4gICAgICAgICAgICA8aW5wdXQgY2xhc3M9J3N1Ym1pdCcgdHlwZT0nc3VibWl0JyB2YWx1ZT0nVHJ5IGl0IG91dCEnIGRhdGEtc3ctdHJhbnNsYXRlLz5cXG4gICAgICAgICAgICA8YSBocmVmPScjJyBjbGFzcz0ncmVzcG9uc2VfaGlkZXInIHN0eWxlPSdkaXNwbGF5Om5vbmUnIGRhdGEtc3ctdHJhbnNsYXRlPkhpZGUgUmVzcG9uc2U8L2E+XFxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9J3Jlc3BvbnNlX3Rocm9iYmVyJyBzdHlsZT0nZGlzcGxheTpub25lJz48L3NwYW4+XFxuICAgICAgICAgIDwvZGl2PlxcblwiO1xufSxcIjIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgPGg0IGRhdGEtc3ctdHJhbnNsYXRlPlJlcXVlc3QgSGVhZGVyczwvaDQ+XFxuICAgICAgICAgIDxkaXYgY2xhc3M9J2Jsb2NrIHJlcXVlc3RfaGVhZGVycyc+PC9kaXY+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3NpbmcsIGFsaWFzMz1jb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbjtcblxuICByZXR1cm4gXCIgIDx1bCBjbGFzcz0nb3BlcmF0aW9ucycgPlxcbiAgICA8bGkgY2xhc3M9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm1ldGhvZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiIG9wZXJhdGlvbicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmVudElkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJfXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmlja25hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XFxuICAgICAgPGRpdiBjbGFzcz0naGVhZGluZyc+XFxuICAgICAgICA8aDM+XFxuICAgICAgICAgIDxzcGFuIGNsYXNzPSdodHRwX21ldGhvZCc+XFxuICAgICAgICAgIDxhIGhyZWY9JyMhL1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmVuY29kZWRQYXJlbnRJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIi9cIlxuICAgICsgYWxpYXMzKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uaWNrbmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIicgY2xhc3M9XFxcInRvZ2dsZU9wZXJhdGlvblxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubWV0aG9kIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2E+XFxuICAgICAgICAgIDwvc3Bhbj5cXG4gICAgICAgICAgPHNwYW4gY2xhc3M9J3BhdGgnPlxcbiAgICAgICAgICA8YSBocmVmPScjIS9cIlxuICAgICsgYWxpYXMzKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbmNvZGVkUGFyZW50SWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCIvXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmlja25hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCInIGNsYXNzPVxcXCJ0b2dnbGVPcGVyYXRpb24gXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXByZWNhdGVkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhdGggOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvYT5cXG4gICAgICAgICAgPC9zcGFuPlxcbiAgICAgICAgPC9oMz5cXG4gICAgICAgIDx1bCBjbGFzcz0nb3B0aW9ucyc+XFxuICAgICAgICAgIDxsaT5cXG4gICAgICAgICAgPGEgaHJlZj0nIyEvXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZW5jb2RlZFBhcmVudElkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiL1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5pY2tuYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiJyBjbGFzcz1cXFwidG9nZ2xlT3BlcmF0aW9uXFxcIj48c3BhbiBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnN1bW1hcnkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc3Bhbj48L2E+XFxuICAgICAgICAgIDwvbGk+XFxuICAgICAgICA8L3VsPlxcbiAgICAgIDwvZGl2PlxcbiAgICAgIDxkaXYgY2xhc3M9J2NvbnRlbnQnIGlkPSdcIlxuICAgICsgYWxpYXMzKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbmNvZGVkUGFyZW50SWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCJfXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmlja25hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCJfY29udGVudCcgc3R5bGU9J2Rpc3BsYXk6bm9uZSc+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXByZWNhdGVkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNlY3VyaXR5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg3LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnR5cGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDksIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaGVhZGVycyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgICAgICAgPGZvcm0gYWNjZXB0LWNoYXJzZXQ9J1VURi04JyBjbGFzcz0nc2FuZGJveCc+XFxuICAgICAgICAgIDxkaXYgc3R5bGU9J21hcmdpbjowO3BhZGRpbmc6MDtkaXNwbGF5OmlubGluZSc+PC9kaXY+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJhbWV0ZXJzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXNwb25zZU1lc3NhZ2VzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxNywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc1JlYWRPbmx5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxOSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMjEsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICAgICAgPC9mb3JtPlxcbiAgICAgICAgPGRpdiBjbGFzcz0ncmVzcG9uc2UnIHN0eWxlPSdkaXNwbGF5Om5vbmUnPlxcbiAgICAgICAgICA8aDQgY2xhc3M9J2N1cmwnPkN1cmw8L2g0PlxcbiAgICAgICAgICA8ZGl2IGNsYXNzPSdibG9jayBjdXJsJz48L2Rpdj5cXG4gICAgICAgICAgPGg0IGRhdGEtc3ctdHJhbnNsYXRlPlJlcXVlc3QgVVJMPC9oND5cXG4gICAgICAgICAgPGRpdiBjbGFzcz0nYmxvY2sgcmVxdWVzdF91cmwnPjwvZGl2PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2hvd1JlcXVlc3RIZWFkZXJzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5SZXNwb25zZSBCb2R5PC9oND5cXG4gICAgICAgICAgPGRpdiBjbGFzcz0nYmxvY2sgcmVzcG9uc2VfYm9keSc+PC9kaXY+XFxuICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5SZXNwb25zZSBDb2RlPC9oND5cXG4gICAgICAgICAgPGRpdiBjbGFzcz0nYmxvY2sgcmVzcG9uc2VfY29kZSc+PC9kaXY+XFxuICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5SZXNwb25zZSBIZWFkZXJzPC9oND5cXG4gICAgICAgICAgPGRpdiBjbGFzcz0nYmxvY2sgcmVzcG9uc2VfaGVhZGVycyc+PC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgICA8L2Rpdj5cXG4gICAgPC9saT5cXG4gIDwvdWw+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW0nXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNGaWxlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdFx0XHQ8aW5wdXQgdHlwZT1cXFwiZmlsZVxcXCIgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJy8+XFxuXHRcdFx0PGRpdiBjbGFzcz1cXFwicGFyYW1ldGVyLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG5cIjtcbn0sXCI0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNywgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJlZGl0b3JfaG9sZGVyXFxcIj48L2Rpdj5cXG5cdFx0XHRcdDx0ZXh0YXJlYSBjbGFzcz0nYm9keS10ZXh0YXJlYScgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGV4dGFyZWE+XFxuICAgICAgICA8YnIgLz5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcInBhcmFtZXRlci1jb250ZW50LXR5cGVcXFwiIC8+XFxuXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXHRcdFx0XHQ8dGV4dGFyZWEgY2xhc3M9J2JvZHktdGV4dGFyZWEnIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+PC90ZXh0YXJlYT5cXG5cdFx0XHRcdDxkaXYgY2xhc3M9XFxcImVkaXRvcl9ob2xkZXJcXFwiPjwvZGl2Plxcblx0XHRcdFx0PGJyIC8+XFxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJwYXJhbWV0ZXItY29udGVudC10eXBlXFxcIiAvPlxcblwiO1xufSxcIjlcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNGaWxlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSgxMCwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMTBcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gKGhlbHBlcnMucmVuZGVyVGV4dFBhcmFtIHx8IChkZXB0aDAgJiYgZGVwdGgwLnJlbmRlclRleHRQYXJhbSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sZGVwdGgwLHtcIm5hbWVcIjpcInJlbmRlclRleHRQYXJhbVwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMTFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIlwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjx0ZCBjbGFzcz0nY29kZSc+PGxhYmVsIGZvcj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjwvdGQ+XFxuPHRkPlxcblxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNCb2R5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg5LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG48L3RkPlxcbjx0ZCBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJhbVR5cGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPlxcblx0PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCI+PC9zcGFuPlxcbjwvdGQ+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW1fbGlzdCddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiIHJlcXVpcmVkXCI7XG59LFwiM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiIG11bHRpcGxlPVxcXCJtdWx0aXBsZVxcXCJcIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgcmVxdWlyZWQgXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICA8b3B0aW9uIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMudW5sZXNzLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaGFzRGVmYXVsdCA6IGRlcHRoMCkse1wibmFtZVwiOlwidW5sZXNzXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDgsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiB2YWx1ZT0nJz48L29wdGlvbj5cXG5cIjtcbn0sXCI4XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgIHNlbGVjdGVkPVxcXCJcXFwiIFwiO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcXG4gICAgICA8b3B0aW9uIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNEZWZhdWx0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICB2YWx1ZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0RlZmF1bHQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgPC9vcHRpb24+XFxuXFxuXCI7XG59LFwiMTFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiBzZWxlY3RlZD1cXFwiXFxcIiAgXCI7XG59LFwiMTNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAoZGVmYXVsdCkgXCI7XG59LFwiMTVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIjxzdHJvbmc+XCI7XG59LFwiMTdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIjwvc3Ryb25nPlwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGhlbHBlciwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPHRkIGNsYXNzPSdjb2RlXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz48bGFiZWwgZm9yPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvbGFiZWw+PC90ZD5cXG48dGQ+XFxuICA8c2VsZWN0IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmlzQXJyYXkgfHwgKGRlcHRoMCAmJiBkZXB0aDAuaXNBcnJheSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwiaXNBcnJheVwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgY2xhc3M9XFxcInBhcmFtZXRlciBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnJlcXVpcmVkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIG5hbWU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XFxuXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy51bmxlc3MuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnJlcXVpcmVkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJ1bmxlc3NcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmFsbG93YWJsZVZhbHVlcyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuZGVzY3JpcHRpdmVWYWx1ZXMgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgPC9zZWxlY3Q+XFxuPC90ZD5cXG48dGQgY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnJlcXVpcmVkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5kZXNjcmlwdGlvbiB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogYWxpYXMyKSwodHlwZW9mIGhlbHBlciA9PT0gXCJmdW5jdGlvblwiID8gaGVscGVyLmNhbGwoYWxpYXMxLHtcIm5hbWVcIjpcImRlc2NyaXB0aW9uXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pIDogaGVscGVyKSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnJlcXVpcmVkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxNywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1UeXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD48c3BhbiBjbGFzcz1cXFwibW9kZWwtc2lnbmF0dXJlXFxcIj48L3NwYW4+PC90ZD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydwYXJhbV9yZWFkb25seSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICAgICAgICA8dGV4dGFyZWEgY2xhc3M9J2JvZHktdGV4dGFyZWEnIHJlYWRvbmx5PSdyZWFkb25seScgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGV4dGFyZWE+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYXJhbWV0ZXItY29udGVudC10eXBlXFxcIiAvPlxcblwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg2LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCI0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgIFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiO1xufSxcIjZcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIChlbXB0eSlcXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8dGQgY2xhc3M9J2NvZGUnPjxsYWJlbCBmb3I9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9sYWJlbD48L3RkPlxcbjx0ZD5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzQm9keSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQgY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1UeXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD48c3BhbiBjbGFzcz1cXFwibW9kZWwtc2lnbmF0dXJlXFxcIj48L3NwYW4+PC90ZD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydwYXJhbV9yZWFkb25seV9yZXF1aXJlZCddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICAgICAgICA8dGV4dGFyZWEgY2xhc3M9J2JvZHktdGV4dGFyZWEnIHJlYWRvbmx5PSdyZWFkb25seScgcGxhY2Vob2xkZXI9JyhyZXF1aXJlZCknIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RleHRhcmVhPlxcblwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg2LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCI0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgIFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiO1xufSxcIjZcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIChlbXB0eSlcXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8dGQgY2xhc3M9J2NvZGUgcmVxdWlyZWQnPjxsYWJlbCBmb3I9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9sYWJlbD48L3RkPlxcbjx0ZD5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzQm9keSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQgY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1UeXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD48c3BhbiBjbGFzcz1cXFwibW9kZWwtc2lnbmF0dXJlXFxcIj48L3NwYW4+PC90ZD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydwYXJhbV9yZXF1aXJlZCddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0ZpbGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0XHRcdDxpbnB1dCB0eXBlPVxcXCJmaWxlXFxcIiBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInLz5cXG5cIjtcbn0sXCI0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNywgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJlZGl0b3JfaG9sZGVyXFxcIj48L2Rpdj5cXG5cdFx0XHRcdDx0ZXh0YXJlYSBjbGFzcz0nYm9keS10ZXh0YXJlYSByZXF1aXJlZCcgcGxhY2Vob2xkZXI9JyhyZXF1aXJlZCknIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RleHRhcmVhPlxcbiAgICAgICAgPGJyIC8+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYXJhbWV0ZXItY29udGVudC10eXBlXFxcIiAvPlxcblwiO1xufSxcIjdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0XHRcdFx0PHRleHRhcmVhIGNsYXNzPSdib2R5LXRleHRhcmVhIHJlcXVpcmVkJyBwbGFjZWhvbGRlcj0nKHJlcXVpcmVkKScgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz48L3RleHRhcmVhPlxcblx0XHRcdFx0PGRpdiBjbGFzcz1cXFwiZWRpdG9yX2hvbGRlclxcXCI+PC9kaXY+XFxuXHRcdFx0XHQ8YnIgLz5cXG5cdFx0XHRcdDxkaXYgY2xhc3M9XFxcInBhcmFtZXRlci1jb250ZW50LXR5cGVcXFwiIC8+XFxuXCI7XG59LFwiOVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0ZpbGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEwLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSgxMiwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMTBcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0XHRcdDxpbnB1dCBjbGFzcz0ncGFyYW1ldGVyIHJlcXVpcmVkJyB0eXBlPSdmaWxlJyBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInLz5cXG5cIjtcbn0sXCIxMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSAoaGVscGVycy5yZW5kZXJUZXh0UGFyYW0gfHwgKGRlcHRoMCAmJiBkZXB0aDAucmVuZGVyVGV4dFBhcmFtKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSxkZXB0aDAse1wibmFtZVwiOlwicmVuZGVyVGV4dFBhcmFtXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIxM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPHRkIGNsYXNzPSdjb2RlIHJlcXVpcmVkJz48bGFiZWwgZm9yPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvbGFiZWw+PC90ZD5cXG48dGQ+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0JvZHkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDksIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPlxcblx0PHN0cm9uZz48c3BhbiBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NwYW4+PC9zdHJvbmc+XFxuPC90ZD5cXG48dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1UeXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD48c3BhbiBjbGFzcz1cXFwibW9kZWwtc2lnbmF0dXJlXFxcIj48L3NwYW4+PC90ZD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydwYXJhbWV0ZXJfY29udGVudF90eXBlJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvbnN1bWVzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgPG9wdGlvbiB2YWx1ZT1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L29wdGlvbj5cXG5cIjtcbn0sXCI0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgIDxvcHRpb24gdmFsdWU9XFxcImFwcGxpY2F0aW9uL2pzb25cXFwiPmFwcGxpY2F0aW9uL2pzb248L29wdGlvbj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBoZWxwZXIsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjxsYWJlbCBmb3I9XFxcIlwiXG4gICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLnBhcmFtZXRlckNvbnRlbnRUeXBlSWQgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtZXRlckNvbnRlbnRUeXBlSWQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogYWxpYXMyKSwodHlwZW9mIGhlbHBlciA9PT0gXCJmdW5jdGlvblwiID8gaGVscGVyLmNhbGwoYWxpYXMxLHtcIm5hbWVcIjpcInBhcmFtZXRlckNvbnRlbnRUeXBlSWRcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5QYXJhbWV0ZXIgY29udGVudCB0eXBlOjwvbGFiZWw+XFxuPHNlbGVjdCBuYW1lPVxcXCJwYXJhbWV0ZXJDb250ZW50VHlwZVxcXCIgaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJhbWV0ZXJDb250ZW50VHlwZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb25zdW1lcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zZWxlY3Q+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncG9wdXAnXSA9IHRlbXBsYXRlKHtcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBoZWxwZXI7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz1cXFwiYXBpLXBvcHVwLWRpYWxvZy13cmFwcGVyXFxcIj5cXG4gICAgPGRpdiBjbGFzcz1cXFwiYXBpLXBvcHVwLXRpdGxlXFxcIj5cIlxuICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy50aXRsZSB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudGl0bGUgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gXCJmdW5jdGlvblwiID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7XCJuYW1lXCI6XCJ0aXRsZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKVxuICAgICsgXCI8L2Rpdj5cXG4gICAgPGRpdiBjbGFzcz1cXFwiYXBpLXBvcHVwLWNvbnRlbnRcXFwiPjwvZGl2PlxcbiAgICA8cCBjbGFzcz1cXFwiZXJyb3ItbXNnXFxcIj48L3A+XFxuICAgIDxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC1hY3Rpb25zXFxcIj5cXG4gICAgICAgIDxidXR0b24gY2xhc3M9XFxcImFwaS1wb3B1cC1jYW5jZWwgYXBpLWJ1dHRvbiBncmF5XFxcIiB0eXBlPVxcXCJidXR0b25cXFwiPkNhbmNlbDwvYnV0dG9uPlxcbiAgICA8L2Rpdj5cXG48L2Rpdj5cXG48ZGl2IGNsYXNzPVxcXCJhcGktcG9wdXAtZGlhbG9nLXNoYWRvd1xcXCI+PC9kaXY+XCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncmVzb3VyY2UnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiA6IFwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgIDxsaT5cXG4gICAgICA8YSBocmVmPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGRhdGEtc3ctdHJhbnNsYXRlPlJhdzwvYT5cXG4gICAgPC9saT5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBoZWxwZXIsIG9wdGlvbnMsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nLCBidWZmZXIgPSBcbiAgXCI8ZGl2IGNsYXNzPSdoZWFkaW5nJz5cXG4gIDxoMj5cXG4gICAgPGEgaHJlZj0nIyEvXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgY2xhc3M9XFxcInRvZ2dsZUVuZHBvaW50TGlzdFxcXCIgZGF0YS1pZD1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPiBcIjtcbiAgc3RhY2sxID0gKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5zdW1tYXJ5IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zdW1tYXJ5IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKG9wdGlvbnM9e1wibmFtZVwiOlwic3VtbWFyeVwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGFsaWFzMSxvcHRpb25zKSA6IGhlbHBlcikpO1xuICBpZiAoIWhlbHBlcnMuc3VtbWFyeSkgeyBzdGFjazEgPSBoZWxwZXJzLmJsb2NrSGVscGVyTWlzc2luZy5jYWxsKGRlcHRoMCxzdGFjazEsb3B0aW9ucyl9XG4gIGlmIChzdGFjazEgIT0gbnVsbCkgeyBidWZmZXIgKz0gc3RhY2sxOyB9XG4gIHJldHVybiBidWZmZXIgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zdW1tYXJ5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgPC9oMj5cXG4gIDx1bCBjbGFzcz0nb3B0aW9ucyc+XFxuICAgIDxsaT5cXG4gICAgICA8YSBocmVmPScjIS9cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nZW5kcG9pbnRMaXN0VG9nZ2VyX1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGNsYXNzPVxcXCJ0b2dnbGVFbmRwb2ludExpc3RcXFwiIGRhdGEtaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlNob3cvSGlkZTwvYT5cXG4gICAgPC9saT5cXG4gICAgPGxpPlxcbiAgICAgIDxhIGhyZWY9JyMnIGNsYXNzPVxcXCJjb2xsYXBzZVJlc291cmNlXFxcIiBkYXRhLWlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5cXG4gICAgICAgIExpc3QgT3BlcmF0aW9uc1xcbiAgICAgIDwvYT5cXG4gICAgPC9saT5cXG4gICAgPGxpPlxcbiAgICAgIDxhIGhyZWY9JyMnIGNsYXNzPVxcXCJleHBhbmRSZXNvdXJjZVxcXCIgZGF0YS1pZD1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+XFxuICAgICAgICBFeHBhbmQgT3BlcmF0aW9uc1xcbiAgICAgIDwvYT5cXG4gICAgPC9saT5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICA8L3VsPlxcbjwvZGl2Plxcbjx1bCBjbGFzcz0nZW5kcG9pbnRzJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIl9lbmRwb2ludF9saXN0JyBzdHlsZT0nZGlzcGxheTpub25lJz5cXG5cXG48L3VsPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3Jlc3BvbnNlX2NvbnRlbnRfdHlwZSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wcm9kdWNlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgIDxvcHRpb24gdmFsdWU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9vcHRpb24+XFxuXCI7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICA8b3B0aW9uIHZhbHVlPVxcXCJhcHBsaWNhdGlvbi9qc29uXFxcIj5hcHBsaWNhdGlvbi9qc29uPC9vcHRpb24+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZywgYWxpYXMzPVwiZnVuY3Rpb25cIiwgYWxpYXM0PWNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uO1xuXG4gIHJldHVybiBcIjxsYWJlbCBkYXRhLXN3LXRyYW5zbGF0ZSBmb3I9XFxcIlwiXG4gICAgKyBhbGlhczQoKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5yZXNwb25zZUNvbnRlbnRUeXBlSWQgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnJlc3BvbnNlQ29udGVudFR5cGVJZCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBhbGlhczIpLCh0eXBlb2YgaGVscGVyID09PSBhbGlhczMgPyBoZWxwZXIuY2FsbChhbGlhczEse1wibmFtZVwiOlwicmVzcG9uc2VDb250ZW50VHlwZUlkXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pIDogaGVscGVyKSkpXG4gICAgKyBcIlxcXCI+UmVzcG9uc2UgQ29udGVudCBUeXBlPC9sYWJlbD5cXG48c2VsZWN0IG5hbWU9XFxcInJlc3BvbnNlQ29udGVudFR5cGVcXFwiIGlkPVxcXCJcIlxuICAgICsgYWxpYXM0KCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMucmVzcG9uc2VDb250ZW50VHlwZUlkIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXNwb25zZUNvbnRlbnRUeXBlSWQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogYWxpYXMyKSwodHlwZW9mIGhlbHBlciA9PT0gYWxpYXMzID8gaGVscGVyLmNhbGwoYWxpYXMxLHtcIm5hbWVcIjpcInJlc3BvbnNlQ29udGVudFR5cGVJZFwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKVxuICAgICsgXCJcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucHJvZHVjZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc2VsZWN0PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3NpZ25hdHVyZSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge307XG5cbiAgcmV0dXJuIFwiXFxuPGRpdj5cXG48dWwgY2xhc3M9XFxcInNpZ25hdHVyZS1uYXZcXFwiPlxcbiAgPGxpPjxhIGNsYXNzPVxcXCJkZXNjcmlwdGlvbi1saW5rXFxcIiBocmVmPVxcXCIjXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5Nb2RlbDwvYT48L2xpPlxcbiAgPGxpPjxhIGNsYXNzPVxcXCJzbmlwcGV0LWxpbmtcXFwiIGhyZWY9XFxcIiNcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkV4YW1wbGUgVmFsdWU8L2E+PC9saT5cXG48L3VsPlxcbjxkaXY+XFxuXFxuPGRpdiBjbGFzcz1cXFwic2lnbmF0dXJlLWNvbnRhaW5lclxcXCI+XFxuICA8ZGl2IGNsYXNzPVxcXCJkZXNjcmlwdGlvblxcXCI+XFxuICAgICAgXCJcbiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zaWduYXR1cmUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCJcXG4gIDwvZGl2PlxcblxcbiAgPGRpdiBjbGFzcz1cXFwic25pcHBldFxcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zYW1wbGVKU09OIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNhbXBsZVhNTCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICA8L2Rpdj5cXG48L2Rpdj5cXG5cIjtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCIgICAgICA8ZGl2IGNsYXNzPVxcXCJzbmlwcGV0X2pzb25cXFwiPlxcbiAgICAgICAgPHByZT48Y29kZT5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zYW1wbGVKU09OIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2NvZGU+PC9wcmU+XFxuICAgICAgICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzUGFyYW0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgICAgIDwvZGl2PlxcblwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIjxzbWFsbCBjbGFzcz1cXFwibm90aWNlXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT48L3NtYWxsPlwiO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIiAgICA8ZGl2IGNsYXNzPVxcXCJzbmlwcGV0X3htbFxcXCI+XFxuICAgICAgPHByZT48Y29kZT5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zYW1wbGVYTUwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvY29kZT48L3ByZT5cXG4gICAgICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzUGFyYW0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgICA8L2Rpdj5cXG5cIjtcbn0sXCI3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2lnbmF0dXJlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IChoZWxwZXJzLmlmQ29uZCB8fCAoZGVwdGgwICYmIGRlcHRoMC5pZkNvbmQpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zYW1wbGVKU09OIDogZGVwdGgwKSxcInx8XCIsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNhbXBsZVhNTCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZDb25kXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3N0YXR1c19jb2RlJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBoZWxwZXIsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICAgIDx0cj5cXG4gICAgICAgIDx0ZD5cIlxuICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5rZXkgfHwgKGRhdGEgJiYgZGF0YS5rZXkpKSAhPSBudWxsID8gaGVscGVyIDogYWxpYXMyKSwodHlwZW9mIGhlbHBlciA9PT0gXCJmdW5jdGlvblwiID8gaGVscGVyLmNhbGwoYWxpYXMxLHtcIm5hbWVcIjpcImtleVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKVxuICAgICsgXCI8L3RkPlxcbiAgICAgICAgPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbiAgICAgICAgPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnR5cGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuICAgICAgPC90cj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8dGQgd2lkdGg9JzE1JScgY2xhc3M9J2NvZGUnPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvZGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkIGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubWVzc2FnZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQgd2lkdGg9JzUwJSc+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCIgLz48L3RkPlxcbjx0ZCBjbGFzcz1cXFwiaGVhZGVyc1xcXCI+XFxuICA8dGFibGU+XFxuICAgIDx0Ym9keT5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmhlYWRlcnMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgIDwvdGJvZHk+XFxuICA8L3RhYmxlPlxcbjwvdGQ+XCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbn0pKCk7fSBcbiAvKiBqc2hpbnQgaWdub3JlOmVuZCAqLyIsIid1c2Ugc3RyaWN0JztcblxuXG4kKGZ1bmN0aW9uKCkge1xuXG5cdC8vIEhlbHBlciBmdW5jdGlvbiBmb3IgdmVydGljYWxseSBhbGlnbmluZyBET00gZWxlbWVudHNcblx0Ly8gaHR0cDovL3d3dy5zZW9kZW52ZXIuY29tL3NpbXBsZS12ZXJ0aWNhbC1hbGlnbi1wbHVnaW4tZm9yLWpxdWVyeS9cblx0JC5mbi52QWxpZ24gPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7XG5cdFx0XHR2YXIgYWggPSAkKHRoaXMpLmhlaWdodCgpO1xuXHRcdFx0dmFyIHBoID0gJCh0aGlzKS5wYXJlbnQoKS5oZWlnaHQoKTtcblx0XHRcdHZhciBtaCA9IChwaCAtIGFoKSAvIDI7XG5cdFx0XHQkKHRoaXMpLmNzcygnbWFyZ2luLXRvcCcsIG1oKTtcblx0XHR9KTtcblx0fTtcblxuXHQkLmZuLnN0cmV0Y2hGb3JtdGFzdGljSW5wdXRXaWR0aFRvUGFyZW50ID0gZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe1xuXHRcdFx0dmFyIHBfd2lkdGggPSAkKHRoaXMpLmNsb3Nlc3QoXCJmb3JtXCIpLmlubmVyV2lkdGgoKTtcblx0XHRcdHZhciBwX3BhZGRpbmcgPSBwYXJzZUludCgkKHRoaXMpLmNsb3Nlc3QoXCJmb3JtXCIpLmNzcygncGFkZGluZy1sZWZ0JykgLDEwKSArIHBhcnNlSW50KCQodGhpcykuY2xvc2VzdCgnZm9ybScpLmNzcygncGFkZGluZy1yaWdodCcpLCAxMCk7XG5cdFx0XHR2YXIgdGhpc19wYWRkaW5nID0gcGFyc2VJbnQoJCh0aGlzKS5jc3MoJ3BhZGRpbmctbGVmdCcpLCAxMCkgKyBwYXJzZUludCgkKHRoaXMpLmNzcygncGFkZGluZy1yaWdodCcpLCAxMCk7XG5cdFx0XHQkKHRoaXMpLmNzcygnd2lkdGgnLCBwX3dpZHRoIC0gcF9wYWRkaW5nIC0gdGhpc19wYWRkaW5nKTtcblx0XHR9KTtcblx0fTtcblxuXHQkKCdmb3JtLmZvcm10YXN0aWMgbGkuc3RyaW5nIGlucHV0LCBmb3JtLmZvcm10YXN0aWMgdGV4dGFyZWEnKS5zdHJldGNoRm9ybXRhc3RpY0lucHV0V2lkdGhUb1BhcmVudCgpO1xuXG5cdC8vIFZlcnRpY2FsbHkgY2VudGVyIHRoZXNlIHBhcmFncmFwaHNcblx0Ly8gUGFyZW50IG1heSBuZWVkIGEgbWluLWhlaWdodCBmb3IgdGhpcyB0byB3b3JrLi5cblx0JCgndWwuZG93bnBsYXllZCBsaSBkaXYuY29udGVudCBwJykudkFsaWduKCk7XG5cblx0Ly8gV2hlbiBhIHNhbmRib3ggZm9ybSBpcyBzdWJtaXR0ZWQuLlxuXHQkKFwiZm9ybS5zYW5kYm94XCIpLnN1Ym1pdChmdW5jdGlvbigpe1xuXG5cdFx0dmFyIGVycm9yX2ZyZWUgPSB0cnVlO1xuXG5cdFx0Ly8gQ3ljbGUgdGhyb3VnaCB0aGUgZm9ybXMgcmVxdWlyZWQgaW5wdXRzXG4gXHRcdCQodGhpcykuZmluZChcImlucHV0LnJlcXVpcmVkXCIpLmVhY2goZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIFJlbW92ZSBhbnkgZXhpc3RpbmcgZXJyb3Igc3R5bGVzIGZyb20gdGhlIGlucHV0XG5cdFx0XHQkKHRoaXMpLnJlbW92ZUNsYXNzKCdlcnJvcicpO1xuXG5cdFx0XHQvLyBUYWNrIHRoZSBlcnJvciBzdHlsZSBvbiBpZiB0aGUgaW5wdXQgaXMgZW1wdHkuLlxuXHRcdFx0aWYgKCQodGhpcykudmFsKCkgPT09ICcnKSB7XG5cdFx0XHRcdCQodGhpcykuYWRkQ2xhc3MoJ2Vycm9yJyk7XG5cdFx0XHRcdCQodGhpcykud2lnZ2xlKCk7XG5cdFx0XHRcdGVycm9yX2ZyZWUgPSBmYWxzZTtcblx0XHRcdH1cblxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIGVycm9yX2ZyZWU7XG5cdH0pO1xuXG59KTtcblxuZnVuY3Rpb24gY2xpcHB5Q29waWVkQ2FsbGJhY2soKSB7XG4gICQoJyNhcGlfa2V5X2NvcGllZCcpLmZhZGVJbigpLmRlbGF5KDEwMDApLmZhZGVPdXQoKTtcblxuICAvLyB2YXIgYiA9ICQoXCIjY2xpcHB5X3Rvb2x0aXBfXCIgKyBhKTtcbiAgLy8gYi5sZW5ndGggIT0gMCAmJiAoYi5hdHRyKFwidGl0bGVcIiwgXCJjb3BpZWQhXCIpLnRyaWdnZXIoXCJ0aXBzeS5yZWxvYWRcIiksIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gIC8vICAgYi5hdHRyKFwidGl0bGVcIiwgXCJjb3B5IHRvIGNsaXBib2FyZFwiKVxuICAvLyB9LFxuICAvLyA1MDApKVxufVxuXG4vLyBMb2dnaW5nIGZ1bmN0aW9uIHRoYXQgYWNjb3VudHMgZm9yIGJyb3dzZXJzIHRoYXQgZG9uJ3QgaGF2ZSB3aW5kb3cuY29uc29sZVxuZnVuY3Rpb24gbG9nKCl7XG4gIGxvZy5oaXN0b3J5ID0gbG9nLmhpc3RvcnkgfHwgW107XG4gIGxvZy5oaXN0b3J5LnB1c2goYXJndW1lbnRzKTtcbiAgaWYodGhpcy5jb25zb2xlKXtcbiAgICBjb25zb2xlLmxvZyggQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKVswXSApO1xuICB9XG59XG5cbi8vIEhhbmRsZSBicm93c2VycyB0aGF0IGRvIGNvbnNvbGUgaW5jb3JyZWN0bHkgKElFOSBhbmQgYmVsb3csIHNlZSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS81NTM5Mzc4Lzc5MTMpXG5pZiAoRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgJiYgY29uc29sZSAmJiB0eXBlb2YgY29uc29sZS5sb2cgPT09IFwib2JqZWN0XCIpIHtcbiAgICBbXG4gICAgICBcImxvZ1wiLFwiaW5mb1wiLFwid2FyblwiLFwiZXJyb3JcIixcImFzc2VydFwiLFwiZGlyXCIsXCJjbGVhclwiLFwicHJvZmlsZVwiLFwicHJvZmlsZUVuZFwiXG4gICAgXS5mb3JFYWNoKGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgICAgICAgY29uc29sZVttZXRob2RdID0gdGhpcy5iaW5kKGNvbnNvbGVbbWV0aG9kXSwgY29uc29sZSk7XG4gICAgfSwgRnVuY3Rpb24ucHJvdG90eXBlLmNhbGwpO1xufVxuXG53aW5kb3cuRG9jcyA9IHtcblxuXHRzaGViYW5nOiBmdW5jdGlvbigpIHtcblxuXHRcdC8vIElmIHNoZWJhbmcgaGFzIGFuIG9wZXJhdGlvbiBuaWNrbmFtZSBpbiBpdC4uXG5cdFx0Ly8gZS5nLiAvZG9jcy8jIS93b3Jkcy9nZXRfc2VhcmNoXG5cdFx0dmFyIGZyYWdtZW50cyA9ICQucGFyYW0uZnJhZ21lbnQoKS5zcGxpdCgnLycpO1xuXHRcdGZyYWdtZW50cy5zaGlmdCgpOyAvLyBnZXQgcmlkIG9mIHRoZSBiYW5nXG5cblx0XHRzd2l0Y2ggKGZyYWdtZW50cy5sZW5ndGgpIHtcblx0XHRcdGNhc2UgMTpcbiAgICAgICAgaWYgKGZyYWdtZW50c1swXS5sZW5ndGggPiAwKSB7IC8vIHByZXZlbnQgbWF0Y2hpbmcgXCIjL1wiXG4gICAgICAgICAgLy8gRXhwYW5kIGFsbCBvcGVyYXRpb25zIGZvciB0aGUgcmVzb3VyY2UgYW5kIHNjcm9sbCB0byBpdFxuICAgICAgICAgIHZhciBkb21faWQgPSAncmVzb3VyY2VfJyArIGZyYWdtZW50c1swXTtcblxuICAgICAgICAgIERvY3MuZXhwYW5kRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UoZnJhZ21lbnRzWzBdKTtcbiAgICAgICAgICAkKFwiI1wiK2RvbV9pZCkuc2xpZGV0byh7aGlnaGxpZ2h0OiBmYWxzZX0pO1xuICAgICAgICB9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHQvLyBSZWZlciB0byB0aGUgZW5kcG9pbnQgRE9NIGVsZW1lbnQsIGUuZy4gI3dvcmRzX2dldF9zZWFyY2hcblxuICAgICAgICAvLyBFeHBhbmQgUmVzb3VyY2VcbiAgICAgICAgRG9jcy5leHBhbmRFbmRwb2ludExpc3RGb3JSZXNvdXJjZShmcmFnbWVudHNbMF0pO1xuICAgICAgICAkKFwiI1wiK2RvbV9pZCkuc2xpZGV0byh7aGlnaGxpZ2h0OiBmYWxzZX0pO1xuXG4gICAgICAgICAgICAvLyBFeHBhbmQgb3BlcmF0aW9uXG4gICAgICAgICAgICB2YXIgbGlfZG9tX2lkID0gZnJhZ21lbnRzLmpvaW4oJ18nKTtcbiAgICAgICAgICAgIHZhciBsaV9jb250ZW50X2RvbV9pZCA9IGxpX2RvbV9pZCArIFwiX2NvbnRlbnRcIjtcblxuXG4gICAgICAgICAgICBEb2NzLmV4cGFuZE9wZXJhdGlvbigkKCcjJytsaV9jb250ZW50X2RvbV9pZCkpO1xuICAgICAgICAgICAgJCgnIycrbGlfZG9tX2lkKS5zbGlkZXRvKHtoaWdobGlnaHQ6IGZhbHNlfSk7XG4gICAgICAgICAgICBicmVhaztcblx0XHR9XG5cdH0sXG5cblx0dG9nZ2xlRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2U6IGZ1bmN0aW9uKHJlc291cmNlKSB7XG5cdFx0dmFyIGVsZW0gPSAkKCdsaSNyZXNvdXJjZV8nICsgRG9jcy5lc2NhcGVSZXNvdXJjZU5hbWUocmVzb3VyY2UpICsgJyB1bC5lbmRwb2ludHMnKTtcblx0XHRpZiAoZWxlbS5pcygnOnZpc2libGUnKSkge1xuXHRcdFx0JC5iYnEucHVzaFN0YXRlKCcjLycsIDIpO1xuXHRcdFx0RG9jcy5jb2xsYXBzZUVuZHBvaW50TGlzdEZvclJlc291cmNlKHJlc291cmNlKTtcblx0XHR9IGVsc2Uge1xuICAgICAgICAgICAgJC5iYnEucHVzaFN0YXRlKCcjLycgKyByZXNvdXJjZSwgMik7XG5cdFx0XHREb2NzLmV4cGFuZEVuZHBvaW50TGlzdEZvclJlc291cmNlKHJlc291cmNlKTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gRXhwYW5kIHJlc291cmNlXG5cdGV4cGFuZEVuZHBvaW50TGlzdEZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdHZhciByZXNvdXJjZSA9IERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKTtcblx0XHRpZiAocmVzb3VyY2UgPT0gJycpIHtcblx0XHRcdCQoJy5yZXNvdXJjZSB1bC5lbmRwb2ludHMnKS5zbGlkZURvd24oKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQkKCdsaSNyZXNvdXJjZV8nICsgcmVzb3VyY2UpLmFkZENsYXNzKCdhY3RpdmUnKTtcblxuXHRcdHZhciBlbGVtID0gJCgnbGkjcmVzb3VyY2VfJyArIHJlc291cmNlICsgJyB1bC5lbmRwb2ludHMnKTtcblx0XHRlbGVtLnNsaWRlRG93bigpO1xuXHR9LFxuXG5cdC8vIENvbGxhcHNlIHJlc291cmNlIGFuZCBtYXJrIGFzIGV4cGxpY2l0bHkgY2xvc2VkXG5cdGNvbGxhcHNlRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2U6IGZ1bmN0aW9uKHJlc291cmNlKSB7XG5cdFx0dmFyIHJlc291cmNlID0gRG9jcy5lc2NhcGVSZXNvdXJjZU5hbWUocmVzb3VyY2UpO1xuXHRcdGlmIChyZXNvdXJjZSA9PSAnJykge1xuXHRcdFx0JCgnLnJlc291cmNlIHVsLmVuZHBvaW50cycpLnNsaWRlVXAoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQkKCdsaSNyZXNvdXJjZV8nICsgcmVzb3VyY2UpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcblxuXHRcdHZhciBlbGVtID0gJCgnbGkjcmVzb3VyY2VfJyArIHJlc291cmNlICsgJyB1bC5lbmRwb2ludHMnKTtcblx0XHRlbGVtLnNsaWRlVXAoKTtcblx0fSxcblxuXHRleHBhbmRPcGVyYXRpb25zRm9yUmVzb3VyY2U6IGZ1bmN0aW9uKHJlc291cmNlKSB7XG5cdFx0Ly8gTWFrZSBzdXJlIHRoZSByZXNvdXJjZSBjb250YWluZXIgaXMgb3Blbi4uXG5cdFx0RG9jcy5leHBhbmRFbmRwb2ludExpc3RGb3JSZXNvdXJjZShyZXNvdXJjZSk7XG5cblx0XHRpZiAocmVzb3VyY2UgPT0gJycpIHtcblx0XHRcdCQoJy5yZXNvdXJjZSB1bC5lbmRwb2ludHMgbGkub3BlcmF0aW9uIGRpdi5jb250ZW50Jykuc2xpZGVEb3duKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0JCgnbGkjcmVzb3VyY2VfJyArIERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKSArICcgbGkub3BlcmF0aW9uIGRpdi5jb250ZW50JykuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdERvY3MuZXhwYW5kT3BlcmF0aW9uKCQodGhpcykpO1xuXHRcdH0pO1xuXHR9LFxuXG5cdGNvbGxhcHNlT3BlcmF0aW9uc0ZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdC8vIE1ha2Ugc3VyZSB0aGUgcmVzb3VyY2UgY29udGFpbmVyIGlzIG9wZW4uLlxuXHRcdERvY3MuZXhwYW5kRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UocmVzb3VyY2UpO1xuXG5cdFx0aWYgKHJlc291cmNlID09ICcnKSB7XG5cdFx0XHQkKCcucmVzb3VyY2UgdWwuZW5kcG9pbnRzIGxpLm9wZXJhdGlvbiBkaXYuY29udGVudCcpLnNsaWRlVXAoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQkKCdsaSNyZXNvdXJjZV8nICsgRG9jcy5lc2NhcGVSZXNvdXJjZU5hbWUocmVzb3VyY2UpICsgJyBsaS5vcGVyYXRpb24gZGl2LmNvbnRlbnQnKS5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0RG9jcy5jb2xsYXBzZU9wZXJhdGlvbigkKHRoaXMpKTtcblx0XHR9KTtcblx0fSxcblxuXHRlc2NhcGVSZXNvdXJjZU5hbWU6IGZ1bmN0aW9uKHJlc291cmNlKSB7XG5cdFx0cmV0dXJuIHJlc291cmNlLnJlcGxhY2UoL1shXCIjJCUmJygpKissLlxcLzo7PD0+P0BcXFtcXFxcXFxdXFxeYHt8fX5dL2csIFwiXFxcXCQmXCIpO1xuXHR9LFxuXG5cdGV4cGFuZE9wZXJhdGlvbjogZnVuY3Rpb24oZWxlbSkge1xuXHRcdGVsZW0uc2xpZGVEb3duKCk7XG5cdH0sXG5cblx0Y29sbGFwc2VPcGVyYXRpb246IGZ1bmN0aW9uKGVsZW0pIHtcblx0XHRlbGVtLnNsaWRlVXAoKTtcblx0fVxufTtcbiIsIi8qIVxuICogaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltXG4gKiBAbGljZW5zZSBlczUtc2hpbSBDb3B5cmlnaHQgMjAwOS0yMDE1IGJ5IGNvbnRyaWJ1dG9ycywgTUlUIExpY2Vuc2VcbiAqIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbi8vIHZpbTogdHM9NCBzdHM9NCBzdz00IGV4cGFuZHRhYlxuXG4vLyBBZGQgc2VtaWNvbG9uIHRvIHByZXZlbnQgSUlGRSBmcm9tIGJlaW5nIHBhc3NlZCBhcyBhcmd1bWVudCB0byBjb25jYXRlbmF0ZWQgY29kZS5cbjtcblxuLy8gVU1EIChVbml2ZXJzYWwgTW9kdWxlIERlZmluaXRpb24pXG4vLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3VtZGpzL3VtZC9ibG9iL21hc3Rlci90ZW1wbGF0ZXMvcmV0dXJuRXhwb3J0cy5qc1xuKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyogZ2xvYmFsIGRlZmluZSwgZXhwb3J0cywgbW9kdWxlICovXG4gICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICAvLyBBTUQuIFJlZ2lzdGVyIGFzIGFuIGFub255bW91cyBtb2R1bGUuXG4gICAgICAgIGRlZmluZShmYWN0b3J5KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAvLyBOb2RlLiBEb2VzIG5vdCB3b3JrIHdpdGggc3RyaWN0IENvbW1vbkpTLCBidXRcbiAgICAgICAgLy8gb25seSBDb21tb25KUy1saWtlIGVudmlyb21lbnRzIHRoYXQgc3VwcG9ydCBtb2R1bGUuZXhwb3J0cyxcbiAgICAgICAgLy8gbGlrZSBOb2RlLlxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBCcm93c2VyIGdsb2JhbHMgKHJvb3QgaXMgd2luZG93KVxuICAgICAgICByb290LnJldHVybkV4cG9ydHMgPSBmYWN0b3J5KCk7XG4gICAgfVxufSh0aGlzLCBmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogQnJpbmdzIGFuIGVudmlyb25tZW50IGFzIGNsb3NlIHRvIEVDTUFTY3JpcHQgNSBjb21wbGlhbmNlXG4gICAgICogYXMgaXMgcG9zc2libGUgd2l0aCB0aGUgZmFjaWxpdGllcyBvZiBlcnN0d2hpbGUgZW5naW5lcy5cbiAgICAgKlxuICAgICAqIEFubm90YXRlZCBFUzU6IGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8gKHNwZWNpZmljIGxpbmtzIGJlbG93KVxuICAgICAqIEVTNSBTcGVjOiBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvcHVibGljYXRpb25zL2ZpbGVzL0VDTUEtU1QvRWNtYS0yNjIucGRmXG4gICAgICogUmVxdWlyZWQgcmVhZGluZzogaHR0cDovL2phdmFzY3JpcHR3ZWJsb2cud29yZHByZXNzLmNvbS8yMDExLzEyLzA1L2V4dGVuZGluZy1qYXZhc2NyaXB0LW5hdGl2ZXMvXG4gICAgICovXG5cbiAgICAvLyBTaG9ydGN1dCB0byBhbiBvZnRlbiBhY2Nlc3NlZCBwcm9wZXJ0aWVzLCBpbiBvcmRlciB0byBhdm9pZCBtdWx0aXBsZVxuICAgIC8vIGRlcmVmZXJlbmNlIHRoYXQgY29zdHMgdW5pdmVyc2FsbHkuIFRoaXMgYWxzbyBob2xkcyBhIHJlZmVyZW5jZSB0byBrbm93bi1nb29kXG4gICAgLy8gZnVuY3Rpb25zLlxuICAgIHZhciAkQXJyYXkgPSBBcnJheTtcbiAgICB2YXIgQXJyYXlQcm90b3R5cGUgPSAkQXJyYXkucHJvdG90eXBlO1xuICAgIHZhciAkT2JqZWN0ID0gT2JqZWN0O1xuICAgIHZhciBPYmplY3RQcm90b3R5cGUgPSAkT2JqZWN0LnByb3RvdHlwZTtcbiAgICB2YXIgJEZ1bmN0aW9uID0gRnVuY3Rpb247XG4gICAgdmFyIEZ1bmN0aW9uUHJvdG90eXBlID0gJEZ1bmN0aW9uLnByb3RvdHlwZTtcbiAgICB2YXIgJFN0cmluZyA9IFN0cmluZztcbiAgICB2YXIgU3RyaW5nUHJvdG90eXBlID0gJFN0cmluZy5wcm90b3R5cGU7XG4gICAgdmFyICROdW1iZXIgPSBOdW1iZXI7XG4gICAgdmFyIE51bWJlclByb3RvdHlwZSA9ICROdW1iZXIucHJvdG90eXBlO1xuICAgIHZhciBhcnJheV9zbGljZSA9IEFycmF5UHJvdG90eXBlLnNsaWNlO1xuICAgIHZhciBhcnJheV9zcGxpY2UgPSBBcnJheVByb3RvdHlwZS5zcGxpY2U7XG4gICAgdmFyIGFycmF5X3B1c2ggPSBBcnJheVByb3RvdHlwZS5wdXNoO1xuICAgIHZhciBhcnJheV91bnNoaWZ0ID0gQXJyYXlQcm90b3R5cGUudW5zaGlmdDtcbiAgICB2YXIgYXJyYXlfY29uY2F0ID0gQXJyYXlQcm90b3R5cGUuY29uY2F0O1xuICAgIHZhciBhcnJheV9qb2luID0gQXJyYXlQcm90b3R5cGUuam9pbjtcbiAgICB2YXIgY2FsbCA9IEZ1bmN0aW9uUHJvdG90eXBlLmNhbGw7XG4gICAgdmFyIGFwcGx5ID0gRnVuY3Rpb25Qcm90b3R5cGUuYXBwbHk7XG4gICAgdmFyIG1heCA9IE1hdGgubWF4O1xuICAgIHZhciBtaW4gPSBNYXRoLm1pbjtcblxuICAgIC8vIEhhdmluZyBhIHRvU3RyaW5nIGxvY2FsIHZhcmlhYmxlIG5hbWUgYnJlYWtzIGluIE9wZXJhIHNvIHVzZSB0b19zdHJpbmcuXG4gICAgdmFyIHRvX3N0cmluZyA9IE9iamVjdFByb3RvdHlwZS50b1N0cmluZztcblxuICAgIC8qIGdsb2JhbCBTeW1ib2wgKi9cbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBvbmUtdmFyLWRlY2xhcmF0aW9uLXBlci1saW5lLCBuby1yZWRlY2xhcmUsIG1heC1zdGF0ZW1lbnRzLXBlci1saW5lICovXG4gICAgdmFyIGhhc1RvU3RyaW5nVGFnID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgU3ltYm9sLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJztcbiAgICB2YXIgaXNDYWxsYWJsZTsgLyogaW5saW5lZCBmcm9tIGh0dHBzOi8vbnBtanMuY29tL2lzLWNhbGxhYmxlICovIHZhciBmblRvU3RyID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nLCBjb25zdHJ1Y3RvclJlZ2V4ID0gL15cXHMqY2xhc3MgLywgaXNFUzZDbGFzc0ZuID0gZnVuY3Rpb24gaXNFUzZDbGFzc0ZuKHZhbHVlKSB7IHRyeSB7IHZhciBmblN0ciA9IGZuVG9TdHIuY2FsbCh2YWx1ZSk7IHZhciBzaW5nbGVTdHJpcHBlZCA9IGZuU3RyLnJlcGxhY2UoL1xcL1xcLy4qXFxuL2csICcnKTsgdmFyIG11bHRpU3RyaXBwZWQgPSBzaW5nbGVTdHJpcHBlZC5yZXBsYWNlKC9cXC9cXCpbLlxcc1xcU10qXFwqXFwvL2csICcnKTsgdmFyIHNwYWNlU3RyaXBwZWQgPSBtdWx0aVN0cmlwcGVkLnJlcGxhY2UoL1xcbi9tZywgJyAnKS5yZXBsYWNlKC8gezJ9L2csICcgJyk7IHJldHVybiBjb25zdHJ1Y3RvclJlZ2V4LnRlc3Qoc3BhY2VTdHJpcHBlZCk7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyAvKiBub3QgYSBmdW5jdGlvbiAqLyB9IH0sIHRyeUZ1bmN0aW9uT2JqZWN0ID0gZnVuY3Rpb24gdHJ5RnVuY3Rpb25PYmplY3QodmFsdWUpIHsgdHJ5IHsgaWYgKGlzRVM2Q2xhc3NGbih2YWx1ZSkpIHsgcmV0dXJuIGZhbHNlOyB9IGZuVG9TdHIuY2FsbCh2YWx1ZSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9LCBmbkNsYXNzID0gJ1tvYmplY3QgRnVuY3Rpb25dJywgZ2VuQ2xhc3MgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLCBpc0NhbGxhYmxlID0gZnVuY3Rpb24gaXNDYWxsYWJsZSh2YWx1ZSkgeyBpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfSBpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9IGlmIChoYXNUb1N0cmluZ1RhZykgeyByZXR1cm4gdHJ5RnVuY3Rpb25PYmplY3QodmFsdWUpOyB9IGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfSB2YXIgc3RyQ2xhc3MgPSB0b19zdHJpbmcuY2FsbCh2YWx1ZSk7IHJldHVybiBzdHJDbGFzcyA9PT0gZm5DbGFzcyB8fCBzdHJDbGFzcyA9PT0gZ2VuQ2xhc3M7IH07XG5cbiAgICB2YXIgaXNSZWdleDsgLyogaW5saW5lZCBmcm9tIGh0dHBzOi8vbnBtanMuY29tL2lzLXJlZ2V4ICovIHZhciByZWdleEV4ZWMgPSBSZWdFeHAucHJvdG90eXBlLmV4ZWMsIHRyeVJlZ2V4RXhlYyA9IGZ1bmN0aW9uIHRyeVJlZ2V4RXhlYyh2YWx1ZSkgeyB0cnkgeyByZWdleEV4ZWMuY2FsbCh2YWx1ZSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9LCByZWdleENsYXNzID0gJ1tvYmplY3QgUmVnRXhwXSc7IGlzUmVnZXggPSBmdW5jdGlvbiBpc1JlZ2V4KHZhbHVlKSB7IGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfSByZXR1cm4gaGFzVG9TdHJpbmdUYWcgPyB0cnlSZWdleEV4ZWModmFsdWUpIDogdG9fc3RyaW5nLmNhbGwodmFsdWUpID09PSByZWdleENsYXNzOyB9O1xuICAgIHZhciBpc1N0cmluZzsgLyogaW5saW5lZCBmcm9tIGh0dHBzOi8vbnBtanMuY29tL2lzLXN0cmluZyAqLyB2YXIgc3RyVmFsdWUgPSBTdHJpbmcucHJvdG90eXBlLnZhbHVlT2YsIHRyeVN0cmluZ09iamVjdCA9IGZ1bmN0aW9uIHRyeVN0cmluZ09iamVjdCh2YWx1ZSkgeyB0cnkgeyBzdHJWYWx1ZS5jYWxsKHZhbHVlKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH0sIHN0cmluZ0NsYXNzID0gJ1tvYmplY3QgU3RyaW5nXSc7IGlzU3RyaW5nID0gZnVuY3Rpb24gaXNTdHJpbmcodmFsdWUpIHsgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHsgcmV0dXJuIHRydWU7IH0gaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHsgcmV0dXJuIGZhbHNlOyB9IHJldHVybiBoYXNUb1N0cmluZ1RhZyA/IHRyeVN0cmluZ09iamVjdCh2YWx1ZSkgOiB0b19zdHJpbmcuY2FsbCh2YWx1ZSkgPT09IHN0cmluZ0NsYXNzOyB9O1xuICAgIC8qIGVzbGludC1lbmFibGUgb25lLXZhci1kZWNsYXJhdGlvbi1wZXItbGluZSwgbm8tcmVkZWNsYXJlLCBtYXgtc3RhdGVtZW50cy1wZXItbGluZSAqL1xuXG4gICAgLyogaW5saW5lZCBmcm9tIGh0dHA6Ly9ucG1qcy5jb20vZGVmaW5lLXByb3BlcnRpZXMgKi9cbiAgICB2YXIgc3VwcG9ydHNEZXNjcmlwdG9ycyA9ICRPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhciBvYmogPSB7fTtcbiAgICAgICAgICAgICRPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCAneCcsIHsgZW51bWVyYWJsZTogZmFsc2UsIHZhbHVlOiBvYmogfSk7XG4gICAgICAgICAgICBmb3IgKHZhciBfIGluIG9iaikgeyAvLyBqc2NzOmlnbm9yZSBkaXNhbGxvd1VudXNlZFZhcmlhYmxlc1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvYmoueCA9PT0gb2JqO1xuICAgICAgICB9IGNhdGNoIChlKSB7IC8qIHRoaXMgaXMgRVMzICovXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9KCkpO1xuICAgIHZhciBkZWZpbmVQcm9wZXJ0aWVzID0gKGZ1bmN0aW9uIChoYXMpIHtcbiAgICAgICAgLy8gRGVmaW5lIGNvbmZpZ3VyYWJsZSwgd3JpdGFibGUsIGFuZCBub24tZW51bWVyYWJsZSBwcm9wc1xuICAgICAgICAvLyBpZiB0aGV5IGRvbid0IGV4aXN0LlxuICAgICAgICB2YXIgZGVmaW5lUHJvcGVydHk7XG4gICAgICAgIGlmIChzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG4gICAgICAgICAgICBkZWZpbmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIG1ldGhvZCwgZm9yY2VBc3NpZ24pIHtcbiAgICAgICAgICAgICAgICBpZiAoIWZvcmNlQXNzaWduICYmIChuYW1lIGluIG9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAkT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iamVjdCwgbmFtZSwge1xuICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IG1ldGhvZFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgbWV0aG9kLCBmb3JjZUFzc2lnbikge1xuICAgICAgICAgICAgICAgIGlmICghZm9yY2VBc3NpZ24gJiYgKG5hbWUgaW4gb2JqZWN0KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9iamVjdFtuYW1lXSA9IG1ldGhvZDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMob2JqZWN0LCBtYXAsIGZvcmNlQXNzaWduKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBuYW1lIGluIG1hcCkge1xuICAgICAgICAgICAgICAgIGlmIChoYXMuY2FsbChtYXAsIG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmluZVByb3BlcnR5KG9iamVjdCwgbmFtZSwgbWFwW25hbWVdLCBmb3JjZUFzc2lnbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0oT2JqZWN0UHJvdG90eXBlLmhhc093blByb3BlcnR5KSk7XG5cbiAgICAvL1xuICAgIC8vIFV0aWxcbiAgICAvLyA9PT09PT1cbiAgICAvL1xuXG4gICAgLyogcmVwbGFjZWFibGUgd2l0aCBodHRwczovL25wbWpzLmNvbS9wYWNrYWdlL2VzLWFic3RyYWN0IC9oZWxwZXJzL2lzUHJpbWl0aXZlICovXG4gICAgdmFyIGlzUHJpbWl0aXZlID0gZnVuY3Rpb24gaXNQcmltaXRpdmUoaW5wdXQpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgaW5wdXQ7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PT0gbnVsbCB8fCAodHlwZSAhPT0gJ29iamVjdCcgJiYgdHlwZSAhPT0gJ2Z1bmN0aW9uJyk7XG4gICAgfTtcblxuICAgIHZhciBpc0FjdHVhbE5hTiA9ICROdW1iZXIuaXNOYU4gfHwgZnVuY3Rpb24gaXNBY3R1YWxOYU4oeCkge1xuICAgICAgICByZXR1cm4geCAhPT0geDtcbiAgICB9O1xuXG4gICAgdmFyIEVTID0ge1xuICAgICAgICAvLyBFUzUgOS40XG4gICAgICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDkuNFxuICAgICAgICAvLyBodHRwOi8vanNwZXJmLmNvbS90by1pbnRlZ2VyXG4gICAgICAgIC8qIHJlcGxhY2VhYmxlIHdpdGggaHR0cHM6Ly9ucG1qcy5jb20vcGFja2FnZS9lcy1hYnN0cmFjdCBFUzUuVG9JbnRlZ2VyICovXG4gICAgICAgIFRvSW50ZWdlcjogZnVuY3Rpb24gVG9JbnRlZ2VyKG51bSkge1xuICAgICAgICAgICAgdmFyIG4gPSArbnVtO1xuICAgICAgICAgICAgaWYgKGlzQWN0dWFsTmFOKG4pKSB7XG4gICAgICAgICAgICAgICAgbiA9IDA7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG4gIT09IDAgJiYgbiAhPT0gKDEgLyAwKSAmJiBuICE9PSAtKDEgLyAwKSkge1xuICAgICAgICAgICAgICAgIG4gPSAobiA+IDAgfHwgLTEpICogTWF0aC5mbG9vcihNYXRoLmFicyhuKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbjtcbiAgICAgICAgfSxcblxuICAgICAgICAvKiByZXBsYWNlYWJsZSB3aXRoIGh0dHBzOi8vbnBtanMuY29tL3BhY2thZ2UvZXMtYWJzdHJhY3QgRVM1LlRvUHJpbWl0aXZlICovXG4gICAgICAgIFRvUHJpbWl0aXZlOiBmdW5jdGlvbiBUb1ByaW1pdGl2ZShpbnB1dCkge1xuICAgICAgICAgICAgdmFyIHZhbCwgdmFsdWVPZiwgdG9TdHI7XG4gICAgICAgICAgICBpZiAoaXNQcmltaXRpdmUoaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFsdWVPZiA9IGlucHV0LnZhbHVlT2Y7XG4gICAgICAgICAgICBpZiAoaXNDYWxsYWJsZSh2YWx1ZU9mKSkge1xuICAgICAgICAgICAgICAgIHZhbCA9IHZhbHVlT2YuY2FsbChpbnB1dCk7XG4gICAgICAgICAgICAgICAgaWYgKGlzUHJpbWl0aXZlKHZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b1N0ciA9IGlucHV0LnRvU3RyaW5nO1xuICAgICAgICAgICAgaWYgKGlzQ2FsbGFibGUodG9TdHIpKSB7XG4gICAgICAgICAgICAgICAgdmFsID0gdG9TdHIuY2FsbChpbnB1dCk7XG4gICAgICAgICAgICAgICAgaWYgKGlzUHJpbWl0aXZlKHZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gRVM1IDkuOVxuICAgICAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3g5LjlcbiAgICAgICAgLyogcmVwbGFjZWFibGUgd2l0aCBodHRwczovL25wbWpzLmNvbS9wYWNrYWdlL2VzLWFic3RyYWN0IEVTNS5Ub09iamVjdCAqL1xuICAgICAgICBUb09iamVjdDogZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgICAgIGlmIChvID09IG51bGwpIHsgLy8gdGhpcyBtYXRjaGVzIGJvdGggbnVsbCBhbmQgdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNhbid0IGNvbnZlcnQgXCIgKyBvICsgJyB0byBvYmplY3QnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAkT2JqZWN0KG8pO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qIHJlcGxhY2VhYmxlIHdpdGggaHR0cHM6Ly9ucG1qcy5jb20vcGFja2FnZS9lcy1hYnN0cmFjdCBFUzUuVG9VaW50MzIgKi9cbiAgICAgICAgVG9VaW50MzI6IGZ1bmN0aW9uIFRvVWludDMyKHgpIHtcbiAgICAgICAgICAgIHJldHVybiB4ID4+PiAwO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8vXG4gICAgLy8gRnVuY3Rpb25cbiAgICAvLyA9PT09PT09PVxuICAgIC8vXG5cbiAgICAvLyBFUy01IDE1LjMuNC41XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuMy40LjVcblxuICAgIHZhciBFbXB0eSA9IGZ1bmN0aW9uIEVtcHR5KCkge307XG5cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEZ1bmN0aW9uUHJvdG90eXBlLCB7XG4gICAgICAgIGJpbmQ6IGZ1bmN0aW9uIGJpbmQodGhhdCkgeyAvLyAubGVuZ3RoIGlzIDFcbiAgICAgICAgICAgIC8vIDEuIExldCBUYXJnZXQgYmUgdGhlIHRoaXMgdmFsdWUuXG4gICAgICAgICAgICB2YXIgdGFyZ2V0ID0gdGhpcztcbiAgICAgICAgICAgIC8vIDIuIElmIElzQ2FsbGFibGUoVGFyZ2V0KSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKHRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBjYWxsZWQgb24gaW5jb21wYXRpYmxlICcgKyB0YXJnZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gMy4gTGV0IEEgYmUgYSBuZXcgKHBvc3NpYmx5IGVtcHR5KSBpbnRlcm5hbCBsaXN0IG9mIGFsbCBvZiB0aGVcbiAgICAgICAgICAgIC8vICAgYXJndW1lbnQgdmFsdWVzIHByb3ZpZGVkIGFmdGVyIHRoaXNBcmcgKGFyZzEsIGFyZzIgZXRjKSwgaW4gb3JkZXIuXG4gICAgICAgICAgICAvLyBYWFggc2xpY2VkQXJncyB3aWxsIHN0YW5kIGluIGZvciBcIkFcIiBpZiB1c2VkXG4gICAgICAgICAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTsgLy8gZm9yIG5vcm1hbCBjYWxsXG4gICAgICAgICAgICAvLyA0LiBMZXQgRiBiZSBhIG5ldyBuYXRpdmUgRUNNQVNjcmlwdCBvYmplY3QuXG4gICAgICAgICAgICAvLyAxMS4gU2V0IHRoZSBbW1Byb3RvdHlwZV1dIGludGVybmFsIHByb3BlcnR5IG9mIEYgdG8gdGhlIHN0YW5kYXJkXG4gICAgICAgICAgICAvLyAgIGJ1aWx0LWluIEZ1bmN0aW9uIHByb3RvdHlwZSBvYmplY3QgYXMgc3BlY2lmaWVkIGluIDE1LjMuMy4xLlxuICAgICAgICAgICAgLy8gMTIuIFNldCB0aGUgW1tDYWxsXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgRiBhcyBkZXNjcmliZWQgaW5cbiAgICAgICAgICAgIC8vICAgMTUuMy40LjUuMS5cbiAgICAgICAgICAgIC8vIDEzLiBTZXQgdGhlIFtbQ29uc3RydWN0XV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgRiBhcyBkZXNjcmliZWQgaW5cbiAgICAgICAgICAgIC8vICAgMTUuMy40LjUuMi5cbiAgICAgICAgICAgIC8vIDE0LiBTZXQgdGhlIFtbSGFzSW5zdGFuY2VdXSBpbnRlcm5hbCBwcm9wZXJ0eSBvZiBGIGFzIGRlc2NyaWJlZCBpblxuICAgICAgICAgICAgLy8gICAxNS4zLjQuNS4zLlxuICAgICAgICAgICAgdmFyIGJvdW5kO1xuICAgICAgICAgICAgdmFyIGJpbmRlciA9IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgYm91bmQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gMTUuMy40LjUuMiBbW0NvbnN0cnVjdF1dXG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gdGhlIFtbQ29uc3RydWN0XV0gaW50ZXJuYWwgbWV0aG9kIG9mIGEgZnVuY3Rpb24gb2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICAvLyBGIHRoYXQgd2FzIGNyZWF0ZWQgdXNpbmcgdGhlIGJpbmQgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggYVxuICAgICAgICAgICAgICAgICAgICAvLyBsaXN0IG9mIGFyZ3VtZW50cyBFeHRyYUFyZ3MsIHRoZSBmb2xsb3dpbmcgc3RlcHMgYXJlIHRha2VuOlxuICAgICAgICAgICAgICAgICAgICAvLyAxLiBMZXQgdGFyZ2V0IGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tUYXJnZXRGdW5jdGlvbl1dXG4gICAgICAgICAgICAgICAgICAgIC8vICAgaW50ZXJuYWwgcHJvcGVydHkuXG4gICAgICAgICAgICAgICAgICAgIC8vIDIuIElmIHRhcmdldCBoYXMgbm8gW1tDb25zdHJ1Y3RdXSBpbnRlcm5hbCBtZXRob2QsIGFcbiAgICAgICAgICAgICAgICAgICAgLy8gICBUeXBlRXJyb3IgZXhjZXB0aW9uIGlzIHRocm93bi5cbiAgICAgICAgICAgICAgICAgICAgLy8gMy4gTGV0IGJvdW5kQXJncyBiZSB0aGUgdmFsdWUgb2YgRidzIFtbQm91bmRBcmdzXV0gaW50ZXJuYWxcbiAgICAgICAgICAgICAgICAgICAgLy8gICBwcm9wZXJ0eS5cbiAgICAgICAgICAgICAgICAgICAgLy8gNC4gTGV0IGFyZ3MgYmUgYSBuZXcgbGlzdCBjb250YWluaW5nIHRoZSBzYW1lIHZhbHVlcyBhcyB0aGVcbiAgICAgICAgICAgICAgICAgICAgLy8gICBsaXN0IGJvdW5kQXJncyBpbiB0aGUgc2FtZSBvcmRlciBmb2xsb3dlZCBieSB0aGUgc2FtZVxuICAgICAgICAgICAgICAgICAgICAvLyAgIHZhbHVlcyBhcyB0aGUgbGlzdCBFeHRyYUFyZ3MgaW4gdGhlIHNhbWUgb3JkZXIuXG4gICAgICAgICAgICAgICAgICAgIC8vIDUuIFJldHVybiB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgdGhlIFtbQ29uc3RydWN0XV0gaW50ZXJuYWxcbiAgICAgICAgICAgICAgICAgICAgLy8gICBtZXRob2Qgb2YgdGFyZ2V0IHByb3ZpZGluZyBhcmdzIGFzIHRoZSBhcmd1bWVudHMuXG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGFwcGx5LmNhbGwoXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlfY29uY2F0LmNhbGwoYXJncywgYXJyYXlfc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBpZiAoJE9iamVjdChyZXN1bHQpID09PSByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyAxNS4zLjQuNS4xIFtbQ2FsbF1dXG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gdGhlIFtbQ2FsbF1dIGludGVybmFsIG1ldGhvZCBvZiBhIGZ1bmN0aW9uIG9iamVjdCwgRixcbiAgICAgICAgICAgICAgICAgICAgLy8gd2hpY2ggd2FzIGNyZWF0ZWQgdXNpbmcgdGhlIGJpbmQgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggYVxuICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHZhbHVlIGFuZCBhIGxpc3Qgb2YgYXJndW1lbnRzIEV4dHJhQXJncywgdGhlIGZvbGxvd2luZ1xuICAgICAgICAgICAgICAgICAgICAvLyBzdGVwcyBhcmUgdGFrZW46XG4gICAgICAgICAgICAgICAgICAgIC8vIDEuIExldCBib3VuZEFyZ3MgYmUgdGhlIHZhbHVlIG9mIEYncyBbW0JvdW5kQXJnc11dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgcHJvcGVydHkuXG4gICAgICAgICAgICAgICAgICAgIC8vIDIuIExldCBib3VuZFRoaXMgYmUgdGhlIHZhbHVlIG9mIEYncyBbW0JvdW5kVGhpc11dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgcHJvcGVydHkuXG4gICAgICAgICAgICAgICAgICAgIC8vIDMuIExldCB0YXJnZXQgYmUgdGhlIHZhbHVlIG9mIEYncyBbW1RhcmdldEZ1bmN0aW9uXV0gaW50ZXJuYWxcbiAgICAgICAgICAgICAgICAgICAgLy8gICBwcm9wZXJ0eS5cbiAgICAgICAgICAgICAgICAgICAgLy8gNC4gTGV0IGFyZ3MgYmUgYSBuZXcgbGlzdCBjb250YWluaW5nIHRoZSBzYW1lIHZhbHVlcyBhcyB0aGVcbiAgICAgICAgICAgICAgICAgICAgLy8gICBsaXN0IGJvdW5kQXJncyBpbiB0aGUgc2FtZSBvcmRlciBmb2xsb3dlZCBieSB0aGUgc2FtZVxuICAgICAgICAgICAgICAgICAgICAvLyAgIHZhbHVlcyBhcyB0aGUgbGlzdCBFeHRyYUFyZ3MgaW4gdGhlIHNhbWUgb3JkZXIuXG4gICAgICAgICAgICAgICAgICAgIC8vIDUuIFJldHVybiB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgdGhlIFtbQ2FsbF1dIGludGVybmFsIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICAvLyAgIG9mIHRhcmdldCBwcm92aWRpbmcgYm91bmRUaGlzIGFzIHRoZSB0aGlzIHZhbHVlIGFuZFxuICAgICAgICAgICAgICAgICAgICAvLyAgIHByb3ZpZGluZyBhcmdzIGFzIHRoZSBhcmd1bWVudHMuXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gZXF1aXY6IHRhcmdldC5jYWxsKHRoaXMsIC4uLmJvdW5kQXJncywgLi4uYXJncylcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFwcGx5LmNhbGwoXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0LFxuICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlfY29uY2F0LmNhbGwoYXJncywgYXJyYXlfc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyAxNS4gSWYgdGhlIFtbQ2xhc3NdXSBpbnRlcm5hbCBwcm9wZXJ0eSBvZiBUYXJnZXQgaXMgXCJGdW5jdGlvblwiLCB0aGVuXG4gICAgICAgICAgICAvLyAgICAgYS4gTGV0IEwgYmUgdGhlIGxlbmd0aCBwcm9wZXJ0eSBvZiBUYXJnZXQgbWludXMgdGhlIGxlbmd0aCBvZiBBLlxuICAgICAgICAgICAgLy8gICAgIGIuIFNldCB0aGUgbGVuZ3RoIG93biBwcm9wZXJ0eSBvZiBGIHRvIGVpdGhlciAwIG9yIEwsIHdoaWNoZXZlciBpc1xuICAgICAgICAgICAgLy8gICAgICAgbGFyZ2VyLlxuICAgICAgICAgICAgLy8gMTYuIEVsc2Ugc2V0IHRoZSBsZW5ndGggb3duIHByb3BlcnR5IG9mIEYgdG8gMC5cblxuICAgICAgICAgICAgdmFyIGJvdW5kTGVuZ3RoID0gbWF4KDAsIHRhcmdldC5sZW5ndGggLSBhcmdzLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIC8vIDE3LiBTZXQgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGxlbmd0aCBvd24gcHJvcGVydHkgb2YgRiB0byB0aGUgdmFsdWVzXG4gICAgICAgICAgICAvLyAgIHNwZWNpZmllZCBpbiAxNS4zLjUuMS5cbiAgICAgICAgICAgIHZhciBib3VuZEFyZ3MgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYm91bmRMZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGFycmF5X3B1c2guY2FsbChib3VuZEFyZ3MsICckJyArIGkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBYWFggQnVpbGQgYSBkeW5hbWljIGZ1bmN0aW9uIHdpdGggZGVzaXJlZCBhbW91bnQgb2YgYXJndW1lbnRzIGlzIHRoZSBvbmx5XG4gICAgICAgICAgICAvLyB3YXkgdG8gc2V0IHRoZSBsZW5ndGggcHJvcGVydHkgb2YgYSBmdW5jdGlvbi5cbiAgICAgICAgICAgIC8vIEluIGVudmlyb25tZW50cyB3aGVyZSBDb250ZW50IFNlY3VyaXR5IFBvbGljaWVzIGVuYWJsZWQgKENocm9tZSBleHRlbnNpb25zLFxuICAgICAgICAgICAgLy8gZm9yIGV4LikgYWxsIHVzZSBvZiBldmFsIG9yIEZ1bmN0aW9uIGNvc3RydWN0b3IgdGhyb3dzIGFuIGV4Y2VwdGlvbi5cbiAgICAgICAgICAgIC8vIEhvd2V2ZXIgaW4gYWxsIG9mIHRoZXNlIGVudmlyb25tZW50cyBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBleGlzdHNcbiAgICAgICAgICAgIC8vIGFuZCBzbyB0aGlzIGNvZGUgd2lsbCBuZXZlciBiZSBleGVjdXRlZC5cbiAgICAgICAgICAgIGJvdW5kID0gJEZ1bmN0aW9uKCdiaW5kZXInLCAncmV0dXJuIGZ1bmN0aW9uICgnICsgYXJyYXlfam9pbi5jYWxsKGJvdW5kQXJncywgJywnKSArICcpeyByZXR1cm4gYmluZGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0nKShiaW5kZXIpO1xuXG4gICAgICAgICAgICBpZiAodGFyZ2V0LnByb3RvdHlwZSkge1xuICAgICAgICAgICAgICAgIEVtcHR5LnByb3RvdHlwZSA9IHRhcmdldC5wcm90b3R5cGU7XG4gICAgICAgICAgICAgICAgYm91bmQucHJvdG90eXBlID0gbmV3IEVtcHR5KCk7XG4gICAgICAgICAgICAgICAgLy8gQ2xlYW4gdXAgZGFuZ2xpbmcgcmVmZXJlbmNlcy5cbiAgICAgICAgICAgICAgICBFbXB0eS5wcm90b3R5cGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBUT0RPXG4gICAgICAgICAgICAvLyAxOC4gU2V0IHRoZSBbW0V4dGVuc2libGVdXSBpbnRlcm5hbCBwcm9wZXJ0eSBvZiBGIHRvIHRydWUuXG5cbiAgICAgICAgICAgIC8vIFRPRE9cbiAgICAgICAgICAgIC8vIDE5LiBMZXQgdGhyb3dlciBiZSB0aGUgW1tUaHJvd1R5cGVFcnJvcl1dIGZ1bmN0aW9uIE9iamVjdCAoMTMuMi4zKS5cbiAgICAgICAgICAgIC8vIDIwLiBDYWxsIHRoZSBbW0RlZmluZU93blByb3BlcnR5XV0gaW50ZXJuYWwgbWV0aG9kIG9mIEYgd2l0aFxuICAgICAgICAgICAgLy8gICBhcmd1bWVudHMgXCJjYWxsZXJcIiwgUHJvcGVydHlEZXNjcmlwdG9yIHtbW0dldF1dOiB0aHJvd2VyLCBbW1NldF1dOlxuICAgICAgICAgICAgLy8gICB0aHJvd2VyLCBbW0VudW1lcmFibGVdXTogZmFsc2UsIFtbQ29uZmlndXJhYmxlXV06IGZhbHNlfSwgYW5kXG4gICAgICAgICAgICAvLyAgIGZhbHNlLlxuICAgICAgICAgICAgLy8gMjEuIENhbGwgdGhlIFtbRGVmaW5lT3duUHJvcGVydHldXSBpbnRlcm5hbCBtZXRob2Qgb2YgRiB3aXRoXG4gICAgICAgICAgICAvLyAgIGFyZ3VtZW50cyBcImFyZ3VtZW50c1wiLCBQcm9wZXJ0eURlc2NyaXB0b3Ige1tbR2V0XV06IHRocm93ZXIsXG4gICAgICAgICAgICAvLyAgIFtbU2V0XV06IHRocm93ZXIsIFtbRW51bWVyYWJsZV1dOiBmYWxzZSwgW1tDb25maWd1cmFibGVdXTogZmFsc2V9LFxuICAgICAgICAgICAgLy8gICBhbmQgZmFsc2UuXG5cbiAgICAgICAgICAgIC8vIFRPRE9cbiAgICAgICAgICAgIC8vIE5PVEUgRnVuY3Rpb24gb2JqZWN0cyBjcmVhdGVkIHVzaW5nIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIGRvIG5vdFxuICAgICAgICAgICAgLy8gaGF2ZSBhIHByb3RvdHlwZSBwcm9wZXJ0eSBvciB0aGUgW1tDb2RlXV0sIFtbRm9ybWFsUGFyYW1ldGVyc11dLCBhbmRcbiAgICAgICAgICAgIC8vIFtbU2NvcGVdXSBpbnRlcm5hbCBwcm9wZXJ0aWVzLlxuICAgICAgICAgICAgLy8gWFhYIGNhbid0IGRlbGV0ZSBwcm90b3R5cGUgaW4gcHVyZS1qcy5cblxuICAgICAgICAgICAgLy8gMjIuIFJldHVybiBGLlxuICAgICAgICAgICAgcmV0dXJuIGJvdW5kO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBfUGxlYXNlIG5vdGU6IFNob3J0Y3V0cyBhcmUgZGVmaW5lZCBhZnRlciBgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmRgIGFzIHdlXG4gICAgLy8gdXNlIGl0IGluIGRlZmluaW5nIHNob3J0Y3V0cy5cbiAgICB2YXIgb3ducyA9IGNhbGwuYmluZChPYmplY3RQcm90b3R5cGUuaGFzT3duUHJvcGVydHkpO1xuICAgIHZhciB0b1N0ciA9IGNhbGwuYmluZChPYmplY3RQcm90b3R5cGUudG9TdHJpbmcpO1xuICAgIHZhciBhcnJheVNsaWNlID0gY2FsbC5iaW5kKGFycmF5X3NsaWNlKTtcbiAgICB2YXIgYXJyYXlTbGljZUFwcGx5ID0gYXBwbHkuYmluZChhcnJheV9zbGljZSk7XG4gICAgdmFyIHN0clNsaWNlID0gY2FsbC5iaW5kKFN0cmluZ1Byb3RvdHlwZS5zbGljZSk7XG4gICAgdmFyIHN0clNwbGl0ID0gY2FsbC5iaW5kKFN0cmluZ1Byb3RvdHlwZS5zcGxpdCk7XG4gICAgdmFyIHN0ckluZGV4T2YgPSBjYWxsLmJpbmQoU3RyaW5nUHJvdG90eXBlLmluZGV4T2YpO1xuICAgIHZhciBwdXNoQ2FsbCA9IGNhbGwuYmluZChhcnJheV9wdXNoKTtcbiAgICB2YXIgaXNFbnVtID0gY2FsbC5iaW5kKE9iamVjdFByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZSk7XG4gICAgdmFyIGFycmF5U29ydCA9IGNhbGwuYmluZChBcnJheVByb3RvdHlwZS5zb3J0KTtcblxuICAgIC8vXG4gICAgLy8gQXJyYXlcbiAgICAvLyA9PT09PVxuICAgIC8vXG5cbiAgICB2YXIgaXNBcnJheSA9ICRBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7XG4gICAgICAgIHJldHVybiB0b1N0cihvYmopID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH07XG5cbiAgICAvLyBFUzUgMTUuNC40LjEyXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjEzXG4gICAgLy8gUmV0dXJuIGxlbithcmdDb3VudC5cbiAgICAvLyBbYnVnZml4LCBpZWx0OF1cbiAgICAvLyBJRSA8IDggYnVnOiBbXS51bnNoaWZ0KDApID09PSB1bmRlZmluZWQgYnV0IHNob3VsZCBiZSBcIjFcIlxuICAgIHZhciBoYXNVbnNoaWZ0UmV0dXJuVmFsdWVCdWcgPSBbXS51bnNoaWZ0KDApICE9PSAxO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgdW5zaGlmdDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYXJyYXlfdW5zaGlmdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgfSwgaGFzVW5zaGlmdFJldHVyblZhbHVlQnVnKTtcblxuICAgIC8vIEVTNSAxNS40LjMuMlxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuMy4yXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvaXNBcnJheVxuICAgIGRlZmluZVByb3BlcnRpZXMoJEFycmF5LCB7IGlzQXJyYXk6IGlzQXJyYXkgfSk7XG5cbiAgICAvLyBUaGUgSXNDYWxsYWJsZSgpIGNoZWNrIGluIHRoZSBBcnJheSBmdW5jdGlvbnNcbiAgICAvLyBoYXMgYmVlbiByZXBsYWNlZCB3aXRoIGEgc3RyaWN0IGNoZWNrIG9uIHRoZVxuICAgIC8vIGludGVybmFsIGNsYXNzIG9mIHRoZSBvYmplY3QgdG8gdHJhcCBjYXNlcyB3aGVyZVxuICAgIC8vIHRoZSBwcm92aWRlZCBmdW5jdGlvbiB3YXMgYWN0dWFsbHkgYSByZWd1bGFyXG4gICAgLy8gZXhwcmVzc2lvbiBsaXRlcmFsLCB3aGljaCBpbiBWOCBhbmRcbiAgICAvLyBKYXZhU2NyaXB0Q29yZSBpcyBhIHR5cGVvZiBcImZ1bmN0aW9uXCIuICBPbmx5IGluXG4gICAgLy8gVjggYXJlIHJlZ3VsYXIgZXhwcmVzc2lvbiBsaXRlcmFscyBwZXJtaXR0ZWQgYXNcbiAgICAvLyByZWR1Y2UgcGFyYW1ldGVycywgc28gaXQgaXMgZGVzaXJhYmxlIGluIHRoZVxuICAgIC8vIGdlbmVyYWwgY2FzZSBmb3IgdGhlIHNoaW0gdG8gbWF0Y2ggdGhlIG1vcmVcbiAgICAvLyBzdHJpY3QgYW5kIGNvbW1vbiBiZWhhdmlvciBvZiByZWplY3RpbmcgcmVndWxhclxuICAgIC8vIGV4cHJlc3Npb25zLlxuXG4gICAgLy8gRVM1IDE1LjQuNC4xOFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xOFxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL2FycmF5L2ZvckVhY2hcblxuICAgIC8vIENoZWNrIGZhaWx1cmUgb2YgYnktaW5kZXggYWNjZXNzIG9mIHN0cmluZyBjaGFyYWN0ZXJzIChJRSA8IDkpXG4gICAgLy8gYW5kIGZhaWx1cmUgb2YgYDAgaW4gYm94ZWRTdHJpbmdgIChSaGlubylcbiAgICB2YXIgYm94ZWRTdHJpbmcgPSAkT2JqZWN0KCdhJyk7XG4gICAgdmFyIHNwbGl0U3RyaW5nID0gYm94ZWRTdHJpbmdbMF0gIT09ICdhJyB8fCAhKDAgaW4gYm94ZWRTdHJpbmcpO1xuXG4gICAgdmFyIHByb3Blcmx5Qm94ZXNDb250ZXh0ID0gZnVuY3Rpb24gcHJvcGVybHlCb3hlZChtZXRob2QpIHtcbiAgICAgICAgLy8gQ2hlY2sgbm9kZSAwLjYuMjEgYnVnIHdoZXJlIHRoaXJkIHBhcmFtZXRlciBpcyBub3QgYm94ZWRcbiAgICAgICAgdmFyIHByb3Blcmx5Qm94ZXNOb25TdHJpY3QgPSB0cnVlO1xuICAgICAgICB2YXIgcHJvcGVybHlCb3hlc1N0cmljdCA9IHRydWU7XG4gICAgICAgIHZhciB0aHJld0V4Y2VwdGlvbiA9IGZhbHNlO1xuICAgICAgICBpZiAobWV0aG9kKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG1ldGhvZC5jYWxsKCdmb28nLCBmdW5jdGlvbiAoXywgX18sIGNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVybHlCb3hlc05vblN0cmljdCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBtZXRob2QuY2FsbChbMV0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgICAgICAgICAgICAgICAgIHByb3Blcmx5Qm94ZXNTdHJpY3QgPSB0eXBlb2YgdGhpcyA9PT0gJ3N0cmluZyc7XG4gICAgICAgICAgICAgICAgfSwgJ3gnKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB0aHJld0V4Y2VwdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICEhbWV0aG9kICYmICF0aHJld0V4Y2VwdGlvbiAmJiBwcm9wZXJseUJveGVzTm9uU3RyaWN0ICYmIHByb3Blcmx5Qm94ZXNTdHJpY3Q7XG4gICAgfTtcblxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgZm9yRWFjaDogZnVuY3Rpb24gZm9yRWFjaChjYWxsYmFja2ZuLyosIHRoaXNBcmcqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBpID0gLTE7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIFQ7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBUID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLmZvckVhY2ggY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHdoaWxlICgrK2kgPCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEludm9rZSB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gd2l0aCBjYWxsLCBwYXNzaW5nIGFyZ3VtZW50czpcbiAgICAgICAgICAgICAgICAgICAgLy8gY29udGV4dCwgcHJvcGVydHkgdmFsdWUsIHByb3BlcnR5IGtleSwgdGhpc0FyZyBvYmplY3RcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBUID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tmbihzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tmbi5jYWxsKFQsIHNlbGZbaV0sIGksIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCAhcHJvcGVybHlCb3hlc0NvbnRleHQoQXJyYXlQcm90b3R5cGUuZm9yRWFjaCkpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xOVxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xOVxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0NvcmVfSmF2YVNjcmlwdF8xLjVfUmVmZXJlbmNlL09iamVjdHMvQXJyYXkvbWFwXG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBtYXA6IGZ1bmN0aW9uIG1hcChjYWxsYmFja2ZuLyosIHRoaXNBcmcqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gJEFycmF5KGxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgVDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIFQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUubWFwIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIFQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBjYWxsYmFja2ZuKHNlbGZbaV0sIGksIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBjYWxsYmFja2ZuLmNhbGwoVCwgc2VsZltpXSwgaSwgb2JqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9LCAhcHJvcGVybHlCb3hlc0NvbnRleHQoQXJyYXlQcm90b3R5cGUubWFwKSk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjIwXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjIwXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vQ29yZV9KYXZhU2NyaXB0XzEuNV9SZWZlcmVuY2UvT2JqZWN0cy9BcnJheS9maWx0ZXJcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKGNhbGxiYWNrZm4vKiwgdGhpc0FyZyovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgIHZhciB2YWx1ZTtcbiAgICAgICAgICAgIHZhciBUO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgVCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5maWx0ZXIgY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gc2VsZltpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBUID09PSAndW5kZWZpbmVkJyA/IGNhbGxiYWNrZm4odmFsdWUsIGksIG9iamVjdCkgOiBjYWxsYmFja2ZuLmNhbGwoVCwgdmFsdWUsIGksIG9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKHJlc3VsdCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgIH0sICFwcm9wZXJseUJveGVzQ29udGV4dChBcnJheVByb3RvdHlwZS5maWx0ZXIpKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTZcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTZcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9ldmVyeVxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgZXZlcnk6IGZ1bmN0aW9uIGV2ZXJ5KGNhbGxiYWNrZm4vKiwgdGhpc0FyZyovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBUO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgVCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5ldmVyeSBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYgJiYgISh0eXBlb2YgVCA9PT0gJ3VuZGVmaW5lZCcgPyBjYWxsYmFja2ZuKHNlbGZbaV0sIGksIG9iamVjdCkgOiBjYWxsYmFja2ZuLmNhbGwoVCwgc2VsZltpXSwgaSwgb2JqZWN0KSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfSwgIXByb3Blcmx5Qm94ZXNDb250ZXh0KEFycmF5UHJvdG90eXBlLmV2ZXJ5KSk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjE3XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjE3XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvc29tZVxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgc29tZTogZnVuY3Rpb24gc29tZShjYWxsYmFja2ZuLyosIHRoaXNBcmcgKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIFQ7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBUID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLnNvbWUgY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmICYmICh0eXBlb2YgVCA9PT0gJ3VuZGVmaW5lZCcgPyBjYWxsYmFja2ZuKHNlbGZbaV0sIGksIG9iamVjdCkgOiBjYWxsYmFja2ZuLmNhbGwoVCwgc2VsZltpXSwgaSwgb2JqZWN0KSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSwgIXByb3Blcmx5Qm94ZXNDb250ZXh0KEFycmF5UHJvdG90eXBlLnNvbWUpKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMjFcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMjFcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9Db3JlX0phdmFTY3JpcHRfMS41X1JlZmVyZW5jZS9PYmplY3RzL0FycmF5L3JlZHVjZVxuICAgIHZhciByZWR1Y2VDb2VyY2VzVG9PYmplY3QgPSBmYWxzZTtcbiAgICBpZiAoQXJyYXlQcm90b3R5cGUucmVkdWNlKSB7XG4gICAgICAgIHJlZHVjZUNvZXJjZXNUb09iamVjdCA9IHR5cGVvZiBBcnJheVByb3RvdHlwZS5yZWR1Y2UuY2FsbCgnZXM1JywgZnVuY3Rpb24gKF8sIF9fLCBfX18sIGxpc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBsaXN0O1xuICAgICAgICB9KSA9PT0gJ29iamVjdCc7XG4gICAgfVxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgcmVkdWNlOiBmdW5jdGlvbiByZWR1Y2UoY2FsbGJhY2tmbi8qLCBpbml0aWFsVmFsdWUqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUucmVkdWNlIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBubyB2YWx1ZSB0byByZXR1cm4gaWYgbm8gaW5pdGlhbCB2YWx1ZSBhbmQgYW4gZW1wdHkgYXJyYXlcbiAgICAgICAgICAgIGlmIChsZW5ndGggPT09IDAgJiYgYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3JlZHVjZSBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gc2VsZltpKytdO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBpZiBhcnJheSBjb250YWlucyBubyB2YWx1ZXMsIG5vIGluaXRpYWwgdmFsdWUgdG8gcmV0dXJuXG4gICAgICAgICAgICAgICAgICAgIGlmICgrK2kgPj0gbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWR1Y2Ugb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IHdoaWxlICh0cnVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yICg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gY2FsbGJhY2tmbihyZXN1bHQsIHNlbGZbaV0sIGksIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfSwgIXJlZHVjZUNvZXJjZXNUb09iamVjdCk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjIyXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjIyXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vQ29yZV9KYXZhU2NyaXB0XzEuNV9SZWZlcmVuY2UvT2JqZWN0cy9BcnJheS9yZWR1Y2VSaWdodFxuICAgIHZhciByZWR1Y2VSaWdodENvZXJjZXNUb09iamVjdCA9IGZhbHNlO1xuICAgIGlmIChBcnJheVByb3RvdHlwZS5yZWR1Y2VSaWdodCkge1xuICAgICAgICByZWR1Y2VSaWdodENvZXJjZXNUb09iamVjdCA9IHR5cGVvZiBBcnJheVByb3RvdHlwZS5yZWR1Y2VSaWdodC5jYWxsKCdlczUnLCBmdW5jdGlvbiAoXywgX18sIF9fXywgbGlzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgICAgIH0pID09PSAnb2JqZWN0JztcbiAgICB9XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICByZWR1Y2VSaWdodDogZnVuY3Rpb24gcmVkdWNlUmlnaHQoY2FsbGJhY2tmbi8qLCBpbml0aWFsKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLnJlZHVjZVJpZ2h0IGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBubyB2YWx1ZSB0byByZXR1cm4gaWYgbm8gaW5pdGlhbCB2YWx1ZSwgZW1wdHkgYXJyYXlcbiAgICAgICAgICAgIGlmIChsZW5ndGggPT09IDAgJiYgYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3JlZHVjZVJpZ2h0IG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZScpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuICAgICAgICAgICAgdmFyIGkgPSBsZW5ndGggLSAxO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBzZWxmW2ktLV07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIGFycmF5IGNvbnRhaW5zIG5vIHZhbHVlcywgbm8gaW5pdGlhbCB2YWx1ZSB0byByZXR1cm5cbiAgICAgICAgICAgICAgICAgICAgaWYgKC0taSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3JlZHVjZVJpZ2h0IG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSB3aGlsZSAodHJ1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpIDwgMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNhbGxiYWNrZm4ocmVzdWx0LCBzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gd2hpbGUgKGktLSk7XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9LCAhcmVkdWNlUmlnaHRDb2VyY2VzVG9PYmplY3QpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xNFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xNFxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2luZGV4T2ZcbiAgICB2YXIgaGFzRmlyZWZveDJJbmRleE9mQnVnID0gQXJyYXlQcm90b3R5cGUuaW5kZXhPZiAmJiBbMCwgMV0uaW5kZXhPZigxLCAyKSAhPT0gLTE7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBpbmRleE9mOiBmdW5jdGlvbiBpbmRleE9mKHNlYXJjaEVsZW1lbnQvKiwgZnJvbUluZGV4ICovKSB7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuXG4gICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBpID0gRVMuVG9JbnRlZ2VyKGFyZ3VtZW50c1sxXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGhhbmRsZSBuZWdhdGl2ZSBpbmRpY2VzXG4gICAgICAgICAgICBpID0gaSA+PSAwID8gaSA6IG1heCgwLCBsZW5ndGggKyBpKTtcbiAgICAgICAgICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmICYmIHNlbGZbaV0gPT09IHNlYXJjaEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgfSwgaGFzRmlyZWZveDJJbmRleE9mQnVnKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTVcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTVcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9sYXN0SW5kZXhPZlxuICAgIHZhciBoYXNGaXJlZm94Mkxhc3RJbmRleE9mQnVnID0gQXJyYXlQcm90b3R5cGUubGFzdEluZGV4T2YgJiYgWzAsIDFdLmxhc3RJbmRleE9mKDAsIC0zKSAhPT0gLTE7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBsYXN0SW5kZXhPZjogZnVuY3Rpb24gbGFzdEluZGV4T2Yoc2VhcmNoRWxlbWVudC8qLCBmcm9tSW5kZXggKi8pIHtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIGlmIChsZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgaSA9IGxlbmd0aCAtIDE7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBpID0gbWluKGksIEVTLlRvSW50ZWdlcihhcmd1bWVudHNbMV0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGhhbmRsZSBuZWdhdGl2ZSBpbmRpY2VzXG4gICAgICAgICAgICBpID0gaSA+PSAwID8gaSA6IGxlbmd0aCAtIE1hdGguYWJzKGkpO1xuICAgICAgICAgICAgZm9yICg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZiAmJiBzZWFyY2hFbGVtZW50ID09PSBzZWxmW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgIH0sIGhhc0ZpcmVmb3gyTGFzdEluZGV4T2ZCdWcpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xMlxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xMlxuICAgIHZhciBzcGxpY2VOb29wUmV0dXJuc0VtcHR5QXJyYXkgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYSA9IFsxLCAyXTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGEuc3BsaWNlKCk7XG4gICAgICAgIHJldHVybiBhLmxlbmd0aCA9PT0gMiAmJiBpc0FycmF5KHJlc3VsdCkgJiYgcmVzdWx0Lmxlbmd0aCA9PT0gMDtcbiAgICB9KCkpO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgLy8gU2FmYXJpIDUuMCBidWcgd2hlcmUgLnNwbGljZSgpIHJldHVybnMgdW5kZWZpbmVkXG4gICAgICAgIHNwbGljZTogZnVuY3Rpb24gc3BsaWNlKHN0YXJ0LCBkZWxldGVDb3VudCkge1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBhcnJheV9zcGxpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sICFzcGxpY2VOb29wUmV0dXJuc0VtcHR5QXJyYXkpO1xuXG4gICAgdmFyIHNwbGljZVdvcmtzV2l0aEVtcHR5T2JqZWN0ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9iaiA9IHt9O1xuICAgICAgICBBcnJheVByb3RvdHlwZS5zcGxpY2UuY2FsbChvYmosIDAsIDAsIDEpO1xuICAgICAgICByZXR1cm4gb2JqLmxlbmd0aCA9PT0gMTtcbiAgICB9KCkpO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgc3BsaWNlOiBmdW5jdGlvbiBzcGxpY2Uoc3RhcnQsIGRlbGV0ZUNvdW50KSB7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICAgICAgdGhpcy5sZW5ndGggPSBtYXgoRVMuVG9JbnRlZ2VyKHRoaXMubGVuZ3RoKSwgMCk7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgdHlwZW9mIGRlbGV0ZUNvdW50ICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgIGFyZ3MgPSBhcnJheVNsaWNlKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbChhcmdzLCB0aGlzLmxlbmd0aCAtIHN0YXJ0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gRVMuVG9JbnRlZ2VyKGRlbGV0ZUNvdW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gYXJyYXlfc3BsaWNlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfSwgIXNwbGljZVdvcmtzV2l0aEVtcHR5T2JqZWN0KTtcbiAgICB2YXIgc3BsaWNlV29ya3NXaXRoTGFyZ2VTcGFyc2VBcnJheXMgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBQZXIgaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2lzc3Vlcy8yOTVcbiAgICAgICAgLy8gU2FmYXJpIDcvOCBicmVha3Mgd2l0aCBzcGFyc2UgYXJyYXlzIG9mIHNpemUgMWU1IG9yIGdyZWF0ZXJcbiAgICAgICAgdmFyIGFyciA9IG5ldyAkQXJyYXkoMWU1KTtcbiAgICAgICAgLy8gbm90ZTogdGhlIGluZGV4IE1VU1QgYmUgOCBvciBsYXJnZXIgb3IgdGhlIHRlc3Qgd2lsbCBmYWxzZSBwYXNzXG4gICAgICAgIGFycls4XSA9ICd4JztcbiAgICAgICAgYXJyLnNwbGljZSgxLCAxKTtcbiAgICAgICAgLy8gbm90ZTogdGhpcyB0ZXN0IG11c3QgYmUgZGVmaW5lZCAqYWZ0ZXIqIHRoZSBpbmRleE9mIHNoaW1cbiAgICAgICAgLy8gcGVyIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbS9pc3N1ZXMvMzEzXG4gICAgICAgIHJldHVybiBhcnIuaW5kZXhPZigneCcpID09PSA3O1xuICAgIH0oKSk7XG4gICAgdmFyIHNwbGljZVdvcmtzV2l0aFNtYWxsU3BhcnNlQXJyYXlzID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gUGVyIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbS9pc3N1ZXMvMjk1XG4gICAgICAgIC8vIE9wZXJhIDEyLjE1IGJyZWFrcyBvbiB0aGlzLCBubyBpZGVhIHdoeS5cbiAgICAgICAgdmFyIG4gPSAyNTY7XG4gICAgICAgIHZhciBhcnIgPSBbXTtcbiAgICAgICAgYXJyW25dID0gJ2EnO1xuICAgICAgICBhcnIuc3BsaWNlKG4gKyAxLCAwLCAnYicpO1xuICAgICAgICByZXR1cm4gYXJyW25dID09PSAnYSc7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNwbGljZTogZnVuY3Rpb24gc3BsaWNlKHN0YXJ0LCBkZWxldGVDb3VudCkge1xuICAgICAgICAgICAgdmFyIE8gPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBBID0gW107XG4gICAgICAgICAgICB2YXIgbGVuID0gRVMuVG9VaW50MzIoTy5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIHJlbGF0aXZlU3RhcnQgPSBFUy5Ub0ludGVnZXIoc3RhcnQpO1xuICAgICAgICAgICAgdmFyIGFjdHVhbFN0YXJ0ID0gcmVsYXRpdmVTdGFydCA8IDAgPyBtYXgoKGxlbiArIHJlbGF0aXZlU3RhcnQpLCAwKSA6IG1pbihyZWxhdGl2ZVN0YXJ0LCBsZW4pO1xuICAgICAgICAgICAgdmFyIGFjdHVhbERlbGV0ZUNvdW50ID0gbWluKG1heChFUy5Ub0ludGVnZXIoZGVsZXRlQ291bnQpLCAwKSwgbGVuIC0gYWN0dWFsU3RhcnQpO1xuXG4gICAgICAgICAgICB2YXIgayA9IDA7XG4gICAgICAgICAgICB2YXIgZnJvbTtcbiAgICAgICAgICAgIHdoaWxlIChrIDwgYWN0dWFsRGVsZXRlQ291bnQpIHtcbiAgICAgICAgICAgICAgICBmcm9tID0gJFN0cmluZyhhY3R1YWxTdGFydCArIGspO1xuICAgICAgICAgICAgICAgIGlmIChvd25zKE8sIGZyb20pKSB7XG4gICAgICAgICAgICAgICAgICAgIEFba10gPSBPW2Zyb21dO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBrICs9IDE7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBpdGVtcyA9IGFycmF5U2xpY2UoYXJndW1lbnRzLCAyKTtcbiAgICAgICAgICAgIHZhciBpdGVtQ291bnQgPSBpdGVtcy5sZW5ndGg7XG4gICAgICAgICAgICB2YXIgdG87XG4gICAgICAgICAgICBpZiAoaXRlbUNvdW50IDwgYWN0dWFsRGVsZXRlQ291bnQpIHtcbiAgICAgICAgICAgICAgICBrID0gYWN0dWFsU3RhcnQ7XG4gICAgICAgICAgICAgICAgdmFyIG1heEsgPSBsZW4gLSBhY3R1YWxEZWxldGVDb3VudDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoayA8IG1heEspIHtcbiAgICAgICAgICAgICAgICAgICAgZnJvbSA9ICRTdHJpbmcoayArIGFjdHVhbERlbGV0ZUNvdW50KTtcbiAgICAgICAgICAgICAgICAgICAgdG8gPSAkU3RyaW5nKGsgKyBpdGVtQ291bnQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3ducyhPLCBmcm9tKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgT1t0b10gPSBPW2Zyb21dO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIE9bdG9dO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGsgKz0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgayA9IGxlbjtcbiAgICAgICAgICAgICAgICB2YXIgbWluSyA9IGxlbiAtIGFjdHVhbERlbGV0ZUNvdW50ICsgaXRlbUNvdW50O1xuICAgICAgICAgICAgICAgIHdoaWxlIChrID4gbWluSykge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgT1trIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIGsgLT0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGl0ZW1Db3VudCA+IGFjdHVhbERlbGV0ZUNvdW50KSB7XG4gICAgICAgICAgICAgICAgayA9IGxlbiAtIGFjdHVhbERlbGV0ZUNvdW50O1xuICAgICAgICAgICAgICAgIHdoaWxlIChrID4gYWN0dWFsU3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZnJvbSA9ICRTdHJpbmcoayArIGFjdHVhbERlbGV0ZUNvdW50IC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIHRvID0gJFN0cmluZyhrICsgaXRlbUNvdW50IC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvd25zKE8sIGZyb20pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBPW3RvXSA9IE9bZnJvbV07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgT1t0b107XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgayAtPSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGsgPSBhY3R1YWxTdGFydDtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICBPW2tdID0gaXRlbXNbaV07XG4gICAgICAgICAgICAgICAgayArPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgTy5sZW5ndGggPSBsZW4gLSBhY3R1YWxEZWxldGVDb3VudCArIGl0ZW1Db3VudDtcblxuICAgICAgICAgICAgcmV0dXJuIEE7XG4gICAgICAgIH1cbiAgICB9LCAhc3BsaWNlV29ya3NXaXRoTGFyZ2VTcGFyc2VBcnJheXMgfHwgIXNwbGljZVdvcmtzV2l0aFNtYWxsU3BhcnNlQXJyYXlzKTtcblxuICAgIHZhciBvcmlnaW5hbEpvaW4gPSBBcnJheVByb3RvdHlwZS5qb2luO1xuICAgIHZhciBoYXNTdHJpbmdKb2luQnVnO1xuICAgIHRyeSB7XG4gICAgICAgIGhhc1N0cmluZ0pvaW5CdWcgPSBBcnJheS5wcm90b3R5cGUuam9pbi5jYWxsKCcxMjMnLCAnLCcpICE9PSAnMSwyLDMnO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaGFzU3RyaW5nSm9pbkJ1ZyA9IHRydWU7XG4gICAgfVxuICAgIGlmIChoYXNTdHJpbmdKb2luQnVnKSB7XG4gICAgICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgICAgIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlcCA9IHR5cGVvZiBzZXBhcmF0b3IgPT09ICd1bmRlZmluZWQnID8gJywnIDogc2VwYXJhdG9yO1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbEpvaW4uY2FsbChpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IHRoaXMsIHNlcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIGhhc1N0cmluZ0pvaW5CdWcpO1xuICAgIH1cblxuICAgIHZhciBoYXNKb2luVW5kZWZpbmVkQnVnID0gWzEsIDJdLmpvaW4odW5kZWZpbmVkKSAhPT0gJzEsMic7XG4gICAgaWYgKGhhc0pvaW5VbmRlZmluZWRCdWcpIHtcbiAgICAgICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICAgICAgam9pbjogZnVuY3Rpb24gam9pbihzZXBhcmF0b3IpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VwID0gdHlwZW9mIHNlcGFyYXRvciA9PT0gJ3VuZGVmaW5lZCcgPyAnLCcgOiBzZXBhcmF0b3I7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsSm9pbi5jYWxsKHRoaXMsIHNlcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIGhhc0pvaW5VbmRlZmluZWRCdWcpO1xuICAgIH1cblxuICAgIHZhciBwdXNoU2hpbSA9IGZ1bmN0aW9uIHB1c2goaXRlbSkge1xuICAgICAgICB2YXIgTyA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICB2YXIgbiA9IEVTLlRvVWludDMyKE8ubGVuZ3RoKTtcbiAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICB3aGlsZSAoaSA8IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIE9bbiArIGldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICAgICAgaSArPSAxO1xuICAgICAgICB9XG4gICAgICAgIE8ubGVuZ3RoID0gbiArIGk7XG4gICAgICAgIHJldHVybiBuICsgaTtcbiAgICB9O1xuXG4gICAgdmFyIHB1c2hJc05vdEdlbmVyaWMgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgb2JqID0ge307XG4gICAgICAgIHZhciByZXN1bHQgPSBBcnJheS5wcm90b3R5cGUucHVzaC5jYWxsKG9iaiwgdW5kZWZpbmVkKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCAhPT0gMSB8fCBvYmoubGVuZ3RoICE9PSAxIHx8IHR5cGVvZiBvYmpbMF0gIT09ICd1bmRlZmluZWQnIHx8ICFvd25zKG9iaiwgMCk7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHB1c2g6IGZ1bmN0aW9uIHB1c2goaXRlbSkge1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkodGhpcykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlfcHVzaC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHB1c2hTaGltLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9LCBwdXNoSXNOb3RHZW5lcmljKTtcblxuICAgIC8vIFRoaXMgZml4ZXMgYSB2ZXJ5IHdlaXJkIGJ1ZyBpbiBPcGVyYSAxMC42IHdoZW4gcHVzaGluZyBgdW5kZWZpbmVkXG4gICAgdmFyIHB1c2hVbmRlZmluZWRJc1dlaXJkID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyciA9IFtdO1xuICAgICAgICB2YXIgcmVzdWx0ID0gYXJyLnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCAhPT0gMSB8fCBhcnIubGVuZ3RoICE9PSAxIHx8IHR5cGVvZiBhcnJbMF0gIT09ICd1bmRlZmluZWQnIHx8ICFvd25zKGFyciwgMCk7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7IHB1c2g6IHB1c2hTaGltIH0sIHB1c2hVbmRlZmluZWRJc1dlaXJkKTtcblxuICAgIC8vIEVTNSAxNS4yLjMuMTRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjQuNC4xMFxuICAgIC8vIEZpeCBib3hlZCBzdHJpbmcgYnVnXG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBzbGljZTogZnVuY3Rpb24gKHN0YXJ0LCBlbmQpIHtcbiAgICAgICAgICAgIHZhciBhcnIgPSBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IHRoaXM7XG4gICAgICAgICAgICByZXR1cm4gYXJyYXlTbGljZUFwcGx5KGFyciwgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH0sIHNwbGl0U3RyaW5nKTtcblxuICAgIHZhciBzb3J0SWdub3Jlc05vbkZ1bmN0aW9ucyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBbMSwgMl0uc29ydChudWxsKTtcbiAgICAgICAgICAgIFsxLCAyXS5zb3J0KHt9KTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSgpKTtcbiAgICB2YXIgc29ydFRocm93c09uUmVnZXggPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyB0aGlzIGlzIGEgcHJvYmxlbSBpbiBGaXJlZm94IDQsIGluIHdoaWNoIGB0eXBlb2YgL2EvID09PSAnZnVuY3Rpb24nYFxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgWzEsIDJdLnNvcnQoL2EvKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSgpKTtcbiAgICB2YXIgc29ydElnbm9yZXNVbmRlZmluZWQgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBhcHBsaWVzIGluIElFIDgsIGZvciBvbmUuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBbMSwgMl0uc29ydCh1bmRlZmluZWQpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9KCkpO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgc29ydDogZnVuY3Rpb24gc29ydChjb21wYXJlRm4pIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29tcGFyZUZuID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBhcnJheVNvcnQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY29tcGFyZUZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5zb3J0IGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGFycmF5U29ydCh0aGlzLCBjb21wYXJlRm4pO1xuICAgICAgICB9XG4gICAgfSwgc29ydElnbm9yZXNOb25GdW5jdGlvbnMgfHwgIXNvcnRJZ25vcmVzVW5kZWZpbmVkIHx8ICFzb3J0VGhyb3dzT25SZWdleCk7XG5cbiAgICAvL1xuICAgIC8vIE9iamVjdFxuICAgIC8vID09PT09PVxuICAgIC8vXG5cbiAgICAvLyBFUzUgMTUuMi4zLjE0XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuMi4zLjE0XG5cbiAgICAvLyBodHRwOi8vd2hhdHRoZWhlYWRzYWlkLmNvbS8yMDEwLzEwL2Etc2FmZXItb2JqZWN0LWtleXMtY29tcGF0aWJpbGl0eS1pbXBsZW1lbnRhdGlvblxuICAgIHZhciBoYXNEb250RW51bUJ1ZyA9ICFpc0VudW0oeyAndG9TdHJpbmcnOiBudWxsIH0sICd0b1N0cmluZycpO1xuICAgIHZhciBoYXNQcm90b0VudW1CdWcgPSBpc0VudW0oZnVuY3Rpb24gKCkge30sICdwcm90b3R5cGUnKTtcbiAgICB2YXIgaGFzU3RyaW5nRW51bUJ1ZyA9ICFvd25zKCd4JywgJzAnKTtcbiAgICB2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUgPSBmdW5jdGlvbiAobykge1xuICAgICAgICB2YXIgY3RvciA9IG8uY29uc3RydWN0b3I7XG4gICAgICAgIHJldHVybiBjdG9yICYmIGN0b3IucHJvdG90eXBlID09PSBvO1xuICAgIH07XG4gICAgdmFyIGJsYWNrbGlzdGVkS2V5cyA9IHtcbiAgICAgICAgJHdpbmRvdzogdHJ1ZSxcbiAgICAgICAgJGNvbnNvbGU6IHRydWUsXG4gICAgICAgICRwYXJlbnQ6IHRydWUsXG4gICAgICAgICRzZWxmOiB0cnVlLFxuICAgICAgICAkZnJhbWU6IHRydWUsXG4gICAgICAgICRmcmFtZXM6IHRydWUsXG4gICAgICAgICRmcmFtZUVsZW1lbnQ6IHRydWUsXG4gICAgICAgICR3ZWJraXRJbmRleGVkREI6IHRydWUsXG4gICAgICAgICR3ZWJraXRTdG9yYWdlSW5mbzogdHJ1ZSxcbiAgICAgICAgJGV4dGVybmFsOiB0cnVlXG4gICAgfTtcbiAgICB2YXIgaGFzQXV0b21hdGlvbkVxdWFsaXR5QnVnID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLyogZ2xvYmFscyB3aW5kb3cgKi9cbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgayBpbiB3aW5kb3cpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKCFibGFja2xpc3RlZEtleXNbJyQnICsga10gJiYgb3ducyh3aW5kb3csIGspICYmIHdpbmRvd1trXSAhPT0gbnVsbCAmJiB0eXBlb2Ygd2luZG93W2tdID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZSh3aW5kb3dba10pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSgpKTtcbiAgICB2YXIgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGVJZk5vdEJ1Z2d5ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcgfHwgIWhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1Zykge1xuICAgICAgICAgICAgcmV0dXJuIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlKG9iamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZShvYmplY3QpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHZhciBkb250RW51bXMgPSBbXG4gICAgICAgICd0b1N0cmluZycsXG4gICAgICAgICd0b0xvY2FsZVN0cmluZycsXG4gICAgICAgICd2YWx1ZU9mJyxcbiAgICAgICAgJ2hhc093blByb3BlcnR5JyxcbiAgICAgICAgJ2lzUHJvdG90eXBlT2YnLFxuICAgICAgICAncHJvcGVydHlJc0VudW1lcmFibGUnLFxuICAgICAgICAnY29uc3RydWN0b3InXG4gICAgXTtcbiAgICB2YXIgZG9udEVudW1zTGVuZ3RoID0gZG9udEVudW1zLmxlbmd0aDtcblxuICAgIC8vIHRha2VuIGRpcmVjdGx5IGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9pcy1hcmd1bWVudHMvYmxvYi9tYXN0ZXIvaW5kZXguanNcbiAgICAvLyBjYW4gYmUgcmVwbGFjZWQgd2l0aCByZXF1aXJlKCdpcy1hcmd1bWVudHMnKSBpZiB3ZSBldmVyIHVzZSBhIGJ1aWxkIHByb2Nlc3MgaW5zdGVhZFxuICAgIHZhciBpc1N0YW5kYXJkQXJndW1lbnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRvU3RyKHZhbHVlKSA9PT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG4gICAgfTtcbiAgICB2YXIgaXNMZWdhY3lBcmd1bWVudHMgPSBmdW5jdGlvbiBpc0FyZ3VtZW50cyh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgIHR5cGVvZiB2YWx1ZS5sZW5ndGggPT09ICdudW1iZXInICYmXG4gICAgICAgICAgICB2YWx1ZS5sZW5ndGggPj0gMCAmJlxuICAgICAgICAgICAgIWlzQXJyYXkodmFsdWUpICYmXG4gICAgICAgICAgICBpc0NhbGxhYmxlKHZhbHVlLmNhbGxlZSk7XG4gICAgfTtcbiAgICB2YXIgaXNBcmd1bWVudHMgPSBpc1N0YW5kYXJkQXJndW1lbnRzKGFyZ3VtZW50cykgPyBpc1N0YW5kYXJkQXJndW1lbnRzIDogaXNMZWdhY3lBcmd1bWVudHM7XG5cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKCRPYmplY3QsIHtcbiAgICAgICAga2V5czogZnVuY3Rpb24ga2V5cyhvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBpc0ZuID0gaXNDYWxsYWJsZShvYmplY3QpO1xuICAgICAgICAgICAgdmFyIGlzQXJncyA9IGlzQXJndW1lbnRzKG9iamVjdCk7XG4gICAgICAgICAgICB2YXIgaXNPYmplY3QgPSBvYmplY3QgIT09IG51bGwgJiYgdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCc7XG4gICAgICAgICAgICB2YXIgaXNTdHIgPSBpc09iamVjdCAmJiBpc1N0cmluZyhvYmplY3QpO1xuXG4gICAgICAgICAgICBpZiAoIWlzT2JqZWN0ICYmICFpc0ZuICYmICFpc0FyZ3MpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0Jyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB0aGVLZXlzID0gW107XG4gICAgICAgICAgICB2YXIgc2tpcFByb3RvID0gaGFzUHJvdG9FbnVtQnVnICYmIGlzRm47XG4gICAgICAgICAgICBpZiAoKGlzU3RyICYmIGhhc1N0cmluZ0VudW1CdWcpIHx8IGlzQXJncykge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKHRoZUtleXMsICRTdHJpbmcoaSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFpc0FyZ3MpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBuYW1lIGluIG9iamVjdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShza2lwUHJvdG8gJiYgbmFtZSA9PT0gJ3Byb3RvdHlwZScpICYmIG93bnMob2JqZWN0LCBuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwodGhlS2V5cywgJFN0cmluZyhuYW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChoYXNEb250RW51bUJ1Zykge1xuICAgICAgICAgICAgICAgIHZhciBza2lwQ29uc3RydWN0b3IgPSBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZUlmTm90QnVnZ3kob2JqZWN0KTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGRvbnRFbnVtc0xlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBkb250RW51bSA9IGRvbnRFbnVtc1tqXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtID09PSAnY29uc3RydWN0b3InKSAmJiBvd25zKG9iamVjdCwgZG9udEVudW0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbCh0aGVLZXlzLCBkb250RW51bSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhlS2V5cztcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgdmFyIGtleXNXb3Jrc1dpdGhBcmd1bWVudHMgPSAkT2JqZWN0LmtleXMgJiYgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gU2FmYXJpIDUuMCBidWdcbiAgICAgICAgcmV0dXJuICRPYmplY3Qua2V5cyhhcmd1bWVudHMpLmxlbmd0aCA9PT0gMjtcbiAgICB9KDEsIDIpKTtcbiAgICB2YXIga2V5c0hhc0FyZ3VtZW50c0xlbmd0aEJ1ZyA9ICRPYmplY3Qua2V5cyAmJiAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXJnS2V5cyA9ICRPYmplY3Qua2V5cyhhcmd1bWVudHMpO1xuICAgICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCAhPT0gMSB8fCBhcmdLZXlzLmxlbmd0aCAhPT0gMSB8fCBhcmdLZXlzWzBdICE9PSAxO1xuICAgIH0oMSkpO1xuICAgIHZhciBvcmlnaW5hbEtleXMgPSAkT2JqZWN0LmtleXM7XG4gICAgZGVmaW5lUHJvcGVydGllcygkT2JqZWN0LCB7XG4gICAgICAgIGtleXM6IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAoaXNBcmd1bWVudHMob2JqZWN0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbEtleXMoYXJyYXlTbGljZShvYmplY3QpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsS2V5cyhvYmplY3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSwgIWtleXNXb3Jrc1dpdGhBcmd1bWVudHMgfHwga2V5c0hhc0FyZ3VtZW50c0xlbmd0aEJ1Zyk7XG5cbiAgICAvL1xuICAgIC8vIERhdGVcbiAgICAvLyA9PT09XG4gICAgLy9cblxuICAgIHZhciBoYXNOZWdhdGl2ZU1vbnRoWWVhckJ1ZyA9IG5ldyBEYXRlKC0zNTA5ODI3MzI5NjAwMjkyKS5nZXRVVENNb250aCgpICE9PSAwO1xuICAgIHZhciBhTmVnYXRpdmVUZXN0RGF0ZSA9IG5ldyBEYXRlKC0xNTA5ODQyMjg5NjAwMjkyKTtcbiAgICB2YXIgYVBvc2l0aXZlVGVzdERhdGUgPSBuZXcgRGF0ZSgxNDQ5NjYyNDAwMDAwKTtcbiAgICB2YXIgaGFzVG9VVENTdHJpbmdGb3JtYXRCdWcgPSBhTmVnYXRpdmVUZXN0RGF0ZS50b1VUQ1N0cmluZygpICE9PSAnTW9uLCAwMSBKYW4gLTQ1ODc1IDExOjU5OjU5IEdNVCc7XG4gICAgdmFyIGhhc1RvRGF0ZVN0cmluZ0Zvcm1hdEJ1ZztcbiAgICB2YXIgaGFzVG9TdHJpbmdGb3JtYXRCdWc7XG4gICAgdmFyIHRpbWVab25lT2Zmc2V0ID0gYU5lZ2F0aXZlVGVzdERhdGUuZ2V0VGltZXpvbmVPZmZzZXQoKTtcbiAgICBpZiAodGltZVpvbmVPZmZzZXQgPCAtNzIwKSB7XG4gICAgICAgIGhhc1RvRGF0ZVN0cmluZ0Zvcm1hdEJ1ZyA9IGFOZWdhdGl2ZVRlc3REYXRlLnRvRGF0ZVN0cmluZygpICE9PSAnVHVlIEphbiAwMiAtNDU4NzUnO1xuICAgICAgICBoYXNUb1N0cmluZ0Zvcm1hdEJ1ZyA9ICEoL15UaHUgRGVjIDEwIDIwMTUgXFxkXFxkOlxcZFxcZDpcXGRcXGQgR01UWy1cXCtdXFxkXFxkXFxkXFxkKD86IHwkKS8pLnRlc3QoYVBvc2l0aXZlVGVzdERhdGUudG9TdHJpbmcoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaGFzVG9EYXRlU3RyaW5nRm9ybWF0QnVnID0gYU5lZ2F0aXZlVGVzdERhdGUudG9EYXRlU3RyaW5nKCkgIT09ICdNb24gSmFuIDAxIC00NTg3NSc7XG4gICAgICAgIGhhc1RvU3RyaW5nRm9ybWF0QnVnID0gISgvXldlZCBEZWMgMDkgMjAxNSBcXGRcXGQ6XFxkXFxkOlxcZFxcZCBHTVRbLVxcK11cXGRcXGRcXGRcXGQoPzogfCQpLykudGVzdChhUG9zaXRpdmVUZXN0RGF0ZS50b1N0cmluZygpKTtcbiAgICB9XG5cbiAgICB2YXIgb3JpZ2luYWxHZXRGdWxsWWVhciA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRGdWxsWWVhcik7XG4gICAgdmFyIG9yaWdpbmFsR2V0TW9udGggPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0TW9udGgpO1xuICAgIHZhciBvcmlnaW5hbEdldERhdGUgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0RGF0ZSk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDRnVsbFllYXIgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VVRDRnVsbFllYXIpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ01vbnRoID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ01vbnRoKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENEYXRlID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ0RhdGUpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ0RheSA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENEYXkpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ0hvdXJzID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ0hvdXJzKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENNaW51dGVzID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ01pbnV0ZXMpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ1NlY29uZHMgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VVRDU2Vjb25kcyk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDTWlsbGlzZWNvbmRzID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ01pbGxpc2Vjb25kcyk7XG4gICAgdmFyIGRheU5hbWUgPSBbJ1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCddO1xuICAgIHZhciBtb250aE5hbWUgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJywgJ09jdCcsICdOb3YnLCAnRGVjJ107XG4gICAgdmFyIGRheXNJbk1vbnRoID0gZnVuY3Rpb24gZGF5c0luTW9udGgobW9udGgsIHllYXIpIHtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsR2V0RGF0ZShuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMCkpO1xuICAgIH07XG5cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGUucHJvdG90eXBlLCB7XG4gICAgICAgIGdldEZ1bGxZZWFyOiBmdW5jdGlvbiBnZXRGdWxsWWVhcigpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgeWVhciA9IG9yaWdpbmFsR2V0RnVsbFllYXIodGhpcyk7XG4gICAgICAgICAgICBpZiAoeWVhciA8IDAgJiYgb3JpZ2luYWxHZXRNb250aCh0aGlzKSA+IDExKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHllYXIgKyAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHllYXI7XG4gICAgICAgIH0sXG4gICAgICAgIGdldE1vbnRoOiBmdW5jdGlvbiBnZXRNb250aCgpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgeWVhciA9IG9yaWdpbmFsR2V0RnVsbFllYXIodGhpcyk7XG4gICAgICAgICAgICB2YXIgbW9udGggPSBvcmlnaW5hbEdldE1vbnRoKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHllYXIgPCAwICYmIG1vbnRoID4gMTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtb250aDtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0RGF0ZTogZnVuY3Rpb24gZ2V0RGF0ZSgpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgeWVhciA9IG9yaWdpbmFsR2V0RnVsbFllYXIodGhpcyk7XG4gICAgICAgICAgICB2YXIgbW9udGggPSBvcmlnaW5hbEdldE1vbnRoKHRoaXMpO1xuICAgICAgICAgICAgdmFyIGRhdGUgPSBvcmlnaW5hbEdldERhdGUodGhpcyk7XG4gICAgICAgICAgICBpZiAoeWVhciA8IDAgJiYgbW9udGggPiAxMSkge1xuICAgICAgICAgICAgICAgIGlmIChtb250aCA9PT0gMTIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBkYXlzID0gZGF5c0luTW9udGgoMCwgeWVhciArIDEpO1xuICAgICAgICAgICAgICAgIHJldHVybiAoZGF5cyAtIGRhdGUpICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgICB9LFxuICAgICAgICBnZXRVVENGdWxsWWVhcjogZnVuY3Rpb24gZ2V0VVRDRnVsbFllYXIoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldFVUQ0Z1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHllYXIgPCAwICYmIG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcykgPiAxMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB5ZWFyICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB5ZWFyO1xuICAgICAgICB9LFxuICAgICAgICBnZXRVVENNb250aDogZnVuY3Rpb24gZ2V0VVRDTW9udGgoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldFVUQ0Z1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRVVENNb250aCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBtb250aCA+IDExKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbW9udGg7XG4gICAgICAgIH0sXG4gICAgICAgIGdldFVUQ0RhdGU6IGZ1bmN0aW9uIGdldFVUQ0RhdGUoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldFVUQ0Z1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRVVENNb250aCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBkYXRlID0gb3JpZ2luYWxHZXRVVENEYXRlKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHllYXIgPCAwICYmIG1vbnRoID4gMTEpIHtcbiAgICAgICAgICAgICAgICBpZiAobW9udGggPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgZGF5cyA9IGRheXNJbk1vbnRoKDAsIHllYXIgKyAxKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gKGRheXMgLSBkYXRlKSArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgICAgfVxuICAgIH0sIGhhc05lZ2F0aXZlTW9udGhZZWFyQnVnKTtcblxuICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZS5wcm90b3R5cGUsIHtcbiAgICAgICAgdG9VVENTdHJpbmc6IGZ1bmN0aW9uIHRvVVRDU3RyaW5nKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBkYXkgPSBvcmlnaW5hbEdldFVUQ0RheSh0aGlzKTtcbiAgICAgICAgICAgIHZhciBkYXRlID0gb3JpZ2luYWxHZXRVVENEYXRlKHRoaXMpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRVVENNb250aCh0aGlzKTtcbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIHZhciBob3VyID0gb3JpZ2luYWxHZXRVVENIb3Vycyh0aGlzKTtcbiAgICAgICAgICAgIHZhciBtaW51dGUgPSBvcmlnaW5hbEdldFVUQ01pbnV0ZXModGhpcyk7XG4gICAgICAgICAgICB2YXIgc2Vjb25kID0gb3JpZ2luYWxHZXRVVENTZWNvbmRzKHRoaXMpO1xuICAgICAgICAgICAgcmV0dXJuIGRheU5hbWVbZGF5XSArICcsICcgK1xuICAgICAgICAgICAgICAgIChkYXRlIDwgMTAgPyAnMCcgKyBkYXRlIDogZGF0ZSkgKyAnICcgK1xuICAgICAgICAgICAgICAgIG1vbnRoTmFtZVttb250aF0gKyAnICcgK1xuICAgICAgICAgICAgICAgIHllYXIgKyAnICcgK1xuICAgICAgICAgICAgICAgIChob3VyIDwgMTAgPyAnMCcgKyBob3VyIDogaG91cikgKyAnOicgK1xuICAgICAgICAgICAgICAgIChtaW51dGUgPCAxMCA/ICcwJyArIG1pbnV0ZSA6IG1pbnV0ZSkgKyAnOicgK1xuICAgICAgICAgICAgICAgIChzZWNvbmQgPCAxMCA/ICcwJyArIHNlY29uZCA6IHNlY29uZCkgKyAnIEdNVCc7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZU1vbnRoWWVhckJ1ZyB8fCBoYXNUb1VUQ1N0cmluZ0Zvcm1hdEJ1Zyk7XG5cbiAgICAvLyBPcGVyYSAxMiBoYXMgYCxgXG4gICAgZGVmaW5lUHJvcGVydGllcyhEYXRlLnByb3RvdHlwZSwge1xuICAgICAgICB0b0RhdGVTdHJpbmc6IGZ1bmN0aW9uIHRvRGF0ZVN0cmluZygpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGF5ID0gdGhpcy5nZXREYXkoKTtcbiAgICAgICAgICAgIHZhciBkYXRlID0gdGhpcy5nZXREYXRlKCk7XG4gICAgICAgICAgICB2YXIgbW9udGggPSB0aGlzLmdldE1vbnRoKCk7XG4gICAgICAgICAgICB2YXIgeWVhciA9IHRoaXMuZ2V0RnVsbFllYXIoKTtcbiAgICAgICAgICAgIHJldHVybiBkYXlOYW1lW2RheV0gKyAnICcgK1xuICAgICAgICAgICAgICAgIG1vbnRoTmFtZVttb250aF0gKyAnICcgK1xuICAgICAgICAgICAgICAgIChkYXRlIDwgMTAgPyAnMCcgKyBkYXRlIDogZGF0ZSkgKyAnICcgK1xuICAgICAgICAgICAgICAgIHllYXI7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZU1vbnRoWWVhckJ1ZyB8fCBoYXNUb0RhdGVTdHJpbmdGb3JtYXRCdWcpO1xuXG4gICAgLy8gY2FuJ3QgdXNlIGRlZmluZVByb3BlcnRpZXMgaGVyZSBiZWNhdXNlIG9mIHRvU3RyaW5nIGVudW1lcmF0aW9uIGlzc3VlIGluIElFIDw9IDhcbiAgICBpZiAoaGFzTmVnYXRpdmVNb250aFllYXJCdWcgfHwgaGFzVG9TdHJpbmdGb3JtYXRCdWcpIHtcbiAgICAgICAgRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGF5ID0gdGhpcy5nZXREYXkoKTtcbiAgICAgICAgICAgIHZhciBkYXRlID0gdGhpcy5nZXREYXRlKCk7XG4gICAgICAgICAgICB2YXIgbW9udGggPSB0aGlzLmdldE1vbnRoKCk7XG4gICAgICAgICAgICB2YXIgeWVhciA9IHRoaXMuZ2V0RnVsbFllYXIoKTtcbiAgICAgICAgICAgIHZhciBob3VyID0gdGhpcy5nZXRIb3VycygpO1xuICAgICAgICAgICAgdmFyIG1pbnV0ZSA9IHRoaXMuZ2V0TWludXRlcygpO1xuICAgICAgICAgICAgdmFyIHNlY29uZCA9IHRoaXMuZ2V0U2Vjb25kcygpO1xuICAgICAgICAgICAgdmFyIHRpbWV6b25lT2Zmc2V0ID0gdGhpcy5nZXRUaW1lem9uZU9mZnNldCgpO1xuICAgICAgICAgICAgdmFyIGhvdXJzT2Zmc2V0ID0gTWF0aC5mbG9vcihNYXRoLmFicyh0aW1lem9uZU9mZnNldCkgLyA2MCk7XG4gICAgICAgICAgICB2YXIgbWludXRlc09mZnNldCA9IE1hdGguZmxvb3IoTWF0aC5hYnModGltZXpvbmVPZmZzZXQpICUgNjApO1xuICAgICAgICAgICAgcmV0dXJuIGRheU5hbWVbZGF5XSArICcgJyArXG4gICAgICAgICAgICAgICAgbW9udGhOYW1lW21vbnRoXSArICcgJyArXG4gICAgICAgICAgICAgICAgKGRhdGUgPCAxMCA/ICcwJyArIGRhdGUgOiBkYXRlKSArICcgJyArXG4gICAgICAgICAgICAgICAgeWVhciArICcgJyArXG4gICAgICAgICAgICAgICAgKGhvdXIgPCAxMCA/ICcwJyArIGhvdXIgOiBob3VyKSArICc6JyArXG4gICAgICAgICAgICAgICAgKG1pbnV0ZSA8IDEwID8gJzAnICsgbWludXRlIDogbWludXRlKSArICc6JyArXG4gICAgICAgICAgICAgICAgKHNlY29uZCA8IDEwID8gJzAnICsgc2Vjb25kIDogc2Vjb25kKSArICcgR01UJyArXG4gICAgICAgICAgICAgICAgKHRpbWV6b25lT2Zmc2V0ID4gMCA/ICctJyA6ICcrJykgK1xuICAgICAgICAgICAgICAgIChob3Vyc09mZnNldCA8IDEwID8gJzAnICsgaG91cnNPZmZzZXQgOiBob3Vyc09mZnNldCkgK1xuICAgICAgICAgICAgICAgIChtaW51dGVzT2Zmc2V0IDwgMTAgPyAnMCcgKyBtaW51dGVzT2Zmc2V0IDogbWludXRlc09mZnNldCk7XG4gICAgICAgIH07XG4gICAgICAgIGlmIChzdXBwb3J0c0Rlc2NyaXB0b3JzKSB7XG4gICAgICAgICAgICAkT2JqZWN0LmRlZmluZVByb3BlcnR5KERhdGUucHJvdG90eXBlLCAndG9TdHJpbmcnLCB7XG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEVTNSAxNS45LjUuNDNcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS45LjUuNDNcbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHJldHVybnMgYSBTdHJpbmcgdmFsdWUgcmVwcmVzZW50IHRoZSBpbnN0YW5jZSBpbiB0aW1lXG4gICAgLy8gcmVwcmVzZW50ZWQgYnkgdGhpcyBEYXRlIG9iamVjdC4gVGhlIGZvcm1hdCBvZiB0aGUgU3RyaW5nIGlzIHRoZSBEYXRlIFRpbWVcbiAgICAvLyBzdHJpbmcgZm9ybWF0IGRlZmluZWQgaW4gMTUuOS4xLjE1LiBBbGwgZmllbGRzIGFyZSBwcmVzZW50IGluIHRoZSBTdHJpbmcuXG4gICAgLy8gVGhlIHRpbWUgem9uZSBpcyBhbHdheXMgVVRDLCBkZW5vdGVkIGJ5IHRoZSBzdWZmaXggWi4gSWYgdGhlIHRpbWUgdmFsdWUgb2ZcbiAgICAvLyB0aGlzIG9iamVjdCBpcyBub3QgYSBmaW5pdGUgTnVtYmVyIGEgUmFuZ2VFcnJvciBleGNlcHRpb24gaXMgdGhyb3duLlxuICAgIHZhciBuZWdhdGl2ZURhdGUgPSAtNjIxOTg3NTUyMDAwMDA7XG4gICAgdmFyIG5lZ2F0aXZlWWVhclN0cmluZyA9ICctMDAwMDAxJztcbiAgICB2YXIgaGFzTmVnYXRpdmVEYXRlQnVnID0gRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcgJiYgbmV3IERhdGUobmVnYXRpdmVEYXRlKS50b0lTT1N0cmluZygpLmluZGV4T2YobmVnYXRpdmVZZWFyU3RyaW5nKSA9PT0gLTE7XG4gICAgdmFyIGhhc1NhZmFyaTUxRGF0ZUJ1ZyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nICYmIG5ldyBEYXRlKC0xKS50b0lTT1N0cmluZygpICE9PSAnMTk2OS0xMi0zMVQyMzo1OTo1OS45OTlaJztcblxuICAgIHZhciBnZXRUaW1lID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFRpbWUpO1xuXG4gICAgZGVmaW5lUHJvcGVydGllcyhEYXRlLnByb3RvdHlwZSwge1xuICAgICAgICB0b0lTT1N0cmluZzogZnVuY3Rpb24gdG9JU09TdHJpbmcoKSB7XG4gICAgICAgICAgICBpZiAoIWlzRmluaXRlKHRoaXMpIHx8ICFpc0Zpbml0ZShnZXRUaW1lKHRoaXMpKSkge1xuICAgICAgICAgICAgICAgIC8vIEFkb3BlIFBob3Rvc2hvcCByZXF1aXJlcyB0aGUgc2Vjb25kIGNoZWNrLlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZyBjYWxsZWQgb24gbm9uLWZpbml0ZSB2YWx1ZS4nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldFVUQ0Z1bGxZZWFyKHRoaXMpO1xuXG4gICAgICAgICAgICB2YXIgbW9udGggPSBvcmlnaW5hbEdldFVUQ01vbnRoKHRoaXMpO1xuICAgICAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbS9pc3N1ZXMvMTExXG4gICAgICAgICAgICB5ZWFyICs9IE1hdGguZmxvb3IobW9udGggLyAxMik7XG4gICAgICAgICAgICBtb250aCA9IChtb250aCAlIDEyICsgMTIpICUgMTI7XG5cbiAgICAgICAgICAgIC8vIHRoZSBkYXRlIHRpbWUgc3RyaW5nIGZvcm1hdCBpcyBzcGVjaWZpZWQgaW4gMTUuOS4xLjE1LlxuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFttb250aCArIDEsIG9yaWdpbmFsR2V0VVRDRGF0ZSh0aGlzKSwgb3JpZ2luYWxHZXRVVENIb3Vycyh0aGlzKSwgb3JpZ2luYWxHZXRVVENNaW51dGVzKHRoaXMpLCBvcmlnaW5hbEdldFVUQ1NlY29uZHModGhpcyldO1xuICAgICAgICAgICAgeWVhciA9IChcbiAgICAgICAgICAgICAgICAoeWVhciA8IDAgPyAnLScgOiAoeWVhciA+IDk5OTkgPyAnKycgOiAnJykpICtcbiAgICAgICAgICAgICAgICBzdHJTbGljZSgnMDAwMDAnICsgTWF0aC5hYnMoeWVhciksICgwIDw9IHllYXIgJiYgeWVhciA8PSA5OTk5KSA/IC00IDogLTYpXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlc3VsdC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgIC8vIHBhZCBtb250aHMsIGRheXMsIGhvdXJzLCBtaW51dGVzLCBhbmQgc2Vjb25kcyB0byBoYXZlIHR3byBkaWdpdHMuXG4gICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gc3RyU2xpY2UoJzAwJyArIHJlc3VsdFtpXSwgLTIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gcGFkIG1pbGxpc2Vjb25kcyB0byBoYXZlIHRocmVlIGRpZ2l0cy5cbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgeWVhciArICctJyArIGFycmF5U2xpY2UocmVzdWx0LCAwLCAyKS5qb2luKCctJykgK1xuICAgICAgICAgICAgICAgICdUJyArIGFycmF5U2xpY2UocmVzdWx0LCAyKS5qb2luKCc6JykgKyAnLicgK1xuICAgICAgICAgICAgICAgIHN0clNsaWNlKCcwMDAnICsgb3JpZ2luYWxHZXRVVENNaWxsaXNlY29uZHModGhpcyksIC0zKSArICdaJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH0sIGhhc05lZ2F0aXZlRGF0ZUJ1ZyB8fCBoYXNTYWZhcmk1MURhdGVCdWcpO1xuXG4gICAgLy8gRVM1IDE1LjkuNS40NFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjkuNS40NFxuICAgIC8vIFRoaXMgZnVuY3Rpb24gcHJvdmlkZXMgYSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBEYXRlIG9iamVjdCBmb3IgdXNlIGJ5XG4gICAgLy8gSlNPTi5zdHJpbmdpZnkgKDE1LjEyLjMpLlxuICAgIHZhciBkYXRlVG9KU09OSXNTdXBwb3J0ZWQgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIERhdGUucHJvdG90eXBlLnRvSlNPTiAmJlxuICAgICAgICAgICAgICAgIG5ldyBEYXRlKE5hTikudG9KU09OKCkgPT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICBuZXcgRGF0ZShuZWdhdGl2ZURhdGUpLnRvSlNPTigpLmluZGV4T2YobmVnYXRpdmVZZWFyU3RyaW5nKSAhPT0gLTEgJiZcbiAgICAgICAgICAgICAgICBEYXRlLnByb3RvdHlwZS50b0pTT04uY2FsbCh7IC8vIGdlbmVyaWNcbiAgICAgICAgICAgICAgICAgICAgdG9JU09TdHJpbmc6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSgpKTtcbiAgICBpZiAoIWRhdGVUb0pTT05Jc1N1cHBvcnRlZCkge1xuICAgICAgICBEYXRlLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oa2V5KSB7XG4gICAgICAgICAgICAvLyBXaGVuIHRoZSB0b0pTT04gbWV0aG9kIGlzIGNhbGxlZCB3aXRoIGFyZ3VtZW50IGtleSwgdGhlIGZvbGxvd2luZ1xuICAgICAgICAgICAgLy8gc3RlcHMgYXJlIHRha2VuOlxuXG4gICAgICAgICAgICAvLyAxLiAgTGV0IE8gYmUgdGhlIHJlc3VsdCBvZiBjYWxsaW5nIFRvT2JqZWN0LCBnaXZpbmcgaXQgdGhlIHRoaXNcbiAgICAgICAgICAgIC8vIHZhbHVlIGFzIGl0cyBhcmd1bWVudC5cbiAgICAgICAgICAgIC8vIDIuIExldCB0diBiZSBFUy5Ub1ByaW1pdGl2ZShPLCBoaW50IE51bWJlcikuXG4gICAgICAgICAgICB2YXIgTyA9ICRPYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgdHYgPSBFUy5Ub1ByaW1pdGl2ZShPKTtcbiAgICAgICAgICAgIC8vIDMuIElmIHR2IGlzIGEgTnVtYmVyIGFuZCBpcyBub3QgZmluaXRlLCByZXR1cm4gbnVsbC5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdHYgPT09ICdudW1iZXInICYmICFpc0Zpbml0ZSh0dikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIDQuIExldCB0b0lTTyBiZSB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgdGhlIFtbR2V0XV0gaW50ZXJuYWwgbWV0aG9kIG9mXG4gICAgICAgICAgICAvLyBPIHdpdGggYXJndW1lbnQgXCJ0b0lTT1N0cmluZ1wiLlxuICAgICAgICAgICAgdmFyIHRvSVNPID0gTy50b0lTT1N0cmluZztcbiAgICAgICAgICAgIC8vIDUuIElmIElzQ2FsbGFibGUodG9JU08pIGlzIGZhbHNlLCB0aHJvdyBhIFR5cGVFcnJvciBleGNlcHRpb24uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUodG9JU08pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndG9JU09TdHJpbmcgcHJvcGVydHkgaXMgbm90IGNhbGxhYmxlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyA2LiBSZXR1cm4gdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBbW0NhbGxdXSBpbnRlcm5hbCBtZXRob2Qgb2ZcbiAgICAgICAgICAgIC8vICB0b0lTTyB3aXRoIE8gYXMgdGhlIHRoaXMgdmFsdWUgYW5kIGFuIGVtcHR5IGFyZ3VtZW50IGxpc3QuXG4gICAgICAgICAgICByZXR1cm4gdG9JU08uY2FsbChPKTtcblxuICAgICAgICAgICAgLy8gTk9URSAxIFRoZSBhcmd1bWVudCBpcyBpZ25vcmVkLlxuXG4gICAgICAgICAgICAvLyBOT1RFIDIgVGhlIHRvSlNPTiBmdW5jdGlvbiBpcyBpbnRlbnRpb25hbGx5IGdlbmVyaWM7IGl0IGRvZXMgbm90XG4gICAgICAgICAgICAvLyByZXF1aXJlIHRoYXQgaXRzIHRoaXMgdmFsdWUgYmUgYSBEYXRlIG9iamVjdC4gVGhlcmVmb3JlLCBpdCBjYW4gYmVcbiAgICAgICAgICAgIC8vIHRyYW5zZmVycmVkIHRvIG90aGVyIGtpbmRzIG9mIG9iamVjdHMgZm9yIHVzZSBhcyBhIG1ldGhvZC4gSG93ZXZlcixcbiAgICAgICAgICAgIC8vIGl0IGRvZXMgcmVxdWlyZSB0aGF0IGFueSBzdWNoIG9iamVjdCBoYXZlIGEgdG9JU09TdHJpbmcgbWV0aG9kLiBBblxuICAgICAgICAgICAgLy8gb2JqZWN0IGlzIGZyZWUgdG8gdXNlIHRoZSBhcmd1bWVudCBrZXkgdG8gZmlsdGVyIGl0c1xuICAgICAgICAgICAgLy8gc3RyaW5naWZpY2F0aW9uLlxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIEVTNSAxNS45LjQuMlxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjkuNC4yXG4gICAgLy8gYmFzZWQgb24gd29yayBzaGFyZWQgYnkgRGFuaWVsIEZyaWVzZW4gKGRhbnRtYW4pXG4gICAgLy8gaHR0cDovL2dpc3QuZ2l0aHViLmNvbS8zMDMyNDlcbiAgICB2YXIgc3VwcG9ydHNFeHRlbmRlZFllYXJzID0gRGF0ZS5wYXJzZSgnKzAzMzY1OC0wOS0yN1QwMTo0Njo0MC4wMDBaJykgPT09IDFlMTU7XG4gICAgdmFyIGFjY2VwdHNJbnZhbGlkRGF0ZXMgPSAhaXNOYU4oRGF0ZS5wYXJzZSgnMjAxMi0wNC0wNFQyNDowMDowMC41MDBaJykpIHx8ICFpc05hTihEYXRlLnBhcnNlKCcyMDEyLTExLTMxVDIzOjU5OjU5LjAwMFonKSkgfHwgIWlzTmFOKERhdGUucGFyc2UoJzIwMTItMTItMzFUMjM6NTk6NjAuMDAwWicpKTtcbiAgICB2YXIgZG9lc05vdFBhcnNlWTJLTmV3WWVhciA9IGlzTmFOKERhdGUucGFyc2UoJzIwMDAtMDEtMDFUMDA6MDA6MDAuMDAwWicpKTtcbiAgICBpZiAoZG9lc05vdFBhcnNlWTJLTmV3WWVhciB8fCBhY2NlcHRzSW52YWxpZERhdGVzIHx8ICFzdXBwb3J0c0V4dGVuZGVkWWVhcnMpIHtcbiAgICAgICAgLy8gWFhYIGdsb2JhbCBhc3NpZ25tZW50IHdvbid0IHdvcmsgaW4gZW1iZWRkaW5ncyB0aGF0IHVzZVxuICAgICAgICAvLyBhbiBhbHRlcm5hdGUgb2JqZWN0IGZvciB0aGUgY29udGV4dC5cbiAgICAgICAgLyogZ2xvYmFsIERhdGU6IHRydWUgKi9cbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cbiAgICAgICAgdmFyIG1heFNhZmVVbnNpZ25lZDMyQml0ID0gTWF0aC5wb3coMiwgMzEpIC0gMTtcbiAgICAgICAgdmFyIGhhc1NhZmFyaVNpZ25lZEludEJ1ZyA9IGlzQWN0dWFsTmFOKG5ldyBEYXRlKDE5NzAsIDAsIDEsIDAsIDAsIDAsIG1heFNhZmVVbnNpZ25lZDMyQml0ICsgMSkuZ2V0VGltZSgpKTtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8taW1wbGljaXQtZ2xvYmFscyAqL1xuICAgICAgICBEYXRlID0gKGZ1bmN0aW9uIChOYXRpdmVEYXRlKSB7XG4gICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8taW1wbGljaXQtZ2xvYmFscyAqL1xuICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVuZGVmICovXG4gICAgICAgICAgICAvLyBEYXRlLmxlbmd0aCA9PT0gN1xuICAgICAgICAgICAgdmFyIERhdGVTaGltID0gZnVuY3Rpb24gRGF0ZShZLCBNLCBELCBoLCBtLCBzLCBtcykge1xuICAgICAgICAgICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHZhciBkYXRlO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgTmF0aXZlRGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgc2Vjb25kcyA9IHM7XG4gICAgICAgICAgICAgICAgICAgIHZhciBtaWxsaXMgPSBtcztcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc1NhZmFyaVNpZ25lZEludEJ1ZyAmJiBsZW5ndGggPj0gNyAmJiBtcyA+IG1heFNhZmVVbnNpZ25lZDMyQml0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB3b3JrIGFyb3VuZCBhIFNhZmFyaSA4LzkgYnVnIHdoZXJlIGl0IHRyZWF0cyB0aGUgc2Vjb25kcyBhcyBzaWduZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtc1RvU2hpZnQgPSBNYXRoLmZsb29yKG1zIC8gbWF4U2FmZVVuc2lnbmVkMzJCaXQpICogbWF4U2FmZVVuc2lnbmVkMzJCaXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc1RvU2hpZnQgPSBNYXRoLmZsb29yKG1zVG9TaGlmdCAvIDFlMyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWNvbmRzICs9IHNUb1NoaWZ0O1xuICAgICAgICAgICAgICAgICAgICAgICAgbWlsbGlzIC09IHNUb1NoaWZ0ICogMWUzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGRhdGUgPSBsZW5ndGggPT09IDEgJiYgJFN0cmluZyhZKSA9PT0gWSA/IC8vIGlzU3RyaW5nKFkpXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBleHBsaWNpdGx5IHBhc3MgaXQgdGhyb3VnaCBwYXJzZTpcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBOYXRpdmVEYXRlKERhdGVTaGltLnBhcnNlKFkpKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBoYXZlIHRvIG1hbnVhbGx5IG1ha2UgY2FsbHMgZGVwZW5kaW5nIG9uIGFyZ3VtZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBsZW5ndGggaGVyZVxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDcgPyBuZXcgTmF0aXZlRGF0ZShZLCBNLCBELCBoLCBtLCBzZWNvbmRzLCBtaWxsaXMpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSA2ID8gbmV3IE5hdGl2ZURhdGUoWSwgTSwgRCwgaCwgbSwgc2Vjb25kcykgOlxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDUgPyBuZXcgTmF0aXZlRGF0ZShZLCBNLCBELCBoLCBtKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gNCA/IG5ldyBOYXRpdmVEYXRlKFksIE0sIEQsIGgpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSAzID8gbmV3IE5hdGl2ZURhdGUoWSwgTSwgRCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDIgPyBuZXcgTmF0aXZlRGF0ZShZLCBNKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gMSA/IG5ldyBOYXRpdmVEYXRlKFkgaW5zdGFuY2VvZiBOYXRpdmVEYXRlID8gK1kgOiBZKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBOYXRpdmVEYXRlKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0ZSA9IE5hdGl2ZURhdGUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFpc1ByaW1pdGl2ZShkYXRlKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBQcmV2ZW50IG1peHVwcyB3aXRoIHVuZml4ZWQgRGF0ZSBvYmplY3RcbiAgICAgICAgICAgICAgICAgICAgZGVmaW5lUHJvcGVydGllcyhkYXRlLCB7IGNvbnN0cnVjdG9yOiBEYXRlU2hpbSB9LCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyAxNS45LjEuMTUgRGF0ZSBUaW1lIFN0cmluZyBGb3JtYXQuXG4gICAgICAgICAgICB2YXIgaXNvRGF0ZUV4cHJlc3Npb24gPSBuZXcgUmVnRXhwKCdeJyArXG4gICAgICAgICAgICAgICAgJyhcXFxcZHs0fXxbKy1dXFxcXGR7Nn0pJyArIC8vIGZvdXItZGlnaXQgeWVhciBjYXB0dXJlIG9yIHNpZ24gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gNi1kaWdpdCBleHRlbmRlZCB5ZWFyXG4gICAgICAgICAgICAgICAgJyg/Oi0oXFxcXGR7Mn0pJyArIC8vIG9wdGlvbmFsIG1vbnRoIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAnKD86LShcXFxcZHsyfSknICsgLy8gb3B0aW9uYWwgZGF5IGNhcHR1cmVcbiAgICAgICAgICAgICAgICAnKD86JyArIC8vIGNhcHR1cmUgaG91cnM6bWludXRlczpzZWNvbmRzLm1pbGxpc2Vjb25kc1xuICAgICAgICAgICAgICAgICAgICAnVChcXFxcZHsyfSknICsgLy8gaG91cnMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnOihcXFxcZHsyfSknICsgLy8gbWludXRlcyBjYXB0dXJlXG4gICAgICAgICAgICAgICAgICAgICcoPzonICsgLy8gb3B0aW9uYWwgOnNlY29uZHMubWlsbGlzZWNvbmRzXG4gICAgICAgICAgICAgICAgICAgICAgICAnOihcXFxcZHsyfSknICsgLy8gc2Vjb25kcyBjYXB0dXJlXG4gICAgICAgICAgICAgICAgICAgICAgICAnKD86KFxcXFwuXFxcXGR7MSx9KSk/JyArIC8vIG1pbGxpc2Vjb25kcyBjYXB0dXJlXG4gICAgICAgICAgICAgICAgICAgICcpPycgK1xuICAgICAgICAgICAgICAgICcoJyArIC8vIGNhcHR1cmUgVVRDIG9mZnNldCBjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgJ1p8JyArIC8vIFVUQyBjYXB0dXJlXG4gICAgICAgICAgICAgICAgICAgICcoPzonICsgLy8gb2Zmc2V0IHNwZWNpZmllciArLy1ob3VyczptaW51dGVzXG4gICAgICAgICAgICAgICAgICAgICAgICAnKFstK10pJyArIC8vIHNpZ24gY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAgICAgJyhcXFxcZHsyfSknICsgLy8gaG91cnMgb2Zmc2V0IGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgICAgICc6KFxcXFxkezJ9KScgKyAvLyBtaW51dGVzIG9mZnNldCBjYXB0dXJlXG4gICAgICAgICAgICAgICAgICAgICcpJyArXG4gICAgICAgICAgICAgICAgJyk/KT8pPyk/JyArXG4gICAgICAgICAgICAnJCcpO1xuXG4gICAgICAgICAgICB2YXIgbW9udGhzID0gWzAsIDMxLCA1OSwgOTAsIDEyMCwgMTUxLCAxODEsIDIxMiwgMjQzLCAyNzMsIDMwNCwgMzM0LCAzNjVdO1xuXG4gICAgICAgICAgICB2YXIgZGF5RnJvbU1vbnRoID0gZnVuY3Rpb24gZGF5RnJvbU1vbnRoKHllYXIsIG1vbnRoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHQgPSBtb250aCA+IDEgPyAxIDogMDtcbiAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICBtb250aHNbbW9udGhdICtcbiAgICAgICAgICAgICAgICAgICAgTWF0aC5mbG9vcigoeWVhciAtIDE5NjkgKyB0KSAvIDQpIC1cbiAgICAgICAgICAgICAgICAgICAgTWF0aC5mbG9vcigoeWVhciAtIDE5MDEgKyB0KSAvIDEwMCkgK1xuICAgICAgICAgICAgICAgICAgICBNYXRoLmZsb29yKCh5ZWFyIC0gMTYwMSArIHQpIC8gNDAwKSArXG4gICAgICAgICAgICAgICAgICAgIDM2NSAqICh5ZWFyIC0gMTk3MClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdmFyIHRvVVRDID0gZnVuY3Rpb24gdG9VVEModCkge1xuICAgICAgICAgICAgICAgIHZhciBzID0gMDtcbiAgICAgICAgICAgICAgICB2YXIgbXMgPSB0O1xuICAgICAgICAgICAgICAgIGlmIChoYXNTYWZhcmlTaWduZWRJbnRCdWcgJiYgbXMgPiBtYXhTYWZlVW5zaWduZWQzMkJpdCkge1xuICAgICAgICAgICAgICAgICAgICAvLyB3b3JrIGFyb3VuZCBhIFNhZmFyaSA4LzkgYnVnIHdoZXJlIGl0IHRyZWF0cyB0aGUgc2Vjb25kcyBhcyBzaWduZWRcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1zVG9TaGlmdCA9IE1hdGguZmxvb3IobXMgLyBtYXhTYWZlVW5zaWduZWQzMkJpdCkgKiBtYXhTYWZlVW5zaWduZWQzMkJpdDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNUb1NoaWZ0ID0gTWF0aC5mbG9vcihtc1RvU2hpZnQgLyAxZTMpO1xuICAgICAgICAgICAgICAgICAgICBzICs9IHNUb1NoaWZ0O1xuICAgICAgICAgICAgICAgICAgICBtcyAtPSBzVG9TaGlmdCAqIDFlMztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuICROdW1iZXIobmV3IE5hdGl2ZURhdGUoMTk3MCwgMCwgMSwgMCwgMCwgcywgbXMpKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIENvcHkgYW55IGN1c3RvbSBtZXRob2RzIGEgM3JkIHBhcnR5IGxpYnJhcnkgbWF5IGhhdmUgYWRkZWRcbiAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBOYXRpdmVEYXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKG93bnMoTmF0aXZlRGF0ZSwga2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBEYXRlU2hpbVtrZXldID0gTmF0aXZlRGF0ZVtrZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ29weSBcIm5hdGl2ZVwiIG1ldGhvZHMgZXhwbGljaXRseTsgdGhleSBtYXkgYmUgbm9uLWVudW1lcmFibGVcbiAgICAgICAgICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZVNoaW0sIHtcbiAgICAgICAgICAgICAgICBub3c6IE5hdGl2ZURhdGUubm93LFxuICAgICAgICAgICAgICAgIFVUQzogTmF0aXZlRGF0ZS5VVENcbiAgICAgICAgICAgIH0sIHRydWUpO1xuICAgICAgICAgICAgRGF0ZVNoaW0ucHJvdG90eXBlID0gTmF0aXZlRGF0ZS5wcm90b3R5cGU7XG4gICAgICAgICAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGVTaGltLnByb3RvdHlwZSwge1xuICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yOiBEYXRlU2hpbVxuICAgICAgICAgICAgfSwgdHJ1ZSk7XG5cbiAgICAgICAgICAgIC8vIFVwZ3JhZGUgRGF0ZS5wYXJzZSB0byBoYW5kbGUgc2ltcGxpZmllZCBJU08gODYwMSBzdHJpbmdzXG4gICAgICAgICAgICB2YXIgcGFyc2VTaGltID0gZnVuY3Rpb24gcGFyc2Uoc3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgdmFyIG1hdGNoID0gaXNvRGF0ZUV4cHJlc3Npb24uZXhlYyhzdHJpbmcpO1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBwYXJzZSBtb250aHMsIGRheXMsIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBhbmQgbWlsbGlzZWNvbmRzXG4gICAgICAgICAgICAgICAgICAgIC8vIHByb3ZpZGUgZGVmYXVsdCB2YWx1ZXMgaWYgbmVjZXNzYXJ5XG4gICAgICAgICAgICAgICAgICAgIC8vIHBhcnNlIHRoZSBVVEMgb2Zmc2V0IGNvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgICB2YXIgeWVhciA9ICROdW1iZXIobWF0Y2hbMV0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgbW9udGggPSAkTnVtYmVyKG1hdGNoWzJdIHx8IDEpIC0gMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRheSA9ICROdW1iZXIobWF0Y2hbM10gfHwgMSkgLSAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgaG91ciA9ICROdW1iZXIobWF0Y2hbNF0gfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW51dGUgPSAkTnVtYmVyKG1hdGNoWzVdIHx8IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kID0gJE51bWJlcihtYXRjaFs2XSB8fCAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbGxpc2Vjb25kID0gTWF0aC5mbG9vcigkTnVtYmVyKG1hdGNoWzddIHx8IDApICogMTAwMCksXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHRpbWUgem9uZSBpcyBtaXNzZWQsIGxvY2FsIG9mZnNldCBzaG91bGQgYmUgdXNlZFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gKEVTIDUuMSBidWcpXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9idWdzLmVjbWFzY3JpcHQub3JnL3Nob3dfYnVnLmNnaT9pZD0xMTJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzTG9jYWxUaW1lID0gQm9vbGVhbihtYXRjaFs0XSAmJiAhbWF0Y2hbOF0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2lnbk9mZnNldCA9IG1hdGNoWzldID09PSAnLScgPyAxIDogLTEsXG4gICAgICAgICAgICAgICAgICAgICAgICBob3VyT2Zmc2V0ID0gJE51bWJlcihtYXRjaFsxMF0gfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW51dGVPZmZzZXQgPSAkTnVtYmVyKG1hdGNoWzExXSB8fCAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc01pbnV0ZXNPclNlY29uZHNPck1pbGxpc2Vjb25kcyA9IG1pbnV0ZSA+IDAgfHwgc2Vjb25kID4gMCB8fCBtaWxsaXNlY29uZCA+IDA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIgPCAoaGFzTWludXRlc09yU2Vjb25kc09yTWlsbGlzZWNvbmRzID8gMjQgOiAyNSkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZSA8IDYwICYmIHNlY29uZCA8IDYwICYmIG1pbGxpc2Vjb25kIDwgMTAwMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgbW9udGggPiAtMSAmJiBtb250aCA8IDEyICYmIGhvdXJPZmZzZXQgPCAyNCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlT2Zmc2V0IDwgNjAgJiYgLy8gZGV0ZWN0IGludmFsaWQgb2Zmc2V0c1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF5ID4gLTEgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIGRheSA8IChkYXlGcm9tTW9udGgoeWVhciwgbW9udGggKyAxKSAtIGRheUZyb21Nb250aCh5ZWFyLCBtb250aCkpXG4gICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkYXlGcm9tTW9udGgoeWVhciwgbW9udGgpICsgZGF5KSAqIDI0ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2Zmc2V0ICogc2lnbk9mZnNldFxuICAgICAgICAgICAgICAgICAgICAgICAgKSAqIDYwO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZXN1bHQgKyBtaW51dGUgKyBtaW51dGVPZmZzZXQgKiBzaWduT2Zmc2V0KSAqIDYwICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWNvbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICkgKiAxMDAwICsgbWlsbGlzZWNvbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0b1VUQyhyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKC04LjY0ZTE1IDw9IHJlc3VsdCAmJiByZXN1bHQgPD0gOC42NGUxNSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIE5hdGl2ZURhdGUucGFyc2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGVTaGltLCB7IHBhcnNlOiBwYXJzZVNoaW0gfSk7XG5cbiAgICAgICAgICAgIHJldHVybiBEYXRlU2hpbTtcbiAgICAgICAgfShEYXRlKSk7XG4gICAgICAgIC8qIGdsb2JhbCBEYXRlOiBmYWxzZSAqL1xuICAgIH1cblxuICAgIC8vIEVTNSAxNS45LjQuNFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjkuNC40XG4gICAgaWYgKCFEYXRlLm5vdykge1xuICAgICAgICBEYXRlLm5vdyA9IGZ1bmN0aW9uIG5vdygpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvL1xuICAgIC8vIE51bWJlclxuICAgIC8vID09PT09PVxuICAgIC8vXG5cbiAgICAvLyBFUzUuMSAxNS43LjQuNVxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjcuNC41XG4gICAgdmFyIGhhc1RvRml4ZWRCdWdzID0gTnVtYmVyUHJvdG90eXBlLnRvRml4ZWQgJiYgKFxuICAgICAgKDAuMDAwMDgpLnRvRml4ZWQoMykgIT09ICcwLjAwMCcgfHxcbiAgICAgICgwLjkpLnRvRml4ZWQoMCkgIT09ICcxJyB8fFxuICAgICAgKDEuMjU1KS50b0ZpeGVkKDIpICE9PSAnMS4yNScgfHxcbiAgICAgICgxMDAwMDAwMDAwMDAwMDAwMTI4KS50b0ZpeGVkKDApICE9PSAnMTAwMDAwMDAwMDAwMDAwMDEyOCdcbiAgICApO1xuXG4gICAgdmFyIHRvRml4ZWRIZWxwZXJzID0ge1xuICAgICAgICBiYXNlOiAxZTcsXG4gICAgICAgIHNpemU6IDYsXG4gICAgICAgIGRhdGE6IFswLCAwLCAwLCAwLCAwLCAwXSxcbiAgICAgICAgbXVsdGlwbHk6IGZ1bmN0aW9uIG11bHRpcGx5KG4sIGMpIHtcbiAgICAgICAgICAgIHZhciBpID0gLTE7XG4gICAgICAgICAgICB2YXIgYzIgPSBjO1xuICAgICAgICAgICAgd2hpbGUgKCsraSA8IHRvRml4ZWRIZWxwZXJzLnNpemUpIHtcbiAgICAgICAgICAgICAgICBjMiArPSBuICogdG9GaXhlZEhlbHBlcnMuZGF0YVtpXTtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5kYXRhW2ldID0gYzIgJSB0b0ZpeGVkSGVscGVycy5iYXNlO1xuICAgICAgICAgICAgICAgIGMyID0gTWF0aC5mbG9vcihjMiAvIHRvRml4ZWRIZWxwZXJzLmJhc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBkaXZpZGU6IGZ1bmN0aW9uIGRpdmlkZShuKSB7XG4gICAgICAgICAgICB2YXIgaSA9IHRvRml4ZWRIZWxwZXJzLnNpemU7XG4gICAgICAgICAgICB2YXIgYyA9IDA7XG4gICAgICAgICAgICB3aGlsZSAoLS1pID49IDApIHtcbiAgICAgICAgICAgICAgICBjICs9IHRvRml4ZWRIZWxwZXJzLmRhdGFbaV07XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGF0YVtpXSA9IE1hdGguZmxvb3IoYyAvIG4pO1xuICAgICAgICAgICAgICAgIGMgPSAoYyAlIG4pICogdG9GaXhlZEhlbHBlcnMuYmFzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgbnVtVG9TdHJpbmc6IGZ1bmN0aW9uIG51bVRvU3RyaW5nKCkge1xuICAgICAgICAgICAgdmFyIGkgPSB0b0ZpeGVkSGVscGVycy5zaXplO1xuICAgICAgICAgICAgdmFyIHMgPSAnJztcbiAgICAgICAgICAgIHdoaWxlICgtLWkgPj0gMCkge1xuICAgICAgICAgICAgICAgIGlmIChzICE9PSAnJyB8fCBpID09PSAwIHx8IHRvRml4ZWRIZWxwZXJzLmRhdGFbaV0gIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSAkU3RyaW5nKHRvRml4ZWRIZWxwZXJzLmRhdGFbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAocyA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSB0O1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcyArPSBzdHJTbGljZSgnMDAwMDAwMCcsIDAsIDcgLSB0Lmxlbmd0aCkgKyB0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHM7XG4gICAgICAgIH0sXG4gICAgICAgIHBvdzogZnVuY3Rpb24gcG93KHgsIG4sIGFjYykge1xuICAgICAgICAgICAgcmV0dXJuIChuID09PSAwID8gYWNjIDogKG4gJSAyID09PSAxID8gcG93KHgsIG4gLSAxLCBhY2MgKiB4KSA6IHBvdyh4ICogeCwgbiAvIDIsIGFjYykpKTtcbiAgICAgICAgfSxcbiAgICAgICAgbG9nOiBmdW5jdGlvbiBsb2coeCkge1xuICAgICAgICAgICAgdmFyIG4gPSAwO1xuICAgICAgICAgICAgdmFyIHgyID0geDtcbiAgICAgICAgICAgIHdoaWxlICh4MiA+PSA0MDk2KSB7XG4gICAgICAgICAgICAgICAgbiArPSAxMjtcbiAgICAgICAgICAgICAgICB4MiAvPSA0MDk2O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgd2hpbGUgKHgyID49IDIpIHtcbiAgICAgICAgICAgICAgICBuICs9IDE7XG4gICAgICAgICAgICAgICAgeDIgLz0gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHZhciB0b0ZpeGVkU2hpbSA9IGZ1bmN0aW9uIHRvRml4ZWQoZnJhY3Rpb25EaWdpdHMpIHtcbiAgICAgICAgdmFyIGYsIHgsIHMsIG0sIGUsIHosIGosIGs7XG5cbiAgICAgICAgLy8gVGVzdCBmb3IgTmFOIGFuZCByb3VuZCBmcmFjdGlvbkRpZ2l0cyBkb3duXG4gICAgICAgIGYgPSAkTnVtYmVyKGZyYWN0aW9uRGlnaXRzKTtcbiAgICAgICAgZiA9IGlzQWN0dWFsTmFOKGYpID8gMCA6IE1hdGguZmxvb3IoZik7XG5cbiAgICAgICAgaWYgKGYgPCAwIHx8IGYgPiAyMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ051bWJlci50b0ZpeGVkIGNhbGxlZCB3aXRoIGludmFsaWQgbnVtYmVyIG9mIGRlY2ltYWxzJyk7XG4gICAgICAgIH1cblxuICAgICAgICB4ID0gJE51bWJlcih0aGlzKTtcblxuICAgICAgICBpZiAoaXNBY3R1YWxOYU4oeCkpIHtcbiAgICAgICAgICAgIHJldHVybiAnTmFOJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIGl0IGlzIHRvbyBiaWcgb3Igc21hbGwsIHJldHVybiB0aGUgc3RyaW5nIHZhbHVlIG9mIHRoZSBudW1iZXJcbiAgICAgICAgaWYgKHggPD0gLTFlMjEgfHwgeCA+PSAxZTIxKSB7XG4gICAgICAgICAgICByZXR1cm4gJFN0cmluZyh4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHMgPSAnJztcblxuICAgICAgICBpZiAoeCA8IDApIHtcbiAgICAgICAgICAgIHMgPSAnLSc7XG4gICAgICAgICAgICB4ID0gLXg7XG4gICAgICAgIH1cblxuICAgICAgICBtID0gJzAnO1xuXG4gICAgICAgIGlmICh4ID4gMWUtMjEpIHtcbiAgICAgICAgICAgIC8vIDFlLTIxIDwgeCA8IDFlMjFcbiAgICAgICAgICAgIC8vIC03MCA8IGxvZzIoeCkgPCA3MFxuICAgICAgICAgICAgZSA9IHRvRml4ZWRIZWxwZXJzLmxvZyh4ICogdG9GaXhlZEhlbHBlcnMucG93KDIsIDY5LCAxKSkgLSA2OTtcbiAgICAgICAgICAgIHogPSAoZSA8IDAgPyB4ICogdG9GaXhlZEhlbHBlcnMucG93KDIsIC1lLCAxKSA6IHggLyB0b0ZpeGVkSGVscGVycy5wb3coMiwgZSwgMSkpO1xuICAgICAgICAgICAgeiAqPSAweDEwMDAwMDAwMDAwMDAwOyAvLyBNYXRoLnBvdygyLCA1Mik7XG4gICAgICAgICAgICBlID0gNTIgLSBlO1xuXG4gICAgICAgICAgICAvLyAtMTggPCBlIDwgMTIyXG4gICAgICAgICAgICAvLyB4ID0geiAvIDIgXiBlXG4gICAgICAgICAgICBpZiAoZSA+IDApIHtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSgwLCB6KTtcbiAgICAgICAgICAgICAgICBqID0gZjtcblxuICAgICAgICAgICAgICAgIHdoaWxlIChqID49IDcpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMubXVsdGlwbHkoMWU3LCAwKTtcbiAgICAgICAgICAgICAgICAgICAgaiAtPSA3O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLm11bHRpcGx5KHRvRml4ZWRIZWxwZXJzLnBvdygxMCwgaiwgMSksIDApO1xuICAgICAgICAgICAgICAgIGogPSBlIC0gMTtcblxuICAgICAgICAgICAgICAgIHdoaWxlIChqID49IDIzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLmRpdmlkZSgxIDw8IDIzKTtcbiAgICAgICAgICAgICAgICAgICAgaiAtPSAyMztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5kaXZpZGUoMSA8PCBqKTtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSgxLCAxKTtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5kaXZpZGUoMik7XG4gICAgICAgICAgICAgICAgbSA9IHRvRml4ZWRIZWxwZXJzLm51bVRvU3RyaW5nKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLm11bHRpcGx5KDAsIHopO1xuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLm11bHRpcGx5KDEgPDwgKC1lKSwgMCk7XG4gICAgICAgICAgICAgICAgbSA9IHRvRml4ZWRIZWxwZXJzLm51bVRvU3RyaW5nKCkgKyBzdHJTbGljZSgnMC4wMDAwMDAwMDAwMDAwMDAwMDAwMCcsIDIsIDIgKyBmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmID4gMCkge1xuICAgICAgICAgICAgayA9IG0ubGVuZ3RoO1xuXG4gICAgICAgICAgICBpZiAoayA8PSBmKSB7XG4gICAgICAgICAgICAgICAgbSA9IHMgKyBzdHJTbGljZSgnMC4wMDAwMDAwMDAwMDAwMDAwMDAwJywgMCwgZiAtIGsgKyAyKSArIG07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG0gPSBzICsgc3RyU2xpY2UobSwgMCwgayAtIGYpICsgJy4nICsgc3RyU2xpY2UobSwgayAtIGYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbSA9IHMgKyBtO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG07XG4gICAgfTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKE51bWJlclByb3RvdHlwZSwgeyB0b0ZpeGVkOiB0b0ZpeGVkU2hpbSB9LCBoYXNUb0ZpeGVkQnVncyk7XG5cbiAgICB2YXIgaGFzVG9QcmVjaXNpb25VbmRlZmluZWRCdWcgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIDEuMC50b1ByZWNpc2lvbih1bmRlZmluZWQpID09PSAnMSc7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfSgpKTtcbiAgICB2YXIgb3JpZ2luYWxUb1ByZWNpc2lvbiA9IE51bWJlclByb3RvdHlwZS50b1ByZWNpc2lvbjtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKE51bWJlclByb3RvdHlwZSwge1xuICAgICAgICB0b1ByZWNpc2lvbjogZnVuY3Rpb24gdG9QcmVjaXNpb24ocHJlY2lzaW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIHByZWNpc2lvbiA9PT0gJ3VuZGVmaW5lZCcgPyBvcmlnaW5hbFRvUHJlY2lzaW9uLmNhbGwodGhpcykgOiBvcmlnaW5hbFRvUHJlY2lzaW9uLmNhbGwodGhpcywgcHJlY2lzaW9uKTtcbiAgICAgICAgfVxuICAgIH0sIGhhc1RvUHJlY2lzaW9uVW5kZWZpbmVkQnVnKTtcblxuICAgIC8vXG4gICAgLy8gU3RyaW5nXG4gICAgLy8gPT09PT09XG4gICAgLy9cblxuICAgIC8vIEVTNSAxNS41LjQuMTRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS41LjQuMTRcblxuICAgIC8vIFtidWdmaXgsIElFIGx0IDksIGZpcmVmb3ggNCwgS29ucXVlcm9yLCBPcGVyYSwgb2JzY3VyZSBicm93c2Vyc11cbiAgICAvLyBNYW55IGJyb3dzZXJzIGRvIG5vdCBzcGxpdCBwcm9wZXJseSB3aXRoIHJlZ3VsYXIgZXhwcmVzc2lvbnMgb3IgdGhleVxuICAgIC8vIGRvIG5vdCBwZXJmb3JtIHRoZSBzcGxpdCBjb3JyZWN0bHkgdW5kZXIgb2JzY3VyZSBjb25kaXRpb25zLlxuICAgIC8vIFNlZSBodHRwOi8vYmxvZy5zdGV2ZW5sZXZpdGhhbi5jb20vYXJjaGl2ZXMvY3Jvc3MtYnJvd3Nlci1zcGxpdFxuICAgIC8vIEkndmUgdGVzdGVkIGluIG1hbnkgYnJvd3NlcnMgYW5kIHRoaXMgc2VlbXMgdG8gY292ZXIgdGhlIGRldmlhbnQgb25lczpcbiAgICAvLyAgICAnYWInLnNwbGl0KC8oPzphYikqLykgc2hvdWxkIGJlIFtcIlwiLCBcIlwiXSwgbm90IFtcIlwiXVxuICAgIC8vICAgICcuJy5zcGxpdCgvKC4/KSguPykvKSBzaG91bGQgYmUgW1wiXCIsIFwiLlwiLCBcIlwiLCBcIlwiXSwgbm90IFtcIlwiLCBcIlwiXVxuICAgIC8vICAgICd0ZXNzdCcuc3BsaXQoLyhzKSovKSBzaG91bGQgYmUgW1widFwiLCB1bmRlZmluZWQsIFwiZVwiLCBcInNcIiwgXCJ0XCJdLCBub3RcbiAgICAvLyAgICAgICBbdW5kZWZpbmVkLCBcInRcIiwgdW5kZWZpbmVkLCBcImVcIiwgLi4uXVxuICAgIC8vICAgICcnLnNwbGl0KC8uPy8pIHNob3VsZCBiZSBbXSwgbm90IFtcIlwiXVxuICAgIC8vICAgICcuJy5zcGxpdCgvKCkoKS8pIHNob3VsZCBiZSBbXCIuXCJdLCBub3QgW1wiXCIsIFwiXCIsIFwiLlwiXVxuXG4gICAgaWYgKFxuICAgICAgICAnYWInLnNwbGl0KC8oPzphYikqLykubGVuZ3RoICE9PSAyIHx8XG4gICAgICAgICcuJy5zcGxpdCgvKC4/KSguPykvKS5sZW5ndGggIT09IDQgfHxcbiAgICAgICAgJ3Rlc3N0Jy5zcGxpdCgvKHMpKi8pWzFdID09PSAndCcgfHxcbiAgICAgICAgJ3Rlc3QnLnNwbGl0KC8oPzopLywgLTEpLmxlbmd0aCAhPT0gNCB8fFxuICAgICAgICAnJy5zcGxpdCgvLj8vKS5sZW5ndGggfHxcbiAgICAgICAgJy4nLnNwbGl0KC8oKSgpLykubGVuZ3RoID4gMVxuICAgICkge1xuICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGNvbXBsaWFudEV4ZWNOcGNnID0gdHlwZW9mICgvKCk/Py8pLmV4ZWMoJycpWzFdID09PSAndW5kZWZpbmVkJzsgLy8gTlBDRzogbm9ucGFydGljaXBhdGluZyBjYXB0dXJpbmcgZ3JvdXBcbiAgICAgICAgICAgIHZhciBtYXhTYWZlMzJCaXRJbnQgPSBNYXRoLnBvdygyLCAzMikgLSAxO1xuXG4gICAgICAgICAgICBTdHJpbmdQcm90b3R5cGUuc3BsaXQgPSBmdW5jdGlvbiAoc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgICAgICAgICAgICAgIHZhciBzdHJpbmcgPSBTdHJpbmcodGhpcyk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzZXBhcmF0b3IgPT09ICd1bmRlZmluZWQnICYmIGxpbWl0ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBJZiBgc2VwYXJhdG9yYCBpcyBub3QgYSByZWdleCwgdXNlIG5hdGl2ZSBzcGxpdFxuICAgICAgICAgICAgICAgIGlmICghaXNSZWdleChzZXBhcmF0b3IpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHJTcGxpdCh0aGlzLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB2YXIgb3V0cHV0ID0gW107XG4gICAgICAgICAgICAgICAgdmFyIGZsYWdzID0gKHNlcGFyYXRvci5pZ25vcmVDYXNlID8gJ2knIDogJycpICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLm11bHRpbGluZSA/ICdtJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlcGFyYXRvci51bmljb2RlID8gJ3UnIDogJycpICsgLy8gaW4gRVM2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlcGFyYXRvci5zdGlja3kgPyAneScgOiAnJyksIC8vIEZpcmVmb3ggMysgYW5kIEVTNlxuICAgICAgICAgICAgICAgICAgICBsYXN0TGFzdEluZGV4ID0gMCxcbiAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSBgZ2xvYmFsYCBhbmQgYXZvaWQgYGxhc3RJbmRleGAgaXNzdWVzIGJ5IHdvcmtpbmcgd2l0aCBhIGNvcHlcbiAgICAgICAgICAgICAgICAgICAgc2VwYXJhdG9yMiwgbWF0Y2gsIGxhc3RJbmRleCwgbGFzdExlbmd0aDtcbiAgICAgICAgICAgICAgICB2YXIgc2VwYXJhdG9yQ29weSA9IG5ldyBSZWdFeHAoc2VwYXJhdG9yLnNvdXJjZSwgZmxhZ3MgKyAnZycpO1xuICAgICAgICAgICAgICAgIGlmICghY29tcGxpYW50RXhlY05wY2cpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRG9lc24ndCBuZWVkIGZsYWdzIGd5LCBidXQgdGhleSBkb24ndCBodXJ0XG4gICAgICAgICAgICAgICAgICAgIHNlcGFyYXRvcjIgPSBuZXcgUmVnRXhwKCdeJyArIHNlcGFyYXRvckNvcHkuc291cmNlICsgJyQoPyFcXFxccyknLCBmbGFncyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8qIFZhbHVlcyBmb3IgYGxpbWl0YCwgcGVyIHRoZSBzcGVjOlxuICAgICAgICAgICAgICAgICAqIElmIHVuZGVmaW5lZDogNDI5NDk2NzI5NSAvLyBtYXhTYWZlMzJCaXRJbnRcbiAgICAgICAgICAgICAgICAgKiBJZiAwLCBJbmZpbml0eSwgb3IgTmFOOiAwXG4gICAgICAgICAgICAgICAgICogSWYgcG9zaXRpdmUgbnVtYmVyOiBsaW1pdCA9IE1hdGguZmxvb3IobGltaXQpOyBpZiAobGltaXQgPiA0Mjk0OTY3Mjk1KSBsaW1pdCAtPSA0Mjk0OTY3Mjk2O1xuICAgICAgICAgICAgICAgICAqIElmIG5lZ2F0aXZlIG51bWJlcjogNDI5NDk2NzI5NiAtIE1hdGguZmxvb3IoTWF0aC5hYnMobGltaXQpKVxuICAgICAgICAgICAgICAgICAqIElmIG90aGVyOiBUeXBlLWNvbnZlcnQsIHRoZW4gdXNlIHRoZSBhYm92ZSBydWxlc1xuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIHZhciBzcGxpdExpbWl0ID0gdHlwZW9mIGxpbWl0ID09PSAndW5kZWZpbmVkJyA/IG1heFNhZmUzMkJpdEludCA6IEVTLlRvVWludDMyKGxpbWl0KTtcbiAgICAgICAgICAgICAgICBtYXRjaCA9IHNlcGFyYXRvckNvcHkuZXhlYyhzdHJpbmcpO1xuICAgICAgICAgICAgICAgIHdoaWxlIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBgc2VwYXJhdG9yQ29weS5sYXN0SW5kZXhgIGlzIG5vdCByZWxpYWJsZSBjcm9zcy1icm93c2VyXG4gICAgICAgICAgICAgICAgICAgIGxhc3RJbmRleCA9IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBpZiAobGFzdEluZGV4ID4gbGFzdExhc3RJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwob3V0cHV0LCBzdHJTbGljZShzdHJpbmcsIGxhc3RMYXN0SW5kZXgsIG1hdGNoLmluZGV4KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggYnJvd3NlcnMgd2hvc2UgYGV4ZWNgIG1ldGhvZHMgZG9uJ3QgY29uc2lzdGVudGx5IHJldHVybiBgdW5kZWZpbmVkYCBmb3JcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vbnBhcnRpY2lwYXRpbmcgY2FwdHVyaW5nIGdyb3Vwc1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb21wbGlhbnRFeGVjTnBjZyAmJiBtYXRjaC5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tbG9vcC1mdW5jICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hbMF0ucmVwbGFjZShzZXBhcmF0b3IyLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aCAtIDI7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbaV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hbaV0gPSB2b2lkIDA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLWxvb3AtZnVuYyAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoLmxlbmd0aCA+IDEgJiYgbWF0Y2guaW5kZXggPCBzdHJpbmcubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlfcHVzaC5hcHBseShvdXRwdXQsIGFycmF5U2xpY2UobWF0Y2gsIDEpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RMZW5ndGggPSBtYXRjaFswXS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0TGFzdEluZGV4ID0gbGFzdEluZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG91dHB1dC5sZW5ndGggPj0gc3BsaXRMaW1pdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXBhcmF0b3JDb3B5Lmxhc3RJbmRleCA9PT0gbWF0Y2guaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlcGFyYXRvckNvcHkubGFzdEluZGV4Kys7IC8vIEF2b2lkIGFuIGluZmluaXRlIGxvb3BcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IHNlcGFyYXRvckNvcHkuZXhlYyhzdHJpbmcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobGFzdExhc3RJbmRleCA9PT0gc3RyaW5nLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAobGFzdExlbmd0aCB8fCAhc2VwYXJhdG9yQ29weS50ZXN0KCcnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwob3V0cHV0LCAnJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbChvdXRwdXQsIHN0clNsaWNlKHN0cmluZywgbGFzdExhc3RJbmRleCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0cHV0Lmxlbmd0aCA+IHNwbGl0TGltaXQgPyBhcnJheVNsaWNlKG91dHB1dCwgMCwgc3BsaXRMaW1pdCkgOiBvdXRwdXQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KCkpO1xuXG4gICAgLy8gW2J1Z2ZpeCwgY2hyb21lXVxuICAgIC8vIElmIHNlcGFyYXRvciBpcyB1bmRlZmluZWQsIHRoZW4gdGhlIHJlc3VsdCBhcnJheSBjb250YWlucyBqdXN0IG9uZSBTdHJpbmcsXG4gICAgLy8gd2hpY2ggaXMgdGhlIHRoaXMgdmFsdWUgKGNvbnZlcnRlZCB0byBhIFN0cmluZykuIElmIGxpbWl0IGlzIG5vdCB1bmRlZmluZWQsXG4gICAgLy8gdGhlbiB0aGUgb3V0cHV0IGFycmF5IGlzIHRydW5jYXRlZCBzbyB0aGF0IGl0IGNvbnRhaW5zIG5vIG1vcmUgdGhhbiBsaW1pdFxuICAgIC8vIGVsZW1lbnRzLlxuICAgIC8vIFwiMFwiLnNwbGl0KHVuZGVmaW5lZCwgMCkgLT4gW11cbiAgICB9IGVsc2UgaWYgKCcwJy5zcGxpdCh2b2lkIDAsIDApLmxlbmd0aCkge1xuICAgICAgICBTdHJpbmdQcm90b3R5cGUuc3BsaXQgPSBmdW5jdGlvbiBzcGxpdChzZXBhcmF0b3IsIGxpbWl0KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHNlcGFyYXRvciA9PT0gJ3VuZGVmaW5lZCcgJiYgbGltaXQgPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3RyU3BsaXQodGhpcywgc2VwYXJhdG9yLCBsaW1pdCk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHN0cl9yZXBsYWNlID0gU3RyaW5nUHJvdG90eXBlLnJlcGxhY2U7XG4gICAgdmFyIHJlcGxhY2VSZXBvcnRzR3JvdXBzQ29ycmVjdGx5ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGdyb3VwcyA9IFtdO1xuICAgICAgICAneCcucmVwbGFjZSgveCguKT8vZywgZnVuY3Rpb24gKG1hdGNoLCBncm91cCkge1xuICAgICAgICAgICAgcHVzaENhbGwoZ3JvdXBzLCBncm91cCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZ3JvdXBzLmxlbmd0aCA9PT0gMSAmJiB0eXBlb2YgZ3JvdXBzWzBdID09PSAndW5kZWZpbmVkJztcbiAgICB9KCkpO1xuXG4gICAgaWYgKCFyZXBsYWNlUmVwb3J0c0dyb3Vwc0NvcnJlY3RseSkge1xuICAgICAgICBTdHJpbmdQcm90b3R5cGUucmVwbGFjZSA9IGZ1bmN0aW9uIHJlcGxhY2Uoc2VhcmNoVmFsdWUsIHJlcGxhY2VWYWx1ZSkge1xuICAgICAgICAgICAgdmFyIGlzRm4gPSBpc0NhbGxhYmxlKHJlcGxhY2VWYWx1ZSk7XG4gICAgICAgICAgICB2YXIgaGFzQ2FwdHVyaW5nR3JvdXBzID0gaXNSZWdleChzZWFyY2hWYWx1ZSkgJiYgKC9cXClbKj9dLykudGVzdChzZWFyY2hWYWx1ZS5zb3VyY2UpO1xuICAgICAgICAgICAgaWYgKCFpc0ZuIHx8ICFoYXNDYXB0dXJpbmdHcm91cHMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UuY2FsbCh0aGlzLCBzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIHdyYXBwZWRSZXBsYWNlVmFsdWUgPSBmdW5jdGlvbiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIHZhciBvcmlnaW5hbExhc3RJbmRleCA9IHNlYXJjaFZhbHVlLmxhc3RJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgc2VhcmNoVmFsdWUubGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBzZWFyY2hWYWx1ZS5leGVjKG1hdGNoKSB8fCBbXTtcbiAgICAgICAgICAgICAgICAgICAgc2VhcmNoVmFsdWUubGFzdEluZGV4ID0gb3JpZ2luYWxMYXN0SW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKGFyZ3MsIGFyZ3VtZW50c1tsZW5ndGggLSAyXSwgYXJndW1lbnRzW2xlbmd0aCAtIDFdKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcGxhY2VWYWx1ZS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJldHVybiBzdHJfcmVwbGFjZS5jYWxsKHRoaXMsIHNlYXJjaFZhbHVlLCB3cmFwcGVkUmVwbGFjZVZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBFQ01BLTI2MiwgM3JkIEIuMi4zXG4gICAgLy8gTm90IGFuIEVDTUFTY3JpcHQgc3RhbmRhcmQsIGFsdGhvdWdoIEVDTUFTY3JpcHQgM3JkIEVkaXRpb24gaGFzIGFcbiAgICAvLyBub24tbm9ybWF0aXZlIHNlY3Rpb24gc3VnZ2VzdGluZyB1bmlmb3JtIHNlbWFudGljcyBhbmQgaXQgc2hvdWxkIGJlXG4gICAgLy8gbm9ybWFsaXplZCBhY3Jvc3MgYWxsIGJyb3dzZXJzXG4gICAgLy8gW2J1Z2ZpeCwgSUUgbHQgOV0gSUUgPCA5IHN1YnN0cigpIHdpdGggbmVnYXRpdmUgdmFsdWUgbm90IHdvcmtpbmcgaW4gSUVcbiAgICB2YXIgc3RyaW5nX3N1YnN0ciA9IFN0cmluZ1Byb3RvdHlwZS5zdWJzdHI7XG4gICAgdmFyIGhhc05lZ2F0aXZlU3Vic3RyQnVnID0gJycuc3Vic3RyICYmICcwYicuc3Vic3RyKC0xKSAhPT0gJ2InO1xuICAgIGRlZmluZVByb3BlcnRpZXMoU3RyaW5nUHJvdG90eXBlLCB7XG4gICAgICAgIHN1YnN0cjogZnVuY3Rpb24gc3Vic3RyKHN0YXJ0LCBsZW5ndGgpIHtcbiAgICAgICAgICAgIHZhciBub3JtYWxpemVkU3RhcnQgPSBzdGFydDtcbiAgICAgICAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgICAgICAgICBub3JtYWxpemVkU3RhcnQgPSBtYXgodGhpcy5sZW5ndGggKyBzdGFydCwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3RyaW5nX3N1YnN0ci5jYWxsKHRoaXMsIG5vcm1hbGl6ZWRTdGFydCwgbGVuZ3RoKTtcbiAgICAgICAgfVxuICAgIH0sIGhhc05lZ2F0aXZlU3Vic3RyQnVnKTtcblxuICAgIC8vIEVTNSAxNS41LjQuMjBcbiAgICAvLyB3aGl0ZXNwYWNlIGZyb206IGh0dHA6Ly9lczUuZ2l0aHViLmlvLyN4MTUuNS40LjIwXG4gICAgdmFyIHdzID0gJ1xceDA5XFx4MEFcXHgwQlxceDBDXFx4MERcXHgyMFxceEEwXFx1MTY4MFxcdTE4MEVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzJyArXG4gICAgICAgICdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOCcgK1xuICAgICAgICAnXFx1MjAyOVxcdUZFRkYnO1xuICAgIHZhciB6ZXJvV2lkdGggPSAnXFx1MjAwYic7XG4gICAgdmFyIHdzUmVnZXhDaGFycyA9ICdbJyArIHdzICsgJ10nO1xuICAgIHZhciB0cmltQmVnaW5SZWdleHAgPSBuZXcgUmVnRXhwKCdeJyArIHdzUmVnZXhDaGFycyArIHdzUmVnZXhDaGFycyArICcqJyk7XG4gICAgdmFyIHRyaW1FbmRSZWdleHAgPSBuZXcgUmVnRXhwKHdzUmVnZXhDaGFycyArIHdzUmVnZXhDaGFycyArICcqJCcpO1xuICAgIHZhciBoYXNUcmltV2hpdGVzcGFjZUJ1ZyA9IFN0cmluZ1Byb3RvdHlwZS50cmltICYmICh3cy50cmltKCkgfHwgIXplcm9XaWR0aC50cmltKCkpO1xuICAgIGRlZmluZVByb3BlcnRpZXMoU3RyaW5nUHJvdG90eXBlLCB7XG4gICAgICAgIC8vIGh0dHA6Ly9ibG9nLnN0ZXZlbmxldml0aGFuLmNvbS9hcmNoaXZlcy9mYXN0ZXItdHJpbS1qYXZhc2NyaXB0XG4gICAgICAgIC8vIGh0dHA6Ly9wZXJmZWN0aW9ua2lsbHMuY29tL3doaXRlc3BhY2UtZGV2aWF0aW9ucy9cbiAgICAgICAgdHJpbTogZnVuY3Rpb24gdHJpbSgpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJjYW4ndCBjb252ZXJ0IFwiICsgdGhpcyArICcgdG8gb2JqZWN0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gJFN0cmluZyh0aGlzKS5yZXBsYWNlKHRyaW1CZWdpblJlZ2V4cCwgJycpLnJlcGxhY2UodHJpbUVuZFJlZ2V4cCwgJycpO1xuICAgICAgICB9XG4gICAgfSwgaGFzVHJpbVdoaXRlc3BhY2VCdWcpO1xuICAgIHZhciB0cmltID0gY2FsbC5iaW5kKFN0cmluZy5wcm90b3R5cGUudHJpbSk7XG5cbiAgICB2YXIgaGFzTGFzdEluZGV4QnVnID0gU3RyaW5nUHJvdG90eXBlLmxhc3RJbmRleE9mICYmICdhYmPjgYLjgYQnLmxhc3RJbmRleE9mKCfjgYLjgYQnLCAyKSAhPT0gLTE7XG4gICAgZGVmaW5lUHJvcGVydGllcyhTdHJpbmdQcm90b3R5cGUsIHtcbiAgICAgICAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaFN0cmluZykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzID09PSAndW5kZWZpbmVkJyB8fCB0aGlzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNhbid0IGNvbnZlcnQgXCIgKyB0aGlzICsgJyB0byBvYmplY3QnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBTID0gJFN0cmluZyh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWFyY2hTdHIgPSAkU3RyaW5nKHNlYXJjaFN0cmluZyk7XG4gICAgICAgICAgICB2YXIgbnVtUG9zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyAkTnVtYmVyKGFyZ3VtZW50c1sxXSkgOiBOYU47XG4gICAgICAgICAgICB2YXIgcG9zID0gaXNBY3R1YWxOYU4obnVtUG9zKSA/IEluZmluaXR5IDogRVMuVG9JbnRlZ2VyKG51bVBvcyk7XG4gICAgICAgICAgICB2YXIgc3RhcnQgPSBtaW4obWF4KHBvcywgMCksIFMubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBzZWFyY2hMZW4gPSBzZWFyY2hTdHIubGVuZ3RoO1xuICAgICAgICAgICAgdmFyIGsgPSBzdGFydCArIHNlYXJjaExlbjtcbiAgICAgICAgICAgIHdoaWxlIChrID4gMCkge1xuICAgICAgICAgICAgICAgIGsgPSBtYXgoMCwgayAtIHNlYXJjaExlbik7XG4gICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gc3RySW5kZXhPZihzdHJTbGljZShTLCBrLCBzdGFydCArIHNlYXJjaExlbiksIHNlYXJjaFN0cik7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gayArIGluZGV4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgIH0sIGhhc0xhc3RJbmRleEJ1Zyk7XG5cbiAgICB2YXIgb3JpZ2luYWxMYXN0SW5kZXhPZiA9IFN0cmluZ1Byb3RvdHlwZS5sYXN0SW5kZXhPZjtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKFN0cmluZ1Byb3RvdHlwZSwge1xuICAgICAgICBsYXN0SW5kZXhPZjogZnVuY3Rpb24gbGFzdEluZGV4T2Yoc2VhcmNoU3RyaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxMYXN0SW5kZXhPZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgfSwgU3RyaW5nUHJvdG90eXBlLmxhc3RJbmRleE9mLmxlbmd0aCAhPT0gMSk7XG5cbiAgICAvLyBFUy01IDE1LjEuMi4yXG4gICAgLyogZXNsaW50LWRpc2FibGUgcmFkaXggKi9cbiAgICBpZiAocGFyc2VJbnQod3MgKyAnMDgnKSAhPT0gOCB8fCBwYXJzZUludCh3cyArICcweDE2JykgIT09IDIyKSB7XG4gICAgLyogZXNsaW50LWVuYWJsZSByYWRpeCAqL1xuICAgICAgICAvKiBnbG9iYWwgcGFyc2VJbnQ6IHRydWUgKi9cbiAgICAgICAgcGFyc2VJbnQgPSAoZnVuY3Rpb24gKG9yaWdQYXJzZUludCkge1xuICAgICAgICAgICAgdmFyIGhleFJlZ2V4ID0gL15bXFwtK10/MFt4WF0vO1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIHBhcnNlSW50KHN0ciwgcmFkaXgpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3RyaW5nID0gdHJpbShTdHJpbmcoc3RyKSk7XG4gICAgICAgICAgICAgICAgdmFyIGRlZmF1bHRlZFJhZGl4ID0gJE51bWJlcihyYWRpeCkgfHwgKGhleFJlZ2V4LnRlc3Qoc3RyaW5nKSA/IDE2IDogMTApO1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnUGFyc2VJbnQoc3RyaW5nLCBkZWZhdWx0ZWRSYWRpeCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KHBhcnNlSW50KSk7XG4gICAgfVxuXG4gICAgLy8gaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4MTUuMS4yLjNcbiAgICBpZiAoMSAvIHBhcnNlRmxvYXQoJy0wJykgIT09IC1JbmZpbml0eSkge1xuICAgICAgICAvKiBnbG9iYWwgcGFyc2VGbG9hdDogdHJ1ZSAqL1xuICAgICAgICBwYXJzZUZsb2F0ID0gKGZ1bmN0aW9uIChvcmlnUGFyc2VGbG9hdCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIHBhcnNlRmxvYXQoc3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgdmFyIGlucHV0U3RyaW5nID0gdHJpbShTdHJpbmcoc3RyaW5nKSk7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IG9yaWdQYXJzZUZsb2F0KGlucHV0U3RyaW5nKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09PSAwICYmIHN0clNsaWNlKGlucHV0U3RyaW5nLCAwLCAxKSA9PT0gJy0nID8gLTAgOiByZXN1bHQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KHBhcnNlRmxvYXQpKTtcbiAgICB9XG5cbiAgICBpZiAoU3RyaW5nKG5ldyBSYW5nZUVycm9yKCd0ZXN0JykpICE9PSAnUmFuZ2VFcnJvcjogdGVzdCcpIHtcbiAgICAgICAgdmFyIGVycm9yVG9TdHJpbmdTaGltID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2FuJ3QgY29udmVydCBcIiArIHRoaXMgKyAnIHRvIG9iamVjdCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIG5hbWUgPSB0aGlzLm5hbWU7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG5hbWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgbmFtZSA9ICdFcnJvcic7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIG5hbWUgPSAkU3RyaW5nKG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIG1zZyA9IHRoaXMubWVzc2FnZTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbXNnID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIG1zZyA9ICcnO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbXNnICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIG1zZyA9ICRTdHJpbmcobXNnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghbmFtZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtc2c7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW1zZykge1xuICAgICAgICAgICAgICAgIHJldHVybiBuYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5hbWUgKyAnOiAnICsgbXNnO1xuICAgICAgICB9O1xuICAgICAgICAvLyBjYW4ndCB1c2UgZGVmaW5lUHJvcGVydGllcyBoZXJlIGJlY2F1c2Ugb2YgdG9TdHJpbmcgZW51bWVyYXRpb24gaXNzdWUgaW4gSUUgPD0gOFxuICAgICAgICBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcgPSBlcnJvclRvU3RyaW5nU2hpbTtcbiAgICB9XG5cbiAgICBpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuICAgICAgICB2YXIgZW5zdXJlTm9uRW51bWVyYWJsZSA9IGZ1bmN0aW9uIChvYmosIHByb3ApIHtcbiAgICAgICAgICAgIGlmIChpc0VudW0ob2JqLCBwcm9wKSkge1xuICAgICAgICAgICAgICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIHByb3ApO1xuICAgICAgICAgICAgICAgIGlmIChkZXNjLmNvbmZpZ3VyYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICBkZXNjLmVudW1lcmFibGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgcHJvcCwgZGVzYyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBlbnN1cmVOb25FbnVtZXJhYmxlKEVycm9yLnByb3RvdHlwZSwgJ21lc3NhZ2UnKTtcbiAgICAgICAgaWYgKEVycm9yLnByb3RvdHlwZS5tZXNzYWdlICE9PSAnJykge1xuICAgICAgICAgICAgRXJyb3IucHJvdG90eXBlLm1lc3NhZ2UgPSAnJztcbiAgICAgICAgfVxuICAgICAgICBlbnN1cmVOb25FbnVtZXJhYmxlKEVycm9yLnByb3RvdHlwZSwgJ25hbWUnKTtcbiAgICB9XG5cbiAgICBpZiAoU3RyaW5nKC9hL21pZykgIT09ICcvYS9naW0nKSB7XG4gICAgICAgIHZhciByZWdleFRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgICAgICB2YXIgc3RyID0gJy8nICsgdGhpcy5zb3VyY2UgKyAnLyc7XG4gICAgICAgICAgICBpZiAodGhpcy5nbG9iYWwpIHtcbiAgICAgICAgICAgICAgICBzdHIgKz0gJ2cnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaWdub3JlQ2FzZSkge1xuICAgICAgICAgICAgICAgIHN0ciArPSAnaSc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5tdWx0aWxpbmUpIHtcbiAgICAgICAgICAgICAgICBzdHIgKz0gJ20nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0cjtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gY2FuJ3QgdXNlIGRlZmluZVByb3BlcnRpZXMgaGVyZSBiZWNhdXNlIG9mIHRvU3RyaW5nIGVudW1lcmF0aW9uIGlzc3VlIGluIElFIDw9IDhcbiAgICAgICAgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZyA9IHJlZ2V4VG9TdHJpbmc7XG4gICAgfVxufSkpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLypqc2xpbnQgZXFlcTogdHJ1ZSovXG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ3Nhbml0aXplJywgZnVuY3Rpb24gKHRleHQpIHtcbiAgICB2YXIgcmVzdWx0O1xuXG4gICAgaWYgKHRleHQgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gJyc7IH1cblxuICAgIHJlc3VsdCA9IHNhbml0aXplSHRtbCh0ZXh0LCB7XG4gICAgICAgIGFsbG93ZWRUYWdzOiBbICdkaXYnLCAnc3BhbicsICdiJywgJ2knLCAnZW0nLCAnc3Ryb25nJywgJ2EnLCAnYnInLCAndGFibGUnLCAndGJvZHknLCAndHInLCAndGgnLCAndGQnIF0sXG4gICAgICAgIGFsbG93ZWRBdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAnZGl2JzogWyAnY2xhc3MnIF0sXG4gICAgICAgICAgICAnc3Bhbic6IFsgJ2NsYXNzJyBdLFxuICAgICAgICAgICAgJ3RhYmxlJzogWyAnY2xhc3MnIF0sXG4gICAgICAgICAgICAndGQnOiBbICdjbGFzcycgXSxcbiAgICAgICAgICAgICd0aCc6IFsgJ2NvbHNwYW4nIF0sXG4gICAgICAgICAgICAnYSc6IFsgJ2hyZWYnIF1cbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG5ldyBIYW5kbGViYXJzLlNhZmVTdHJpbmcocmVzdWx0KTtcbn0pO1xuXG5IYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdyZW5kZXJUZXh0UGFyYW0nLCBmdW5jdGlvbihwYXJhbSkge1xuICAgIHZhciByZXN1bHQsIHR5cGUgPSAndGV4dCcsIGlkQXR0ID0gJyc7XG4gICAgdmFyIHBhcmFtVHlwZSA9IHBhcmFtLnR5cGUgfHwgcGFyYW0uc2NoZW1hICYmIHBhcmFtLnNjaGVtYS50eXBlIHx8ICcnO1xuICAgIHZhciBpc0FycmF5ID0gcGFyYW1UeXBlLnRvTG93ZXJDYXNlKCkgPT09ICdhcnJheScgfHwgcGFyYW0uYWxsb3dNdWx0aXBsZTtcbiAgICB2YXIgZGVmYXVsdFZhbHVlID0gaXNBcnJheSAmJiBBcnJheS5pc0FycmF5KHBhcmFtLmRlZmF1bHQpID8gcGFyYW0uZGVmYXVsdC5qb2luKCdcXG4nKSA6IHBhcmFtLmRlZmF1bHQ7XG4gICAgdmFyIG5hbWUgPSBIYW5kbGViYXJzLlV0aWxzLmVzY2FwZUV4cHJlc3Npb24ocGFyYW0ubmFtZSk7XG4gICAgdmFyIHZhbHVlSWQgPSBIYW5kbGViYXJzLlV0aWxzLmVzY2FwZUV4cHJlc3Npb24ocGFyYW0udmFsdWVJZCk7XG4gICAgcGFyYW1UeXBlID0gSGFuZGxlYmFycy5VdGlscy5lc2NhcGVFeHByZXNzaW9uKHBhcmFtVHlwZSk7XG5cbiAgICB2YXIgZGF0YVZlbmRvckV4dGVuc2lvbnMgPSBPYmplY3Qua2V5cyhwYXJhbSkuZmlsdGVyKGZ1bmN0aW9uKHByb3BlcnR5KSB7XG4gICAgICAgIC8vIGZpbHRlciBYLWRhdGEtIHByb3BlcnRpZXNcbiAgICAgICAgcmV0dXJuIHByb3BlcnR5Lm1hdGNoKC9eWC1kYXRhLS9pKSAhPT0gbnVsbDtcbiAgICB9KS5yZWR1Y2UoZnVuY3Rpb24ocmVzdWx0LCBwcm9wZXJ0eSkge1xuICAgICAgICAvLyByZW1vdmUgWC0gZnJvbSBwcm9wZXJ0eSBuYW1lLCBzbyBpdCByZXN1bHRzIGluIGh0bWwgYXR0cmlidXRlcyBsaWtlIGRhdGEtZm9vPSdiYXInXG4gICAgICAgIHJldHVybiByZXN1bHQgKz0gJyAnICsgcHJvcGVydHkuc3Vic3RyaW5nKDIsIHByb3BlcnR5Lmxlbmd0aCkgKyAnPVxcJycgKyBwYXJhbVtwcm9wZXJ0eV0gKyAnXFwnJztcbiAgICB9LCAnJyk7XG5cbiAgICBpZihwYXJhbS5mb3JtYXQgJiYgcGFyYW0uZm9ybWF0ID09PSAncGFzc3dvcmQnKSB7XG4gICAgICAgIHR5cGUgPSAncGFzc3dvcmQnO1xuICAgIH1cblxuICAgIGlmKHZhbHVlSWQpIHtcbiAgICAgICAgaWRBdHQgPSAnIGlkPVxcJycgKyB2YWx1ZUlkICsgJ1xcJyc7XG4gICAgfVxuXG4gICAgaWYgKGRlZmF1bHRWYWx1ZSkge1xuICAgICAgZGVmYXVsdFZhbHVlID0gc2FuaXRpemVIdG1sKGRlZmF1bHRWYWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlZmF1bHRWYWx1ZSA9ICcnO1xuICAgIH1cblxuICAgIGlmKGlzQXJyYXkpIHtcbiAgICAgICAgcmVzdWx0ID0gJzx0ZXh0YXJlYSBjbGFzcz1cXCdib2R5LXRleHRhcmVhJyArIChwYXJhbS5yZXF1aXJlZCA/ICcgcmVxdWlyZWQnIDogJycpICsgJ1xcJyBuYW1lPVxcJycgKyBuYW1lICsgJ1xcJycgKyBpZEF0dCArIGRhdGFWZW5kb3JFeHRlbnNpb25zO1xuICAgICAgICByZXN1bHQgKz0gJyBwbGFjZWhvbGRlcj1cXCdQcm92aWRlIG11bHRpcGxlIHZhbHVlcyBpbiBuZXcgbGluZXMnICsgKHBhcmFtLnJlcXVpcmVkID8gJyAoYXQgbGVhc3Qgb25lIHJlcXVpcmVkKS4nIDogJy4nKSArICdcXCc+JztcbiAgICAgICAgcmVzdWx0ICs9IGRlZmF1bHRWYWx1ZSArICc8L3RleHRhcmVhPic7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHBhcmFtZXRlckNsYXNzID0gJ3BhcmFtZXRlcic7XG4gICAgICAgIGlmKHBhcmFtLnJlcXVpcmVkKSB7XG4gICAgICAgICAgcGFyYW1ldGVyQ2xhc3MgKz0gJyByZXF1aXJlZCc7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0ID0gJzxpbnB1dCBjbGFzcz1cXCcnICsgcGFyYW1ldGVyQ2xhc3MgKyAnXFwnIG1pbmxlbmd0aD1cXCcnICsgKHBhcmFtLnJlcXVpcmVkID8gMSA6IDApICsgJ1xcJyc7XG4gICAgICAgIHJlc3VsdCArPSAnIG5hbWU9XFwnJyArIG5hbWUgKydcXCcgcGxhY2Vob2xkZXI9XFwnJyArIChwYXJhbS5yZXF1aXJlZCA/ICcocmVxdWlyZWQpJyA6ICcnKSArICdcXCcnICsgaWRBdHQgKyBkYXRhVmVuZG9yRXh0ZW5zaW9ucztcbiAgICAgICAgcmVzdWx0ICs9ICcgdHlwZT1cXCcnICsgdHlwZSArICdcXCcgdmFsdWU9XFwnJyArIGRlZmF1bHRWYWx1ZSArICdcXCcvPic7XG4gICAgfVxuICAgIHJldHVybiBuZXcgSGFuZGxlYmFycy5TYWZlU3RyaW5nKHJlc3VsdCk7XG59KTtcblxuSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcignaWZDb25kJywgZnVuY3Rpb24gKHYxLCBvcGVyYXRvciwgdjIsIG9wdGlvbnMpIHtcblxuICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSAnPT0nOlxuICAgICAgICAgICAgcmV0dXJuICh2MSA9PSB2MikgPyBvcHRpb25zLmZuKHRoaXMpIDogb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgICAgICBjYXNlICc9PT0nOlxuICAgICAgICAgICAgcmV0dXJuICh2MSA9PT0gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPCc6XG4gICAgICAgICAgICByZXR1cm4gKHYxIDwgdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPD0nOlxuICAgICAgICAgICAgcmV0dXJuICh2MSA8PSB2MikgPyBvcHRpb25zLmZuKHRoaXMpIDogb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgICAgICBjYXNlICc+JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPiB2MikgPyBvcHRpb25zLmZuKHRoaXMpIDogb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgICAgICBjYXNlICc+PSc6XG4gICAgICAgICAgICByZXR1cm4gKHYxID49IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJyYmJzpcbiAgICAgICAgICAgIHJldHVybiAodjEgJiYgdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnfHwnOlxuICAgICAgICAgICAgcmV0dXJuICh2MSB8fCB2MikgPyBvcHRpb25zLmZuKHRoaXMpIDogb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICB9XG59KTtcblxuSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcignZXNjYXBlJywgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdmFyIHRleHQgPSBIYW5kbGViYXJzLlV0aWxzLmVzY2FwZUV4cHJlc3Npb24odmFsdWUpO1xuXG4gICAgcmV0dXJuIG5ldyBIYW5kbGViYXJzLlNhZmVTdHJpbmcodGV4dCk7XG59KTtcbiIsIihmdW5jdGlvbihmKXtpZih0eXBlb2YgZXhwb3J0cz09PVwib2JqZWN0XCImJnR5cGVvZiBtb2R1bGUhPT1cInVuZGVmaW5lZFwiKXttb2R1bGUuZXhwb3J0cz1mKCl9ZWxzZSBpZih0eXBlb2YgZGVmaW5lPT09XCJmdW5jdGlvblwiJiZkZWZpbmUuYW1kKXtkZWZpbmUoW10sZil9ZWxzZXt2YXIgZztpZih0eXBlb2Ygd2luZG93IT09XCJ1bmRlZmluZWRcIil7Zz13aW5kb3d9ZWxzZSBpZih0eXBlb2YgZ2xvYmFsIT09XCJ1bmRlZmluZWRcIil7Zz1nbG9iYWx9ZWxzZSBpZih0eXBlb2Ygc2VsZiE9PVwidW5kZWZpbmVkXCIpe2c9c2VsZn1lbHNle2c9dGhpc31nLnNhbml0aXplSHRtbD1mKCl9fSkoZnVuY3Rpb24oKXt2YXIgZGVmaW5lLG1vZHVsZSxleHBvcnRzO3JldHVybiBmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30oezE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBodG1scGFyc2VyPXJlcXVpcmUoXCJodG1scGFyc2VyMlwiKTt2YXIgZXh0ZW5kPXJlcXVpcmUoXCJ4dGVuZFwiKTt2YXIgcXVvdGVSZWdleHA9cmVxdWlyZShcInJlZ2V4cC1xdW90ZVwiKTtmdW5jdGlvbiBlYWNoKG9iaixjYil7aWYob2JqKU9iamVjdC5rZXlzKG9iaikuZm9yRWFjaChmdW5jdGlvbihrZXkpe2NiKG9ialtrZXldLGtleSl9KX1mdW5jdGlvbiBoYXMob2JqLGtleSl7cmV0dXJue30uaGFzT3duUHJvcGVydHkuY2FsbChvYmosa2V5KX1tb2R1bGUuZXhwb3J0cz1zYW5pdGl6ZUh0bWw7ZnVuY3Rpb24gc2FuaXRpemVIdG1sKGh0bWwsb3B0aW9ucyxfcmVjdXJzaW5nKXt2YXIgcmVzdWx0PVwiXCI7ZnVuY3Rpb24gRnJhbWUodGFnLGF0dHJpYnMpe3ZhciB0aGF0PXRoaXM7dGhpcy50YWc9dGFnO3RoaXMuYXR0cmlicz1hdHRyaWJzfHx7fTt0aGlzLnRhZ1Bvc2l0aW9uPXJlc3VsdC5sZW5ndGg7dGhpcy50ZXh0PVwiXCI7dGhpcy51cGRhdGVQYXJlbnROb2RlVGV4dD1mdW5jdGlvbigpe2lmKHN0YWNrLmxlbmd0aCl7dmFyIHBhcmVudEZyYW1lPXN0YWNrW3N0YWNrLmxlbmd0aC0xXTtwYXJlbnRGcmFtZS50ZXh0Kz10aGF0LnRleHR9fX1pZighb3B0aW9ucyl7b3B0aW9ucz1zYW5pdGl6ZUh0bWwuZGVmYXVsdHM7b3B0aW9ucy5wYXJzZXI9aHRtbFBhcnNlckRlZmF1bHRzfWVsc2V7b3B0aW9ucz1leHRlbmQoc2FuaXRpemVIdG1sLmRlZmF1bHRzLG9wdGlvbnMpO2lmKG9wdGlvbnMucGFyc2VyKXtvcHRpb25zLnBhcnNlcj1leHRlbmQoaHRtbFBhcnNlckRlZmF1bHRzLG9wdGlvbnMucGFyc2VyKX1lbHNle29wdGlvbnMucGFyc2VyPWh0bWxQYXJzZXJEZWZhdWx0c319dmFyIG5vblRleHRUYWdzQXJyYXk9b3B0aW9ucy5ub25UZXh0VGFnc3x8W1wic2NyaXB0XCIsXCJzdHlsZVwiLFwidGV4dGFyZWFcIl07dmFyIGFsbG93ZWRBdHRyaWJ1dGVzTWFwO3ZhciBhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXA7aWYob3B0aW9ucy5hbGxvd2VkQXR0cmlidXRlcyl7YWxsb3dlZEF0dHJpYnV0ZXNNYXA9e307YWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwPXt9O2VhY2gob3B0aW9ucy5hbGxvd2VkQXR0cmlidXRlcyxmdW5jdGlvbihhdHRyaWJ1dGVzLHRhZyl7YWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXT1bXTt2YXIgZ2xvYlJlZ2V4PVtdO2F0dHJpYnV0ZXMuZm9yRWFjaChmdW5jdGlvbihuYW1lKXtpZihuYW1lLmluZGV4T2YoXCIqXCIpPj0wKXtnbG9iUmVnZXgucHVzaChxdW90ZVJlZ2V4cChuYW1lKS5yZXBsYWNlKC9cXFxcXFwqL2csXCIuKlwiKSl9ZWxzZXthbGxvd2VkQXR0cmlidXRlc01hcFt0YWddLnB1c2gobmFtZSl9fSk7YWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwW3RhZ109bmV3IFJlZ0V4cChcIl4oXCIrZ2xvYlJlZ2V4LmpvaW4oXCJ8XCIpK1wiKSRcIil9KX12YXIgYWxsb3dlZENsYXNzZXNNYXA9e307ZWFjaChvcHRpb25zLmFsbG93ZWRDbGFzc2VzLGZ1bmN0aW9uKGNsYXNzZXMsdGFnKXtpZihhbGxvd2VkQXR0cmlidXRlc01hcCl7aWYoIWhhcyhhbGxvd2VkQXR0cmlidXRlc01hcCx0YWcpKXthbGxvd2VkQXR0cmlidXRlc01hcFt0YWddPVtdfWFsbG93ZWRBdHRyaWJ1dGVzTWFwW3RhZ10ucHVzaChcImNsYXNzXCIpfWFsbG93ZWRDbGFzc2VzTWFwW3RhZ109Y2xhc3Nlc30pO3ZhciB0cmFuc2Zvcm1UYWdzTWFwPXt9O3ZhciB0cmFuc2Zvcm1UYWdzQWxsO2VhY2gob3B0aW9ucy50cmFuc2Zvcm1UYWdzLGZ1bmN0aW9uKHRyYW5zZm9ybSx0YWcpe3ZhciB0cmFuc0Z1bjtpZih0eXBlb2YgdHJhbnNmb3JtPT09XCJmdW5jdGlvblwiKXt0cmFuc0Z1bj10cmFuc2Zvcm19ZWxzZSBpZih0eXBlb2YgdHJhbnNmb3JtPT09XCJzdHJpbmdcIil7dHJhbnNGdW49c2FuaXRpemVIdG1sLnNpbXBsZVRyYW5zZm9ybSh0cmFuc2Zvcm0pfWlmKHRhZz09PVwiKlwiKXt0cmFuc2Zvcm1UYWdzQWxsPXRyYW5zRnVufWVsc2V7dHJhbnNmb3JtVGFnc01hcFt0YWddPXRyYW5zRnVufX0pO3ZhciBkZXB0aD0wO3ZhciBzdGFjaz1bXTt2YXIgc2tpcE1hcD17fTt2YXIgdHJhbnNmb3JtTWFwPXt9O3ZhciBza2lwVGV4dD1mYWxzZTt2YXIgc2tpcFRleHREZXB0aD0wO3ZhciBwYXJzZXI9bmV3IGh0bWxwYXJzZXIuUGFyc2VyKHtvbm9wZW50YWc6ZnVuY3Rpb24obmFtZSxhdHRyaWJzKXtpZihza2lwVGV4dCl7c2tpcFRleHREZXB0aCsrO3JldHVybn12YXIgZnJhbWU9bmV3IEZyYW1lKG5hbWUsYXR0cmlicyk7c3RhY2sucHVzaChmcmFtZSk7dmFyIHNraXA9ZmFsc2U7dmFyIGhhc1RleHQ9ZnJhbWUudGV4dD90cnVlOmZhbHNlO3ZhciB0cmFuc2Zvcm1lZFRhZztpZihoYXModHJhbnNmb3JtVGFnc01hcCxuYW1lKSl7dHJhbnNmb3JtZWRUYWc9dHJhbnNmb3JtVGFnc01hcFtuYW1lXShuYW1lLGF0dHJpYnMpO2ZyYW1lLmF0dHJpYnM9YXR0cmlicz10cmFuc2Zvcm1lZFRhZy5hdHRyaWJzO2lmKHRyYW5zZm9ybWVkVGFnLnRleHQhPT11bmRlZmluZWQpe2ZyYW1lLmlubmVyVGV4dD10cmFuc2Zvcm1lZFRhZy50ZXh0fWlmKG5hbWUhPT10cmFuc2Zvcm1lZFRhZy50YWdOYW1lKXtmcmFtZS5uYW1lPW5hbWU9dHJhbnNmb3JtZWRUYWcudGFnTmFtZTt0cmFuc2Zvcm1NYXBbZGVwdGhdPXRyYW5zZm9ybWVkVGFnLnRhZ05hbWV9fWlmKHRyYW5zZm9ybVRhZ3NBbGwpe3RyYW5zZm9ybWVkVGFnPXRyYW5zZm9ybVRhZ3NBbGwobmFtZSxhdHRyaWJzKTtmcmFtZS5hdHRyaWJzPWF0dHJpYnM9dHJhbnNmb3JtZWRUYWcuYXR0cmlicztpZihuYW1lIT09dHJhbnNmb3JtZWRUYWcudGFnTmFtZSl7ZnJhbWUubmFtZT1uYW1lPXRyYW5zZm9ybWVkVGFnLnRhZ05hbWU7dHJhbnNmb3JtTWFwW2RlcHRoXT10cmFuc2Zvcm1lZFRhZy50YWdOYW1lfX1pZihvcHRpb25zLmFsbG93ZWRUYWdzJiZvcHRpb25zLmFsbG93ZWRUYWdzLmluZGV4T2YobmFtZSk9PT0tMSl7c2tpcD10cnVlO2lmKG5vblRleHRUYWdzQXJyYXkuaW5kZXhPZihuYW1lKSE9PS0xKXtza2lwVGV4dD10cnVlO3NraXBUZXh0RGVwdGg9MX1za2lwTWFwW2RlcHRoXT10cnVlfWRlcHRoKys7aWYoc2tpcCl7cmV0dXJufXJlc3VsdCs9XCI8XCIrbmFtZTtpZighYWxsb3dlZEF0dHJpYnV0ZXNNYXB8fGhhcyhhbGxvd2VkQXR0cmlidXRlc01hcCxuYW1lKXx8YWxsb3dlZEF0dHJpYnV0ZXNNYXBbXCIqXCJdKXtlYWNoKGF0dHJpYnMsZnVuY3Rpb24odmFsdWUsYSl7aWYoIWFsbG93ZWRBdHRyaWJ1dGVzTWFwfHxoYXMoYWxsb3dlZEF0dHJpYnV0ZXNNYXAsbmFtZSkmJmFsbG93ZWRBdHRyaWJ1dGVzTWFwW25hbWVdLmluZGV4T2YoYSkhPT0tMXx8YWxsb3dlZEF0dHJpYnV0ZXNNYXBbXCIqXCJdJiZhbGxvd2VkQXR0cmlidXRlc01hcFtcIipcIl0uaW5kZXhPZihhKSE9PS0xfHxoYXMoYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwLG5hbWUpJiZhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXBbbmFtZV0udGVzdChhKXx8YWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwW1wiKlwiXSYmYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwW1wiKlwiXS50ZXN0KGEpKXtpZihhPT09XCJocmVmXCJ8fGE9PT1cInNyY1wiKXtpZihuYXVnaHR5SHJlZihuYW1lLHZhbHVlKSl7ZGVsZXRlIGZyYW1lLmF0dHJpYnNbYV07cmV0dXJufX1pZihhPT09XCJjbGFzc1wiKXt2YWx1ZT1maWx0ZXJDbGFzc2VzKHZhbHVlLGFsbG93ZWRDbGFzc2VzTWFwW25hbWVdKTtpZighdmFsdWUubGVuZ3RoKXtkZWxldGUgZnJhbWUuYXR0cmlic1thXTtyZXR1cm59fXJlc3VsdCs9XCIgXCIrYTtpZih2YWx1ZS5sZW5ndGgpe3Jlc3VsdCs9Jz1cIicrZXNjYXBlSHRtbCh2YWx1ZSkrJ1wiJ319ZWxzZXtkZWxldGUgZnJhbWUuYXR0cmlic1thXX19KX1pZihvcHRpb25zLnNlbGZDbG9zaW5nLmluZGV4T2YobmFtZSkhPT0tMSl7cmVzdWx0Kz1cIiAvPlwifWVsc2V7cmVzdWx0Kz1cIj5cIjtpZihmcmFtZS5pbm5lclRleHQmJiFoYXNUZXh0JiYhb3B0aW9ucy50ZXh0RmlsdGVyKXtyZXN1bHQrPWZyYW1lLmlubmVyVGV4dH19fSxvbnRleHQ6ZnVuY3Rpb24odGV4dCl7aWYoc2tpcFRleHQpe3JldHVybn12YXIgbGFzdEZyYW1lPXN0YWNrW3N0YWNrLmxlbmd0aC0xXTt2YXIgdGFnO2lmKGxhc3RGcmFtZSl7dGFnPWxhc3RGcmFtZS50YWc7dGV4dD1sYXN0RnJhbWUuaW5uZXJUZXh0IT09dW5kZWZpbmVkP2xhc3RGcmFtZS5pbm5lclRleHQ6dGV4dH1pZih0YWc9PT1cInNjcmlwdFwifHx0YWc9PT1cInN0eWxlXCIpe3Jlc3VsdCs9dGV4dH1lbHNle3ZhciBlc2NhcGVkPWVzY2FwZUh0bWwodGV4dCk7aWYob3B0aW9ucy50ZXh0RmlsdGVyKXtyZXN1bHQrPW9wdGlvbnMudGV4dEZpbHRlcihlc2NhcGVkKX1lbHNle3Jlc3VsdCs9ZXNjYXBlZH19aWYoc3RhY2subGVuZ3RoKXt2YXIgZnJhbWU9c3RhY2tbc3RhY2subGVuZ3RoLTFdO2ZyYW1lLnRleHQrPXRleHR9fSxvbmNsb3NldGFnOmZ1bmN0aW9uKG5hbWUpe2lmKHNraXBUZXh0KXtza2lwVGV4dERlcHRoLS07aWYoIXNraXBUZXh0RGVwdGgpe3NraXBUZXh0PWZhbHNlfWVsc2V7cmV0dXJufX12YXIgZnJhbWU9c3RhY2sucG9wKCk7aWYoIWZyYW1lKXtyZXR1cm59c2tpcFRleHQ9ZmFsc2U7ZGVwdGgtLTtpZihza2lwTWFwW2RlcHRoXSl7ZGVsZXRlIHNraXBNYXBbZGVwdGhdO2ZyYW1lLnVwZGF0ZVBhcmVudE5vZGVUZXh0KCk7cmV0dXJufWlmKHRyYW5zZm9ybU1hcFtkZXB0aF0pe25hbWU9dHJhbnNmb3JtTWFwW2RlcHRoXTtkZWxldGUgdHJhbnNmb3JtTWFwW2RlcHRoXX1pZihvcHRpb25zLmV4Y2x1c2l2ZUZpbHRlciYmb3B0aW9ucy5leGNsdXNpdmVGaWx0ZXIoZnJhbWUpKXtyZXN1bHQ9cmVzdWx0LnN1YnN0cigwLGZyYW1lLnRhZ1Bvc2l0aW9uKTtyZXR1cm59ZnJhbWUudXBkYXRlUGFyZW50Tm9kZVRleHQoKTtpZihvcHRpb25zLnNlbGZDbG9zaW5nLmluZGV4T2YobmFtZSkhPT0tMSl7cmV0dXJufXJlc3VsdCs9XCI8L1wiK25hbWUrXCI+XCJ9fSxvcHRpb25zLnBhcnNlcik7cGFyc2VyLndyaXRlKGh0bWwpO3BhcnNlci5lbmQoKTtyZXR1cm4gcmVzdWx0O2Z1bmN0aW9uIGVzY2FwZUh0bWwocyl7aWYodHlwZW9mIHMhPT1cInN0cmluZ1wiKXtzPXMrXCJcIn1yZXR1cm4gcy5yZXBsYWNlKC9cXCYvZyxcIiZhbXA7XCIpLnJlcGxhY2UoLzwvZyxcIiZsdDtcIikucmVwbGFjZSgvXFw+L2csXCImZ3Q7XCIpLnJlcGxhY2UoL1xcXCIvZyxcIiZxdW90O1wiKX1mdW5jdGlvbiBuYXVnaHR5SHJlZihuYW1lLGhyZWYpe2hyZWY9aHJlZi5yZXBsYWNlKC9bXFx4MDAtXFx4MjBdKy9nLFwiXCIpO2hyZWY9aHJlZi5yZXBsYWNlKC88XFwhXFwtXFwtLio/XFwtXFwtXFw+L2csXCJcIik7dmFyIG1hdGNoZXM9aHJlZi5tYXRjaCgvXihbYS16QS1aXSspXFw6Lyk7aWYoIW1hdGNoZXMpe3JldHVybiBmYWxzZX12YXIgc2NoZW1lPW1hdGNoZXNbMV0udG9Mb3dlckNhc2UoKTtpZihoYXMob3B0aW9ucy5hbGxvd2VkU2NoZW1lc0J5VGFnLG5hbWUpKXtyZXR1cm4gb3B0aW9ucy5hbGxvd2VkU2NoZW1lc0J5VGFnW25hbWVdLmluZGV4T2Yoc2NoZW1lKT09PS0xfXJldHVybiFvcHRpb25zLmFsbG93ZWRTY2hlbWVzfHxvcHRpb25zLmFsbG93ZWRTY2hlbWVzLmluZGV4T2Yoc2NoZW1lKT09PS0xfWZ1bmN0aW9uIGZpbHRlckNsYXNzZXMoY2xhc3NlcyxhbGxvd2VkKXtpZighYWxsb3dlZCl7cmV0dXJuIGNsYXNzZXN9Y2xhc3Nlcz1jbGFzc2VzLnNwbGl0KC9cXHMrLyk7cmV0dXJuIGNsYXNzZXMuZmlsdGVyKGZ1bmN0aW9uKGNsc3Mpe3JldHVybiBhbGxvd2VkLmluZGV4T2YoY2xzcykhPT0tMX0pLmpvaW4oXCIgXCIpfX12YXIgaHRtbFBhcnNlckRlZmF1bHRzPXtkZWNvZGVFbnRpdGllczp0cnVlfTtzYW5pdGl6ZUh0bWwuZGVmYXVsdHM9e2FsbG93ZWRUYWdzOltcImgzXCIsXCJoNFwiLFwiaDVcIixcImg2XCIsXCJibG9ja3F1b3RlXCIsXCJwXCIsXCJhXCIsXCJ1bFwiLFwib2xcIixcIm5sXCIsXCJsaVwiLFwiYlwiLFwiaVwiLFwic3Ryb25nXCIsXCJlbVwiLFwic3RyaWtlXCIsXCJjb2RlXCIsXCJoclwiLFwiYnJcIixcImRpdlwiLFwidGFibGVcIixcInRoZWFkXCIsXCJjYXB0aW9uXCIsXCJ0Ym9keVwiLFwidHJcIixcInRoXCIsXCJ0ZFwiLFwicHJlXCJdLGFsbG93ZWRBdHRyaWJ1dGVzOnthOltcImhyZWZcIixcIm5hbWVcIixcInRhcmdldFwiXSxpbWc6W1wic3JjXCJdfSxzZWxmQ2xvc2luZzpbXCJpbWdcIixcImJyXCIsXCJoclwiLFwiYXJlYVwiLFwiYmFzZVwiLFwiYmFzZWZvbnRcIixcImlucHV0XCIsXCJsaW5rXCIsXCJtZXRhXCJdLGFsbG93ZWRTY2hlbWVzOltcImh0dHBcIixcImh0dHBzXCIsXCJmdHBcIixcIm1haWx0b1wiXSxhbGxvd2VkU2NoZW1lc0J5VGFnOnt9fTtzYW5pdGl6ZUh0bWwuc2ltcGxlVHJhbnNmb3JtPWZ1bmN0aW9uKG5ld1RhZ05hbWUsbmV3QXR0cmlicyxtZXJnZSl7bWVyZ2U9bWVyZ2U9PT11bmRlZmluZWQ/dHJ1ZTptZXJnZTtuZXdBdHRyaWJzPW5ld0F0dHJpYnN8fHt9O3JldHVybiBmdW5jdGlvbih0YWdOYW1lLGF0dHJpYnMpe3ZhciBhdHRyaWI7aWYobWVyZ2Upe2ZvcihhdHRyaWIgaW4gbmV3QXR0cmlicyl7YXR0cmlic1thdHRyaWJdPW5ld0F0dHJpYnNbYXR0cmliXX19ZWxzZXthdHRyaWJzPW5ld0F0dHJpYnN9cmV0dXJue3RhZ05hbWU6bmV3VGFnTmFtZSxhdHRyaWJzOmF0dHJpYnN9fX19LHtodG1scGFyc2VyMjozNixcInJlZ2V4cC1xdW90ZVwiOjU0LHh0ZW5kOjU4fV0sMjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XCJ1c2Ugc3RyaWN0XCI7ZXhwb3J0cy50b0J5dGVBcnJheT10b0J5dGVBcnJheTtleHBvcnRzLmZyb21CeXRlQXJyYXk9ZnJvbUJ5dGVBcnJheTt2YXIgbG9va3VwPVtdO3ZhciByZXZMb29rdXA9W107dmFyIEFycj10eXBlb2YgVWludDhBcnJheSE9PVwidW5kZWZpbmVkXCI/VWludDhBcnJheTpBcnJheTtmdW5jdGlvbiBpbml0KCl7dmFyIGNvZGU9XCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvXCI7Zm9yKHZhciBpPTAsbGVuPWNvZGUubGVuZ3RoO2k8bGVuOysraSl7bG9va3VwW2ldPWNvZGVbaV07cmV2TG9va3VwW2NvZGUuY2hhckNvZGVBdChpKV09aX1yZXZMb29rdXBbXCItXCIuY2hhckNvZGVBdCgwKV09NjI7cmV2TG9va3VwW1wiX1wiLmNoYXJDb2RlQXQoMCldPTYzfWluaXQoKTtmdW5jdGlvbiB0b0J5dGVBcnJheShiNjQpe3ZhciBpLGosbCx0bXAscGxhY2VIb2xkZXJzLGFycjt2YXIgbGVuPWI2NC5sZW5ndGg7aWYobGVuJTQ+MCl7dGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNFwiKX1wbGFjZUhvbGRlcnM9YjY0W2xlbi0yXT09PVwiPVwiPzI6YjY0W2xlbi0xXT09PVwiPVwiPzE6MDthcnI9bmV3IEFycihsZW4qMy80LXBsYWNlSG9sZGVycyk7bD1wbGFjZUhvbGRlcnM+MD9sZW4tNDpsZW47dmFyIEw9MDtmb3IoaT0wLGo9MDtpPGw7aSs9NCxqKz0zKXt0bXA9cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXTw8MTh8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMSldPDwxMnxyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSsyKV08PDZ8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMyldO2FycltMKytdPXRtcD4+MTYmMjU1O2FycltMKytdPXRtcD4+OCYyNTU7YXJyW0wrK109dG1wJjI1NX1pZihwbGFjZUhvbGRlcnM9PT0yKXt0bXA9cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXTw8MnxyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSsxKV0+PjQ7YXJyW0wrK109dG1wJjI1NX1lbHNlIGlmKHBsYWNlSG9sZGVycz09PTEpe3RtcD1yZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldPDwxMHxyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSsxKV08PDR8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMildPj4yO2FycltMKytdPXRtcD4+OCYyNTU7YXJyW0wrK109dG1wJjI1NX1yZXR1cm4gYXJyfWZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NChudW0pe3JldHVybiBsb29rdXBbbnVtPj4xOCY2M10rbG9va3VwW251bT4+MTImNjNdK2xvb2t1cFtudW0+PjYmNjNdK2xvb2t1cFtudW0mNjNdfWZ1bmN0aW9uIGVuY29kZUNodW5rKHVpbnQ4LHN0YXJ0LGVuZCl7dmFyIHRtcDt2YXIgb3V0cHV0PVtdO2Zvcih2YXIgaT1zdGFydDtpPGVuZDtpKz0zKXt0bXA9KHVpbnQ4W2ldPDwxNikrKHVpbnQ4W2krMV08PDgpK3VpbnQ4W2krMl07b3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpfXJldHVybiBvdXRwdXQuam9pbihcIlwiKX1mdW5jdGlvbiBmcm9tQnl0ZUFycmF5KHVpbnQ4KXt2YXIgdG1wO3ZhciBsZW49dWludDgubGVuZ3RoO3ZhciBleHRyYUJ5dGVzPWxlbiUzO3ZhciBvdXRwdXQ9XCJcIjt2YXIgcGFydHM9W107dmFyIG1heENodW5rTGVuZ3RoPTE2MzgzO2Zvcih2YXIgaT0wLGxlbjI9bGVuLWV4dHJhQnl0ZXM7aTxsZW4yO2krPW1heENodW5rTGVuZ3RoKXtwYXJ0cy5wdXNoKGVuY29kZUNodW5rKHVpbnQ4LGksaSttYXhDaHVua0xlbmd0aD5sZW4yP2xlbjI6aSttYXhDaHVua0xlbmd0aCkpfWlmKGV4dHJhQnl0ZXM9PT0xKXt0bXA9dWludDhbbGVuLTFdO291dHB1dCs9bG9va3VwW3RtcD4+Ml07b3V0cHV0Kz1sb29rdXBbdG1wPDw0JjYzXTtvdXRwdXQrPVwiPT1cIn1lbHNlIGlmKGV4dHJhQnl0ZXM9PT0yKXt0bXA9KHVpbnQ4W2xlbi0yXTw8OCkrdWludDhbbGVuLTFdO291dHB1dCs9bG9va3VwW3RtcD4+MTBdO291dHB1dCs9bG9va3VwW3RtcD4+NCY2M107b3V0cHV0Kz1sb29rdXBbdG1wPDwyJjYzXTtvdXRwdXQrPVwiPVwifXBhcnRzLnB1c2gob3V0cHV0KTtyZXR1cm4gcGFydHMuam9pbihcIlwiKX19LHt9XSwzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt9LHt9XSw0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24oZ2xvYmFsKXtcInVzZSBzdHJpY3RcIjt2YXIgYnVmZmVyPXJlcXVpcmUoXCJidWZmZXJcIik7dmFyIEJ1ZmZlcj1idWZmZXIuQnVmZmVyO3ZhciBTbG93QnVmZmVyPWJ1ZmZlci5TbG93QnVmZmVyO3ZhciBNQVhfTEVOPWJ1ZmZlci5rTWF4TGVuZ3RofHwyMTQ3NDgzNjQ3O2V4cG9ydHMuYWxsb2M9ZnVuY3Rpb24gYWxsb2Moc2l6ZSxmaWxsLGVuY29kaW5nKXtpZih0eXBlb2YgQnVmZmVyLmFsbG9jPT09XCJmdW5jdGlvblwiKXtyZXR1cm4gQnVmZmVyLmFsbG9jKHNpemUsZmlsbCxlbmNvZGluZyl9aWYodHlwZW9mIGVuY29kaW5nPT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcImVuY29kaW5nIG11c3Qgbm90IGJlIG51bWJlclwiKX1pZih0eXBlb2Ygc2l6ZSE9PVwibnVtYmVyXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJzaXplIG11c3QgYmUgYSBudW1iZXJcIil9aWYoc2l6ZT5NQVhfTEVOKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInNpemUgaXMgdG9vIGxhcmdlXCIpfXZhciBlbmM9ZW5jb2Rpbmc7dmFyIF9maWxsPWZpbGw7aWYoX2ZpbGw9PT11bmRlZmluZWQpe2VuYz11bmRlZmluZWQ7X2ZpbGw9MH12YXIgYnVmPW5ldyBCdWZmZXIoc2l6ZSk7aWYodHlwZW9mIF9maWxsPT09XCJzdHJpbmdcIil7dmFyIGZpbGxCdWY9bmV3IEJ1ZmZlcihfZmlsbCxlbmMpO3ZhciBmbGVuPWZpbGxCdWYubGVuZ3RoO3ZhciBpPS0xO3doaWxlKCsraTxzaXplKXtidWZbaV09ZmlsbEJ1ZltpJWZsZW5dfX1lbHNle2J1Zi5maWxsKF9maWxsKX1yZXR1cm4gYnVmfTtleHBvcnRzLmFsbG9jVW5zYWZlPWZ1bmN0aW9uIGFsbG9jVW5zYWZlKHNpemUpe2lmKHR5cGVvZiBCdWZmZXIuYWxsb2NVbnNhZmU9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBCdWZmZXIuYWxsb2NVbnNhZmUoc2l6ZSl9aWYodHlwZW9mIHNpemUhPT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwic2l6ZSBtdXN0IGJlIGEgbnVtYmVyXCIpfWlmKHNpemU+TUFYX0xFTil7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJzaXplIGlzIHRvbyBsYXJnZVwiKX1yZXR1cm4gbmV3IEJ1ZmZlcihzaXplKX07ZXhwb3J0cy5mcm9tPWZ1bmN0aW9uIGZyb20odmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpe2lmKHR5cGVvZiBCdWZmZXIuZnJvbT09PVwiZnVuY3Rpb25cIiYmKCFnbG9iYWwuVWludDhBcnJheXx8VWludDhBcnJheS5mcm9tIT09QnVmZmVyLmZyb20pKXtyZXR1cm4gQnVmZmVyLmZyb20odmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpfWlmKHR5cGVvZiB2YWx1ZT09PVwibnVtYmVyXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpfWlmKHR5cGVvZiB2YWx1ZT09PVwic3RyaW5nXCIpe3JldHVybiBuZXcgQnVmZmVyKHZhbHVlLGVuY29kaW5nT3JPZmZzZXQpfWlmKHR5cGVvZiBBcnJheUJ1ZmZlciE9PVwidW5kZWZpbmVkXCImJnZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpe3ZhciBvZmZzZXQ9ZW5jb2RpbmdPck9mZnNldDtpZihhcmd1bWVudHMubGVuZ3RoPT09MSl7cmV0dXJuIG5ldyBCdWZmZXIodmFsdWUpfWlmKHR5cGVvZiBvZmZzZXQ9PT1cInVuZGVmaW5lZFwiKXtvZmZzZXQ9MH12YXIgbGVuPWxlbmd0aDtpZih0eXBlb2YgbGVuPT09XCJ1bmRlZmluZWRcIil7bGVuPXZhbHVlLmJ5dGVMZW5ndGgtb2Zmc2V0fWlmKG9mZnNldD49dmFsdWUuYnl0ZUxlbmd0aCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInb2Zmc2V0JyBpcyBvdXQgb2YgYm91bmRzXCIpfWlmKGxlbj52YWx1ZS5ieXRlTGVuZ3RoLW9mZnNldCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInbGVuZ3RoJyBpcyBvdXQgb2YgYm91bmRzXCIpfXJldHVybiBuZXcgQnVmZmVyKHZhbHVlLnNsaWNlKG9mZnNldCxvZmZzZXQrbGVuKSl9aWYoQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSl7dmFyIG91dD1uZXcgQnVmZmVyKHZhbHVlLmxlbmd0aCk7dmFsdWUuY29weShvdXQsMCwwLHZhbHVlLmxlbmd0aCk7cmV0dXJuIG91dH1pZih2YWx1ZSl7aWYoQXJyYXkuaXNBcnJheSh2YWx1ZSl8fHR5cGVvZiBBcnJheUJ1ZmZlciE9PVwidW5kZWZpbmVkXCImJnZhbHVlLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHxcImxlbmd0aFwiaW4gdmFsdWUpe3JldHVybiBuZXcgQnVmZmVyKHZhbHVlKX1pZih2YWx1ZS50eXBlPT09XCJCdWZmZXJcIiYmQXJyYXkuaXNBcnJheSh2YWx1ZS5kYXRhKSl7cmV0dXJuIG5ldyBCdWZmZXIodmFsdWUuZGF0YSl9fXRocm93IG5ldyBUeXBlRXJyb3IoXCJGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsIFwiK1wiQXJyYXlCdWZmZXIsIEFycmF5LCBvciBhcnJheS1saWtlIG9iamVjdC5cIil9O2V4cG9ydHMuYWxsb2NVbnNhZmVTbG93PWZ1bmN0aW9uIGFsbG9jVW5zYWZlU2xvdyhzaXplKXtpZih0eXBlb2YgQnVmZmVyLmFsbG9jVW5zYWZlU2xvdz09PVwiZnVuY3Rpb25cIil7cmV0dXJuIEJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3coc2l6ZSl9aWYodHlwZW9mIHNpemUhPT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwic2l6ZSBtdXN0IGJlIGEgbnVtYmVyXCIpfWlmKHNpemU+PU1BWF9MRU4pe3Rocm93IG5ldyBSYW5nZUVycm9yKFwic2l6ZSBpcyB0b28gbGFyZ2VcIil9cmV0dXJuIG5ldyBTbG93QnVmZmVyKHNpemUpfX0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsIT09XCJ1bmRlZmluZWRcIj9nbG9iYWw6dHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiP3NlbGY6dHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCI/d2luZG93Ont9KX0se2J1ZmZlcjo1fV0sNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKGdsb2JhbCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGJhc2U2ND1yZXF1aXJlKFwiYmFzZTY0LWpzXCIpO3ZhciBpZWVlNzU0PXJlcXVpcmUoXCJpZWVlNzU0XCIpO3ZhciBpc0FycmF5PXJlcXVpcmUoXCJpc2FycmF5XCIpO2V4cG9ydHMuQnVmZmVyPUJ1ZmZlcjtleHBvcnRzLlNsb3dCdWZmZXI9U2xvd0J1ZmZlcjtleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTPTUwO0J1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUPWdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUIT09dW5kZWZpbmVkP2dsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUOnR5cGVkQXJyYXlTdXBwb3J0KCk7ZXhwb3J0cy5rTWF4TGVuZ3RoPWtNYXhMZW5ndGgoKTtmdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCgpe3RyeXt2YXIgYXJyPW5ldyBVaW50OEFycmF5KDEpO2Fyci5fX3Byb3RvX189e19fcHJvdG9fXzpVaW50OEFycmF5LnByb3RvdHlwZSxmb286ZnVuY3Rpb24oKXtyZXR1cm4gNDJ9fTtyZXR1cm4gYXJyLmZvbygpPT09NDImJnR5cGVvZiBhcnIuc3ViYXJyYXk9PT1cImZ1bmN0aW9uXCImJmFyci5zdWJhcnJheSgxLDEpLmJ5dGVMZW5ndGg9PT0wfWNhdGNoKGUpe3JldHVybiBmYWxzZX19ZnVuY3Rpb24ga01heExlbmd0aCgpe3JldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVD8yMTQ3NDgzNjQ3OjEwNzM3NDE4MjN9ZnVuY3Rpb24gY3JlYXRlQnVmZmVyKHRoYXQsbGVuZ3RoKXtpZihrTWF4TGVuZ3RoKCk8bGVuZ3RoKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgdHlwZWQgYXJyYXkgbGVuZ3RoXCIpfWlmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGF0PW5ldyBVaW50OEFycmF5KGxlbmd0aCk7dGhhdC5fX3Byb3RvX189QnVmZmVyLnByb3RvdHlwZX1lbHNle2lmKHRoYXQ9PT1udWxsKXt0aGF0PW5ldyBCdWZmZXIobGVuZ3RoKX10aGF0Lmxlbmd0aD1sZW5ndGh9cmV0dXJuIHRoYXR9ZnVuY3Rpb24gQnVmZmVyKGFyZyxlbmNvZGluZ09yT2Zmc2V0LGxlbmd0aCl7aWYoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUJiYhKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKXtyZXR1cm4gbmV3IEJ1ZmZlcihhcmcsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpfWlmKHR5cGVvZiBhcmc9PT1cIm51bWJlclwiKXtpZih0eXBlb2YgZW5jb2RpbmdPck9mZnNldD09PVwic3RyaW5nXCIpe3Rocm93IG5ldyBFcnJvcihcIklmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nXCIpfXJldHVybiBhbGxvY1Vuc2FmZSh0aGlzLGFyZyl9cmV0dXJuIGZyb20odGhpcyxhcmcsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpfUJ1ZmZlci5wb29sU2l6ZT04MTkyO0J1ZmZlci5fYXVnbWVudD1mdW5jdGlvbihhcnIpe2Fyci5fX3Byb3RvX189QnVmZmVyLnByb3RvdHlwZTtyZXR1cm4gYXJyfTtmdW5jdGlvbiBmcm9tKHRoYXQsdmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpe2lmKHR5cGVvZiB2YWx1ZT09PVwibnVtYmVyXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpfWlmKHR5cGVvZiBBcnJheUJ1ZmZlciE9PVwidW5kZWZpbmVkXCImJnZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpe3JldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCx2YWx1ZSxlbmNvZGluZ09yT2Zmc2V0LGxlbmd0aCl9aWYodHlwZW9mIHZhbHVlPT09XCJzdHJpbmdcIil7cmV0dXJuIGZyb21TdHJpbmcodGhhdCx2YWx1ZSxlbmNvZGluZ09yT2Zmc2V0KX1yZXR1cm4gZnJvbU9iamVjdCh0aGF0LHZhbHVlKX1CdWZmZXIuZnJvbT1mdW5jdGlvbih2YWx1ZSxlbmNvZGluZ09yT2Zmc2V0LGxlbmd0aCl7cmV0dXJuIGZyb20obnVsbCx2YWx1ZSxlbmNvZGluZ09yT2Zmc2V0LGxlbmd0aCl9O2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXtCdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXz1VaW50OEFycmF5LnByb3RvdHlwZTtCdWZmZXIuX19wcm90b19fPVVpbnQ4QXJyYXk7aWYodHlwZW9mIFN5bWJvbCE9PVwidW5kZWZpbmVkXCImJlN5bWJvbC5zcGVjaWVzJiZCdWZmZXJbU3ltYm9sLnNwZWNpZXNdPT09QnVmZmVyKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLFN5bWJvbC5zcGVjaWVzLHt2YWx1ZTpudWxsLGNvbmZpZ3VyYWJsZTp0cnVlfSl9fWZ1bmN0aW9uIGFzc2VydFNpemUoc2l6ZSl7aWYodHlwZW9mIHNpemUhPT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJyl9ZWxzZSBpZihzaXplPDApe3Rocm93IG5ldyBSYW5nZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBuZWdhdGl2ZScpfX1mdW5jdGlvbiBhbGxvYyh0aGF0LHNpemUsZmlsbCxlbmNvZGluZyl7YXNzZXJ0U2l6ZShzaXplKTtpZihzaXplPD0wKXtyZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsc2l6ZSl9aWYoZmlsbCE9PXVuZGVmaW5lZCl7cmV0dXJuIHR5cGVvZiBlbmNvZGluZz09PVwic3RyaW5nXCI/Y3JlYXRlQnVmZmVyKHRoYXQsc2l6ZSkuZmlsbChmaWxsLGVuY29kaW5nKTpjcmVhdGVCdWZmZXIodGhhdCxzaXplKS5maWxsKGZpbGwpfXJldHVybiBjcmVhdGVCdWZmZXIodGhhdCxzaXplKX1CdWZmZXIuYWxsb2M9ZnVuY3Rpb24oc2l6ZSxmaWxsLGVuY29kaW5nKXtyZXR1cm4gYWxsb2MobnVsbCxzaXplLGZpbGwsZW5jb2RpbmcpfTtmdW5jdGlvbiBhbGxvY1Vuc2FmZSh0aGF0LHNpemUpe2Fzc2VydFNpemUoc2l6ZSk7dGhhdD1jcmVhdGVCdWZmZXIodGhhdCxzaXplPDA/MDpjaGVja2VkKHNpemUpfDApO2lmKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7Zm9yKHZhciBpPTA7aTxzaXplOysraSl7dGhhdFtpXT0wfX1yZXR1cm4gdGhhdH1CdWZmZXIuYWxsb2NVbnNhZmU9ZnVuY3Rpb24oc2l6ZSl7cmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsc2l6ZSl9O0J1ZmZlci5hbGxvY1Vuc2FmZVNsb3c9ZnVuY3Rpb24oc2l6ZSl7cmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsc2l6ZSl9O2Z1bmN0aW9uIGZyb21TdHJpbmcodGhhdCxzdHJpbmcsZW5jb2Rpbmcpe2lmKHR5cGVvZiBlbmNvZGluZyE9PVwic3RyaW5nXCJ8fGVuY29kaW5nPT09XCJcIil7ZW5jb2Rpbmc9XCJ1dGY4XCJ9aWYoIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSl7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJlbmNvZGluZ1wiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgZW5jb2RpbmcnKX12YXIgbGVuZ3RoPWJ5dGVMZW5ndGgoc3RyaW5nLGVuY29kaW5nKXwwO3RoYXQ9Y3JlYXRlQnVmZmVyKHRoYXQsbGVuZ3RoKTt2YXIgYWN0dWFsPXRoYXQud3JpdGUoc3RyaW5nLGVuY29kaW5nKTtpZihhY3R1YWwhPT1sZW5ndGgpe3RoYXQ9dGhhdC5zbGljZSgwLGFjdHVhbCl9cmV0dXJuIHRoYXR9ZnVuY3Rpb24gZnJvbUFycmF5TGlrZSh0aGF0LGFycmF5KXt2YXIgbGVuZ3RoPWFycmF5Lmxlbmd0aDwwPzA6Y2hlY2tlZChhcnJheS5sZW5ndGgpfDA7dGhhdD1jcmVhdGVCdWZmZXIodGhhdCxsZW5ndGgpO2Zvcih2YXIgaT0wO2k8bGVuZ3RoO2krPTEpe3RoYXRbaV09YXJyYXlbaV0mMjU1fXJldHVybiB0aGF0fWZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlcih0aGF0LGFycmF5LGJ5dGVPZmZzZXQsbGVuZ3RoKXthcnJheS5ieXRlTGVuZ3RoO2lmKGJ5dGVPZmZzZXQ8MHx8YXJyYXkuYnl0ZUxlbmd0aDxieXRlT2Zmc2V0KXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIidvZmZzZXQnIGlzIG91dCBvZiBib3VuZHNcIil9aWYoYXJyYXkuYnl0ZUxlbmd0aDxieXRlT2Zmc2V0KyhsZW5ndGh8fDApKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIidsZW5ndGgnIGlzIG91dCBvZiBib3VuZHNcIil9aWYoYnl0ZU9mZnNldD09PXVuZGVmaW5lZCYmbGVuZ3RoPT09dW5kZWZpbmVkKXthcnJheT1uZXcgVWludDhBcnJheShhcnJheSl9ZWxzZSBpZihsZW5ndGg9PT11bmRlZmluZWQpe2FycmF5PW5ldyBVaW50OEFycmF5KGFycmF5LGJ5dGVPZmZzZXQpfWVsc2V7YXJyYXk9bmV3IFVpbnQ4QXJyYXkoYXJyYXksYnl0ZU9mZnNldCxsZW5ndGgpfWlmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGF0PWFycmF5O3RoYXQuX19wcm90b19fPUJ1ZmZlci5wcm90b3R5cGV9ZWxzZXt0aGF0PWZyb21BcnJheUxpa2UodGhhdCxhcnJheSl9cmV0dXJuIHRoYXR9ZnVuY3Rpb24gZnJvbU9iamVjdCh0aGF0LG9iail7aWYoQnVmZmVyLmlzQnVmZmVyKG9iaikpe3ZhciBsZW49Y2hlY2tlZChvYmoubGVuZ3RoKXwwO3RoYXQ9Y3JlYXRlQnVmZmVyKHRoYXQsbGVuKTtpZih0aGF0Lmxlbmd0aD09PTApe3JldHVybiB0aGF0fW9iai5jb3B5KHRoYXQsMCwwLGxlbik7cmV0dXJuIHRoYXR9aWYob2JqKXtpZih0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZvYmouYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXJ8fFwibGVuZ3RoXCJpbiBvYmope2lmKHR5cGVvZiBvYmoubGVuZ3RoIT09XCJudW1iZXJcInx8aXNuYW4ob2JqLmxlbmd0aCkpe3JldHVybiBjcmVhdGVCdWZmZXIodGhhdCwwKX1yZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LG9iail9aWYob2JqLnR5cGU9PT1cIkJ1ZmZlclwiJiZpc0FycmF5KG9iai5kYXRhKSl7cmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCxvYmouZGF0YSl9fXRocm93IG5ldyBUeXBlRXJyb3IoXCJGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuXCIpfWZ1bmN0aW9uIGNoZWNrZWQobGVuZ3RoKXtpZihsZW5ndGg+PWtNYXhMZW5ndGgoKSl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtIFwiK1wic2l6ZTogMHhcIitrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpK1wiIGJ5dGVzXCIpfXJldHVybiBsZW5ndGh8MH1mdW5jdGlvbiBTbG93QnVmZmVyKGxlbmd0aCl7aWYoK2xlbmd0aCE9bGVuZ3RoKXtsZW5ndGg9MH1yZXR1cm4gQnVmZmVyLmFsbG9jKCtsZW5ndGgpfUJ1ZmZlci5pc0J1ZmZlcj1mdW5jdGlvbiBpc0J1ZmZlcihiKXtyZXR1cm4hIShiIT1udWxsJiZiLl9pc0J1ZmZlcil9O0J1ZmZlci5jb21wYXJlPWZ1bmN0aW9uIGNvbXBhcmUoYSxiKXtpZighQnVmZmVyLmlzQnVmZmVyKGEpfHwhQnVmZmVyLmlzQnVmZmVyKGIpKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnRzIG11c3QgYmUgQnVmZmVyc1wiKX1pZihhPT09YilyZXR1cm4gMDt2YXIgeD1hLmxlbmd0aDt2YXIgeT1iLmxlbmd0aDtmb3IodmFyIGk9MCxsZW49TWF0aC5taW4oeCx5KTtpPGxlbjsrK2kpe2lmKGFbaV0hPT1iW2ldKXt4PWFbaV07eT1iW2ldO2JyZWFrfX1pZih4PHkpcmV0dXJuLTE7aWYoeTx4KXJldHVybiAxO3JldHVybiAwfTtCdWZmZXIuaXNFbmNvZGluZz1mdW5jdGlvbiBpc0VuY29kaW5nKGVuY29kaW5nKXtzd2l0Y2goU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKXtjYXNlXCJoZXhcIjpjYXNlXCJ1dGY4XCI6Y2FzZVwidXRmLThcIjpjYXNlXCJhc2NpaVwiOmNhc2VcImxhdGluMVwiOmNhc2VcImJpbmFyeVwiOmNhc2VcImJhc2U2NFwiOmNhc2VcInVjczJcIjpjYXNlXCJ1Y3MtMlwiOmNhc2VcInV0ZjE2bGVcIjpjYXNlXCJ1dGYtMTZsZVwiOnJldHVybiB0cnVlO2RlZmF1bHQ6cmV0dXJuIGZhbHNlfX07QnVmZmVyLmNvbmNhdD1mdW5jdGlvbiBjb25jYXQobGlzdCxsZW5ndGgpe2lmKCFpc0FycmF5KGxpc3QpKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKX1pZihsaXN0Lmxlbmd0aD09PTApe3JldHVybiBCdWZmZXIuYWxsb2MoMCl9dmFyIGk7aWYobGVuZ3RoPT09dW5kZWZpbmVkKXtsZW5ndGg9MDtmb3IoaT0wO2k8bGlzdC5sZW5ndGg7KytpKXtsZW5ndGgrPWxpc3RbaV0ubGVuZ3RofX12YXIgYnVmZmVyPUJ1ZmZlci5hbGxvY1Vuc2FmZShsZW5ndGgpO3ZhciBwb3M9MDtmb3IoaT0wO2k8bGlzdC5sZW5ndGg7KytpKXt2YXIgYnVmPWxpc3RbaV07aWYoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKX1idWYuY29weShidWZmZXIscG9zKTtwb3MrPWJ1Zi5sZW5ndGh9cmV0dXJuIGJ1ZmZlcn07ZnVuY3Rpb24gYnl0ZUxlbmd0aChzdHJpbmcsZW5jb2Rpbmcpe2lmKEJ1ZmZlci5pc0J1ZmZlcihzdHJpbmcpKXtyZXR1cm4gc3RyaW5nLmxlbmd0aH1pZih0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZ0eXBlb2YgQXJyYXlCdWZmZXIuaXNWaWV3PT09XCJmdW5jdGlvblwiJiYoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZyl8fHN0cmluZyBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSl7cmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RofWlmKHR5cGVvZiBzdHJpbmchPT1cInN0cmluZ1wiKXtzdHJpbmc9XCJcIitzdHJpbmd9dmFyIGxlbj1zdHJpbmcubGVuZ3RoO2lmKGxlbj09PTApcmV0dXJuIDA7dmFyIGxvd2VyZWRDYXNlPWZhbHNlO2Zvcig7Oyl7c3dpdGNoKGVuY29kaW5nKXtjYXNlXCJhc2NpaVwiOmNhc2VcImxhdGluMVwiOmNhc2VcImJpbmFyeVwiOnJldHVybiBsZW47Y2FzZVwidXRmOFwiOmNhc2VcInV0Zi04XCI6Y2FzZSB1bmRlZmluZWQ6cmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoO2Nhc2VcInVjczJcIjpjYXNlXCJ1Y3MtMlwiOmNhc2VcInV0ZjE2bGVcIjpjYXNlXCJ1dGYtMTZsZVwiOnJldHVybiBsZW4qMjtjYXNlXCJoZXhcIjpyZXR1cm4gbGVuPj4+MTtjYXNlXCJiYXNlNjRcIjpyZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aDtkZWZhdWx0OmlmKGxvd2VyZWRDYXNlKXJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aDtlbmNvZGluZz0oXCJcIitlbmNvZGluZykudG9Mb3dlckNhc2UoKTtsb3dlcmVkQ2FzZT10cnVlfX19QnVmZmVyLmJ5dGVMZW5ndGg9Ynl0ZUxlbmd0aDtmdW5jdGlvbiBzbG93VG9TdHJpbmcoZW5jb2Rpbmcsc3RhcnQsZW5kKXt2YXIgbG93ZXJlZENhc2U9ZmFsc2U7aWYoc3RhcnQ9PT11bmRlZmluZWR8fHN0YXJ0PDApe3N0YXJ0PTB9aWYoc3RhcnQ+dGhpcy5sZW5ndGgpe3JldHVyblwiXCJ9aWYoZW5kPT09dW5kZWZpbmVkfHxlbmQ+dGhpcy5sZW5ndGgpe2VuZD10aGlzLmxlbmd0aH1pZihlbmQ8PTApe3JldHVyblwiXCJ9ZW5kPj4+PTA7c3RhcnQ+Pj49MDtpZihlbmQ8PXN0YXJ0KXtyZXR1cm5cIlwifWlmKCFlbmNvZGluZyllbmNvZGluZz1cInV0ZjhcIjt3aGlsZSh0cnVlKXtzd2l0Y2goZW5jb2Rpbmcpe2Nhc2VcImhleFwiOnJldHVybiBoZXhTbGljZSh0aGlzLHN0YXJ0LGVuZCk7Y2FzZVwidXRmOFwiOmNhc2VcInV0Zi04XCI6cmV0dXJuIHV0ZjhTbGljZSh0aGlzLHN0YXJ0LGVuZCk7Y2FzZVwiYXNjaWlcIjpyZXR1cm4gYXNjaWlTbGljZSh0aGlzLHN0YXJ0LGVuZCk7Y2FzZVwibGF0aW4xXCI6Y2FzZVwiYmluYXJ5XCI6cmV0dXJuIGxhdGluMVNsaWNlKHRoaXMsc3RhcnQsZW5kKTtjYXNlXCJiYXNlNjRcIjpyZXR1cm4gYmFzZTY0U2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcInVjczJcIjpjYXNlXCJ1Y3MtMlwiOmNhc2VcInV0ZjE2bGVcIjpjYXNlXCJ1dGYtMTZsZVwiOnJldHVybiB1dGYxNmxlU2xpY2UodGhpcyxzdGFydCxlbmQpO2RlZmF1bHQ6aWYobG93ZXJlZENhc2UpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKTtlbmNvZGluZz0oZW5jb2RpbmcrXCJcIikudG9Mb3dlckNhc2UoKTtsb3dlcmVkQ2FzZT10cnVlfX19QnVmZmVyLnByb3RvdHlwZS5faXNCdWZmZXI9dHJ1ZTtmdW5jdGlvbiBzd2FwKGIsbixtKXt2YXIgaT1iW25dO2Jbbl09YlttXTtiW21dPWl9QnVmZmVyLnByb3RvdHlwZS5zd2FwMTY9ZnVuY3Rpb24gc3dhcDE2KCl7dmFyIGxlbj10aGlzLmxlbmd0aDtpZihsZW4lMiE9PTApe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHNcIil9Zm9yKHZhciBpPTA7aTxsZW47aSs9Mil7c3dhcCh0aGlzLGksaSsxKX1yZXR1cm4gdGhpc307QnVmZmVyLnByb3RvdHlwZS5zd2FwMzI9ZnVuY3Rpb24gc3dhcDMyKCl7dmFyIGxlbj10aGlzLmxlbmd0aDtpZihsZW4lNCE9PTApe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDMyLWJpdHNcIil9Zm9yKHZhciBpPTA7aTxsZW47aSs9NCl7c3dhcCh0aGlzLGksaSszKTtzd2FwKHRoaXMsaSsxLGkrMil9cmV0dXJuIHRoaXN9O0J1ZmZlci5wcm90b3R5cGUuc3dhcDY0PWZ1bmN0aW9uIHN3YXA2NCgpe3ZhciBsZW49dGhpcy5sZW5ndGg7aWYobGVuJTghPT0wKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkJ1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA2NC1iaXRzXCIpfWZvcih2YXIgaT0wO2k8bGVuO2krPTgpe3N3YXAodGhpcyxpLGkrNyk7c3dhcCh0aGlzLGkrMSxpKzYpO3N3YXAodGhpcyxpKzIsaSs1KTtzd2FwKHRoaXMsaSszLGkrNCl9cmV0dXJuIHRoaXN9O0J1ZmZlci5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24gdG9TdHJpbmcoKXt2YXIgbGVuZ3RoPXRoaXMubGVuZ3RofDA7aWYobGVuZ3RoPT09MClyZXR1cm5cIlwiO2lmKGFyZ3VtZW50cy5sZW5ndGg9PT0wKXJldHVybiB1dGY4U2xpY2UodGhpcywwLGxlbmd0aCk7cmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLGFyZ3VtZW50cyl9O0J1ZmZlci5wcm90b3R5cGUuZXF1YWxzPWZ1bmN0aW9uIGVxdWFscyhiKXtpZighQnVmZmVyLmlzQnVmZmVyKGIpKXRocm93IG5ldyBUeXBlRXJyb3IoXCJBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyXCIpO2lmKHRoaXM9PT1iKXJldHVybiB0cnVlO3JldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLGIpPT09MH07QnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0PWZ1bmN0aW9uIGluc3BlY3QoKXt2YXIgc3RyPVwiXCI7dmFyIG1heD1leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTO2lmKHRoaXMubGVuZ3RoPjApe3N0cj10aGlzLnRvU3RyaW5nKFwiaGV4XCIsMCxtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oXCIgXCIpO2lmKHRoaXMubGVuZ3RoPm1heClzdHIrPVwiIC4uLiBcIn1yZXR1cm5cIjxCdWZmZXIgXCIrc3RyK1wiPlwifTtCdWZmZXIucHJvdG90eXBlLmNvbXBhcmU9ZnVuY3Rpb24gY29tcGFyZSh0YXJnZXQsc3RhcnQsZW5kLHRoaXNTdGFydCx0aGlzRW5kKXtpZighQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyXCIpfWlmKHN0YXJ0PT09dW5kZWZpbmVkKXtzdGFydD0wfWlmKGVuZD09PXVuZGVmaW5lZCl7ZW5kPXRhcmdldD90YXJnZXQubGVuZ3RoOjB9aWYodGhpc1N0YXJ0PT09dW5kZWZpbmVkKXt0aGlzU3RhcnQ9MH1pZih0aGlzRW5kPT09dW5kZWZpbmVkKXt0aGlzRW5kPXRoaXMubGVuZ3RofWlmKHN0YXJ0PDB8fGVuZD50YXJnZXQubGVuZ3RofHx0aGlzU3RhcnQ8MHx8dGhpc0VuZD50aGlzLmxlbmd0aCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJvdXQgb2YgcmFuZ2UgaW5kZXhcIil9aWYodGhpc1N0YXJ0Pj10aGlzRW5kJiZzdGFydD49ZW5kKXtyZXR1cm4gMH1pZih0aGlzU3RhcnQ+PXRoaXNFbmQpe3JldHVybi0xfWlmKHN0YXJ0Pj1lbmQpe3JldHVybiAxfXN0YXJ0Pj4+PTA7ZW5kPj4+PTA7dGhpc1N0YXJ0Pj4+PTA7dGhpc0VuZD4+Pj0wO2lmKHRoaXM9PT10YXJnZXQpcmV0dXJuIDA7dmFyIHg9dGhpc0VuZC10aGlzU3RhcnQ7dmFyIHk9ZW5kLXN0YXJ0O3ZhciBsZW49TWF0aC5taW4oeCx5KTt2YXIgdGhpc0NvcHk9dGhpcy5zbGljZSh0aGlzU3RhcnQsdGhpc0VuZCk7dmFyIHRhcmdldENvcHk9dGFyZ2V0LnNsaWNlKHN0YXJ0LGVuZCk7Zm9yKHZhciBpPTA7aTxsZW47KytpKXtpZih0aGlzQ29weVtpXSE9PXRhcmdldENvcHlbaV0pe3g9dGhpc0NvcHlbaV07eT10YXJnZXRDb3B5W2ldO2JyZWFrfX1pZih4PHkpcmV0dXJuLTE7aWYoeTx4KXJldHVybiAxO3JldHVybiAwfTtmdW5jdGlvbiBiaWRpcmVjdGlvbmFsSW5kZXhPZihidWZmZXIsdmFsLGJ5dGVPZmZzZXQsZW5jb2RpbmcsZGlyKXtpZihidWZmZXIubGVuZ3RoPT09MClyZXR1cm4tMTtpZih0eXBlb2YgYnl0ZU9mZnNldD09PVwic3RyaW5nXCIpe2VuY29kaW5nPWJ5dGVPZmZzZXQ7Ynl0ZU9mZnNldD0wfWVsc2UgaWYoYnl0ZU9mZnNldD4yMTQ3NDgzNjQ3KXtieXRlT2Zmc2V0PTIxNDc0ODM2NDd9ZWxzZSBpZihieXRlT2Zmc2V0PC0yMTQ3NDgzNjQ4KXtieXRlT2Zmc2V0PS0yMTQ3NDgzNjQ4fWJ5dGVPZmZzZXQ9K2J5dGVPZmZzZXQ7aWYoaXNOYU4oYnl0ZU9mZnNldCkpe2J5dGVPZmZzZXQ9ZGlyPzA6YnVmZmVyLmxlbmd0aC0xfWlmKGJ5dGVPZmZzZXQ8MClieXRlT2Zmc2V0PWJ1ZmZlci5sZW5ndGgrYnl0ZU9mZnNldDtpZihieXRlT2Zmc2V0Pj1idWZmZXIubGVuZ3RoKXtpZihkaXIpcmV0dXJuLTE7ZWxzZSBieXRlT2Zmc2V0PWJ1ZmZlci5sZW5ndGgtMX1lbHNlIGlmKGJ5dGVPZmZzZXQ8MCl7aWYoZGlyKWJ5dGVPZmZzZXQ9MDtlbHNlIHJldHVybi0xfWlmKHR5cGVvZiB2YWw9PT1cInN0cmluZ1wiKXt2YWw9QnVmZmVyLmZyb20odmFsLGVuY29kaW5nKX1pZihCdWZmZXIuaXNCdWZmZXIodmFsKSl7aWYodmFsLmxlbmd0aD09PTApe3JldHVybi0xfXJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLGRpcil9ZWxzZSBpZih0eXBlb2YgdmFsPT09XCJudW1iZXJcIil7dmFsPXZhbCYyNTU7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQmJnR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mPT09XCJmdW5jdGlvblwiKXtpZihkaXIpe3JldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoYnVmZmVyLHZhbCxieXRlT2Zmc2V0KX1lbHNle3JldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZi5jYWxsKGJ1ZmZlcix2YWwsYnl0ZU9mZnNldCl9fXJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLFt2YWxdLGJ5dGVPZmZzZXQsZW5jb2RpbmcsZGlyKX10aHJvdyBuZXcgVHlwZUVycm9yKFwidmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyXCIpfWZ1bmN0aW9uIGFycmF5SW5kZXhPZihhcnIsdmFsLGJ5dGVPZmZzZXQsZW5jb2RpbmcsZGlyKXt2YXIgaW5kZXhTaXplPTE7dmFyIGFyckxlbmd0aD1hcnIubGVuZ3RoO3ZhciB2YWxMZW5ndGg9dmFsLmxlbmd0aDtpZihlbmNvZGluZyE9PXVuZGVmaW5lZCl7ZW5jb2Rpbmc9U3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpO2lmKGVuY29kaW5nPT09XCJ1Y3MyXCJ8fGVuY29kaW5nPT09XCJ1Y3MtMlwifHxlbmNvZGluZz09PVwidXRmMTZsZVwifHxlbmNvZGluZz09PVwidXRmLTE2bGVcIil7aWYoYXJyLmxlbmd0aDwyfHx2YWwubGVuZ3RoPDIpe3JldHVybi0xfWluZGV4U2l6ZT0yO2Fyckxlbmd0aC89Mjt2YWxMZW5ndGgvPTI7Ynl0ZU9mZnNldC89Mn19ZnVuY3Rpb24gcmVhZChidWYsaSl7aWYoaW5kZXhTaXplPT09MSl7cmV0dXJuIGJ1ZltpXX1lbHNle3JldHVybiBidWYucmVhZFVJbnQxNkJFKGkqaW5kZXhTaXplKX19dmFyIGk7aWYoZGlyKXt2YXIgZm91bmRJbmRleD0tMTtmb3IoaT1ieXRlT2Zmc2V0O2k8YXJyTGVuZ3RoO2krKyl7aWYocmVhZChhcnIsaSk9PT1yZWFkKHZhbCxmb3VuZEluZGV4PT09LTE/MDppLWZvdW5kSW5kZXgpKXtpZihmb3VuZEluZGV4PT09LTEpZm91bmRJbmRleD1pO2lmKGktZm91bmRJbmRleCsxPT09dmFsTGVuZ3RoKXJldHVybiBmb3VuZEluZGV4KmluZGV4U2l6ZX1lbHNle2lmKGZvdW5kSW5kZXghPT0tMSlpLT1pLWZvdW5kSW5kZXg7Zm91bmRJbmRleD0tMX19fWVsc2V7aWYoYnl0ZU9mZnNldCt2YWxMZW5ndGg+YXJyTGVuZ3RoKWJ5dGVPZmZzZXQ9YXJyTGVuZ3RoLXZhbExlbmd0aDtmb3IoaT1ieXRlT2Zmc2V0O2k+PTA7aS0tKXt2YXIgZm91bmQ9dHJ1ZTtmb3IodmFyIGo9MDtqPHZhbExlbmd0aDtqKyspe2lmKHJlYWQoYXJyLGkraikhPT1yZWFkKHZhbCxqKSl7Zm91bmQ9ZmFsc2U7YnJlYWt9fWlmKGZvdW5kKXJldHVybiBpfX1yZXR1cm4tMX1CdWZmZXIucHJvdG90eXBlLmluY2x1ZGVzPWZ1bmN0aW9uIGluY2x1ZGVzKHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nKXtyZXR1cm4gdGhpcy5pbmRleE9mKHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nKSE9PS0xfTtCdWZmZXIucHJvdG90eXBlLmluZGV4T2Y9ZnVuY3Rpb24gaW5kZXhPZih2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyl7cmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsdmFsLGJ5dGVPZmZzZXQsZW5jb2RpbmcsdHJ1ZSl9O0J1ZmZlci5wcm90b3R5cGUubGFzdEluZGV4T2Y9ZnVuY3Rpb24gbGFzdEluZGV4T2YodmFsLGJ5dGVPZmZzZXQsZW5jb2Rpbmcpe3JldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLGZhbHNlKX07ZnVuY3Rpb24gaGV4V3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtvZmZzZXQ9TnVtYmVyKG9mZnNldCl8fDA7dmFyIHJlbWFpbmluZz1idWYubGVuZ3RoLW9mZnNldDtpZighbGVuZ3RoKXtsZW5ndGg9cmVtYWluaW5nfWVsc2V7bGVuZ3RoPU51bWJlcihsZW5ndGgpO2lmKGxlbmd0aD5yZW1haW5pbmcpe2xlbmd0aD1yZW1haW5pbmd9fXZhciBzdHJMZW49c3RyaW5nLmxlbmd0aDtpZihzdHJMZW4lMiE9PTApdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgaGV4IHN0cmluZ1wiKTtpZihsZW5ndGg+c3RyTGVuLzIpe2xlbmd0aD1zdHJMZW4vMn1mb3IodmFyIGk9MDtpPGxlbmd0aDsrK2kpe3ZhciBwYXJzZWQ9cGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpKjIsMiksMTYpO2lmKGlzTmFOKHBhcnNlZCkpcmV0dXJuIGk7YnVmW29mZnNldCtpXT1wYXJzZWR9cmV0dXJuIGl9ZnVuY3Rpb24gdXRmOFdyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl7cmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLGJ1Zi5sZW5ndGgtb2Zmc2V0KSxidWYsb2Zmc2V0LGxlbmd0aCl9ZnVuY3Rpb24gYXNjaWlXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpe3JldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLGJ1ZixvZmZzZXQsbGVuZ3RoKX1mdW5jdGlvbiBsYXRpbjFXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpe3JldHVybiBhc2NpaVdyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl9ZnVuY3Rpb24gYmFzZTY0V3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksYnVmLG9mZnNldCxsZW5ndGgpfWZ1bmN0aW9uIHVjczJXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpe3JldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZyxidWYubGVuZ3RoLW9mZnNldCksYnVmLG9mZnNldCxsZW5ndGgpfUJ1ZmZlci5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24gd3JpdGUoc3RyaW5nLG9mZnNldCxsZW5ndGgsZW5jb2Rpbmcpe2lmKG9mZnNldD09PXVuZGVmaW5lZCl7ZW5jb2Rpbmc9XCJ1dGY4XCI7bGVuZ3RoPXRoaXMubGVuZ3RoO29mZnNldD0wfWVsc2UgaWYobGVuZ3RoPT09dW5kZWZpbmVkJiZ0eXBlb2Ygb2Zmc2V0PT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9b2Zmc2V0O2xlbmd0aD10aGlzLmxlbmd0aDtvZmZzZXQ9MH1lbHNlIGlmKGlzRmluaXRlKG9mZnNldCkpe29mZnNldD1vZmZzZXR8MDtpZihpc0Zpbml0ZShsZW5ndGgpKXtsZW5ndGg9bGVuZ3RofDA7aWYoZW5jb2Rpbmc9PT11bmRlZmluZWQpZW5jb2Rpbmc9XCJ1dGY4XCJ9ZWxzZXtlbmNvZGluZz1sZW5ndGg7bGVuZ3RoPXVuZGVmaW5lZH19ZWxzZXt0aHJvdyBuZXcgRXJyb3IoXCJCdWZmZXIud3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0WywgbGVuZ3RoXSkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZFwiKX12YXIgcmVtYWluaW5nPXRoaXMubGVuZ3RoLW9mZnNldDtpZihsZW5ndGg9PT11bmRlZmluZWR8fGxlbmd0aD5yZW1haW5pbmcpbGVuZ3RoPXJlbWFpbmluZztpZihzdHJpbmcubGVuZ3RoPjAmJihsZW5ndGg8MHx8b2Zmc2V0PDApfHxvZmZzZXQ+dGhpcy5sZW5ndGgpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiQXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHNcIil9aWYoIWVuY29kaW5nKWVuY29kaW5nPVwidXRmOFwiO3ZhciBsb3dlcmVkQ2FzZT1mYWxzZTtmb3IoOzspe3N3aXRjaChlbmNvZGluZyl7Y2FzZVwiaGV4XCI6cmV0dXJuIGhleFdyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2Nhc2VcInV0ZjhcIjpjYXNlXCJ1dGYtOFwiOnJldHVybiB1dGY4V3JpdGUodGhpcyxzdHJpbmcsb2Zmc2V0LGxlbmd0aCk7Y2FzZVwiYXNjaWlcIjpyZXR1cm4gYXNjaWlXcml0ZSh0aGlzLHN0cmluZyxvZmZzZXQsbGVuZ3RoKTtjYXNlXCJsYXRpbjFcIjpjYXNlXCJiaW5hcnlcIjpyZXR1cm4gbGF0aW4xV3JpdGUodGhpcyxzdHJpbmcsb2Zmc2V0LGxlbmd0aCk7Y2FzZVwiYmFzZTY0XCI6cmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2Nhc2VcInVjczJcIjpjYXNlXCJ1Y3MtMlwiOmNhc2VcInV0ZjE2bGVcIjpjYXNlXCJ1dGYtMTZsZVwiOnJldHVybiB1Y3MyV3JpdGUodGhpcyxzdHJpbmcsb2Zmc2V0LGxlbmd0aCk7ZGVmYXVsdDppZihsb3dlcmVkQ2FzZSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5rbm93biBlbmNvZGluZzogXCIrZW5jb2RpbmcpO2VuY29kaW5nPShcIlwiK2VuY29kaW5nKS50b0xvd2VyQ2FzZSgpO2xvd2VyZWRDYXNlPXRydWV9fX07QnVmZmVyLnByb3RvdHlwZS50b0pTT049ZnVuY3Rpb24gdG9KU09OKCl7cmV0dXJue3R5cGU6XCJCdWZmZXJcIixkYXRhOkFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2Fycnx8dGhpcywwKX19O2Z1bmN0aW9uIGJhc2U2NFNsaWNlKGJ1ZixzdGFydCxlbmQpe2lmKHN0YXJ0PT09MCYmZW5kPT09YnVmLmxlbmd0aCl7cmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zil9ZWxzZXtyZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LGVuZCkpfX1mdW5jdGlvbiB1dGY4U2xpY2UoYnVmLHN0YXJ0LGVuZCl7ZW5kPU1hdGgubWluKGJ1Zi5sZW5ndGgsZW5kKTt2YXIgcmVzPVtdO3ZhciBpPXN0YXJ0O3doaWxlKGk8ZW5kKXt2YXIgZmlyc3RCeXRlPWJ1ZltpXTt2YXIgY29kZVBvaW50PW51bGw7dmFyIGJ5dGVzUGVyU2VxdWVuY2U9Zmlyc3RCeXRlPjIzOT80OmZpcnN0Qnl0ZT4yMjM/MzpmaXJzdEJ5dGU+MTkxPzI6MTtpZihpK2J5dGVzUGVyU2VxdWVuY2U8PWVuZCl7dmFyIHNlY29uZEJ5dGUsdGhpcmRCeXRlLGZvdXJ0aEJ5dGUsdGVtcENvZGVQb2ludDtzd2l0Y2goYnl0ZXNQZXJTZXF1ZW5jZSl7Y2FzZSAxOmlmKGZpcnN0Qnl0ZTwxMjgpe2NvZGVQb2ludD1maXJzdEJ5dGV9YnJlYWs7Y2FzZSAyOnNlY29uZEJ5dGU9YnVmW2krMV07aWYoKHNlY29uZEJ5dGUmMTkyKT09PTEyOCl7dGVtcENvZGVQb2ludD0oZmlyc3RCeXRlJjMxKTw8NnxzZWNvbmRCeXRlJjYzO2lmKHRlbXBDb2RlUG9pbnQ+MTI3KXtjb2RlUG9pbnQ9dGVtcENvZGVQb2ludH19YnJlYWs7Y2FzZSAzOnNlY29uZEJ5dGU9YnVmW2krMV07dGhpcmRCeXRlPWJ1ZltpKzJdO2lmKChzZWNvbmRCeXRlJjE5Mik9PT0xMjgmJih0aGlyZEJ5dGUmMTkyKT09PTEyOCl7dGVtcENvZGVQb2ludD0oZmlyc3RCeXRlJjE1KTw8MTJ8KHNlY29uZEJ5dGUmNjMpPDw2fHRoaXJkQnl0ZSY2MztpZih0ZW1wQ29kZVBvaW50PjIwNDcmJih0ZW1wQ29kZVBvaW50PDU1Mjk2fHx0ZW1wQ29kZVBvaW50PjU3MzQzKSl7Y29kZVBvaW50PXRlbXBDb2RlUG9pbnR9fWJyZWFrO2Nhc2UgNDpzZWNvbmRCeXRlPWJ1ZltpKzFdO3RoaXJkQnl0ZT1idWZbaSsyXTtmb3VydGhCeXRlPWJ1ZltpKzNdO2lmKChzZWNvbmRCeXRlJjE5Mik9PT0xMjgmJih0aGlyZEJ5dGUmMTkyKT09PTEyOCYmKGZvdXJ0aEJ5dGUmMTkyKT09PTEyOCl7dGVtcENvZGVQb2ludD0oZmlyc3RCeXRlJjE1KTw8MTh8KHNlY29uZEJ5dGUmNjMpPDwxMnwodGhpcmRCeXRlJjYzKTw8Nnxmb3VydGhCeXRlJjYzO2lmKHRlbXBDb2RlUG9pbnQ+NjU1MzUmJnRlbXBDb2RlUG9pbnQ8MTExNDExMil7Y29kZVBvaW50PXRlbXBDb2RlUG9pbnR9fX19aWYoY29kZVBvaW50PT09bnVsbCl7Y29kZVBvaW50PTY1NTMzO2J5dGVzUGVyU2VxdWVuY2U9MX1lbHNlIGlmKGNvZGVQb2ludD42NTUzNSl7Y29kZVBvaW50LT02NTUzNjtyZXMucHVzaChjb2RlUG9pbnQ+Pj4xMCYxMDIzfDU1Mjk2KTtjb2RlUG9pbnQ9NTYzMjB8Y29kZVBvaW50JjEwMjN9cmVzLnB1c2goY29kZVBvaW50KTtpKz1ieXRlc1BlclNlcXVlbmNlfXJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKX12YXIgTUFYX0FSR1VNRU5UU19MRU5HVEg9NDA5NjtmdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkoY29kZVBvaW50cyl7dmFyIGxlbj1jb2RlUG9pbnRzLmxlbmd0aDtpZihsZW48PU1BWF9BUkdVTUVOVFNfTEVOR1RIKXtyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsY29kZVBvaW50cyl9dmFyIHJlcz1cIlwiO3ZhciBpPTA7d2hpbGUoaTxsZW4pe3Jlcys9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsY29kZVBvaW50cy5zbGljZShpLGkrPU1BWF9BUkdVTUVOVFNfTEVOR1RIKSl9cmV0dXJuIHJlc31mdW5jdGlvbiBhc2NpaVNsaWNlKGJ1ZixzdGFydCxlbmQpe3ZhciByZXQ9XCJcIjtlbmQ9TWF0aC5taW4oYnVmLmxlbmd0aCxlbmQpO2Zvcih2YXIgaT1zdGFydDtpPGVuZDsrK2kpe3JldCs9U3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0mMTI3KX1yZXR1cm4gcmV0fWZ1bmN0aW9uIGxhdGluMVNsaWNlKGJ1ZixzdGFydCxlbmQpe3ZhciByZXQ9XCJcIjtlbmQ9TWF0aC5taW4oYnVmLmxlbmd0aCxlbmQpO2Zvcih2YXIgaT1zdGFydDtpPGVuZDsrK2kpe3JldCs9U3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pfXJldHVybiByZXR9ZnVuY3Rpb24gaGV4U2xpY2UoYnVmLHN0YXJ0LGVuZCl7dmFyIGxlbj1idWYubGVuZ3RoO2lmKCFzdGFydHx8c3RhcnQ8MClzdGFydD0wO2lmKCFlbmR8fGVuZDwwfHxlbmQ+bGVuKWVuZD1sZW47dmFyIG91dD1cIlwiO2Zvcih2YXIgaT1zdGFydDtpPGVuZDsrK2kpe291dCs9dG9IZXgoYnVmW2ldKX1yZXR1cm4gb3V0fWZ1bmN0aW9uIHV0ZjE2bGVTbGljZShidWYsc3RhcnQsZW5kKXt2YXIgYnl0ZXM9YnVmLnNsaWNlKHN0YXJ0LGVuZCk7dmFyIHJlcz1cIlwiO2Zvcih2YXIgaT0wO2k8Ynl0ZXMubGVuZ3RoO2krPTIpe3Jlcys9U3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXStieXRlc1tpKzFdKjI1Nil9cmV0dXJuIHJlc31CdWZmZXIucHJvdG90eXBlLnNsaWNlPWZ1bmN0aW9uIHNsaWNlKHN0YXJ0LGVuZCl7dmFyIGxlbj10aGlzLmxlbmd0aDtzdGFydD1+fnN0YXJ0O2VuZD1lbmQ9PT11bmRlZmluZWQ/bGVuOn5+ZW5kO2lmKHN0YXJ0PDApe3N0YXJ0Kz1sZW47aWYoc3RhcnQ8MClzdGFydD0wfWVsc2UgaWYoc3RhcnQ+bGVuKXtzdGFydD1sZW59aWYoZW5kPDApe2VuZCs9bGVuO2lmKGVuZDwwKWVuZD0wfWVsc2UgaWYoZW5kPmxlbil7ZW5kPWxlbn1pZihlbmQ8c3RhcnQpZW5kPXN0YXJ0O3ZhciBuZXdCdWY7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe25ld0J1Zj10aGlzLnN1YmFycmF5KHN0YXJ0LGVuZCk7bmV3QnVmLl9fcHJvdG9fXz1CdWZmZXIucHJvdG90eXBlfWVsc2V7dmFyIHNsaWNlTGVuPWVuZC1zdGFydDtuZXdCdWY9bmV3IEJ1ZmZlcihzbGljZUxlbix1bmRlZmluZWQpO2Zvcih2YXIgaT0wO2k8c2xpY2VMZW47KytpKXtuZXdCdWZbaV09dGhpc1tpK3N0YXJ0XX19cmV0dXJuIG5ld0J1Zn07ZnVuY3Rpb24gY2hlY2tPZmZzZXQob2Zmc2V0LGV4dCxsZW5ndGgpe2lmKG9mZnNldCUxIT09MHx8b2Zmc2V0PDApdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJvZmZzZXQgaXMgbm90IHVpbnRcIik7aWYob2Zmc2V0K2V4dD5sZW5ndGgpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoXCIpfUJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRT1mdW5jdGlvbiByZWFkVUludExFKG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCxieXRlTGVuZ3RoLHRoaXMubGVuZ3RoKTt2YXIgdmFsPXRoaXNbb2Zmc2V0XTt2YXIgbXVsPTE7dmFyIGk9MDt3aGlsZSgrK2k8Ynl0ZUxlbmd0aCYmKG11bCo9MjU2KSl7dmFsKz10aGlzW29mZnNldCtpXSptdWx9cmV0dXJuIHZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFPWZ1bmN0aW9uIHJlYWRVSW50QkUob2Zmc2V0LGJ5dGVMZW5ndGgsbm9Bc3NlcnQpe29mZnNldD1vZmZzZXR8MDtieXRlTGVuZ3RoPWJ5dGVMZW5ndGh8MDtpZighbm9Bc3NlcnQpe2NoZWNrT2Zmc2V0KG9mZnNldCxieXRlTGVuZ3RoLHRoaXMubGVuZ3RoKX12YXIgdmFsPXRoaXNbb2Zmc2V0Ky0tYnl0ZUxlbmd0aF07dmFyIG11bD0xO3doaWxlKGJ5dGVMZW5ndGg+MCYmKG11bCo9MjU2KSl7dmFsKz10aGlzW29mZnNldCstLWJ5dGVMZW5ndGhdKm11bH1yZXR1cm4gdmFsfTtCdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OD1mdW5jdGlvbiByZWFkVUludDgob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDEsdGhpcy5sZW5ndGgpO3JldHVybiB0aGlzW29mZnNldF19O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFPWZ1bmN0aW9uIHJlYWRVSW50MTZMRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMix0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XXx0aGlzW29mZnNldCsxXTw8OH07QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkU9ZnVuY3Rpb24gcmVhZFVJbnQxNkJFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCwyLHRoaXMubGVuZ3RoKTtyZXR1cm4gdGhpc1tvZmZzZXRdPDw4fHRoaXNbb2Zmc2V0KzFdfTtCdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRT1mdW5jdGlvbiByZWFkVUludDMyTEUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDQsdGhpcy5sZW5ndGgpO3JldHVybih0aGlzW29mZnNldF18dGhpc1tvZmZzZXQrMV08PDh8dGhpc1tvZmZzZXQrMl08PDE2KSt0aGlzW29mZnNldCszXSoxNjc3NzIxNn07QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkU9ZnVuY3Rpb24gcmVhZFVJbnQzMkJFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw0LHRoaXMubGVuZ3RoKTtyZXR1cm4gdGhpc1tvZmZzZXRdKjE2Nzc3MjE2Kyh0aGlzW29mZnNldCsxXTw8MTZ8dGhpc1tvZmZzZXQrMl08PDh8dGhpc1tvZmZzZXQrM10pfTtCdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRT1mdW5jdGlvbiByZWFkSW50TEUob2Zmc2V0LGJ5dGVMZW5ndGgsbm9Bc3NlcnQpe29mZnNldD1vZmZzZXR8MDtieXRlTGVuZ3RoPWJ5dGVMZW5ndGh8MDtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LGJ5dGVMZW5ndGgsdGhpcy5sZW5ndGgpO3ZhciB2YWw9dGhpc1tvZmZzZXRdO3ZhciBtdWw9MTt2YXIgaT0wO3doaWxlKCsraTxieXRlTGVuZ3RoJiYobXVsKj0yNTYpKXt2YWwrPXRoaXNbb2Zmc2V0K2ldKm11bH1tdWwqPTEyODtpZih2YWw+PW11bCl2YWwtPU1hdGgucG93KDIsOCpieXRlTGVuZ3RoKTtyZXR1cm4gdmFsfTtCdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRT1mdW5jdGlvbiByZWFkSW50QkUob2Zmc2V0LGJ5dGVMZW5ndGgsbm9Bc3NlcnQpe29mZnNldD1vZmZzZXR8MDtieXRlTGVuZ3RoPWJ5dGVMZW5ndGh8MDtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LGJ5dGVMZW5ndGgsdGhpcy5sZW5ndGgpO1xudmFyIGk9Ynl0ZUxlbmd0aDt2YXIgbXVsPTE7dmFyIHZhbD10aGlzW29mZnNldCstLWldO3doaWxlKGk+MCYmKG11bCo9MjU2KSl7dmFsKz10aGlzW29mZnNldCstLWldKm11bH1tdWwqPTEyODtpZih2YWw+PW11bCl2YWwtPU1hdGgucG93KDIsOCpieXRlTGVuZ3RoKTtyZXR1cm4gdmFsfTtCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4PWZ1bmN0aW9uIHJlYWRJbnQ4KG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCwxLHRoaXMubGVuZ3RoKTtpZighKHRoaXNbb2Zmc2V0XSYxMjgpKXJldHVybiB0aGlzW29mZnNldF07cmV0dXJuKDI1NS10aGlzW29mZnNldF0rMSkqLTF9O0J1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEU9ZnVuY3Rpb24gcmVhZEludDE2TEUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDIsdGhpcy5sZW5ndGgpO3ZhciB2YWw9dGhpc1tvZmZzZXRdfHRoaXNbb2Zmc2V0KzFdPDw4O3JldHVybiB2YWwmMzI3Njg/dmFsfDQyOTQ5MDE3NjA6dmFsfTtCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFPWZ1bmN0aW9uIHJlYWRJbnQxNkJFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCwyLHRoaXMubGVuZ3RoKTt2YXIgdmFsPXRoaXNbb2Zmc2V0KzFdfHRoaXNbb2Zmc2V0XTw8ODtyZXR1cm4gdmFsJjMyNzY4P3ZhbHw0Mjk0OTAxNzYwOnZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRT1mdW5jdGlvbiByZWFkSW50MzJMRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsNCx0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XXx0aGlzW29mZnNldCsxXTw8OHx0aGlzW29mZnNldCsyXTw8MTZ8dGhpc1tvZmZzZXQrM108PDI0fTtCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFPWZ1bmN0aW9uIHJlYWRJbnQzMkJFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw0LHRoaXMubGVuZ3RoKTtyZXR1cm4gdGhpc1tvZmZzZXRdPDwyNHx0aGlzW29mZnNldCsxXTw8MTZ8dGhpc1tvZmZzZXQrMl08PDh8dGhpc1tvZmZzZXQrM119O0J1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEU9ZnVuY3Rpb24gcmVhZEZsb2F0TEUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDQsdGhpcy5sZW5ndGgpO3JldHVybiBpZWVlNzU0LnJlYWQodGhpcyxvZmZzZXQsdHJ1ZSwyMyw0KX07QnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRT1mdW5jdGlvbiByZWFkRmxvYXRCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsNCx0aGlzLmxlbmd0aCk7cmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLG9mZnNldCxmYWxzZSwyMyw0KX07QnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEU9ZnVuY3Rpb24gcmVhZERvdWJsZUxFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw4LHRoaXMubGVuZ3RoKTtyZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsb2Zmc2V0LHRydWUsNTIsOCl9O0J1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFPWZ1bmN0aW9uIHJlYWREb3VibGVCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsOCx0aGlzLmxlbmd0aCk7cmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLG9mZnNldCxmYWxzZSw1Miw4KX07ZnVuY3Rpb24gY2hlY2tJbnQoYnVmLHZhbHVlLG9mZnNldCxleHQsbWF4LG1pbil7aWYoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKXRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYnVmZmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpO2lmKHZhbHVlPm1heHx8dmFsdWU8bWluKXRocm93IG5ldyBSYW5nZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgaXMgb3V0IG9mIGJvdW5kcycpO2lmKG9mZnNldCtleHQ+YnVmLmxlbmd0aCl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkluZGV4IG91dCBvZiByYW5nZVwiKX1CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFPWZ1bmN0aW9uIHdyaXRlVUludExFKHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2J5dGVMZW5ndGg9Ynl0ZUxlbmd0aHwwO2lmKCFub0Fzc2VydCl7dmFyIG1heEJ5dGVzPU1hdGgucG93KDIsOCpieXRlTGVuZ3RoKS0xO2NoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbWF4Qnl0ZXMsMCl9dmFyIG11bD0xO3ZhciBpPTA7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTt3aGlsZSgrK2k8Ynl0ZUxlbmd0aCYmKG11bCo9MjU2KSl7dGhpc1tvZmZzZXQraV09dmFsdWUvbXVsJjI1NX1yZXR1cm4gb2Zmc2V0K2J5dGVMZW5ndGh9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkU9ZnVuY3Rpb24gd3JpdGVVSW50QkUodmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KXt2YXIgbWF4Qnl0ZXM9TWF0aC5wb3coMiw4KmJ5dGVMZW5ndGgpLTE7Y2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsYnl0ZUxlbmd0aCxtYXhCeXRlcywwKX12YXIgaT1ieXRlTGVuZ3RoLTE7dmFyIG11bD0xO3RoaXNbb2Zmc2V0K2ldPXZhbHVlJjI1NTt3aGlsZSgtLWk+PTAmJihtdWwqPTI1Nikpe3RoaXNbb2Zmc2V0K2ldPXZhbHVlL211bCYyNTV9cmV0dXJuIG9mZnNldCtieXRlTGVuZ3RofTtCdWZmZXIucHJvdG90eXBlLndyaXRlVUludDg9ZnVuY3Rpb24gd3JpdGVVSW50OCh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDEsMjU1LDApO2lmKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl2YWx1ZT1NYXRoLmZsb29yKHZhbHVlKTt0aGlzW29mZnNldF09dmFsdWUmMjU1O3JldHVybiBvZmZzZXQrMX07ZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MTYoYnVmLHZhbHVlLG9mZnNldCxsaXR0bGVFbmRpYW4pe2lmKHZhbHVlPDApdmFsdWU9NjU1MzUrdmFsdWUrMTtmb3IodmFyIGk9MCxqPU1hdGgubWluKGJ1Zi5sZW5ndGgtb2Zmc2V0LDIpO2k8ajsrK2kpe2J1ZltvZmZzZXQraV09KHZhbHVlJjI1NTw8OCoobGl0dGxlRW5kaWFuP2k6MS1pKSk+Pj4obGl0dGxlRW5kaWFuP2k6MS1pKSo4fX1CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEU9ZnVuY3Rpb24gd3JpdGVVSW50MTZMRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDIsNjU1MzUsMCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZSYyNTU7dGhpc1tvZmZzZXQrMV09dmFsdWU+Pj44fWVsc2V7b2JqZWN0V3JpdGVVSW50MTYodGhpcyx2YWx1ZSxvZmZzZXQsdHJ1ZSl9cmV0dXJuIG9mZnNldCsyfTtCdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkU9ZnVuY3Rpb24gd3JpdGVVSW50MTZCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDIsNjU1MzUsMCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZT4+Pjg7dGhpc1tvZmZzZXQrMV09dmFsdWUmMjU1fWVsc2V7b2JqZWN0V3JpdGVVSW50MTYodGhpcyx2YWx1ZSxvZmZzZXQsZmFsc2UpfXJldHVybiBvZmZzZXQrMn07ZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MzIoYnVmLHZhbHVlLG9mZnNldCxsaXR0bGVFbmRpYW4pe2lmKHZhbHVlPDApdmFsdWU9NDI5NDk2NzI5NSt2YWx1ZSsxO2Zvcih2YXIgaT0wLGo9TWF0aC5taW4oYnVmLmxlbmd0aC1vZmZzZXQsNCk7aTxqOysraSl7YnVmW29mZnNldCtpXT12YWx1ZT4+PihsaXR0bGVFbmRpYW4/aTozLWkpKjgmMjU1fX1CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEU9ZnVuY3Rpb24gd3JpdGVVSW50MzJMRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDQsNDI5NDk2NzI5NSwwKTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXQrM109dmFsdWU+Pj4yNDt0aGlzW29mZnNldCsyXT12YWx1ZT4+PjE2O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+ODt0aGlzW29mZnNldF09dmFsdWUmMjU1fWVsc2V7b2JqZWN0V3JpdGVVSW50MzIodGhpcyx2YWx1ZSxvZmZzZXQsdHJ1ZSl9cmV0dXJuIG9mZnNldCs0fTtCdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkU9ZnVuY3Rpb24gd3JpdGVVSW50MzJCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDQsNDI5NDk2NzI5NSwwKTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlPj4+MjQ7dGhpc1tvZmZzZXQrMV09dmFsdWU+Pj4xNjt0aGlzW29mZnNldCsyXT12YWx1ZT4+Pjg7dGhpc1tvZmZzZXQrM109dmFsdWUmMjU1fWVsc2V7b2JqZWN0V3JpdGVVSW50MzIodGhpcyx2YWx1ZSxvZmZzZXQsZmFsc2UpfXJldHVybiBvZmZzZXQrNH07QnVmZmVyLnByb3RvdHlwZS53cml0ZUludExFPWZ1bmN0aW9uIHdyaXRlSW50TEUodmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KXt2YXIgbGltaXQ9TWF0aC5wb3coMiw4KmJ5dGVMZW5ndGgtMSk7Y2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsYnl0ZUxlbmd0aCxsaW1pdC0xLC1saW1pdCl9dmFyIGk9MDt2YXIgbXVsPTE7dmFyIHN1Yj0wO3RoaXNbb2Zmc2V0XT12YWx1ZSYyNTU7d2hpbGUoKytpPGJ5dGVMZW5ndGgmJihtdWwqPTI1Nikpe2lmKHZhbHVlPDAmJnN1Yj09PTAmJnRoaXNbb2Zmc2V0K2ktMV0hPT0wKXtzdWI9MX10aGlzW29mZnNldCtpXT0odmFsdWUvbXVsPj4wKS1zdWImMjU1fXJldHVybiBvZmZzZXQrYnl0ZUxlbmd0aH07QnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFPWZ1bmN0aW9uIHdyaXRlSW50QkUodmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KXt2YXIgbGltaXQ9TWF0aC5wb3coMiw4KmJ5dGVMZW5ndGgtMSk7Y2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsYnl0ZUxlbmd0aCxsaW1pdC0xLC1saW1pdCl9dmFyIGk9Ynl0ZUxlbmd0aC0xO3ZhciBtdWw9MTt2YXIgc3ViPTA7dGhpc1tvZmZzZXQraV09dmFsdWUmMjU1O3doaWxlKC0taT49MCYmKG11bCo9MjU2KSl7aWYodmFsdWU8MCYmc3ViPT09MCYmdGhpc1tvZmZzZXQraSsxXSE9PTApe3N1Yj0xfXRoaXNbb2Zmc2V0K2ldPSh2YWx1ZS9tdWw+PjApLXN1YiYyNTV9cmV0dXJuIG9mZnNldCtieXRlTGVuZ3RofTtCdWZmZXIucHJvdG90eXBlLndyaXRlSW50OD1mdW5jdGlvbiB3cml0ZUludDgodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwxLDEyNywtMTI4KTtpZighQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpdmFsdWU9TWF0aC5mbG9vcih2YWx1ZSk7aWYodmFsdWU8MCl2YWx1ZT0yNTUrdmFsdWUrMTt0aGlzW29mZnNldF09dmFsdWUmMjU1O3JldHVybiBvZmZzZXQrMX07QnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEU9ZnVuY3Rpb24gd3JpdGVJbnQxNkxFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsMiwzMjc2NywtMzI3NjgpO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWUmMjU1O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+OH1lbHNle29iamVjdFdyaXRlVUludDE2KHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUpfXJldHVybiBvZmZzZXQrMn07QnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkU9ZnVuY3Rpb24gd3JpdGVJbnQxNkJFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsMiwzMjc2NywtMzI3NjgpO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzFdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDE2KHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlKX1yZXR1cm4gb2Zmc2V0KzJ9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFPWZ1bmN0aW9uIHdyaXRlSW50MzJMRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDQsMjE0NzQ4MzY0NywtMjE0NzQ4MzY0OCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZSYyNTU7dGhpc1tvZmZzZXQrMV09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzJdPXZhbHVlPj4+MTY7dGhpc1tvZmZzZXQrM109dmFsdWU+Pj4yNH1lbHNle29iamVjdFdyaXRlVUludDMyKHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUpfXJldHVybiBvZmZzZXQrNH07QnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkU9ZnVuY3Rpb24gd3JpdGVJbnQzMkJFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsNCwyMTQ3NDgzNjQ3LC0yMTQ3NDgzNjQ4KTtpZih2YWx1ZTwwKXZhbHVlPTQyOTQ5NjcyOTUrdmFsdWUrMTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlPj4+MjQ7dGhpc1tvZmZzZXQrMV09dmFsdWU+Pj4xNjt0aGlzW29mZnNldCsyXT12YWx1ZT4+Pjg7dGhpc1tvZmZzZXQrM109dmFsdWUmMjU1fWVsc2V7b2JqZWN0V3JpdGVVSW50MzIodGhpcyx2YWx1ZSxvZmZzZXQsZmFsc2UpfXJldHVybiBvZmZzZXQrNH07ZnVuY3Rpb24gY2hlY2tJRUVFNzU0KGJ1Zix2YWx1ZSxvZmZzZXQsZXh0LG1heCxtaW4pe2lmKG9mZnNldCtleHQ+YnVmLmxlbmd0aCl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkluZGV4IG91dCBvZiByYW5nZVwiKTtpZihvZmZzZXQ8MCl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkluZGV4IG91dCBvZiByYW5nZVwiKX1mdW5jdGlvbiB3cml0ZUZsb2F0KGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuLG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpe2NoZWNrSUVFRTc1NChidWYsdmFsdWUsb2Zmc2V0LDQsMy40MDI4MjM0NjYzODUyODg2ZTM4LC0zLjQwMjgyMzQ2NjM4NTI4ODZlMzgpfWllZWU3NTQud3JpdGUoYnVmLHZhbHVlLG9mZnNldCxsaXR0bGVFbmRpYW4sMjMsNCk7cmV0dXJuIG9mZnNldCs0fUJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFPWZ1bmN0aW9uIHdyaXRlRmxvYXRMRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3JldHVybiB3cml0ZUZsb2F0KHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUsbm9Bc3NlcnQpfTtCdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRT1mdW5jdGlvbiB3cml0ZUZsb2F0QkUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXtyZXR1cm4gd3JpdGVGbG9hdCh0aGlzLHZhbHVlLG9mZnNldCxmYWxzZSxub0Fzc2VydCl9O2Z1bmN0aW9uIHdyaXRlRG91YmxlKGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuLG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpe2NoZWNrSUVFRTc1NChidWYsdmFsdWUsb2Zmc2V0LDgsMS43OTc2OTMxMzQ4NjIzMTU3ZTMwOCwtMS43OTc2OTMxMzQ4NjIzMTU3ZTMwOCl9aWVlZTc1NC53cml0ZShidWYsdmFsdWUsb2Zmc2V0LGxpdHRsZUVuZGlhbiw1Miw4KTtyZXR1cm4gb2Zmc2V0Kzh9QnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFPWZ1bmN0aW9uIHdyaXRlRG91YmxlTEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXtyZXR1cm4gd3JpdGVEb3VibGUodGhpcyx2YWx1ZSxvZmZzZXQsdHJ1ZSxub0Fzc2VydCl9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRT1mdW5jdGlvbiB3cml0ZURvdWJsZUJFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7cmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlLG5vQXNzZXJ0KX07QnVmZmVyLnByb3RvdHlwZS5jb3B5PWZ1bmN0aW9uIGNvcHkodGFyZ2V0LHRhcmdldFN0YXJ0LHN0YXJ0LGVuZCl7aWYoIXN0YXJ0KXN0YXJ0PTA7aWYoIWVuZCYmZW5kIT09MCllbmQ9dGhpcy5sZW5ndGg7aWYodGFyZ2V0U3RhcnQ+PXRhcmdldC5sZW5ndGgpdGFyZ2V0U3RhcnQ9dGFyZ2V0Lmxlbmd0aDtpZighdGFyZ2V0U3RhcnQpdGFyZ2V0U3RhcnQ9MDtpZihlbmQ+MCYmZW5kPHN0YXJ0KWVuZD1zdGFydDtpZihlbmQ9PT1zdGFydClyZXR1cm4gMDtpZih0YXJnZXQubGVuZ3RoPT09MHx8dGhpcy5sZW5ndGg9PT0wKXJldHVybiAwO2lmKHRhcmdldFN0YXJ0PDApe3Rocm93IG5ldyBSYW5nZUVycm9yKFwidGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kc1wiKX1pZihzdGFydDwwfHxzdGFydD49dGhpcy5sZW5ndGgpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzXCIpO2lmKGVuZDwwKXRocm93IG5ldyBSYW5nZUVycm9yKFwic291cmNlRW5kIG91dCBvZiBib3VuZHNcIik7aWYoZW5kPnRoaXMubGVuZ3RoKWVuZD10aGlzLmxlbmd0aDtpZih0YXJnZXQubGVuZ3RoLXRhcmdldFN0YXJ0PGVuZC1zdGFydCl7ZW5kPXRhcmdldC5sZW5ndGgtdGFyZ2V0U3RhcnQrc3RhcnR9dmFyIGxlbj1lbmQtc3RhcnQ7dmFyIGk7aWYodGhpcz09PXRhcmdldCYmc3RhcnQ8dGFyZ2V0U3RhcnQmJnRhcmdldFN0YXJ0PGVuZCl7Zm9yKGk9bGVuLTE7aT49MDstLWkpe3RhcmdldFtpK3RhcmdldFN0YXJ0XT10aGlzW2krc3RhcnRdfX1lbHNlIGlmKGxlbjwxZTN8fCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7Zm9yKGk9MDtpPGxlbjsrK2kpe3RhcmdldFtpK3RhcmdldFN0YXJ0XT10aGlzW2krc3RhcnRdfX1lbHNle1VpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKHRhcmdldCx0aGlzLnN1YmFycmF5KHN0YXJ0LHN0YXJ0K2xlbiksdGFyZ2V0U3RhcnQpfXJldHVybiBsZW59O0J1ZmZlci5wcm90b3R5cGUuZmlsbD1mdW5jdGlvbiBmaWxsKHZhbCxzdGFydCxlbmQsZW5jb2Rpbmcpe2lmKHR5cGVvZiB2YWw9PT1cInN0cmluZ1wiKXtpZih0eXBlb2Ygc3RhcnQ9PT1cInN0cmluZ1wiKXtlbmNvZGluZz1zdGFydDtzdGFydD0wO2VuZD10aGlzLmxlbmd0aH1lbHNlIGlmKHR5cGVvZiBlbmQ9PT1cInN0cmluZ1wiKXtlbmNvZGluZz1lbmQ7ZW5kPXRoaXMubGVuZ3RofWlmKHZhbC5sZW5ndGg9PT0xKXt2YXIgY29kZT12YWwuY2hhckNvZGVBdCgwKTtpZihjb2RlPDI1Nil7dmFsPWNvZGV9fWlmKGVuY29kaW5nIT09dW5kZWZpbmVkJiZ0eXBlb2YgZW5jb2RpbmchPT1cInN0cmluZ1wiKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwiZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZ1wiKX1pZih0eXBlb2YgZW5jb2Rpbmc9PT1cInN0cmluZ1wiJiYhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5rbm93biBlbmNvZGluZzogXCIrZW5jb2RpbmcpfX1lbHNlIGlmKHR5cGVvZiB2YWw9PT1cIm51bWJlclwiKXt2YWw9dmFsJjI1NX1pZihzdGFydDwwfHx0aGlzLmxlbmd0aDxzdGFydHx8dGhpcy5sZW5ndGg8ZW5kKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIk91dCBvZiByYW5nZSBpbmRleFwiKX1pZihlbmQ8PXN0YXJ0KXtyZXR1cm4gdGhpc31zdGFydD1zdGFydD4+PjA7ZW5kPWVuZD09PXVuZGVmaW5lZD90aGlzLmxlbmd0aDplbmQ+Pj4wO2lmKCF2YWwpdmFsPTA7dmFyIGk7aWYodHlwZW9mIHZhbD09PVwibnVtYmVyXCIpe2ZvcihpPXN0YXJ0O2k8ZW5kOysraSl7dGhpc1tpXT12YWx9fWVsc2V7dmFyIGJ5dGVzPUJ1ZmZlci5pc0J1ZmZlcih2YWwpP3ZhbDp1dGY4VG9CeXRlcyhuZXcgQnVmZmVyKHZhbCxlbmNvZGluZykudG9TdHJpbmcoKSk7dmFyIGxlbj1ieXRlcy5sZW5ndGg7Zm9yKGk9MDtpPGVuZC1zdGFydDsrK2kpe3RoaXNbaStzdGFydF09Ynl0ZXNbaSVsZW5dfX1yZXR1cm4gdGhpc307dmFyIElOVkFMSURfQkFTRTY0X1JFPS9bXitcXC8wLTlBLVphLXotX10vZztmdW5jdGlvbiBiYXNlNjRjbGVhbihzdHIpe3N0cj1zdHJpbmd0cmltKHN0cikucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSxcIlwiKTtpZihzdHIubGVuZ3RoPDIpcmV0dXJuXCJcIjt3aGlsZShzdHIubGVuZ3RoJTQhPT0wKXtzdHI9c3RyK1wiPVwifXJldHVybiBzdHJ9ZnVuY3Rpb24gc3RyaW5ndHJpbShzdHIpe2lmKHN0ci50cmltKXJldHVybiBzdHIudHJpbSgpO3JldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZyxcIlwiKX1mdW5jdGlvbiB0b0hleChuKXtpZihuPDE2KXJldHVyblwiMFwiK24udG9TdHJpbmcoMTYpO3JldHVybiBuLnRvU3RyaW5nKDE2KX1mdW5jdGlvbiB1dGY4VG9CeXRlcyhzdHJpbmcsdW5pdHMpe3VuaXRzPXVuaXRzfHxJbmZpbml0eTt2YXIgY29kZVBvaW50O3ZhciBsZW5ndGg9c3RyaW5nLmxlbmd0aDt2YXIgbGVhZFN1cnJvZ2F0ZT1udWxsO3ZhciBieXRlcz1bXTtmb3IodmFyIGk9MDtpPGxlbmd0aDsrK2kpe2NvZGVQb2ludD1zdHJpbmcuY2hhckNvZGVBdChpKTtpZihjb2RlUG9pbnQ+NTUyOTUmJmNvZGVQb2ludDw1NzM0NCl7aWYoIWxlYWRTdXJyb2dhdGUpe2lmKGNvZGVQb2ludD41NjMxOSl7aWYoKHVuaXRzLT0zKT4tMSlieXRlcy5wdXNoKDIzOSwxOTEsMTg5KTtjb250aW51ZX1lbHNlIGlmKGkrMT09PWxlbmd0aCl7aWYoKHVuaXRzLT0zKT4tMSlieXRlcy5wdXNoKDIzOSwxOTEsMTg5KTtjb250aW51ZX1sZWFkU3Vycm9nYXRlPWNvZGVQb2ludDtjb250aW51ZX1pZihjb2RlUG9pbnQ8NTYzMjApe2lmKCh1bml0cy09Myk+LTEpYnl0ZXMucHVzaCgyMzksMTkxLDE4OSk7bGVhZFN1cnJvZ2F0ZT1jb2RlUG9pbnQ7Y29udGludWV9Y29kZVBvaW50PShsZWFkU3Vycm9nYXRlLTU1Mjk2PDwxMHxjb2RlUG9pbnQtNTYzMjApKzY1NTM2fWVsc2UgaWYobGVhZFN1cnJvZ2F0ZSl7aWYoKHVuaXRzLT0zKT4tMSlieXRlcy5wdXNoKDIzOSwxOTEsMTg5KX1sZWFkU3Vycm9nYXRlPW51bGw7aWYoY29kZVBvaW50PDEyOCl7aWYoKHVuaXRzLT0xKTwwKWJyZWFrO2J5dGVzLnB1c2goY29kZVBvaW50KX1lbHNlIGlmKGNvZGVQb2ludDwyMDQ4KXtpZigodW5pdHMtPTIpPDApYnJlYWs7Ynl0ZXMucHVzaChjb2RlUG9pbnQ+PjZ8MTkyLGNvZGVQb2ludCY2M3wxMjgpfWVsc2UgaWYoY29kZVBvaW50PDY1NTM2KXtpZigodW5pdHMtPTMpPDApYnJlYWs7Ynl0ZXMucHVzaChjb2RlUG9pbnQ+PjEyfDIyNCxjb2RlUG9pbnQ+PjYmNjN8MTI4LGNvZGVQb2ludCY2M3wxMjgpfWVsc2UgaWYoY29kZVBvaW50PDExMTQxMTIpe2lmKCh1bml0cy09NCk8MClicmVhaztieXRlcy5wdXNoKGNvZGVQb2ludD4+MTh8MjQwLGNvZGVQb2ludD4+MTImNjN8MTI4LGNvZGVQb2ludD4+NiY2M3wxMjgsY29kZVBvaW50JjYzfDEyOCl9ZWxzZXt0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGNvZGUgcG9pbnRcIil9fXJldHVybiBieXRlc31mdW5jdGlvbiBhc2NpaVRvQnl0ZXMoc3RyKXt2YXIgYnl0ZUFycmF5PVtdO2Zvcih2YXIgaT0wO2k8c3RyLmxlbmd0aDsrK2kpe2J5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpJjI1NSl9cmV0dXJuIGJ5dGVBcnJheX1mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyhzdHIsdW5pdHMpe3ZhciBjLGhpLGxvO3ZhciBieXRlQXJyYXk9W107Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7aWYoKHVuaXRzLT0yKTwwKWJyZWFrO2M9c3RyLmNoYXJDb2RlQXQoaSk7aGk9Yz4+ODtsbz1jJTI1NjtieXRlQXJyYXkucHVzaChsbyk7Ynl0ZUFycmF5LnB1c2goaGkpfXJldHVybiBieXRlQXJyYXl9ZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyhzdHIpe3JldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSl9ZnVuY3Rpb24gYmxpdEJ1ZmZlcihzcmMsZHN0LG9mZnNldCxsZW5ndGgpe2Zvcih2YXIgaT0wO2k8bGVuZ3RoOysraSl7aWYoaStvZmZzZXQ+PWRzdC5sZW5ndGh8fGk+PXNyYy5sZW5ndGgpYnJlYWs7ZHN0W2krb2Zmc2V0XT1zcmNbaV19cmV0dXJuIGl9ZnVuY3Rpb24gaXNuYW4odmFsKXtyZXR1cm4gdmFsIT09dmFsfX0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsIT09XCJ1bmRlZmluZWRcIj9nbG9iYWw6dHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiP3NlbGY6dHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCI/d2luZG93Ont9KX0se1wiYmFzZTY0LWpzXCI6MixpZWVlNzU0OjM3LGlzYXJyYXk6NDB9XSw2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24oQnVmZmVyKXtmdW5jdGlvbiBpc0FycmF5KGFyZyl7aWYoQXJyYXkuaXNBcnJheSl7cmV0dXJuIEFycmF5LmlzQXJyYXkoYXJnKX1yZXR1cm4gb2JqZWN0VG9TdHJpbmcoYXJnKT09PVwiW29iamVjdCBBcnJheV1cIn1leHBvcnRzLmlzQXJyYXk9aXNBcnJheTtmdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwiYm9vbGVhblwifWV4cG9ydHMuaXNCb29sZWFuPWlzQm9vbGVhbjtmdW5jdGlvbiBpc051bGwoYXJnKXtyZXR1cm4gYXJnPT09bnVsbH1leHBvcnRzLmlzTnVsbD1pc051bGw7ZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKXtyZXR1cm4gYXJnPT1udWxsfWV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQ9aXNOdWxsT3JVbmRlZmluZWQ7ZnVuY3Rpb24gaXNOdW1iZXIoYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwibnVtYmVyXCJ9ZXhwb3J0cy5pc051bWJlcj1pc051bWJlcjtmdW5jdGlvbiBpc1N0cmluZyhhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJzdHJpbmdcIn1leHBvcnRzLmlzU3RyaW5nPWlzU3RyaW5nO2Z1bmN0aW9uIGlzU3ltYm9sKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cInN5bWJvbFwifWV4cG9ydHMuaXNTeW1ib2w9aXNTeW1ib2w7ZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKXtyZXR1cm4gYXJnPT09dm9pZCAwfWV4cG9ydHMuaXNVbmRlZmluZWQ9aXNVbmRlZmluZWQ7ZnVuY3Rpb24gaXNSZWdFeHAocmUpe3JldHVybiBvYmplY3RUb1N0cmluZyhyZSk9PT1cIltvYmplY3QgUmVnRXhwXVwifWV4cG9ydHMuaXNSZWdFeHA9aXNSZWdFeHA7ZnVuY3Rpb24gaXNPYmplY3QoYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwib2JqZWN0XCImJmFyZyE9PW51bGx9ZXhwb3J0cy5pc09iamVjdD1pc09iamVjdDtmdW5jdGlvbiBpc0RhdGUoZCl7cmV0dXJuIG9iamVjdFRvU3RyaW5nKGQpPT09XCJbb2JqZWN0IERhdGVdXCJ9ZXhwb3J0cy5pc0RhdGU9aXNEYXRlO2Z1bmN0aW9uIGlzRXJyb3IoZSl7cmV0dXJuIG9iamVjdFRvU3RyaW5nKGUpPT09XCJbb2JqZWN0IEVycm9yXVwifHxlIGluc3RhbmNlb2YgRXJyb3J9ZXhwb3J0cy5pc0Vycm9yPWlzRXJyb3I7ZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJmdW5jdGlvblwifWV4cG9ydHMuaXNGdW5jdGlvbj1pc0Z1bmN0aW9uO2Z1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZyl7cmV0dXJuIGFyZz09PW51bGx8fHR5cGVvZiBhcmc9PT1cImJvb2xlYW5cInx8dHlwZW9mIGFyZz09PVwibnVtYmVyXCJ8fHR5cGVvZiBhcmc9PT1cInN0cmluZ1wifHx0eXBlb2YgYXJnPT09XCJzeW1ib2xcInx8dHlwZW9mIGFyZz09PVwidW5kZWZpbmVkXCJ9ZXhwb3J0cy5pc1ByaW1pdGl2ZT1pc1ByaW1pdGl2ZTtleHBvcnRzLmlzQnVmZmVyPUJ1ZmZlci5pc0J1ZmZlcjtmdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKXtyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pfX0pLmNhbGwodGhpcyx7aXNCdWZmZXI6cmVxdWlyZShcIi4uLy4uL2lzLWJ1ZmZlci9pbmRleC5qc1wiKX0pfSx7XCIuLi8uLi9pcy1idWZmZXIvaW5kZXguanNcIjozOX1dLDc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBFbGVtZW50VHlwZT1yZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIik7dmFyIGVudGl0aWVzPXJlcXVpcmUoXCJlbnRpdGllc1wiKTt2YXIgYm9vbGVhbkF0dHJpYnV0ZXM9e19fcHJvdG9fXzpudWxsLGFsbG93ZnVsbHNjcmVlbjp0cnVlLGFzeW5jOnRydWUsYXV0b2ZvY3VzOnRydWUsYXV0b3BsYXk6dHJ1ZSxjaGVja2VkOnRydWUsY29udHJvbHM6dHJ1ZSxkZWZhdWx0OnRydWUsZGVmZXI6dHJ1ZSxkaXNhYmxlZDp0cnVlLGhpZGRlbjp0cnVlLGlzbWFwOnRydWUsbG9vcDp0cnVlLG11bHRpcGxlOnRydWUsbXV0ZWQ6dHJ1ZSxvcGVuOnRydWUscmVhZG9ubHk6dHJ1ZSxyZXF1aXJlZDp0cnVlLHJldmVyc2VkOnRydWUsc2NvcGVkOnRydWUsc2VhbWxlc3M6dHJ1ZSxzZWxlY3RlZDp0cnVlLHR5cGVtdXN0bWF0Y2g6dHJ1ZX07dmFyIHVuZW5jb2RlZEVsZW1lbnRzPXtfX3Byb3RvX186bnVsbCxzdHlsZTp0cnVlLHNjcmlwdDp0cnVlLHhtcDp0cnVlLGlmcmFtZTp0cnVlLG5vZW1iZWQ6dHJ1ZSxub2ZyYW1lczp0cnVlLHBsYWludGV4dDp0cnVlLG5vc2NyaXB0OnRydWV9O2Z1bmN0aW9uIGZvcm1hdEF0dHJzKGF0dHJpYnV0ZXMsb3B0cyl7aWYoIWF0dHJpYnV0ZXMpcmV0dXJuO3ZhciBvdXRwdXQ9XCJcIix2YWx1ZTtmb3IodmFyIGtleSBpbiBhdHRyaWJ1dGVzKXt2YWx1ZT1hdHRyaWJ1dGVzW2tleV07aWYob3V0cHV0KXtvdXRwdXQrPVwiIFwifWlmKCF2YWx1ZSYmYm9vbGVhbkF0dHJpYnV0ZXNba2V5XSl7b3V0cHV0Kz1rZXl9ZWxzZXtvdXRwdXQrPWtleSsnPVwiJysob3B0cy5kZWNvZGVFbnRpdGllcz9lbnRpdGllcy5lbmNvZGVYTUwodmFsdWUpOnZhbHVlKSsnXCInfX1yZXR1cm4gb3V0cHV0fXZhciBzaW5nbGVUYWc9e19fcHJvdG9fXzpudWxsLGFyZWE6dHJ1ZSxiYXNlOnRydWUsYmFzZWZvbnQ6dHJ1ZSxicjp0cnVlLGNvbDp0cnVlLGNvbW1hbmQ6dHJ1ZSxlbWJlZDp0cnVlLGZyYW1lOnRydWUsaHI6dHJ1ZSxpbWc6dHJ1ZSxpbnB1dDp0cnVlLGlzaW5kZXg6dHJ1ZSxrZXlnZW46dHJ1ZSxsaW5rOnRydWUsbWV0YTp0cnVlLHBhcmFtOnRydWUsc291cmNlOnRydWUsdHJhY2s6dHJ1ZSx3YnI6dHJ1ZX07dmFyIHJlbmRlcj1tb2R1bGUuZXhwb3J0cz1mdW5jdGlvbihkb20sb3B0cyl7aWYoIUFycmF5LmlzQXJyYXkoZG9tKSYmIWRvbS5jaGVlcmlvKWRvbT1bZG9tXTtvcHRzPW9wdHN8fHt9O3ZhciBvdXRwdXQ9XCJcIjtmb3IodmFyIGk9MDtpPGRvbS5sZW5ndGg7aSsrKXt2YXIgZWxlbT1kb21baV07aWYoZWxlbS50eXBlPT09XCJyb290XCIpb3V0cHV0Kz1yZW5kZXIoZWxlbS5jaGlsZHJlbixvcHRzKTtlbHNlIGlmKEVsZW1lbnRUeXBlLmlzVGFnKGVsZW0pKW91dHB1dCs9cmVuZGVyVGFnKGVsZW0sb3B0cyk7ZWxzZSBpZihlbGVtLnR5cGU9PT1FbGVtZW50VHlwZS5EaXJlY3RpdmUpb3V0cHV0Kz1yZW5kZXJEaXJlY3RpdmUoZWxlbSk7ZWxzZSBpZihlbGVtLnR5cGU9PT1FbGVtZW50VHlwZS5Db21tZW50KW91dHB1dCs9cmVuZGVyQ29tbWVudChlbGVtKTtlbHNlIGlmKGVsZW0udHlwZT09PUVsZW1lbnRUeXBlLkNEQVRBKW91dHB1dCs9cmVuZGVyQ2RhdGEoZWxlbSk7ZWxzZSBvdXRwdXQrPXJlbmRlclRleHQoZWxlbSxvcHRzKX1yZXR1cm4gb3V0cHV0fTtmdW5jdGlvbiByZW5kZXJUYWcoZWxlbSxvcHRzKXtpZihlbGVtLm5hbWU9PT1cInN2Z1wiKW9wdHM9e2RlY29kZUVudGl0aWVzOm9wdHMuZGVjb2RlRW50aXRpZXMseG1sTW9kZTp0cnVlfTt2YXIgdGFnPVwiPFwiK2VsZW0ubmFtZSxhdHRyaWJzPWZvcm1hdEF0dHJzKGVsZW0uYXR0cmlicyxvcHRzKTtpZihhdHRyaWJzKXt0YWcrPVwiIFwiK2F0dHJpYnN9aWYob3B0cy54bWxNb2RlJiYoIWVsZW0uY2hpbGRyZW58fGVsZW0uY2hpbGRyZW4ubGVuZ3RoPT09MCkpe3RhZys9XCIvPlwifWVsc2V7dGFnKz1cIj5cIjtpZihlbGVtLmNoaWxkcmVuKXt0YWcrPXJlbmRlcihlbGVtLmNoaWxkcmVuLG9wdHMpfWlmKCFzaW5nbGVUYWdbZWxlbS5uYW1lXXx8b3B0cy54bWxNb2RlKXt0YWcrPVwiPC9cIitlbGVtLm5hbWUrXCI+XCJ9fXJldHVybiB0YWd9ZnVuY3Rpb24gcmVuZGVyRGlyZWN0aXZlKGVsZW0pe3JldHVyblwiPFwiK2VsZW0uZGF0YStcIj5cIn1mdW5jdGlvbiByZW5kZXJUZXh0KGVsZW0sb3B0cyl7dmFyIGRhdGE9ZWxlbS5kYXRhfHxcIlwiO2lmKG9wdHMuZGVjb2RlRW50aXRpZXMmJiEoZWxlbS5wYXJlbnQmJmVsZW0ucGFyZW50Lm5hbWUgaW4gdW5lbmNvZGVkRWxlbWVudHMpKXtkYXRhPWVudGl0aWVzLmVuY29kZVhNTChkYXRhKX1yZXR1cm4gZGF0YX1mdW5jdGlvbiByZW5kZXJDZGF0YShlbGVtKXtyZXR1cm5cIjwhW0NEQVRBW1wiK2VsZW0uY2hpbGRyZW5bMF0uZGF0YStcIl1dPlwifWZ1bmN0aW9uIHJlbmRlckNvbW1lbnQoZWxlbSl7cmV0dXJuXCI8IS0tXCIrZWxlbS5kYXRhK1wiLS0+XCJ9fSx7ZG9tZWxlbWVudHR5cGU6OCxlbnRpdGllczoyMH1dLDg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXtUZXh0OlwidGV4dFwiLERpcmVjdGl2ZTpcImRpcmVjdGl2ZVwiLENvbW1lbnQ6XCJjb21tZW50XCIsU2NyaXB0Olwic2NyaXB0XCIsU3R5bGU6XCJzdHlsZVwiLFRhZzpcInRhZ1wiLENEQVRBOlwiY2RhdGFcIixpc1RhZzpmdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS50eXBlPT09XCJ0YWdcInx8ZWxlbS50eXBlPT09XCJzY3JpcHRcInx8ZWxlbS50eXBlPT09XCJzdHlsZVwifX19LHt9XSw5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz17VGV4dDpcInRleHRcIixEaXJlY3RpdmU6XCJkaXJlY3RpdmVcIixDb21tZW50OlwiY29tbWVudFwiLFNjcmlwdDpcInNjcmlwdFwiLFN0eWxlOlwic3R5bGVcIixUYWc6XCJ0YWdcIixDREFUQTpcImNkYXRhXCIsRG9jdHlwZTpcImRvY3R5cGVcIixpc1RhZzpmdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS50eXBlPT09XCJ0YWdcInx8ZWxlbS50eXBlPT09XCJzY3JpcHRcInx8ZWxlbS50eXBlPT09XCJzdHlsZVwifX19LHt9XSwxMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIEVsZW1lbnRUeXBlPXJlcXVpcmUoXCJkb21lbGVtZW50dHlwZVwiKTt2YXIgcmVfd2hpdGVzcGFjZT0vXFxzKy9nO3ZhciBOb2RlUHJvdG90eXBlPXJlcXVpcmUoXCIuL2xpYi9ub2RlXCIpO3ZhciBFbGVtZW50UHJvdG90eXBlPXJlcXVpcmUoXCIuL2xpYi9lbGVtZW50XCIpO2Z1bmN0aW9uIERvbUhhbmRsZXIoY2FsbGJhY2ssb3B0aW9ucyxlbGVtZW50Q0Ipe2lmKHR5cGVvZiBjYWxsYmFjaz09PVwib2JqZWN0XCIpe2VsZW1lbnRDQj1vcHRpb25zO29wdGlvbnM9Y2FsbGJhY2s7Y2FsbGJhY2s9bnVsbH1lbHNlIGlmKHR5cGVvZiBvcHRpb25zPT09XCJmdW5jdGlvblwiKXtlbGVtZW50Q0I9b3B0aW9ucztvcHRpb25zPWRlZmF1bHRPcHRzfXRoaXMuX2NhbGxiYWNrPWNhbGxiYWNrO3RoaXMuX29wdGlvbnM9b3B0aW9uc3x8ZGVmYXVsdE9wdHM7dGhpcy5fZWxlbWVudENCPWVsZW1lbnRDQjt0aGlzLmRvbT1bXTt0aGlzLl9kb25lPWZhbHNlO3RoaXMuX3RhZ1N0YWNrPVtdO3RoaXMuX3BhcnNlcj10aGlzLl9wYXJzZXJ8fG51bGx9dmFyIGRlZmF1bHRPcHRzPXtub3JtYWxpemVXaGl0ZXNwYWNlOmZhbHNlLHdpdGhTdGFydEluZGljZXM6ZmFsc2V9O0RvbUhhbmRsZXIucHJvdG90eXBlLm9ucGFyc2VyaW5pdD1mdW5jdGlvbihwYXJzZXIpe3RoaXMuX3BhcnNlcj1wYXJzZXJ9O0RvbUhhbmRsZXIucHJvdG90eXBlLm9ucmVzZXQ9ZnVuY3Rpb24oKXtEb21IYW5kbGVyLmNhbGwodGhpcyx0aGlzLl9jYWxsYmFjayx0aGlzLl9vcHRpb25zLHRoaXMuX2VsZW1lbnRDQil9O0RvbUhhbmRsZXIucHJvdG90eXBlLm9uZW5kPWZ1bmN0aW9uKCl7aWYodGhpcy5fZG9uZSlyZXR1cm47dGhpcy5fZG9uZT10cnVlO3RoaXMuX3BhcnNlcj1udWxsO3RoaXMuX2hhbmRsZUNhbGxiYWNrKG51bGwpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5faGFuZGxlQ2FsbGJhY2s9RG9tSGFuZGxlci5wcm90b3R5cGUub25lcnJvcj1mdW5jdGlvbihlcnJvcil7aWYodHlwZW9mIHRoaXMuX2NhbGxiYWNrPT09XCJmdW5jdGlvblwiKXt0aGlzLl9jYWxsYmFjayhlcnJvcix0aGlzLmRvbSl9ZWxzZXtpZihlcnJvcil0aHJvdyBlcnJvcn19O0RvbUhhbmRsZXIucHJvdG90eXBlLm9uY2xvc2V0YWc9ZnVuY3Rpb24oKXt2YXIgZWxlbT10aGlzLl90YWdTdGFjay5wb3AoKTtpZih0aGlzLl9lbGVtZW50Q0IpdGhpcy5fZWxlbWVudENCKGVsZW0pfTtEb21IYW5kbGVyLnByb3RvdHlwZS5fYWRkRG9tRWxlbWVudD1mdW5jdGlvbihlbGVtZW50KXt2YXIgcGFyZW50PXRoaXMuX3RhZ1N0YWNrW3RoaXMuX3RhZ1N0YWNrLmxlbmd0aC0xXTt2YXIgc2libGluZ3M9cGFyZW50P3BhcmVudC5jaGlsZHJlbjp0aGlzLmRvbTt2YXIgcHJldmlvdXNTaWJsaW5nPXNpYmxpbmdzW3NpYmxpbmdzLmxlbmd0aC0xXTtlbGVtZW50Lm5leHQ9bnVsbDtpZih0aGlzLl9vcHRpb25zLndpdGhTdGFydEluZGljZXMpe2VsZW1lbnQuc3RhcnRJbmRleD10aGlzLl9wYXJzZXIuc3RhcnRJbmRleH1pZih0aGlzLl9vcHRpb25zLndpdGhEb21MdmwxKXtlbGVtZW50Ll9fcHJvdG9fXz1lbGVtZW50LnR5cGU9PT1cInRhZ1wiP0VsZW1lbnRQcm90b3R5cGU6Tm9kZVByb3RvdHlwZX1pZihwcmV2aW91c1NpYmxpbmcpe2VsZW1lbnQucHJldj1wcmV2aW91c1NpYmxpbmc7cHJldmlvdXNTaWJsaW5nLm5leHQ9ZWxlbWVudH1lbHNle2VsZW1lbnQucHJldj1udWxsfXNpYmxpbmdzLnB1c2goZWxlbWVudCk7ZWxlbWVudC5wYXJlbnQ9cGFyZW50fHxudWxsfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbm9wZW50YWc9ZnVuY3Rpb24obmFtZSxhdHRyaWJzKXt2YXIgZWxlbWVudD17dHlwZTpuYW1lPT09XCJzY3JpcHRcIj9FbGVtZW50VHlwZS5TY3JpcHQ6bmFtZT09PVwic3R5bGVcIj9FbGVtZW50VHlwZS5TdHlsZTpFbGVtZW50VHlwZS5UYWcsbmFtZTpuYW1lLGF0dHJpYnM6YXR0cmlicyxjaGlsZHJlbjpbXX07dGhpcy5fYWRkRG9tRWxlbWVudChlbGVtZW50KTt0aGlzLl90YWdTdGFjay5wdXNoKGVsZW1lbnQpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbnRleHQ9ZnVuY3Rpb24oZGF0YSl7dmFyIG5vcm1hbGl6ZT10aGlzLl9vcHRpb25zLm5vcm1hbGl6ZVdoaXRlc3BhY2V8fHRoaXMuX29wdGlvbnMuaWdub3JlV2hpdGVzcGFjZTt2YXIgbGFzdFRhZztpZighdGhpcy5fdGFnU3RhY2subGVuZ3RoJiZ0aGlzLmRvbS5sZW5ndGgmJihsYXN0VGFnPXRoaXMuZG9tW3RoaXMuZG9tLmxlbmd0aC0xXSkudHlwZT09PUVsZW1lbnRUeXBlLlRleHQpe2lmKG5vcm1hbGl6ZSl7bGFzdFRhZy5kYXRhPShsYXN0VGFnLmRhdGErZGF0YSkucmVwbGFjZShyZV93aGl0ZXNwYWNlLFwiIFwiKX1lbHNle2xhc3RUYWcuZGF0YSs9ZGF0YX19ZWxzZXtpZih0aGlzLl90YWdTdGFjay5sZW5ndGgmJihsYXN0VGFnPXRoaXMuX3RhZ1N0YWNrW3RoaXMuX3RhZ1N0YWNrLmxlbmd0aC0xXSkmJihsYXN0VGFnPWxhc3RUYWcuY2hpbGRyZW5bbGFzdFRhZy5jaGlsZHJlbi5sZW5ndGgtMV0pJiZsYXN0VGFnLnR5cGU9PT1FbGVtZW50VHlwZS5UZXh0KXtpZihub3JtYWxpemUpe2xhc3RUYWcuZGF0YT0obGFzdFRhZy5kYXRhK2RhdGEpLnJlcGxhY2UocmVfd2hpdGVzcGFjZSxcIiBcIil9ZWxzZXtsYXN0VGFnLmRhdGErPWRhdGF9fWVsc2V7aWYobm9ybWFsaXplKXtkYXRhPWRhdGEucmVwbGFjZShyZV93aGl0ZXNwYWNlLFwiIFwiKX10aGlzLl9hZGREb21FbGVtZW50KHtkYXRhOmRhdGEsdHlwZTpFbGVtZW50VHlwZS5UZXh0fSl9fX07RG9tSGFuZGxlci5wcm90b3R5cGUub25jb21tZW50PWZ1bmN0aW9uKGRhdGEpe3ZhciBsYXN0VGFnPXRoaXMuX3RhZ1N0YWNrW3RoaXMuX3RhZ1N0YWNrLmxlbmd0aC0xXTtpZihsYXN0VGFnJiZsYXN0VGFnLnR5cGU9PT1FbGVtZW50VHlwZS5Db21tZW50KXtsYXN0VGFnLmRhdGErPWRhdGE7cmV0dXJufXZhciBlbGVtZW50PXtkYXRhOmRhdGEsdHlwZTpFbGVtZW50VHlwZS5Db21tZW50fTt0aGlzLl9hZGREb21FbGVtZW50KGVsZW1lbnQpO3RoaXMuX3RhZ1N0YWNrLnB1c2goZWxlbWVudCl9O0RvbUhhbmRsZXIucHJvdG90eXBlLm9uY2RhdGFzdGFydD1mdW5jdGlvbigpe3ZhciBlbGVtZW50PXtjaGlsZHJlbjpbe2RhdGE6XCJcIix0eXBlOkVsZW1lbnRUeXBlLlRleHR9XSx0eXBlOkVsZW1lbnRUeXBlLkNEQVRBfTt0aGlzLl9hZGREb21FbGVtZW50KGVsZW1lbnQpO3RoaXMuX3RhZ1N0YWNrLnB1c2goZWxlbWVudCl9O0RvbUhhbmRsZXIucHJvdG90eXBlLm9uY29tbWVudGVuZD1Eb21IYW5kbGVyLnByb3RvdHlwZS5vbmNkYXRhZW5kPWZ1bmN0aW9uKCl7dGhpcy5fdGFnU3RhY2sucG9wKCl9O0RvbUhhbmRsZXIucHJvdG90eXBlLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uPWZ1bmN0aW9uKG5hbWUsZGF0YSl7dGhpcy5fYWRkRG9tRWxlbWVudCh7bmFtZTpuYW1lLGRhdGE6ZGF0YSx0eXBlOkVsZW1lbnRUeXBlLkRpcmVjdGl2ZX0pfTttb2R1bGUuZXhwb3J0cz1Eb21IYW5kbGVyfSx7XCIuL2xpYi9lbGVtZW50XCI6MTEsXCIuL2xpYi9ub2RlXCI6MTIsZG9tZWxlbWVudHR5cGU6OX1dLDExOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgTm9kZVByb3RvdHlwZT1yZXF1aXJlKFwiLi9ub2RlXCIpO3ZhciBFbGVtZW50UHJvdG90eXBlPW1vZHVsZS5leHBvcnRzPU9iamVjdC5jcmVhdGUoTm9kZVByb3RvdHlwZSk7dmFyIGRvbUx2bDE9e3RhZ05hbWU6XCJuYW1lXCJ9O09iamVjdC5rZXlzKGRvbUx2bDEpLmZvckVhY2goZnVuY3Rpb24oa2V5KXt2YXIgc2hvcnRoYW5kPWRvbUx2bDFba2V5XTtPYmplY3QuZGVmaW5lUHJvcGVydHkoRWxlbWVudFByb3RvdHlwZSxrZXkse2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzW3Nob3J0aGFuZF18fG51bGx9LHNldDpmdW5jdGlvbih2YWwpe3RoaXNbc2hvcnRoYW5kXT12YWw7cmV0dXJuIHZhbH19KX0pfSx7XCIuL25vZGVcIjoxMn1dLDEyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgTm9kZVByb3RvdHlwZT1tb2R1bGUuZXhwb3J0cz17Z2V0IGZpcnN0Q2hpbGQoKXt2YXIgY2hpbGRyZW49dGhpcy5jaGlsZHJlbjtyZXR1cm4gY2hpbGRyZW4mJmNoaWxkcmVuWzBdfHxudWxsfSxnZXQgbGFzdENoaWxkKCl7dmFyIGNoaWxkcmVuPXRoaXMuY2hpbGRyZW47cmV0dXJuIGNoaWxkcmVuJiZjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGgtMV18fG51bGx9LGdldCBub2RlVHlwZSgpe3JldHVybiBub2RlVHlwZXNbdGhpcy50eXBlXXx8bm9kZVR5cGVzLmVsZW1lbnR9fTt2YXIgZG9tTHZsMT17dGFnTmFtZTpcIm5hbWVcIixjaGlsZE5vZGVzOlwiY2hpbGRyZW5cIixwYXJlbnROb2RlOlwicGFyZW50XCIscHJldmlvdXNTaWJsaW5nOlwicHJldlwiLG5leHRTaWJsaW5nOlwibmV4dFwiLG5vZGVWYWx1ZTpcImRhdGFcIn07dmFyIG5vZGVUeXBlcz17ZWxlbWVudDoxLHRleHQ6MyxjZGF0YTo0LGNvbW1lbnQ6OH07T2JqZWN0LmtleXMoZG9tTHZsMSkuZm9yRWFjaChmdW5jdGlvbihrZXkpe3ZhciBzaG9ydGhhbmQ9ZG9tTHZsMVtrZXldO09iamVjdC5kZWZpbmVQcm9wZXJ0eShOb2RlUHJvdG90eXBlLGtleSx7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXNbc2hvcnRoYW5kXXx8bnVsbH0sc2V0OmZ1bmN0aW9uKHZhbCl7dGhpc1tzaG9ydGhhbmRdPXZhbDtyZXR1cm4gdmFsfX0pfSl9LHt9XSwxMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIERvbVV0aWxzPW1vZHVsZS5leHBvcnRzO1tyZXF1aXJlKFwiLi9saWIvc3RyaW5naWZ5XCIpLHJlcXVpcmUoXCIuL2xpYi90cmF2ZXJzYWxcIikscmVxdWlyZShcIi4vbGliL21hbmlwdWxhdGlvblwiKSxyZXF1aXJlKFwiLi9saWIvcXVlcnlpbmdcIikscmVxdWlyZShcIi4vbGliL2xlZ2FjeVwiKSxyZXF1aXJlKFwiLi9saWIvaGVscGVyc1wiKV0uZm9yRWFjaChmdW5jdGlvbihleHQpe09iamVjdC5rZXlzKGV4dCkuZm9yRWFjaChmdW5jdGlvbihrZXkpe0RvbVV0aWxzW2tleV09ZXh0W2tleV0uYmluZChEb21VdGlscyl9KX0pfSx7XCIuL2xpYi9oZWxwZXJzXCI6MTQsXCIuL2xpYi9sZWdhY3lcIjoxNSxcIi4vbGliL21hbmlwdWxhdGlvblwiOjE2LFwiLi9saWIvcXVlcnlpbmdcIjoxNyxcIi4vbGliL3N0cmluZ2lmeVwiOjE4LFwiLi9saWIvdHJhdmVyc2FsXCI6MTl9XSwxNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7ZXhwb3J0cy5yZW1vdmVTdWJzZXRzPWZ1bmN0aW9uKG5vZGVzKXt2YXIgaWR4PW5vZGVzLmxlbmd0aCxub2RlLGFuY2VzdG9yLHJlcGxhY2U7d2hpbGUoLS1pZHg+LTEpe25vZGU9YW5jZXN0b3I9bm9kZXNbaWR4XTtub2Rlc1tpZHhdPW51bGw7cmVwbGFjZT10cnVlO3doaWxlKGFuY2VzdG9yKXtpZihub2Rlcy5pbmRleE9mKGFuY2VzdG9yKT4tMSl7cmVwbGFjZT1mYWxzZTtub2Rlcy5zcGxpY2UoaWR4LDEpO2JyZWFrfWFuY2VzdG9yPWFuY2VzdG9yLnBhcmVudH1pZihyZXBsYWNlKXtub2Rlc1tpZHhdPW5vZGV9fXJldHVybiBub2Rlc307dmFyIFBPU0lUSU9OPXtESVNDT05ORUNURUQ6MSxQUkVDRURJTkc6MixGT0xMT1dJTkc6NCxDT05UQUlOUzo4LENPTlRBSU5FRF9CWToxNn07dmFyIGNvbXBhcmVQb3M9ZXhwb3J0cy5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbj1mdW5jdGlvbihub2RlQSxub2RlQil7dmFyIGFQYXJlbnRzPVtdO3ZhciBiUGFyZW50cz1bXTt2YXIgY3VycmVudCxzaGFyZWRQYXJlbnQsc2libGluZ3MsYVNpYmxpbmcsYlNpYmxpbmcsaWR4O2lmKG5vZGVBPT09bm9kZUIpe3JldHVybiAwfWN1cnJlbnQ9bm9kZUE7d2hpbGUoY3VycmVudCl7YVBhcmVudHMudW5zaGlmdChjdXJyZW50KTtjdXJyZW50PWN1cnJlbnQucGFyZW50fWN1cnJlbnQ9bm9kZUI7d2hpbGUoY3VycmVudCl7YlBhcmVudHMudW5zaGlmdChjdXJyZW50KTtjdXJyZW50PWN1cnJlbnQucGFyZW50fWlkeD0wO3doaWxlKGFQYXJlbnRzW2lkeF09PT1iUGFyZW50c1tpZHhdKXtpZHgrK31pZihpZHg9PT0wKXtyZXR1cm4gUE9TSVRJT04uRElTQ09OTkVDVEVEfXNoYXJlZFBhcmVudD1hUGFyZW50c1tpZHgtMV07c2libGluZ3M9c2hhcmVkUGFyZW50LmNoaWxkcmVuO2FTaWJsaW5nPWFQYXJlbnRzW2lkeF07YlNpYmxpbmc9YlBhcmVudHNbaWR4XTtpZihzaWJsaW5ncy5pbmRleE9mKGFTaWJsaW5nKT5zaWJsaW5ncy5pbmRleE9mKGJTaWJsaW5nKSl7aWYoc2hhcmVkUGFyZW50PT09bm9kZUIpe3JldHVybiBQT1NJVElPTi5GT0xMT1dJTkd8UE9TSVRJT04uQ09OVEFJTkVEX0JZfXJldHVybiBQT1NJVElPTi5GT0xMT1dJTkd9ZWxzZXtpZihzaGFyZWRQYXJlbnQ9PT1ub2RlQSl7cmV0dXJuIFBPU0lUSU9OLlBSRUNFRElOR3xQT1NJVElPTi5DT05UQUlOU31yZXR1cm4gUE9TSVRJT04uUFJFQ0VESU5HfX07ZXhwb3J0cy51bmlxdWVTb3J0PWZ1bmN0aW9uKG5vZGVzKXt2YXIgaWR4PW5vZGVzLmxlbmd0aCxub2RlLHBvc2l0aW9uO25vZGVzPW5vZGVzLnNsaWNlKCk7d2hpbGUoLS1pZHg+LTEpe25vZGU9bm9kZXNbaWR4XTtwb3NpdGlvbj1ub2Rlcy5pbmRleE9mKG5vZGUpO2lmKHBvc2l0aW9uPi0xJiZwb3NpdGlvbjxpZHgpe25vZGVzLnNwbGljZShpZHgsMSl9fW5vZGVzLnNvcnQoZnVuY3Rpb24oYSxiKXt2YXIgcmVsYXRpdmU9Y29tcGFyZVBvcyhhLGIpO2lmKHJlbGF0aXZlJlBPU0lUSU9OLlBSRUNFRElORyl7cmV0dXJuLTF9ZWxzZSBpZihyZWxhdGl2ZSZQT1NJVElPTi5GT0xMT1dJTkcpe3JldHVybiAxfXJldHVybiAwfSk7cmV0dXJuIG5vZGVzfX0se31dLDE1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgRWxlbWVudFR5cGU9cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpO3ZhciBpc1RhZz1leHBvcnRzLmlzVGFnPUVsZW1lbnRUeXBlLmlzVGFnO2V4cG9ydHMudGVzdEVsZW1lbnQ9ZnVuY3Rpb24ob3B0aW9ucyxlbGVtZW50KXtmb3IodmFyIGtleSBpbiBvcHRpb25zKXtpZighb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShrZXkpKTtlbHNlIGlmKGtleT09PVwidGFnX25hbWVcIil7aWYoIWlzVGFnKGVsZW1lbnQpfHwhb3B0aW9ucy50YWdfbmFtZShlbGVtZW50Lm5hbWUpKXtyZXR1cm4gZmFsc2V9fWVsc2UgaWYoa2V5PT09XCJ0YWdfdHlwZVwiKXtpZighb3B0aW9ucy50YWdfdHlwZShlbGVtZW50LnR5cGUpKXJldHVybiBmYWxzZX1lbHNlIGlmKGtleT09PVwidGFnX2NvbnRhaW5zXCIpe2lmKGlzVGFnKGVsZW1lbnQpfHwhb3B0aW9ucy50YWdfY29udGFpbnMoZWxlbWVudC5kYXRhKSl7cmV0dXJuIGZhbHNlfX1lbHNlIGlmKCFlbGVtZW50LmF0dHJpYnN8fCFvcHRpb25zW2tleV0oZWxlbWVudC5hdHRyaWJzW2tleV0pKXtyZXR1cm4gZmFsc2V9fXJldHVybiB0cnVlfTt2YXIgQ2hlY2tzPXt0YWdfbmFtZTpmdW5jdGlvbihuYW1lKXtpZih0eXBlb2YgbmFtZT09PVwiZnVuY3Rpb25cIil7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiBpc1RhZyhlbGVtKSYmbmFtZShlbGVtLm5hbWUpfX1lbHNlIGlmKG5hbWU9PT1cIipcIil7cmV0dXJuIGlzVGFnfWVsc2V7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiBpc1RhZyhlbGVtKSYmZWxlbS5uYW1lPT09bmFtZX19fSx0YWdfdHlwZTpmdW5jdGlvbih0eXBlKXtpZih0eXBlb2YgdHlwZT09PVwiZnVuY3Rpb25cIil7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiB0eXBlKGVsZW0udHlwZSl9fWVsc2V7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiBlbGVtLnR5cGU9PT10eXBlfX19LHRhZ19jb250YWluczpmdW5jdGlvbihkYXRhKXtpZih0eXBlb2YgZGF0YT09PVwiZnVuY3Rpb25cIil7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiFpc1RhZyhlbGVtKSYmZGF0YShlbGVtLmRhdGEpfX1lbHNle3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4haXNUYWcoZWxlbSkmJmVsZW0uZGF0YT09PWRhdGF9fX19O2Z1bmN0aW9uIGdldEF0dHJpYkNoZWNrKGF0dHJpYix2YWx1ZSl7aWYodHlwZW9mIHZhbHVlPT09XCJmdW5jdGlvblwiKXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0uYXR0cmlicyYmdmFsdWUoZWxlbS5hdHRyaWJzW2F0dHJpYl0pfX1lbHNle3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5hdHRyaWJzJiZlbGVtLmF0dHJpYnNbYXR0cmliXT09PXZhbHVlfX19ZnVuY3Rpb24gY29tYmluZUZ1bmNzKGEsYil7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiBhKGVsZW0pfHxiKGVsZW0pfX1leHBvcnRzLmdldEVsZW1lbnRzPWZ1bmN0aW9uKG9wdGlvbnMsZWxlbWVudCxyZWN1cnNlLGxpbWl0KXt2YXIgZnVuY3M9T2JqZWN0LmtleXMob3B0aW9ucykubWFwKGZ1bmN0aW9uKGtleSl7dmFyIHZhbHVlPW9wdGlvbnNba2V5XTtyZXR1cm4ga2V5IGluIENoZWNrcz9DaGVja3Nba2V5XSh2YWx1ZSk6Z2V0QXR0cmliQ2hlY2soa2V5LHZhbHVlKX0pO3JldHVybiBmdW5jcy5sZW5ndGg9PT0wP1tdOnRoaXMuZmlsdGVyKGZ1bmNzLnJlZHVjZShjb21iaW5lRnVuY3MpLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl9O2V4cG9ydHMuZ2V0RWxlbWVudEJ5SWQ9ZnVuY3Rpb24oaWQsZWxlbWVudCxyZWN1cnNlKXtpZighQXJyYXkuaXNBcnJheShlbGVtZW50KSllbGVtZW50PVtlbGVtZW50XTtyZXR1cm4gdGhpcy5maW5kT25lKGdldEF0dHJpYkNoZWNrKFwiaWRcIixpZCksZWxlbWVudCxyZWN1cnNlIT09ZmFsc2UpfTtleHBvcnRzLmdldEVsZW1lbnRzQnlUYWdOYW1lPWZ1bmN0aW9uKG5hbWUsZWxlbWVudCxyZWN1cnNlLGxpbWl0KXtyZXR1cm4gdGhpcy5maWx0ZXIoQ2hlY2tzLnRhZ19uYW1lKG5hbWUpLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl9O2V4cG9ydHMuZ2V0RWxlbWVudHNCeVRhZ1R5cGU9ZnVuY3Rpb24odHlwZSxlbGVtZW50LHJlY3Vyc2UsbGltaXQpe3JldHVybiB0aGlzLmZpbHRlcihDaGVja3MudGFnX3R5cGUodHlwZSksZWxlbWVudCxyZWN1cnNlLGxpbWl0KX19LHtkb21lbGVtZW50dHlwZTo5fV0sMTY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe2V4cG9ydHMucmVtb3ZlRWxlbWVudD1mdW5jdGlvbihlbGVtKXtpZihlbGVtLnByZXYpZWxlbS5wcmV2Lm5leHQ9ZWxlbS5uZXh0O2lmKGVsZW0ubmV4dCllbGVtLm5leHQucHJldj1lbGVtLnByZXY7aWYoZWxlbS5wYXJlbnQpe3ZhciBjaGlsZHM9ZWxlbS5wYXJlbnQuY2hpbGRyZW47Y2hpbGRzLnNwbGljZShjaGlsZHMubGFzdEluZGV4T2YoZWxlbSksMSl9fTtleHBvcnRzLnJlcGxhY2VFbGVtZW50PWZ1bmN0aW9uKGVsZW0scmVwbGFjZW1lbnQpe3ZhciBwcmV2PXJlcGxhY2VtZW50LnByZXY9ZWxlbS5wcmV2O2lmKHByZXYpe3ByZXYubmV4dD1yZXBsYWNlbWVudH12YXIgbmV4dD1yZXBsYWNlbWVudC5uZXh0PWVsZW0ubmV4dDtpZihuZXh0KXtuZXh0LnByZXY9cmVwbGFjZW1lbnR9dmFyIHBhcmVudD1yZXBsYWNlbWVudC5wYXJlbnQ9ZWxlbS5wYXJlbnQ7aWYocGFyZW50KXt2YXIgY2hpbGRzPXBhcmVudC5jaGlsZHJlbjtjaGlsZHNbY2hpbGRzLmxhc3RJbmRleE9mKGVsZW0pXT1yZXBsYWNlbWVudH19O2V4cG9ydHMuYXBwZW5kQ2hpbGQ9ZnVuY3Rpb24oZWxlbSxjaGlsZCl7Y2hpbGQucGFyZW50PWVsZW07aWYoZWxlbS5jaGlsZHJlbi5wdXNoKGNoaWxkKSE9PTEpe3ZhciBzaWJsaW5nPWVsZW0uY2hpbGRyZW5bZWxlbS5jaGlsZHJlbi5sZW5ndGgtMl07c2libGluZy5uZXh0PWNoaWxkO2NoaWxkLnByZXY9c2libGluZztjaGlsZC5uZXh0PW51bGx9fTtleHBvcnRzLmFwcGVuZD1mdW5jdGlvbihlbGVtLG5leHQpe3ZhciBwYXJlbnQ9ZWxlbS5wYXJlbnQsY3Vyck5leHQ9ZWxlbS5uZXh0O25leHQubmV4dD1jdXJyTmV4dDtuZXh0LnByZXY9ZWxlbTtlbGVtLm5leHQ9bmV4dDtuZXh0LnBhcmVudD1wYXJlbnQ7aWYoY3Vyck5leHQpe2N1cnJOZXh0LnByZXY9bmV4dDtpZihwYXJlbnQpe3ZhciBjaGlsZHM9cGFyZW50LmNoaWxkcmVuO2NoaWxkcy5zcGxpY2UoY2hpbGRzLmxhc3RJbmRleE9mKGN1cnJOZXh0KSwwLG5leHQpfX1lbHNlIGlmKHBhcmVudCl7cGFyZW50LmNoaWxkcmVuLnB1c2gobmV4dCl9fTtleHBvcnRzLnByZXBlbmQ9ZnVuY3Rpb24oZWxlbSxwcmV2KXt2YXIgcGFyZW50PWVsZW0ucGFyZW50O2lmKHBhcmVudCl7dmFyIGNoaWxkcz1wYXJlbnQuY2hpbGRyZW47Y2hpbGRzLnNwbGljZShjaGlsZHMubGFzdEluZGV4T2YoZWxlbSksMCxwcmV2KX1pZihlbGVtLnByZXYpe2VsZW0ucHJldi5uZXh0PXByZXZ9cHJldi5wYXJlbnQ9cGFyZW50O3ByZXYucHJldj1lbGVtLnByZXY7cHJldi5uZXh0PWVsZW07ZWxlbS5wcmV2PXByZXZ9fSx7fV0sMTc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBpc1RhZz1yZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIikuaXNUYWc7bW9kdWxlLmV4cG9ydHM9e2ZpbHRlcjpmaWx0ZXIsZmluZDpmaW5kLGZpbmRPbmVDaGlsZDpmaW5kT25lQ2hpbGQsZmluZE9uZTpmaW5kT25lLGV4aXN0c09uZTpleGlzdHNPbmUsZmluZEFsbDpmaW5kQWxsfTtmdW5jdGlvbiBmaWx0ZXIodGVzdCxlbGVtZW50LHJlY3Vyc2UsbGltaXQpe2lmKCFBcnJheS5pc0FycmF5KGVsZW1lbnQpKWVsZW1lbnQ9W2VsZW1lbnRdO2lmKHR5cGVvZiBsaW1pdCE9PVwibnVtYmVyXCJ8fCFpc0Zpbml0ZShsaW1pdCkpe2xpbWl0PUluZmluaXR5fXJldHVybiBmaW5kKHRlc3QsZWxlbWVudCxyZWN1cnNlIT09ZmFsc2UsbGltaXQpfWZ1bmN0aW9uIGZpbmQodGVzdCxlbGVtcyxyZWN1cnNlLGxpbWl0KXt2YXIgcmVzdWx0PVtdLGNoaWxkcztmb3IodmFyIGk9MCxqPWVsZW1zLmxlbmd0aDtpPGo7aSsrKXtpZih0ZXN0KGVsZW1zW2ldKSl7cmVzdWx0LnB1c2goZWxlbXNbaV0pO2lmKC0tbGltaXQ8PTApYnJlYWt9Y2hpbGRzPWVsZW1zW2ldLmNoaWxkcmVuO2lmKHJlY3Vyc2UmJmNoaWxkcyYmY2hpbGRzLmxlbmd0aD4wKXtjaGlsZHM9ZmluZCh0ZXN0LGNoaWxkcyxyZWN1cnNlLGxpbWl0KTtyZXN1bHQ9cmVzdWx0LmNvbmNhdChjaGlsZHMpO2xpbWl0LT1jaGlsZHMubGVuZ3RoO2lmKGxpbWl0PD0wKWJyZWFrfX1yZXR1cm4gcmVzdWx0fWZ1bmN0aW9uIGZpbmRPbmVDaGlsZCh0ZXN0LGVsZW1zKXtmb3IodmFyIGk9MCxsPWVsZW1zLmxlbmd0aDtpPGw7aSsrKXtpZih0ZXN0KGVsZW1zW2ldKSlyZXR1cm4gZWxlbXNbaV19cmV0dXJuIG51bGx9ZnVuY3Rpb24gZmluZE9uZSh0ZXN0LGVsZW1zKXt2YXIgZWxlbT1udWxsO2Zvcih2YXIgaT0wLGw9ZWxlbXMubGVuZ3RoO2k8bCYmIWVsZW07aSsrKXtpZighaXNUYWcoZWxlbXNbaV0pKXtjb250aW51ZX1lbHNlIGlmKHRlc3QoZWxlbXNbaV0pKXtlbGVtPWVsZW1zW2ldfWVsc2UgaWYoZWxlbXNbaV0uY2hpbGRyZW4ubGVuZ3RoPjApe2VsZW09ZmluZE9uZSh0ZXN0LGVsZW1zW2ldLmNoaWxkcmVuKX19cmV0dXJuIGVsZW19ZnVuY3Rpb24gZXhpc3RzT25lKHRlc3QsZWxlbXMpe2Zvcih2YXIgaT0wLGw9ZWxlbXMubGVuZ3RoO2k8bDtpKyspe2lmKGlzVGFnKGVsZW1zW2ldKSYmKHRlc3QoZWxlbXNbaV0pfHxlbGVtc1tpXS5jaGlsZHJlbi5sZW5ndGg+MCYmZXhpc3RzT25lKHRlc3QsZWxlbXNbaV0uY2hpbGRyZW4pKSl7cmV0dXJuIHRydWV9fXJldHVybiBmYWxzZX1mdW5jdGlvbiBmaW5kQWxsKHRlc3QsZWxlbXMpe3ZhciByZXN1bHQ9W107Zm9yKHZhciBpPTAsaj1lbGVtcy5sZW5ndGg7aTxqO2krKyl7aWYoIWlzVGFnKGVsZW1zW2ldKSljb250aW51ZTtpZih0ZXN0KGVsZW1zW2ldKSlyZXN1bHQucHVzaChlbGVtc1tpXSk7aWYoZWxlbXNbaV0uY2hpbGRyZW4ubGVuZ3RoPjApe3Jlc3VsdD1yZXN1bHQuY29uY2F0KGZpbmRBbGwodGVzdCxlbGVtc1tpXS5jaGlsZHJlbikpfX1yZXR1cm4gcmVzdWx0fX0se2RvbWVsZW1lbnR0eXBlOjl9XSwxODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIEVsZW1lbnRUeXBlPXJlcXVpcmUoXCJkb21lbGVtZW50dHlwZVwiKSxnZXRPdXRlckhUTUw9cmVxdWlyZShcImRvbS1zZXJpYWxpemVyXCIpLGlzVGFnPUVsZW1lbnRUeXBlLmlzVGFnO21vZHVsZS5leHBvcnRzPXtnZXRJbm5lckhUTUw6Z2V0SW5uZXJIVE1MLGdldE91dGVySFRNTDpnZXRPdXRlckhUTUwsZ2V0VGV4dDpnZXRUZXh0fTtmdW5jdGlvbiBnZXRJbm5lckhUTUwoZWxlbSxvcHRzKXtyZXR1cm4gZWxlbS5jaGlsZHJlbj9lbGVtLmNoaWxkcmVuLm1hcChmdW5jdGlvbihlbGVtKXtyZXR1cm4gZ2V0T3V0ZXJIVE1MKGVsZW0sb3B0cyl9KS5qb2luKFwiXCIpOlwiXCJ9ZnVuY3Rpb24gZ2V0VGV4dChlbGVtKXtpZihBcnJheS5pc0FycmF5KGVsZW0pKXJldHVybiBlbGVtLm1hcChnZXRUZXh0KS5qb2luKFwiXCIpO2lmKGlzVGFnKGVsZW0pfHxlbGVtLnR5cGU9PT1FbGVtZW50VHlwZS5DREFUQSlyZXR1cm4gZ2V0VGV4dChlbGVtLmNoaWxkcmVuKTtpZihlbGVtLnR5cGU9PT1FbGVtZW50VHlwZS5UZXh0KXJldHVybiBlbGVtLmRhdGE7cmV0dXJuXCJcIn19LHtcImRvbS1zZXJpYWxpemVyXCI6Nyxkb21lbGVtZW50dHlwZTo5fV0sMTk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBnZXRDaGlsZHJlbj1leHBvcnRzLmdldENoaWxkcmVuPWZ1bmN0aW9uKGVsZW0pe3JldHVybiBlbGVtLmNoaWxkcmVufTt2YXIgZ2V0UGFyZW50PWV4cG9ydHMuZ2V0UGFyZW50PWZ1bmN0aW9uKGVsZW0pe3JldHVybiBlbGVtLnBhcmVudH07ZXhwb3J0cy5nZXRTaWJsaW5ncz1mdW5jdGlvbihlbGVtKXt2YXIgcGFyZW50PWdldFBhcmVudChlbGVtKTtyZXR1cm4gcGFyZW50P2dldENoaWxkcmVuKHBhcmVudCk6W2VsZW1dfTtleHBvcnRzLmdldEF0dHJpYnV0ZVZhbHVlPWZ1bmN0aW9uKGVsZW0sbmFtZSl7cmV0dXJuIGVsZW0uYXR0cmlicyYmZWxlbS5hdHRyaWJzW25hbWVdfTtleHBvcnRzLmhhc0F0dHJpYj1mdW5jdGlvbihlbGVtLG5hbWUpe3JldHVybiEhZWxlbS5hdHRyaWJzJiZoYXNPd25Qcm9wZXJ0eS5jYWxsKGVsZW0uYXR0cmlicyxuYW1lKX07ZXhwb3J0cy5nZXROYW1lPWZ1bmN0aW9uKGVsZW0pe3JldHVybiBlbGVtLm5hbWV9fSx7fV0sMjA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBlbmNvZGU9cmVxdWlyZShcIi4vbGliL2VuY29kZS5qc1wiKSxkZWNvZGU9cmVxdWlyZShcIi4vbGliL2RlY29kZS5qc1wiKTtleHBvcnRzLmRlY29kZT1mdW5jdGlvbihkYXRhLGxldmVsKXtyZXR1cm4oIWxldmVsfHxsZXZlbDw9MD9kZWNvZGUuWE1MOmRlY29kZS5IVE1MKShkYXRhKX07ZXhwb3J0cy5kZWNvZGVTdHJpY3Q9ZnVuY3Rpb24oZGF0YSxsZXZlbCl7cmV0dXJuKCFsZXZlbHx8bGV2ZWw8PTA/ZGVjb2RlLlhNTDpkZWNvZGUuSFRNTFN0cmljdCkoZGF0YSl9O2V4cG9ydHMuZW5jb2RlPWZ1bmN0aW9uKGRhdGEsbGV2ZWwpe3JldHVybighbGV2ZWx8fGxldmVsPD0wP2VuY29kZS5YTUw6ZW5jb2RlLkhUTUwpKGRhdGEpfTtleHBvcnRzLmVuY29kZVhNTD1lbmNvZGUuWE1MO2V4cG9ydHMuZW5jb2RlSFRNTDQ9ZXhwb3J0cy5lbmNvZGVIVE1MNT1leHBvcnRzLmVuY29kZUhUTUw9ZW5jb2RlLkhUTUw7ZXhwb3J0cy5kZWNvZGVYTUw9ZXhwb3J0cy5kZWNvZGVYTUxTdHJpY3Q9ZGVjb2RlLlhNTDtleHBvcnRzLmRlY29kZUhUTUw0PWV4cG9ydHMuZGVjb2RlSFRNTDU9ZXhwb3J0cy5kZWNvZGVIVE1MPWRlY29kZS5IVE1MO2V4cG9ydHMuZGVjb2RlSFRNTDRTdHJpY3Q9ZXhwb3J0cy5kZWNvZGVIVE1MNVN0cmljdD1leHBvcnRzLmRlY29kZUhUTUxTdHJpY3Q9ZGVjb2RlLkhUTUxTdHJpY3Q7ZXhwb3J0cy5lc2NhcGU9ZW5jb2RlLmVzY2FwZX0se1wiLi9saWIvZGVjb2RlLmpzXCI6MjEsXCIuL2xpYi9lbmNvZGUuanNcIjoyM31dLDIxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgZW50aXR5TWFwPXJlcXVpcmUoXCIuLi9tYXBzL2VudGl0aWVzLmpzb25cIiksbGVnYWN5TWFwPXJlcXVpcmUoXCIuLi9tYXBzL2xlZ2FjeS5qc29uXCIpLHhtbE1hcD1yZXF1aXJlKFwiLi4vbWFwcy94bWwuanNvblwiKSxkZWNvZGVDb2RlUG9pbnQ9cmVxdWlyZShcIi4vZGVjb2RlX2NvZGVwb2ludC5qc1wiKTt2YXIgZGVjb2RlWE1MU3RyaWN0PWdldFN0cmljdERlY29kZXIoeG1sTWFwKSxkZWNvZGVIVE1MU3RyaWN0PWdldFN0cmljdERlY29kZXIoZW50aXR5TWFwKTtmdW5jdGlvbiBnZXRTdHJpY3REZWNvZGVyKG1hcCl7dmFyIGtleXM9T2JqZWN0LmtleXMobWFwKS5qb2luKFwifFwiKSxyZXBsYWNlPWdldFJlcGxhY2VyKG1hcCk7a2V5cys9XCJ8I1t4WF1bXFxcXGRhLWZBLUZdK3wjXFxcXGQrXCI7dmFyIHJlPW5ldyBSZWdFeHAoXCImKD86XCIra2V5cytcIik7XCIsXCJnXCIpO3JldHVybiBmdW5jdGlvbihzdHIpe3JldHVybiBTdHJpbmcoc3RyKS5yZXBsYWNlKHJlLHJlcGxhY2UpfX12YXIgZGVjb2RlSFRNTD1mdW5jdGlvbigpe3ZhciBsZWdhY3k9T2JqZWN0LmtleXMobGVnYWN5TWFwKS5zb3J0KHNvcnRlcik7dmFyIGtleXM9T2JqZWN0LmtleXMoZW50aXR5TWFwKS5zb3J0KHNvcnRlcik7Zm9yKHZhciBpPTAsaj0wO2k8a2V5cy5sZW5ndGg7aSsrKXtpZihsZWdhY3lbal09PT1rZXlzW2ldKXtrZXlzW2ldKz1cIjs/XCI7aisrfWVsc2V7a2V5c1tpXSs9XCI7XCJ9fXZhciByZT1uZXcgUmVnRXhwKFwiJig/OlwiK2tleXMuam9pbihcInxcIikrXCJ8I1t4WF1bXFxcXGRhLWZBLUZdKzs/fCNcXFxcZCs7PylcIixcImdcIikscmVwbGFjZT1nZXRSZXBsYWNlcihlbnRpdHlNYXApO2Z1bmN0aW9uIHJlcGxhY2VyKHN0cil7aWYoc3RyLnN1YnN0cigtMSkhPT1cIjtcIilzdHIrPVwiO1wiO3JldHVybiByZXBsYWNlKHN0cil9cmV0dXJuIGZ1bmN0aW9uKHN0cil7cmV0dXJuIFN0cmluZyhzdHIpLnJlcGxhY2UocmUscmVwbGFjZXIpfX0oKTtmdW5jdGlvbiBzb3J0ZXIoYSxiKXtyZXR1cm4gYTxiPzE6LTF9ZnVuY3Rpb24gZ2V0UmVwbGFjZXIobWFwKXtyZXR1cm4gZnVuY3Rpb24gcmVwbGFjZShzdHIpe2lmKHN0ci5jaGFyQXQoMSk9PT1cIiNcIil7aWYoc3RyLmNoYXJBdCgyKT09PVwiWFwifHxzdHIuY2hhckF0KDIpPT09XCJ4XCIpe3JldHVybiBkZWNvZGVDb2RlUG9pbnQocGFyc2VJbnQoc3RyLnN1YnN0cigzKSwxNikpfXJldHVybiBkZWNvZGVDb2RlUG9pbnQocGFyc2VJbnQoc3RyLnN1YnN0cigyKSwxMCkpfXJldHVybiBtYXBbc3RyLnNsaWNlKDEsLTEpXTtcbn19bW9kdWxlLmV4cG9ydHM9e1hNTDpkZWNvZGVYTUxTdHJpY3QsSFRNTDpkZWNvZGVIVE1MLEhUTUxTdHJpY3Q6ZGVjb2RlSFRNTFN0cmljdH19LHtcIi4uL21hcHMvZW50aXRpZXMuanNvblwiOjI1LFwiLi4vbWFwcy9sZWdhY3kuanNvblwiOjI2LFwiLi4vbWFwcy94bWwuanNvblwiOjI3LFwiLi9kZWNvZGVfY29kZXBvaW50LmpzXCI6MjJ9XSwyMjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGRlY29kZU1hcD1yZXF1aXJlKFwiLi4vbWFwcy9kZWNvZGUuanNvblwiKTttb2R1bGUuZXhwb3J0cz1kZWNvZGVDb2RlUG9pbnQ7ZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50KGNvZGVQb2ludCl7aWYoY29kZVBvaW50Pj01NTI5NiYmY29kZVBvaW50PD01NzM0M3x8Y29kZVBvaW50PjExMTQxMTEpe3JldHVyblwi77+9XCJ9aWYoY29kZVBvaW50IGluIGRlY29kZU1hcCl7Y29kZVBvaW50PWRlY29kZU1hcFtjb2RlUG9pbnRdfXZhciBvdXRwdXQ9XCJcIjtpZihjb2RlUG9pbnQ+NjU1MzUpe2NvZGVQb2ludC09NjU1MzY7b3V0cHV0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGVQb2ludD4+PjEwJjEwMjN8NTUyOTYpO2NvZGVQb2ludD01NjMyMHxjb2RlUG9pbnQmMTAyM31vdXRwdXQrPVN0cmluZy5mcm9tQ2hhckNvZGUoY29kZVBvaW50KTtyZXR1cm4gb3V0cHV0fX0se1wiLi4vbWFwcy9kZWNvZGUuanNvblwiOjI0fV0sMjM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBpbnZlcnNlWE1MPWdldEludmVyc2VPYmoocmVxdWlyZShcIi4uL21hcHMveG1sLmpzb25cIikpLHhtbFJlcGxhY2VyPWdldEludmVyc2VSZXBsYWNlcihpbnZlcnNlWE1MKTtleHBvcnRzLlhNTD1nZXRJbnZlcnNlKGludmVyc2VYTUwseG1sUmVwbGFjZXIpO3ZhciBpbnZlcnNlSFRNTD1nZXRJbnZlcnNlT2JqKHJlcXVpcmUoXCIuLi9tYXBzL2VudGl0aWVzLmpzb25cIikpLGh0bWxSZXBsYWNlcj1nZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZUhUTUwpO2V4cG9ydHMuSFRNTD1nZXRJbnZlcnNlKGludmVyc2VIVE1MLGh0bWxSZXBsYWNlcik7ZnVuY3Rpb24gZ2V0SW52ZXJzZU9iaihvYmope3JldHVybiBPYmplY3Qua2V5cyhvYmopLnNvcnQoKS5yZWR1Y2UoZnVuY3Rpb24oaW52ZXJzZSxuYW1lKXtpbnZlcnNlW29ialtuYW1lXV09XCImXCIrbmFtZStcIjtcIjtyZXR1cm4gaW52ZXJzZX0se30pfWZ1bmN0aW9uIGdldEludmVyc2VSZXBsYWNlcihpbnZlcnNlKXt2YXIgc2luZ2xlPVtdLG11bHRpcGxlPVtdO09iamVjdC5rZXlzKGludmVyc2UpLmZvckVhY2goZnVuY3Rpb24oayl7aWYoay5sZW5ndGg9PT0xKXtzaW5nbGUucHVzaChcIlxcXFxcIitrKX1lbHNle211bHRpcGxlLnB1c2goayl9fSk7bXVsdGlwbGUudW5zaGlmdChcIltcIitzaW5nbGUuam9pbihcIlwiKStcIl1cIik7cmV0dXJuIG5ldyBSZWdFeHAobXVsdGlwbGUuam9pbihcInxcIiksXCJnXCIpfXZhciByZV9ub25BU0NJST0vW15cXDAtXFx4N0ZdL2cscmVfYXN0cmFsU3ltYm9scz0vW1xcdUQ4MDAtXFx1REJGRl1bXFx1REMwMC1cXHVERkZGXS9nO2Z1bmN0aW9uIHNpbmdsZUNoYXJSZXBsYWNlcihjKXtyZXR1cm5cIiYjeFwiK2MuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKStcIjtcIn1mdW5jdGlvbiBhc3RyYWxSZXBsYWNlcihjKXt2YXIgaGlnaD1jLmNoYXJDb2RlQXQoMCk7dmFyIGxvdz1jLmNoYXJDb2RlQXQoMSk7dmFyIGNvZGVQb2ludD0oaGlnaC01NTI5NikqMTAyNCtsb3ctNTYzMjArNjU1MzY7cmV0dXJuXCImI3hcIitjb2RlUG9pbnQudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkrXCI7XCJ9ZnVuY3Rpb24gZ2V0SW52ZXJzZShpbnZlcnNlLHJlKXtmdW5jdGlvbiBmdW5jKG5hbWUpe3JldHVybiBpbnZlcnNlW25hbWVdfXJldHVybiBmdW5jdGlvbihkYXRhKXtyZXR1cm4gZGF0YS5yZXBsYWNlKHJlLGZ1bmMpLnJlcGxhY2UocmVfYXN0cmFsU3ltYm9scyxhc3RyYWxSZXBsYWNlcikucmVwbGFjZShyZV9ub25BU0NJSSxzaW5nbGVDaGFyUmVwbGFjZXIpfX12YXIgcmVfeG1sQ2hhcnM9Z2V0SW52ZXJzZVJlcGxhY2VyKGludmVyc2VYTUwpO2Z1bmN0aW9uIGVzY2FwZVhNTChkYXRhKXtyZXR1cm4gZGF0YS5yZXBsYWNlKHJlX3htbENoYXJzLHNpbmdsZUNoYXJSZXBsYWNlcikucmVwbGFjZShyZV9hc3RyYWxTeW1ib2xzLGFzdHJhbFJlcGxhY2VyKS5yZXBsYWNlKHJlX25vbkFTQ0lJLHNpbmdsZUNoYXJSZXBsYWNlcil9ZXhwb3J0cy5lc2NhcGU9ZXNjYXBlWE1MfSx7XCIuLi9tYXBzL2VudGl0aWVzLmpzb25cIjoyNSxcIi4uL21hcHMveG1sLmpzb25cIjoyN31dLDI0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz17MDo2NTUzMywxMjg6ODM2NCwxMzA6ODIxOCwxMzE6NDAyLDEzMjo4MjIyLDEzMzo4MjMwLDEzNDo4MjI0LDEzNTo4MjI1LDEzNjo3MTAsMTM3OjgyNDAsMTM4OjM1MiwxMzk6ODI0OSwxNDA6MzM4LDE0MjozODEsMTQ1OjgyMTYsMTQ2OjgyMTcsMTQ3OjgyMjAsMTQ4OjgyMjEsMTQ5OjgyMjYsMTUwOjgyMTEsMTUxOjgyMTIsMTUyOjczMiwxNTM6ODQ4MiwxNTQ6MzUzLDE1NTo4MjUwLDE1NjozMzksMTU4OjM4MiwxNTk6Mzc2fX0se31dLDI1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz17QWFjdXRlOlwiw4FcIixhYWN1dGU6XCLDoVwiLEFicmV2ZTpcIsSCXCIsYWJyZXZlOlwixINcIixhYzpcIuKIvlwiLGFjZDpcIuKIv1wiLGFjRTpcIuKIvsyzXCIsQWNpcmM6XCLDglwiLGFjaXJjOlwiw6JcIixhY3V0ZTpcIsK0XCIsQWN5Olwi0JBcIixhY3k6XCLQsFwiLEFFbGlnOlwiw4ZcIixhZWxpZzpcIsOmXCIsYWY6XCLigaFcIixBZnI6XCLwnZSEXCIsYWZyOlwi8J2UnlwiLEFncmF2ZTpcIsOAXCIsYWdyYXZlOlwiw6BcIixhbGVmc3ltOlwi4oS1XCIsYWxlcGg6XCLihLVcIixBbHBoYTpcIs6RXCIsYWxwaGE6XCLOsVwiLEFtYWNyOlwixIBcIixhbWFjcjpcIsSBXCIsYW1hbGc6XCLiqL9cIixhbXA6XCImXCIsQU1QOlwiJlwiLGFuZGFuZDpcIuKplVwiLEFuZDpcIuKpk1wiLGFuZDpcIuKIp1wiLGFuZGQ6XCLiqZxcIixhbmRzbG9wZTpcIuKpmFwiLGFuZHY6XCLiqZpcIixhbmc6XCLiiKBcIixhbmdlOlwi4qakXCIsYW5nbGU6XCLiiKBcIixhbmdtc2RhYTpcIuKmqFwiLGFuZ21zZGFiOlwi4qapXCIsYW5nbXNkYWM6XCLipqpcIixhbmdtc2RhZDpcIuKmq1wiLGFuZ21zZGFlOlwi4qasXCIsYW5nbXNkYWY6XCLipq1cIixhbmdtc2RhZzpcIuKmrlwiLGFuZ21zZGFoOlwi4qavXCIsYW5nbXNkOlwi4oihXCIsYW5ncnQ6XCLiiJ9cIixhbmdydHZiOlwi4oq+XCIsYW5ncnR2YmQ6XCLipp1cIixhbmdzcGg6XCLiiKJcIixhbmdzdDpcIsOFXCIsYW5nemFycjpcIuKNvFwiLEFvZ29uOlwixIRcIixhb2dvbjpcIsSFXCIsQW9wZjpcIvCdlLhcIixhb3BmOlwi8J2VklwiLGFwYWNpcjpcIuKpr1wiLGFwOlwi4omIXCIsYXBFOlwi4qmwXCIsYXBlOlwi4omKXCIsYXBpZDpcIuKJi1wiLGFwb3M6XCInXCIsQXBwbHlGdW5jdGlvbjpcIuKBoVwiLGFwcHJveDpcIuKJiFwiLGFwcHJveGVxOlwi4omKXCIsQXJpbmc6XCLDhVwiLGFyaW5nOlwiw6VcIixBc2NyOlwi8J2SnFwiLGFzY3I6XCLwnZK2XCIsQXNzaWduOlwi4omUXCIsYXN0OlwiKlwiLGFzeW1wOlwi4omIXCIsYXN5bXBlcTpcIuKJjVwiLEF0aWxkZTpcIsODXCIsYXRpbGRlOlwiw6NcIixBdW1sOlwiw4RcIixhdW1sOlwiw6RcIixhd2NvbmludDpcIuKIs1wiLGF3aW50Olwi4qiRXCIsYmFja2Nvbmc6XCLiiYxcIixiYWNrZXBzaWxvbjpcIs+2XCIsYmFja3ByaW1lOlwi4oC1XCIsYmFja3NpbTpcIuKIvVwiLGJhY2tzaW1lcTpcIuKLjVwiLEJhY2tzbGFzaDpcIuKIllwiLEJhcnY6XCLiq6dcIixiYXJ2ZWU6XCLiir1cIixiYXJ3ZWQ6XCLijIVcIixCYXJ3ZWQ6XCLijIZcIixiYXJ3ZWRnZTpcIuKMhVwiLGJicms6XCLijrVcIixiYnJrdGJyazpcIuKOtlwiLGJjb25nOlwi4omMXCIsQmN5Olwi0JFcIixiY3k6XCLQsVwiLGJkcXVvOlwi4oCeXCIsYmVjYXVzOlwi4oi1XCIsYmVjYXVzZTpcIuKItVwiLEJlY2F1c2U6XCLiiLVcIixiZW1wdHl2Olwi4qawXCIsYmVwc2k6XCLPtlwiLGJlcm5vdTpcIuKErFwiLEJlcm5vdWxsaXM6XCLihKxcIixCZXRhOlwizpJcIixiZXRhOlwizrJcIixiZXRoOlwi4oS2XCIsYmV0d2VlbjpcIuKJrFwiLEJmcjpcIvCdlIVcIixiZnI6XCLwnZSfXCIsYmlnY2FwOlwi4ouCXCIsYmlnY2lyYzpcIuKXr1wiLGJpZ2N1cDpcIuKLg1wiLGJpZ29kb3Q6XCLiqIBcIixiaWdvcGx1czpcIuKogVwiLGJpZ290aW1lczpcIuKoglwiLGJpZ3NxY3VwOlwi4qiGXCIsYmlnc3RhcjpcIuKYhVwiLGJpZ3RyaWFuZ2xlZG93bjpcIuKWvVwiLGJpZ3RyaWFuZ2xldXA6XCLilrNcIixiaWd1cGx1czpcIuKohFwiLGJpZ3ZlZTpcIuKLgVwiLGJpZ3dlZGdlOlwi4ouAXCIsYmthcm93Olwi4qSNXCIsYmxhY2tsb3plbmdlOlwi4qerXCIsYmxhY2tzcXVhcmU6XCLilqpcIixibGFja3RyaWFuZ2xlOlwi4pa0XCIsYmxhY2t0cmlhbmdsZWRvd246XCLilr5cIixibGFja3RyaWFuZ2xlbGVmdDpcIuKXglwiLGJsYWNrdHJpYW5nbGVyaWdodDpcIuKWuFwiLGJsYW5rOlwi4pCjXCIsYmxrMTI6XCLilpJcIixibGsxNDpcIuKWkVwiLGJsazM0Olwi4paTXCIsYmxvY2s6XCLilohcIixibmU6XCI94oOlXCIsYm5lcXVpdjpcIuKJoeKDpVwiLGJOb3Q6XCLiq61cIixibm90Olwi4oyQXCIsQm9wZjpcIvCdlLlcIixib3BmOlwi8J2Vk1wiLGJvdDpcIuKKpVwiLGJvdHRvbTpcIuKKpVwiLGJvd3RpZTpcIuKLiFwiLGJveGJveDpcIuKniVwiLGJveGRsOlwi4pSQXCIsYm94ZEw6XCLilZVcIixib3hEbDpcIuKVllwiLGJveERMOlwi4pWXXCIsYm94ZHI6XCLilIxcIixib3hkUjpcIuKVklwiLGJveERyOlwi4pWTXCIsYm94RFI6XCLilZRcIixib3hoOlwi4pSAXCIsYm94SDpcIuKVkFwiLGJveGhkOlwi4pSsXCIsYm94SGQ6XCLilaRcIixib3hoRDpcIuKVpVwiLGJveEhEOlwi4pWmXCIsYm94aHU6XCLilLRcIixib3hIdTpcIuKVp1wiLGJveGhVOlwi4pWoXCIsYm94SFU6XCLilalcIixib3htaW51czpcIuKKn1wiLGJveHBsdXM6XCLiip5cIixib3h0aW1lczpcIuKKoFwiLGJveHVsOlwi4pSYXCIsYm94dUw6XCLilZtcIixib3hVbDpcIuKVnFwiLGJveFVMOlwi4pWdXCIsYm94dXI6XCLilJRcIixib3h1UjpcIuKVmFwiLGJveFVyOlwi4pWZXCIsYm94VVI6XCLilZpcIixib3h2Olwi4pSCXCIsYm94VjpcIuKVkVwiLGJveHZoOlwi4pS8XCIsYm94dkg6XCLilapcIixib3hWaDpcIuKVq1wiLGJveFZIOlwi4pWsXCIsYm94dmw6XCLilKRcIixib3h2TDpcIuKVoVwiLGJveFZsOlwi4pWiXCIsYm94Vkw6XCLilaNcIixib3h2cjpcIuKUnFwiLGJveHZSOlwi4pWeXCIsYm94VnI6XCLilZ9cIixib3hWUjpcIuKVoFwiLGJwcmltZTpcIuKAtVwiLGJyZXZlOlwiy5hcIixCcmV2ZTpcIsuYXCIsYnJ2YmFyOlwiwqZcIixic2NyOlwi8J2St1wiLEJzY3I6XCLihKxcIixic2VtaTpcIuKBj1wiLGJzaW06XCLiiL1cIixic2ltZTpcIuKLjVwiLGJzb2xiOlwi4qeFXCIsYnNvbDpcIlxcXFxcIixic29saHN1YjpcIuKfiFwiLGJ1bGw6XCLigKJcIixidWxsZXQ6XCLigKJcIixidW1wOlwi4omOXCIsYnVtcEU6XCLiqq5cIixidW1wZTpcIuKJj1wiLEJ1bXBlcTpcIuKJjlwiLGJ1bXBlcTpcIuKJj1wiLENhY3V0ZTpcIsSGXCIsY2FjdXRlOlwixIdcIixjYXBhbmQ6XCLiqYRcIixjYXBicmN1cDpcIuKpiVwiLGNhcGNhcDpcIuKpi1wiLGNhcDpcIuKIqVwiLENhcDpcIuKLklwiLGNhcGN1cDpcIuKph1wiLGNhcGRvdDpcIuKpgFwiLENhcGl0YWxEaWZmZXJlbnRpYWxEOlwi4oWFXCIsY2FwczpcIuKIqe+4gFwiLGNhcmV0Olwi4oGBXCIsY2Fyb246XCLLh1wiLENheWxleXM6XCLihK1cIixjY2FwczpcIuKpjVwiLENjYXJvbjpcIsSMXCIsY2Nhcm9uOlwixI1cIixDY2VkaWw6XCLDh1wiLGNjZWRpbDpcIsOnXCIsQ2NpcmM6XCLEiFwiLGNjaXJjOlwixIlcIixDY29uaW50Olwi4oiwXCIsY2N1cHM6XCLiqYxcIixjY3Vwc3NtOlwi4qmQXCIsQ2RvdDpcIsSKXCIsY2RvdDpcIsSLXCIsY2VkaWw6XCLCuFwiLENlZGlsbGE6XCLCuFwiLGNlbXB0eXY6XCLiprJcIixjZW50OlwiwqJcIixjZW50ZXJkb3Q6XCLCt1wiLENlbnRlckRvdDpcIsK3XCIsY2ZyOlwi8J2UoFwiLENmcjpcIuKErVwiLENIY3k6XCLQp1wiLGNoY3k6XCLRh1wiLGNoZWNrOlwi4pyTXCIsY2hlY2ttYXJrOlwi4pyTXCIsQ2hpOlwizqdcIixjaGk6XCLPh1wiLGNpcmM6XCLLhlwiLGNpcmNlcTpcIuKJl1wiLGNpcmNsZWFycm93bGVmdDpcIuKGulwiLGNpcmNsZWFycm93cmlnaHQ6XCLihrtcIixjaXJjbGVkYXN0Olwi4oqbXCIsY2lyY2xlZGNpcmM6XCLiippcIixjaXJjbGVkZGFzaDpcIuKKnVwiLENpcmNsZURvdDpcIuKKmVwiLGNpcmNsZWRSOlwiwq5cIixjaXJjbGVkUzpcIuKTiFwiLENpcmNsZU1pbnVzOlwi4oqWXCIsQ2lyY2xlUGx1czpcIuKKlVwiLENpcmNsZVRpbWVzOlwi4oqXXCIsY2lyOlwi4peLXCIsY2lyRTpcIuKng1wiLGNpcmU6XCLiiZdcIixjaXJmbmludDpcIuKokFwiLGNpcm1pZDpcIuKrr1wiLGNpcnNjaXI6XCLip4JcIixDbG9ja3dpc2VDb250b3VySW50ZWdyYWw6XCLiiLJcIixDbG9zZUN1cmx5RG91YmxlUXVvdGU6XCLigJ1cIixDbG9zZUN1cmx5UXVvdGU6XCLigJlcIixjbHViczpcIuKZo1wiLGNsdWJzdWl0Olwi4pmjXCIsY29sb246XCI6XCIsQ29sb246XCLiiLdcIixDb2xvbmU6XCLiqbRcIixjb2xvbmU6XCLiiZRcIixjb2xvbmVxOlwi4omUXCIsY29tbWE6XCIsXCIsY29tbWF0OlwiQFwiLGNvbXA6XCLiiIFcIixjb21wZm46XCLiiJhcIixjb21wbGVtZW50Olwi4oiBXCIsY29tcGxleGVzOlwi4oSCXCIsY29uZzpcIuKJhVwiLGNvbmdkb3Q6XCLiqa1cIixDb25ncnVlbnQ6XCLiiaFcIixjb25pbnQ6XCLiiK5cIixDb25pbnQ6XCLiiK9cIixDb250b3VySW50ZWdyYWw6XCLiiK5cIixjb3BmOlwi8J2VlFwiLENvcGY6XCLihIJcIixjb3Byb2Q6XCLiiJBcIixDb3Byb2R1Y3Q6XCLiiJBcIixjb3B5OlwiwqlcIixDT1BZOlwiwqlcIixjb3B5c3I6XCLihJdcIixDb3VudGVyQ2xvY2t3aXNlQ29udG91ckludGVncmFsOlwi4oizXCIsY3JhcnI6XCLihrVcIixjcm9zczpcIuKcl1wiLENyb3NzOlwi4qivXCIsQ3NjcjpcIvCdkp5cIixjc2NyOlwi8J2SuFwiLGNzdWI6XCLiq49cIixjc3ViZTpcIuKrkVwiLGNzdXA6XCLiq5BcIixjc3VwZTpcIuKrklwiLGN0ZG90Olwi4ouvXCIsY3VkYXJybDpcIuKkuFwiLGN1ZGFycnI6XCLipLVcIixjdWVwcjpcIuKLnlwiLGN1ZXNjOlwi4oufXCIsY3VsYXJyOlwi4oa2XCIsY3VsYXJycDpcIuKkvVwiLGN1cGJyY2FwOlwi4qmIXCIsY3VwY2FwOlwi4qmGXCIsQ3VwQ2FwOlwi4omNXCIsY3VwOlwi4oiqXCIsQ3VwOlwi4ouTXCIsY3VwY3VwOlwi4qmKXCIsY3VwZG90Olwi4oqNXCIsY3Vwb3I6XCLiqYVcIixjdXBzOlwi4oiq77iAXCIsY3VyYXJyOlwi4oa3XCIsY3VyYXJybTpcIuKkvFwiLGN1cmx5ZXFwcmVjOlwi4oueXCIsY3VybHllcXN1Y2M6XCLii59cIixjdXJseXZlZTpcIuKLjlwiLGN1cmx5d2VkZ2U6XCLii49cIixjdXJyZW46XCLCpFwiLGN1cnZlYXJyb3dsZWZ0Olwi4oa2XCIsY3VydmVhcnJvd3JpZ2h0Olwi4oa3XCIsY3V2ZWU6XCLii45cIixjdXdlZDpcIuKLj1wiLGN3Y29uaW50Olwi4oiyXCIsY3dpbnQ6XCLiiLFcIixjeWxjdHk6XCLijK1cIixkYWdnZXI6XCLigKBcIixEYWdnZXI6XCLigKFcIixkYWxldGg6XCLihLhcIixkYXJyOlwi4oaTXCIsRGFycjpcIuKGoVwiLGRBcnI6XCLih5NcIixkYXNoOlwi4oCQXCIsRGFzaHY6XCLiq6RcIixkYXNodjpcIuKKo1wiLGRia2Fyb3c6XCLipI9cIixkYmxhYzpcIsudXCIsRGNhcm9uOlwixI5cIixkY2Fyb246XCLEj1wiLERjeTpcItCUXCIsZGN5Olwi0LRcIixkZGFnZ2VyOlwi4oChXCIsZGRhcnI6XCLih4pcIixERDpcIuKFhVwiLGRkOlwi4oWGXCIsRERvdHJhaGQ6XCLipJFcIixkZG90c2VxOlwi4qm3XCIsZGVnOlwiwrBcIixEZWw6XCLiiIdcIixEZWx0YTpcIs6UXCIsZGVsdGE6XCLOtFwiLGRlbXB0eXY6XCLiprFcIixkZmlzaHQ6XCLipb9cIixEZnI6XCLwnZSHXCIsZGZyOlwi8J2UoVwiLGRIYXI6XCLipaVcIixkaGFybDpcIuKHg1wiLGRoYXJyOlwi4oeCXCIsRGlhY3JpdGljYWxBY3V0ZTpcIsK0XCIsRGlhY3JpdGljYWxEb3Q6XCLLmVwiLERpYWNyaXRpY2FsRG91YmxlQWN1dGU6XCLLnVwiLERpYWNyaXRpY2FsR3JhdmU6XCJgXCIsRGlhY3JpdGljYWxUaWxkZTpcIsucXCIsZGlhbTpcIuKLhFwiLGRpYW1vbmQ6XCLii4RcIixEaWFtb25kOlwi4ouEXCIsZGlhbW9uZHN1aXQ6XCLimaZcIixkaWFtczpcIuKZplwiLGRpZTpcIsKoXCIsRGlmZmVyZW50aWFsRDpcIuKFhlwiLGRpZ2FtbWE6XCLPnVwiLGRpc2luOlwi4ouyXCIsZGl2Olwiw7dcIixkaXZpZGU6XCLDt1wiLGRpdmlkZW9udGltZXM6XCLii4dcIixkaXZvbng6XCLii4dcIixESmN5Olwi0IJcIixkamN5Olwi0ZJcIixkbGNvcm46XCLijJ5cIixkbGNyb3A6XCLijI1cIixkb2xsYXI6XCIkXCIsRG9wZjpcIvCdlLtcIixkb3BmOlwi8J2VlVwiLERvdDpcIsKoXCIsZG90Olwiy5lcIixEb3REb3Q6XCLig5xcIixkb3RlcTpcIuKJkFwiLGRvdGVxZG90Olwi4omRXCIsRG90RXF1YWw6XCLiiZBcIixkb3RtaW51czpcIuKIuFwiLGRvdHBsdXM6XCLiiJRcIixkb3RzcXVhcmU6XCLiiqFcIixkb3VibGViYXJ3ZWRnZTpcIuKMhlwiLERvdWJsZUNvbnRvdXJJbnRlZ3JhbDpcIuKIr1wiLERvdWJsZURvdDpcIsKoXCIsRG91YmxlRG93bkFycm93Olwi4oeTXCIsRG91YmxlTGVmdEFycm93Olwi4oeQXCIsRG91YmxlTGVmdFJpZ2h0QXJyb3c6XCLih5RcIixEb3VibGVMZWZ0VGVlOlwi4qukXCIsRG91YmxlTG9uZ0xlZnRBcnJvdzpcIuKfuFwiLERvdWJsZUxvbmdMZWZ0UmlnaHRBcnJvdzpcIuKfulwiLERvdWJsZUxvbmdSaWdodEFycm93Olwi4p+5XCIsRG91YmxlUmlnaHRBcnJvdzpcIuKHklwiLERvdWJsZVJpZ2h0VGVlOlwi4oqoXCIsRG91YmxlVXBBcnJvdzpcIuKHkVwiLERvdWJsZVVwRG93bkFycm93Olwi4oeVXCIsRG91YmxlVmVydGljYWxCYXI6XCLiiKVcIixEb3duQXJyb3dCYXI6XCLipJNcIixkb3duYXJyb3c6XCLihpNcIixEb3duQXJyb3c6XCLihpNcIixEb3duYXJyb3c6XCLih5NcIixEb3duQXJyb3dVcEFycm93Olwi4oe1XCIsRG93bkJyZXZlOlwizJFcIixkb3duZG93bmFycm93czpcIuKHilwiLGRvd25oYXJwb29ubGVmdDpcIuKHg1wiLGRvd25oYXJwb29ucmlnaHQ6XCLih4JcIixEb3duTGVmdFJpZ2h0VmVjdG9yOlwi4qWQXCIsRG93bkxlZnRUZWVWZWN0b3I6XCLipZ5cIixEb3duTGVmdFZlY3RvckJhcjpcIuKlllwiLERvd25MZWZ0VmVjdG9yOlwi4oa9XCIsRG93blJpZ2h0VGVlVmVjdG9yOlwi4qWfXCIsRG93blJpZ2h0VmVjdG9yQmFyOlwi4qWXXCIsRG93blJpZ2h0VmVjdG9yOlwi4oeBXCIsRG93blRlZUFycm93Olwi4oanXCIsRG93blRlZTpcIuKKpFwiLGRyYmthcm93Olwi4qSQXCIsZHJjb3JuOlwi4oyfXCIsZHJjcm9wOlwi4oyMXCIsRHNjcjpcIvCdkp9cIixkc2NyOlwi8J2SuVwiLERTY3k6XCLQhVwiLGRzY3k6XCLRlVwiLGRzb2w6XCLip7ZcIixEc3Ryb2s6XCLEkFwiLGRzdHJvazpcIsSRXCIsZHRkb3Q6XCLii7FcIixkdHJpOlwi4pa/XCIsZHRyaWY6XCLilr5cIixkdWFycjpcIuKHtVwiLGR1aGFyOlwi4qWvXCIsZHdhbmdsZTpcIuKmplwiLERaY3k6XCLQj1wiLGR6Y3k6XCLRn1wiLGR6aWdyYXJyOlwi4p+/XCIsRWFjdXRlOlwiw4lcIixlYWN1dGU6XCLDqVwiLGVhc3RlcjpcIuKprlwiLEVjYXJvbjpcIsSaXCIsZWNhcm9uOlwixJtcIixFY2lyYzpcIsOKXCIsZWNpcmM6XCLDqlwiLGVjaXI6XCLiiZZcIixlY29sb246XCLiiZVcIixFY3k6XCLQrVwiLGVjeTpcItGNXCIsZUREb3Q6XCLiqbdcIixFZG90OlwixJZcIixlZG90OlwixJdcIixlRG90Olwi4omRXCIsZWU6XCLihYdcIixlZkRvdDpcIuKJklwiLEVmcjpcIvCdlIhcIixlZnI6XCLwnZSiXCIsZWc6XCLiqppcIixFZ3JhdmU6XCLDiFwiLGVncmF2ZTpcIsOoXCIsZWdzOlwi4qqWXCIsZWdzZG90Olwi4qqYXCIsZWw6XCLiqplcIixFbGVtZW50Olwi4oiIXCIsZWxpbnRlcnM6XCLij6dcIixlbGw6XCLihJNcIixlbHM6XCLiqpVcIixlbHNkb3Q6XCLiqpdcIixFbWFjcjpcIsSSXCIsZW1hY3I6XCLEk1wiLGVtcHR5Olwi4oiFXCIsZW1wdHlzZXQ6XCLiiIVcIixFbXB0eVNtYWxsU3F1YXJlOlwi4pe7XCIsZW1wdHl2Olwi4oiFXCIsRW1wdHlWZXJ5U21hbGxTcXVhcmU6XCLilqtcIixlbXNwMTM6XCLigIRcIixlbXNwMTQ6XCLigIVcIixlbXNwOlwi4oCDXCIsRU5HOlwixYpcIixlbmc6XCLFi1wiLGVuc3A6XCLigIJcIixFb2dvbjpcIsSYXCIsZW9nb246XCLEmVwiLEVvcGY6XCLwnZS8XCIsZW9wZjpcIvCdlZZcIixlcGFyOlwi4ouVXCIsZXBhcnNsOlwi4qejXCIsZXBsdXM6XCLiqbFcIixlcHNpOlwizrVcIixFcHNpbG9uOlwizpVcIixlcHNpbG9uOlwizrVcIixlcHNpdjpcIs+1XCIsZXFjaXJjOlwi4omWXCIsZXFjb2xvbjpcIuKJlVwiLGVxc2ltOlwi4omCXCIsZXFzbGFudGd0cjpcIuKqllwiLGVxc2xhbnRsZXNzOlwi4qqVXCIsRXF1YWw6XCLiqbVcIixlcXVhbHM6XCI9XCIsRXF1YWxUaWxkZTpcIuKJglwiLGVxdWVzdDpcIuKJn1wiLEVxdWlsaWJyaXVtOlwi4oeMXCIsZXF1aXY6XCLiiaFcIixlcXVpdkREOlwi4qm4XCIsZXF2cGFyc2w6XCLip6VcIixlcmFycjpcIuKlsVwiLGVyRG90Olwi4omTXCIsZXNjcjpcIuKEr1wiLEVzY3I6XCLihLBcIixlc2RvdDpcIuKJkFwiLEVzaW06XCLiqbNcIixlc2ltOlwi4omCXCIsRXRhOlwizpdcIixldGE6XCLOt1wiLEVUSDpcIsOQXCIsZXRoOlwiw7BcIixFdW1sOlwiw4tcIixldW1sOlwiw6tcIixldXJvOlwi4oKsXCIsZXhjbDpcIiFcIixleGlzdDpcIuKIg1wiLEV4aXN0czpcIuKIg1wiLGV4cGVjdGF0aW9uOlwi4oSwXCIsZXhwb25lbnRpYWxlOlwi4oWHXCIsRXhwb25lbnRpYWxFOlwi4oWHXCIsZmFsbGluZ2RvdHNlcTpcIuKJklwiLEZjeTpcItCkXCIsZmN5Olwi0YRcIixmZW1hbGU6XCLimYBcIixmZmlsaWc6XCLvrINcIixmZmxpZzpcIu+sgFwiLGZmbGxpZzpcIu+shFwiLEZmcjpcIvCdlIlcIixmZnI6XCLwnZSjXCIsZmlsaWc6XCLvrIFcIixGaWxsZWRTbWFsbFNxdWFyZTpcIuKXvFwiLEZpbGxlZFZlcnlTbWFsbFNxdWFyZTpcIuKWqlwiLGZqbGlnOlwiZmpcIixmbGF0Olwi4pmtXCIsZmxsaWc6XCLvrIJcIixmbHRuczpcIuKWsVwiLGZub2Y6XCLGklwiLEZvcGY6XCLwnZS9XCIsZm9wZjpcIvCdlZdcIixmb3JhbGw6XCLiiIBcIixGb3JBbGw6XCLiiIBcIixmb3JrOlwi4ouUXCIsZm9ya3Y6XCLiq5lcIixGb3VyaWVydHJmOlwi4oSxXCIsZnBhcnRpbnQ6XCLiqI1cIixmcmFjMTI6XCLCvVwiLGZyYWMxMzpcIuKFk1wiLGZyYWMxNDpcIsK8XCIsZnJhYzE1Olwi4oWVXCIsZnJhYzE2Olwi4oWZXCIsZnJhYzE4Olwi4oWbXCIsZnJhYzIzOlwi4oWUXCIsZnJhYzI1Olwi4oWWXCIsZnJhYzM0Olwiwr5cIixmcmFjMzU6XCLihZdcIixmcmFjMzg6XCLihZxcIixmcmFjNDU6XCLihZhcIixmcmFjNTY6XCLihZpcIixmcmFjNTg6XCLihZ1cIixmcmFjNzg6XCLihZ5cIixmcmFzbDpcIuKBhFwiLGZyb3duOlwi4oyiXCIsZnNjcjpcIvCdkrtcIixGc2NyOlwi4oSxXCIsZ2FjdXRlOlwix7VcIixHYW1tYTpcIs6TXCIsZ2FtbWE6XCLOs1wiLEdhbW1hZDpcIs+cXCIsZ2FtbWFkOlwiz51cIixnYXA6XCLiqoZcIixHYnJldmU6XCLEnlwiLGdicmV2ZTpcIsSfXCIsR2NlZGlsOlwixKJcIixHY2lyYzpcIsScXCIsZ2NpcmM6XCLEnVwiLEdjeTpcItCTXCIsZ2N5Olwi0LNcIixHZG90OlwixKBcIixnZG90OlwixKFcIixnZTpcIuKJpVwiLGdFOlwi4omnXCIsZ0VsOlwi4qqMXCIsZ2VsOlwi4oubXCIsZ2VxOlwi4omlXCIsZ2VxcTpcIuKJp1wiLGdlcXNsYW50Olwi4qm+XCIsZ2VzY2M6XCLiqqlcIixnZXM6XCLiqb5cIixnZXNkb3Q6XCLiqoBcIixnZXNkb3RvOlwi4qqCXCIsZ2VzZG90b2w6XCLiqoRcIixnZXNsOlwi4oub77iAXCIsZ2VzbGVzOlwi4qqUXCIsR2ZyOlwi8J2UilwiLGdmcjpcIvCdlKRcIixnZzpcIuKJq1wiLEdnOlwi4ouZXCIsZ2dnOlwi4ouZXCIsZ2ltZWw6XCLihLdcIixHSmN5Olwi0INcIixnamN5Olwi0ZNcIixnbGE6XCLiqqVcIixnbDpcIuKJt1wiLGdsRTpcIuKqklwiLGdsajpcIuKqpFwiLGduYXA6XCLiqopcIixnbmFwcHJveDpcIuKqilwiLGduZTpcIuKqiFwiLGduRTpcIuKJqVwiLGduZXE6XCLiqohcIixnbmVxcTpcIuKJqVwiLGduc2ltOlwi4ounXCIsR29wZjpcIvCdlL5cIixnb3BmOlwi8J2VmFwiLGdyYXZlOlwiYFwiLEdyZWF0ZXJFcXVhbDpcIuKJpVwiLEdyZWF0ZXJFcXVhbExlc3M6XCLii5tcIixHcmVhdGVyRnVsbEVxdWFsOlwi4omnXCIsR3JlYXRlckdyZWF0ZXI6XCLiqqJcIixHcmVhdGVyTGVzczpcIuKJt1wiLEdyZWF0ZXJTbGFudEVxdWFsOlwi4qm+XCIsR3JlYXRlclRpbGRlOlwi4omzXCIsR3NjcjpcIvCdkqJcIixnc2NyOlwi4oSKXCIsZ3NpbTpcIuKJs1wiLGdzaW1lOlwi4qqOXCIsZ3NpbWw6XCLiqpBcIixndGNjOlwi4qqnXCIsZ3RjaXI6XCLiqbpcIixndDpcIj5cIixHVDpcIj5cIixHdDpcIuKJq1wiLGd0ZG90Olwi4ouXXCIsZ3RsUGFyOlwi4qaVXCIsZ3RxdWVzdDpcIuKpvFwiLGd0cmFwcHJveDpcIuKqhlwiLGd0cmFycjpcIuKluFwiLGd0cmRvdDpcIuKLl1wiLGd0cmVxbGVzczpcIuKLm1wiLGd0cmVxcWxlc3M6XCLiqoxcIixndHJsZXNzOlwi4om3XCIsZ3Ryc2ltOlwi4omzXCIsZ3ZlcnRuZXFxOlwi4omp77iAXCIsZ3ZuRTpcIuKJqe+4gFwiLEhhY2VrOlwiy4dcIixoYWlyc3A6XCLigIpcIixoYWxmOlwiwr1cIixoYW1pbHQ6XCLihItcIixIQVJEY3k6XCLQqlwiLGhhcmRjeTpcItGKXCIsaGFycmNpcjpcIuKliFwiLGhhcnI6XCLihpRcIixoQXJyOlwi4oeUXCIsaGFycnc6XCLihq1cIixIYXQ6XCJeXCIsaGJhcjpcIuKEj1wiLEhjaXJjOlwixKRcIixoY2lyYzpcIsSlXCIsaGVhcnRzOlwi4pmlXCIsaGVhcnRzdWl0Olwi4pmlXCIsaGVsbGlwOlwi4oCmXCIsaGVyY29uOlwi4oq5XCIsaGZyOlwi8J2UpVwiLEhmcjpcIuKEjFwiLEhpbGJlcnRTcGFjZTpcIuKEi1wiLGhrc2Vhcm93Olwi4qSlXCIsaGtzd2Fyb3c6XCLipKZcIixob2FycjpcIuKHv1wiLGhvbXRodDpcIuKIu1wiLGhvb2tsZWZ0YXJyb3c6XCLihqlcIixob29rcmlnaHRhcnJvdzpcIuKGqlwiLGhvcGY6XCLwnZWZXCIsSG9wZjpcIuKEjVwiLGhvcmJhcjpcIuKAlVwiLEhvcml6b250YWxMaW5lOlwi4pSAXCIsaHNjcjpcIvCdkr1cIixIc2NyOlwi4oSLXCIsaHNsYXNoOlwi4oSPXCIsSHN0cm9rOlwixKZcIixoc3Ryb2s6XCLEp1wiLEh1bXBEb3duSHVtcDpcIuKJjlwiLEh1bXBFcXVhbDpcIuKJj1wiLGh5YnVsbDpcIuKBg1wiLGh5cGhlbjpcIuKAkFwiLElhY3V0ZTpcIsONXCIsaWFjdXRlOlwiw61cIixpYzpcIuKBo1wiLEljaXJjOlwiw45cIixpY2lyYzpcIsOuXCIsSWN5Olwi0JhcIixpY3k6XCLQuFwiLElkb3Q6XCLEsFwiLElFY3k6XCLQlVwiLGllY3k6XCLQtVwiLGlleGNsOlwiwqFcIixpZmY6XCLih5RcIixpZnI6XCLwnZSmXCIsSWZyOlwi4oSRXCIsSWdyYXZlOlwiw4xcIixpZ3JhdmU6XCLDrFwiLGlpOlwi4oWIXCIsaWlpaW50Olwi4qiMXCIsaWlpbnQ6XCLiiK1cIixpaW5maW46XCLip5xcIixpaW90YTpcIuKEqVwiLElKbGlnOlwixLJcIixpamxpZzpcIsSzXCIsSW1hY3I6XCLEqlwiLGltYWNyOlwixKtcIixpbWFnZTpcIuKEkVwiLEltYWdpbmFyeUk6XCLihYhcIixpbWFnbGluZTpcIuKEkFwiLGltYWdwYXJ0Olwi4oSRXCIsaW1hdGg6XCLEsVwiLEltOlwi4oSRXCIsaW1vZjpcIuKKt1wiLGltcGVkOlwixrVcIixJbXBsaWVzOlwi4oeSXCIsaW5jYXJlOlwi4oSFXCIsaW46XCLiiIhcIixpbmZpbjpcIuKInlwiLGluZmludGllOlwi4qedXCIsaW5vZG90OlwixLFcIixpbnRjYWw6XCLiirpcIixpbnQ6XCLiiKtcIixJbnQ6XCLiiKxcIixpbnRlZ2VyczpcIuKEpFwiLEludGVncmFsOlwi4oirXCIsaW50ZXJjYWw6XCLiirpcIixJbnRlcnNlY3Rpb246XCLii4JcIixpbnRsYXJoazpcIuKol1wiLGludHByb2Q6XCLiqLxcIixJbnZpc2libGVDb21tYTpcIuKBo1wiLEludmlzaWJsZVRpbWVzOlwi4oGiXCIsSU9jeTpcItCBXCIsaW9jeTpcItGRXCIsSW9nb246XCLErlwiLGlvZ29uOlwixK9cIixJb3BmOlwi8J2VgFwiLGlvcGY6XCLwnZWaXCIsSW90YTpcIs6ZXCIsaW90YTpcIs65XCIsaXByb2Q6XCLiqLxcIixpcXVlc3Q6XCLCv1wiLGlzY3I6XCLwnZK+XCIsSXNjcjpcIuKEkFwiLGlzaW46XCLiiIhcIixpc2luZG90Olwi4ou1XCIsaXNpbkU6XCLii7lcIixpc2luczpcIuKLtFwiLGlzaW5zdjpcIuKLs1wiLGlzaW52Olwi4oiIXCIsaXQ6XCLigaJcIixJdGlsZGU6XCLEqFwiLGl0aWxkZTpcIsSpXCIsSXVrY3k6XCLQhlwiLGl1a2N5Olwi0ZZcIixJdW1sOlwiw49cIixpdW1sOlwiw69cIixKY2lyYzpcIsS0XCIsamNpcmM6XCLEtVwiLEpjeTpcItCZXCIsamN5Olwi0LlcIixKZnI6XCLwnZSNXCIsamZyOlwi8J2Up1wiLGptYXRoOlwiyLdcIixKb3BmOlwi8J2VgVwiLGpvcGY6XCLwnZWbXCIsSnNjcjpcIvCdkqVcIixqc2NyOlwi8J2Sv1wiLEpzZXJjeTpcItCIXCIsanNlcmN5Olwi0ZhcIixKdWtjeTpcItCEXCIsanVrY3k6XCLRlFwiLEthcHBhOlwizppcIixrYXBwYTpcIs66XCIsa2FwcGF2Olwiz7BcIixLY2VkaWw6XCLEtlwiLGtjZWRpbDpcIsS3XCIsS2N5Olwi0JpcIixrY3k6XCLQulwiLEtmcjpcIvCdlI5cIixrZnI6XCLwnZSoXCIsa2dyZWVuOlwixLhcIixLSGN5Olwi0KVcIixraGN5Olwi0YVcIixLSmN5Olwi0IxcIixramN5Olwi0ZxcIixLb3BmOlwi8J2VglwiLGtvcGY6XCLwnZWcXCIsS3NjcjpcIvCdkqZcIixrc2NyOlwi8J2TgFwiLGxBYXJyOlwi4oeaXCIsTGFjdXRlOlwixLlcIixsYWN1dGU6XCLEulwiLGxhZW1wdHl2Olwi4qa0XCIsbGFncmFuOlwi4oSSXCIsTGFtYmRhOlwizptcIixsYW1iZGE6XCLOu1wiLGxhbmc6XCLin6hcIixMYW5nOlwi4p+qXCIsbGFuZ2Q6XCLippFcIixsYW5nbGU6XCLin6hcIixsYXA6XCLiqoVcIixMYXBsYWNldHJmOlwi4oSSXCIsbGFxdW86XCLCq1wiLGxhcnJiOlwi4oekXCIsbGFycmJmczpcIuKkn1wiLGxhcnI6XCLihpBcIixMYXJyOlwi4oaeXCIsbEFycjpcIuKHkFwiLGxhcnJmczpcIuKknVwiLGxhcnJoazpcIuKGqVwiLGxhcnJscDpcIuKGq1wiLGxhcnJwbDpcIuKkuVwiLGxhcnJzaW06XCLipbNcIixsYXJydGw6XCLihqJcIixsYXRhaWw6XCLipJlcIixsQXRhaWw6XCLipJtcIixsYXQ6XCLiqqtcIixsYXRlOlwi4qqtXCIsbGF0ZXM6XCLiqq3vuIBcIixsYmFycjpcIuKkjFwiLGxCYXJyOlwi4qSOXCIsbGJicms6XCLinbJcIixsYnJhY2U6XCJ7XCIsbGJyYWNrOlwiW1wiLGxicmtlOlwi4qaLXCIsbGJya3NsZDpcIuKmj1wiLGxicmtzbHU6XCLipo1cIixMY2Fyb246XCLEvVwiLGxjYXJvbjpcIsS+XCIsTGNlZGlsOlwixLtcIixsY2VkaWw6XCLEvFwiLGxjZWlsOlwi4oyIXCIsbGN1YjpcIntcIixMY3k6XCLQm1wiLGxjeTpcItC7XCIsbGRjYTpcIuKktlwiLGxkcXVvOlwi4oCcXCIsbGRxdW9yOlwi4oCeXCIsbGRyZGhhcjpcIuKlp1wiLGxkcnVzaGFyOlwi4qWLXCIsbGRzaDpcIuKGslwiLGxlOlwi4omkXCIsbEU6XCLiiaZcIixMZWZ0QW5nbGVCcmFja2V0Olwi4p+oXCIsTGVmdEFycm93QmFyOlwi4oekXCIsbGVmdGFycm93Olwi4oaQXCIsTGVmdEFycm93Olwi4oaQXCIsTGVmdGFycm93Olwi4oeQXCIsTGVmdEFycm93UmlnaHRBcnJvdzpcIuKHhlwiLGxlZnRhcnJvd3RhaWw6XCLihqJcIixMZWZ0Q2VpbGluZzpcIuKMiFwiLExlZnREb3VibGVCcmFja2V0Olwi4p+mXCIsTGVmdERvd25UZWVWZWN0b3I6XCLipaFcIixMZWZ0RG93blZlY3RvckJhcjpcIuKlmVwiLExlZnREb3duVmVjdG9yOlwi4oeDXCIsTGVmdEZsb29yOlwi4oyKXCIsbGVmdGhhcnBvb25kb3duOlwi4oa9XCIsbGVmdGhhcnBvb251cDpcIuKGvFwiLGxlZnRsZWZ0YXJyb3dzOlwi4oeHXCIsbGVmdHJpZ2h0YXJyb3c6XCLihpRcIixMZWZ0UmlnaHRBcnJvdzpcIuKGlFwiLExlZnRyaWdodGFycm93Olwi4oeUXCIsbGVmdHJpZ2h0YXJyb3dzOlwi4oeGXCIsbGVmdHJpZ2h0aGFycG9vbnM6XCLih4tcIixsZWZ0cmlnaHRzcXVpZ2Fycm93Olwi4oatXCIsTGVmdFJpZ2h0VmVjdG9yOlwi4qWOXCIsTGVmdFRlZUFycm93Olwi4oakXCIsTGVmdFRlZTpcIuKKo1wiLExlZnRUZWVWZWN0b3I6XCLipZpcIixsZWZ0dGhyZWV0aW1lczpcIuKLi1wiLExlZnRUcmlhbmdsZUJhcjpcIuKnj1wiLExlZnRUcmlhbmdsZTpcIuKKslwiLExlZnRUcmlhbmdsZUVxdWFsOlwi4oq0XCIsTGVmdFVwRG93blZlY3RvcjpcIuKlkVwiLExlZnRVcFRlZVZlY3RvcjpcIuKloFwiLExlZnRVcFZlY3RvckJhcjpcIuKlmFwiLExlZnRVcFZlY3RvcjpcIuKGv1wiLExlZnRWZWN0b3JCYXI6XCLipZJcIixMZWZ0VmVjdG9yOlwi4oa8XCIsbEVnOlwi4qqLXCIsbGVnOlwi4ouaXCIsbGVxOlwi4omkXCIsbGVxcTpcIuKJplwiLGxlcXNsYW50Olwi4qm9XCIsbGVzY2M6XCLiqqhcIixsZXM6XCLiqb1cIixsZXNkb3Q6XCLiqb9cIixsZXNkb3RvOlwi4qqBXCIsbGVzZG90b3I6XCLiqoNcIixsZXNnOlwi4oua77iAXCIsbGVzZ2VzOlwi4qqTXCIsbGVzc2FwcHJveDpcIuKqhVwiLGxlc3Nkb3Q6XCLii5ZcIixsZXNzZXFndHI6XCLii5pcIixsZXNzZXFxZ3RyOlwi4qqLXCIsTGVzc0VxdWFsR3JlYXRlcjpcIuKLmlwiLExlc3NGdWxsRXF1YWw6XCLiiaZcIixMZXNzR3JlYXRlcjpcIuKJtlwiLGxlc3NndHI6XCLiibZcIixMZXNzTGVzczpcIuKqoVwiLGxlc3NzaW06XCLiibJcIixMZXNzU2xhbnRFcXVhbDpcIuKpvVwiLExlc3NUaWxkZTpcIuKJslwiLGxmaXNodDpcIuKlvFwiLGxmbG9vcjpcIuKMilwiLExmcjpcIvCdlI9cIixsZnI6XCLwnZSpXCIsbGc6XCLiibZcIixsZ0U6XCLiqpFcIixsSGFyOlwi4qWiXCIsbGhhcmQ6XCLihr1cIixsaGFydTpcIuKGvFwiLGxoYXJ1bDpcIuKlqlwiLGxoYmxrOlwi4paEXCIsTEpjeTpcItCJXCIsbGpjeTpcItGZXCIsbGxhcnI6XCLih4dcIixsbDpcIuKJqlwiLExsOlwi4ouYXCIsbGxjb3JuZXI6XCLijJ5cIixMbGVmdGFycm93Olwi4oeaXCIsbGxoYXJkOlwi4qWrXCIsbGx0cmk6XCLil7pcIixMbWlkb3Q6XCLEv1wiLGxtaWRvdDpcIsWAXCIsbG1vdXN0YWNoZTpcIuKOsFwiLGxtb3VzdDpcIuKOsFwiLGxuYXA6XCLiqolcIixsbmFwcHJveDpcIuKqiVwiLGxuZTpcIuKqh1wiLGxuRTpcIuKJqFwiLGxuZXE6XCLiqodcIixsbmVxcTpcIuKJqFwiLGxuc2ltOlwi4oumXCIsbG9hbmc6XCLin6xcIixsb2FycjpcIuKHvVwiLGxvYnJrOlwi4p+mXCIsbG9uZ2xlZnRhcnJvdzpcIuKftVwiLExvbmdMZWZ0QXJyb3c6XCLin7VcIixMb25nbGVmdGFycm93Olwi4p+4XCIsbG9uZ2xlZnRyaWdodGFycm93Olwi4p+3XCIsTG9uZ0xlZnRSaWdodEFycm93Olwi4p+3XCIsTG9uZ2xlZnRyaWdodGFycm93Olwi4p+6XCIsbG9uZ21hcHN0bzpcIuKfvFwiLGxvbmdyaWdodGFycm93Olwi4p+2XCIsTG9uZ1JpZ2h0QXJyb3c6XCLin7ZcIixMb25ncmlnaHRhcnJvdzpcIuKfuVwiLGxvb3BhcnJvd2xlZnQ6XCLihqtcIixsb29wYXJyb3dyaWdodDpcIuKGrFwiLGxvcGFyOlwi4qaFXCIsTG9wZjpcIvCdlYNcIixsb3BmOlwi8J2VnVwiLGxvcGx1czpcIuKorVwiLGxvdGltZXM6XCLiqLRcIixsb3dhc3Q6XCLiiJdcIixsb3diYXI6XCJfXCIsTG93ZXJMZWZ0QXJyb3c6XCLihplcIixMb3dlclJpZ2h0QXJyb3c6XCLihphcIixsb3o6XCLil4pcIixsb3plbmdlOlwi4peKXCIsbG96ZjpcIuKnq1wiLGxwYXI6XCIoXCIsbHBhcmx0Olwi4qaTXCIsbHJhcnI6XCLih4ZcIixscmNvcm5lcjpcIuKMn1wiLGxyaGFyOlwi4oeLXCIsbHJoYXJkOlwi4qWtXCIsbHJtOlwi4oCOXCIsbHJ0cmk6XCLiir9cIixsc2FxdW86XCLigLlcIixsc2NyOlwi8J2TgVwiLExzY3I6XCLihJJcIixsc2g6XCLihrBcIixMc2g6XCLihrBcIixsc2ltOlwi4omyXCIsbHNpbWU6XCLiqo1cIixsc2ltZzpcIuKqj1wiLGxzcWI6XCJbXCIsbHNxdW86XCLigJhcIixsc3F1b3I6XCLigJpcIixMc3Ryb2s6XCLFgVwiLGxzdHJvazpcIsWCXCIsbHRjYzpcIuKqplwiLGx0Y2lyOlwi4qm5XCIsbHQ6XCI8XCIsTFQ6XCI8XCIsTHQ6XCLiiapcIixsdGRvdDpcIuKLllwiLGx0aHJlZTpcIuKLi1wiLGx0aW1lczpcIuKLiVwiLGx0bGFycjpcIuKltlwiLGx0cXVlc3Q6XCLiqbtcIixsdHJpOlwi4peDXCIsbHRyaWU6XCLiirRcIixsdHJpZjpcIuKXglwiLGx0clBhcjpcIuKmllwiLGx1cmRzaGFyOlwi4qWKXCIsbHVydWhhcjpcIuKlplwiLGx2ZXJ0bmVxcTpcIuKJqO+4gFwiLGx2bkU6XCLiiajvuIBcIixtYWNyOlwiwq9cIixtYWxlOlwi4pmCXCIsbWFsdDpcIuKcoFwiLG1hbHRlc2U6XCLinKBcIixNYXA6XCLipIVcIixtYXA6XCLihqZcIixtYXBzdG86XCLihqZcIixtYXBzdG9kb3duOlwi4oanXCIsbWFwc3RvbGVmdDpcIuKGpFwiLG1hcHN0b3VwOlwi4oalXCIsbWFya2VyOlwi4pauXCIsbWNvbW1hOlwi4qipXCIsTWN5Olwi0JxcIixtY3k6XCLQvFwiLG1kYXNoOlwi4oCUXCIsbUREb3Q6XCLiiLpcIixtZWFzdXJlZGFuZ2xlOlwi4oihXCIsTWVkaXVtU3BhY2U6XCLigZ9cIixNZWxsaW50cmY6XCLihLNcIixNZnI6XCLwnZSQXCIsbWZyOlwi8J2UqlwiLG1obzpcIuKEp1wiLG1pY3JvOlwiwrVcIixtaWRhc3Q6XCIqXCIsbWlkY2lyOlwi4quwXCIsbWlkOlwi4oijXCIsbWlkZG90OlwiwrdcIixtaW51c2I6XCLiip9cIixtaW51czpcIuKIklwiLG1pbnVzZDpcIuKIuFwiLG1pbnVzZHU6XCLiqKpcIixNaW51c1BsdXM6XCLiiJNcIixtbGNwOlwi4qubXCIsbWxkcjpcIuKAplwiLG1ucGx1czpcIuKIk1wiLG1vZGVsczpcIuKKp1wiLE1vcGY6XCLwnZWEXCIsbW9wZjpcIvCdlZ5cIixtcDpcIuKIk1wiLG1zY3I6XCLwnZOCXCIsTXNjcjpcIuKEs1wiLG1zdHBvczpcIuKIvlwiLE11OlwizpxcIixtdTpcIs68XCIsbXVsdGltYXA6XCLiirhcIixtdW1hcDpcIuKKuFwiLG5hYmxhOlwi4oiHXCIsTmFjdXRlOlwixYNcIixuYWN1dGU6XCLFhFwiLG5hbmc6XCLiiKDig5JcIixuYXA6XCLiiYlcIixuYXBFOlwi4qmwzLhcIixuYXBpZDpcIuKJi8y4XCIsbmFwb3M6XCLFiVwiLG5hcHByb3g6XCLiiYlcIixuYXR1cmFsOlwi4pmuXCIsbmF0dXJhbHM6XCLihJVcIixuYXR1cjpcIuKZrlwiLG5ic3A6XCLCoFwiLG5idW1wOlwi4omOzLhcIixuYnVtcGU6XCLiiY/MuFwiLG5jYXA6XCLiqYNcIixOY2Fyb246XCLFh1wiLG5jYXJvbjpcIsWIXCIsTmNlZGlsOlwixYVcIixuY2VkaWw6XCLFhlwiLG5jb25nOlwi4omHXCIsbmNvbmdkb3Q6XCLiqa3MuFwiLG5jdXA6XCLiqYJcIixOY3k6XCLQnVwiLG5jeTpcItC9XCIsbmRhc2g6XCLigJNcIixuZWFyaGs6XCLipKRcIixuZWFycjpcIuKGl1wiLG5lQXJyOlwi4oeXXCIsbmVhcnJvdzpcIuKGl1wiLG5lOlwi4omgXCIsbmVkb3Q6XCLiiZDMuFwiLE5lZ2F0aXZlTWVkaXVtU3BhY2U6XCLigItcIixOZWdhdGl2ZVRoaWNrU3BhY2U6XCLigItcIixOZWdhdGl2ZVRoaW5TcGFjZTpcIuKAi1wiLE5lZ2F0aXZlVmVyeVRoaW5TcGFjZTpcIuKAi1wiLG5lcXVpdjpcIuKJolwiLG5lc2VhcjpcIuKkqFwiLG5lc2ltOlwi4omCzLhcIixOZXN0ZWRHcmVhdGVyR3JlYXRlcjpcIuKJq1wiLE5lc3RlZExlc3NMZXNzOlwi4omqXCIsTmV3TGluZTpcIlxcblwiLG5leGlzdDpcIuKIhFwiLG5leGlzdHM6XCLiiIRcIixOZnI6XCLwnZSRXCIsbmZyOlwi8J2Uq1wiLG5nRTpcIuKJp8y4XCIsbmdlOlwi4omxXCIsbmdlcTpcIuKJsVwiLG5nZXFxOlwi4omnzLhcIixuZ2Vxc2xhbnQ6XCLiqb7MuFwiLG5nZXM6XCLiqb7MuFwiLG5HZzpcIuKLmcy4XCIsbmdzaW06XCLiibVcIixuR3Q6XCLiiavig5JcIixuZ3Q6XCLiia9cIixuZ3RyOlwi4omvXCIsbkd0djpcIuKJq8y4XCIsbmhhcnI6XCLihq5cIixuaEFycjpcIuKHjlwiLG5ocGFyOlwi4quyXCIsbmk6XCLiiItcIixuaXM6XCLii7xcIixuaXNkOlwi4ou6XCIsbml2Olwi4oiLXCIsTkpjeTpcItCKXCIsbmpjeTpcItGaXCIsbmxhcnI6XCLihppcIixubEFycjpcIuKHjVwiLG5sZHI6XCLigKVcIixubEU6XCLiiabMuFwiLG5sZTpcIuKJsFwiLG5sZWZ0YXJyb3c6XCLihppcIixuTGVmdGFycm93Olwi4oeNXCIsbmxlZnRyaWdodGFycm93Olwi4oauXCIsbkxlZnRyaWdodGFycm93Olwi4oeOXCIsbmxlcTpcIuKJsFwiLG5sZXFxOlwi4ommzLhcIixubGVxc2xhbnQ6XCLiqb3MuFwiLG5sZXM6XCLiqb3MuFwiLG5sZXNzOlwi4omuXCIsbkxsOlwi4ouYzLhcIixubHNpbTpcIuKJtFwiLG5MdDpcIuKJquKDklwiLG5sdDpcIuKJrlwiLG5sdHJpOlwi4ouqXCIsbmx0cmllOlwi4ousXCIsbkx0djpcIuKJqsy4XCIsbm1pZDpcIuKIpFwiLE5vQnJlYWs6XCLigaBcIixOb25CcmVha2luZ1NwYWNlOlwiwqBcIixub3BmOlwi8J2Vn1wiLE5vcGY6XCLihJVcIixOb3Q6XCLiq6xcIixub3Q6XCLCrFwiLE5vdENvbmdydWVudDpcIuKJolwiLE5vdEN1cENhcDpcIuKJrVwiLE5vdERvdWJsZVZlcnRpY2FsQmFyOlwi4oimXCIsTm90RWxlbWVudDpcIuKIiVwiLE5vdEVxdWFsOlwi4omgXCIsTm90RXF1YWxUaWxkZTpcIuKJgsy4XCIsTm90RXhpc3RzOlwi4oiEXCIsTm90R3JlYXRlcjpcIuKJr1wiLE5vdEdyZWF0ZXJFcXVhbDpcIuKJsVwiLE5vdEdyZWF0ZXJGdWxsRXF1YWw6XCLiiafMuFwiLE5vdEdyZWF0ZXJHcmVhdGVyOlwi4omrzLhcIixOb3RHcmVhdGVyTGVzczpcIuKJuVwiLE5vdEdyZWF0ZXJTbGFudEVxdWFsOlwi4qm+zLhcIixOb3RHcmVhdGVyVGlsZGU6XCLiibVcIixOb3RIdW1wRG93bkh1bXA6XCLiiY7MuFwiLE5vdEh1bXBFcXVhbDpcIuKJj8y4XCIsbm90aW46XCLiiIlcIixub3RpbmRvdDpcIuKLtcy4XCIsbm90aW5FOlwi4ou5zLhcIixub3RpbnZhOlwi4oiJXCIsbm90aW52YjpcIuKLt1wiLG5vdGludmM6XCLii7ZcIixOb3RMZWZ0VHJpYW5nbGVCYXI6XCLip4/MuFwiLE5vdExlZnRUcmlhbmdsZTpcIuKLqlwiLE5vdExlZnRUcmlhbmdsZUVxdWFsOlwi4ousXCIsTm90TGVzczpcIuKJrlwiLE5vdExlc3NFcXVhbDpcIuKJsFwiLE5vdExlc3NHcmVhdGVyOlwi4om4XCIsTm90TGVzc0xlc3M6XCLiiarMuFwiLE5vdExlc3NTbGFudEVxdWFsOlwi4qm9zLhcIixOb3RMZXNzVGlsZGU6XCLiibRcIixOb3ROZXN0ZWRHcmVhdGVyR3JlYXRlcjpcIuKqosy4XCIsTm90TmVzdGVkTGVzc0xlc3M6XCLiqqHMuFwiLG5vdG5pOlwi4oiMXCIsbm90bml2YTpcIuKIjFwiLG5vdG5pdmI6XCLii75cIixub3RuaXZjOlwi4ou9XCIsTm90UHJlY2VkZXM6XCLiioBcIixOb3RQcmVjZWRlc0VxdWFsOlwi4qqvzLhcIixOb3RQcmVjZWRlc1NsYW50RXF1YWw6XCLii6BcIixOb3RSZXZlcnNlRWxlbWVudDpcIuKIjFwiLE5vdFJpZ2h0VHJpYW5nbGVCYXI6XCLip5DMuFwiLE5vdFJpZ2h0VHJpYW5nbGU6XCLii6tcIixOb3RSaWdodFRyaWFuZ2xlRXF1YWw6XCLii61cIixOb3RTcXVhcmVTdWJzZXQ6XCLiio/MuFwiLE5vdFNxdWFyZVN1YnNldEVxdWFsOlwi4ouiXCIsTm90U3F1YXJlU3VwZXJzZXQ6XCLiipDMuFwiLE5vdFNxdWFyZVN1cGVyc2V0RXF1YWw6XCLii6NcIixOb3RTdWJzZXQ6XCLiioLig5JcIixOb3RTdWJzZXRFcXVhbDpcIuKKiFwiLE5vdFN1Y2NlZWRzOlwi4oqBXCIsTm90U3VjY2VlZHNFcXVhbDpcIuKqsMy4XCIsTm90U3VjY2VlZHNTbGFudEVxdWFsOlwi4ouhXCIsTm90U3VjY2VlZHNUaWxkZTpcIuKJv8y4XCIsTm90U3VwZXJzZXQ6XCLiioPig5JcIixOb3RTdXBlcnNldEVxdWFsOlwi4oqJXCIsTm90VGlsZGU6XCLiiYFcIixOb3RUaWxkZUVxdWFsOlwi4omEXCIsTm90VGlsZGVGdWxsRXF1YWw6XCLiiYdcIixOb3RUaWxkZVRpbGRlOlwi4omJXCIsTm90VmVydGljYWxCYXI6XCLiiKRcIixucGFyYWxsZWw6XCLiiKZcIixucGFyOlwi4oimXCIsbnBhcnNsOlwi4qu94oOlXCIsbnBhcnQ6XCLiiILMuFwiLG5wb2xpbnQ6XCLiqJRcIixucHI6XCLiioBcIixucHJjdWU6XCLii6BcIixucHJlYzpcIuKKgFwiLG5wcmVjZXE6XCLiqq/MuFwiLG5wcmU6XCLiqq/MuFwiLG5yYXJyYzpcIuKks8y4XCIsbnJhcnI6XCLihptcIixuckFycjpcIuKHj1wiLG5yYXJydzpcIuKGncy4XCIsbnJpZ2h0YXJyb3c6XCLihptcIixuUmlnaHRhcnJvdzpcIuKHj1wiLG5ydHJpOlwi4ourXCIsbnJ0cmllOlwi4outXCIsbnNjOlwi4oqBXCIsbnNjY3VlOlwi4ouhXCIsbnNjZTpcIuKqsMy4XCIsTnNjcjpcIvCdkqlcIixuc2NyOlwi8J2Tg1wiLG5zaG9ydG1pZDpcIuKIpFwiLG5zaG9ydHBhcmFsbGVsOlwi4oimXCIsbnNpbTpcIuKJgVwiLG5zaW1lOlwi4omEXCIsbnNpbWVxOlwi4omEXCIsbnNtaWQ6XCLiiKRcIixuc3BhcjpcIuKIplwiLG5zcXN1YmU6XCLii6JcIixuc3FzdXBlOlwi4oujXCIsbnN1YjpcIuKKhFwiLG5zdWJFOlwi4quFzLhcIixuc3ViZTpcIuKKiFwiLG5zdWJzZXQ6XCLiioLig5JcIixuc3Vic2V0ZXE6XCLiiohcIixuc3Vic2V0ZXFxOlwi4quFzLhcIixuc3VjYzpcIuKKgVwiLG5zdWNjZXE6XCLiqrDMuFwiLG5zdXA6XCLiioVcIixuc3VwRTpcIuKrhsy4XCIsbnN1cGU6XCLiiolcIixuc3Vwc2V0Olwi4oqD4oOSXCIsbnN1cHNldGVxOlwi4oqJXCIsbnN1cHNldGVxcTpcIuKrhsy4XCIsbnRnbDpcIuKJuVwiLE50aWxkZTpcIsORXCIsbnRpbGRlOlwiw7FcIixudGxnOlwi4om4XCIsbnRyaWFuZ2xlbGVmdDpcIuKLqlwiLG50cmlhbmdsZWxlZnRlcTpcIuKLrFwiLG50cmlhbmdsZXJpZ2h0Olwi4ourXCIsbnRyaWFuZ2xlcmlnaHRlcTpcIuKLrVwiLE51Olwizp1cIixudTpcIs69XCIsbnVtOlwiI1wiLG51bWVybzpcIuKEllwiLG51bXNwOlwi4oCHXCIsbnZhcDpcIuKJjeKDklwiLG52ZGFzaDpcIuKKrFwiLG52RGFzaDpcIuKKrVwiLG5WZGFzaDpcIuKKrlwiLG5WRGFzaDpcIuKKr1wiLG52Z2U6XCLiiaXig5JcIixudmd0OlwiPuKDklwiLG52SGFycjpcIuKkhFwiLG52aW5maW46XCLip55cIixudmxBcnI6XCLipIJcIixudmxlOlwi4omk4oOSXCIsbnZsdDpcIjzig5JcIixudmx0cmllOlwi4oq04oOSXCIsbnZyQXJyOlwi4qSDXCIsbnZydHJpZTpcIuKKteKDklwiLG52c2ltOlwi4oi84oOSXCIsbndhcmhrOlwi4qSjXCIsbndhcnI6XCLihpZcIixud0FycjpcIuKHllwiLG53YXJyb3c6XCLihpZcIixud25lYXI6XCLipKdcIixPYWN1dGU6XCLDk1wiLG9hY3V0ZTpcIsOzXCIsb2FzdDpcIuKKm1wiLE9jaXJjOlwiw5RcIixvY2lyYzpcIsO0XCIsb2NpcjpcIuKKmlwiLE9jeTpcItCeXCIsb2N5Olwi0L5cIixvZGFzaDpcIuKKnVwiLE9kYmxhYzpcIsWQXCIsb2RibGFjOlwixZFcIixvZGl2Olwi4qi4XCIsb2RvdDpcIuKKmVwiLG9kc29sZDpcIuKmvFwiLE9FbGlnOlwixZJcIixvZWxpZzpcIsWTXCIsb2ZjaXI6XCLipr9cIixPZnI6XCLwnZSSXCIsb2ZyOlwi8J2UrFwiLG9nb246XCLLm1wiLE9ncmF2ZTpcIsOSXCIsb2dyYXZlOlwiw7JcIixvZ3Q6XCLip4FcIixvaGJhcjpcIuKmtVwiLG9obTpcIs6pXCIsb2ludDpcIuKIrlwiLG9sYXJyOlwi4oa6XCIsb2xjaXI6XCLipr5cIixvbGNyb3NzOlwi4qa7XCIsb2xpbmU6XCLigL5cIixvbHQ6XCLip4BcIixPbWFjcjpcIsWMXCIsb21hY3I6XCLFjVwiLE9tZWdhOlwizqlcIixvbWVnYTpcIs+JXCIsT21pY3JvbjpcIs6fXCIsb21pY3JvbjpcIs6/XCIsb21pZDpcIuKmtlwiLG9taW51czpcIuKKllwiLE9vcGY6XCLwnZWGXCIsb29wZjpcIvCdlaBcIixvcGFyOlwi4qa3XCIsT3BlbkN1cmx5RG91YmxlUXVvdGU6XCLigJxcIixPcGVuQ3VybHlRdW90ZTpcIuKAmFwiLG9wZXJwOlwi4qa5XCIsb3BsdXM6XCLiipVcIixvcmFycjpcIuKGu1wiLE9yOlwi4qmUXCIsb3I6XCLiiKhcIixvcmQ6XCLiqZ1cIixvcmRlcjpcIuKEtFwiLG9yZGVyb2Y6XCLihLRcIixvcmRmOlwiwqpcIixvcmRtOlwiwrpcIixvcmlnb2Y6XCLiirZcIixvcm9yOlwi4qmWXCIsb3JzbG9wZTpcIuKpl1wiLG9ydjpcIuKpm1wiLG9TOlwi4pOIXCIsT3NjcjpcIvCdkqpcIixvc2NyOlwi4oS0XCIsT3NsYXNoOlwiw5hcIixvc2xhc2g6XCLDuFwiLG9zb2w6XCLiiphcIixPdGlsZGU6XCLDlVwiLG90aWxkZTpcIsO1XCIsb3RpbWVzYXM6XCLiqLZcIixPdGltZXM6XCLiqLdcIixvdGltZXM6XCLiipdcIixPdW1sOlwiw5ZcIixvdW1sOlwiw7ZcIixvdmJhcjpcIuKMvVwiLE92ZXJCYXI6XCLigL5cIixPdmVyQnJhY2U6XCLij55cIixPdmVyQnJhY2tldDpcIuKOtFwiLE92ZXJQYXJlbnRoZXNpczpcIuKPnFwiLHBhcmE6XCLCtlwiLHBhcmFsbGVsOlwi4oilXCIscGFyOlwi4oilXCIscGFyc2ltOlwi4quzXCIscGFyc2w6XCLiq71cIixwYXJ0Olwi4oiCXCIsUGFydGlhbEQ6XCLiiIJcIixQY3k6XCLQn1wiLHBjeTpcItC/XCIscGVyY250OlwiJVwiLHBlcmlvZDpcIi5cIixwZXJtaWw6XCLigLBcIixwZXJwOlwi4oqlXCIscGVydGVuazpcIuKAsVwiLFBmcjpcIvCdlJNcIixwZnI6XCLwnZStXCIsUGhpOlwizqZcIixwaGk6XCLPhlwiLHBoaXY6XCLPlVwiLHBobW1hdDpcIuKEs1wiLHBob25lOlwi4piOXCIsUGk6XCLOoFwiLHBpOlwiz4BcIixwaXRjaGZvcms6XCLii5RcIixwaXY6XCLPllwiLHBsYW5jazpcIuKEj1wiLHBsYW5ja2g6XCLihI5cIixwbGFua3Y6XCLihI9cIixwbHVzYWNpcjpcIuKoo1wiLHBsdXNiOlwi4oqeXCIscGx1c2NpcjpcIuKoolwiLHBsdXM6XCIrXCIscGx1c2RvOlwi4oiUXCIscGx1c2R1Olwi4qilXCIscGx1c2U6XCLiqbJcIixQbHVzTWludXM6XCLCsVwiLHBsdXNtbjpcIsKxXCIscGx1c3NpbTpcIuKoplwiLHBsdXN0d286XCLiqKdcIixwbTpcIsKxXCIsUG9pbmNhcmVwbGFuZTpcIuKEjFwiLHBvaW50aW50Olwi4qiVXCIscG9wZjpcIvCdlaFcIixQb3BmOlwi4oSZXCIscG91bmQ6XCLCo1wiLHByYXA6XCLiqrdcIixQcjpcIuKqu1wiLHByOlwi4om6XCIscHJjdWU6XCLiibxcIixwcmVjYXBwcm94Olwi4qq3XCIscHJlYzpcIuKJulwiLHByZWNjdXJseWVxOlwi4om8XCIsUHJlY2VkZXM6XCLiibpcIixQcmVjZWRlc0VxdWFsOlwi4qqvXCIsUHJlY2VkZXNTbGFudEVxdWFsOlwi4om8XCIsUHJlY2VkZXNUaWxkZTpcIuKJvlwiLHByZWNlcTpcIuKqr1wiLHByZWNuYXBwcm94Olwi4qq5XCIscHJlY25lcXE6XCLiqrVcIixwcmVjbnNpbTpcIuKLqFwiLHByZTpcIuKqr1wiLHByRTpcIuKqs1wiLHByZWNzaW06XCLiib5cIixwcmltZTpcIuKAslwiLFByaW1lOlwi4oCzXCIscHJpbWVzOlwi4oSZXCIscHJuYXA6XCLiqrlcIixwcm5FOlwi4qq1XCIscHJuc2ltOlwi4ouoXCIscHJvZDpcIuKIj1wiLFByb2R1Y3Q6XCLiiI9cIixwcm9mYWxhcjpcIuKMrlwiLHByb2ZsaW5lOlwi4oySXCIscHJvZnN1cmY6XCLijJNcIixwcm9wOlwi4oidXCIsUHJvcG9ydGlvbmFsOlwi4oidXCIsUHJvcG9ydGlvbjpcIuKIt1wiLHByb3B0bzpcIuKInVwiLHByc2ltOlwi4om+XCIscHJ1cmVsOlwi4oqwXCIsUHNjcjpcIvCdkqtcIixwc2NyOlwi8J2ThVwiLFBzaTpcIs6oXCIscHNpOlwiz4hcIixwdW5jc3A6XCLigIhcIixRZnI6XCLwnZSUXCIscWZyOlwi8J2UrlwiLHFpbnQ6XCLiqIxcIixxb3BmOlwi8J2VolwiLFFvcGY6XCLihJpcIixxcHJpbWU6XCLigZdcIixRc2NyOlwi8J2SrFwiLHFzY3I6XCLwnZOGXCIscXVhdGVybmlvbnM6XCLihI1cIixxdWF0aW50Olwi4qiWXCIscXVlc3Q6XCI/XCIscXVlc3RlcTpcIuKJn1wiLHF1b3Q6J1wiJyxRVU9UOidcIicsckFhcnI6XCLih5tcIixyYWNlOlwi4oi9zLFcIixSYWN1dGU6XCLFlFwiLHJhY3V0ZTpcIsWVXCIscmFkaWM6XCLiiJpcIixyYWVtcHR5djpcIuKms1wiLHJhbmc6XCLin6lcIixSYW5nOlwi4p+rXCIscmFuZ2Q6XCLippJcIixyYW5nZTpcIuKmpVwiLHJhbmdsZTpcIuKfqVwiLHJhcXVvOlwiwrtcIixyYXJyYXA6XCLipbVcIixyYXJyYjpcIuKHpVwiLHJhcnJiZnM6XCLipKBcIixyYXJyYzpcIuKks1wiLHJhcnI6XCLihpJcIixSYXJyOlwi4oagXCIsckFycjpcIuKHklwiLHJhcnJmczpcIuKknlwiLHJhcnJoazpcIuKGqlwiLHJhcnJscDpcIuKGrFwiLHJhcnJwbDpcIuKlhVwiLHJhcnJzaW06XCLipbRcIixSYXJydGw6XCLipJZcIixyYXJydGw6XCLihqNcIixyYXJydzpcIuKGnVwiLHJhdGFpbDpcIuKkmlwiLHJBdGFpbDpcIuKknFwiLHJhdGlvOlwi4oi2XCIscmF0aW9uYWxzOlwi4oSaXCIscmJhcnI6XCLipI1cIixyQmFycjpcIuKkj1wiLFJCYXJyOlwi4qSQXCIscmJicms6XCLinbNcIixyYnJhY2U6XCJ9XCIscmJyYWNrOlwiXVwiLHJicmtlOlwi4qaMXCIscmJya3NsZDpcIuKmjlwiLHJicmtzbHU6XCLippBcIixSY2Fyb246XCLFmFwiLHJjYXJvbjpcIsWZXCIsUmNlZGlsOlwixZZcIixyY2VkaWw6XCLFl1wiLHJjZWlsOlwi4oyJXCIscmN1YjpcIn1cIixSY3k6XCLQoFwiLHJjeTpcItGAXCIscmRjYTpcIuKkt1wiLHJkbGRoYXI6XCLipalcIixyZHF1bzpcIuKAnVwiLHJkcXVvcjpcIuKAnVwiLHJkc2g6XCLihrNcIixyZWFsOlwi4oScXCIscmVhbGluZTpcIuKEm1wiLHJlYWxwYXJ0Olwi4oScXCIscmVhbHM6XCLihJ1cIixSZTpcIuKEnFwiLHJlY3Q6XCLilq1cIixyZWc6XCLCrlwiLFJFRzpcIsKuXCIsUmV2ZXJzZUVsZW1lbnQ6XCLiiItcIixSZXZlcnNlRXF1aWxpYnJpdW06XCLih4tcIixSZXZlcnNlVXBFcXVpbGlicml1bTpcIuKlr1wiLHJmaXNodDpcIuKlvVwiLHJmbG9vcjpcIuKMi1wiLHJmcjpcIvCdlK9cIixSZnI6XCLihJxcIixySGFyOlwi4qWkXCIscmhhcmQ6XCLih4FcIixyaGFydTpcIuKHgFwiLHJoYXJ1bDpcIuKlrFwiLFJobzpcIs6hXCIscmhvOlwiz4FcIixyaG92Olwiz7FcIixSaWdodEFuZ2xlQnJhY2tldDpcIuKfqVwiLFJpZ2h0QXJyb3dCYXI6XCLih6VcIixyaWdodGFycm93Olwi4oaSXCIsUmlnaHRBcnJvdzpcIuKGklwiLFJpZ2h0YXJyb3c6XCLih5JcIixSaWdodEFycm93TGVmdEFycm93Olwi4oeEXCIscmlnaHRhcnJvd3RhaWw6XCLihqNcIixSaWdodENlaWxpbmc6XCLijIlcIixSaWdodERvdWJsZUJyYWNrZXQ6XCLin6dcIixSaWdodERvd25UZWVWZWN0b3I6XCLipZ1cIixSaWdodERvd25WZWN0b3JCYXI6XCLipZVcIixSaWdodERvd25WZWN0b3I6XCLih4JcIixSaWdodEZsb29yOlwi4oyLXCIscmlnaHRoYXJwb29uZG93bjpcIuKHgVwiLHJpZ2h0aGFycG9vbnVwOlwi4oeAXCIscmlnaHRsZWZ0YXJyb3dzOlwi4oeEXCIscmlnaHRsZWZ0aGFycG9vbnM6XCLih4xcIixyaWdodHJpZ2h0YXJyb3dzOlwi4oeJXCIscmlnaHRzcXVpZ2Fycm93Olwi4oadXCIsUmlnaHRUZWVBcnJvdzpcIuKGplwiLFJpZ2h0VGVlOlwi4oqiXCIsUmlnaHRUZWVWZWN0b3I6XCLipZtcIixyaWdodHRocmVldGltZXM6XCLii4xcIixSaWdodFRyaWFuZ2xlQmFyOlwi4qeQXCIsUmlnaHRUcmlhbmdsZTpcIuKKs1wiLFJpZ2h0VHJpYW5nbGVFcXVhbDpcIuKKtVwiLFJpZ2h0VXBEb3duVmVjdG9yOlwi4qWPXCIsUmlnaHRVcFRlZVZlY3RvcjpcIuKlnFwiLFJpZ2h0VXBWZWN0b3JCYXI6XCLipZRcIixSaWdodFVwVmVjdG9yOlwi4oa+XCIsUmlnaHRWZWN0b3JCYXI6XCLipZNcIixSaWdodFZlY3RvcjpcIuKHgFwiLHJpbmc6XCLLmlwiLHJpc2luZ2RvdHNlcTpcIuKJk1wiLHJsYXJyOlwi4oeEXCIscmxoYXI6XCLih4xcIixybG06XCLigI9cIixybW91c3RhY2hlOlwi4o6xXCIscm1vdXN0Olwi4o6xXCIscm5taWQ6XCLiq65cIixyb2FuZzpcIuKfrVwiLHJvYXJyOlwi4oe+XCIscm9icms6XCLin6dcIixyb3BhcjpcIuKmhlwiLHJvcGY6XCLwnZWjXCIsUm9wZjpcIuKEnVwiLHJvcGx1czpcIuKorlwiLHJvdGltZXM6XCLiqLVcIixSb3VuZEltcGxpZXM6XCLipbBcIixycGFyOlwiKVwiLHJwYXJndDpcIuKmlFwiLHJwcG9saW50Olwi4qiSXCIscnJhcnI6XCLih4lcIixScmlnaHRhcnJvdzpcIuKHm1wiLHJzYXF1bzpcIuKAulwiLHJzY3I6XCLwnZOHXCIsUnNjcjpcIuKEm1wiLHJzaDpcIuKGsVwiLFJzaDpcIuKGsVwiLHJzcWI6XCJdXCIscnNxdW86XCLigJlcIixyc3F1b3I6XCLigJlcIixydGhyZWU6XCLii4xcIixydGltZXM6XCLii4pcIixydHJpOlwi4pa5XCIscnRyaWU6XCLiirVcIixydHJpZjpcIuKWuFwiLHJ0cmlsdHJpOlwi4qeOXCIsUnVsZURlbGF5ZWQ6XCLip7RcIixydWx1aGFyOlwi4qWoXCIscng6XCLihJ5cIixTYWN1dGU6XCLFmlwiLHNhY3V0ZTpcIsWbXCIsc2JxdW86XCLigJpcIixzY2FwOlwi4qq4XCIsU2Nhcm9uOlwixaBcIixzY2Fyb246XCLFoVwiLFNjOlwi4qq8XCIsc2M6XCLiibtcIixzY2N1ZTpcIuKJvVwiLHNjZTpcIuKqsFwiLHNjRTpcIuKqtFwiLFNjZWRpbDpcIsWeXCIsc2NlZGlsOlwixZ9cIixTY2lyYzpcIsWcXCIsc2NpcmM6XCLFnVwiLHNjbmFwOlwi4qq6XCIsc2NuRTpcIuKqtlwiLHNjbnNpbTpcIuKLqVwiLHNjcG9saW50Olwi4qiTXCIsc2NzaW06XCLiib9cIixTY3k6XCLQoVwiLHNjeTpcItGBXCIsc2RvdGI6XCLiiqFcIixzZG90Olwi4ouFXCIsc2RvdGU6XCLiqaZcIixzZWFyaGs6XCLipKVcIixzZWFycjpcIuKGmFwiLHNlQXJyOlwi4oeYXCIsc2VhcnJvdzpcIuKGmFwiLHNlY3Q6XCLCp1wiLHNlbWk6XCI7XCIsc2Vzd2FyOlwi4qSpXCIsc2V0bWludXM6XCLiiJZcIixzZXRtbjpcIuKIllwiLHNleHQ6XCLinLZcIixTZnI6XCLwnZSWXCIsc2ZyOlwi8J2UsFwiLHNmcm93bjpcIuKMolwiLHNoYXJwOlwi4pmvXCIsU0hDSGN5Olwi0KlcIixzaGNoY3k6XCLRiVwiLFNIY3k6XCLQqFwiLHNoY3k6XCLRiFwiLFNob3J0RG93bkFycm93Olwi4oaTXCIsU2hvcnRMZWZ0QXJyb3c6XCLihpBcIixzaG9ydG1pZDpcIuKIo1wiLHNob3J0cGFyYWxsZWw6XCLiiKVcIixTaG9ydFJpZ2h0QXJyb3c6XCLihpJcIixTaG9ydFVwQXJyb3c6XCLihpFcIixzaHk6XCLCrVwiLFNpZ21hOlwizqNcIixzaWdtYTpcIs+DXCIsc2lnbWFmOlwiz4JcIixzaWdtYXY6XCLPglwiLHNpbTpcIuKIvFwiLHNpbWRvdDpcIuKpqlwiLHNpbWU6XCLiiYNcIixzaW1lcTpcIuKJg1wiLHNpbWc6XCLiqp5cIixzaW1nRTpcIuKqoFwiLHNpbWw6XCLiqp1cIixzaW1sRTpcIuKqn1wiLHNpbW5lOlwi4omGXCIsc2ltcGx1czpcIuKopFwiLHNpbXJhcnI6XCLipbJcIixzbGFycjpcIuKGkFwiLFNtYWxsQ2lyY2xlOlwi4oiYXCIsc21hbGxzZXRtaW51czpcIuKIllwiLHNtYXNocDpcIuKos1wiLHNtZXBhcnNsOlwi4qekXCIsc21pZDpcIuKIo1wiLHNtaWxlOlwi4oyjXCIsc210Olwi4qqqXCIsc210ZTpcIuKqrFwiLHNtdGVzOlwi4qqs77iAXCIsU09GVGN5Olwi0KxcIixzb2Z0Y3k6XCLRjFwiLHNvbGJhcjpcIuKMv1wiLHNvbGI6XCLip4RcIixzb2w6XCIvXCIsU29wZjpcIvCdlYpcIixzb3BmOlwi8J2VpFwiLHNwYWRlczpcIuKZoFwiLHNwYWRlc3VpdDpcIuKZoFwiLHNwYXI6XCLiiKVcIixzcWNhcDpcIuKKk1wiLHNxY2FwczpcIuKKk++4gFwiLHNxY3VwOlwi4oqUXCIsc3FjdXBzOlwi4oqU77iAXCIsU3FydDpcIuKImlwiLHNxc3ViOlwi4oqPXCIsc3FzdWJlOlwi4oqRXCIsc3FzdWJzZXQ6XCLiio9cIixzcXN1YnNldGVxOlwi4oqRXCIsc3FzdXA6XCLiipBcIixzcXN1cGU6XCLiipJcIixzcXN1cHNldDpcIuKKkFwiLHNxc3Vwc2V0ZXE6XCLiipJcIixzcXVhcmU6XCLilqFcIixTcXVhcmU6XCLilqFcIixTcXVhcmVJbnRlcnNlY3Rpb246XCLiipNcIixTcXVhcmVTdWJzZXQ6XCLiio9cIixTcXVhcmVTdWJzZXRFcXVhbDpcIuKKkVwiLFNxdWFyZVN1cGVyc2V0Olwi4oqQXCIsU3F1YXJlU3VwZXJzZXRFcXVhbDpcIuKKklwiLFNxdWFyZVVuaW9uOlwi4oqUXCIsc3F1YXJmOlwi4paqXCIsc3F1Olwi4pahXCIsc3F1ZjpcIuKWqlwiLHNyYXJyOlwi4oaSXCIsU3NjcjpcIvCdkq5cIixzc2NyOlwi8J2TiFwiLHNzZXRtbjpcIuKIllwiLHNzbWlsZTpcIuKMo1wiLHNzdGFyZjpcIuKLhlwiLFN0YXI6XCLii4ZcIixzdGFyOlwi4piGXCIsc3RhcmY6XCLimIVcIixzdHJhaWdodGVwc2lsb246XCLPtVwiLHN0cmFpZ2h0cGhpOlwiz5VcIixzdHJuczpcIsKvXCIsc3ViOlwi4oqCXCIsU3ViOlwi4ouQXCIsc3ViZG90Olwi4qq9XCIsc3ViRTpcIuKrhVwiLHN1YmU6XCLiioZcIixzdWJlZG90Olwi4quDXCIsc3VibXVsdDpcIuKrgVwiLHN1Ym5FOlwi4quLXCIsc3VibmU6XCLiiopcIixzdWJwbHVzOlwi4qq/XCIsc3VicmFycjpcIuKluVwiLHN1YnNldDpcIuKKglwiLFN1YnNldDpcIuKLkFwiLHN1YnNldGVxOlwi4oqGXCIsc3Vic2V0ZXFxOlwi4quFXCIsU3Vic2V0RXF1YWw6XCLiioZcIixzdWJzZXRuZXE6XCLiiopcIixzdWJzZXRuZXFxOlwi4quLXCIsc3Vic2ltOlwi4quHXCIsc3Vic3ViOlwi4quVXCIsc3Vic3VwOlwi4quTXCIsc3VjY2FwcHJveDpcIuKquFwiLHN1Y2M6XCLiibtcIixzdWNjY3VybHllcTpcIuKJvVwiLFN1Y2NlZWRzOlwi4om7XCIsU3VjY2VlZHNFcXVhbDpcIuKqsFwiLFN1Y2NlZWRzU2xhbnRFcXVhbDpcIuKJvVwiLFN1Y2NlZWRzVGlsZGU6XCLiib9cIixzdWNjZXE6XCLiqrBcIixzdWNjbmFwcHJveDpcIuKqulwiLHN1Y2NuZXFxOlwi4qq2XCIsc3VjY25zaW06XCLii6lcIixzdWNjc2ltOlwi4om/XCIsU3VjaFRoYXQ6XCLiiItcIixzdW06XCLiiJFcIixTdW06XCLiiJFcIixzdW5nOlwi4pmqXCIsc3VwMTpcIsK5XCIsc3VwMjpcIsKyXCIsc3VwMzpcIsKzXCIsc3VwOlwi4oqDXCIsU3VwOlwi4ouRXCIsc3VwZG90Olwi4qq+XCIsc3VwZHN1YjpcIuKrmFwiLHN1cEU6XCLiq4ZcIixzdXBlOlwi4oqHXCIsc3VwZWRvdDpcIuKrhFwiLFN1cGVyc2V0Olwi4oqDXCIsU3VwZXJzZXRFcXVhbDpcIuKKh1wiLHN1cGhzb2w6XCLin4lcIixzdXBoc3ViOlwi4quXXCIsc3VwbGFycjpcIuKlu1wiLHN1cG11bHQ6XCLiq4JcIixzdXBuRTpcIuKrjFwiLHN1cG5lOlwi4oqLXCIsc3VwcGx1czpcIuKrgFwiLHN1cHNldDpcIuKKg1wiLFN1cHNldDpcIuKLkVwiLHN1cHNldGVxOlwi4oqHXCIsc3Vwc2V0ZXFxOlwi4quGXCIsc3Vwc2V0bmVxOlwi4oqLXCIsc3Vwc2V0bmVxcTpcIuKrjFwiLHN1cHNpbTpcIuKriFwiLHN1cHN1YjpcIuKrlFwiLHN1cHN1cDpcIuKrllwiLHN3YXJoazpcIuKkplwiLHN3YXJyOlwi4oaZXCIsc3dBcnI6XCLih5lcIixzd2Fycm93Olwi4oaZXCIsc3dud2FyOlwi4qSqXCIsc3psaWc6XCLDn1wiLFRhYjpcIlxcdFwiLHRhcmdldDpcIuKMllwiLFRhdTpcIs6kXCIsdGF1Olwiz4RcIix0YnJrOlwi4o60XCIsVGNhcm9uOlwixaRcIix0Y2Fyb246XCLFpVwiLFRjZWRpbDpcIsWiXCIsdGNlZGlsOlwixaNcIixUY3k6XCLQolwiLHRjeTpcItGCXCIsdGRvdDpcIuKDm1wiLHRlbHJlYzpcIuKMlVwiLFRmcjpcIvCdlJdcIix0ZnI6XCLwnZSxXCIsdGhlcmU0Olwi4oi0XCIsdGhlcmVmb3JlOlwi4oi0XCIsVGhlcmVmb3JlOlwi4oi0XCIsVGhldGE6XCLOmFwiLHRoZXRhOlwizrhcIix0aGV0YXN5bTpcIs+RXCIsdGhldGF2Olwiz5FcIix0aGlja2FwcHJveDpcIuKJiFwiLHRoaWNrc2ltOlwi4oi8XCIsVGhpY2tTcGFjZTpcIuKBn+KAilwiLFRoaW5TcGFjZTpcIuKAiVwiLHRoaW5zcDpcIuKAiVwiLHRoa2FwOlwi4omIXCIsdGhrc2ltOlwi4oi8XCIsVEhPUk46XCLDnlwiLHRob3JuOlwiw75cIix0aWxkZTpcIsucXCIsVGlsZGU6XCLiiLxcIixUaWxkZUVxdWFsOlwi4omDXCIsVGlsZGVGdWxsRXF1YWw6XCLiiYVcIixUaWxkZVRpbGRlOlwi4omIXCIsdGltZXNiYXI6XCLiqLFcIix0aW1lc2I6XCLiiqBcIix0aW1lczpcIsOXXCIsdGltZXNkOlwi4qiwXCIsdGludDpcIuKIrVwiLHRvZWE6XCLipKhcIix0b3Bib3Q6XCLijLZcIix0b3BjaXI6XCLiq7FcIix0b3A6XCLiiqRcIixUb3BmOlwi8J2Vi1wiLHRvcGY6XCLwnZWlXCIsdG9wZm9yazpcIuKrmlwiLHRvc2E6XCLipKlcIix0cHJpbWU6XCLigLRcIix0cmFkZTpcIuKEolwiLFRSQURFOlwi4oSiXCIsdHJpYW5nbGU6XCLilrVcIix0cmlhbmdsZWRvd246XCLilr9cIix0cmlhbmdsZWxlZnQ6XCLil4NcIix0cmlhbmdsZWxlZnRlcTpcIuKKtFwiLHRyaWFuZ2xlcTpcIuKJnFwiLHRyaWFuZ2xlcmlnaHQ6XCLilrlcIix0cmlhbmdsZXJpZ2h0ZXE6XCLiirVcIix0cmlkb3Q6XCLil6xcIix0cmllOlwi4omcXCIsdHJpbWludXM6XCLiqLpcIixUcmlwbGVEb3Q6XCLig5tcIix0cmlwbHVzOlwi4qi5XCIsdHJpc2I6XCLip41cIix0cml0aW1lOlwi4qi7XCIsdHJwZXppdW06XCLij6JcIixUc2NyOlwi8J2Sr1wiLHRzY3I6XCLwnZOJXCIsVFNjeTpcItCmXCIsdHNjeTpcItGGXCIsVFNIY3k6XCLQi1wiLHRzaGN5Olwi0ZtcIixUc3Ryb2s6XCLFplwiLHRzdHJvazpcIsWnXCIsdHdpeHQ6XCLiiaxcIix0d29oZWFkbGVmdGFycm93Olwi4oaeXCIsdHdvaGVhZHJpZ2h0YXJyb3c6XCLihqBcIixVYWN1dGU6XCLDmlwiLHVhY3V0ZTpcIsO6XCIsdWFycjpcIuKGkVwiLFVhcnI6XCLihp9cIix1QXJyOlwi4oeRXCIsVWFycm9jaXI6XCLipYlcIixVYnJjeTpcItCOXCIsdWJyY3k6XCLRnlwiLFVicmV2ZTpcIsWsXCIsdWJyZXZlOlwixa1cIixVY2lyYzpcIsObXCIsdWNpcmM6XCLDu1wiLFVjeTpcItCjXCIsdWN5Olwi0YNcIix1ZGFycjpcIuKHhVwiLFVkYmxhYzpcIsWwXCIsdWRibGFjOlwixbFcIix1ZGhhcjpcIuKlrlwiLHVmaXNodDpcIuKlvlwiLFVmcjpcIvCdlJhcIix1ZnI6XCLwnZSyXCIsVWdyYXZlOlwiw5lcIix1Z3JhdmU6XCLDuVwiLHVIYXI6XCLipaNcIix1aGFybDpcIuKGv1wiLHVoYXJyOlwi4oa+XCIsdWhibGs6XCLiloBcIix1bGNvcm46XCLijJxcIix1bGNvcm5lcjpcIuKMnFwiLHVsY3JvcDpcIuKMj1wiLHVsdHJpOlwi4pe4XCIsVW1hY3I6XCLFqlwiLHVtYWNyOlwixatcIix1bWw6XCLCqFwiLFVuZGVyQmFyOlwiX1wiLFVuZGVyQnJhY2U6XCLij59cIixVbmRlckJyYWNrZXQ6XCLijrVcIixVbmRlclBhcmVudGhlc2lzOlwi4o+dXCIsVW5pb246XCLii4NcIixVbmlvblBsdXM6XCLiio5cIixVb2dvbjpcIsWyXCIsdW9nb246XCLFs1wiLFVvcGY6XCLwnZWMXCIsdW9wZjpcIvCdlaZcIixVcEFycm93QmFyOlwi4qSSXCIsdXBhcnJvdzpcIuKGkVwiLFVwQXJyb3c6XCLihpFcIixVcGFycm93Olwi4oeRXCIsVXBBcnJvd0Rvd25BcnJvdzpcIuKHhVwiLHVwZG93bmFycm93Olwi4oaVXCIsVXBEb3duQXJyb3c6XCLihpVcIixVcGRvd25hcnJvdzpcIuKHlVwiLFVwRXF1aWxpYnJpdW06XCLipa5cIix1cGhhcnBvb25sZWZ0Olwi4oa/XCIsdXBoYXJwb29ucmlnaHQ6XCLihr5cIix1cGx1czpcIuKKjlwiLFVwcGVyTGVmdEFycm93Olwi4oaWXCIsVXBwZXJSaWdodEFycm93Olwi4oaXXCIsdXBzaTpcIs+FXCIsVXBzaTpcIs+SXCIsdXBzaWg6XCLPklwiLFVwc2lsb246XCLOpVwiLHVwc2lsb246XCLPhVwiLFVwVGVlQXJyb3c6XCLihqVcIixVcFRlZTpcIuKKpVwiLHVwdXBhcnJvd3M6XCLih4hcIix1cmNvcm46XCLijJ1cIix1cmNvcm5lcjpcIuKMnVwiLHVyY3JvcDpcIuKMjlwiLFVyaW5nOlwixa5cIix1cmluZzpcIsWvXCIsdXJ0cmk6XCLil7lcIixVc2NyOlwi8J2SsFwiLHVzY3I6XCLwnZOKXCIsdXRkb3Q6XCLii7BcIixVdGlsZGU6XCLFqFwiLHV0aWxkZTpcIsWpXCIsdXRyaTpcIuKWtVwiLHV0cmlmOlwi4pa0XCIsdXVhcnI6XCLih4hcIixVdW1sOlwiw5xcIix1dW1sOlwiw7xcIix1d2FuZ2xlOlwi4qanXCIsdmFuZ3J0Olwi4qacXCIsdmFyZXBzaWxvbjpcIs+1XCIsdmFya2FwcGE6XCLPsFwiLHZhcm5vdGhpbmc6XCLiiIVcIix2YXJwaGk6XCLPlVwiLHZhcnBpOlwiz5ZcIix2YXJwcm9wdG86XCLiiJ1cIix2YXJyOlwi4oaVXCIsdkFycjpcIuKHlVwiLHZhcnJobzpcIs+xXCIsdmFyc2lnbWE6XCLPglwiLHZhcnN1YnNldG5lcTpcIuKKiu+4gFwiLHZhcnN1YnNldG5lcXE6XCLiq4vvuIBcIix2YXJzdXBzZXRuZXE6XCLiiovvuIBcIix2YXJzdXBzZXRuZXFxOlwi4quM77iAXCIsdmFydGhldGE6XCLPkVwiLHZhcnRyaWFuZ2xlbGVmdDpcIuKKslwiLHZhcnRyaWFuZ2xlcmlnaHQ6XCLiirNcIix2QmFyOlwi4quoXCIsVmJhcjpcIuKrq1wiLHZCYXJ2Olwi4qupXCIsVmN5Olwi0JJcIix2Y3k6XCLQslwiLHZkYXNoOlwi4oqiXCIsdkRhc2g6XCLiiqhcIixWZGFzaDpcIuKKqVwiLFZEYXNoOlwi4oqrXCIsVmRhc2hsOlwi4qumXCIsdmVlYmFyOlwi4oq7XCIsdmVlOlwi4oioXCIsVmVlOlwi4ouBXCIsdmVlZXE6XCLiiZpcIix2ZWxsaXA6XCLii65cIix2ZXJiYXI6XCJ8XCIsVmVyYmFyOlwi4oCWXCIsdmVydDpcInxcIixWZXJ0Olwi4oCWXCIsVmVydGljYWxCYXI6XCLiiKNcIixWZXJ0aWNhbExpbmU6XCJ8XCIsVmVydGljYWxTZXBhcmF0b3I6XCLinZhcIixWZXJ0aWNhbFRpbGRlOlwi4omAXCIsVmVyeVRoaW5TcGFjZTpcIuKAilwiLFZmcjpcIvCdlJlcIix2ZnI6XCLwnZSzXCIsdmx0cmk6XCLiirJcIix2bnN1YjpcIuKKguKDklwiLHZuc3VwOlwi4oqD4oOSXCIsVm9wZjpcIvCdlY1cIix2b3BmOlwi8J2Vp1wiLHZwcm9wOlwi4oidXCIsdnJ0cmk6XCLiirNcIixWc2NyOlwi8J2SsVwiLHZzY3I6XCLwnZOLXCIsdnN1Ym5FOlwi4quL77iAXCIsdnN1Ym5lOlwi4oqK77iAXCIsdnN1cG5FOlwi4quM77iAXCIsdnN1cG5lOlwi4oqL77iAXCIsVnZkYXNoOlwi4oqqXCIsdnppZ3phZzpcIuKmmlwiLFdjaXJjOlwixbRcIix3Y2lyYzpcIsW1XCIsd2VkYmFyOlwi4qmfXCIsd2VkZ2U6XCLiiKdcIixXZWRnZTpcIuKLgFwiLHdlZGdlcTpcIuKJmVwiLHdlaWVycDpcIuKEmFwiLFdmcjpcIvCdlJpcIix3ZnI6XCLwnZS0XCIsV29wZjpcIvCdlY5cIix3b3BmOlwi8J2VqFwiLHdwOlwi4oSYXCIsd3I6XCLiiYBcIix3cmVhdGg6XCLiiYBcIixXc2NyOlwi8J2SslwiLHdzY3I6XCLwnZOMXCIseGNhcDpcIuKLglwiLHhjaXJjOlwi4pevXCIseGN1cDpcIuKLg1wiLHhkdHJpOlwi4pa9XCIsWGZyOlwi8J2Um1wiLHhmcjpcIvCdlLVcIix4aGFycjpcIuKft1wiLHhoQXJyOlwi4p+6XCIsWGk6XCLOnlwiLHhpOlwizr5cIix4bGFycjpcIuKftVwiLHhsQXJyOlwi4p+4XCIseG1hcDpcIuKfvFwiLHhuaXM6XCLii7tcIix4b2RvdDpcIuKogFwiLFhvcGY6XCLwnZWPXCIseG9wZjpcIvCdlalcIix4b3BsdXM6XCLiqIFcIix4b3RpbWU6XCLiqIJcIix4cmFycjpcIuKftlwiLHhyQXJyOlwi4p+5XCIsWHNjcjpcIvCdkrNcIix4c2NyOlwi8J2TjVwiLHhzcWN1cDpcIuKohlwiLHh1cGx1czpcIuKohFwiLHh1dHJpOlwi4pazXCIseHZlZTpcIuKLgVwiLHh3ZWRnZTpcIuKLgFwiLFlhY3V0ZTpcIsOdXCIseWFjdXRlOlwiw71cIixZQWN5Olwi0K9cIix5YWN5Olwi0Y9cIixZY2lyYzpcIsW2XCIseWNpcmM6XCLFt1wiLFljeTpcItCrXCIseWN5Olwi0YtcIix5ZW46XCLCpVwiLFlmcjpcIvCdlJxcIix5ZnI6XCLwnZS2XCIsWUljeTpcItCHXCIseWljeTpcItGXXCIsWW9wZjpcIvCdlZBcIix5b3BmOlwi8J2VqlwiLFlzY3I6XCLwnZK0XCIseXNjcjpcIvCdk45cIixZVWN5Olwi0K5cIix5dWN5Olwi0Y5cIix5dW1sOlwiw79cIixZdW1sOlwixbhcIixaYWN1dGU6XCLFuVwiLHphY3V0ZTpcIsW6XCIsWmNhcm9uOlwixb1cIix6Y2Fyb246XCLFvlwiLFpjeTpcItCXXCIsemN5Olwi0LdcIixaZG90OlwixbtcIix6ZG90OlwixbxcIix6ZWV0cmY6XCLihKhcIixaZXJvV2lkdGhTcGFjZTpcIuKAi1wiLFpldGE6XCLOllwiLHpldGE6XCLOtlwiLHpmcjpcIvCdlLdcIixaZnI6XCLihKhcIixaSGN5Olwi0JZcIix6aGN5Olwi0LZcIix6aWdyYXJyOlwi4oedXCIsem9wZjpcIvCdlatcIixab3BmOlwi4oSkXCIsWnNjcjpcIvCdkrVcIix6c2NyOlwi8J2Tj1wiLHp3ajpcIuKAjVwiLHp3bmo6XCLigIxcIn19LHt9XSwyNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e0FhY3V0ZTpcIsOBXCIsYWFjdXRlOlwiw6FcIixBY2lyYzpcIsOCXCIsYWNpcmM6XCLDolwiLGFjdXRlOlwiwrRcIixBRWxpZzpcIsOGXCIsYWVsaWc6XCLDplwiLEFncmF2ZTpcIsOAXCIsYWdyYXZlOlwiw6BcIixhbXA6XCImXCIsQU1QOlwiJlwiLEFyaW5nOlwiw4VcIixhcmluZzpcIsOlXCIsQXRpbGRlOlwiw4NcIixhdGlsZGU6XCLDo1wiLEF1bWw6XCLDhFwiLGF1bWw6XCLDpFwiLGJydmJhcjpcIsKmXCIsQ2NlZGlsOlwiw4dcIixjY2VkaWw6XCLDp1wiLGNlZGlsOlwiwrhcIixjZW50OlwiwqJcIixjb3B5OlwiwqlcIixDT1BZOlwiwqlcIixjdXJyZW46XCLCpFwiLGRlZzpcIsKwXCIsZGl2aWRlOlwiw7dcIixFYWN1dGU6XCLDiVwiLGVhY3V0ZTpcIsOpXCIsRWNpcmM6XCLDilwiLGVjaXJjOlwiw6pcIixFZ3JhdmU6XCLDiFwiLGVncmF2ZTpcIsOoXCIsRVRIOlwiw5BcIixldGg6XCLDsFwiLEV1bWw6XCLDi1wiLGV1bWw6XCLDq1wiLGZyYWMxMjpcIsK9XCIsZnJhYzE0OlwiwrxcIixmcmFjMzQ6XCLCvlwiLGd0OlwiPlwiLEdUOlwiPlwiLElhY3V0ZTpcIsONXCIsaWFjdXRlOlwiw61cIixJY2lyYzpcIsOOXCIsaWNpcmM6XCLDrlwiLGlleGNsOlwiwqFcIixJZ3JhdmU6XCLDjFwiLGlncmF2ZTpcIsOsXCIsaXF1ZXN0Olwiwr9cIixJdW1sOlwiw49cIixpdW1sOlwiw69cIixsYXF1bzpcIsKrXCIsbHQ6XCI8XCIsTFQ6XCI8XCIsbWFjcjpcIsKvXCIsbWljcm86XCLCtVwiLG1pZGRvdDpcIsK3XCIsbmJzcDpcIsKgXCIsbm90OlwiwqxcIixOdGlsZGU6XCLDkVwiLG50aWxkZTpcIsOxXCIsT2FjdXRlOlwiw5NcIixvYWN1dGU6XCLDs1wiLE9jaXJjOlwiw5RcIixvY2lyYzpcIsO0XCIsT2dyYXZlOlwiw5JcIixvZ3JhdmU6XCLDslwiLG9yZGY6XCLCqlwiLG9yZG06XCLCulwiLE9zbGFzaDpcIsOYXCIsb3NsYXNoOlwiw7hcIixPdGlsZGU6XCLDlVwiLG90aWxkZTpcIsO1XCIsT3VtbDpcIsOWXCIsb3VtbDpcIsO2XCIscGFyYTpcIsK2XCIscGx1c21uOlwiwrFcIixwb3VuZDpcIsKjXCIscXVvdDonXCInLFFVT1Q6J1wiJyxyYXF1bzpcIsK7XCIscmVnOlwiwq5cIixSRUc6XCLCrlwiLHNlY3Q6XCLCp1wiLHNoeTpcIsKtXCIsc3VwMTpcIsK5XCIsc3VwMjpcIsKyXCIsc3VwMzpcIsKzXCIsc3psaWc6XCLDn1wiLFRIT1JOOlwiw55cIix0aG9ybjpcIsO+XCIsdGltZXM6XCLDl1wiLFVhY3V0ZTpcIsOaXCIsdWFjdXRlOlwiw7pcIixVY2lyYzpcIsObXCIsdWNpcmM6XCLDu1wiLFVncmF2ZTpcIsOZXCIsdWdyYXZlOlwiw7lcIix1bWw6XCLCqFwiLFV1bWw6XCLDnFwiLHV1bWw6XCLDvFwiLFlhY3V0ZTpcIsOdXCIseWFjdXRlOlwiw71cIix5ZW46XCLCpVwiLHl1bWw6XCLDv1wifX0se31dLDI3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz17YW1wOlwiJlwiLGFwb3M6XCInXCIsZ3Q6XCI+XCIsbHQ6XCI8XCIscXVvdDonXCInfX0se31dLDI4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtmdW5jdGlvbiBFdmVudEVtaXR0ZXIoKXt0aGlzLl9ldmVudHM9dGhpcy5fZXZlbnRzfHx7fTt0aGlzLl9tYXhMaXN0ZW5lcnM9dGhpcy5fbWF4TGlzdGVuZXJzfHx1bmRlZmluZWR9bW9kdWxlLmV4cG9ydHM9RXZlbnRFbWl0dGVyO0V2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXI9RXZlbnRFbWl0dGVyO0V2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cz11bmRlZmluZWQ7RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzPXVuZGVmaW5lZDtFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycz0xMDtFdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycz1mdW5jdGlvbihuKXtpZighaXNOdW1iZXIobil8fG48MHx8aXNOYU4obikpdGhyb3cgVHlwZUVycm9yKFwibiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyXCIpO3RoaXMuX21heExpc3RlbmVycz1uO3JldHVybiB0aGlzfTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQ9ZnVuY3Rpb24odHlwZSl7dmFyIGVyLGhhbmRsZXIsbGVuLGFyZ3MsaSxsaXN0ZW5lcnM7aWYoIXRoaXMuX2V2ZW50cyl0aGlzLl9ldmVudHM9e307aWYodHlwZT09PVwiZXJyb3JcIil7aWYoIXRoaXMuX2V2ZW50cy5lcnJvcnx8aXNPYmplY3QodGhpcy5fZXZlbnRzLmVycm9yKSYmIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpe2VyPWFyZ3VtZW50c1sxXTtpZihlciBpbnN0YW5jZW9mIEVycm9yKXt0aHJvdyBlcn1lbHNle3ZhciBlcnI9bmV3IEVycm9yKCdVbmNhdWdodCwgdW5zcGVjaWZpZWQgXCJlcnJvclwiIGV2ZW50LiAoJytlcitcIilcIik7ZXJyLmNvbnRleHQ9ZXI7dGhyb3cgZXJyfX19aGFuZGxlcj10aGlzLl9ldmVudHNbdHlwZV07aWYoaXNVbmRlZmluZWQoaGFuZGxlcikpcmV0dXJuIGZhbHNlO2lmKGlzRnVuY3Rpb24oaGFuZGxlcikpe3N3aXRjaChhcmd1bWVudHMubGVuZ3RoKXtjYXNlIDE6aGFuZGxlci5jYWxsKHRoaXMpO2JyZWFrO2Nhc2UgMjpoYW5kbGVyLmNhbGwodGhpcyxhcmd1bWVudHNbMV0pO2JyZWFrO2Nhc2UgMzpoYW5kbGVyLmNhbGwodGhpcyxhcmd1bWVudHNbMV0sYXJndW1lbnRzWzJdKTticmVhaztkZWZhdWx0OmFyZ3M9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDEpO2hhbmRsZXIuYXBwbHkodGhpcyxhcmdzKX19ZWxzZSBpZihpc09iamVjdChoYW5kbGVyKSl7YXJncz1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMSk7bGlzdGVuZXJzPWhhbmRsZXIuc2xpY2UoKTtsZW49bGlzdGVuZXJzLmxlbmd0aDtmb3IoaT0wO2k8bGVuO2krKylsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcyxhcmdzKX1yZXR1cm4gdHJ1ZX07RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcj1mdW5jdGlvbih0eXBlLGxpc3RlbmVyKXt2YXIgbTtpZighaXNGdW5jdGlvbihsaXN0ZW5lcikpdGhyb3cgVHlwZUVycm9yKFwibGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpO2lmKCF0aGlzLl9ldmVudHMpdGhpcy5fZXZlbnRzPXt9O2lmKHRoaXMuX2V2ZW50cy5uZXdMaXN0ZW5lcil0aGlzLmVtaXQoXCJuZXdMaXN0ZW5lclwiLHR5cGUsaXNGdW5jdGlvbihsaXN0ZW5lci5saXN0ZW5lcik/bGlzdGVuZXIubGlzdGVuZXI6bGlzdGVuZXIpO2lmKCF0aGlzLl9ldmVudHNbdHlwZV0pdGhpcy5fZXZlbnRzW3R5cGVdPWxpc3RlbmVyO2Vsc2UgaWYoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSl0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7ZWxzZSB0aGlzLl9ldmVudHNbdHlwZV09W3RoaXMuX2V2ZW50c1t0eXBlXSxsaXN0ZW5lcl07aWYoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSYmIXRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQpe2lmKCFpc1VuZGVmaW5lZCh0aGlzLl9tYXhMaXN0ZW5lcnMpKXttPXRoaXMuX21heExpc3RlbmVyc31lbHNle209RXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnN9aWYobSYmbT4wJiZ0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoPm0pe3RoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQ9dHJ1ZTtjb25zb2xlLmVycm9yKFwiKG5vZGUpIHdhcm5pbmc6IHBvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgXCIrXCJsZWFrIGRldGVjdGVkLiAlZCBsaXN0ZW5lcnMgYWRkZWQuIFwiK1wiVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gaW5jcmVhc2UgbGltaXQuXCIsdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCk7aWYodHlwZW9mIGNvbnNvbGUudHJhY2U9PT1cImZ1bmN0aW9uXCIpe2NvbnNvbGUudHJhY2UoKX19fXJldHVybiB0aGlzfTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uPUV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlPWZ1bmN0aW9uKHR5cGUsbGlzdGVuZXIpe2lmKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSl0aHJvdyBUeXBlRXJyb3IoXCJsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb25cIik7dmFyIGZpcmVkPWZhbHNlO2Z1bmN0aW9uIGcoKXt0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsZyk7aWYoIWZpcmVkKXtmaXJlZD10cnVlO2xpc3RlbmVyLmFwcGx5KHRoaXMsYXJndW1lbnRzKX19Zy5saXN0ZW5lcj1saXN0ZW5lcjt0aGlzLm9uKHR5cGUsZyk7cmV0dXJuIHRoaXN9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXI9ZnVuY3Rpb24odHlwZSxsaXN0ZW5lcil7dmFyIGxpc3QscG9zaXRpb24sbGVuZ3RoLGk7aWYoIWlzRnVuY3Rpb24obGlzdGVuZXIpKXRocm93IFR5cGVFcnJvcihcImxpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvblwiKTtpZighdGhpcy5fZXZlbnRzfHwhdGhpcy5fZXZlbnRzW3R5cGVdKXJldHVybiB0aGlzO2xpc3Q9dGhpcy5fZXZlbnRzW3R5cGVdO2xlbmd0aD1saXN0Lmxlbmd0aDtwb3NpdGlvbj0tMTtpZihsaXN0PT09bGlzdGVuZXJ8fGlzRnVuY3Rpb24obGlzdC5saXN0ZW5lcikmJmxpc3QubGlzdGVuZXI9PT1saXN0ZW5lcil7ZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtpZih0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpdGhpcy5lbWl0KFwicmVtb3ZlTGlzdGVuZXJcIix0eXBlLGxpc3RlbmVyKX1lbHNlIGlmKGlzT2JqZWN0KGxpc3QpKXtmb3IoaT1sZW5ndGg7aS0tID4wOyl7aWYobGlzdFtpXT09PWxpc3RlbmVyfHxsaXN0W2ldLmxpc3RlbmVyJiZsaXN0W2ldLmxpc3RlbmVyPT09bGlzdGVuZXIpe3Bvc2l0aW9uPWk7YnJlYWt9fWlmKHBvc2l0aW9uPDApcmV0dXJuIHRoaXM7aWYobGlzdC5sZW5ndGg9PT0xKXtsaXN0Lmxlbmd0aD0wO2RlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV19ZWxzZXtsaXN0LnNwbGljZShwb3NpdGlvbiwxKTtcbn1pZih0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpdGhpcy5lbWl0KFwicmVtb3ZlTGlzdGVuZXJcIix0eXBlLGxpc3RlbmVyKX1yZXR1cm4gdGhpc307RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnM9ZnVuY3Rpb24odHlwZSl7dmFyIGtleSxsaXN0ZW5lcnM7aWYoIXRoaXMuX2V2ZW50cylyZXR1cm4gdGhpcztpZighdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKXtpZihhcmd1bWVudHMubGVuZ3RoPT09MCl0aGlzLl9ldmVudHM9e307ZWxzZSBpZih0aGlzLl9ldmVudHNbdHlwZV0pZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtyZXR1cm4gdGhpc31pZihhcmd1bWVudHMubGVuZ3RoPT09MCl7Zm9yKGtleSBpbiB0aGlzLl9ldmVudHMpe2lmKGtleT09PVwicmVtb3ZlTGlzdGVuZXJcIiljb250aW51ZTt0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpfXRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKFwicmVtb3ZlTGlzdGVuZXJcIik7dGhpcy5fZXZlbnRzPXt9O3JldHVybiB0aGlzfWxpc3RlbmVycz10aGlzLl9ldmVudHNbdHlwZV07aWYoaXNGdW5jdGlvbihsaXN0ZW5lcnMpKXt0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsbGlzdGVuZXJzKX1lbHNlIGlmKGxpc3RlbmVycyl7d2hpbGUobGlzdGVuZXJzLmxlbmd0aCl0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGgtMV0pfWRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07cmV0dXJuIHRoaXN9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzPWZ1bmN0aW9uKHR5cGUpe3ZhciByZXQ7aWYoIXRoaXMuX2V2ZW50c3x8IXRoaXMuX2V2ZW50c1t0eXBlXSlyZXQ9W107ZWxzZSBpZihpc0Z1bmN0aW9uKHRoaXMuX2V2ZW50c1t0eXBlXSkpcmV0PVt0aGlzLl9ldmVudHNbdHlwZV1dO2Vsc2UgcmV0PXRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO3JldHVybiByZXR9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudD1mdW5jdGlvbih0eXBlKXtpZih0aGlzLl9ldmVudHMpe3ZhciBldmxpc3RlbmVyPXRoaXMuX2V2ZW50c1t0eXBlXTtpZihpc0Z1bmN0aW9uKGV2bGlzdGVuZXIpKXJldHVybiAxO2Vsc2UgaWYoZXZsaXN0ZW5lcilyZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGh9cmV0dXJuIDB9O0V2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50PWZ1bmN0aW9uKGVtaXR0ZXIsdHlwZSl7cmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJDb3VudCh0eXBlKX07ZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJmdW5jdGlvblwifWZ1bmN0aW9uIGlzTnVtYmVyKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cIm51bWJlclwifWZ1bmN0aW9uIGlzT2JqZWN0KGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cIm9iamVjdFwiJiZhcmchPT1udWxsfWZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZyl7cmV0dXJuIGFyZz09PXZvaWQgMH19LHt9XSwyOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9Q29sbGVjdGluZ0hhbmRsZXI7ZnVuY3Rpb24gQ29sbGVjdGluZ0hhbmRsZXIoY2JzKXt0aGlzLl9jYnM9Y2JzfHx7fTt0aGlzLmV2ZW50cz1bXX12YXIgRVZFTlRTPXJlcXVpcmUoXCIuL1wiKS5FVkVOVFM7T2JqZWN0LmtleXMoRVZFTlRTKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpe2lmKEVWRU5UU1tuYW1lXT09PTApe25hbWU9XCJvblwiK25hbWU7Q29sbGVjdGluZ0hhbmRsZXIucHJvdG90eXBlW25hbWVdPWZ1bmN0aW9uKCl7dGhpcy5ldmVudHMucHVzaChbbmFtZV0pO2lmKHRoaXMuX2Nic1tuYW1lXSl0aGlzLl9jYnNbbmFtZV0oKX19ZWxzZSBpZihFVkVOVFNbbmFtZV09PT0xKXtuYW1lPVwib25cIituYW1lO0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZVtuYW1lXT1mdW5jdGlvbihhKXt0aGlzLmV2ZW50cy5wdXNoKFtuYW1lLGFdKTtpZih0aGlzLl9jYnNbbmFtZV0pdGhpcy5fY2JzW25hbWVdKGEpfX1lbHNlIGlmKEVWRU5UU1tuYW1lXT09PTIpe25hbWU9XCJvblwiK25hbWU7Q29sbGVjdGluZ0hhbmRsZXIucHJvdG90eXBlW25hbWVdPWZ1bmN0aW9uKGEsYil7dGhpcy5ldmVudHMucHVzaChbbmFtZSxhLGJdKTtpZih0aGlzLl9jYnNbbmFtZV0pdGhpcy5fY2JzW25hbWVdKGEsYil9fWVsc2V7dGhyb3cgRXJyb3IoXCJ3cm9uZyBudW1iZXIgb2YgYXJndW1lbnRzXCIpfX0pO0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZS5vbnJlc2V0PWZ1bmN0aW9uKCl7dGhpcy5ldmVudHM9W107aWYodGhpcy5fY2JzLm9ucmVzZXQpdGhpcy5fY2JzLm9ucmVzZXQoKX07Q29sbGVjdGluZ0hhbmRsZXIucHJvdG90eXBlLnJlc3RhcnQ9ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnMub25yZXNldCl0aGlzLl9jYnMub25yZXNldCgpO2Zvcih2YXIgaT0wLGxlbj10aGlzLmV2ZW50cy5sZW5ndGg7aTxsZW47aSsrKXtpZih0aGlzLl9jYnNbdGhpcy5ldmVudHNbaV1bMF1dKXt2YXIgbnVtPXRoaXMuZXZlbnRzW2ldLmxlbmd0aDtpZihudW09PT0xKXt0aGlzLl9jYnNbdGhpcy5ldmVudHNbaV1bMF1dKCl9ZWxzZSBpZihudW09PT0yKXt0aGlzLl9jYnNbdGhpcy5ldmVudHNbaV1bMF1dKHRoaXMuZXZlbnRzW2ldWzFdKX1lbHNle3RoaXMuX2Nic1t0aGlzLmV2ZW50c1tpXVswXV0odGhpcy5ldmVudHNbaV1bMV0sdGhpcy5ldmVudHNbaV1bMl0pfX19fX0se1wiLi9cIjozNn1dLDMwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgaW5kZXg9cmVxdWlyZShcIi4vaW5kZXguanNcIiksRG9tSGFuZGxlcj1pbmRleC5Eb21IYW5kbGVyLERvbVV0aWxzPWluZGV4LkRvbVV0aWxzO2Z1bmN0aW9uIEZlZWRIYW5kbGVyKGNhbGxiYWNrLG9wdGlvbnMpe3RoaXMuaW5pdChjYWxsYmFjayxvcHRpb25zKX1yZXF1aXJlKFwiaW5oZXJpdHNcIikoRmVlZEhhbmRsZXIsRG9tSGFuZGxlcik7RmVlZEhhbmRsZXIucHJvdG90eXBlLmluaXQ9RG9tSGFuZGxlcjtmdW5jdGlvbiBnZXRFbGVtZW50cyh3aGF0LHdoZXJlKXtyZXR1cm4gRG9tVXRpbHMuZ2V0RWxlbWVudHNCeVRhZ05hbWUod2hhdCx3aGVyZSx0cnVlKX1mdW5jdGlvbiBnZXRPbmVFbGVtZW50KHdoYXQsd2hlcmUpe3JldHVybiBEb21VdGlscy5nZXRFbGVtZW50c0J5VGFnTmFtZSh3aGF0LHdoZXJlLHRydWUsMSlbMF19ZnVuY3Rpb24gZmV0Y2god2hhdCx3aGVyZSxyZWN1cnNlKXtyZXR1cm4gRG9tVXRpbHMuZ2V0VGV4dChEb21VdGlscy5nZXRFbGVtZW50c0J5VGFnTmFtZSh3aGF0LHdoZXJlLHJlY3Vyc2UsMSkpLnRyaW0oKX1mdW5jdGlvbiBhZGRDb25kaXRpb25hbGx5KG9iaixwcm9wLHdoYXQsd2hlcmUscmVjdXJzZSl7dmFyIHRtcD1mZXRjaCh3aGF0LHdoZXJlLHJlY3Vyc2UpO2lmKHRtcClvYmpbcHJvcF09dG1wfXZhciBpc1ZhbGlkRmVlZD1mdW5jdGlvbih2YWx1ZSl7cmV0dXJuIHZhbHVlPT09XCJyc3NcInx8dmFsdWU9PT1cImZlZWRcInx8dmFsdWU9PT1cInJkZjpSREZcIn07RmVlZEhhbmRsZXIucHJvdG90eXBlLm9uZW5kPWZ1bmN0aW9uKCl7dmFyIGZlZWQ9e30sZmVlZFJvb3Q9Z2V0T25lRWxlbWVudChpc1ZhbGlkRmVlZCx0aGlzLmRvbSksdG1wLGNoaWxkcztpZihmZWVkUm9vdCl7aWYoZmVlZFJvb3QubmFtZT09PVwiZmVlZFwiKXtjaGlsZHM9ZmVlZFJvb3QuY2hpbGRyZW47ZmVlZC50eXBlPVwiYXRvbVwiO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcImlkXCIsXCJpZFwiLGNoaWxkcyk7YWRkQ29uZGl0aW9uYWxseShmZWVkLFwidGl0bGVcIixcInRpdGxlXCIsY2hpbGRzKTtpZigodG1wPWdldE9uZUVsZW1lbnQoXCJsaW5rXCIsY2hpbGRzKSkmJih0bXA9dG1wLmF0dHJpYnMpJiYodG1wPXRtcC5ocmVmKSlmZWVkLmxpbms9dG1wO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcImRlc2NyaXB0aW9uXCIsXCJzdWJ0aXRsZVwiLGNoaWxkcyk7aWYodG1wPWZldGNoKFwidXBkYXRlZFwiLGNoaWxkcykpZmVlZC51cGRhdGVkPW5ldyBEYXRlKHRtcCk7YWRkQ29uZGl0aW9uYWxseShmZWVkLFwiYXV0aG9yXCIsXCJlbWFpbFwiLGNoaWxkcyx0cnVlKTtmZWVkLml0ZW1zPWdldEVsZW1lbnRzKFwiZW50cnlcIixjaGlsZHMpLm1hcChmdW5jdGlvbihpdGVtKXt2YXIgZW50cnk9e30sdG1wO2l0ZW09aXRlbS5jaGlsZHJlbjthZGRDb25kaXRpb25hbGx5KGVudHJ5LFwiaWRcIixcImlkXCIsaXRlbSk7YWRkQ29uZGl0aW9uYWxseShlbnRyeSxcInRpdGxlXCIsXCJ0aXRsZVwiLGl0ZW0pO2lmKCh0bXA9Z2V0T25lRWxlbWVudChcImxpbmtcIixpdGVtKSkmJih0bXA9dG1wLmF0dHJpYnMpJiYodG1wPXRtcC5ocmVmKSllbnRyeS5saW5rPXRtcDtpZih0bXA9ZmV0Y2goXCJzdW1tYXJ5XCIsaXRlbSl8fGZldGNoKFwiY29udGVudFwiLGl0ZW0pKWVudHJ5LmRlc2NyaXB0aW9uPXRtcDtpZih0bXA9ZmV0Y2goXCJ1cGRhdGVkXCIsaXRlbSkpZW50cnkucHViRGF0ZT1uZXcgRGF0ZSh0bXApO3JldHVybiBlbnRyeX0pfWVsc2V7Y2hpbGRzPWdldE9uZUVsZW1lbnQoXCJjaGFubmVsXCIsZmVlZFJvb3QuY2hpbGRyZW4pLmNoaWxkcmVuO2ZlZWQudHlwZT1mZWVkUm9vdC5uYW1lLnN1YnN0cigwLDMpO2ZlZWQuaWQ9XCJcIjthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJ0aXRsZVwiLFwidGl0bGVcIixjaGlsZHMpO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcImxpbmtcIixcImxpbmtcIixjaGlsZHMpO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcImRlc2NyaXB0aW9uXCIsXCJkZXNjcmlwdGlvblwiLGNoaWxkcyk7aWYodG1wPWZldGNoKFwibGFzdEJ1aWxkRGF0ZVwiLGNoaWxkcykpZmVlZC51cGRhdGVkPW5ldyBEYXRlKHRtcCk7YWRkQ29uZGl0aW9uYWxseShmZWVkLFwiYXV0aG9yXCIsXCJtYW5hZ2luZ0VkaXRvclwiLGNoaWxkcyx0cnVlKTtmZWVkLml0ZW1zPWdldEVsZW1lbnRzKFwiaXRlbVwiLGZlZWRSb290LmNoaWxkcmVuKS5tYXAoZnVuY3Rpb24oaXRlbSl7dmFyIGVudHJ5PXt9LHRtcDtpdGVtPWl0ZW0uY2hpbGRyZW47YWRkQ29uZGl0aW9uYWxseShlbnRyeSxcImlkXCIsXCJndWlkXCIsaXRlbSk7YWRkQ29uZGl0aW9uYWxseShlbnRyeSxcInRpdGxlXCIsXCJ0aXRsZVwiLGl0ZW0pO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJsaW5rXCIsXCJsaW5rXCIsaXRlbSk7YWRkQ29uZGl0aW9uYWxseShlbnRyeSxcImRlc2NyaXB0aW9uXCIsXCJkZXNjcmlwdGlvblwiLGl0ZW0pO2lmKHRtcD1mZXRjaChcInB1YkRhdGVcIixpdGVtKSllbnRyeS5wdWJEYXRlPW5ldyBEYXRlKHRtcCk7cmV0dXJuIGVudHJ5fSl9fXRoaXMuZG9tPWZlZWQ7RG9tSGFuZGxlci5wcm90b3R5cGUuX2hhbmRsZUNhbGxiYWNrLmNhbGwodGhpcyxmZWVkUm9vdD9udWxsOkVycm9yKFwiY291bGRuJ3QgZmluZCByb290IG9mIGZlZWRcIikpfTttb2R1bGUuZXhwb3J0cz1GZWVkSGFuZGxlcn0se1wiLi9pbmRleC5qc1wiOjM2LGluaGVyaXRzOjM4fV0sMzE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBUb2tlbml6ZXI9cmVxdWlyZShcIi4vVG9rZW5pemVyLmpzXCIpO3ZhciBmb3JtVGFncz17aW5wdXQ6dHJ1ZSxvcHRpb246dHJ1ZSxvcHRncm91cDp0cnVlLHNlbGVjdDp0cnVlLGJ1dHRvbjp0cnVlLGRhdGFsaXN0OnRydWUsdGV4dGFyZWE6dHJ1ZX07dmFyIG9wZW5JbXBsaWVzQ2xvc2U9e3RyOnt0cjp0cnVlLHRoOnRydWUsdGQ6dHJ1ZX0sdGg6e3RoOnRydWV9LHRkOnt0aGVhZDp0cnVlLHRoOnRydWUsdGQ6dHJ1ZX0sYm9keTp7aGVhZDp0cnVlLGxpbms6dHJ1ZSxzY3JpcHQ6dHJ1ZX0sbGk6e2xpOnRydWV9LHA6e3A6dHJ1ZX0saDE6e3A6dHJ1ZX0saDI6e3A6dHJ1ZX0saDM6e3A6dHJ1ZX0saDQ6e3A6dHJ1ZX0saDU6e3A6dHJ1ZX0saDY6e3A6dHJ1ZX0sc2VsZWN0OmZvcm1UYWdzLGlucHV0OmZvcm1UYWdzLG91dHB1dDpmb3JtVGFncyxidXR0b246Zm9ybVRhZ3MsZGF0YWxpc3Q6Zm9ybVRhZ3MsdGV4dGFyZWE6Zm9ybVRhZ3Msb3B0aW9uOntvcHRpb246dHJ1ZX0sb3B0Z3JvdXA6e29wdGdyb3VwOnRydWV9fTt2YXIgdm9pZEVsZW1lbnRzPXtfX3Byb3RvX186bnVsbCxhcmVhOnRydWUsYmFzZTp0cnVlLGJhc2Vmb250OnRydWUsYnI6dHJ1ZSxjb2w6dHJ1ZSxjb21tYW5kOnRydWUsZW1iZWQ6dHJ1ZSxmcmFtZTp0cnVlLGhyOnRydWUsaW1nOnRydWUsaW5wdXQ6dHJ1ZSxpc2luZGV4OnRydWUsa2V5Z2VuOnRydWUsbGluazp0cnVlLG1ldGE6dHJ1ZSxwYXJhbTp0cnVlLHNvdXJjZTp0cnVlLHRyYWNrOnRydWUsd2JyOnRydWUscGF0aDp0cnVlLGNpcmNsZTp0cnVlLGVsbGlwc2U6dHJ1ZSxsaW5lOnRydWUscmVjdDp0cnVlLHVzZTp0cnVlLHN0b3A6dHJ1ZSxwb2x5bGluZTp0cnVlLHBvbHlnb246dHJ1ZX07dmFyIHJlX25hbWVFbmQ9L1xcc3xcXC8vO2Z1bmN0aW9uIFBhcnNlcihjYnMsb3B0aW9ucyl7dGhpcy5fb3B0aW9ucz1vcHRpb25zfHx7fTt0aGlzLl9jYnM9Y2JzfHx7fTt0aGlzLl90YWduYW1lPVwiXCI7dGhpcy5fYXR0cmlibmFtZT1cIlwiO3RoaXMuX2F0dHJpYnZhbHVlPVwiXCI7dGhpcy5fYXR0cmlicz1udWxsO3RoaXMuX3N0YWNrPVtdO3RoaXMuc3RhcnRJbmRleD0wO3RoaXMuZW5kSW5kZXg9bnVsbDt0aGlzLl9sb3dlckNhc2VUYWdOYW1lcz1cImxvd2VyQ2FzZVRhZ3NcImluIHRoaXMuX29wdGlvbnM/ISF0aGlzLl9vcHRpb25zLmxvd2VyQ2FzZVRhZ3M6IXRoaXMuX29wdGlvbnMueG1sTW9kZTt0aGlzLl9sb3dlckNhc2VBdHRyaWJ1dGVOYW1lcz1cImxvd2VyQ2FzZUF0dHJpYnV0ZU5hbWVzXCJpbiB0aGlzLl9vcHRpb25zPyEhdGhpcy5fb3B0aW9ucy5sb3dlckNhc2VBdHRyaWJ1dGVOYW1lczohdGhpcy5fb3B0aW9ucy54bWxNb2RlO2lmKHRoaXMuX29wdGlvbnMuVG9rZW5pemVyKXtUb2tlbml6ZXI9dGhpcy5fb3B0aW9ucy5Ub2tlbml6ZXJ9dGhpcy5fdG9rZW5pemVyPW5ldyBUb2tlbml6ZXIodGhpcy5fb3B0aW9ucyx0aGlzKTtpZih0aGlzLl9jYnMub25wYXJzZXJpbml0KXRoaXMuX2Nicy5vbnBhcnNlcmluaXQodGhpcyl9cmVxdWlyZShcImluaGVyaXRzXCIpKFBhcnNlcixyZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcik7UGFyc2VyLnByb3RvdHlwZS5fdXBkYXRlUG9zaXRpb249ZnVuY3Rpb24oaW5pdGlhbE9mZnNldCl7aWYodGhpcy5lbmRJbmRleD09PW51bGwpe2lmKHRoaXMuX3Rva2VuaXplci5fc2VjdGlvblN0YXJ0PD1pbml0aWFsT2Zmc2V0KXt0aGlzLnN0YXJ0SW5kZXg9MH1lbHNle3RoaXMuc3RhcnRJbmRleD10aGlzLl90b2tlbml6ZXIuX3NlY3Rpb25TdGFydC1pbml0aWFsT2Zmc2V0fX1lbHNlIHRoaXMuc3RhcnRJbmRleD10aGlzLmVuZEluZGV4KzE7dGhpcy5lbmRJbmRleD10aGlzLl90b2tlbml6ZXIuZ2V0QWJzb2x1dGVJbmRleCgpfTtQYXJzZXIucHJvdG90eXBlLm9udGV4dD1mdW5jdGlvbihkYXRhKXt0aGlzLl91cGRhdGVQb3NpdGlvbigxKTt0aGlzLmVuZEluZGV4LS07aWYodGhpcy5fY2JzLm9udGV4dCl0aGlzLl9jYnMub250ZXh0KGRhdGEpfTtQYXJzZXIucHJvdG90eXBlLm9ub3BlbnRhZ25hbWU9ZnVuY3Rpb24obmFtZSl7aWYodGhpcy5fbG93ZXJDYXNlVGFnTmFtZXMpe25hbWU9bmFtZS50b0xvd2VyQ2FzZSgpfXRoaXMuX3RhZ25hbWU9bmFtZTtpZighdGhpcy5fb3B0aW9ucy54bWxNb2RlJiZuYW1lIGluIG9wZW5JbXBsaWVzQ2xvc2Upe2Zvcih2YXIgZWw7KGVsPXRoaXMuX3N0YWNrW3RoaXMuX3N0YWNrLmxlbmd0aC0xXSlpbiBvcGVuSW1wbGllc0Nsb3NlW25hbWVdO3RoaXMub25jbG9zZXRhZyhlbCkpO31pZih0aGlzLl9vcHRpb25zLnhtbE1vZGV8fCEobmFtZSBpbiB2b2lkRWxlbWVudHMpKXt0aGlzLl9zdGFjay5wdXNoKG5hbWUpfWlmKHRoaXMuX2Nicy5vbm9wZW50YWduYW1lKXRoaXMuX2Nicy5vbm9wZW50YWduYW1lKG5hbWUpO2lmKHRoaXMuX2Nicy5vbm9wZW50YWcpdGhpcy5fYXR0cmlicz17fX07UGFyc2VyLnByb3RvdHlwZS5vbm9wZW50YWdlbmQ9ZnVuY3Rpb24oKXt0aGlzLl91cGRhdGVQb3NpdGlvbigxKTtpZih0aGlzLl9hdHRyaWJzKXtpZih0aGlzLl9jYnMub25vcGVudGFnKXRoaXMuX2Nicy5vbm9wZW50YWcodGhpcy5fdGFnbmFtZSx0aGlzLl9hdHRyaWJzKTt0aGlzLl9hdHRyaWJzPW51bGx9aWYoIXRoaXMuX29wdGlvbnMueG1sTW9kZSYmdGhpcy5fY2JzLm9uY2xvc2V0YWcmJnRoaXMuX3RhZ25hbWUgaW4gdm9pZEVsZW1lbnRzKXt0aGlzLl9jYnMub25jbG9zZXRhZyh0aGlzLl90YWduYW1lKX10aGlzLl90YWduYW1lPVwiXCJ9O1BhcnNlci5wcm90b3R5cGUub25jbG9zZXRhZz1mdW5jdGlvbihuYW1lKXt0aGlzLl91cGRhdGVQb3NpdGlvbigxKTtpZih0aGlzLl9sb3dlckNhc2VUYWdOYW1lcyl7bmFtZT1uYW1lLnRvTG93ZXJDYXNlKCl9aWYodGhpcy5fc3RhY2subGVuZ3RoJiYoIShuYW1lIGluIHZvaWRFbGVtZW50cyl8fHRoaXMuX29wdGlvbnMueG1sTW9kZSkpe3ZhciBwb3M9dGhpcy5fc3RhY2subGFzdEluZGV4T2YobmFtZSk7aWYocG9zIT09LTEpe2lmKHRoaXMuX2Nicy5vbmNsb3NldGFnKXtwb3M9dGhpcy5fc3RhY2subGVuZ3RoLXBvczt3aGlsZShwb3MtLSl0aGlzLl9jYnMub25jbG9zZXRhZyh0aGlzLl9zdGFjay5wb3AoKSl9ZWxzZSB0aGlzLl9zdGFjay5sZW5ndGg9cG9zfWVsc2UgaWYobmFtZT09PVwicFwiJiYhdGhpcy5fb3B0aW9ucy54bWxNb2RlKXt0aGlzLm9ub3BlbnRhZ25hbWUobmFtZSk7dGhpcy5fY2xvc2VDdXJyZW50VGFnKCl9fWVsc2UgaWYoIXRoaXMuX29wdGlvbnMueG1sTW9kZSYmKG5hbWU9PT1cImJyXCJ8fG5hbWU9PT1cInBcIikpe3RoaXMub25vcGVudGFnbmFtZShuYW1lKTt0aGlzLl9jbG9zZUN1cnJlbnRUYWcoKX19O1BhcnNlci5wcm90b3R5cGUub25zZWxmY2xvc2luZ3RhZz1mdW5jdGlvbigpe2lmKHRoaXMuX29wdGlvbnMueG1sTW9kZXx8dGhpcy5fb3B0aW9ucy5yZWNvZ25pemVTZWxmQ2xvc2luZyl7dGhpcy5fY2xvc2VDdXJyZW50VGFnKCl9ZWxzZXt0aGlzLm9ub3BlbnRhZ2VuZCgpfX07UGFyc2VyLnByb3RvdHlwZS5fY2xvc2VDdXJyZW50VGFnPWZ1bmN0aW9uKCl7dmFyIG5hbWU9dGhpcy5fdGFnbmFtZTt0aGlzLm9ub3BlbnRhZ2VuZCgpO2lmKHRoaXMuX3N0YWNrW3RoaXMuX3N0YWNrLmxlbmd0aC0xXT09PW5hbWUpe2lmKHRoaXMuX2Nicy5vbmNsb3NldGFnKXt0aGlzLl9jYnMub25jbG9zZXRhZyhuYW1lKX10aGlzLl9zdGFjay5wb3AoKX19O1BhcnNlci5wcm90b3R5cGUub25hdHRyaWJuYW1lPWZ1bmN0aW9uKG5hbWUpe2lmKHRoaXMuX2xvd2VyQ2FzZUF0dHJpYnV0ZU5hbWVzKXtuYW1lPW5hbWUudG9Mb3dlckNhc2UoKX10aGlzLl9hdHRyaWJuYW1lPW5hbWV9O1BhcnNlci5wcm90b3R5cGUub25hdHRyaWJkYXRhPWZ1bmN0aW9uKHZhbHVlKXt0aGlzLl9hdHRyaWJ2YWx1ZSs9dmFsdWV9O1BhcnNlci5wcm90b3R5cGUub25hdHRyaWJlbmQ9ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnMub25hdHRyaWJ1dGUpdGhpcy5fY2JzLm9uYXR0cmlidXRlKHRoaXMuX2F0dHJpYm5hbWUsdGhpcy5fYXR0cmlidmFsdWUpO2lmKHRoaXMuX2F0dHJpYnMmJiFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5fYXR0cmlicyx0aGlzLl9hdHRyaWJuYW1lKSl7dGhpcy5fYXR0cmlic1t0aGlzLl9hdHRyaWJuYW1lXT10aGlzLl9hdHRyaWJ2YWx1ZX10aGlzLl9hdHRyaWJuYW1lPVwiXCI7dGhpcy5fYXR0cmlidmFsdWU9XCJcIn07UGFyc2VyLnByb3RvdHlwZS5fZ2V0SW5zdHJ1Y3Rpb25OYW1lPWZ1bmN0aW9uKHZhbHVlKXt2YXIgaWR4PXZhbHVlLnNlYXJjaChyZV9uYW1lRW5kKSxuYW1lPWlkeDwwP3ZhbHVlOnZhbHVlLnN1YnN0cigwLGlkeCk7aWYodGhpcy5fbG93ZXJDYXNlVGFnTmFtZXMpe25hbWU9bmFtZS50b0xvd2VyQ2FzZSgpfXJldHVybiBuYW1lfTtQYXJzZXIucHJvdG90eXBlLm9uZGVjbGFyYXRpb249ZnVuY3Rpb24odmFsdWUpe2lmKHRoaXMuX2Nicy5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbil7dmFyIG5hbWU9dGhpcy5fZ2V0SW5zdHJ1Y3Rpb25OYW1lKHZhbHVlKTt0aGlzLl9jYnMub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24oXCIhXCIrbmFtZSxcIiFcIit2YWx1ZSl9fTtQYXJzZXIucHJvdG90eXBlLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uPWZ1bmN0aW9uKHZhbHVlKXtpZih0aGlzLl9jYnMub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24pe3ZhciBuYW1lPXRoaXMuX2dldEluc3RydWN0aW9uTmFtZSh2YWx1ZSk7dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKFwiP1wiK25hbWUsXCI/XCIrdmFsdWUpfX07UGFyc2VyLnByb3RvdHlwZS5vbmNvbW1lbnQ9ZnVuY3Rpb24odmFsdWUpe3RoaXMuX3VwZGF0ZVBvc2l0aW9uKDQpO2lmKHRoaXMuX2Nicy5vbmNvbW1lbnQpdGhpcy5fY2JzLm9uY29tbWVudCh2YWx1ZSk7aWYodGhpcy5fY2JzLm9uY29tbWVudGVuZCl0aGlzLl9jYnMub25jb21tZW50ZW5kKCl9O1BhcnNlci5wcm90b3R5cGUub25jZGF0YT1mdW5jdGlvbih2YWx1ZSl7dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7aWYodGhpcy5fb3B0aW9ucy54bWxNb2RlfHx0aGlzLl9vcHRpb25zLnJlY29nbml6ZUNEQVRBKXtpZih0aGlzLl9jYnMub25jZGF0YXN0YXJ0KXRoaXMuX2Nicy5vbmNkYXRhc3RhcnQoKTtpZih0aGlzLl9jYnMub250ZXh0KXRoaXMuX2Nicy5vbnRleHQodmFsdWUpO2lmKHRoaXMuX2Nicy5vbmNkYXRhZW5kKXRoaXMuX2Nicy5vbmNkYXRhZW5kKCl9ZWxzZXt0aGlzLm9uY29tbWVudChcIltDREFUQVtcIit2YWx1ZStcIl1dXCIpfX07UGFyc2VyLnByb3RvdHlwZS5vbmVycm9yPWZ1bmN0aW9uKGVycil7aWYodGhpcy5fY2JzLm9uZXJyb3IpdGhpcy5fY2JzLm9uZXJyb3IoZXJyKX07UGFyc2VyLnByb3RvdHlwZS5vbmVuZD1mdW5jdGlvbigpe2lmKHRoaXMuX2Nicy5vbmNsb3NldGFnKXtmb3IodmFyIGk9dGhpcy5fc3RhY2subGVuZ3RoO2k+MDt0aGlzLl9jYnMub25jbG9zZXRhZyh0aGlzLl9zdGFja1stLWldKSk7fWlmKHRoaXMuX2Nicy5vbmVuZCl0aGlzLl9jYnMub25lbmQoKX07UGFyc2VyLnByb3RvdHlwZS5yZXNldD1mdW5jdGlvbigpe2lmKHRoaXMuX2Nicy5vbnJlc2V0KXRoaXMuX2Nicy5vbnJlc2V0KCk7dGhpcy5fdG9rZW5pemVyLnJlc2V0KCk7dGhpcy5fdGFnbmFtZT1cIlwiO3RoaXMuX2F0dHJpYm5hbWU9XCJcIjt0aGlzLl9hdHRyaWJzPW51bGw7dGhpcy5fc3RhY2s9W107aWYodGhpcy5fY2JzLm9ucGFyc2VyaW5pdCl0aGlzLl9jYnMub25wYXJzZXJpbml0KHRoaXMpfTtQYXJzZXIucHJvdG90eXBlLnBhcnNlQ29tcGxldGU9ZnVuY3Rpb24oZGF0YSl7dGhpcy5yZXNldCgpO3RoaXMuZW5kKGRhdGEpfTtQYXJzZXIucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKGNodW5rKXt0aGlzLl90b2tlbml6ZXIud3JpdGUoY2h1bmspfTtQYXJzZXIucHJvdG90eXBlLmVuZD1mdW5jdGlvbihjaHVuayl7dGhpcy5fdG9rZW5pemVyLmVuZChjaHVuayl9O1BhcnNlci5wcm90b3R5cGUucGF1c2U9ZnVuY3Rpb24oKXt0aGlzLl90b2tlbml6ZXIucGF1c2UoKX07UGFyc2VyLnByb3RvdHlwZS5yZXN1bWU9ZnVuY3Rpb24oKXt0aGlzLl90b2tlbml6ZXIucmVzdW1lKCl9O1BhcnNlci5wcm90b3R5cGUucGFyc2VDaHVuaz1QYXJzZXIucHJvdG90eXBlLndyaXRlO1BhcnNlci5wcm90b3R5cGUuZG9uZT1QYXJzZXIucHJvdG90eXBlLmVuZDttb2R1bGUuZXhwb3J0cz1QYXJzZXJ9LHtcIi4vVG9rZW5pemVyLmpzXCI6MzQsZXZlbnRzOjI4LGluaGVyaXRzOjM4fV0sMzI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPVByb3h5SGFuZGxlcjtmdW5jdGlvbiBQcm94eUhhbmRsZXIoY2JzKXt0aGlzLl9jYnM9Y2JzfHx7fX12YXIgRVZFTlRTPXJlcXVpcmUoXCIuL1wiKS5FVkVOVFM7T2JqZWN0LmtleXMoRVZFTlRTKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpe2lmKEVWRU5UU1tuYW1lXT09PTApe25hbWU9XCJvblwiK25hbWU7UHJveHlIYW5kbGVyLnByb3RvdHlwZVtuYW1lXT1mdW5jdGlvbigpe2lmKHRoaXMuX2Nic1tuYW1lXSl0aGlzLl9jYnNbbmFtZV0oKX19ZWxzZSBpZihFVkVOVFNbbmFtZV09PT0xKXtuYW1lPVwib25cIituYW1lO1Byb3h5SGFuZGxlci5wcm90b3R5cGVbbmFtZV09ZnVuY3Rpb24oYSl7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXShhKX19ZWxzZSBpZihFVkVOVFNbbmFtZV09PT0yKXtuYW1lPVwib25cIituYW1lO1Byb3h5SGFuZGxlci5wcm90b3R5cGVbbmFtZV09ZnVuY3Rpb24oYSxiKXtpZih0aGlzLl9jYnNbbmFtZV0pdGhpcy5fY2JzW25hbWVdKGEsYil9fWVsc2V7dGhyb3cgRXJyb3IoXCJ3cm9uZyBudW1iZXIgb2YgYXJndW1lbnRzXCIpfX0pfSx7XCIuL1wiOjM2fV0sMzM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPVN0cmVhbTt2YXIgUGFyc2VyPXJlcXVpcmUoXCIuL1dyaXRhYmxlU3RyZWFtLmpzXCIpO2Z1bmN0aW9uIFN0cmVhbShvcHRpb25zKXtQYXJzZXIuY2FsbCh0aGlzLG5ldyBDYnModGhpcyksb3B0aW9ucyl9cmVxdWlyZShcImluaGVyaXRzXCIpKFN0cmVhbSxQYXJzZXIpO1N0cmVhbS5wcm90b3R5cGUucmVhZGFibGU9dHJ1ZTtmdW5jdGlvbiBDYnMoc2NvcGUpe3RoaXMuc2NvcGU9c2NvcGV9dmFyIEVWRU5UUz1yZXF1aXJlKFwiLi4vXCIpLkVWRU5UUztPYmplY3Qua2V5cyhFVkVOVFMpLmZvckVhY2goZnVuY3Rpb24obmFtZSl7aWYoRVZFTlRTW25hbWVdPT09MCl7Q2JzLnByb3RvdHlwZVtcIm9uXCIrbmFtZV09ZnVuY3Rpb24oKXt0aGlzLnNjb3BlLmVtaXQobmFtZSl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09MSl7Q2JzLnByb3RvdHlwZVtcIm9uXCIrbmFtZV09ZnVuY3Rpb24oYSl7dGhpcy5zY29wZS5lbWl0KG5hbWUsYSl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09Mil7Q2JzLnByb3RvdHlwZVtcIm9uXCIrbmFtZV09ZnVuY3Rpb24oYSxiKXt0aGlzLnNjb3BlLmVtaXQobmFtZSxhLGIpfX1lbHNle3Rocm93IEVycm9yKFwid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50cyFcIil9fSl9LHtcIi4uL1wiOjM2LFwiLi9Xcml0YWJsZVN0cmVhbS5qc1wiOjM1LGluaGVyaXRzOjM4fV0sMzQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPVRva2VuaXplcjt2YXIgZGVjb2RlQ29kZVBvaW50PXJlcXVpcmUoXCJlbnRpdGllcy9saWIvZGVjb2RlX2NvZGVwb2ludC5qc1wiKSxlbnRpdHlNYXA9cmVxdWlyZShcImVudGl0aWVzL21hcHMvZW50aXRpZXMuanNvblwiKSxsZWdhY3lNYXA9cmVxdWlyZShcImVudGl0aWVzL21hcHMvbGVnYWN5Lmpzb25cIikseG1sTWFwPXJlcXVpcmUoXCJlbnRpdGllcy9tYXBzL3htbC5qc29uXCIpLGk9MCxURVhUPWkrKyxCRUZPUkVfVEFHX05BTUU9aSsrLElOX1RBR19OQU1FPWkrKyxJTl9TRUxGX0NMT1NJTkdfVEFHPWkrKyxCRUZPUkVfQ0xPU0lOR19UQUdfTkFNRT1pKyssSU5fQ0xPU0lOR19UQUdfTkFNRT1pKyssQUZURVJfQ0xPU0lOR19UQUdfTkFNRT1pKyssQkVGT1JFX0FUVFJJQlVURV9OQU1FPWkrKyxJTl9BVFRSSUJVVEVfTkFNRT1pKyssQUZURVJfQVRUUklCVVRFX05BTUU9aSsrLEJFRk9SRV9BVFRSSUJVVEVfVkFMVUU9aSsrLElOX0FUVFJJQlVURV9WQUxVRV9EUT1pKyssSU5fQVRUUklCVVRFX1ZBTFVFX1NRPWkrKyxJTl9BVFRSSUJVVEVfVkFMVUVfTlE9aSsrLEJFRk9SRV9ERUNMQVJBVElPTj1pKyssSU5fREVDTEFSQVRJT049aSsrLElOX1BST0NFU1NJTkdfSU5TVFJVQ1RJT049aSsrLEJFRk9SRV9DT01NRU5UPWkrKyxJTl9DT01NRU5UPWkrKyxBRlRFUl9DT01NRU5UXzE9aSsrLEFGVEVSX0NPTU1FTlRfMj1pKyssQkVGT1JFX0NEQVRBXzE9aSsrLEJFRk9SRV9DREFUQV8yPWkrKyxCRUZPUkVfQ0RBVEFfMz1pKyssQkVGT1JFX0NEQVRBXzQ9aSsrLEJFRk9SRV9DREFUQV81PWkrKyxCRUZPUkVfQ0RBVEFfNj1pKyssSU5fQ0RBVEE9aSsrLEFGVEVSX0NEQVRBXzE9aSsrLEFGVEVSX0NEQVRBXzI9aSsrLEJFRk9SRV9TUEVDSUFMPWkrKyxCRUZPUkVfU1BFQ0lBTF9FTkQ9aSsrLEJFRk9SRV9TQ1JJUFRfMT1pKyssQkVGT1JFX1NDUklQVF8yPWkrKyxCRUZPUkVfU0NSSVBUXzM9aSsrLEJFRk9SRV9TQ1JJUFRfND1pKyssQkVGT1JFX1NDUklQVF81PWkrKyxBRlRFUl9TQ1JJUFRfMT1pKyssQUZURVJfU0NSSVBUXzI9aSsrLEFGVEVSX1NDUklQVF8zPWkrKyxBRlRFUl9TQ1JJUFRfND1pKyssQUZURVJfU0NSSVBUXzU9aSsrLEJFRk9SRV9TVFlMRV8xPWkrKyxCRUZPUkVfU1RZTEVfMj1pKyssQkVGT1JFX1NUWUxFXzM9aSsrLEJFRk9SRV9TVFlMRV80PWkrKyxBRlRFUl9TVFlMRV8xPWkrKyxBRlRFUl9TVFlMRV8yPWkrKyxBRlRFUl9TVFlMRV8zPWkrKyxBRlRFUl9TVFlMRV80PWkrKyxCRUZPUkVfRU5USVRZPWkrKyxCRUZPUkVfTlVNRVJJQ19FTlRJVFk9aSsrLElOX05BTUVEX0VOVElUWT1pKyssSU5fTlVNRVJJQ19FTlRJVFk9aSsrLElOX0hFWF9FTlRJVFk9aSsrLGo9MCxTUEVDSUFMX05PTkU9aisrLFNQRUNJQUxfU0NSSVBUPWorKyxTUEVDSUFMX1NUWUxFPWorKztmdW5jdGlvbiB3aGl0ZXNwYWNlKGMpe3JldHVybiBjPT09XCIgXCJ8fGM9PT1cIlxcblwifHxjPT09XCJcXHRcInx8Yz09PVwiXFxmXCJ8fGM9PT1cIlxcclwifWZ1bmN0aW9uIGNoYXJhY3RlclN0YXRlKGNoYXIsU1VDQ0VTUyl7cmV0dXJuIGZ1bmN0aW9uKGMpe2lmKGM9PT1jaGFyKXRoaXMuX3N0YXRlPVNVQ0NFU1N9fWZ1bmN0aW9uIGlmRWxzZVN0YXRlKHVwcGVyLFNVQ0NFU1MsRkFJTFVSRSl7dmFyIGxvd2VyPXVwcGVyLnRvTG93ZXJDYXNlKCk7aWYodXBwZXI9PT1sb3dlcil7cmV0dXJuIGZ1bmN0aW9uKGMpe2lmKGM9PT1sb3dlcil7dGhpcy5fc3RhdGU9U1VDQ0VTU31lbHNle3RoaXMuX3N0YXRlPUZBSUxVUkU7dGhpcy5faW5kZXgtLX19fWVsc2V7cmV0dXJuIGZ1bmN0aW9uKGMpe2lmKGM9PT1sb3dlcnx8Yz09PXVwcGVyKXt0aGlzLl9zdGF0ZT1TVUNDRVNTfWVsc2V7dGhpcy5fc3RhdGU9RkFJTFVSRTt0aGlzLl9pbmRleC0tfX19fWZ1bmN0aW9uIGNvbnN1bWVTcGVjaWFsTmFtZUNoYXIodXBwZXIsTkVYVF9TVEFURSl7dmFyIGxvd2VyPXVwcGVyLnRvTG93ZXJDYXNlKCk7cmV0dXJuIGZ1bmN0aW9uKGMpe2lmKGM9PT1sb3dlcnx8Yz09PXVwcGVyKXt0aGlzLl9zdGF0ZT1ORVhUX1NUQVRFfWVsc2V7dGhpcy5fc3RhdGU9SU5fVEFHX05BTUU7dGhpcy5faW5kZXgtLX19fWZ1bmN0aW9uIFRva2VuaXplcihvcHRpb25zLGNicyl7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9idWZmZXI9XCJcIjt0aGlzLl9zZWN0aW9uU3RhcnQ9MDt0aGlzLl9pbmRleD0wO3RoaXMuX2J1ZmZlck9mZnNldD0wO3RoaXMuX2Jhc2VTdGF0ZT1URVhUO3RoaXMuX3NwZWNpYWw9U1BFQ0lBTF9OT05FO3RoaXMuX2Nicz1jYnM7dGhpcy5fcnVubmluZz10cnVlO3RoaXMuX2VuZGVkPWZhbHNlO3RoaXMuX3htbE1vZGU9ISEob3B0aW9ucyYmb3B0aW9ucy54bWxNb2RlKTt0aGlzLl9kZWNvZGVFbnRpdGllcz0hIShvcHRpb25zJiZvcHRpb25zLmRlY29kZUVudGl0aWVzKX1Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZVRleHQ9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPFwiKXtpZih0aGlzLl9pbmRleD50aGlzLl9zZWN0aW9uU3RhcnQpe3RoaXMuX2Nicy5vbnRleHQodGhpcy5fZ2V0U2VjdGlvbigpKX10aGlzLl9zdGF0ZT1CRUZPUkVfVEFHX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fWVsc2UgaWYodGhpcy5fZGVjb2RlRW50aXRpZXMmJnRoaXMuX3NwZWNpYWw9PT1TUEVDSUFMX05PTkUmJmM9PT1cIiZcIil7aWYodGhpcy5faW5kZXg+dGhpcy5fc2VjdGlvblN0YXJ0KXt0aGlzLl9jYnMub250ZXh0KHRoaXMuX2dldFNlY3Rpb24oKSl9dGhpcy5fYmFzZVN0YXRlPVRFWFQ7dGhpcy5fc3RhdGU9QkVGT1JFX0VOVElUWTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVRhZ05hbWU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiL1wiKXt0aGlzLl9zdGF0ZT1CRUZPUkVfQ0xPU0lOR19UQUdfTkFNRX1lbHNlIGlmKGM9PT1cIjxcIil7dGhpcy5fY2JzLm9udGV4dCh0aGlzLl9nZXRTZWN0aW9uKCkpO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH1lbHNlIGlmKGM9PT1cIj5cInx8dGhpcy5fc3BlY2lhbCE9PVNQRUNJQUxfTk9ORXx8d2hpdGVzcGFjZShjKSl7dGhpcy5fc3RhdGU9VEVYVH1lbHNlIGlmKGM9PT1cIiFcIil7dGhpcy5fc3RhdGU9QkVGT1JFX0RFQ0xBUkFUSU9OO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoYz09PVwiP1wiKXt0aGlzLl9zdGF0ZT1JTl9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2V7dGhpcy5fc3RhdGU9IXRoaXMuX3htbE1vZGUmJihjPT09XCJzXCJ8fGM9PT1cIlNcIik/QkVGT1JFX1NQRUNJQUw6SU5fVEFHX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJblRhZ05hbWU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiL1wifHxjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX2VtaXRUb2tlbihcIm9ub3BlbnRhZ25hbWVcIik7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNsb3NlaW5nVGFnTmFtZT1mdW5jdGlvbihjKXtpZih3aGl0ZXNwYWNlKGMpKTtlbHNlIGlmKGM9PT1cIj5cIil7dGhpcy5fc3RhdGU9VEVYVH1lbHNlIGlmKHRoaXMuX3NwZWNpYWwhPT1TUEVDSUFMX05PTkUpe2lmKGM9PT1cInNcInx8Yz09PVwiU1wiKXt0aGlzLl9zdGF0ZT1CRUZPUkVfU1BFQ0lBTF9FTkR9ZWxzZXt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX2luZGV4LS19fWVsc2V7dGhpcy5fc3RhdGU9SU5fQ0xPU0lOR19UQUdfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluQ2xvc2VpbmdUYWdOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fZW1pdFRva2VuKFwib25jbG9zZXRhZ1wiKTt0aGlzLl9zdGF0ZT1BRlRFUl9DTE9TSU5HX1RBR19OQU1FO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ2xvc2VpbmdUYWdOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQXR0cmlidXRlTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI+XCIpe3RoaXMuX2Nicy5vbm9wZW50YWdlbmQoKTt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoYz09PVwiL1wiKXt0aGlzLl9zdGF0ZT1JTl9TRUxGX0NMT1NJTkdfVEFHfWVsc2UgaWYoIXdoaXRlc3BhY2UoYykpe3RoaXMuX3N0YXRlPUlOX0FUVFJJQlVURV9OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5TZWxmQ2xvc2luZ1RhZz1mdW5jdGlvbihjKXtpZihjPT09XCI+XCIpe3RoaXMuX2Nicy5vbnNlbGZjbG9zaW5ndGFnKCk7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKCF3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zdGF0ZT1CRUZPUkVfQVRUUklCVVRFX05BTUU7dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5BdHRyaWJ1dGVOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj1cInx8Yz09PVwiL1wifHxjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX2Nicy5vbmF0dHJpYm5hbWUodGhpcy5fZ2V0U2VjdGlvbigpKTt0aGlzLl9zZWN0aW9uU3RhcnQ9LTE7dGhpcy5fc3RhdGU9QUZURVJfQVRUUklCVVRFX05BTUU7dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJBdHRyaWJ1dGVOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj1cIil7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9WQUxVRX1lbHNlIGlmKGM9PT1cIi9cInx8Yz09PVwiPlwiKXt0aGlzLl9jYnMub25hdHRyaWJlbmQoKTt0aGlzLl9zdGF0ZT1CRUZPUkVfQVRUUklCVVRFX05BTUU7dGhpcy5faW5kZXgtLX1lbHNlIGlmKCF3aGl0ZXNwYWNlKGMpKXt0aGlzLl9jYnMub25hdHRyaWJlbmQoKTt0aGlzLl9zdGF0ZT1JTl9BVFRSSUJVVEVfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUF0dHJpYnV0ZVZhbHVlPWZ1bmN0aW9uKGMpe2lmKGM9PT0nXCInKXt0aGlzLl9zdGF0ZT1JTl9BVFRSSUJVVEVfVkFMVUVfRFE7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZihjPT09XCInXCIpe3RoaXMuX3N0YXRlPUlOX0FUVFJJQlVURV9WQUxVRV9TUTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKCF3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zdGF0ZT1JTl9BVFRSSUJVVEVfVkFMVUVfTlE7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4O3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluQXR0cmlidXRlVmFsdWVEb3VibGVRdW90ZXM9ZnVuY3Rpb24oYyl7aWYoYz09PSdcIicpe3RoaXMuX2VtaXRUb2tlbihcIm9uYXR0cmliZGF0YVwiKTt0aGlzLl9jYnMub25hdHRyaWJlbmQoKTt0aGlzLl9zdGF0ZT1CRUZPUkVfQVRUUklCVVRFX05BTUV9ZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyYmYz09PVwiJlwiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fYmFzZVN0YXRlPXRoaXMuX3N0YXRlO3RoaXMuX3N0YXRlPUJFRk9SRV9FTlRJVFk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlU2luZ2xlUXVvdGVzPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIidcIil7dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO3RoaXMuX2Nicy5vbmF0dHJpYmVuZCgpO3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfTkFNRX1lbHNlIGlmKHRoaXMuX2RlY29kZUVudGl0aWVzJiZjPT09XCImXCIpe3RoaXMuX2VtaXRUb2tlbihcIm9uYXR0cmliZGF0YVwiKTt0aGlzLl9iYXNlU3RhdGU9dGhpcy5fc3RhdGU7dGhpcy5fc3RhdGU9QkVGT1JFX0VOVElUWTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluQXR0cmlidXRlVmFsdWVOb1F1b3Rlcz1mdW5jdGlvbihjKXtpZih3aGl0ZXNwYWNlKGMpfHxjPT09XCI+XCIpe3RoaXMuX2VtaXRUb2tlbihcIm9uYXR0cmliZGF0YVwiKTt0aGlzLl9jYnMub25hdHRyaWJlbmQoKTt0aGlzLl9zdGF0ZT1CRUZPUkVfQVRUUklCVVRFX05BTUU7dGhpcy5faW5kZXgtLX1lbHNlIGlmKHRoaXMuX2RlY29kZUVudGl0aWVzJiZjPT09XCImXCIpe3RoaXMuX2VtaXRUb2tlbihcIm9uYXR0cmliZGF0YVwiKTt0aGlzLl9iYXNlU3RhdGU9dGhpcy5fc3RhdGU7dGhpcy5fc3RhdGU9QkVGT1JFX0VOVElUWTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZURlY2xhcmF0aW9uPWZ1bmN0aW9uKGMpe3RoaXMuX3N0YXRlPWM9PT1cIltcIj9CRUZPUkVfQ0RBVEFfMTpjPT09XCItXCI/QkVGT1JFX0NPTU1FTlQ6SU5fREVDTEFSQVRJT059O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5EZWNsYXJhdGlvbj1mdW5jdGlvbihjKXtpZihjPT09XCI+XCIpe3RoaXMuX2Nicy5vbmRlY2xhcmF0aW9uKHRoaXMuX2dldFNlY3Rpb24oKSk7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb249ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24odGhpcy5fZ2V0U2VjdGlvbigpKTt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDb21tZW50PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi1cIil7dGhpcy5fc3RhdGU9SU5fQ09NTUVOVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNle3RoaXMuX3N0YXRlPUlOX0RFQ0xBUkFUSU9OfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkNvbW1lbnQ9ZnVuY3Rpb24oYyl7aWYoYz09PVwiLVwiKXRoaXMuX3N0YXRlPUFGVEVSX0NPTU1FTlRfMX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNvbW1lbnQxPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi1cIil7dGhpcy5fc3RhdGU9QUZURVJfQ09NTUVOVF8yfWVsc2V7dGhpcy5fc3RhdGU9SU5fQ09NTUVOVH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJDb21tZW50Mj1mdW5jdGlvbihjKXtpZihjPT09XCI+XCIpe3RoaXMuX2Nicy5vbmNvbW1lbnQodGhpcy5fYnVmZmVyLnN1YnN0cmluZyh0aGlzLl9zZWN0aW9uU3RhcnQsdGhpcy5faW5kZXgtMikpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZihjIT09XCItXCIpe3RoaXMuX3N0YXRlPUlOX0NPTU1FTlR9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhMT1pZkVsc2VTdGF0ZShcIkNcIixCRUZPUkVfQ0RBVEFfMixJTl9ERUNMQVJBVElPTik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTI9aWZFbHNlU3RhdGUoXCJEXCIsQkVGT1JFX0NEQVRBXzMsSU5fREVDTEFSQVRJT04pO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGEzPWlmRWxzZVN0YXRlKFwiQVwiLEJFRk9SRV9DREFUQV80LElOX0RFQ0xBUkFUSU9OKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhND1pZkVsc2VTdGF0ZShcIlRcIixCRUZPUkVfQ0RBVEFfNSxJTl9ERUNMQVJBVElPTik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTU9aWZFbHNlU3RhdGUoXCJBXCIsQkVGT1JFX0NEQVRBXzYsSU5fREVDTEFSQVRJT04pO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGE2PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIltcIil7dGhpcy5fc3RhdGU9SU5fQ0RBVEE7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZXt0aGlzLl9zdGF0ZT1JTl9ERUNMQVJBVElPTjt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkNkYXRhPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIl1cIil0aGlzLl9zdGF0ZT1BRlRFUl9DREFUQV8xfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ2RhdGExPWNoYXJhY3RlclN0YXRlKFwiXVwiLEFGVEVSX0NEQVRBXzIpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJDZGF0YTI9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25jZGF0YSh0aGlzLl9idWZmZXIuc3Vic3RyaW5nKHRoaXMuX3NlY3Rpb25TdGFydCx0aGlzLl9pbmRleC0yKSk7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKGMhPT1cIl1cIil7dGhpcy5fc3RhdGU9SU5fQ0RBVEF9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNwZWNpYWw9ZnVuY3Rpb24oYyl7aWYoYz09PVwiY1wifHxjPT09XCJDXCIpe3RoaXMuX3N0YXRlPUJFRk9SRV9TQ1JJUFRfMX1lbHNlIGlmKGM9PT1cInRcInx8Yz09PVwiVFwiKXt0aGlzLl9zdGF0ZT1CRUZPUkVfU1RZTEVfMX1lbHNle3RoaXMuX3N0YXRlPUlOX1RBR19OQU1FO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNwZWNpYWxFbmQ9ZnVuY3Rpb24oYyl7aWYodGhpcy5fc3BlY2lhbD09PVNQRUNJQUxfU0NSSVBUJiYoYz09PVwiY1wifHxjPT09XCJDXCIpKXt0aGlzLl9zdGF0ZT1BRlRFUl9TQ1JJUFRfMX1lbHNlIGlmKHRoaXMuX3NwZWNpYWw9PT1TUEVDSUFMX1NUWUxFJiYoYz09PVwidFwifHxjPT09XCJUXCIpKXt0aGlzLl9zdGF0ZT1BRlRFUl9TVFlMRV8xfWVsc2UgdGhpcy5fc3RhdGU9VEVYVH07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQxPWNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJSXCIsQkVGT1JFX1NDUklQVF8yKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDI9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIklcIixCRUZPUkVfU0NSSVBUXzMpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0Mz1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiUFwiLEJFRk9SRV9TQ1JJUFRfNCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQ0PWNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJUXCIsQkVGT1JFX1NDUklQVF81KTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiL1wifHxjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX3NwZWNpYWw9U1BFQ0lBTF9TQ1JJUFR9dGhpcy5fc3RhdGU9SU5fVEFHX05BTUU7dGhpcy5faW5kZXgtLX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclNjcmlwdDE9aWZFbHNlU3RhdGUoXCJSXCIsQUZURVJfU0NSSVBUXzIsVEVYVCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclNjcmlwdDI9aWZFbHNlU3RhdGUoXCJJXCIsQUZURVJfU0NSSVBUXzMsVEVYVCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclNjcmlwdDM9aWZFbHNlU3RhdGUoXCJQXCIsQUZURVJfU0NSSVBUXzQsVEVYVCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclNjcmlwdDQ9aWZFbHNlU3RhdGUoXCJUXCIsQUZURVJfU0NSSVBUXzUsVEVYVCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclNjcmlwdDU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zcGVjaWFsPVNQRUNJQUxfTk9ORTt0aGlzLl9zdGF0ZT1JTl9DTE9TSU5HX1RBR19OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleC02O3RoaXMuX2luZGV4LS19ZWxzZSB0aGlzLl9zdGF0ZT1URVhUfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVN0eWxlMT1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiWVwiLEJFRk9SRV9TVFlMRV8yKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVN0eWxlMj1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiTFwiLEJFRk9SRV9TVFlMRV8zKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVN0eWxlMz1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiRVwiLEJFRk9SRV9TVFlMRV80KTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVN0eWxlND1mdW5jdGlvbihjKXtpZihjPT09XCIvXCJ8fGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fc3BlY2lhbD1TUEVDSUFMX1NUWUxFfXRoaXMuX3N0YXRlPUlOX1RBR19OQU1FO3RoaXMuX2luZGV4LS19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTdHlsZTE9aWZFbHNlU3RhdGUoXCJZXCIsQUZURVJfU1RZTEVfMixURVhUKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU3R5bGUyPWlmRWxzZVN0YXRlKFwiTFwiLEFGVEVSX1NUWUxFXzMsVEVYVCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclN0eWxlMz1pZkVsc2VTdGF0ZShcIkVcIixBRlRFUl9TVFlMRV80LFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTdHlsZTQ9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zcGVjaWFsPVNQRUNJQUxfTk9ORTt0aGlzLl9zdGF0ZT1JTl9DTE9TSU5HX1RBR19OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleC01O3RoaXMuX2luZGV4LS19ZWxzZSB0aGlzLl9zdGF0ZT1URVhUfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUVudGl0eT1pZkVsc2VTdGF0ZShcIiNcIixCRUZPUkVfTlVNRVJJQ19FTlRJVFksSU5fTkFNRURfRU5USVRZKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZU51bWVyaWNFbnRpdHk9aWZFbHNlU3RhdGUoXCJYXCIsSU5fSEVYX0VOVElUWSxJTl9OVU1FUklDX0VOVElUWSk7VG9rZW5pemVyLnByb3RvdHlwZS5fcGFyc2VOYW1lZEVudGl0eVN0cmljdD1mdW5jdGlvbigpe2lmKHRoaXMuX3NlY3Rpb25TdGFydCsxPHRoaXMuX2luZGV4KXt2YXIgZW50aXR5PXRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0KzEsdGhpcy5faW5kZXgpLG1hcD10aGlzLl94bWxNb2RlP3htbE1hcDplbnRpdHlNYXA7aWYobWFwLmhhc093blByb3BlcnR5KGVudGl0eSkpe3RoaXMuX2VtaXRQYXJ0aWFsKG1hcFtlbnRpdHldKTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9wYXJzZUxlZ2FjeUVudGl0eT1mdW5jdGlvbigpe3ZhciBzdGFydD10aGlzLl9zZWN0aW9uU3RhcnQrMSxsaW1pdD10aGlzLl9pbmRleC1zdGFydDtpZihsaW1pdD42KWxpbWl0PTY7d2hpbGUobGltaXQ+PTIpe3ZhciBlbnRpdHk9dGhpcy5fYnVmZmVyLnN1YnN0cihzdGFydCxsaW1pdCk7aWYobGVnYWN5TWFwLmhhc093blByb3BlcnR5KGVudGl0eSkpe3RoaXMuX2VtaXRQYXJ0aWFsKGxlZ2FjeU1hcFtlbnRpdHldKTt0aGlzLl9zZWN0aW9uU3RhcnQrPWxpbWl0KzE7cmV0dXJufWVsc2V7bGltaXQtLX19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluTmFtZWRFbnRpdHk9ZnVuY3Rpb24oYyl7aWYoYz09PVwiO1wiKXt0aGlzLl9wYXJzZU5hbWVkRW50aXR5U3RyaWN0KCk7aWYodGhpcy5fc2VjdGlvblN0YXJ0KzE8dGhpcy5faW5kZXgmJiF0aGlzLl94bWxNb2RlKXt0aGlzLl9wYXJzZUxlZ2FjeUVudGl0eSgpfXRoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZX1lbHNlIGlmKChjPFwiYVwifHxjPlwielwiKSYmKGM8XCJBXCJ8fGM+XCJaXCIpJiYoYzxcIjBcInx8Yz5cIjlcIikpe2lmKHRoaXMuX3htbE1vZGUpO2Vsc2UgaWYodGhpcy5fc2VjdGlvblN0YXJ0KzE9PT10aGlzLl9pbmRleCk7ZWxzZSBpZih0aGlzLl9iYXNlU3RhdGUhPT1URVhUKXtpZihjIT09XCI9XCIpe3RoaXMuX3BhcnNlTmFtZWRFbnRpdHlTdHJpY3QoKX19ZWxzZXt0aGlzLl9wYXJzZUxlZ2FjeUVudGl0eSgpfXRoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fZGVjb2RlTnVtZXJpY0VudGl0eT1mdW5jdGlvbihvZmZzZXQsYmFzZSl7dmFyIHNlY3Rpb25TdGFydD10aGlzLl9zZWN0aW9uU3RhcnQrb2Zmc2V0O2lmKHNlY3Rpb25TdGFydCE9PXRoaXMuX2luZGV4KXt2YXIgZW50aXR5PXRoaXMuX2J1ZmZlci5zdWJzdHJpbmcoc2VjdGlvblN0YXJ0LHRoaXMuX2luZGV4KTt2YXIgcGFyc2VkPXBhcnNlSW50KGVudGl0eSxiYXNlKTt0aGlzLl9lbWl0UGFydGlhbChkZWNvZGVDb2RlUG9pbnQocGFyc2VkKSk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fWVsc2V7dGhpcy5fc2VjdGlvblN0YXJ0LS19dGhpcy5fc3RhdGU9dGhpcy5fYmFzZVN0YXRlfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluTnVtZXJpY0VudGl0eT1mdW5jdGlvbihjKXtpZihjPT09XCI7XCIpe3RoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMiwxMCk7dGhpcy5fc2VjdGlvblN0YXJ0Kyt9ZWxzZSBpZihjPFwiMFwifHxjPlwiOVwiKXtpZighdGhpcy5feG1sTW9kZSl7dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgyLDEwKX1lbHNle3RoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZX10aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkhleEVudGl0eT1mdW5jdGlvbihjKXtpZihjPT09XCI7XCIpe3RoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMywxNik7dGhpcy5fc2VjdGlvblN0YXJ0Kyt9ZWxzZSBpZigoYzxcImFcInx8Yz5cImZcIikmJihjPFwiQVwifHxjPlwiRlwiKSYmKGM8XCIwXCJ8fGM+XCI5XCIpKXtpZighdGhpcy5feG1sTW9kZSl7dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgzLDE2KX1lbHNle3RoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZX10aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fY2xlYW51cD1mdW5jdGlvbigpe2lmKHRoaXMuX3NlY3Rpb25TdGFydDwwKXt0aGlzLl9idWZmZXI9XCJcIjt0aGlzLl9pbmRleD0wO3RoaXMuX2J1ZmZlck9mZnNldCs9dGhpcy5faW5kZXh9ZWxzZSBpZih0aGlzLl9ydW5uaW5nKXtpZih0aGlzLl9zdGF0ZT09PVRFWFQpe2lmKHRoaXMuX3NlY3Rpb25TdGFydCE9PXRoaXMuX2luZGV4KXt0aGlzLl9jYnMub250ZXh0KHRoaXMuX2J1ZmZlci5zdWJzdHIodGhpcy5fc2VjdGlvblN0YXJ0KSl9dGhpcy5fYnVmZmVyPVwiXCI7dGhpcy5fYnVmZmVyT2Zmc2V0Kz10aGlzLl9pbmRleDt0aGlzLl9pbmRleD0wfWVsc2UgaWYodGhpcy5fc2VjdGlvblN0YXJ0PT09dGhpcy5faW5kZXgpe3RoaXMuX2J1ZmZlcj1cIlwiO3RoaXMuX2J1ZmZlck9mZnNldCs9dGhpcy5faW5kZXg7dGhpcy5faW5kZXg9MH1lbHNle3RoaXMuX2J1ZmZlcj10aGlzLl9idWZmZXIuc3Vic3RyKHRoaXMuX3NlY3Rpb25TdGFydCk7dGhpcy5faW5kZXgtPXRoaXMuX3NlY3Rpb25TdGFydDt0aGlzLl9idWZmZXJPZmZzZXQrPXRoaXMuX3NlY3Rpb25TdGFydH10aGlzLl9zZWN0aW9uU3RhcnQ9MH19O1Rva2VuaXplci5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24oY2h1bmspe2lmKHRoaXMuX2VuZGVkKXRoaXMuX2Nicy5vbmVycm9yKEVycm9yKFwiLndyaXRlKCkgYWZ0ZXIgZG9uZSFcIikpO3RoaXMuX2J1ZmZlcis9Y2h1bms7dGhpcy5fcGFyc2UoKX07VG9rZW5pemVyLnByb3RvdHlwZS5fcGFyc2U9ZnVuY3Rpb24oKXt3aGlsZSh0aGlzLl9pbmRleDx0aGlzLl9idWZmZXIubGVuZ3RoJiZ0aGlzLl9ydW5uaW5nKXt2YXIgYz10aGlzLl9idWZmZXIuY2hhckF0KHRoaXMuX2luZGV4KTtpZih0aGlzLl9zdGF0ZT09PVRFWFQpe3RoaXMuX3N0YXRlVGV4dChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1RBR19OQU1FKXt0aGlzLl9zdGF0ZUJlZm9yZVRhZ05hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX1RBR19OQU1FKXt0aGlzLl9zdGF0ZUluVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NMT1NJTkdfVEFHX05BTUUpe3RoaXMuX3N0YXRlQmVmb3JlQ2xvc2VpbmdUYWdOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9DTE9TSU5HX1RBR19OQU1FKXt0aGlzLl9zdGF0ZUluQ2xvc2VpbmdUYWdOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9DTE9TSU5HX1RBR19OQU1FKXt0aGlzLl9zdGF0ZUFmdGVyQ2xvc2VpbmdUYWdOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9TRUxGX0NMT1NJTkdfVEFHKXt0aGlzLl9zdGF0ZUluU2VsZkNsb3NpbmdUYWcoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9BVFRSSUJVVEVfTkFNRSl7dGhpcy5fc3RhdGVCZWZvcmVBdHRyaWJ1dGVOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9BVFRSSUJVVEVfTkFNRSl7dGhpcy5fc3RhdGVJbkF0dHJpYnV0ZU5hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX0FUVFJJQlVURV9OQU1FKXt0aGlzLl9zdGF0ZUFmdGVyQXR0cmlidXRlTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0FUVFJJQlVURV9WQUxVRSl7dGhpcy5fc3RhdGVCZWZvcmVBdHRyaWJ1dGVWYWx1ZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQVRUUklCVVRFX1ZBTFVFX0RRKXt0aGlzLl9zdGF0ZUluQXR0cmlidXRlVmFsdWVEb3VibGVRdW90ZXMoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0FUVFJJQlVURV9WQUxVRV9TUSl7dGhpcy5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlU2luZ2xlUXVvdGVzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9BVFRSSUJVVEVfVkFMVUVfTlEpe3RoaXMuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZU5vUXVvdGVzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfREVDTEFSQVRJT04pe3RoaXMuX3N0YXRlQmVmb3JlRGVjbGFyYXRpb24oYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0RFQ0xBUkFUSU9OKXt0aGlzLl9zdGF0ZUluRGVjbGFyYXRpb24oYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04pe3RoaXMuX3N0YXRlSW5Qcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DT01NRU5UKXt0aGlzLl9zdGF0ZUJlZm9yZUNvbW1lbnQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0NPTU1FTlQpe3RoaXMuX3N0YXRlSW5Db21tZW50KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9DT01NRU5UXzEpe3RoaXMuX3N0YXRlQWZ0ZXJDb21tZW50MShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfQ09NTUVOVF8yKXt0aGlzLl9zdGF0ZUFmdGVyQ29tbWVudDIoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DREFUQV8xKXt0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhMShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NEQVRBXzIpe3RoaXMuX3N0YXRlQmVmb3JlQ2RhdGEyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0RBVEFfMyl7dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTMoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DREFUQV80KXt0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhNChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NEQVRBXzUpe3RoaXMuX3N0YXRlQmVmb3JlQ2RhdGE1KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0RBVEFfNil7dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTYoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0NEQVRBKXt0aGlzLl9zdGF0ZUluQ2RhdGEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX0NEQVRBXzEpe3RoaXMuX3N0YXRlQWZ0ZXJDZGF0YTEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX0NEQVRBXzIpe3RoaXMuX3N0YXRlQWZ0ZXJDZGF0YTIoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TUEVDSUFMKXt0aGlzLl9zdGF0ZUJlZm9yZVNwZWNpYWwoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TUEVDSUFMX0VORCl7dGhpcy5fc3RhdGVCZWZvcmVTcGVjaWFsRW5kKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU0NSSVBUXzEpe3RoaXMuX3N0YXRlQmVmb3JlU2NyaXB0MShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NDUklQVF8yKXt0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDIoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TQ1JJUFRfMyl7dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU0NSSVBUXzQpe3RoaXMuX3N0YXRlQmVmb3JlU2NyaXB0NChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NDUklQVF81KXt0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NDUklQVF8xKXt0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0MShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU0NSSVBUXzIpe3RoaXMuX3N0YXRlQWZ0ZXJTY3JpcHQyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TQ1JJUFRfMyl7dGhpcy5fc3RhdGVBZnRlclNjcmlwdDMoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NDUklQVF80KXt0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0NChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU0NSSVBUXzUpe3RoaXMuX3N0YXRlQWZ0ZXJTY3JpcHQ1KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1RZTEVfMSl7dGhpcy5fc3RhdGVCZWZvcmVTdHlsZTEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TVFlMRV8yKXt0aGlzLl9zdGF0ZUJlZm9yZVN0eWxlMihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NUWUxFXzMpe3RoaXMuX3N0YXRlQmVmb3JlU3R5bGUzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1RZTEVfNCl7dGhpcy5fc3RhdGVCZWZvcmVTdHlsZTQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NUWUxFXzEpe3RoaXMuX3N0YXRlQWZ0ZXJTdHlsZTEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NUWUxFXzIpe3RoaXMuX3N0YXRlQWZ0ZXJTdHlsZTIoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NUWUxFXzMpe3RoaXMuX3N0YXRlQWZ0ZXJTdHlsZTMoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NUWUxFXzQpe3RoaXMuX3N0YXRlQWZ0ZXJTdHlsZTQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9FTlRJVFkpe3RoaXMuX3N0YXRlQmVmb3JlRW50aXR5KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfTlVNRVJJQ19FTlRJVFkpe3RoaXMuX3N0YXRlQmVmb3JlTnVtZXJpY0VudGl0eShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fTkFNRURfRU5USVRZKXt0aGlzLl9zdGF0ZUluTmFtZWRFbnRpdHkoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX05VTUVSSUNfRU5USVRZKXt0aGlzLl9zdGF0ZUluTnVtZXJpY0VudGl0eShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fSEVYX0VOVElUWSl7dGhpcy5fc3RhdGVJbkhleEVudGl0eShjKX1lbHNle3RoaXMuX2Nicy5vbmVycm9yKEVycm9yKFwidW5rbm93biBfc3RhdGVcIiksdGhpcy5fc3RhdGUpfXRoaXMuX2luZGV4Kyt9dGhpcy5fY2xlYW51cCgpfTtUb2tlbml6ZXIucHJvdG90eXBlLnBhdXNlPWZ1bmN0aW9uKCl7dGhpcy5fcnVubmluZz1mYWxzZX07VG9rZW5pemVyLnByb3RvdHlwZS5yZXN1bWU9ZnVuY3Rpb24oKXt0aGlzLl9ydW5uaW5nPXRydWU7aWYodGhpcy5faW5kZXg8dGhpcy5fYnVmZmVyLmxlbmd0aCl7dGhpcy5fcGFyc2UoKX1pZih0aGlzLl9lbmRlZCl7dGhpcy5fZmluaXNoKCl9fTtUb2tlbml6ZXIucHJvdG90eXBlLmVuZD1mdW5jdGlvbihjaHVuayl7aWYodGhpcy5fZW5kZWQpdGhpcy5fY2JzLm9uZXJyb3IoRXJyb3IoXCIuZW5kKCkgYWZ0ZXIgZG9uZSFcIikpO2lmKGNodW5rKXRoaXMud3JpdGUoY2h1bmspO3RoaXMuX2VuZGVkPXRydWU7aWYodGhpcy5fcnVubmluZyl0aGlzLl9maW5pc2goKX07VG9rZW5pemVyLnByb3RvdHlwZS5fZmluaXNoPWZ1bmN0aW9uKCl7aWYodGhpcy5fc2VjdGlvblN0YXJ0PHRoaXMuX2luZGV4KXt0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKX10aGlzLl9jYnMub25lbmQoKX07VG9rZW5pemVyLnByb3RvdHlwZS5faGFuZGxlVHJhaWxpbmdEYXRhPWZ1bmN0aW9uKCl7dmFyIGRhdGE9dGhpcy5fYnVmZmVyLnN1YnN0cih0aGlzLl9zZWN0aW9uU3RhcnQpO2lmKHRoaXMuX3N0YXRlPT09SU5fQ0RBVEF8fHRoaXMuX3N0YXRlPT09QUZURVJfQ0RBVEFfMXx8dGhpcy5fc3RhdGU9PT1BRlRFUl9DREFUQV8yKXt0aGlzLl9jYnMub25jZGF0YShkYXRhKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQ09NTUVOVHx8dGhpcy5fc3RhdGU9PT1BRlRFUl9DT01NRU5UXzF8fHRoaXMuX3N0YXRlPT09QUZURVJfQ09NTUVOVF8yKXt0aGlzLl9jYnMub25jb21tZW50KGRhdGEpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9OQU1FRF9FTlRJVFkmJiF0aGlzLl94bWxNb2RlKXt0aGlzLl9wYXJzZUxlZ2FjeUVudGl0eSgpO2lmKHRoaXMuX3NlY3Rpb25TdGFydDx0aGlzLl9pbmRleCl7dGhpcy5fc3RhdGU9dGhpcy5fYmFzZVN0YXRlO3RoaXMuX2hhbmRsZVRyYWlsaW5nRGF0YSgpfX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fTlVNRVJJQ19FTlRJVFkmJiF0aGlzLl94bWxNb2RlKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDIsMTApO2lmKHRoaXMuX3NlY3Rpb25TdGFydDx0aGlzLl9pbmRleCl7dGhpcy5fc3RhdGU9dGhpcy5fYmFzZVN0YXRlO3RoaXMuX2hhbmRsZVRyYWlsaW5nRGF0YSgpfX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fSEVYX0VOVElUWSYmIXRoaXMuX3htbE1vZGUpe3RoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMywxNik7aWYodGhpcy5fc2VjdGlvblN0YXJ0PHRoaXMuX2luZGV4KXt0aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGU7dGhpcy5faGFuZGxlVHJhaWxpbmdEYXRhKCl9fWVsc2UgaWYodGhpcy5fc3RhdGUhPT1JTl9UQUdfTkFNRSYmdGhpcy5fc3RhdGUhPT1CRUZPUkVfQVRUUklCVVRFX05BTUUmJnRoaXMuX3N0YXRlIT09QkVGT1JFX0FUVFJJQlVURV9WQUxVRSYmdGhpcy5fc3RhdGUhPT1BRlRFUl9BVFRSSUJVVEVfTkFNRSYmdGhpcy5fc3RhdGUhPT1JTl9BVFRSSUJVVEVfTkFNRSYmdGhpcy5fc3RhdGUhPT1JTl9BVFRSSUJVVEVfVkFMVUVfU1EmJnRoaXMuX3N0YXRlIT09SU5fQVRUUklCVVRFX1ZBTFVFX0RRJiZ0aGlzLl9zdGF0ZSE9PUlOX0FUVFJJQlVURV9WQUxVRV9OUSYmdGhpcy5fc3RhdGUhPT1JTl9DTE9TSU5HX1RBR19OQU1FKXtcbnRoaXMuX2Nicy5vbnRleHQoZGF0YSl9fTtUb2tlbml6ZXIucHJvdG90eXBlLnJlc2V0PWZ1bmN0aW9uKCl7VG9rZW5pemVyLmNhbGwodGhpcyx7eG1sTW9kZTp0aGlzLl94bWxNb2RlLGRlY29kZUVudGl0aWVzOnRoaXMuX2RlY29kZUVudGl0aWVzfSx0aGlzLl9jYnMpfTtUb2tlbml6ZXIucHJvdG90eXBlLmdldEFic29sdXRlSW5kZXg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fYnVmZmVyT2Zmc2V0K3RoaXMuX2luZGV4fTtUb2tlbml6ZXIucHJvdG90eXBlLl9nZXRTZWN0aW9uPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0LHRoaXMuX2luZGV4KX07VG9rZW5pemVyLnByb3RvdHlwZS5fZW1pdFRva2VuPWZ1bmN0aW9uKG5hbWUpe3RoaXMuX2Nic1tuYW1lXSh0aGlzLl9nZXRTZWN0aW9uKCkpO3RoaXMuX3NlY3Rpb25TdGFydD0tMX07VG9rZW5pemVyLnByb3RvdHlwZS5fZW1pdFBhcnRpYWw9ZnVuY3Rpb24odmFsdWUpe2lmKHRoaXMuX2Jhc2VTdGF0ZSE9PVRFWFQpe3RoaXMuX2Nicy5vbmF0dHJpYmRhdGEodmFsdWUpfWVsc2V7dGhpcy5fY2JzLm9udGV4dCh2YWx1ZSl9fX0se1wiZW50aXRpZXMvbGliL2RlY29kZV9jb2RlcG9pbnQuanNcIjoyMixcImVudGl0aWVzL21hcHMvZW50aXRpZXMuanNvblwiOjI1LFwiZW50aXRpZXMvbWFwcy9sZWdhY3kuanNvblwiOjI2LFwiZW50aXRpZXMvbWFwcy94bWwuanNvblwiOjI3fV0sMzU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPVN0cmVhbTt2YXIgUGFyc2VyPXJlcXVpcmUoXCIuL1BhcnNlci5qc1wiKSxXcml0YWJsZVN0cmVhbT1yZXF1aXJlKFwic3RyZWFtXCIpLldyaXRhYmxlfHxyZXF1aXJlKFwicmVhZGFibGUtc3RyZWFtXCIpLldyaXRhYmxlLFN0cmluZ0RlY29kZXI9cmVxdWlyZShcInN0cmluZ19kZWNvZGVyXCIpLlN0cmluZ0RlY29kZXIsQnVmZmVyPXJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO2Z1bmN0aW9uIFN0cmVhbShjYnMsb3B0aW9ucyl7dmFyIHBhcnNlcj10aGlzLl9wYXJzZXI9bmV3IFBhcnNlcihjYnMsb3B0aW9ucyk7dmFyIGRlY29kZXI9dGhpcy5fZGVjb2Rlcj1uZXcgU3RyaW5nRGVjb2RlcjtXcml0YWJsZVN0cmVhbS5jYWxsKHRoaXMse2RlY29kZVN0cmluZ3M6ZmFsc2V9KTt0aGlzLm9uY2UoXCJmaW5pc2hcIixmdW5jdGlvbigpe3BhcnNlci5lbmQoZGVjb2Rlci5lbmQoKSl9KX1yZXF1aXJlKFwiaW5oZXJpdHNcIikoU3RyZWFtLFdyaXRhYmxlU3RyZWFtKTtXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUuX3dyaXRlPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXtpZihjaHVuayBpbnN0YW5jZW9mIEJ1ZmZlciljaHVuaz10aGlzLl9kZWNvZGVyLndyaXRlKGNodW5rKTt0aGlzLl9wYXJzZXIud3JpdGUoY2h1bmspO2NiKCl9fSx7XCIuL1BhcnNlci5qc1wiOjMxLGJ1ZmZlcjo1LGluaGVyaXRzOjM4LFwicmVhZGFibGUtc3RyZWFtXCI6MyxzdHJlYW06NTUsc3RyaW5nX2RlY29kZXI6NTZ9XSwzNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIFBhcnNlcj1yZXF1aXJlKFwiLi9QYXJzZXIuanNcIiksRG9tSGFuZGxlcj1yZXF1aXJlKFwiZG9taGFuZGxlclwiKTtmdW5jdGlvbiBkZWZpbmVQcm9wKG5hbWUsdmFsdWUpe2RlbGV0ZSBtb2R1bGUuZXhwb3J0c1tuYW1lXTttb2R1bGUuZXhwb3J0c1tuYW1lXT12YWx1ZTtyZXR1cm4gdmFsdWV9bW9kdWxlLmV4cG9ydHM9e1BhcnNlcjpQYXJzZXIsVG9rZW5pemVyOnJlcXVpcmUoXCIuL1Rva2VuaXplci5qc1wiKSxFbGVtZW50VHlwZTpyZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIiksRG9tSGFuZGxlcjpEb21IYW5kbGVyLGdldCBGZWVkSGFuZGxlcigpe3JldHVybiBkZWZpbmVQcm9wKFwiRmVlZEhhbmRsZXJcIixyZXF1aXJlKFwiLi9GZWVkSGFuZGxlci5qc1wiKSl9LGdldCBTdHJlYW0oKXtyZXR1cm4gZGVmaW5lUHJvcChcIlN0cmVhbVwiLHJlcXVpcmUoXCIuL1N0cmVhbS5qc1wiKSl9LGdldCBXcml0YWJsZVN0cmVhbSgpe3JldHVybiBkZWZpbmVQcm9wKFwiV3JpdGFibGVTdHJlYW1cIixyZXF1aXJlKFwiLi9Xcml0YWJsZVN0cmVhbS5qc1wiKSl9LGdldCBQcm94eUhhbmRsZXIoKXtyZXR1cm4gZGVmaW5lUHJvcChcIlByb3h5SGFuZGxlclwiLHJlcXVpcmUoXCIuL1Byb3h5SGFuZGxlci5qc1wiKSl9LGdldCBEb21VdGlscygpe3JldHVybiBkZWZpbmVQcm9wKFwiRG9tVXRpbHNcIixyZXF1aXJlKFwiZG9tdXRpbHNcIikpfSxnZXQgQ29sbGVjdGluZ0hhbmRsZXIoKXtyZXR1cm4gZGVmaW5lUHJvcChcIkNvbGxlY3RpbmdIYW5kbGVyXCIscmVxdWlyZShcIi4vQ29sbGVjdGluZ0hhbmRsZXIuanNcIikpfSxEZWZhdWx0SGFuZGxlcjpEb21IYW5kbGVyLGdldCBSc3NIYW5kbGVyKCl7cmV0dXJuIGRlZmluZVByb3AoXCJSc3NIYW5kbGVyXCIsdGhpcy5GZWVkSGFuZGxlcil9LHBhcnNlRE9NOmZ1bmN0aW9uKGRhdGEsb3B0aW9ucyl7dmFyIGhhbmRsZXI9bmV3IERvbUhhbmRsZXIob3B0aW9ucyk7bmV3IFBhcnNlcihoYW5kbGVyLG9wdGlvbnMpLmVuZChkYXRhKTtyZXR1cm4gaGFuZGxlci5kb219LHBhcnNlRmVlZDpmdW5jdGlvbihmZWVkLG9wdGlvbnMpe3ZhciBoYW5kbGVyPW5ldyBtb2R1bGUuZXhwb3J0cy5GZWVkSGFuZGxlcihvcHRpb25zKTtuZXcgUGFyc2VyKGhhbmRsZXIsb3B0aW9ucykuZW5kKGZlZWQpO3JldHVybiBoYW5kbGVyLmRvbX0sY3JlYXRlRG9tU3RyZWFtOmZ1bmN0aW9uKGNiLG9wdGlvbnMsZWxlbWVudENiKXt2YXIgaGFuZGxlcj1uZXcgRG9tSGFuZGxlcihjYixvcHRpb25zLGVsZW1lbnRDYik7cmV0dXJuIG5ldyBQYXJzZXIoaGFuZGxlcixvcHRpb25zKX0sRVZFTlRTOnthdHRyaWJ1dGU6MixjZGF0YXN0YXJ0OjAsY2RhdGFlbmQ6MCx0ZXh0OjEscHJvY2Vzc2luZ2luc3RydWN0aW9uOjIsY29tbWVudDoxLGNvbW1lbnRlbmQ6MCxjbG9zZXRhZzoxLG9wZW50YWc6MixvcGVudGFnbmFtZToxLGVycm9yOjEsZW5kOjB9fX0se1wiLi9Db2xsZWN0aW5nSGFuZGxlci5qc1wiOjI5LFwiLi9GZWVkSGFuZGxlci5qc1wiOjMwLFwiLi9QYXJzZXIuanNcIjozMSxcIi4vUHJveHlIYW5kbGVyLmpzXCI6MzIsXCIuL1N0cmVhbS5qc1wiOjMzLFwiLi9Ub2tlbml6ZXIuanNcIjozNCxcIi4vV3JpdGFibGVTdHJlYW0uanNcIjozNSxkb21lbGVtZW50dHlwZTo5LGRvbWhhbmRsZXI6MTAsZG9tdXRpbHM6MTN9XSwzNzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7ZXhwb3J0cy5yZWFkPWZ1bmN0aW9uKGJ1ZmZlcixvZmZzZXQsaXNMRSxtTGVuLG5CeXRlcyl7dmFyIGUsbTt2YXIgZUxlbj1uQnl0ZXMqOC1tTGVuLTE7dmFyIGVNYXg9KDE8PGVMZW4pLTE7dmFyIGVCaWFzPWVNYXg+PjE7dmFyIG5CaXRzPS03O3ZhciBpPWlzTEU/bkJ5dGVzLTE6MDt2YXIgZD1pc0xFPy0xOjE7dmFyIHM9YnVmZmVyW29mZnNldCtpXTtpKz1kO2U9cyYoMTw8LW5CaXRzKS0xO3M+Pj0tbkJpdHM7bkJpdHMrPWVMZW47Zm9yKDtuQml0cz4wO2U9ZSoyNTYrYnVmZmVyW29mZnNldCtpXSxpKz1kLG5CaXRzLT04KXt9bT1lJigxPDwtbkJpdHMpLTE7ZT4+PS1uQml0cztuQml0cys9bUxlbjtmb3IoO25CaXRzPjA7bT1tKjI1NitidWZmZXJbb2Zmc2V0K2ldLGkrPWQsbkJpdHMtPTgpe31pZihlPT09MCl7ZT0xLWVCaWFzfWVsc2UgaWYoZT09PWVNYXgpe3JldHVybiBtP05hTjoocz8tMToxKSpJbmZpbml0eX1lbHNle209bStNYXRoLnBvdygyLG1MZW4pO2U9ZS1lQmlhc31yZXR1cm4ocz8tMToxKSptKk1hdGgucG93KDIsZS1tTGVuKX07ZXhwb3J0cy53cml0ZT1mdW5jdGlvbihidWZmZXIsdmFsdWUsb2Zmc2V0LGlzTEUsbUxlbixuQnl0ZXMpe3ZhciBlLG0sYzt2YXIgZUxlbj1uQnl0ZXMqOC1tTGVuLTE7dmFyIGVNYXg9KDE8PGVMZW4pLTE7dmFyIGVCaWFzPWVNYXg+PjE7dmFyIHJ0PW1MZW49PT0yMz9NYXRoLnBvdygyLC0yNCktTWF0aC5wb3coMiwtNzcpOjA7dmFyIGk9aXNMRT8wOm5CeXRlcy0xO3ZhciBkPWlzTEU/MTotMTt2YXIgcz12YWx1ZTwwfHx2YWx1ZT09PTAmJjEvdmFsdWU8MD8xOjA7dmFsdWU9TWF0aC5hYnModmFsdWUpO2lmKGlzTmFOKHZhbHVlKXx8dmFsdWU9PT1JbmZpbml0eSl7bT1pc05hTih2YWx1ZSk/MTowO2U9ZU1heH1lbHNle2U9TWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkvTWF0aC5MTjIpO2lmKHZhbHVlKihjPU1hdGgucG93KDIsLWUpKTwxKXtlLS07Yyo9Mn1pZihlK2VCaWFzPj0xKXt2YWx1ZSs9cnQvY31lbHNle3ZhbHVlKz1ydCpNYXRoLnBvdygyLDEtZUJpYXMpfWlmKHZhbHVlKmM+PTIpe2UrKztjLz0yfWlmKGUrZUJpYXM+PWVNYXgpe209MDtlPWVNYXh9ZWxzZSBpZihlK2VCaWFzPj0xKXttPSh2YWx1ZSpjLTEpKk1hdGgucG93KDIsbUxlbik7ZT1lK2VCaWFzfWVsc2V7bT12YWx1ZSpNYXRoLnBvdygyLGVCaWFzLTEpKk1hdGgucG93KDIsbUxlbik7ZT0wfX1mb3IoO21MZW4+PTg7YnVmZmVyW29mZnNldCtpXT1tJjI1NSxpKz1kLG0vPTI1NixtTGVuLT04KXt9ZT1lPDxtTGVufG07ZUxlbis9bUxlbjtmb3IoO2VMZW4+MDtidWZmZXJbb2Zmc2V0K2ldPWUmMjU1LGkrPWQsZS89MjU2LGVMZW4tPTgpe31idWZmZXJbb2Zmc2V0K2ktZF18PXMqMTI4fX0se31dLDM4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtpZih0eXBlb2YgT2JqZWN0LmNyZWF0ZT09PVwiZnVuY3Rpb25cIil7bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24gaW5oZXJpdHMoY3RvcixzdXBlckN0b3Ipe2N0b3Iuc3VwZXJfPXN1cGVyQ3RvcjtjdG9yLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUse2NvbnN0cnVjdG9yOnt2YWx1ZTpjdG9yLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX19KX19ZWxzZXttb2R1bGUuZXhwb3J0cz1mdW5jdGlvbiBpbmhlcml0cyhjdG9yLHN1cGVyQ3Rvcil7Y3Rvci5zdXBlcl89c3VwZXJDdG9yO3ZhciBUZW1wQ3Rvcj1mdW5jdGlvbigpe307VGVtcEN0b3IucHJvdG90eXBlPXN1cGVyQ3Rvci5wcm90b3R5cGU7Y3Rvci5wcm90b3R5cGU9bmV3IFRlbXBDdG9yO2N0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yPWN0b3J9fX0se31dLDM5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1mdW5jdGlvbihvYmope3JldHVybiBvYmohPW51bGwmJihpc0J1ZmZlcihvYmopfHxpc1Nsb3dCdWZmZXIob2JqKXx8ISFvYmouX2lzQnVmZmVyKX07ZnVuY3Rpb24gaXNCdWZmZXIob2JqKXtyZXR1cm4hIW9iai5jb25zdHJ1Y3RvciYmdHlwZW9mIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcj09PVwiZnVuY3Rpb25cIiYmb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyKG9iail9ZnVuY3Rpb24gaXNTbG93QnVmZmVyKG9iail7cmV0dXJuIHR5cGVvZiBvYmoucmVhZEZsb2F0TEU9PT1cImZ1bmN0aW9uXCImJnR5cGVvZiBvYmouc2xpY2U9PT1cImZ1bmN0aW9uXCImJmlzQnVmZmVyKG9iai5zbGljZSgwLDApKX19LHt9XSw0MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIHRvU3RyaW5nPXt9LnRvU3RyaW5nO21vZHVsZS5leHBvcnRzPUFycmF5LmlzQXJyYXl8fGZ1bmN0aW9uKGFycil7cmV0dXJuIHRvU3RyaW5nLmNhbGwoYXJyKT09XCJbb2JqZWN0IEFycmF5XVwifX0se31dLDQxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24ocHJvY2Vzcyl7XCJ1c2Ugc3RyaWN0XCI7aWYoIXByb2Nlc3MudmVyc2lvbnx8cHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoXCJ2MC5cIik9PT0wfHxwcm9jZXNzLnZlcnNpb24uaW5kZXhPZihcInYxLlwiKT09PTAmJnByb2Nlc3MudmVyc2lvbi5pbmRleE9mKFwidjEuOC5cIikhPT0wKXttb2R1bGUuZXhwb3J0cz1uZXh0VGlja31lbHNle21vZHVsZS5leHBvcnRzPXByb2Nlc3MubmV4dFRpY2t9ZnVuY3Rpb24gbmV4dFRpY2soZm4sYXJnMSxhcmcyLGFyZzMpe2lmKHR5cGVvZiBmbiE9PVwiZnVuY3Rpb25cIil7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJjYWxsYmFja1wiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpfXZhciBsZW49YXJndW1lbnRzLmxlbmd0aDt2YXIgYXJncyxpO3N3aXRjaChsZW4pe2Nhc2UgMDpjYXNlIDE6cmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZm4pO2Nhc2UgMjpyZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tPbmUoKXtmbi5jYWxsKG51bGwsYXJnMSl9KTtjYXNlIDM6cmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrVHdvKCl7Zm4uY2FsbChudWxsLGFyZzEsYXJnMil9KTtjYXNlIDQ6cmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrVGhyZWUoKXtmbi5jYWxsKG51bGwsYXJnMSxhcmcyLGFyZzMpfSk7ZGVmYXVsdDphcmdzPW5ldyBBcnJheShsZW4tMSk7aT0wO3doaWxlKGk8YXJncy5sZW5ndGgpe2FyZ3NbaSsrXT1hcmd1bWVudHNbaV19cmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrKCl7Zm4uYXBwbHkobnVsbCxhcmdzKX0pfX19KS5jYWxsKHRoaXMscmVxdWlyZShcIl9wcm9jZXNzXCIpKX0se19wcm9jZXNzOjQyfV0sNDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBwcm9jZXNzPW1vZHVsZS5leHBvcnRzPXt9O3ZhciBjYWNoZWRTZXRUaW1lb3V0O3ZhciBjYWNoZWRDbGVhclRpbWVvdXQ7ZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpe3Rocm93IG5ldyBFcnJvcihcInNldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWRcIil9ZnVuY3Rpb24gZGVmYXVsdENsZWFyVGltZW91dCgpe3Rocm93IG5ldyBFcnJvcihcImNsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZFwiKX0oZnVuY3Rpb24oKXt0cnl7aWYodHlwZW9mIHNldFRpbWVvdXQ9PT1cImZ1bmN0aW9uXCIpe2NhY2hlZFNldFRpbWVvdXQ9c2V0VGltZW91dH1lbHNle2NhY2hlZFNldFRpbWVvdXQ9ZGVmYXVsdFNldFRpbW91dH19Y2F0Y2goZSl7Y2FjaGVkU2V0VGltZW91dD1kZWZhdWx0U2V0VGltb3V0fXRyeXtpZih0eXBlb2YgY2xlYXJUaW1lb3V0PT09XCJmdW5jdGlvblwiKXtjYWNoZWRDbGVhclRpbWVvdXQ9Y2xlYXJUaW1lb3V0fWVsc2V7Y2FjaGVkQ2xlYXJUaW1lb3V0PWRlZmF1bHRDbGVhclRpbWVvdXR9fWNhdGNoKGUpe2NhY2hlZENsZWFyVGltZW91dD1kZWZhdWx0Q2xlYXJUaW1lb3V0fX0pKCk7ZnVuY3Rpb24gcnVuVGltZW91dChmdW4pe2lmKGNhY2hlZFNldFRpbWVvdXQ9PT1zZXRUaW1lb3V0KXtyZXR1cm4gc2V0VGltZW91dChmdW4sMCl9aWYoKGNhY2hlZFNldFRpbWVvdXQ9PT1kZWZhdWx0U2V0VGltb3V0fHwhY2FjaGVkU2V0VGltZW91dCkmJnNldFRpbWVvdXQpe2NhY2hlZFNldFRpbWVvdXQ9c2V0VGltZW91dDtyZXR1cm4gc2V0VGltZW91dChmdW4sMCl9dHJ5e3JldHVybiBjYWNoZWRTZXRUaW1lb3V0KGZ1biwwKX1jYXRjaChlKXt0cnl7cmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbChudWxsLGZ1biwwKX1jYXRjaChlKXtyZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsZnVuLDApfX19ZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcil7aWYoY2FjaGVkQ2xlYXJUaW1lb3V0PT09Y2xlYXJUaW1lb3V0KXtyZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcil9aWYoKGNhY2hlZENsZWFyVGltZW91dD09PWRlZmF1bHRDbGVhclRpbWVvdXR8fCFjYWNoZWRDbGVhclRpbWVvdXQpJiZjbGVhclRpbWVvdXQpe2NhY2hlZENsZWFyVGltZW91dD1jbGVhclRpbWVvdXQ7cmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpfXRyeXtyZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcil9Y2F0Y2goZSl7dHJ5e3JldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLG1hcmtlcil9Y2F0Y2goZSl7cmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsbWFya2VyKX19fXZhciBxdWV1ZT1bXTt2YXIgZHJhaW5pbmc9ZmFsc2U7dmFyIGN1cnJlbnRRdWV1ZTt2YXIgcXVldWVJbmRleD0tMTtmdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKXtpZighZHJhaW5pbmd8fCFjdXJyZW50UXVldWUpe3JldHVybn1kcmFpbmluZz1mYWxzZTtpZihjdXJyZW50UXVldWUubGVuZ3RoKXtxdWV1ZT1jdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKX1lbHNle3F1ZXVlSW5kZXg9LTF9aWYocXVldWUubGVuZ3RoKXtkcmFpblF1ZXVlKCl9fWZ1bmN0aW9uIGRyYWluUXVldWUoKXtpZihkcmFpbmluZyl7cmV0dXJufXZhciB0aW1lb3V0PXJ1blRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtkcmFpbmluZz10cnVlO3ZhciBsZW49cXVldWUubGVuZ3RoO3doaWxlKGxlbil7Y3VycmVudFF1ZXVlPXF1ZXVlO3F1ZXVlPVtdO3doaWxlKCsrcXVldWVJbmRleDxsZW4pe2lmKGN1cnJlbnRRdWV1ZSl7Y3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpfX1xdWV1ZUluZGV4PS0xO2xlbj1xdWV1ZS5sZW5ndGh9Y3VycmVudFF1ZXVlPW51bGw7ZHJhaW5pbmc9ZmFsc2U7cnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpfXByb2Nlc3MubmV4dFRpY2s9ZnVuY3Rpb24oZnVuKXt2YXIgYXJncz1uZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aC0xKTtpZihhcmd1bWVudHMubGVuZ3RoPjEpe2Zvcih2YXIgaT0xO2k8YXJndW1lbnRzLmxlbmd0aDtpKyspe2FyZ3NbaS0xXT1hcmd1bWVudHNbaV19fXF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLGFyZ3MpKTtpZihxdWV1ZS5sZW5ndGg9PT0xJiYhZHJhaW5pbmcpe3J1blRpbWVvdXQoZHJhaW5RdWV1ZSl9fTtmdW5jdGlvbiBJdGVtKGZ1bixhcnJheSl7dGhpcy5mdW49ZnVuO3RoaXMuYXJyYXk9YXJyYXl9SXRlbS5wcm90b3R5cGUucnVuPWZ1bmN0aW9uKCl7dGhpcy5mdW4uYXBwbHkobnVsbCx0aGlzLmFycmF5KX07cHJvY2Vzcy50aXRsZT1cImJyb3dzZXJcIjtwcm9jZXNzLmJyb3dzZXI9dHJ1ZTtwcm9jZXNzLmVudj17fTtwcm9jZXNzLmFyZ3Y9W107cHJvY2Vzcy52ZXJzaW9uPVwiXCI7cHJvY2Vzcy52ZXJzaW9ucz17fTtmdW5jdGlvbiBub29wKCl7fXByb2Nlc3Mub249bm9vcDtwcm9jZXNzLmFkZExpc3RlbmVyPW5vb3A7cHJvY2Vzcy5vbmNlPW5vb3A7cHJvY2Vzcy5vZmY9bm9vcDtwcm9jZXNzLnJlbW92ZUxpc3RlbmVyPW5vb3A7cHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnM9bm9vcDtwcm9jZXNzLmVtaXQ9bm9vcDtwcm9jZXNzLmJpbmRpbmc9ZnVuY3Rpb24obmFtZSl7dGhyb3cgbmV3IEVycm9yKFwicHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWRcIil9O3Byb2Nlc3MuY3dkPWZ1bmN0aW9uKCl7cmV0dXJuXCIvXCJ9O3Byb2Nlc3MuY2hkaXI9ZnVuY3Rpb24oZGlyKXt0aHJvdyBuZXcgRXJyb3IoXCJwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWRcIil9O3Byb2Nlc3MudW1hc2s9ZnVuY3Rpb24oKXtyZXR1cm4gMH19LHt9XSw0MzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fZHVwbGV4LmpzXCIpfSx7XCIuL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiOjQ0fV0sNDQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1widXNlIHN0cmljdFwiO3ZhciBvYmplY3RLZXlzPU9iamVjdC5rZXlzfHxmdW5jdGlvbihvYmope3ZhciBrZXlzPVtdO2Zvcih2YXIga2V5IGluIG9iail7a2V5cy5wdXNoKGtleSl9cmV0dXJuIGtleXN9O21vZHVsZS5leHBvcnRzPUR1cGxleDt2YXIgcHJvY2Vzc05leHRUaWNrPXJlcXVpcmUoXCJwcm9jZXNzLW5leHRpY2stYXJnc1wiKTt2YXIgdXRpbD1yZXF1aXJlKFwiY29yZS11dGlsLWlzXCIpO3V0aWwuaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO3ZhciBSZWFkYWJsZT1yZXF1aXJlKFwiLi9fc3RyZWFtX3JlYWRhYmxlXCIpO3ZhciBXcml0YWJsZT1yZXF1aXJlKFwiLi9fc3RyZWFtX3dyaXRhYmxlXCIpO3V0aWwuaW5oZXJpdHMoRHVwbGV4LFJlYWRhYmxlKTt2YXIga2V5cz1vYmplY3RLZXlzKFdyaXRhYmxlLnByb3RvdHlwZSk7Zm9yKHZhciB2PTA7djxrZXlzLmxlbmd0aDt2Kyspe3ZhciBtZXRob2Q9a2V5c1t2XTtpZighRHVwbGV4LnByb3RvdHlwZVttZXRob2RdKUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXT1Xcml0YWJsZS5wcm90b3R5cGVbbWV0aG9kXX1mdW5jdGlvbiBEdXBsZXgob3B0aW9ucyl7aWYoISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSlyZXR1cm4gbmV3IER1cGxleChvcHRpb25zKTtSZWFkYWJsZS5jYWxsKHRoaXMsb3B0aW9ucyk7V3JpdGFibGUuY2FsbCh0aGlzLG9wdGlvbnMpO2lmKG9wdGlvbnMmJm9wdGlvbnMucmVhZGFibGU9PT1mYWxzZSl0aGlzLnJlYWRhYmxlPWZhbHNlO2lmKG9wdGlvbnMmJm9wdGlvbnMud3JpdGFibGU9PT1mYWxzZSl0aGlzLndyaXRhYmxlPWZhbHNlO3RoaXMuYWxsb3dIYWxmT3Blbj10cnVlO2lmKG9wdGlvbnMmJm9wdGlvbnMuYWxsb3dIYWxmT3Blbj09PWZhbHNlKXRoaXMuYWxsb3dIYWxmT3Blbj1mYWxzZTt0aGlzLm9uY2UoXCJlbmRcIixvbmVuZCl9ZnVuY3Rpb24gb25lbmQoKXtpZih0aGlzLmFsbG93SGFsZk9wZW58fHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kZWQpcmV0dXJuO3Byb2Nlc3NOZXh0VGljayhvbkVuZE5ULHRoaXMpfWZ1bmN0aW9uIG9uRW5kTlQoc2VsZil7c2VsZi5lbmQoKX1mdW5jdGlvbiBmb3JFYWNoKHhzLGYpe2Zvcih2YXIgaT0wLGw9eHMubGVuZ3RoO2k8bDtpKyspe2YoeHNbaV0saSl9fX0se1wiLi9fc3RyZWFtX3JlYWRhYmxlXCI6NDYsXCIuL19zdHJlYW1fd3JpdGFibGVcIjo0OCxcImNvcmUtdXRpbC1pc1wiOjYsaW5oZXJpdHM6MzgsXCJwcm9jZXNzLW5leHRpY2stYXJnc1wiOjQxfV0sNDU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1widXNlIHN0cmljdFwiO21vZHVsZS5leHBvcnRzPVBhc3NUaHJvdWdoO3ZhciBUcmFuc2Zvcm09cmVxdWlyZShcIi4vX3N0cmVhbV90cmFuc2Zvcm1cIik7dmFyIHV0aWw9cmVxdWlyZShcImNvcmUtdXRpbC1pc1wiKTt1dGlsLmluaGVyaXRzPXJlcXVpcmUoXCJpbmhlcml0c1wiKTt1dGlsLmluaGVyaXRzKFBhc3NUaHJvdWdoLFRyYW5zZm9ybSk7ZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucyl7aWYoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKXJldHVybiBuZXcgUGFzc1Rocm91Z2gob3B0aW9ucyk7VHJhbnNmb3JtLmNhbGwodGhpcyxvcHRpb25zKX1QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7Y2IobnVsbCxjaHVuayl9fSx7XCIuL19zdHJlYW1fdHJhbnNmb3JtXCI6NDcsXCJjb3JlLXV0aWwtaXNcIjo2LGluaGVyaXRzOjM4fV0sNDY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeyhmdW5jdGlvbihwcm9jZXNzKXtcInVzZSBzdHJpY3RcIjttb2R1bGUuZXhwb3J0cz1SZWFkYWJsZTt2YXIgcHJvY2Vzc05leHRUaWNrPXJlcXVpcmUoXCJwcm9jZXNzLW5leHRpY2stYXJnc1wiKTt2YXIgaXNBcnJheT1yZXF1aXJlKFwiaXNhcnJheVwiKTtSZWFkYWJsZS5SZWFkYWJsZVN0YXRlPVJlYWRhYmxlU3RhdGU7dmFyIEVFPXJlcXVpcmUoXCJldmVudHNcIikuRXZlbnRFbWl0dGVyO3ZhciBFRWxpc3RlbmVyQ291bnQ9ZnVuY3Rpb24oZW1pdHRlcix0eXBlKXtyZXR1cm4gZW1pdHRlci5saXN0ZW5lcnModHlwZSkubGVuZ3RofTt2YXIgU3RyZWFtOyhmdW5jdGlvbigpe3RyeXtTdHJlYW09cmVxdWlyZShcInN0XCIrXCJyZWFtXCIpfWNhdGNoKF8pe31maW5hbGx5e2lmKCFTdHJlYW0pU3RyZWFtPXJlcXVpcmUoXCJldmVudHNcIikuRXZlbnRFbWl0dGVyfX0pKCk7dmFyIEJ1ZmZlcj1yZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcjt2YXIgYnVmZmVyU2hpbT1yZXF1aXJlKFwiYnVmZmVyLXNoaW1zXCIpO3ZhciB1dGlsPXJlcXVpcmUoXCJjb3JlLXV0aWwtaXNcIik7dXRpbC5pbmhlcml0cz1yZXF1aXJlKFwiaW5oZXJpdHNcIik7dmFyIGRlYnVnVXRpbD1yZXF1aXJlKFwidXRpbFwiKTt2YXIgZGVidWc9dm9pZCAwO2lmKGRlYnVnVXRpbCYmZGVidWdVdGlsLmRlYnVnbG9nKXtkZWJ1Zz1kZWJ1Z1V0aWwuZGVidWdsb2coXCJzdHJlYW1cIil9ZWxzZXtkZWJ1Zz1mdW5jdGlvbigpe319dmFyIEJ1ZmZlckxpc3Q9cmVxdWlyZShcIi4vaW50ZXJuYWwvc3RyZWFtcy9CdWZmZXJMaXN0XCIpO3ZhciBTdHJpbmdEZWNvZGVyO3V0aWwuaW5oZXJpdHMoUmVhZGFibGUsU3RyZWFtKTtmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIoZW1pdHRlcixldmVudCxmbil7aWYodHlwZW9mIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyPT09XCJmdW5jdGlvblwiKXtyZXR1cm4gZW1pdHRlci5wcmVwZW5kTGlzdGVuZXIoZXZlbnQsZm4pfWVsc2V7aWYoIWVtaXR0ZXIuX2V2ZW50c3x8IWVtaXR0ZXIuX2V2ZW50c1tldmVudF0pZW1pdHRlci5vbihldmVudCxmbik7ZWxzZSBpZihpc0FycmF5KGVtaXR0ZXIuX2V2ZW50c1tldmVudF0pKWVtaXR0ZXIuX2V2ZW50c1tldmVudF0udW5zaGlmdChmbik7ZWxzZSBlbWl0dGVyLl9ldmVudHNbZXZlbnRdPVtmbixlbWl0dGVyLl9ldmVudHNbZXZlbnRdXX19dmFyIER1cGxleDtmdW5jdGlvbiBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsc3RyZWFtKXtEdXBsZXg9RHVwbGV4fHxyZXF1aXJlKFwiLi9fc3RyZWFtX2R1cGxleFwiKTtvcHRpb25zPW9wdGlvbnN8fHt9O3RoaXMub2JqZWN0TW9kZT0hIW9wdGlvbnMub2JqZWN0TW9kZTtpZihzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXgpdGhpcy5vYmplY3RNb2RlPXRoaXMub2JqZWN0TW9kZXx8ISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTt2YXIgaHdtPW9wdGlvbnMuaGlnaFdhdGVyTWFyazt2YXIgZGVmYXVsdEh3bT10aGlzLm9iamVjdE1vZGU/MTY6MTYqMTAyNDt0aGlzLmhpZ2hXYXRlck1hcms9aHdtfHxod209PT0wP2h3bTpkZWZhdWx0SHdtO3RoaXMuaGlnaFdhdGVyTWFyaz1+fnRoaXMuaGlnaFdhdGVyTWFyazt0aGlzLmJ1ZmZlcj1uZXcgQnVmZmVyTGlzdDt0aGlzLmxlbmd0aD0wO3RoaXMucGlwZXM9bnVsbDt0aGlzLnBpcGVzQ291bnQ9MDt0aGlzLmZsb3dpbmc9bnVsbDt0aGlzLmVuZGVkPWZhbHNlO3RoaXMuZW5kRW1pdHRlZD1mYWxzZTt0aGlzLnJlYWRpbmc9ZmFsc2U7dGhpcy5zeW5jPXRydWU7dGhpcy5uZWVkUmVhZGFibGU9ZmFsc2U7dGhpcy5lbWl0dGVkUmVhZGFibGU9ZmFsc2U7dGhpcy5yZWFkYWJsZUxpc3RlbmluZz1mYWxzZTt0aGlzLnJlc3VtZVNjaGVkdWxlZD1mYWxzZTt0aGlzLmRlZmF1bHRFbmNvZGluZz1vcHRpb25zLmRlZmF1bHRFbmNvZGluZ3x8XCJ1dGY4XCI7dGhpcy5yYW5PdXQ9ZmFsc2U7dGhpcy5hd2FpdERyYWluPTA7dGhpcy5yZWFkaW5nTW9yZT1mYWxzZTt0aGlzLmRlY29kZXI9bnVsbDt0aGlzLmVuY29kaW5nPW51bGw7aWYob3B0aW9ucy5lbmNvZGluZyl7aWYoIVN0cmluZ0RlY29kZXIpU3RyaW5nRGVjb2Rlcj1yZXF1aXJlKFwic3RyaW5nX2RlY29kZXIvXCIpLlN0cmluZ0RlY29kZXI7dGhpcy5kZWNvZGVyPW5ldyBTdHJpbmdEZWNvZGVyKG9wdGlvbnMuZW5jb2RpbmcpO3RoaXMuZW5jb2Rpbmc9b3B0aW9ucy5lbmNvZGluZ319dmFyIER1cGxleDtmdW5jdGlvbiBSZWFkYWJsZShvcHRpb25zKXtEdXBsZXg9RHVwbGV4fHxyZXF1aXJlKFwiLi9fc3RyZWFtX2R1cGxleFwiKTtpZighKHRoaXMgaW5zdGFuY2VvZiBSZWFkYWJsZSkpcmV0dXJuIG5ldyBSZWFkYWJsZShvcHRpb25zKTt0aGlzLl9yZWFkYWJsZVN0YXRlPW5ldyBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsdGhpcyk7dGhpcy5yZWFkYWJsZT10cnVlO2lmKG9wdGlvbnMmJnR5cGVvZiBvcHRpb25zLnJlYWQ9PT1cImZ1bmN0aW9uXCIpdGhpcy5fcmVhZD1vcHRpb25zLnJlYWQ7U3RyZWFtLmNhbGwodGhpcyl9UmVhZGFibGUucHJvdG90eXBlLnB1c2g9ZnVuY3Rpb24oY2h1bmssZW5jb2Rpbmcpe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKCFzdGF0ZS5vYmplY3RNb2RlJiZ0eXBlb2YgY2h1bms9PT1cInN0cmluZ1wiKXtlbmNvZGluZz1lbmNvZGluZ3x8c3RhdGUuZGVmYXVsdEVuY29kaW5nO2lmKGVuY29kaW5nIT09c3RhdGUuZW5jb2Rpbmcpe2NodW5rPWJ1ZmZlclNoaW0uZnJvbShjaHVuayxlbmNvZGluZyk7ZW5jb2Rpbmc9XCJcIn19cmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcyxzdGF0ZSxjaHVuayxlbmNvZGluZyxmYWxzZSl9O1JlYWRhYmxlLnByb3RvdHlwZS51bnNoaWZ0PWZ1bmN0aW9uKGNodW5rKXt2YXIgc3RhdGU9dGhpcy5fcmVhZGFibGVTdGF0ZTtyZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLHN0YXRlLGNodW5rLFwiXCIsdHJ1ZSl9O1JlYWRhYmxlLnByb3RvdHlwZS5pc1BhdXNlZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmc9PT1mYWxzZX07ZnVuY3Rpb24gcmVhZGFibGVBZGRDaHVuayhzdHJlYW0sc3RhdGUsY2h1bmssZW5jb2RpbmcsYWRkVG9Gcm9udCl7dmFyIGVyPWNodW5rSW52YWxpZChzdGF0ZSxjaHVuayk7aWYoZXIpe3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlcil9ZWxzZSBpZihjaHVuaz09PW51bGwpe3N0YXRlLnJlYWRpbmc9ZmFsc2U7b25Fb2ZDaHVuayhzdHJlYW0sc3RhdGUpfWVsc2UgaWYoc3RhdGUub2JqZWN0TW9kZXx8Y2h1bmsmJmNodW5rLmxlbmd0aD4wKXtpZihzdGF0ZS5lbmRlZCYmIWFkZFRvRnJvbnQpe3ZhciBlPW5ldyBFcnJvcihcInN0cmVhbS5wdXNoKCkgYWZ0ZXIgRU9GXCIpO3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlKX1lbHNlIGlmKHN0YXRlLmVuZEVtaXR0ZWQmJmFkZFRvRnJvbnQpe3ZhciBfZT1uZXcgRXJyb3IoXCJzdHJlYW0udW5zaGlmdCgpIGFmdGVyIGVuZCBldmVudFwiKTtzdHJlYW0uZW1pdChcImVycm9yXCIsX2UpfWVsc2V7dmFyIHNraXBBZGQ7aWYoc3RhdGUuZGVjb2RlciYmIWFkZFRvRnJvbnQmJiFlbmNvZGluZyl7Y2h1bms9c3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7c2tpcEFkZD0hc3RhdGUub2JqZWN0TW9kZSYmY2h1bmsubGVuZ3RoPT09MH1pZighYWRkVG9Gcm9udClzdGF0ZS5yZWFkaW5nPWZhbHNlO2lmKCFza2lwQWRkKXtpZihzdGF0ZS5mbG93aW5nJiZzdGF0ZS5sZW5ndGg9PT0wJiYhc3RhdGUuc3luYyl7c3RyZWFtLmVtaXQoXCJkYXRhXCIsY2h1bmspO3N0cmVhbS5yZWFkKDApfWVsc2V7c3RhdGUubGVuZ3RoKz1zdGF0ZS5vYmplY3RNb2RlPzE6Y2h1bmsubGVuZ3RoO2lmKGFkZFRvRnJvbnQpc3RhdGUuYnVmZmVyLnVuc2hpZnQoY2h1bmspO2Vsc2Ugc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO2lmKHN0YXRlLm5lZWRSZWFkYWJsZSllbWl0UmVhZGFibGUoc3RyZWFtKX19bWF5YmVSZWFkTW9yZShzdHJlYW0sc3RhdGUpfX1lbHNlIGlmKCFhZGRUb0Zyb250KXtzdGF0ZS5yZWFkaW5nPWZhbHNlfXJldHVybiBuZWVkTW9yZURhdGEoc3RhdGUpfWZ1bmN0aW9uIG5lZWRNb3JlRGF0YShzdGF0ZSl7cmV0dXJuIXN0YXRlLmVuZGVkJiYoc3RhdGUubmVlZFJlYWRhYmxlfHxzdGF0ZS5sZW5ndGg8c3RhdGUuaGlnaFdhdGVyTWFya3x8c3RhdGUubGVuZ3RoPT09MCl9UmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nPWZ1bmN0aW9uKGVuYyl7aWYoIVN0cmluZ0RlY29kZXIpU3RyaW5nRGVjb2Rlcj1yZXF1aXJlKFwic3RyaW5nX2RlY29kZXIvXCIpLlN0cmluZ0RlY29kZXI7dGhpcy5fcmVhZGFibGVTdGF0ZS5kZWNvZGVyPW5ldyBTdHJpbmdEZWNvZGVyKGVuYyk7dGhpcy5fcmVhZGFibGVTdGF0ZS5lbmNvZGluZz1lbmM7cmV0dXJuIHRoaXN9O3ZhciBNQVhfSFdNPTgzODg2MDg7ZnVuY3Rpb24gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobil7aWYobj49TUFYX0hXTSl7bj1NQVhfSFdNfWVsc2V7bi0tO258PW4+Pj4xO258PW4+Pj4yO258PW4+Pj40O258PW4+Pj44O258PW4+Pj4xNjtuKyt9cmV0dXJuIG59ZnVuY3Rpb24gaG93TXVjaFRvUmVhZChuLHN0YXRlKXtpZihuPD0wfHxzdGF0ZS5sZW5ndGg9PT0wJiZzdGF0ZS5lbmRlZClyZXR1cm4gMDtpZihzdGF0ZS5vYmplY3RNb2RlKXJldHVybiAxO2lmKG4hPT1uKXtpZihzdGF0ZS5mbG93aW5nJiZzdGF0ZS5sZW5ndGgpcmV0dXJuIHN0YXRlLmJ1ZmZlci5oZWFkLmRhdGEubGVuZ3RoO2Vsc2UgcmV0dXJuIHN0YXRlLmxlbmd0aH1pZihuPnN0YXRlLmhpZ2hXYXRlck1hcmspc3RhdGUuaGlnaFdhdGVyTWFyaz1jb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKTtpZihuPD1zdGF0ZS5sZW5ndGgpcmV0dXJuIG47aWYoIXN0YXRlLmVuZGVkKXtzdGF0ZS5uZWVkUmVhZGFibGU9dHJ1ZTtyZXR1cm4gMH1yZXR1cm4gc3RhdGUubGVuZ3RofVJlYWRhYmxlLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKG4pe2RlYnVnKFwicmVhZFwiLG4pO249cGFyc2VJbnQobiwxMCk7dmFyIHN0YXRlPXRoaXMuX3JlYWRhYmxlU3RhdGU7dmFyIG5PcmlnPW47aWYobiE9PTApc3RhdGUuZW1pdHRlZFJlYWRhYmxlPWZhbHNlO2lmKG49PT0wJiZzdGF0ZS5uZWVkUmVhZGFibGUmJihzdGF0ZS5sZW5ndGg+PXN0YXRlLmhpZ2hXYXRlck1hcmt8fHN0YXRlLmVuZGVkKSl7ZGVidWcoXCJyZWFkOiBlbWl0UmVhZGFibGVcIixzdGF0ZS5sZW5ndGgsc3RhdGUuZW5kZWQpO2lmKHN0YXRlLmxlbmd0aD09PTAmJnN0YXRlLmVuZGVkKWVuZFJlYWRhYmxlKHRoaXMpO2Vsc2UgZW1pdFJlYWRhYmxlKHRoaXMpO3JldHVybiBudWxsfW49aG93TXVjaFRvUmVhZChuLHN0YXRlKTtpZihuPT09MCYmc3RhdGUuZW5kZWQpe2lmKHN0YXRlLmxlbmd0aD09PTApZW5kUmVhZGFibGUodGhpcyk7cmV0dXJuIG51bGx9dmFyIGRvUmVhZD1zdGF0ZS5uZWVkUmVhZGFibGU7ZGVidWcoXCJuZWVkIHJlYWRhYmxlXCIsZG9SZWFkKTtpZihzdGF0ZS5sZW5ndGg9PT0wfHxzdGF0ZS5sZW5ndGgtbjxzdGF0ZS5oaWdoV2F0ZXJNYXJrKXtkb1JlYWQ9dHJ1ZTtkZWJ1ZyhcImxlbmd0aCBsZXNzIHRoYW4gd2F0ZXJtYXJrXCIsZG9SZWFkKX1pZihzdGF0ZS5lbmRlZHx8c3RhdGUucmVhZGluZyl7ZG9SZWFkPWZhbHNlO2RlYnVnKFwicmVhZGluZyBvciBlbmRlZFwiLGRvUmVhZCl9ZWxzZSBpZihkb1JlYWQpe2RlYnVnKFwiZG8gcmVhZFwiKTtzdGF0ZS5yZWFkaW5nPXRydWU7c3RhdGUuc3luYz10cnVlO2lmKHN0YXRlLmxlbmd0aD09PTApc3RhdGUubmVlZFJlYWRhYmxlPXRydWU7dGhpcy5fcmVhZChzdGF0ZS5oaWdoV2F0ZXJNYXJrKTtzdGF0ZS5zeW5jPWZhbHNlO2lmKCFzdGF0ZS5yZWFkaW5nKW49aG93TXVjaFRvUmVhZChuT3JpZyxzdGF0ZSl9dmFyIHJldDtpZihuPjApcmV0PWZyb21MaXN0KG4sc3RhdGUpO2Vsc2UgcmV0PW51bGw7aWYocmV0PT09bnVsbCl7c3RhdGUubmVlZFJlYWRhYmxlPXRydWU7bj0wfWVsc2V7c3RhdGUubGVuZ3RoLT1ufWlmKHN0YXRlLmxlbmd0aD09PTApe2lmKCFzdGF0ZS5lbmRlZClzdGF0ZS5uZWVkUmVhZGFibGU9dHJ1ZTtpZihuT3JpZyE9PW4mJnN0YXRlLmVuZGVkKWVuZFJlYWRhYmxlKHRoaXMpfWlmKHJldCE9PW51bGwpdGhpcy5lbWl0KFwiZGF0YVwiLHJldCk7cmV0dXJuIHJldH07ZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLGNodW5rKXt2YXIgZXI9bnVsbDtpZighQnVmZmVyLmlzQnVmZmVyKGNodW5rKSYmdHlwZW9mIGNodW5rIT09XCJzdHJpbmdcIiYmY2h1bmshPT1udWxsJiZjaHVuayE9PXVuZGVmaW5lZCYmIXN0YXRlLm9iamVjdE1vZGUpe2VyPW5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rXCIpfXJldHVybiBlcn1mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSxzdGF0ZSl7aWYoc3RhdGUuZW5kZWQpcmV0dXJuO2lmKHN0YXRlLmRlY29kZXIpe3ZhciBjaHVuaz1zdGF0ZS5kZWNvZGVyLmVuZCgpO2lmKGNodW5rJiZjaHVuay5sZW5ndGgpe3N0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtzdGF0ZS5sZW5ndGgrPXN0YXRlLm9iamVjdE1vZGU/MTpjaHVuay5sZW5ndGh9fXN0YXRlLmVuZGVkPXRydWU7ZW1pdFJlYWRhYmxlKHN0cmVhbSl9ZnVuY3Rpb24gZW1pdFJlYWRhYmxlKHN0cmVhbSl7dmFyIHN0YXRlPXN0cmVhbS5fcmVhZGFibGVTdGF0ZTtzdGF0ZS5uZWVkUmVhZGFibGU9ZmFsc2U7aWYoIXN0YXRlLmVtaXR0ZWRSZWFkYWJsZSl7ZGVidWcoXCJlbWl0UmVhZGFibGVcIixzdGF0ZS5mbG93aW5nKTtzdGF0ZS5lbWl0dGVkUmVhZGFibGU9dHJ1ZTtpZihzdGF0ZS5zeW5jKXByb2Nlc3NOZXh0VGljayhlbWl0UmVhZGFibGVfLHN0cmVhbSk7ZWxzZSBlbWl0UmVhZGFibGVfKHN0cmVhbSl9fWZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKXtkZWJ1ZyhcImVtaXQgcmVhZGFibGVcIik7c3RyZWFtLmVtaXQoXCJyZWFkYWJsZVwiKTtmbG93KHN0cmVhbSl9ZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sc3RhdGUpe2lmKCFzdGF0ZS5yZWFkaW5nTW9yZSl7c3RhdGUucmVhZGluZ01vcmU9dHJ1ZTtwcm9jZXNzTmV4dFRpY2sobWF5YmVSZWFkTW9yZV8sc3RyZWFtLHN0YXRlKX19ZnVuY3Rpb24gbWF5YmVSZWFkTW9yZV8oc3RyZWFtLHN0YXRlKXt2YXIgbGVuPXN0YXRlLmxlbmd0aDt3aGlsZSghc3RhdGUucmVhZGluZyYmIXN0YXRlLmZsb3dpbmcmJiFzdGF0ZS5lbmRlZCYmc3RhdGUubGVuZ3RoPHN0YXRlLmhpZ2hXYXRlck1hcmspe2RlYnVnKFwibWF5YmVSZWFkTW9yZSByZWFkIDBcIik7c3RyZWFtLnJlYWQoMCk7aWYobGVuPT09c3RhdGUubGVuZ3RoKWJyZWFrO2Vsc2UgbGVuPXN0YXRlLmxlbmd0aH1zdGF0ZS5yZWFkaW5nTW9yZT1mYWxzZX1SZWFkYWJsZS5wcm90b3R5cGUuX3JlYWQ9ZnVuY3Rpb24obil7dGhpcy5lbWl0KFwiZXJyb3JcIixuZXcgRXJyb3IoXCJub3QgaW1wbGVtZW50ZWRcIikpfTtSZWFkYWJsZS5wcm90b3R5cGUucGlwZT1mdW5jdGlvbihkZXN0LHBpcGVPcHRzKXt2YXIgc3JjPXRoaXM7dmFyIHN0YXRlPXRoaXMuX3JlYWRhYmxlU3RhdGU7c3dpdGNoKHN0YXRlLnBpcGVzQ291bnQpe2Nhc2UgMDpzdGF0ZS5waXBlcz1kZXN0O2JyZWFrO2Nhc2UgMTpzdGF0ZS5waXBlcz1bc3RhdGUucGlwZXMsZGVzdF07YnJlYWs7ZGVmYXVsdDpzdGF0ZS5waXBlcy5wdXNoKGRlc3QpO2JyZWFrfXN0YXRlLnBpcGVzQ291bnQrPTE7ZGVidWcoXCJwaXBlIGNvdW50PSVkIG9wdHM9JWpcIixzdGF0ZS5waXBlc0NvdW50LHBpcGVPcHRzKTt2YXIgZG9FbmQ9KCFwaXBlT3B0c3x8cGlwZU9wdHMuZW5kIT09ZmFsc2UpJiZkZXN0IT09cHJvY2Vzcy5zdGRvdXQmJmRlc3QhPT1wcm9jZXNzLnN0ZGVycjt2YXIgZW5kRm49ZG9FbmQ/b25lbmQ6Y2xlYW51cDtpZihzdGF0ZS5lbmRFbWl0dGVkKXByb2Nlc3NOZXh0VGljayhlbmRGbik7ZWxzZSBzcmMub25jZShcImVuZFwiLGVuZEZuKTtkZXN0Lm9uKFwidW5waXBlXCIsb251bnBpcGUpO2Z1bmN0aW9uIG9udW5waXBlKHJlYWRhYmxlKXtkZWJ1ZyhcIm9udW5waXBlXCIpO2lmKHJlYWRhYmxlPT09c3JjKXtjbGVhbnVwKCl9fWZ1bmN0aW9uIG9uZW5kKCl7ZGVidWcoXCJvbmVuZFwiKTtkZXN0LmVuZCgpfXZhciBvbmRyYWluPXBpcGVPbkRyYWluKHNyYyk7ZGVzdC5vbihcImRyYWluXCIsb25kcmFpbik7dmFyIGNsZWFuZWRVcD1mYWxzZTtmdW5jdGlvbiBjbGVhbnVwKCl7ZGVidWcoXCJjbGVhbnVwXCIpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJjbG9zZVwiLG9uY2xvc2UpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJmaW5pc2hcIixvbmZpbmlzaCk7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImRyYWluXCIsb25kcmFpbik7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImVycm9yXCIsb25lcnJvcik7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcInVucGlwZVwiLG9udW5waXBlKTtzcmMucmVtb3ZlTGlzdGVuZXIoXCJlbmRcIixvbmVuZCk7c3JjLnJlbW92ZUxpc3RlbmVyKFwiZW5kXCIsY2xlYW51cCk7c3JjLnJlbW92ZUxpc3RlbmVyKFwiZGF0YVwiLG9uZGF0YSk7Y2xlYW5lZFVwPXRydWU7aWYoc3RhdGUuYXdhaXREcmFpbiYmKCFkZXN0Ll93cml0YWJsZVN0YXRlfHxkZXN0Ll93cml0YWJsZVN0YXRlLm5lZWREcmFpbikpb25kcmFpbigpfXZhciBpbmNyZWFzZWRBd2FpdERyYWluPWZhbHNlO3NyYy5vbihcImRhdGFcIixvbmRhdGEpO2Z1bmN0aW9uIG9uZGF0YShjaHVuayl7ZGVidWcoXCJvbmRhdGFcIik7aW5jcmVhc2VkQXdhaXREcmFpbj1mYWxzZTt2YXIgcmV0PWRlc3Qud3JpdGUoY2h1bmspO2lmKGZhbHNlPT09cmV0JiYhaW5jcmVhc2VkQXdhaXREcmFpbil7aWYoKHN0YXRlLnBpcGVzQ291bnQ9PT0xJiZzdGF0ZS5waXBlcz09PWRlc3R8fHN0YXRlLnBpcGVzQ291bnQ+MSYmaW5kZXhPZihzdGF0ZS5waXBlcyxkZXN0KSE9PS0xKSYmIWNsZWFuZWRVcCl7ZGVidWcoXCJmYWxzZSB3cml0ZSByZXNwb25zZSwgcGF1c2VcIixzcmMuX3JlYWRhYmxlU3RhdGUuYXdhaXREcmFpbik7c3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4rKztpbmNyZWFzZWRBd2FpdERyYWluPXRydWV9c3JjLnBhdXNlKCl9fWZ1bmN0aW9uIG9uZXJyb3IoZXIpe2RlYnVnKFwib25lcnJvclwiLGVyKTt1bnBpcGUoKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZXJyb3JcIixvbmVycm9yKTtpZihFRWxpc3RlbmVyQ291bnQoZGVzdCxcImVycm9yXCIpPT09MClkZXN0LmVtaXQoXCJlcnJvclwiLGVyKX1wcmVwZW5kTGlzdGVuZXIoZGVzdCxcImVycm9yXCIsb25lcnJvcik7ZnVuY3Rpb24gb25jbG9zZSgpe2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJmaW5pc2hcIixvbmZpbmlzaCk7dW5waXBlKCl9ZGVzdC5vbmNlKFwiY2xvc2VcIixvbmNsb3NlKTtmdW5jdGlvbiBvbmZpbmlzaCgpe2RlYnVnKFwib25maW5pc2hcIik7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImNsb3NlXCIsb25jbG9zZSk7dW5waXBlKCl9ZGVzdC5vbmNlKFwiZmluaXNoXCIsb25maW5pc2gpO2Z1bmN0aW9uIHVucGlwZSgpe2RlYnVnKFwidW5waXBlXCIpO3NyYy51bnBpcGUoZGVzdCl9ZGVzdC5lbWl0KFwicGlwZVwiLHNyYyk7aWYoIXN0YXRlLmZsb3dpbmcpe2RlYnVnKFwicGlwZSByZXN1bWVcIik7c3JjLnJlc3VtZSgpfXJldHVybiBkZXN0fTtmdW5jdGlvbiBwaXBlT25EcmFpbihzcmMpe3JldHVybiBmdW5jdGlvbigpe3ZhciBzdGF0ZT1zcmMuX3JlYWRhYmxlU3RhdGU7ZGVidWcoXCJwaXBlT25EcmFpblwiLHN0YXRlLmF3YWl0RHJhaW4pO2lmKHN0YXRlLmF3YWl0RHJhaW4pc3RhdGUuYXdhaXREcmFpbi0tO2lmKHN0YXRlLmF3YWl0RHJhaW49PT0wJiZFRWxpc3RlbmVyQ291bnQoc3JjLFwiZGF0YVwiKSl7c3RhdGUuZmxvd2luZz10cnVlO2Zsb3coc3JjKX19fVJlYWRhYmxlLnByb3RvdHlwZS51bnBpcGU9ZnVuY3Rpb24oZGVzdCl7dmFyIHN0YXRlPXRoaXMuX3JlYWRhYmxlU3RhdGU7aWYoc3RhdGUucGlwZXNDb3VudD09PTApcmV0dXJuIHRoaXM7aWYoc3RhdGUucGlwZXNDb3VudD09PTEpe2lmKGRlc3QmJmRlc3QhPT1zdGF0ZS5waXBlcylyZXR1cm4gdGhpcztpZighZGVzdClkZXN0PXN0YXRlLnBpcGVzO3N0YXRlLnBpcGVzPW51bGw7c3RhdGUucGlwZXNDb3VudD0wO3N0YXRlLmZsb3dpbmc9ZmFsc2U7aWYoZGVzdClkZXN0LmVtaXQoXCJ1bnBpcGVcIix0aGlzKTtyZXR1cm4gdGhpc31pZighZGVzdCl7dmFyIGRlc3RzPXN0YXRlLnBpcGVzO3ZhciBsZW49c3RhdGUucGlwZXNDb3VudDtzdGF0ZS5waXBlcz1udWxsO3N0YXRlLnBpcGVzQ291bnQ9MDtzdGF0ZS5mbG93aW5nPWZhbHNlO2Zvcih2YXIgX2k9MDtfaTxsZW47X2krKyl7ZGVzdHNbX2ldLmVtaXQoXCJ1bnBpcGVcIix0aGlzKX1yZXR1cm4gdGhpc312YXIgaT1pbmRleE9mKHN0YXRlLnBpcGVzLGRlc3QpO2lmKGk9PT0tMSlyZXR1cm4gdGhpcztzdGF0ZS5waXBlcy5zcGxpY2UoaSwxKTtzdGF0ZS5waXBlc0NvdW50LT0xO2lmKHN0YXRlLnBpcGVzQ291bnQ9PT0xKXN0YXRlLnBpcGVzPXN0YXRlLnBpcGVzWzBdO2Rlc3QuZW1pdChcInVucGlwZVwiLHRoaXMpO3JldHVybiB0aGlzfTtSZWFkYWJsZS5wcm90b3R5cGUub249ZnVuY3Rpb24oZXYsZm4pe3ZhciByZXM9U3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKHRoaXMsZXYsZm4pO2lmKGV2PT09XCJkYXRhXCIpe2lmKHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyE9PWZhbHNlKXRoaXMucmVzdW1lKCl9ZWxzZSBpZihldj09PVwicmVhZGFibGVcIil7dmFyIHN0YXRlPXRoaXMuX3JlYWRhYmxlU3RhdGU7aWYoIXN0YXRlLmVuZEVtaXR0ZWQmJiFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZyl7c3RhdGUucmVhZGFibGVMaXN0ZW5pbmc9c3RhdGUubmVlZFJlYWRhYmxlPXRydWU7c3RhdGUuZW1pdHRlZFJlYWRhYmxlPWZhbHNlO2lmKCFzdGF0ZS5yZWFkaW5nKXtwcm9jZXNzTmV4dFRpY2soblJlYWRpbmdOZXh0VGljayx0aGlzKX1lbHNlIGlmKHN0YXRlLmxlbmd0aCl7ZW1pdFJlYWRhYmxlKHRoaXMsc3RhdGUpfX19cmV0dXJuIHJlc307UmVhZGFibGUucHJvdG90eXBlLmFkZExpc3RlbmVyPVJlYWRhYmxlLnByb3RvdHlwZS5vbjtmdW5jdGlvbiBuUmVhZGluZ05leHRUaWNrKHNlbGYpe2RlYnVnKFwicmVhZGFibGUgbmV4dHRpY2sgcmVhZCAwXCIpO3NlbGYucmVhZCgwKX1SZWFkYWJsZS5wcm90b3R5cGUucmVzdW1lPWZ1bmN0aW9uKCl7dmFyIHN0YXRlPXRoaXMuX3JlYWRhYmxlU3RhdGU7aWYoIXN0YXRlLmZsb3dpbmcpe2RlYnVnKFwicmVzdW1lXCIpO3N0YXRlLmZsb3dpbmc9dHJ1ZTtyZXN1bWUodGhpcyxzdGF0ZSl9cmV0dXJuIHRoaXN9O2Z1bmN0aW9uIHJlc3VtZShzdHJlYW0sc3RhdGUpe2lmKCFzdGF0ZS5yZXN1bWVTY2hlZHVsZWQpe3N0YXRlLnJlc3VtZVNjaGVkdWxlZD10cnVlO3Byb2Nlc3NOZXh0VGljayhyZXN1bWVfLHN0cmVhbSxzdGF0ZSl9fWZ1bmN0aW9uIHJlc3VtZV8oc3RyZWFtLHN0YXRlKXtpZighc3RhdGUucmVhZGluZyl7ZGVidWcoXCJyZXN1bWUgcmVhZCAwXCIpO3N0cmVhbS5yZWFkKDApfXN0YXRlLnJlc3VtZVNjaGVkdWxlZD1mYWxzZTtzdGF0ZS5hd2FpdERyYWluPTA7c3RyZWFtLmVtaXQoXCJyZXN1bWVcIik7ZmxvdyhzdHJlYW0pO2lmKHN0YXRlLmZsb3dpbmcmJiFzdGF0ZS5yZWFkaW5nKXN0cmVhbS5yZWFkKDApfVJlYWRhYmxlLnByb3RvdHlwZS5wYXVzZT1mdW5jdGlvbigpe2RlYnVnKFwiY2FsbCBwYXVzZSBmbG93aW5nPSVqXCIsdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKTtpZihmYWxzZSE9PXRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyl7ZGVidWcoXCJwYXVzZVwiKTt0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmc9ZmFsc2U7dGhpcy5lbWl0KFwicGF1c2VcIil9cmV0dXJuIHRoaXN9O2Z1bmN0aW9uIGZsb3coc3RyZWFtKXt2YXIgc3RhdGU9c3RyZWFtLl9yZWFkYWJsZVN0YXRlO2RlYnVnKFwiZmxvd1wiLHN0YXRlLmZsb3dpbmcpO3doaWxlKHN0YXRlLmZsb3dpbmcmJnN0cmVhbS5yZWFkKCkhPT1udWxsKXt9fVJlYWRhYmxlLnByb3RvdHlwZS53cmFwPWZ1bmN0aW9uKHN0cmVhbSl7dmFyIHN0YXRlPXRoaXMuX3JlYWRhYmxlU3RhdGU7dmFyIHBhdXNlZD1mYWxzZTt2YXIgc2VsZj10aGlzO3N0cmVhbS5vbihcImVuZFwiLGZ1bmN0aW9uKCl7ZGVidWcoXCJ3cmFwcGVkIGVuZFwiKTtpZihzdGF0ZS5kZWNvZGVyJiYhc3RhdGUuZW5kZWQpe3ZhciBjaHVuaz1zdGF0ZS5kZWNvZGVyLmVuZCgpO2lmKGNodW5rJiZjaHVuay5sZW5ndGgpc2VsZi5wdXNoKGNodW5rKX1zZWxmLnB1c2gobnVsbCl9KTtzdHJlYW0ub24oXCJkYXRhXCIsZnVuY3Rpb24oY2h1bmspe2RlYnVnKFwid3JhcHBlZCBkYXRhXCIpO2lmKHN0YXRlLmRlY29kZXIpY2h1bms9c3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7aWYoc3RhdGUub2JqZWN0TW9kZSYmKGNodW5rPT09bnVsbHx8Y2h1bms9PT11bmRlZmluZWQpKXJldHVybjtlbHNlIGlmKCFzdGF0ZS5vYmplY3RNb2RlJiYoIWNodW5rfHwhY2h1bmsubGVuZ3RoKSlyZXR1cm47dmFyIHJldD1zZWxmLnB1c2goY2h1bmspO2lmKCFyZXQpe3BhdXNlZD10cnVlO3N0cmVhbS5wYXVzZSgpfX0pO2Zvcih2YXIgaSBpbiBzdHJlYW0pe2lmKHRoaXNbaV09PT11bmRlZmluZWQmJnR5cGVvZiBzdHJlYW1baV09PT1cImZ1bmN0aW9uXCIpe3RoaXNbaV09ZnVuY3Rpb24obWV0aG9kKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gc3RyZWFtW21ldGhvZF0uYXBwbHkoc3RyZWFtLGFyZ3VtZW50cyl9fShpKX19dmFyIGV2ZW50cz1bXCJlcnJvclwiLFwiY2xvc2VcIixcImRlc3Ryb3lcIixcInBhdXNlXCIsXCJyZXN1bWVcIl07Zm9yRWFjaChldmVudHMsZnVuY3Rpb24oZXYpe3N0cmVhbS5vbihldixzZWxmLmVtaXQuYmluZChzZWxmLGV2KSl9KTtzZWxmLl9yZWFkPWZ1bmN0aW9uKG4pe2RlYnVnKFwid3JhcHBlZCBfcmVhZFwiLG4pO2lmKHBhdXNlZCl7cGF1c2VkPWZhbHNlO3N0cmVhbS5yZXN1bWUoKX19O3JldHVybiBzZWxmfTtSZWFkYWJsZS5fZnJvbUxpc3Q9ZnJvbUxpc3Q7ZnVuY3Rpb24gZnJvbUxpc3QobixzdGF0ZSl7aWYoc3RhdGUubGVuZ3RoPT09MClyZXR1cm4gbnVsbDt2YXIgcmV0O2lmKHN0YXRlLm9iamVjdE1vZGUpcmV0PXN0YXRlLmJ1ZmZlci5zaGlmdCgpO2Vsc2UgaWYoIW58fG4+PXN0YXRlLmxlbmd0aCl7aWYoc3RhdGUuZGVjb2RlcilyZXQ9c3RhdGUuYnVmZmVyLmpvaW4oXCJcIik7ZWxzZSBpZihzdGF0ZS5idWZmZXIubGVuZ3RoPT09MSlyZXQ9c3RhdGUuYnVmZmVyLmhlYWQuZGF0YTtlbHNlIHJldD1zdGF0ZS5idWZmZXIuY29uY2F0KHN0YXRlLmxlbmd0aCk7c3RhdGUuYnVmZmVyLmNsZWFyKCl9ZWxzZXtyZXQ9ZnJvbUxpc3RQYXJ0aWFsKG4sc3RhdGUuYnVmZmVyLHN0YXRlLmRlY29kZXIpfXJldHVybiByZXR9ZnVuY3Rpb24gZnJvbUxpc3RQYXJ0aWFsKG4sbGlzdCxoYXNTdHJpbmdzKXt2YXIgcmV0O2lmKG48bGlzdC5oZWFkLmRhdGEubGVuZ3RoKXtyZXQ9bGlzdC5oZWFkLmRhdGEuc2xpY2UoMCxuKTtsaXN0LmhlYWQuZGF0YT1saXN0LmhlYWQuZGF0YS5zbGljZShuKX1lbHNlIGlmKG49PT1saXN0LmhlYWQuZGF0YS5sZW5ndGgpe3JldD1saXN0LnNoaWZ0KCl9ZWxzZXtyZXQ9aGFzU3RyaW5ncz9jb3B5RnJvbUJ1ZmZlclN0cmluZyhuLGxpc3QpOmNvcHlGcm9tQnVmZmVyKG4sbGlzdCl9cmV0dXJuIHJldH1mdW5jdGlvbiBjb3B5RnJvbUJ1ZmZlclN0cmluZyhuLGxpc3Qpe3ZhciBwPWxpc3QuaGVhZDt2YXIgYz0xO3ZhciByZXQ9cC5kYXRhO24tPXJldC5sZW5ndGg7d2hpbGUocD1wLm5leHQpe3ZhciBzdHI9cC5kYXRhO3ZhciBuYj1uPnN0ci5sZW5ndGg/c3RyLmxlbmd0aDpuO2lmKG5iPT09c3RyLmxlbmd0aClyZXQrPXN0cjtlbHNlIHJldCs9c3RyLnNsaWNlKDAsbik7bi09bmI7aWYobj09PTApe2lmKG5iPT09c3RyLmxlbmd0aCl7KytjO2lmKHAubmV4dClsaXN0LmhlYWQ9cC5uZXh0O2Vsc2UgbGlzdC5oZWFkPWxpc3QudGFpbD1udWxsfWVsc2V7bGlzdC5oZWFkPXA7cC5kYXRhPXN0ci5zbGljZShuYil9YnJlYWt9KytjfWxpc3QubGVuZ3RoLT1jO3JldHVybiByZXR9ZnVuY3Rpb24gY29weUZyb21CdWZmZXIobixsaXN0KXt2YXIgcmV0PWJ1ZmZlclNoaW0uYWxsb2NVbnNhZmUobik7dmFyIHA9bGlzdC5oZWFkO3ZhciBjPTE7cC5kYXRhLmNvcHkocmV0KTtuLT1wLmRhdGEubGVuZ3RoO3doaWxlKHA9cC5uZXh0KXt2YXIgYnVmPXAuZGF0YTt2YXIgbmI9bj5idWYubGVuZ3RoP2J1Zi5sZW5ndGg6bjtidWYuY29weShyZXQscmV0Lmxlbmd0aC1uLDAsbmIpO24tPW5iO2lmKG49PT0wKXtpZihuYj09PWJ1Zi5sZW5ndGgpeysrYztpZihwLm5leHQpbGlzdC5oZWFkPXAubmV4dDtlbHNlIGxpc3QuaGVhZD1saXN0LnRhaWw9bnVsbH1lbHNle2xpc3QuaGVhZD1wO3AuZGF0YT1idWYuc2xpY2UobmIpfWJyZWFrfSsrY31saXN0Lmxlbmd0aC09YztyZXR1cm4gcmV0fWZ1bmN0aW9uIGVuZFJlYWRhYmxlKHN0cmVhbSl7dmFyIHN0YXRlPXN0cmVhbS5fcmVhZGFibGVTdGF0ZTtpZihzdGF0ZS5sZW5ndGg+MCl0aHJvdyBuZXcgRXJyb3IoJ1wiZW5kUmVhZGFibGUoKVwiIGNhbGxlZCBvbiBub24tZW1wdHkgc3RyZWFtJyk7aWYoIXN0YXRlLmVuZEVtaXR0ZWQpe3N0YXRlLmVuZGVkPXRydWU7cHJvY2Vzc05leHRUaWNrKGVuZFJlYWRhYmxlTlQsc3RhdGUsc3RyZWFtKX19ZnVuY3Rpb24gZW5kUmVhZGFibGVOVChzdGF0ZSxzdHJlYW0pe2lmKCFzdGF0ZS5lbmRFbWl0dGVkJiZzdGF0ZS5sZW5ndGg9PT0wKXtzdGF0ZS5lbmRFbWl0dGVkPXRydWU7c3RyZWFtLnJlYWRhYmxlPWZhbHNlO3N0cmVhbS5lbWl0KFwiZW5kXCIpfX1mdW5jdGlvbiBmb3JFYWNoKHhzLGYpe2Zvcih2YXIgaT0wLGw9eHMubGVuZ3RoO2k8bDtpKyspe2YoeHNbaV0saSl9fWZ1bmN0aW9uIGluZGV4T2YoeHMseCl7Zm9yKHZhciBpPTAsbD14cy5sZW5ndGg7aTxsO2krKyl7aWYoeHNbaV09PT14KXJldHVybiBpfXJldHVybi0xfX0pLmNhbGwodGhpcyxyZXF1aXJlKFwiX3Byb2Nlc3NcIikpfSx7XCIuL19zdHJlYW1fZHVwbGV4XCI6NDQsXCIuL2ludGVybmFsL3N0cmVhbXMvQnVmZmVyTGlzdFwiOjQ5LF9wcm9jZXNzOjQyLGJ1ZmZlcjo1LFwiYnVmZmVyLXNoaW1zXCI6NCxcImNvcmUtdXRpbC1pc1wiOjYsZXZlbnRzOjI4LGluaGVyaXRzOjM4LGlzYXJyYXk6NDAsXCJwcm9jZXNzLW5leHRpY2stYXJnc1wiOjQxLFwic3RyaW5nX2RlY29kZXIvXCI6NTYsdXRpbDozfV0sNDc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1widXNlIHN0cmljdFwiO21vZHVsZS5leHBvcnRzPVRyYW5zZm9ybTt2YXIgRHVwbGV4PXJlcXVpcmUoXCIuL19zdHJlYW1fZHVwbGV4XCIpO3ZhciB1dGlsPXJlcXVpcmUoXCJjb3JlLXV0aWwtaXNcIik7dXRpbC5pbmhlcml0cz1yZXF1aXJlKFwiaW5oZXJpdHNcIik7dXRpbC5pbmhlcml0cyhUcmFuc2Zvcm0sRHVwbGV4KTtmdW5jdGlvbiBUcmFuc2Zvcm1TdGF0ZShzdHJlYW0pe3RoaXMuYWZ0ZXJUcmFuc2Zvcm09ZnVuY3Rpb24oZXIsZGF0YSl7cmV0dXJuIGFmdGVyVHJhbnNmb3JtKHN0cmVhbSxlcixkYXRhKX07dGhpcy5uZWVkVHJhbnNmb3JtPWZhbHNlO3RoaXMudHJhbnNmb3JtaW5nPWZhbHNlO3RoaXMud3JpdGVjYj1udWxsO3RoaXMud3JpdGVjaHVuaz1udWxsO3RoaXMud3JpdGVlbmNvZGluZz1udWxsfWZ1bmN0aW9uIGFmdGVyVHJhbnNmb3JtKHN0cmVhbSxlcixkYXRhKXt2YXIgdHM9c3RyZWFtLl90cmFuc2Zvcm1TdGF0ZTt0cy50cmFuc2Zvcm1pbmc9ZmFsc2U7dmFyIGNiPXRzLndyaXRlY2I7aWYoIWNiKXJldHVybiBzdHJlYW0uZW1pdChcImVycm9yXCIsbmV3IEVycm9yKFwibm8gd3JpdGVjYiBpbiBUcmFuc2Zvcm0gY2xhc3NcIikpO3RzLndyaXRlY2h1bms9bnVsbDt0cy53cml0ZWNiPW51bGw7aWYoZGF0YSE9PW51bGwmJmRhdGEhPT11bmRlZmluZWQpc3RyZWFtLnB1c2goZGF0YSk7Y2IoZXIpO3ZhciBycz1zdHJlYW0uX3JlYWRhYmxlU3RhdGU7cnMucmVhZGluZz1mYWxzZTtpZihycy5uZWVkUmVhZGFibGV8fHJzLmxlbmd0aDxycy5oaWdoV2F0ZXJNYXJrKXtzdHJlYW0uX3JlYWQocnMuaGlnaFdhdGVyTWFyayl9fWZ1bmN0aW9uIFRyYW5zZm9ybShvcHRpb25zKXtpZighKHRoaXMgaW5zdGFuY2VvZiBUcmFuc2Zvcm0pKXJldHVybiBuZXcgVHJhbnNmb3JtKG9wdGlvbnMpO0R1cGxleC5jYWxsKHRoaXMsb3B0aW9ucyk7dGhpcy5fdHJhbnNmb3JtU3RhdGU9bmV3IFRyYW5zZm9ybVN0YXRlKHRoaXMpO3ZhciBzdHJlYW09dGhpczt0aGlzLl9yZWFkYWJsZVN0YXRlLm5lZWRSZWFkYWJsZT10cnVlO3RoaXMuX3JlYWRhYmxlU3RhdGUuc3luYz1mYWxzZTtpZihvcHRpb25zKXtpZih0eXBlb2Ygb3B0aW9ucy50cmFuc2Zvcm09PT1cImZ1bmN0aW9uXCIpdGhpcy5fdHJhbnNmb3JtPW9wdGlvbnMudHJhbnNmb3JtO2lmKHR5cGVvZiBvcHRpb25zLmZsdXNoPT09XCJmdW5jdGlvblwiKXRoaXMuX2ZsdXNoPW9wdGlvbnMuZmx1c2h9dGhpcy5vbmNlKFwicHJlZmluaXNoXCIsZnVuY3Rpb24oKXtpZih0eXBlb2YgdGhpcy5fZmx1c2g9PT1cImZ1bmN0aW9uXCIpdGhpcy5fZmx1c2goZnVuY3Rpb24oZXIpe2RvbmUoc3RyZWFtLGVyKX0pO2Vsc2UgZG9uZShzdHJlYW0pfSl9VHJhbnNmb3JtLnByb3RvdHlwZS5wdXNoPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nKXt0aGlzLl90cmFuc2Zvcm1TdGF0ZS5uZWVkVHJhbnNmb3JtPWZhbHNlO3JldHVybiBEdXBsZXgucHJvdG90eXBlLnB1c2guY2FsbCh0aGlzLGNodW5rLGVuY29kaW5nKX07VHJhbnNmb3JtLnByb3RvdHlwZS5fdHJhbnNmb3JtPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXt0aHJvdyBuZXcgRXJyb3IoXCJOb3QgaW1wbGVtZW50ZWRcIil9O1RyYW5zZm9ybS5wcm90b3R5cGUuX3dyaXRlPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXt2YXIgdHM9dGhpcy5fdHJhbnNmb3JtU3RhdGU7dHMud3JpdGVjYj1jYjt0cy53cml0ZWNodW5rPWNodW5rO3RzLndyaXRlZW5jb2Rpbmc9ZW5jb2Rpbmc7aWYoIXRzLnRyYW5zZm9ybWluZyl7dmFyIHJzPXRoaXMuX3JlYWRhYmxlU3RhdGU7aWYodHMubmVlZFRyYW5zZm9ybXx8cnMubmVlZFJlYWRhYmxlfHxycy5sZW5ndGg8cnMuaGlnaFdhdGVyTWFyayl0aGlzLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspfX07VHJhbnNmb3JtLnByb3RvdHlwZS5fcmVhZD1mdW5jdGlvbihuKXt2YXIgdHM9dGhpcy5fdHJhbnNmb3JtU3RhdGU7aWYodHMud3JpdGVjaHVuayE9PW51bGwmJnRzLndyaXRlY2ImJiF0cy50cmFuc2Zvcm1pbmcpe3RzLnRyYW5zZm9ybWluZz10cnVlO3RoaXMuX3RyYW5zZm9ybSh0cy53cml0ZWNodW5rLHRzLndyaXRlZW5jb2RpbmcsdHMuYWZ0ZXJUcmFuc2Zvcm0pfWVsc2V7dHMubmVlZFRyYW5zZm9ybT10cnVlfX07ZnVuY3Rpb24gZG9uZShzdHJlYW0sZXIpe2lmKGVyKXJldHVybiBzdHJlYW0uZW1pdChcImVycm9yXCIsZXIpO3ZhciB3cz1zdHJlYW0uX3dyaXRhYmxlU3RhdGU7dmFyIHRzPXN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7aWYod3MubGVuZ3RoKXRocm93IG5ldyBFcnJvcihcIkNhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiB3cy5sZW5ndGggIT0gMFwiKTtpZih0cy50cmFuc2Zvcm1pbmcpdGhyb3cgbmV3IEVycm9yKFwiQ2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHN0aWxsIHRyYW5zZm9ybWluZ1wiKTtyZXR1cm4gc3RyZWFtLnB1c2gobnVsbCl9fSx7XCIuL19zdHJlYW1fZHVwbGV4XCI6NDQsXCJjb3JlLXV0aWwtaXNcIjo2LGluaGVyaXRzOjM4fV0sNDg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeyhmdW5jdGlvbihwcm9jZXNzKXtcInVzZSBzdHJpY3RcIjttb2R1bGUuZXhwb3J0cz1Xcml0YWJsZTt2YXIgcHJvY2Vzc05leHRUaWNrPXJlcXVpcmUoXCJwcm9jZXNzLW5leHRpY2stYXJnc1wiKTt2YXIgYXN5bmNXcml0ZT0hcHJvY2Vzcy5icm93c2VyJiZbXCJ2MC4xMFwiLFwidjAuOS5cIl0uaW5kZXhPZihwcm9jZXNzLnZlcnNpb24uc2xpY2UoMCw1KSk+LTE/c2V0SW1tZWRpYXRlOnByb2Nlc3NOZXh0VGljaztXcml0YWJsZS5Xcml0YWJsZVN0YXRlPVdyaXRhYmxlU3RhdGU7dmFyIHV0aWw9cmVxdWlyZShcImNvcmUtdXRpbC1pc1wiKTt1dGlsLmluaGVyaXRzPXJlcXVpcmUoXCJpbmhlcml0c1wiKTt2YXIgaW50ZXJuYWxVdGlsPXtkZXByZWNhdGU6cmVxdWlyZShcInV0aWwtZGVwcmVjYXRlXCIpfTt2YXIgU3RyZWFtOyhmdW5jdGlvbigpe3RyeXtTdHJlYW09cmVxdWlyZShcInN0XCIrXCJyZWFtXCIpfWNhdGNoKF8pe31maW5hbGx5e2lmKCFTdHJlYW0pU3RyZWFtPXJlcXVpcmUoXCJldmVudHNcIikuRXZlbnRFbWl0dGVyfX0pKCk7dmFyIEJ1ZmZlcj1yZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcjt2YXIgYnVmZmVyU2hpbT1yZXF1aXJlKFwiYnVmZmVyLXNoaW1zXCIpO3V0aWwuaW5oZXJpdHMoV3JpdGFibGUsU3RyZWFtKTtmdW5jdGlvbiBub3AoKXt9ZnVuY3Rpb24gV3JpdGVSZXEoY2h1bmssZW5jb2RpbmcsY2Ipe3RoaXMuY2h1bms9Y2h1bms7dGhpcy5lbmNvZGluZz1lbmNvZGluZzt0aGlzLmNhbGxiYWNrPWNiO3RoaXMubmV4dD1udWxsfXZhciBEdXBsZXg7ZnVuY3Rpb24gV3JpdGFibGVTdGF0ZShvcHRpb25zLHN0cmVhbSl7RHVwbGV4PUR1cGxleHx8cmVxdWlyZShcIi4vX3N0cmVhbV9kdXBsZXhcIik7b3B0aW9ucz1vcHRpb25zfHx7fTt0aGlzLm9iamVjdE1vZGU9ISFvcHRpb25zLm9iamVjdE1vZGU7aWYoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KXRoaXMub2JqZWN0TW9kZT10aGlzLm9iamVjdE1vZGV8fCEhb3B0aW9ucy53cml0YWJsZU9iamVjdE1vZGU7dmFyIGh3bT1vcHRpb25zLmhpZ2hXYXRlck1hcms7dmFyIGRlZmF1bHRId209dGhpcy5vYmplY3RNb2RlPzE2OjE2KjEwMjQ7dGhpcy5oaWdoV2F0ZXJNYXJrPWh3bXx8aHdtPT09MD9od206ZGVmYXVsdEh3bTt0aGlzLmhpZ2hXYXRlck1hcms9fn50aGlzLmhpZ2hXYXRlck1hcms7dGhpcy5uZWVkRHJhaW49ZmFsc2U7dGhpcy5lbmRpbmc9ZmFsc2U7dGhpcy5lbmRlZD1mYWxzZTt0aGlzLmZpbmlzaGVkPWZhbHNlO3ZhciBub0RlY29kZT1vcHRpb25zLmRlY29kZVN0cmluZ3M9PT1mYWxzZTt0aGlzLmRlY29kZVN0cmluZ3M9IW5vRGVjb2RlO3RoaXMuZGVmYXVsdEVuY29kaW5nPW9wdGlvbnMuZGVmYXVsdEVuY29kaW5nfHxcInV0ZjhcIjt0aGlzLmxlbmd0aD0wO3RoaXMud3JpdGluZz1mYWxzZTt0aGlzLmNvcmtlZD0wO3RoaXMuc3luYz10cnVlO3RoaXMuYnVmZmVyUHJvY2Vzc2luZz1mYWxzZTt0aGlzLm9ud3JpdGU9ZnVuY3Rpb24oZXIpe29ud3JpdGUoc3RyZWFtLGVyKX07dGhpcy53cml0ZWNiPW51bGw7dGhpcy53cml0ZWxlbj0wO3RoaXMuYnVmZmVyZWRSZXF1ZXN0PW51bGw7dGhpcy5sYXN0QnVmZmVyZWRSZXF1ZXN0PW51bGw7dGhpcy5wZW5kaW5nY2I9MDt0aGlzLnByZWZpbmlzaGVkPWZhbHNlO3RoaXMuZXJyb3JFbWl0dGVkPWZhbHNlO3RoaXMuYnVmZmVyZWRSZXF1ZXN0Q291bnQ9MDt0aGlzLmNvcmtlZFJlcXVlc3RzRnJlZT1uZXcgQ29ya2VkUmVxdWVzdCh0aGlzKX1Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXI9ZnVuY3Rpb24gd3JpdGFibGVTdGF0ZUdldEJ1ZmZlcigpe3ZhciBjdXJyZW50PXRoaXMuYnVmZmVyZWRSZXF1ZXN0O3ZhciBvdXQ9W107d2hpbGUoY3VycmVudCl7b3V0LnB1c2goY3VycmVudCk7Y3VycmVudD1jdXJyZW50Lm5leHR9cmV0dXJuIG91dH07KGZ1bmN0aW9uKCl7dHJ5e09iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0YXRlLnByb3RvdHlwZSxcImJ1ZmZlclwiLHtnZXQ6aW50ZXJuYWxVdGlsLmRlcHJlY2F0ZShmdW5jdGlvbigpe3JldHVybiB0aGlzLmdldEJ1ZmZlcigpfSxcIl93cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyIFwiK1wiaW5zdGVhZC5cIil9KX1jYXRjaChfKXt9fSkoKTt2YXIgRHVwbGV4O2Z1bmN0aW9uIFdyaXRhYmxlKG9wdGlvbnMpe0R1cGxleD1EdXBsZXh8fHJlcXVpcmUoXCIuL19zdHJlYW1fZHVwbGV4XCIpO2lmKCEodGhpcyBpbnN0YW5jZW9mIFdyaXRhYmxlKSYmISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSlyZXR1cm4gbmV3IFdyaXRhYmxlKG9wdGlvbnMpO3RoaXMuX3dyaXRhYmxlU3RhdGU9bmV3IFdyaXRhYmxlU3RhdGUob3B0aW9ucyx0aGlzKTt0aGlzLndyaXRhYmxlPXRydWU7aWYob3B0aW9ucyl7aWYodHlwZW9mIG9wdGlvbnMud3JpdGU9PT1cImZ1bmN0aW9uXCIpdGhpcy5fd3JpdGU9b3B0aW9ucy53cml0ZTtpZih0eXBlb2Ygb3B0aW9ucy53cml0ZXY9PT1cImZ1bmN0aW9uXCIpdGhpcy5fd3JpdGV2PW9wdGlvbnMud3JpdGV2fVN0cmVhbS5jYWxsKHRoaXMpfVdyaXRhYmxlLnByb3RvdHlwZS5waXBlPWZ1bmN0aW9uKCl7dGhpcy5lbWl0KFwiZXJyb3JcIixuZXcgRXJyb3IoXCJDYW5ub3QgcGlwZSwgbm90IHJlYWRhYmxlXCIpKX07ZnVuY3Rpb24gd3JpdGVBZnRlckVuZChzdHJlYW0sY2Ipe3ZhciBlcj1uZXcgRXJyb3IoXCJ3cml0ZSBhZnRlciBlbmRcIik7c3RyZWFtLmVtaXQoXCJlcnJvclwiLGVyKTtwcm9jZXNzTmV4dFRpY2soY2IsZXIpfWZ1bmN0aW9uIHZhbGlkQ2h1bmsoc3RyZWFtLHN0YXRlLGNodW5rLGNiKXt2YXIgdmFsaWQ9dHJ1ZTt2YXIgZXI9ZmFsc2U7aWYoY2h1bms9PT1udWxsKXtlcj1uZXcgVHlwZUVycm9yKFwiTWF5IG5vdCB3cml0ZSBudWxsIHZhbHVlcyB0byBzdHJlYW1cIil9ZWxzZSBpZighQnVmZmVyLmlzQnVmZmVyKGNodW5rKSYmdHlwZW9mIGNodW5rIT09XCJzdHJpbmdcIiYmY2h1bmshPT11bmRlZmluZWQmJiFzdGF0ZS5vYmplY3RNb2RlKXtlcj1uZXcgVHlwZUVycm9yKFwiSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVua1wiKX1pZihlcil7c3RyZWFtLmVtaXQoXCJlcnJvclwiLGVyKTtwcm9jZXNzTmV4dFRpY2soY2IsZXIpO3ZhbGlkPWZhbHNlfXJldHVybiB2YWxpZH1Xcml0YWJsZS5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24oY2h1bmssZW5jb2RpbmcsY2Ipe3ZhciBzdGF0ZT10aGlzLl93cml0YWJsZVN0YXRlO3ZhciByZXQ9ZmFsc2U7aWYodHlwZW9mIGVuY29kaW5nPT09XCJmdW5jdGlvblwiKXtjYj1lbmNvZGluZztlbmNvZGluZz1udWxsfWlmKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpZW5jb2Rpbmc9XCJidWZmZXJcIjtlbHNlIGlmKCFlbmNvZGluZyllbmNvZGluZz1zdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7aWYodHlwZW9mIGNiIT09XCJmdW5jdGlvblwiKWNiPW5vcDtpZihzdGF0ZS5lbmRlZCl3cml0ZUFmdGVyRW5kKHRoaXMsY2IpO2Vsc2UgaWYodmFsaWRDaHVuayh0aGlzLHN0YXRlLGNodW5rLGNiKSl7XG5zdGF0ZS5wZW5kaW5nY2IrKztyZXQ9d3JpdGVPckJ1ZmZlcih0aGlzLHN0YXRlLGNodW5rLGVuY29kaW5nLGNiKX1yZXR1cm4gcmV0fTtXcml0YWJsZS5wcm90b3R5cGUuY29yaz1mdW5jdGlvbigpe3ZhciBzdGF0ZT10aGlzLl93cml0YWJsZVN0YXRlO3N0YXRlLmNvcmtlZCsrfTtXcml0YWJsZS5wcm90b3R5cGUudW5jb3JrPWZ1bmN0aW9uKCl7dmFyIHN0YXRlPXRoaXMuX3dyaXRhYmxlU3RhdGU7aWYoc3RhdGUuY29ya2VkKXtzdGF0ZS5jb3JrZWQtLTtpZighc3RhdGUud3JpdGluZyYmIXN0YXRlLmNvcmtlZCYmIXN0YXRlLmZpbmlzaGVkJiYhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyYmc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KWNsZWFyQnVmZmVyKHRoaXMsc3RhdGUpfX07V3JpdGFibGUucHJvdG90eXBlLnNldERlZmF1bHRFbmNvZGluZz1mdW5jdGlvbiBzZXREZWZhdWx0RW5jb2RpbmcoZW5jb2Rpbmcpe2lmKHR5cGVvZiBlbmNvZGluZz09PVwic3RyaW5nXCIpZW5jb2Rpbmc9ZW5jb2RpbmcudG9Mb3dlckNhc2UoKTtpZighKFtcImhleFwiLFwidXRmOFwiLFwidXRmLThcIixcImFzY2lpXCIsXCJiaW5hcnlcIixcImJhc2U2NFwiLFwidWNzMlwiLFwidWNzLTJcIixcInV0ZjE2bGVcIixcInV0Zi0xNmxlXCIsXCJyYXdcIl0uaW5kZXhPZigoZW5jb2RpbmcrXCJcIikudG9Mb3dlckNhc2UoKSk+LTEpKXRocm93IG5ldyBUeXBlRXJyb3IoXCJVbmtub3duIGVuY29kaW5nOiBcIitlbmNvZGluZyk7dGhpcy5fd3JpdGFibGVTdGF0ZS5kZWZhdWx0RW5jb2Rpbmc9ZW5jb2Rpbmc7cmV0dXJuIHRoaXN9O2Z1bmN0aW9uIGRlY29kZUNodW5rKHN0YXRlLGNodW5rLGVuY29kaW5nKXtpZighc3RhdGUub2JqZWN0TW9kZSYmc3RhdGUuZGVjb2RlU3RyaW5ncyE9PWZhbHNlJiZ0eXBlb2YgY2h1bms9PT1cInN0cmluZ1wiKXtjaHVuaz1idWZmZXJTaGltLmZyb20oY2h1bmssZW5jb2RpbmcpfXJldHVybiBjaHVua31mdW5jdGlvbiB3cml0ZU9yQnVmZmVyKHN0cmVhbSxzdGF0ZSxjaHVuayxlbmNvZGluZyxjYil7Y2h1bms9ZGVjb2RlQ2h1bmsoc3RhdGUsY2h1bmssZW5jb2RpbmcpO2lmKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpZW5jb2Rpbmc9XCJidWZmZXJcIjt2YXIgbGVuPXN0YXRlLm9iamVjdE1vZGU/MTpjaHVuay5sZW5ndGg7c3RhdGUubGVuZ3RoKz1sZW47dmFyIHJldD1zdGF0ZS5sZW5ndGg8c3RhdGUuaGlnaFdhdGVyTWFyaztpZighcmV0KXN0YXRlLm5lZWREcmFpbj10cnVlO2lmKHN0YXRlLndyaXRpbmd8fHN0YXRlLmNvcmtlZCl7dmFyIGxhc3Q9c3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0PW5ldyBXcml0ZVJlcShjaHVuayxlbmNvZGluZyxjYik7aWYobGFzdCl7bGFzdC5uZXh0PXN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3R9ZWxzZXtzdGF0ZS5idWZmZXJlZFJlcXVlc3Q9c3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdH1zdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudCs9MX1lbHNle2RvV3JpdGUoc3RyZWFtLHN0YXRlLGZhbHNlLGxlbixjaHVuayxlbmNvZGluZyxjYil9cmV0dXJuIHJldH1mdW5jdGlvbiBkb1dyaXRlKHN0cmVhbSxzdGF0ZSx3cml0ZXYsbGVuLGNodW5rLGVuY29kaW5nLGNiKXtzdGF0ZS53cml0ZWxlbj1sZW47c3RhdGUud3JpdGVjYj1jYjtzdGF0ZS53cml0aW5nPXRydWU7c3RhdGUuc3luYz10cnVlO2lmKHdyaXRldilzdHJlYW0uX3dyaXRldihjaHVuayxzdGF0ZS5vbndyaXRlKTtlbHNlIHN0cmVhbS5fd3JpdGUoY2h1bmssZW5jb2Rpbmcsc3RhdGUub253cml0ZSk7c3RhdGUuc3luYz1mYWxzZX1mdW5jdGlvbiBvbndyaXRlRXJyb3Ioc3RyZWFtLHN0YXRlLHN5bmMsZXIsY2Ipey0tc3RhdGUucGVuZGluZ2NiO2lmKHN5bmMpcHJvY2Vzc05leHRUaWNrKGNiLGVyKTtlbHNlIGNiKGVyKTtzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkPXRydWU7c3RyZWFtLmVtaXQoXCJlcnJvclwiLGVyKX1mdW5jdGlvbiBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpe3N0YXRlLndyaXRpbmc9ZmFsc2U7c3RhdGUud3JpdGVjYj1udWxsO3N0YXRlLmxlbmd0aC09c3RhdGUud3JpdGVsZW47c3RhdGUud3JpdGVsZW49MH1mdW5jdGlvbiBvbndyaXRlKHN0cmVhbSxlcil7dmFyIHN0YXRlPXN0cmVhbS5fd3JpdGFibGVTdGF0ZTt2YXIgc3luYz1zdGF0ZS5zeW5jO3ZhciBjYj1zdGF0ZS53cml0ZWNiO29ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSk7aWYoZXIpb253cml0ZUVycm9yKHN0cmVhbSxzdGF0ZSxzeW5jLGVyLGNiKTtlbHNle3ZhciBmaW5pc2hlZD1uZWVkRmluaXNoKHN0YXRlKTtpZighZmluaXNoZWQmJiFzdGF0ZS5jb3JrZWQmJiFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nJiZzdGF0ZS5idWZmZXJlZFJlcXVlc3Qpe2NsZWFyQnVmZmVyKHN0cmVhbSxzdGF0ZSl9aWYoc3luYyl7YXN5bmNXcml0ZShhZnRlcldyaXRlLHN0cmVhbSxzdGF0ZSxmaW5pc2hlZCxjYil9ZWxzZXthZnRlcldyaXRlKHN0cmVhbSxzdGF0ZSxmaW5pc2hlZCxjYil9fX1mdW5jdGlvbiBhZnRlcldyaXRlKHN0cmVhbSxzdGF0ZSxmaW5pc2hlZCxjYil7aWYoIWZpbmlzaGVkKW9ud3JpdGVEcmFpbihzdHJlYW0sc3RhdGUpO3N0YXRlLnBlbmRpbmdjYi0tO2NiKCk7ZmluaXNoTWF5YmUoc3RyZWFtLHN0YXRlKX1mdW5jdGlvbiBvbndyaXRlRHJhaW4oc3RyZWFtLHN0YXRlKXtpZihzdGF0ZS5sZW5ndGg9PT0wJiZzdGF0ZS5uZWVkRHJhaW4pe3N0YXRlLm5lZWREcmFpbj1mYWxzZTtzdHJlYW0uZW1pdChcImRyYWluXCIpfX1mdW5jdGlvbiBjbGVhckJ1ZmZlcihzdHJlYW0sc3RhdGUpe3N0YXRlLmJ1ZmZlclByb2Nlc3Npbmc9dHJ1ZTt2YXIgZW50cnk9c3RhdGUuYnVmZmVyZWRSZXF1ZXN0O2lmKHN0cmVhbS5fd3JpdGV2JiZlbnRyeSYmZW50cnkubmV4dCl7dmFyIGw9c3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQ7dmFyIGJ1ZmZlcj1uZXcgQXJyYXkobCk7dmFyIGhvbGRlcj1zdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWU7aG9sZGVyLmVudHJ5PWVudHJ5O3ZhciBjb3VudD0wO3doaWxlKGVudHJ5KXtidWZmZXJbY291bnRdPWVudHJ5O2VudHJ5PWVudHJ5Lm5leHQ7Y291bnQrPTF9ZG9Xcml0ZShzdHJlYW0sc3RhdGUsdHJ1ZSxzdGF0ZS5sZW5ndGgsYnVmZmVyLFwiXCIsaG9sZGVyLmZpbmlzaCk7c3RhdGUucGVuZGluZ2NiKys7c3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdD1udWxsO2lmKGhvbGRlci5uZXh0KXtzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWU9aG9sZGVyLm5leHQ7aG9sZGVyLm5leHQ9bnVsbH1lbHNle3N0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZT1uZXcgQ29ya2VkUmVxdWVzdChzdGF0ZSl9fWVsc2V7d2hpbGUoZW50cnkpe3ZhciBjaHVuaz1lbnRyeS5jaHVuazt2YXIgZW5jb2Rpbmc9ZW50cnkuZW5jb2Rpbmc7dmFyIGNiPWVudHJ5LmNhbGxiYWNrO3ZhciBsZW49c3RhdGUub2JqZWN0TW9kZT8xOmNodW5rLmxlbmd0aDtkb1dyaXRlKHN0cmVhbSxzdGF0ZSxmYWxzZSxsZW4sY2h1bmssZW5jb2RpbmcsY2IpO2VudHJ5PWVudHJ5Lm5leHQ7aWYoc3RhdGUud3JpdGluZyl7YnJlYWt9fWlmKGVudHJ5PT09bnVsbClzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0PW51bGx9c3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQ9MDtzdGF0ZS5idWZmZXJlZFJlcXVlc3Q9ZW50cnk7c3RhdGUuYnVmZmVyUHJvY2Vzc2luZz1mYWxzZX1Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRlPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXtjYihuZXcgRXJyb3IoXCJub3QgaW1wbGVtZW50ZWRcIikpfTtXcml0YWJsZS5wcm90b3R5cGUuX3dyaXRldj1udWxsO1dyaXRhYmxlLnByb3RvdHlwZS5lbmQ9ZnVuY3Rpb24oY2h1bmssZW5jb2RpbmcsY2Ipe3ZhciBzdGF0ZT10aGlzLl93cml0YWJsZVN0YXRlO2lmKHR5cGVvZiBjaHVuaz09PVwiZnVuY3Rpb25cIil7Y2I9Y2h1bms7Y2h1bms9bnVsbDtlbmNvZGluZz1udWxsfWVsc2UgaWYodHlwZW9mIGVuY29kaW5nPT09XCJmdW5jdGlvblwiKXtjYj1lbmNvZGluZztlbmNvZGluZz1udWxsfWlmKGNodW5rIT09bnVsbCYmY2h1bmshPT11bmRlZmluZWQpdGhpcy53cml0ZShjaHVuayxlbmNvZGluZyk7aWYoc3RhdGUuY29ya2VkKXtzdGF0ZS5jb3JrZWQ9MTt0aGlzLnVuY29yaygpfWlmKCFzdGF0ZS5lbmRpbmcmJiFzdGF0ZS5maW5pc2hlZCllbmRXcml0YWJsZSh0aGlzLHN0YXRlLGNiKX07ZnVuY3Rpb24gbmVlZEZpbmlzaChzdGF0ZSl7cmV0dXJuIHN0YXRlLmVuZGluZyYmc3RhdGUubGVuZ3RoPT09MCYmc3RhdGUuYnVmZmVyZWRSZXF1ZXN0PT09bnVsbCYmIXN0YXRlLmZpbmlzaGVkJiYhc3RhdGUud3JpdGluZ31mdW5jdGlvbiBwcmVmaW5pc2goc3RyZWFtLHN0YXRlKXtpZighc3RhdGUucHJlZmluaXNoZWQpe3N0YXRlLnByZWZpbmlzaGVkPXRydWU7c3RyZWFtLmVtaXQoXCJwcmVmaW5pc2hcIil9fWZ1bmN0aW9uIGZpbmlzaE1heWJlKHN0cmVhbSxzdGF0ZSl7dmFyIG5lZWQ9bmVlZEZpbmlzaChzdGF0ZSk7aWYobmVlZCl7aWYoc3RhdGUucGVuZGluZ2NiPT09MCl7cHJlZmluaXNoKHN0cmVhbSxzdGF0ZSk7c3RhdGUuZmluaXNoZWQ9dHJ1ZTtzdHJlYW0uZW1pdChcImZpbmlzaFwiKX1lbHNle3ByZWZpbmlzaChzdHJlYW0sc3RhdGUpfX1yZXR1cm4gbmVlZH1mdW5jdGlvbiBlbmRXcml0YWJsZShzdHJlYW0sc3RhdGUsY2Ipe3N0YXRlLmVuZGluZz10cnVlO2ZpbmlzaE1heWJlKHN0cmVhbSxzdGF0ZSk7aWYoY2Ipe2lmKHN0YXRlLmZpbmlzaGVkKXByb2Nlc3NOZXh0VGljayhjYik7ZWxzZSBzdHJlYW0ub25jZShcImZpbmlzaFwiLGNiKX1zdGF0ZS5lbmRlZD10cnVlO3N0cmVhbS53cml0YWJsZT1mYWxzZX1mdW5jdGlvbiBDb3JrZWRSZXF1ZXN0KHN0YXRlKXt2YXIgX3RoaXM9dGhpczt0aGlzLm5leHQ9bnVsbDt0aGlzLmVudHJ5PW51bGw7dGhpcy5maW5pc2g9ZnVuY3Rpb24oZXJyKXt2YXIgZW50cnk9X3RoaXMuZW50cnk7X3RoaXMuZW50cnk9bnVsbDt3aGlsZShlbnRyeSl7dmFyIGNiPWVudHJ5LmNhbGxiYWNrO3N0YXRlLnBlbmRpbmdjYi0tO2NiKGVycik7ZW50cnk9ZW50cnkubmV4dH1pZihzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUpe3N0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZS5uZXh0PV90aGlzfWVsc2V7c3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlPV90aGlzfX19fSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJfcHJvY2Vzc1wiKSl9LHtcIi4vX3N0cmVhbV9kdXBsZXhcIjo0NCxfcHJvY2Vzczo0MixidWZmZXI6NSxcImJ1ZmZlci1zaGltc1wiOjQsXCJjb3JlLXV0aWwtaXNcIjo2LGV2ZW50czoyOCxpbmhlcml0czozOCxcInByb2Nlc3MtbmV4dGljay1hcmdzXCI6NDEsXCJ1dGlsLWRlcHJlY2F0ZVwiOjU3fV0sNDk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1widXNlIHN0cmljdFwiO3ZhciBCdWZmZXI9cmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXI7dmFyIGJ1ZmZlclNoaW09cmVxdWlyZShcImJ1ZmZlci1zaGltc1wiKTttb2R1bGUuZXhwb3J0cz1CdWZmZXJMaXN0O2Z1bmN0aW9uIEJ1ZmZlckxpc3QoKXt0aGlzLmhlYWQ9bnVsbDt0aGlzLnRhaWw9bnVsbDt0aGlzLmxlbmd0aD0wfUJ1ZmZlckxpc3QucHJvdG90eXBlLnB1c2g9ZnVuY3Rpb24odil7dmFyIGVudHJ5PXtkYXRhOnYsbmV4dDpudWxsfTtpZih0aGlzLmxlbmd0aD4wKXRoaXMudGFpbC5uZXh0PWVudHJ5O2Vsc2UgdGhpcy5oZWFkPWVudHJ5O3RoaXMudGFpbD1lbnRyeTsrK3RoaXMubGVuZ3RofTtCdWZmZXJMaXN0LnByb3RvdHlwZS51bnNoaWZ0PWZ1bmN0aW9uKHYpe3ZhciBlbnRyeT17ZGF0YTp2LG5leHQ6dGhpcy5oZWFkfTtpZih0aGlzLmxlbmd0aD09PTApdGhpcy50YWlsPWVudHJ5O3RoaXMuaGVhZD1lbnRyeTsrK3RoaXMubGVuZ3RofTtCdWZmZXJMaXN0LnByb3RvdHlwZS5zaGlmdD1mdW5jdGlvbigpe2lmKHRoaXMubGVuZ3RoPT09MClyZXR1cm47dmFyIHJldD10aGlzLmhlYWQuZGF0YTtpZih0aGlzLmxlbmd0aD09PTEpdGhpcy5oZWFkPXRoaXMudGFpbD1udWxsO2Vsc2UgdGhpcy5oZWFkPXRoaXMuaGVhZC5uZXh0Oy0tdGhpcy5sZW5ndGg7cmV0dXJuIHJldH07QnVmZmVyTGlzdC5wcm90b3R5cGUuY2xlYXI9ZnVuY3Rpb24oKXt0aGlzLmhlYWQ9dGhpcy50YWlsPW51bGw7dGhpcy5sZW5ndGg9MH07QnVmZmVyTGlzdC5wcm90b3R5cGUuam9pbj1mdW5jdGlvbihzKXtpZih0aGlzLmxlbmd0aD09PTApcmV0dXJuXCJcIjt2YXIgcD10aGlzLmhlYWQ7dmFyIHJldD1cIlwiK3AuZGF0YTt3aGlsZShwPXAubmV4dCl7cmV0Kz1zK3AuZGF0YX1yZXR1cm4gcmV0fTtCdWZmZXJMaXN0LnByb3RvdHlwZS5jb25jYXQ9ZnVuY3Rpb24obil7aWYodGhpcy5sZW5ndGg9PT0wKXJldHVybiBidWZmZXJTaGltLmFsbG9jKDApO2lmKHRoaXMubGVuZ3RoPT09MSlyZXR1cm4gdGhpcy5oZWFkLmRhdGE7dmFyIHJldD1idWZmZXJTaGltLmFsbG9jVW5zYWZlKG4+Pj4wKTt2YXIgcD10aGlzLmhlYWQ7dmFyIGk9MDt3aGlsZShwKXtwLmRhdGEuY29weShyZXQsaSk7aSs9cC5kYXRhLmxlbmd0aDtwPXAubmV4dH1yZXR1cm4gcmV0fX0se2J1ZmZlcjo1LFwiYnVmZmVyLXNoaW1zXCI6NH1dLDUwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qc1wiKX0se1wiLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qc1wiOjQ1fV0sNTE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeyhmdW5jdGlvbihwcm9jZXNzKXt2YXIgU3RyZWFtPWZ1bmN0aW9uKCl7dHJ5e3JldHVybiByZXF1aXJlKFwic3RcIitcInJlYW1cIil9Y2F0Y2goXyl7fX0oKTtleHBvcnRzPW1vZHVsZS5leHBvcnRzPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzXCIpO2V4cG9ydHMuU3RyZWFtPVN0cmVhbXx8ZXhwb3J0cztleHBvcnRzLlJlYWRhYmxlPWV4cG9ydHM7ZXhwb3J0cy5Xcml0YWJsZT1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV93cml0YWJsZS5qc1wiKTtleHBvcnRzLkR1cGxleD1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIik7ZXhwb3J0cy5UcmFuc2Zvcm09cmVxdWlyZShcIi4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCIpO2V4cG9ydHMuUGFzc1Rocm91Z2g9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIik7aWYoIXByb2Nlc3MuYnJvd3NlciYmcHJvY2Vzcy5lbnYuUkVBREFCTEVfU1RSRUFNPT09XCJkaXNhYmxlXCImJlN0cmVhbSl7bW9kdWxlLmV4cG9ydHM9U3RyZWFtfX0pLmNhbGwodGhpcyxyZXF1aXJlKFwiX3Byb2Nlc3NcIikpfSx7XCIuL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiOjQ0LFwiLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qc1wiOjQ1LFwiLi9saWIvX3N0cmVhbV9yZWFkYWJsZS5qc1wiOjQ2LFwiLi9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanNcIjo0NyxcIi4vbGliL19zdHJlYW1fd3JpdGFibGUuanNcIjo0OCxfcHJvY2Vzczo0Mn1dLDUyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanNcIil9LHtcIi4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCI6NDd9XSw1MzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fd3JpdGFibGUuanNcIil9LHtcIi4vbGliL19zdHJlYW1fd3JpdGFibGUuanNcIjo0OH1dLDU0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1mdW5jdGlvbihzdHJpbmcpe3JldHVybiBzdHJpbmcucmVwbGFjZSgvWy1cXFxcXiQqKz8uKCl8W1xcXXt9XS9nLFwiXFxcXCQmXCIpfX0se31dLDU1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1TdHJlYW07dmFyIEVFPXJlcXVpcmUoXCJldmVudHNcIikuRXZlbnRFbWl0dGVyO3ZhciBpbmhlcml0cz1yZXF1aXJlKFwiaW5oZXJpdHNcIik7aW5oZXJpdHMoU3RyZWFtLEVFKTtTdHJlYW0uUmVhZGFibGU9cmVxdWlyZShcInJlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS5qc1wiKTtTdHJlYW0uV3JpdGFibGU9cmVxdWlyZShcInJlYWRhYmxlLXN0cmVhbS93cml0YWJsZS5qc1wiKTtTdHJlYW0uRHVwbGV4PXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzXCIpO1N0cmVhbS5UcmFuc2Zvcm09cmVxdWlyZShcInJlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanNcIik7U3RyZWFtLlBhc3NUaHJvdWdoPXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanNcIik7U3RyZWFtLlN0cmVhbT1TdHJlYW07ZnVuY3Rpb24gU3RyZWFtKCl7RUUuY2FsbCh0aGlzKX1TdHJlYW0ucHJvdG90eXBlLnBpcGU9ZnVuY3Rpb24oZGVzdCxvcHRpb25zKXt2YXIgc291cmNlPXRoaXM7ZnVuY3Rpb24gb25kYXRhKGNodW5rKXtpZihkZXN0LndyaXRhYmxlKXtpZihmYWxzZT09PWRlc3Qud3JpdGUoY2h1bmspJiZzb3VyY2UucGF1c2Upe3NvdXJjZS5wYXVzZSgpfX19c291cmNlLm9uKFwiZGF0YVwiLG9uZGF0YSk7ZnVuY3Rpb24gb25kcmFpbigpe2lmKHNvdXJjZS5yZWFkYWJsZSYmc291cmNlLnJlc3VtZSl7c291cmNlLnJlc3VtZSgpfX1kZXN0Lm9uKFwiZHJhaW5cIixvbmRyYWluKTtpZighZGVzdC5faXNTdGRpbyYmKCFvcHRpb25zfHxvcHRpb25zLmVuZCE9PWZhbHNlKSl7c291cmNlLm9uKFwiZW5kXCIsb25lbmQpO3NvdXJjZS5vbihcImNsb3NlXCIsb25jbG9zZSl9dmFyIGRpZE9uRW5kPWZhbHNlO2Z1bmN0aW9uIG9uZW5kKCl7aWYoZGlkT25FbmQpcmV0dXJuO2RpZE9uRW5kPXRydWU7ZGVzdC5lbmQoKX1mdW5jdGlvbiBvbmNsb3NlKCl7aWYoZGlkT25FbmQpcmV0dXJuO2RpZE9uRW5kPXRydWU7aWYodHlwZW9mIGRlc3QuZGVzdHJveT09PVwiZnVuY3Rpb25cIilkZXN0LmRlc3Ryb3koKX1mdW5jdGlvbiBvbmVycm9yKGVyKXtjbGVhbnVwKCk7aWYoRUUubGlzdGVuZXJDb3VudCh0aGlzLFwiZXJyb3JcIik9PT0wKXt0aHJvdyBlcn19c291cmNlLm9uKFwiZXJyb3JcIixvbmVycm9yKTtkZXN0Lm9uKFwiZXJyb3JcIixvbmVycm9yKTtmdW5jdGlvbiBjbGVhbnVwKCl7c291cmNlLnJlbW92ZUxpc3RlbmVyKFwiZGF0YVwiLG9uZGF0YSk7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImRyYWluXCIsb25kcmFpbik7c291cmNlLnJlbW92ZUxpc3RlbmVyKFwiZW5kXCIsb25lbmQpO3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImNsb3NlXCIsb25jbG9zZSk7c291cmNlLnJlbW92ZUxpc3RlbmVyKFwiZXJyb3JcIixvbmVycm9yKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZXJyb3JcIixvbmVycm9yKTtzb3VyY2UucmVtb3ZlTGlzdGVuZXIoXCJlbmRcIixjbGVhbnVwKTtzb3VyY2UucmVtb3ZlTGlzdGVuZXIoXCJjbG9zZVwiLGNsZWFudXApO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJjbG9zZVwiLGNsZWFudXApfXNvdXJjZS5vbihcImVuZFwiLGNsZWFudXApO3NvdXJjZS5vbihcImNsb3NlXCIsY2xlYW51cCk7ZGVzdC5vbihcImNsb3NlXCIsY2xlYW51cCk7ZGVzdC5lbWl0KFwicGlwZVwiLHNvdXJjZSk7cmV0dXJuIGRlc3R9fSx7ZXZlbnRzOjI4LGluaGVyaXRzOjM4LFwicmVhZGFibGUtc3RyZWFtL2R1cGxleC5qc1wiOjQzLFwicmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzXCI6NTAsXCJyZWFkYWJsZS1zdHJlYW0vcmVhZGFibGUuanNcIjo1MSxcInJlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanNcIjo1MixcInJlYWRhYmxlLXN0cmVhbS93cml0YWJsZS5qc1wiOjUzfV0sNTY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBCdWZmZXI9cmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXI7dmFyIGlzQnVmZmVyRW5jb2Rpbmc9QnVmZmVyLmlzRW5jb2Rpbmd8fGZ1bmN0aW9uKGVuY29kaW5nKXtzd2l0Y2goZW5jb2RpbmcmJmVuY29kaW5nLnRvTG93ZXJDYXNlKCkpe2Nhc2VcImhleFwiOmNhc2VcInV0ZjhcIjpjYXNlXCJ1dGYtOFwiOmNhc2VcImFzY2lpXCI6Y2FzZVwiYmluYXJ5XCI6Y2FzZVwiYmFzZTY0XCI6Y2FzZVwidWNzMlwiOmNhc2VcInVjcy0yXCI6Y2FzZVwidXRmMTZsZVwiOmNhc2VcInV0Zi0xNmxlXCI6Y2FzZVwicmF3XCI6cmV0dXJuIHRydWU7ZGVmYXVsdDpyZXR1cm4gZmFsc2V9fTtmdW5jdGlvbiBhc3NlcnRFbmNvZGluZyhlbmNvZGluZyl7aWYoZW5jb2RpbmcmJiFpc0J1ZmZlckVuY29kaW5nKGVuY29kaW5nKSl7dGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBlbmNvZGluZzogXCIrZW5jb2RpbmcpfX12YXIgU3RyaW5nRGVjb2Rlcj1leHBvcnRzLlN0cmluZ0RlY29kZXI9ZnVuY3Rpb24oZW5jb2Rpbmcpe3RoaXMuZW5jb2Rpbmc9KGVuY29kaW5nfHxcInV0ZjhcIikudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bLV9dLyxcIlwiKTthc3NlcnRFbmNvZGluZyhlbmNvZGluZyk7c3dpdGNoKHRoaXMuZW5jb2Rpbmcpe2Nhc2VcInV0ZjhcIjp0aGlzLnN1cnJvZ2F0ZVNpemU9MzticmVhaztjYXNlXCJ1Y3MyXCI6Y2FzZVwidXRmMTZsZVwiOnRoaXMuc3Vycm9nYXRlU2l6ZT0yO3RoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXI9dXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcjticmVhaztjYXNlXCJiYXNlNjRcIjp0aGlzLnN1cnJvZ2F0ZVNpemU9Mzt0aGlzLmRldGVjdEluY29tcGxldGVDaGFyPWJhc2U2NERldGVjdEluY29tcGxldGVDaGFyO2JyZWFrO2RlZmF1bHQ6dGhpcy53cml0ZT1wYXNzVGhyb3VnaFdyaXRlO3JldHVybn10aGlzLmNoYXJCdWZmZXI9bmV3IEJ1ZmZlcig2KTt0aGlzLmNoYXJSZWNlaXZlZD0wO3RoaXMuY2hhckxlbmd0aD0wfTtTdHJpbmdEZWNvZGVyLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbihidWZmZXIpe3ZhciBjaGFyU3RyPVwiXCI7d2hpbGUodGhpcy5jaGFyTGVuZ3RoKXt2YXIgYXZhaWxhYmxlPWJ1ZmZlci5sZW5ndGg+PXRoaXMuY2hhckxlbmd0aC10aGlzLmNoYXJSZWNlaXZlZD90aGlzLmNoYXJMZW5ndGgtdGhpcy5jaGFyUmVjZWl2ZWQ6YnVmZmVyLmxlbmd0aDtidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsdGhpcy5jaGFyUmVjZWl2ZWQsMCxhdmFpbGFibGUpO3RoaXMuY2hhclJlY2VpdmVkKz1hdmFpbGFibGU7aWYodGhpcy5jaGFyUmVjZWl2ZWQ8dGhpcy5jaGFyTGVuZ3RoKXtyZXR1cm5cIlwifWJ1ZmZlcj1idWZmZXIuc2xpY2UoYXZhaWxhYmxlLGJ1ZmZlci5sZW5ndGgpO2NoYXJTdHI9dGhpcy5jaGFyQnVmZmVyLnNsaWNlKDAsdGhpcy5jaGFyTGVuZ3RoKS50b1N0cmluZyh0aGlzLmVuY29kaW5nKTt2YXIgY2hhckNvZGU9Y2hhclN0ci5jaGFyQ29kZUF0KGNoYXJTdHIubGVuZ3RoLTEpO2lmKGNoYXJDb2RlPj01NTI5NiYmY2hhckNvZGU8PTU2MzE5KXt0aGlzLmNoYXJMZW5ndGgrPXRoaXMuc3Vycm9nYXRlU2l6ZTtjaGFyU3RyPVwiXCI7Y29udGludWV9dGhpcy5jaGFyUmVjZWl2ZWQ9dGhpcy5jaGFyTGVuZ3RoPTA7aWYoYnVmZmVyLmxlbmd0aD09PTApe3JldHVybiBjaGFyU3RyfWJyZWFrfXRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKTt2YXIgZW5kPWJ1ZmZlci5sZW5ndGg7aWYodGhpcy5jaGFyTGVuZ3RoKXtidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsMCxidWZmZXIubGVuZ3RoLXRoaXMuY2hhclJlY2VpdmVkLGVuZCk7ZW5kLT10aGlzLmNoYXJSZWNlaXZlZH1jaGFyU3RyKz1idWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywwLGVuZCk7dmFyIGVuZD1jaGFyU3RyLmxlbmd0aC0xO3ZhciBjaGFyQ29kZT1jaGFyU3RyLmNoYXJDb2RlQXQoZW5kKTtpZihjaGFyQ29kZT49NTUyOTYmJmNoYXJDb2RlPD01NjMxOSl7dmFyIHNpemU9dGhpcy5zdXJyb2dhdGVTaXplO3RoaXMuY2hhckxlbmd0aCs9c2l6ZTt0aGlzLmNoYXJSZWNlaXZlZCs9c2l6ZTt0aGlzLmNoYXJCdWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsc2l6ZSwwLHNpemUpO2J1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwwLDAsc2l6ZSk7cmV0dXJuIGNoYXJTdHIuc3Vic3RyaW5nKDAsZW5kKX1yZXR1cm4gY2hhclN0cn07U3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZGV0ZWN0SW5jb21wbGV0ZUNoYXI9ZnVuY3Rpb24oYnVmZmVyKXt2YXIgaT1idWZmZXIubGVuZ3RoPj0zPzM6YnVmZmVyLmxlbmd0aDtmb3IoO2k+MDtpLS0pe3ZhciBjPWJ1ZmZlcltidWZmZXIubGVuZ3RoLWldO2lmKGk9PTEmJmM+PjU9PTYpe3RoaXMuY2hhckxlbmd0aD0yO2JyZWFrfWlmKGk8PTImJmM+PjQ9PTE0KXt0aGlzLmNoYXJMZW5ndGg9MzticmVha31pZihpPD0zJiZjPj4zPT0zMCl7dGhpcy5jaGFyTGVuZ3RoPTQ7YnJlYWt9fXRoaXMuY2hhclJlY2VpdmVkPWl9O1N0cmluZ0RlY29kZXIucHJvdG90eXBlLmVuZD1mdW5jdGlvbihidWZmZXIpe3ZhciByZXM9XCJcIjtpZihidWZmZXImJmJ1ZmZlci5sZW5ndGgpcmVzPXRoaXMud3JpdGUoYnVmZmVyKTtpZih0aGlzLmNoYXJSZWNlaXZlZCl7dmFyIGNyPXRoaXMuY2hhclJlY2VpdmVkO3ZhciBidWY9dGhpcy5jaGFyQnVmZmVyO3ZhciBlbmM9dGhpcy5lbmNvZGluZztyZXMrPWJ1Zi5zbGljZSgwLGNyKS50b1N0cmluZyhlbmMpfXJldHVybiByZXN9O2Z1bmN0aW9uIHBhc3NUaHJvdWdoV3JpdGUoYnVmZmVyKXtyZXR1cm4gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpfWZ1bmN0aW9uIHV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKXt0aGlzLmNoYXJSZWNlaXZlZD1idWZmZXIubGVuZ3RoJTI7dGhpcy5jaGFyTGVuZ3RoPXRoaXMuY2hhclJlY2VpdmVkPzI6MH1mdW5jdGlvbiBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpe3RoaXMuY2hhclJlY2VpdmVkPWJ1ZmZlci5sZW5ndGglMzt0aGlzLmNoYXJMZW5ndGg9dGhpcy5jaGFyUmVjZWl2ZWQ/MzowfX0se2J1ZmZlcjo1fV0sNTc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeyhmdW5jdGlvbihnbG9iYWwpe21vZHVsZS5leHBvcnRzPWRlcHJlY2F0ZTtmdW5jdGlvbiBkZXByZWNhdGUoZm4sbXNnKXtpZihjb25maWcoXCJub0RlcHJlY2F0aW9uXCIpKXtyZXR1cm4gZm59dmFyIHdhcm5lZD1mYWxzZTtmdW5jdGlvbiBkZXByZWNhdGVkKCl7aWYoIXdhcm5lZCl7aWYoY29uZmlnKFwidGhyb3dEZXByZWNhdGlvblwiKSl7dGhyb3cgbmV3IEVycm9yKG1zZyl9ZWxzZSBpZihjb25maWcoXCJ0cmFjZURlcHJlY2F0aW9uXCIpKXtjb25zb2xlLnRyYWNlKG1zZyl9ZWxzZXtjb25zb2xlLndhcm4obXNnKX13YXJuZWQ9dHJ1ZX1yZXR1cm4gZm4uYXBwbHkodGhpcyxhcmd1bWVudHMpfXJldHVybiBkZXByZWNhdGVkfWZ1bmN0aW9uIGNvbmZpZyhuYW1lKXt0cnl7aWYoIWdsb2JhbC5sb2NhbFN0b3JhZ2UpcmV0dXJuIGZhbHNlfWNhdGNoKF8pe3JldHVybiBmYWxzZX12YXIgdmFsPWdsb2JhbC5sb2NhbFN0b3JhZ2VbbmFtZV07aWYobnVsbD09dmFsKXJldHVybiBmYWxzZTtyZXR1cm4gU3RyaW5nKHZhbCkudG9Mb3dlckNhc2UoKT09PVwidHJ1ZVwifX0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsIT09XCJ1bmRlZmluZWRcIj9nbG9iYWw6dHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiP3NlbGY6dHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCI/d2luZG93Ont9KX0se31dLDU4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1leHRlbmQ7dmFyIGhhc093blByb3BlcnR5PU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7ZnVuY3Rpb24gZXh0ZW5kKCl7dmFyIHRhcmdldD17fTtmb3IodmFyIGk9MDtpPGFyZ3VtZW50cy5sZW5ndGg7aSsrKXt2YXIgc291cmNlPWFyZ3VtZW50c1tpXTtmb3IodmFyIGtleSBpbiBzb3VyY2Upe2lmKGhhc093blByb3BlcnR5LmNhbGwoc291cmNlLGtleSkpe3RhcmdldFtrZXldPXNvdXJjZVtrZXldfX19cmV0dXJuIHRhcmdldH19LHt9XX0se30sWzFdKSgxKX0pO1xuIiwiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIndXNlIHN0cmljdCc7XG5cbnZhciBhdXRoID0gcmVxdWlyZSgnLi9saWIvYXV0aCcpO1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2xpYi9oZWxwZXJzJyk7XG52YXIgU3dhZ2dlckNsaWVudCA9IHJlcXVpcmUoJy4vbGliL2NsaWVudCcpO1xudmFyIGRlcHJlY2F0aW9uV3JhcHBlciA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMpIHtcbiAgaGVscGVycy5sb2coJ1RoaXMgaXMgZGVwcmVjYXRlZCwgdXNlIFwibmV3IFN3YWdnZXJDbGllbnRcIiBpbnN0ZWFkLicpO1xuXG4gIHJldHVybiBuZXcgU3dhZ2dlckNsaWVudCh1cmwsIG9wdGlvbnMpO1xufTtcblxuLyogSGVyZSBmb3IgSUU4IFN1cHBvcnQgKi9cbmlmICghQXJyYXkucHJvdG90eXBlLmluZGV4T2YpIHtcbiAgQXJyYXkucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbihvYmosIHN0YXJ0KSB7XG4gICAgZm9yICh2YXIgaSA9IChzdGFydCB8fCAwKSwgaiA9IHRoaXMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG4gICAgICBpZiAodGhpc1tpXSA9PT0gb2JqKSB7IHJldHVybiBpOyB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfTtcbn1cblxuLyogSGVyZSBmb3IgSUU4IFN1cHBvcnQgKi9cbmlmICghU3RyaW5nLnByb3RvdHlwZS50cmltKSB7XG4gIFN0cmluZy5wcm90b3R5cGUudHJpbSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJyk7XG4gIH07XG59XG5cbi8qIEhlcmUgZm9yIG5vZGUgMTAueCBzdXBwb3J0ICovXG5pZiAoIVN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGgpIHtcbiAgU3RyaW5nLnByb3RvdHlwZS5lbmRzV2l0aCA9IGZ1bmN0aW9uKHN1ZmZpeCkge1xuICAgIHJldHVybiB0aGlzLmluZGV4T2Yoc3VmZml4LCB0aGlzLmxlbmd0aCAtIHN1ZmZpeC5sZW5ndGgpICE9PSAtMTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTd2FnZ2VyQ2xpZW50O1xuXG5Td2FnZ2VyQ2xpZW50LkFwaUtleUF1dGhvcml6YXRpb24gPSBhdXRoLkFwaUtleUF1dGhvcml6YXRpb247XG5Td2FnZ2VyQ2xpZW50LlBhc3N3b3JkQXV0aG9yaXphdGlvbiA9IGF1dGguUGFzc3dvcmRBdXRob3JpemF0aW9uO1xuU3dhZ2dlckNsaWVudC5Db29raWVBdXRob3JpemF0aW9uID0gYXV0aC5Db29raWVBdXRob3JpemF0aW9uO1xuU3dhZ2dlckNsaWVudC5Td2FnZ2VyQXBpID0gZGVwcmVjYXRpb25XcmFwcGVyO1xuU3dhZ2dlckNsaWVudC5Td2FnZ2VyQ2xpZW50ID0gZGVwcmVjYXRpb25XcmFwcGVyO1xuU3dhZ2dlckNsaWVudC5TY2hlbWFNYXJrdXAgPSByZXF1aXJlKCcuL2xpYi9zY2hlbWEtbWFya3VwJyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG52YXIgYnRvYSA9IHJlcXVpcmUoJ2J0b2EnKTsgLy8ganNoaW50IGlnbm9yZTpsaW5lXG52YXIgQ29va2llSmFyID0gcmVxdWlyZSgnY29va2llamFyJykuQ29va2llSmFyO1xudmFyIF8gPSB7XG4gIGVhY2g6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9lYWNoJyksXG4gIGluY2x1ZGVzOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vaW5jbHVkZXMnKSxcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpXG59O1xuXG4vKipcbiAqIFN3YWdnZXJBdXRob3JpemF0aW9ucyBhcHBsaWVzIHRoZSBjb3JyZWN0IGF1dGhvcml6YXRpb24gdG8gYW4gb3BlcmF0aW9uIGJlaW5nIGV4ZWN1dGVkXG4gKi9cbnZhciBTd2FnZ2VyQXV0aG9yaXphdGlvbnMgPSBtb2R1bGUuZXhwb3J0cy5Td2FnZ2VyQXV0aG9yaXphdGlvbnMgPSBmdW5jdGlvbiAoYXV0aHopIHtcbiAgdGhpcy5hdXRoeiA9IGF1dGh6IHx8IHt9O1xufTtcblxuLyoqXG4gKiBBZGQgYXV0aHMgdG8gdGhlIGhhc2hcbiAqIFdpbGwgb3ZlcndyaXRlIGFueSBleGlzdGluZ1xuICpcbiAqL1xuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAobmFtZSwgYXV0aCkge1xuICBpZihfLmlzT2JqZWN0KG5hbWUpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG5hbWUpIHtcbiAgICAgIHRoaXMuYXV0aHpba2V5XSA9IG5hbWVba2V5XTtcbiAgICB9XG4gIH0gZWxzZSBpZih0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZycgKXtcbiAgICB0aGlzLmF1dGh6W25hbWVdID0gYXV0aDtcbiAgfVxuXG4gIHJldHVybiBhdXRoO1xufTtcblxuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gZGVsZXRlIHRoaXMuYXV0aHpbbmFtZV07XG59O1xuXG5Td2FnZ2VyQXV0aG9yaXphdGlvbnMucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaiwgc2VjdXJpdGllcykge1xuICB2YXIgc3RhdHVzID0gdHJ1ZTtcbiAgdmFyIGFwcGx5QWxsID0gIXNlY3VyaXRpZXM7XG4gIHZhciBmbGF0dGVuZWRTZWN1cml0aWVzID0gW107XG5cbiAgLy8gZmF2b3IgdGhlIG9iamVjdC1sZXZlbCBhdXRob3JpemF0aW9ucyBvdmVyIGdsb2JhbFxuICB2YXIgYXV0aHogPSBvYmouY2xpZW50QXV0aG9yaXphdGlvbnMgfHwgdGhpcy5hdXRoejtcblxuICAvLyBTZWN1cml0aWVzIGNvdWxkIGJlIFsge30gXVxuICBfLmVhY2goc2VjdXJpdGllcywgZnVuY3Rpb24gKG9iaiwga2V5KSB7XG5cbiAgICAvLyBNYWtlIHN1cmUgd2UgYWNjb3VudCBmb3Igc2VjdXJpdGllcyBiZWluZyBbIHN0ciBdXG4gICAgaWYodHlwZW9mIGtleSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGZsYXR0ZW5lZFNlY3VyaXRpZXMucHVzaChrZXkpO1xuICAgIH1cblxuICAgIC8vIEZsYXR0ZW4ga2V5cyBpbiB0byBvdXIgYXJyYXlcbiAgICBfLmVhY2gob2JqLCBmdW5jdGlvbiAodmFsLCBrZXkpIHtcbiAgICAgIGZsYXR0ZW5lZFNlY3VyaXRpZXMucHVzaChrZXkpO1xuICAgIH0pO1xuICB9KTtcblxuICBfLmVhY2goYXV0aHosIGZ1bmN0aW9uIChhdXRoLCBhdXRoTmFtZSkge1xuICAgIGlmKGFwcGx5QWxsIHx8IF8uaW5jbHVkZXMoZmxhdHRlbmVkU2VjdXJpdGllcywgYXV0aE5hbWUpKSB7XG4gICAgICB2YXIgbmV3U3RhdHVzID0gYXV0aC5hcHBseShvYmopO1xuICAgICAgc3RhdHVzID0gc3RhdHVzICYmICEhbmV3U3RhdHVzOyAvLyBsb2dpY2FsIE9ScyByZWdhcmRpbmcgc3RhdHVzXG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gc3RhdHVzO1xufTtcblxuLyoqXG4gKiBBcGlLZXlBdXRob3JpemF0aW9uIGFsbG93cyBhIHF1ZXJ5IHBhcmFtIG9yIGhlYWRlciB0byBiZSBpbmplY3RlZFxuICovXG52YXIgQXBpS2V5QXV0aG9yaXphdGlvbiA9IG1vZHVsZS5leHBvcnRzLkFwaUtleUF1dGhvcml6YXRpb24gPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIHR5cGUpIHtcbiAgdGhpcy5uYW1lID0gbmFtZTtcbiAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICB0aGlzLnR5cGUgPSB0eXBlO1xufTtcblxuQXBpS2V5QXV0aG9yaXphdGlvbi5wcm90b3R5cGUuYXBwbHkgPSBmdW5jdGlvbiAob2JqKSB7XG4gIGlmICh0aGlzLnR5cGUgPT09ICdxdWVyeScpIHtcbiAgICAvLyBzZWUgaWYgYWxyZWFkeSBhcHBsaWVkLiAgSWYgc28sIGRvbid0IGRvIGl0IGFnYWluXG5cbiAgICB2YXIgcXA7XG4gICAgaWYgKG9iai51cmwuaW5kZXhPZignPycpID4gMCkge1xuICAgICAgcXAgPSBvYmoudXJsLnN1YnN0cmluZyhvYmoudXJsLmluZGV4T2YoJz8nKSArIDEpO1xuICAgICAgdmFyIHBhcnRzID0gcXAuc3BsaXQoJyYnKTtcbiAgICAgIGlmKHBhcnRzICYmIHBhcnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIGt2ID0gcGFydHNbaV0uc3BsaXQoJz0nKTtcbiAgICAgICAgICBpZihrdiAmJiBrdi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBpZiAoa3ZbMF0gPT09IHRoaXMubmFtZSkge1xuICAgICAgICAgICAgICAvLyBza2lwIGl0XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAob2JqLnVybC5pbmRleE9mKCc/JykgPiAwKSB7XG4gICAgICBvYmoudXJsID0gb2JqLnVybCArICcmJyArIHRoaXMubmFtZSArICc9JyArIHRoaXMudmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9iai51cmwgPSBvYmoudXJsICsgJz8nICsgdGhpcy5uYW1lICsgJz0nICsgdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmICh0aGlzLnR5cGUgPT09ICdoZWFkZXInKSB7XG4gICAgaWYodHlwZW9mIG9iai5oZWFkZXJzW3RoaXMubmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBvYmouaGVhZGVyc1t0aGlzLm5hbWVdID0gdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcblxudmFyIENvb2tpZUF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5Db29raWVBdXRob3JpemF0aW9uID0gZnVuY3Rpb24gKGNvb2tpZSkge1xuICB0aGlzLmNvb2tpZSA9IGNvb2tpZTtcbn07XG5cbkNvb2tpZUF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBvYmouY29va2llSmFyID0gb2JqLmNvb2tpZUphciB8fCBuZXcgQ29va2llSmFyKCk7XG4gIG9iai5jb29raWVKYXIuc2V0Q29va2llKHRoaXMuY29va2llKTtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogUGFzc3dvcmQgQXV0aG9yaXphdGlvbiBpcyBhIGJhc2ljIGF1dGggaW1wbGVtZW50YXRpb25cbiAqL1xudmFyIFBhc3N3b3JkQXV0aG9yaXphdGlvbiA9IG1vZHVsZS5leHBvcnRzLlBhc3N3b3JkQXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uICh1c2VybmFtZSwgcGFzc3dvcmQpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICBoZWxwZXJzLmxvZygnUGFzc3dvcmRBdXRob3JpemF0aW9uOiB0aGUgXFwnbmFtZVxcJyBhcmd1bWVudCBoYXMgYmVlbiByZW1vdmVkLCBwYXNzIG9ubHkgdXNlcm5hbWUgYW5kIHBhc3N3b3JkJyk7XG4gICAgdXNlcm5hbWUgPSBhcmd1bWVudHNbMV07XG4gICAgcGFzc3dvcmQgPSBhcmd1bWVudHNbMl07XG4gIH1cbiAgdGhpcy51c2VybmFtZSA9IHVzZXJuYW1lO1xuICB0aGlzLnBhc3N3b3JkID0gcGFzc3dvcmQ7XG59O1xuXG5QYXNzd29yZEF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBpZih0eXBlb2Ygb2JqLmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvYmouaGVhZGVycy5BdXRob3JpemF0aW9uID0gJ0Jhc2ljICcgKyBidG9hKHRoaXMudXNlcm5hbWUgKyAnOicgKyB0aGlzLnBhc3N3b3JkKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIF8gPSB7XG4gIGJpbmQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvZnVuY3Rpb24vYmluZCcpLFxuICBjbG9uZURlZXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAnKSxcbiAgZmluZDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZpbmQnKSxcbiAgZm9yRWFjaDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2gnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5JyksXG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgaXNGdW5jdGlvbjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzRnVuY3Rpb24nKSxcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpXG59O1xudmFyIGF1dGggPSByZXF1aXJlKCcuL2F1dGgnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG52YXIgTW9kZWwgPSByZXF1aXJlKCcuL3R5cGVzL21vZGVsJyk7XG52YXIgT3BlcmF0aW9uID0gcmVxdWlyZSgnLi90eXBlcy9vcGVyYXRpb24nKTtcbnZhciBPcGVyYXRpb25Hcm91cCA9IHJlcXVpcmUoJy4vdHlwZXMvb3BlcmF0aW9uR3JvdXAnKTtcbnZhciBSZXNvbHZlciA9IHJlcXVpcmUoJy4vcmVzb2x2ZXInKTtcbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4vaHR0cCcpO1xudmFyIFN3YWdnZXJTcGVjQ29udmVydGVyID0gcmVxdWlyZSgnLi9zcGVjLWNvbnZlcnRlcicpO1xudmFyIFEgPSByZXF1aXJlKCdxJyk7XG5cbi8vIFdlIGhhdmUgdG8ga2VlcCB0cmFjayBvZiB0aGUgZnVuY3Rpb24vcHJvcGVydHkgbmFtZXMgdG8gYXZvaWQgY29sbGlzaW9ucyBmb3IgdGFnIG5hbWVzIHdoaWNoIGFyZSB1c2VkIHRvIGFsbG93IHRoZVxuLy8gZm9sbG93aW5nIHVzYWdlOiAnY2xpZW50Lnt0YWdOYW1lfSdcbnZhciByZXNlcnZlZENsaWVudFRhZ3MgPSBbXG4gICdhcGlzJyxcbiAgJ2F1dGhvcml6YXRpb25TY2hlbWUnLFxuICAnYXV0aG9yaXphdGlvbnMnLFxuICAnYmFzZVBhdGgnLFxuICAnYnVpbGQnLFxuICAnYnVpbGRGcm9tMV8xU3BlYycsXG4gICdidWlsZEZyb20xXzJTcGVjJyxcbiAgJ2J1aWxkRnJvbVNwZWMnLFxuICAnY2xpZW50QXV0aG9yaXphdGlvbnMnLFxuICAnY29udmVydEluZm8nLFxuICAnZGVidWcnLFxuICAnZGVmYXVsdEVycm9yQ2FsbGJhY2snLFxuICAnZGVmYXVsdFN1Y2Nlc3NDYWxsYmFjaycsXG4gICdlbmFibGVDb29raWVzJyxcbiAgJ2ZhaWwnLFxuICAnZmFpbHVyZScsXG4gICdmaW5pc2gnLFxuICAnaGVscCcsXG4gICdob3N0JyxcbiAgJ2lkRnJvbU9wJyxcbiAgJ2luZm8nLFxuICAnaW5pdGlhbGl6ZScsXG4gICdpc0J1aWx0JyxcbiAgJ2lzVmFsaWQnLFxuICAnbW9kZWxQcm9wZXJ0eU1hY3JvJyxcbiAgJ21vZGVscycsXG4gICdtb2RlbHNBcnJheScsXG4gICdvcHRpb25zJyxcbiAgJ3BhcmFtZXRlck1hY3JvJyxcbiAgJ3BhcnNlVXJpJyxcbiAgJ3Byb2dyZXNzJyxcbiAgJ3Jlc291cmNlQ291bnQnLFxuICAnc2FtcGxlTW9kZWxzJyxcbiAgJ3NlbGZSZWZsZWN0JyxcbiAgJ3NldENvbnNvbGlkYXRlZE1vZGVscycsXG4gICdzcGVjJyxcbiAgJ3N1cHBvcnRlZFN1Ym1pdE1ldGhvZHMnLFxuICAnc3dhZ2dlclJlcXVlc3RIZWFkZXJzJyxcbiAgJ3RhZ0Zyb21MYWJlbCcsXG4gICd0aXRsZScsXG4gICd1cmwnLFxuICAndXNlSlF1ZXJ5JyxcbiAgJ2pxdWVyeUFqYXhDYWNoZSdcbl07XG4vLyBXZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWVzIHRvIGF2b2lkIGNvbGxpc2lvbnMgZm9yIHRhZyBuYW1lcyB3aGljaCBhcmUgdXNlZCB0byBhbGxvdyB0aGVcbi8vIGZvbGxvd2luZyB1c2FnZTogJ2NsaWVudC5hcGlzLnt0YWdOYW1lfSdcbnZhciByZXNlcnZlZEFwaVRhZ3MgPSBbXG4gICdhcGlzJyxcbiAgJ2FzQ3VybCcsXG4gICdkZXNjcmlwdGlvbicsXG4gICdleHRlcm5hbERvY3MnLFxuICAnaGVscCcsXG4gICdsYWJlbCcsXG4gICduYW1lJyxcbiAgJ29wZXJhdGlvbicsXG4gICdvcGVyYXRpb25zJyxcbiAgJ29wZXJhdGlvbnNBcnJheScsXG4gICdwYXRoJyxcbiAgJ3RhZydcbl07XG52YXIgc3VwcG9ydGVkT3BlcmF0aW9uTWV0aG9kcyA9IFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ29wdGlvbnMnLCAncGF0Y2gnLCAncG9zdCcsICdwdXQnXTtcbnZhciBTd2FnZ2VyQ2xpZW50ID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIHRoaXMuYXV0aG9yaXphdGlvbnMgPSBudWxsO1xuICB0aGlzLmF1dGhvcml6YXRpb25TY2hlbWUgPSBudWxsO1xuICB0aGlzLmJhc2VQYXRoID0gbnVsbDtcbiAgdGhpcy5kZWJ1ZyA9IGZhbHNlO1xuICB0aGlzLmVuYWJsZUNvb2tpZXMgPSBmYWxzZTtcbiAgdGhpcy5pbmZvID0gbnVsbDtcbiAgdGhpcy5pc0J1aWx0ID0gZmFsc2U7XG4gIHRoaXMuaXNWYWxpZCA9IGZhbHNlO1xuICB0aGlzLm1vZGVsc0FycmF5ID0gW107XG4gIHRoaXMucmVzb3VyY2VDb3VudCA9IDA7XG4gIHRoaXMudXJsID0gbnVsbDtcbiAgdGhpcy51c2VKUXVlcnkgPSBmYWxzZTtcbiAgdGhpcy5qcXVlcnlBamF4Q2FjaGUgPSBmYWxzZTtcbiAgdGhpcy5zd2FnZ2VyT2JqZWN0ID0ge307XG4gIHRoaXMuZGVmZXJyZWRDbGllbnQgPSB1bmRlZmluZWQ7XG5cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IG5ldyBhdXRoLlN3YWdnZXJBdXRob3JpemF0aW9ucygpO1xuXG4gIGlmICh0eXBlb2YgdXJsICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiB0aGlzLmluaXRpYWxpemUodXJsLCBvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMpIHtcbiAgdGhpcy5tb2RlbHMgPSB7fTtcbiAgdGhpcy5zYW1wbGVNb2RlbHMgPSB7fTtcblxuICBpZiAodHlwZW9mIHVybCA9PT0gJ3N0cmluZycpIHtcbiAgICB0aGlzLnVybCA9IHVybDtcbiAgfSBlbHNlIGlmIChfLmlzT2JqZWN0KHVybCkpIHtcbiAgICBvcHRpb25zID0gdXJsO1xuICAgIHRoaXMudXJsID0gb3B0aW9ucy51cmw7XG4gIH1cblxuICBpZih0aGlzLnVybCAmJiB0aGlzLnVybC5pbmRleE9mKCdodHRwOicpID09PSAtMSAmJiB0aGlzLnVybC5pbmRleE9mKCdodHRwczonKSA9PT0gLTEpIHtcbiAgICAvLyBubyBwcm90b2NvbCwgc28gd2UgY2FuIG9ubHkgdXNlIHdpbmRvdyBpZiBpdCBleGlzdHNcbiAgICBpZih0eXBlb2Yod2luZG93KSAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93ICYmIHdpbmRvdy5sb2NhdGlvbikge1xuICAgICAgdGhpcy51cmwgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgdGhpcy51cmw7XG4gICAgfVxuICB9XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKG9wdGlvbnMuYXV0aG9yaXphdGlvbnMpO1xuICB0aGlzLnN3YWdnZXJSZXF1ZXN0SGVhZGVycyA9IG9wdGlvbnMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzIHx8ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTgsKi8qJztcbiAgdGhpcy5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrID0gb3B0aW9ucy5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrIHx8IG51bGw7XG4gIHRoaXMuZGVmYXVsdEVycm9yQ2FsbGJhY2sgPSBvcHRpb25zLmRlZmF1bHRFcnJvckNhbGxiYWNrIHx8IG51bGw7XG4gIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvID0gb3B0aW9ucy5tb2RlbFByb3BlcnR5TWFjcm8gfHwgbnVsbDtcbiAgdGhpcy5jb25uZWN0aW9uQWdlbnQgPSBvcHRpb25zLmNvbm5lY3Rpb25BZ2VudCB8fCBudWxsO1xuICB0aGlzLnBhcmFtZXRlck1hY3JvID0gb3B0aW9ucy5wYXJhbWV0ZXJNYWNybyB8fCBudWxsO1xuICB0aGlzLnVzZVByb21pc2UgPSBvcHRpb25zLnVzZVByb21pc2UgfHwgbnVsbDtcblxuICAvLyBvcGVyYXRpb24gcmVxdWVzdCB0aW1lb3V0IGRlZmF1bHRcbiAgdGhpcy50aW1lb3V0ID0gb3B0aW9ucy50aW1lb3V0IHx8IG51bGw7XG4gIC8vIGRlZmF1bHQgdG8gcmVxdWVzdCB0aW1lb3V0IHdoZW4gbm90IHNwZWNpZmllZFxuICB0aGlzLmZldGNoU3BlY1RpbWVvdXQgPSB0eXBlb2Ygb3B0aW9ucy5mZXRjaFNwZWNUaW1lb3V0ICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICBvcHRpb25zLmZldGNoU3BlY1RpbWVvdXQgOiBvcHRpb25zLnRpbWVvdXQgfHwgbnVsbDtcblxuICBpZih0aGlzLnVzZVByb21pc2UpIHtcbiAgICB0aGlzLmRlZmVycmVkQ2xpZW50ID0gUS5kZWZlcigpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRpb25zLnN1Y2Nlc3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLnN1Y2Nlc3MgPSBvcHRpb25zLnN1Y2Nlc3M7XG4gIH1cbiAgaWYgKG9wdGlvbnMudXNlSlF1ZXJ5KSB7XG4gICAgdGhpcy51c2VKUXVlcnkgPSBvcHRpb25zLnVzZUpRdWVyeTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLmpxdWVyeUFqYXhDYWNoZSkge1xuICAgIHRoaXMuanF1ZXJ5QWpheENhY2hlID0gb3B0aW9ucy5qcXVlcnlBamF4Q2FjaGU7XG4gIH1cblxuICBpZiAob3B0aW9ucy5lbmFibGVDb29raWVzKSB7XG4gICAgdGhpcy5lbmFibGVDb29raWVzID0gb3B0aW9ucy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBtYXliZSBkb24ndCBuZWVkIHRoaXM/XG4gIHRoaXMub3B0aW9ucy50aW1lb3V0ID0gdGhpcy50aW1lb3V0O1xuICB0aGlzLm9wdGlvbnMuZmV0Y2hTcGVjVGltZW91dCA9IHRoaXMuZmV0Y2hTcGVjVGltZW91dDtcblxuICB0aGlzLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgfHwgW107XG4gIHRoaXMuZmFpbHVyZSA9IG9wdGlvbnMuZmFpbHVyZSB8fCBmdW5jdGlvbiAoZXJyKSB7IHRocm93IGVycjsgfTtcbiAgdGhpcy5wcm9ncmVzcyA9IG9wdGlvbnMucHJvZ3Jlc3MgfHwgZnVuY3Rpb24gKCkge307XG4gIHRoaXMuc3BlYyA9IF8uY2xvbmVEZWVwKG9wdGlvbnMuc3BlYyk7IC8vIENsb25lIHNvIHdlIGRvIG5vdCBhbHRlciB0aGUgcHJvdmlkZWQgZG9jdW1lbnRcblxuICBpZiAob3B0aW9ucy5zY2hlbWUpIHtcbiAgICB0aGlzLnNjaGVtZSA9IG9wdGlvbnMuc2NoZW1lO1xuICB9XG5cbiAgaWYgKHRoaXMudXNlUHJvbWlzZSB8fCB0eXBlb2Ygb3B0aW9ucy5zdWNjZXNzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5yZWFkeSA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXMuYnVpbGQoKTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbiAobW9jaykge1xuICBpZiAodGhpcy5pc0J1aWx0KSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHRoaXMuc3BlYykge1xuICAgIHRoaXMucHJvZ3Jlc3MoJ2ZldGNoaW5nIHJlc291cmNlIGxpc3Q7IFBsZWFzZSB3YWl0LicpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucHJvZ3Jlc3MoJ2ZldGNoaW5nIHJlc291cmNlIGxpc3Q6ICcgKyB0aGlzLnVybCArICc7IFBsZWFzZSB3YWl0LicpO1xuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1c2VKUXVlcnk6IHRoaXMudXNlSlF1ZXJ5LFxuICAgIGpxdWVyeUFqYXhDYWNoZTogdGhpcy5qcXVlcnlBamF4Q2FjaGUsXG4gICAgY29ubmVjdGlvbkFnZW50OiB0aGlzLmNvbm5lY3Rpb25BZ2VudCxcbiAgICBlbmFibGVDb29raWVzOiB0aGlzLmVuYWJsZUNvb2tpZXMsXG4gICAgdXJsOiB0aGlzLnVybCxcbiAgICBtZXRob2Q6ICdnZXQnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIGFjY2VwdDogdGhpcy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnNcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBlcnJvcjogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChzZWxmLnVybC5zdWJzdHJpbmcoMCwgNCkgIT09ICdodHRwJykge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ1BsZWFzZSBzcGVjaWZ5IHRoZSBwcm90b2NvbCBmb3IgJyArIHNlbGYudXJsKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5lcnJPYmogJiYgKHJlc3BvbnNlLmVyck9iai5jb2RlID09PSAnRUNPTk5BQk9SVEVEJyB8fCByZXNwb25zZS5lcnJPYmoubWVzc2FnZS5pbmRleE9mKCd0aW1lb3V0JykgIT09IC0xKSkge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ1JlcXVlc3QgdGltZWQgb3V0IGFmdGVyICcgKyBzZWxmLmZldGNoU3BlY1RpbWVvdXQgKyAnbXMnKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdDYW5cXCd0IHJlYWQgZnJvbSBzZXJ2ZXIuICBJdCBtYXkgbm90IGhhdmUgdGhlIGFwcHJvcHJpYXRlIGFjY2Vzcy1jb250cm9sLW9yaWdpbiBzZXR0aW5ncy4nKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDQwNCkge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ0NhblxcJ3QgcmVhZCBzd2FnZ2VyIEpTT04gZnJvbSAnICsgc2VsZi51cmwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwocmVzcG9uc2Uuc3RhdHVzICsgJyA6ICcgKyByZXNwb25zZS5zdGF0dXNUZXh0ICsgJyAnICsgc2VsZi51cmwpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgcmVzcG9uc2U6IGZ1bmN0aW9uIChyZXNwKSB7XG5cbiAgICAgICAgdmFyIHJlc3BvbnNlT2JqID0gcmVzcC5vYmo7XG4gICAgICAgIGlmKCFyZXNwb25zZU9iaikge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ2ZhaWxlZCB0byBwYXJzZSBKU09OL1lBTUwgcmVzcG9uc2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYuc3dhZ2dlclZlcnNpb24gPSByZXNwb25zZU9iai5zd2FnZ2VyVmVyc2lvbjtcbiAgICAgICAgc2VsZi5zd2FnZ2VyT2JqZWN0ID0gcmVzcG9uc2VPYmo7XG5cbiAgICAgICAgaWYgKHJlc3BvbnNlT2JqLnN3YWdnZXIgJiYgcGFyc2VJbnQocmVzcG9uc2VPYmouc3dhZ2dlcikgPT09IDIpIHtcbiAgICAgICAgICBzZWxmLnN3YWdnZXJWZXJzaW9uID0gcmVzcG9uc2VPYmouc3dhZ2dlcjtcblxuICAgICAgICAgIG5ldyBSZXNvbHZlcigpLnJlc29sdmUocmVzcG9uc2VPYmosIHNlbGYudXJsLCBzZWxmLmJ1aWxkRnJvbVNwZWMsIHNlbGYpO1xuXG4gICAgICAgICAgc2VsZi5pc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgY29udmVydGVyID0gbmV3IFN3YWdnZXJTcGVjQ29udmVydGVyKCk7XG4gICAgICAgICAgc2VsZi5vbGRTd2FnZ2VyT2JqZWN0ID0gc2VsZi5zd2FnZ2VyT2JqZWN0O1xuXG4gICAgICAgICAgY29udmVydGVyLnNldERvY3VtZW50YXRpb25Mb2NhdGlvbihzZWxmLnVybCk7XG4gICAgICAgICAgY29udmVydGVyLmNvbnZlcnQocmVzcG9uc2VPYmosIHNlbGYuY2xpZW50QXV0aG9yaXphdGlvbnMsIHNlbGYub3B0aW9ucywgZnVuY3Rpb24oc3BlYykge1xuICAgICAgICAgICAgc2VsZi5zd2FnZ2VyT2JqZWN0ID0gc3BlYztcbiAgICAgICAgICAgIG5ldyBSZXNvbHZlcigpLnJlc29sdmUoc3BlYywgc2VsZi51cmwsIHNlbGYuYnVpbGRGcm9tU3BlYywgc2VsZik7XG4gICAgICAgICAgICBzZWxmLmlzVmFsaWQgPSB0cnVlO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8vIG9ubHkgc2V0IHRpbWVvdXQgd2hlbiBzcGVjaWZpZWRcbiAgaWYgKHRoaXMuZmV0Y2hTcGVjVGltZW91dCkge1xuICAgIG9iai50aW1lb3V0ID0gdGhpcy5mZXRjaFNwZWNUaW1lb3V0O1xuICB9XG5cbiAgaWYgKHRoaXMuc3BlYykge1xuICAgIHNlbGYuc3dhZ2dlck9iamVjdCA9IHRoaXMuc3BlYztcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIG5ldyBSZXNvbHZlcigpLnJlc29sdmUoc2VsZi5zcGVjLCBzZWxmLnVybCwgc2VsZi5idWlsZEZyb21TcGVjLCBzZWxmKTtcbiAgICB9LCAxMCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmopO1xuXG4gICAgaWYgKG1vY2spIHtcbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgbmV3IFN3YWdnZXJIdHRwKCkuZXhlY3V0ZShvYmosIHRoaXMub3B0aW9ucyk7XG4gIH1cblxuICByZXR1cm4gKHRoaXMudXNlUHJvbWlzZSkgPyB0aGlzLmRlZmVycmVkQ2xpZW50LnByb21pc2UgOiB0aGlzO1xufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuYnVpbGRGcm9tU3BlYyA9IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICBpZiAodGhpcy5pc0J1aWx0KSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB0aGlzLmFwaXMgPSB7fTtcbiAgdGhpcy5hcGlzQXJyYXkgPSBbXTtcbiAgdGhpcy5iYXNlUGF0aCA9IHJlc3BvbnNlLmJhc2VQYXRoIHx8ICcnO1xuICB0aGlzLmNvbnN1bWVzID0gcmVzcG9uc2UuY29uc3VtZXM7XG4gIHRoaXMuaG9zdCA9IHJlc3BvbnNlLmhvc3QgfHwgJyc7XG4gIHRoaXMuaW5mbyA9IHJlc3BvbnNlLmluZm8gfHwge307XG4gIHRoaXMucHJvZHVjZXMgPSByZXNwb25zZS5wcm9kdWNlcztcbiAgdGhpcy5zY2hlbWVzID0gcmVzcG9uc2Uuc2NoZW1lcyB8fCBbXTtcbiAgdGhpcy5zZWN1cml0eURlZmluaXRpb25zID0gXy5jbG9uZURlZXAocmVzcG9uc2Uuc2VjdXJpdHlEZWZpbml0aW9ucyk7XG4gIHRoaXMuc2VjdXJpdHkgPSByZXNwb25zZS5zZWN1cml0eTtcbiAgdGhpcy50aXRsZSA9IHJlc3BvbnNlLnRpdGxlIHx8ICcnO1xuXG4gIHZhciBrZXksIGRlZmluZWRUYWdzID0ge30sIGssIGxvY2F0aW9uLCBzZWxmID0gdGhpcywgaTtcblxuICBpZiAocmVzcG9uc2UuZXh0ZXJuYWxEb2NzKSB7XG4gICAgdGhpcy5leHRlcm5hbERvY3MgPSByZXNwb25zZS5leHRlcm5hbERvY3M7XG4gIH1cblxuICAvLyBsZWdhY3kgc3VwcG9ydFxuICB0aGlzLmF1dGhTY2hlbWVzID0gdGhpcy5zZWN1cml0eURlZmluaXRpb25zO1xuXG4gIGlmKHRoaXMuc2VjdXJpdHlEZWZpbml0aW9ucykge1xuICAgIGZvcihrZXkgaW4gdGhpcy5zZWN1cml0eURlZmluaXRpb25zKSB7XG4gICAgICB2YXIgc2VjdXJpdHlEZWZpbml0aW9uID0gdGhpcy5zZWN1cml0eURlZmluaXRpb25zW2tleV07XG4gICAgICBzZWN1cml0eURlZmluaXRpb24udmVuZG9yRXh0ZW5zaW9ucyA9IHt9O1xuICAgICAgZm9yKHZhciBleHQgaW4gc2VjdXJpdHlEZWZpbml0aW9uKSB7XG4gICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoZXh0LCBzZWN1cml0eURlZmluaXRpb24pO1xuICAgICAgICBpZiAoZXh0ID09PSAnc2NvcGVzJykge1xuICAgICAgICAgIHZhciBzY29wZXMgPSBzZWN1cml0eURlZmluaXRpb25bZXh0XTtcbiAgICAgICAgICBpZih0eXBlb2Ygc2NvcGVzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgc2NvcGVzLnZlbmRvckV4dGVuc2lvbnMgPSB7fTtcbiAgICAgICAgICAgIGZvciAodmFyIHMgaW4gc2NvcGVzKSB7XG4gICAgICAgICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMocywgc2NvcGVzKTtcbiAgICAgICAgICAgICAgaWYocy5pbmRleE9mKCd4LScpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHNjb3Blc1tzXTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KHJlc3BvbnNlLnRhZ3MpKSB7XG4gICAgZGVmaW5lZFRhZ3MgPSB7fTtcblxuICAgIGZvciAoayA9IDA7IGsgPCByZXNwb25zZS50YWdzLmxlbmd0aDsgaysrKSB7XG4gICAgICB2YXIgdCA9IF8uY2xvbmVEZWVwKHJlc3BvbnNlLnRhZ3Nba10pO1xuICAgICAgZGVmaW5lZFRhZ3NbdC5uYW1lXSA9IHQ7XG4gICAgICBmb3IoaSBpbiB0KSB7XG4gICAgICAgIGlmKGkgPT09ICdleHRlcm5hbERvY3MnICYmIHR5cGVvZiB0W2ldID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIGZvcih2YXIgaiBpbiB0W2ldKSB7XG4gICAgICAgICAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKGosIHRbaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKGksIHQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG5cbiAgaWYgKHR5cGVvZiB0aGlzLnVybCA9PT0gJ3N0cmluZycpIHtcbiAgICBsb2NhdGlvbiA9IHRoaXMucGFyc2VVcmkodGhpcy51cmwpO1xuICAgIGlmICh0eXBlb2YgdGhpcy5zY2hlbWUgPT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB0aGlzLnNjaGVtZXMgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMuc2NoZW1lcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIHVzZSB0aGUgd2luZG93IHNjaGVtZVxuICAgICAgICB0aGlzLnNjaGVtZSA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbC5yZXBsYWNlKCc6JywnJyk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5zY2hlbWUgPSBsb2NhdGlvbi5zY2hlbWUgfHwgJ2h0dHAnO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmxvY2F0aW9uLnByb3RvY29sLmluZGV4T2YoJ2Nocm9tZS1leHRlbnNpb24nKSA9PT0gMCkge1xuXHRcdC8vIGlmIGl0IGlzIGNocm9tZSBzd2FnZ2VyIHVpIGV4dGVuc2lvbiBzY2hlbWUgdGhlbiBsZXQgc3dhZ2dlciBkb2MgdXJsIHNjaGVtZSBkZWNpZGUgdGhlIHByb3RvY29sXG5cdFx0dGhpcy5zY2hlbWUgPSBsb2NhdGlvbi5zY2hlbWU7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuc2NoZW1lID09PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdmFyIHNjaGVtZSA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbC5yZXBsYWNlKCc6JywnJyk7XG4gICAgICAgIGlmKHNjaGVtZSA9PT0gJ2h0dHBzJyAmJiB0aGlzLnNjaGVtZXMuaW5kZXhPZihzY2hlbWUpID09PSAtMSkge1xuICAgICAgICAgIC8vIGNhbid0IGNhbGwgaHR0cCBmcm9tIGh0dHBzIHNlcnZlZCBwYWdlIGluIGEgYnJvd3NlciFcbiAgICAgICAgICBoZWxwZXJzLmxvZygnQ2Fubm90IGNhbGwgYSBodHRwIHNlcnZlciBmcm9tIGh0dHBzIGluc2lkZSBhIGJyb3dzZXIhJyk7XG4gICAgICAgICAgdGhpcy5zY2hlbWUgPSAnaHR0cCc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZih0aGlzLnNjaGVtZXMuaW5kZXhPZihzY2hlbWUpICE9PSAtMSkge1xuICAgICAgICAgIHRoaXMuc2NoZW1lID0gc2NoZW1lO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGlmKHRoaXMuc2NoZW1lcy5pbmRleE9mKCdodHRwcycpICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zY2hlbWUgPSAnaHR0cHMnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2NoZW1lID0gJ2h0dHAnO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHRoaXMuc2NoZW1lID0gdGhpcy5zY2hlbWVzWzBdIHx8IGxvY2F0aW9uLnNjaGVtZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRoaXMuaG9zdCA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5ob3N0ID09PSAnJykge1xuICAgICAgdGhpcy5ob3N0ID0gbG9jYXRpb24uaG9zdDtcblxuICAgICAgaWYgKGxvY2F0aW9uLnBvcnQpIHtcbiAgICAgICAgdGhpcy5ob3N0ID0gdGhpcy5ob3N0ICsgJzonICsgbG9jYXRpb24ucG9ydDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZXMgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMuc2NoZW1lcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuc2NoZW1lID0gJ2h0dHAnO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgdGhpcy5zY2hlbWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLnNjaGVtZSA9IHRoaXMuc2NoZW1lc1swXTtcbiAgICB9XG4gIH1cblxuICB0aGlzLmRlZmluaXRpb25zID0gcmVzcG9uc2UuZGVmaW5pdGlvbnM7XG5cbiAgZm9yIChrZXkgaW4gdGhpcy5kZWZpbml0aW9ucykge1xuICAgIHZhciBtb2RlbCA9IG5ldyBNb2RlbChrZXksIHRoaXMuZGVmaW5pdGlvbnNba2V5XSwgdGhpcy5tb2RlbHMsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcblxuICAgIGlmIChtb2RlbCkge1xuICAgICAgdGhpcy5tb2RlbHNba2V5XSA9IG1vZGVsO1xuICAgIH1cbiAgfVxuXG4gIC8vIGdldCBwYXRocywgY3JlYXRlIGZ1bmN0aW9ucyBmb3IgZWFjaCBvcGVyYXRpb25JZFxuXG4gIC8vIEJpbmQgaGVscCB0byAnY2xpZW50LmFwaXMnXG4gIHNlbGYuYXBpcy5oZWxwID0gXy5iaW5kKHNlbGYuaGVscCwgc2VsZik7XG5cbiAgXy5mb3JFYWNoKHJlc3BvbnNlLnBhdGhzLCBmdW5jdGlvbiAocGF0aE9iaiwgcGF0aCkge1xuICAgIC8vIE9ubHkgcHJvY2VzcyBhIHBhdGggaWYgaXQncyBhbiBvYmplY3RcbiAgICBpZiAoIV8uaXNQbGFpbk9iamVjdChwYXRoT2JqKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIF8uZm9yRWFjaChzdXBwb3J0ZWRPcGVyYXRpb25NZXRob2RzLCBmdW5jdGlvbiAobWV0aG9kKSB7XG4gICAgICB2YXIgb3BlcmF0aW9uID0gcGF0aE9ialttZXRob2RdO1xuXG4gICAgICBpZiAoXy5pc1VuZGVmaW5lZChvcGVyYXRpb24pKSB7XG4gICAgICAgIC8vIE9wZXJhdGlvbiBkb2VzIG5vdCBleGlzdFxuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2UgaWYgKCFfLmlzUGxhaW5PYmplY3Qob3BlcmF0aW9uKSkge1xuICAgICAgICAvLyBPcGVyYXRpb24gZXhpc3RzIGJ1dCBpdCBpcyBub3QgYW4gT3BlcmF0aW9uIE9iamVjdC4gIFNpbmNlIHRoaXMgaXMgaW52YWxpZCwgbG9nIGl0LlxuICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyBtZXRob2QgKyAnXFwnIG9wZXJhdGlvbiBmb3IgXFwnJyArIHBhdGggKyAnXFwnIHBhdGggaXMgbm90IGFuIE9wZXJhdGlvbiBPYmplY3QnKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciB0YWdzID0gb3BlcmF0aW9uLnRhZ3M7XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHRhZ3MpIHx8ICFfLmlzQXJyYXkodGFncykgfHwgdGFncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGFncyA9IG9wZXJhdGlvbi50YWdzID0gWyAnZGVmYXVsdCcgXTtcbiAgICAgIH1cblxuICAgICAgdmFyIG9wZXJhdGlvbklkID0gc2VsZi5pZEZyb21PcChwYXRoLCBtZXRob2QsIG9wZXJhdGlvbik7XG5cbiAgICAgIHZhciBvcGVyYXRpb25PYmplY3QgPSBuZXcgT3BlcmF0aW9uKHNlbGYsXG4gICAgICAgIG9wZXJhdGlvbi5zY2hlbWUsXG4gICAgICAgIG9wZXJhdGlvbklkLFxuICAgICAgICBtZXRob2QsXG4gICAgICAgIHBhdGgsXG4gICAgICAgIG9wZXJhdGlvbixcbiAgICAgICAgc2VsZi5kZWZpbml0aW9ucyxcbiAgICAgICAgc2VsZi5tb2RlbHMsXG4gICAgICAgIHNlbGYuY2xpZW50QXV0aG9yaXphdGlvbnMpO1xuXG4gICAgICBvcGVyYXRpb25PYmplY3QuY29ubmVjdGlvbkFnZW50ID0gc2VsZi5jb25uZWN0aW9uQWdlbnQ7XG4gICAgICBvcGVyYXRpb25PYmplY3QudmVuZG9yRXh0ZW5zaW9ucyA9IHt9O1xuICAgICAgZm9yKGkgaW4gb3BlcmF0aW9uKSB7XG4gICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaSwgb3BlcmF0aW9uT2JqZWN0LCBvcGVyYXRpb25baV0pO1xuICAgICAgfVxuICAgICAgb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcyA9IG9wZXJhdGlvbi5leHRlcm5hbERvY3M7XG4gICAgICBpZihvcGVyYXRpb25PYmplY3QuZXh0ZXJuYWxEb2NzKSB7XG4gICAgICAgIG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MgPSBfLmNsb25lRGVlcChvcGVyYXRpb25PYmplY3QuZXh0ZXJuYWxEb2NzKTtcbiAgICAgICAgb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcy52ZW5kb3JFeHRlbnNpb25zID0ge307XG4gICAgICAgIGZvcihpIGluIG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MpIHtcbiAgICAgICAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKGksIG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGJpbmQgc2VsZiBvcGVyYXRpb24ncyBleGVjdXRlIGNvbW1hbmQgdG8gdGhlIGFwaVxuICAgICAgXy5mb3JFYWNoKHRhZ3MsIGZ1bmN0aW9uICh0YWcpIHtcbiAgICAgICAgdmFyIGNsaWVudFByb3BlcnR5ID0gXy5pbmRleE9mKHJlc2VydmVkQ2xpZW50VGFncywgdGFnKSA+IC0xID8gJ18nICsgdGFnIDogdGFnO1xuICAgICAgICB2YXIgYXBpUHJvcGVydHkgPSBfLmluZGV4T2YocmVzZXJ2ZWRBcGlUYWdzLCB0YWcpID4gLTEgPyAnXycgKyB0YWcgOiB0YWc7XG4gICAgICAgIHZhciBvcGVyYXRpb25Hcm91cCA9IHNlbGZbY2xpZW50UHJvcGVydHldO1xuXG4gICAgICAgIGlmIChjbGllbnRQcm9wZXJ0eSAhPT0gdGFnKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgdGFnICsgJ1xcJyB0YWcgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWUuICBVc2UgXFwnY2xpZW50LicgK1xuICAgICAgICAgICAgICAgICAgICAgIGNsaWVudFByb3BlcnR5ICsgJ1xcJyBvciBcXCdjbGllbnQuYXBpcy4nICsgdGFnICsgJ1xcJyBpbnN0ZWFkIG9mIFxcJ2NsaWVudC4nICsgdGFnICsgJ1xcJy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhcGlQcm9wZXJ0eSAhPT0gdGFnKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgdGFnICsgJ1xcJyB0YWcgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IG9wZXJhdGlvbiBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lLiAgVXNlICcgK1xuICAgICAgICAgICAgICAgICAgICAgICdcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnXFwnIGluc3RlYWQgb2YgXFwnY2xpZW50LmFwaXMuJyArIHRhZyArICdcXCcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXy5pbmRleE9mKHJlc2VydmVkQXBpVGFncywgb3BlcmF0aW9uSWQpID4gLTEpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyBvcGVyYXRpb25JZCArICdcXCcgb3BlcmF0aW9uSWQgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IG9wZXJhdGlvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAnZnVuY3Rpb24vcHJvcGVydHkgbmFtZS4gIFVzZSBcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnLl8nICsgb3BlcmF0aW9uSWQgK1xuICAgICAgICAgICAgICAgICAgICAgICdcXCcgaW5zdGVhZCBvZiBcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnLicgKyBvcGVyYXRpb25JZCArICdcXCcuJyk7XG5cbiAgICAgICAgICBvcGVyYXRpb25JZCA9ICdfJyArIG9wZXJhdGlvbklkO1xuICAgICAgICAgIG9wZXJhdGlvbk9iamVjdC5uaWNrbmFtZSA9IG9wZXJhdGlvbklkOyAvLyBTbyAnY2xpZW50LmFwaXMuW3RhZ10ub3BlcmF0aW9uSWQuaGVscCgpIHdvcmtzIHByb3Blcmx5XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChvcGVyYXRpb25Hcm91cCkpIHtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cCA9IHNlbGZbY2xpZW50UHJvcGVydHldID0gc2VsZi5hcGlzW2FwaVByb3BlcnR5XSA9IHt9O1xuXG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAub3BlcmF0aW9ucyA9IHt9O1xuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmxhYmVsID0gYXBpUHJvcGVydHk7XG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAuYXBpcyA9IHt9O1xuXG4gICAgICAgICAgdmFyIHRhZ0RlZiA9IGRlZmluZWRUYWdzW3RhZ107XG5cbiAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQodGFnRGVmKSkge1xuICAgICAgICAgICAgb3BlcmF0aW9uR3JvdXAuZGVzY3JpcHRpb24gPSB0YWdEZWYuZGVzY3JpcHRpb247XG4gICAgICAgICAgICBvcGVyYXRpb25Hcm91cC5leHRlcm5hbERvY3MgPSB0YWdEZWYuZXh0ZXJuYWxEb2NzO1xuICAgICAgICAgICAgb3BlcmF0aW9uR3JvdXAudmVuZG9yRXh0ZW5zaW9ucyA9IHRhZ0RlZi52ZW5kb3JFeHRlbnNpb25zO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHNlbGZbY2xpZW50UHJvcGVydHldLmhlbHAgPSBfLmJpbmQoc2VsZi5oZWxwLCBvcGVyYXRpb25Hcm91cCk7XG4gICAgICAgICAgc2VsZi5hcGlzQXJyYXkucHVzaChuZXcgT3BlcmF0aW9uR3JvdXAodGFnLCBvcGVyYXRpb25Hcm91cC5kZXNjcmlwdGlvbiwgb3BlcmF0aW9uR3JvdXAuZXh0ZXJuYWxEb2NzLCBvcGVyYXRpb25PYmplY3QpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wZXJhdGlvbklkID0gc2VsZi5tYWtlVW5pcXVlT3BlcmF0aW9uSWQob3BlcmF0aW9uSWQsIHNlbGYuYXBpc1thcGlQcm9wZXJ0eV0pO1xuXG4gICAgICAgIC8vIEJpbmQgdGFnIGhlbHBcbiAgICAgICAgaWYgKCFfLmlzRnVuY3Rpb24ob3BlcmF0aW9uR3JvdXAuaGVscCkpIHtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cC5oZWxwID0gXy5iaW5kKHNlbGYuaGVscCwgb3BlcmF0aW9uR3JvdXApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYmluZCB0byB0aGUgYXBpcyBvYmplY3RcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0gPSBvcGVyYXRpb25Hcm91cFtvcGVyYXRpb25JZF0gPSBfLmJpbmQob3BlcmF0aW9uT2JqZWN0LmV4ZWN1dGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uT2JqZWN0KTtcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0uaGVscCA9IG9wZXJhdGlvbkdyb3VwW29wZXJhdGlvbklkXS5oZWxwID0gXy5iaW5kKG9wZXJhdGlvbk9iamVjdC5oZWxwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uT2JqZWN0KTtcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0uYXNDdXJsID0gb3BlcmF0aW9uR3JvdXBbb3BlcmF0aW9uSWRdLmFzQ3VybCA9IF8uYmluZChvcGVyYXRpb25PYmplY3QuYXNDdXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbk9iamVjdCk7XG5cbiAgICAgICAgb3BlcmF0aW9uR3JvdXAuYXBpc1tvcGVyYXRpb25JZF0gPSBvcGVyYXRpb25Hcm91cC5vcGVyYXRpb25zW29wZXJhdGlvbklkXSA9IG9wZXJhdGlvbk9iamVjdDtcblxuICAgICAgICAvLyBsZWdhY3kgVUkgZmVhdHVyZVxuICAgICAgICB2YXIgYXBpID0gXy5maW5kKHNlbGYuYXBpc0FycmF5LCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgICAgICAgcmV0dXJuIGFwaS50YWcgPT09IHRhZztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGFwaSkge1xuICAgICAgICAgIGFwaS5vcGVyYXRpb25zQXJyYXkucHVzaChvcGVyYXRpb25PYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gc29ydCB0aGUgYXBpc0FycmF5IGFjY29yZGluZyB0byB0aGUgdGFnc1xuICB2YXIgc29ydGVkQXBpcyA9IFtdO1xuICBfLmZvckVhY2goT2JqZWN0LmtleXMoZGVmaW5lZFRhZ3MpLCBmdW5jdGlvbiAodGFnKSB7XG4gICAgdmFyIHBvcztcbiAgICBmb3IocG9zIGluIHNlbGYuYXBpc0FycmF5KSB7XG4gICAgICB2YXIgX2FwaSA9IHNlbGYuYXBpc0FycmF5W3Bvc107XG4gICAgICBpZihfYXBpICYmIHRhZyA9PT0gX2FwaS5uYW1lKSB7XG4gICAgICAgIHNvcnRlZEFwaXMucHVzaChfYXBpKTtcbiAgICAgICAgc2VsZi5hcGlzQXJyYXlbcG9zXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgLy8gYWRkIGFueXRoaW5nIGxlZnRcbiAgXy5mb3JFYWNoKHNlbGYuYXBpc0FycmF5LCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgaWYoYXBpKSB7XG4gICAgICBzb3J0ZWRBcGlzLnB1c2goYXBpKTtcbiAgICB9XG4gIH0pO1xuICBzZWxmLmFwaXNBcnJheSA9IHNvcnRlZEFwaXM7XG5cbiAgXy5mb3JFYWNoKHJlc3BvbnNlLmRlZmluaXRpb25zLCBmdW5jdGlvbiAoZGVmaW5pdGlvbk9iaiwgZGVmaW5pdGlvbikge1xuICAgIGRlZmluaXRpb25PYmouaWQgPSBkZWZpbml0aW9uLnRvTG93ZXJDYXNlKCk7XG4gICAgZGVmaW5pdGlvbk9iai5uYW1lID0gZGVmaW5pdGlvbjtcbiAgICBzZWxmLm1vZGVsc0FycmF5LnB1c2goZGVmaW5pdGlvbk9iaik7XG4gIH0pO1xuXG4gIHRoaXMuaXNCdWlsdCA9IHRydWU7XG5cbiAgaWYgKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuaXNWYWxpZCA9IHRydWU7XG4gICAgdGhpcy5pc0J1aWx0ID0gdHJ1ZTtcbiAgICB0aGlzLmRlZmVycmVkQ2xpZW50LnJlc29sdmUodGhpcyk7XG5cbiAgICByZXR1cm4gdGhpcy5kZWZlcnJlZENsaWVudC5wcm9taXNlO1xuICB9XG5cbiAgaWYgKHRoaXMuc3VjY2Vzcykge1xuICAgIHRoaXMuc3VjY2VzcygpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5tYWtlVW5pcXVlT3BlcmF0aW9uSWQgPSBmdW5jdGlvbihvcGVyYXRpb25JZCwgYXBpKSB7XG4gIHZhciBjb3VudCA9IDA7XG4gIHZhciBuYW1lID0gb3BlcmF0aW9uSWQ7XG5cbiAgLy8gbWFrZSB1bmlxdWUgYWNyb3NzIHRoaXMgb3BlcmF0aW9uIGdyb3VwXG4gIHdoaWxlKHRydWUpIHtcbiAgICB2YXIgbWF0Y2hlZCA9IGZhbHNlO1xuICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24gKG9wZXJhdGlvbikge1xuICAgICAgaWYob3BlcmF0aW9uLm5pY2tuYW1lID09PSBuYW1lKSB7XG4gICAgICAgIG1hdGNoZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmKCFtYXRjaGVkKSB7XG4gICAgICByZXR1cm4gbmFtZTtcbiAgICB9XG4gICAgbmFtZSA9IG9wZXJhdGlvbklkICsgJ18nICsgY291bnQ7XG4gICAgY291bnQgKys7XG4gIH1cblxuICByZXR1cm4gb3BlcmF0aW9uSWQ7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5wYXJzZVVyaSA9IGZ1bmN0aW9uICh1cmkpIHtcbiAgdmFyIHVybFBhcnNlUkUgPSAvXigoKChbXjpcXC8jXFw/XSs6KT8oPzooXFwvXFwvKSgoPzooKFteOkBcXC8jXFw/XSspKD86XFw6KFteOkBcXC8jXFw/XSspKT8pQCk/KChbXjpcXC8jXFw/XFxdXFxbXSt8XFxbW15cXC9cXF1AIz9dK1xcXSkoPzpcXDooWzAtOV0rKSk/KSk/KT8pPygoXFwvPyg/OlteXFwvXFw/I10rXFwvKykqKShbXlxcPyNdKikpKT8oXFw/W14jXSspPykoIy4qKT8vO1xuICB2YXIgcGFydHMgPSB1cmxQYXJzZVJFLmV4ZWModXJpKTtcblxuICByZXR1cm4ge1xuICAgIHNjaGVtZTogcGFydHNbNF0gPyBwYXJ0c1s0XS5yZXBsYWNlKCc6JywnJykgOiB1bmRlZmluZWQsXG4gICAgaG9zdDogcGFydHNbMTFdLFxuICAgIHBvcnQ6IHBhcnRzWzEyXSxcbiAgICBwYXRoOiBwYXJ0c1sxNV1cbiAgfTtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmhlbHAgPSBmdW5jdGlvbiAoZG9udFByaW50KSB7XG4gIHZhciBvdXRwdXQgPSAnJztcblxuICBpZiAodGhpcyBpbnN0YW5jZW9mIFN3YWdnZXJDbGllbnQpIHtcbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAoYXBpLCBuYW1lKSB7XG4gICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KGFwaSkpIHtcbiAgICAgICAgb3V0cHV0ICs9ICdvcGVyYXRpb25zIGZvciB0aGUgXFwnJyArIG5hbWUgKyAnXFwnIHRhZ1xcbic7XG5cbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbiAob3BlcmF0aW9uLCBuYW1lKSB7XG4gICAgICAgICAgb3V0cHV0ICs9ICcgICogJyArIG5hbWUgKyAnOiAnICsgb3BlcmF0aW9uLnN1bW1hcnkgKyAnXFxuJztcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodGhpcyBpbnN0YW5jZW9mIE9wZXJhdGlvbkdyb3VwIHx8IF8uaXNQbGFpbk9iamVjdCh0aGlzKSkge1xuICAgIG91dHB1dCArPSAnb3BlcmF0aW9ucyBmb3IgdGhlIFxcJycgKyB0aGlzLmxhYmVsICsgJ1xcJyB0YWdcXG4nO1xuXG4gICAgXy5mb3JFYWNoKHRoaXMuYXBpcywgZnVuY3Rpb24gKG9wZXJhdGlvbiwgbmFtZSkge1xuICAgICAgb3V0cHV0ICs9ICcgICogJyArIG5hbWUgKyAnOiAnICsgb3BlcmF0aW9uLnN1bW1hcnkgKyAnXFxuJztcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChkb250UHJpbnQpIHtcbiAgICByZXR1cm4gb3V0cHV0O1xuICB9IGVsc2Uge1xuICAgIGhlbHBlcnMubG9nKG91dHB1dCk7XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS50YWdGcm9tTGFiZWwgPSBmdW5jdGlvbiAobGFiZWwpIHtcbiAgcmV0dXJuIGxhYmVsO1xufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaWRGcm9tT3AgPSBmdW5jdGlvbiAocGF0aCwgaHR0cE1ldGhvZCwgb3ApIHtcbiAgaWYoIW9wIHx8ICFvcC5vcGVyYXRpb25JZCkge1xuICAgIG9wID0gb3AgfHwge307XG4gICAgb3Aub3BlcmF0aW9uSWQgPSBodHRwTWV0aG9kICsgJ18nICsgcGF0aDtcbiAgfVxuICB2YXIgb3BJZCA9IG9wLm9wZXJhdGlvbklkLnJlcGxhY2UoL1tcXHMhQCMkJV4mKigpXys9XFxbe1xcXX07Ojw+fC5cXC8/LFxcXFwnXCJcIi1dL2csICdfJykgfHwgKHBhdGguc3Vic3RyaW5nKDEpICsgJ18nICsgaHR0cE1ldGhvZCk7XG5cbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvKChfKXsyLH0pL2csICdfJyk7XG4gIG9wSWQgPSBvcElkLnJlcGxhY2UoL14oXykqL2csICcnKTtcbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvKFtfXSkqJC9nLCAnJyk7XG5cbiAgcmV0dXJuIG9wSWQ7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5zZXRIb3N0ID0gZnVuY3Rpb24gKGhvc3QpIHtcbiAgdGhpcy5ob3N0ID0gaG9zdDtcblxuICBpZih0aGlzLmFwaXMpIHtcbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbihhcGkpIHtcbiAgICAgIGlmKGFwaS5vcGVyYXRpb25zKSB7XG4gICAgICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24ob3BlcmF0aW9uKSB7XG4gICAgICAgICAgb3BlcmF0aW9uLmhvc3QgPSBob3N0O1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuc2V0QmFzZVBhdGggPSBmdW5jdGlvbiAoYmFzZVBhdGgpIHtcbiAgdGhpcy5iYXNlUGF0aCA9IGJhc2VQYXRoO1xuXG4gIGlmKHRoaXMuYXBpcykge1xuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uKGFwaSkge1xuICAgICAgaWYoYXBpLm9wZXJhdGlvbnMpIHtcbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbihvcGVyYXRpb24pIHtcbiAgICAgICAgICBvcGVyYXRpb24uYmFzZVBhdGggPSBiYXNlUGF0aDtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnNldFNjaGVtZXMgPSBmdW5jdGlvbiAoc2NoZW1lcykge1xuICB0aGlzLnNjaGVtZXMgPSBzY2hlbWVzO1xuXG4gIGlmKHNjaGVtZXMgJiYgc2NoZW1lcy5sZW5ndGggPiAwKSB7XG4gICAgaWYodGhpcy5hcGlzKSB7XG4gICAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgICAgIGlmIChhcGkub3BlcmF0aW9ucykge1xuICAgICAgICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24gKG9wZXJhdGlvbikge1xuICAgICAgICAgICAgb3BlcmF0aW9uLnNjaGVtZSA9IHNjaGVtZXNbMF07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuZmFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gIGlmICh0aGlzLnVzZVByb21pc2UpIHtcbiAgICB0aGlzLmRlZmVycmVkQ2xpZW50LnJlamVjdChtZXNzYWdlKTtcbiAgICByZXR1cm4gdGhpcy5kZWZlcnJlZENsaWVudC5wcm9taXNlO1xuICB9IGVsc2Uge1xuICAgIGlmICh0aGlzLmZhaWx1cmUpIHtcbiAgICAgIHRoaXMuZmFpbHVyZShtZXNzYWdlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLmZhaWx1cmUobWVzc2FnZSk7XG4gICAgfVxuICB9XG59O1xuIiwiKGZ1bmN0aW9uIChwcm9jZXNzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIF8gPSB7XG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGluZGV4T2Y6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZicpXG59O1xuXG5tb2R1bGUuZXhwb3J0cy5fX2JpbmQgPSBmdW5jdGlvbiAoZm4sIG1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpe1xuICAgIHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTtcbiAgfTtcbn07XG5cbnZhciBsb2cgPSBtb2R1bGUuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgLy8gT25seSBsb2cgaWYgYXZhaWxhYmxlIGFuZCB3ZSdyZSBub3QgdGVzdGluZ1xuICBpZiAoY29uc29sZSAmJiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnKSB7XG4gICAgY29uc29sZS5sb2coQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKVswXSk7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzLmZhaWwgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICBsb2cobWVzc2FnZSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5vcHRpb25IdG1sID0gZnVuY3Rpb24gKGxhYmVsLCB2YWx1ZSkge1xuICByZXR1cm4gJzx0cj48dGQgY2xhc3M9XCJvcHRpb25OYW1lXCI+JyArIGxhYmVsICsgJzo8L3RkPjx0ZD4nICsgdmFsdWUgKyAnPC90ZD48L3RyPic7XG59O1xuXG52YXIgcmVzb2x2ZVNjaGVtYSA9IG1vZHVsZS5leHBvcnRzLnJlc29sdmVTY2hlbWEgPSBmdW5jdGlvbiAoc2NoZW1hKSB7XG4gIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLnNjaGVtYSkpIHtcbiAgICBzY2hlbWEgPSByZXNvbHZlU2NoZW1hKHNjaGVtYS5zY2hlbWEpO1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLnNpbXBsZVJlZiA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChuYW1lLmluZGV4T2YoJyMvZGVmaW5pdGlvbnMvJykgPT09IDApIHtcbiAgICByZXR1cm4gbmFtZS5zdWJzdHJpbmcoJyMvZGVmaW5pdGlvbnMvJy5sZW5ndGgpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuYW1lO1xuICB9XG59O1xuXG4vKipcbiAqIGhlbHBlciB0byByZW1vdmUgZXh0ZW5zaW9ucyBhbmQgYWRkIHRoZW0gdG8gYW4gb2JqZWN0XG4gKlxuICogQHBhcmFtIGtleW5hbWVcbiAqIEBwYXJhbSBvYmpcbiAqL1xubW9kdWxlLmV4cG9ydHMuZXh0cmFjdEV4dGVuc2lvbnMgPSBmdW5jdGlvbiAoa2V5bmFtZSwgb2JqLCB2YWx1ZSkge1xuICBpZigha2V5bmFtZSB8fCAhb2JqKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBrZXluYW1lID09PSAnc3RyaW5nJyAmJiBrZXluYW1lLmluZGV4T2YoJ3gtJykgPT09IDApIHtcbiAgICBvYmoudmVuZG9yRXh0ZW5zaW9ucyA9IG9iai52ZW5kb3JFeHRlbnNpb25zIHx8IHt9O1xuICAgIGlmKHZhbHVlKSB7XG4gICAgICBvYmoudmVuZG9yRXh0ZW5zaW9uc1trZXluYW1lXSA9IHZhbHVlO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIG9iai52ZW5kb3JFeHRlbnNpb25zW2tleW5hbWVdID0gb2JqW2tleW5hbWVdO1xuICAgIH1cbiAgfVxufTtcbn0pLmNhbGwodGhpcyxyZXF1aXJlKCdfcHJvY2VzcycpKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW14cFlpOW9aV3h3WlhKekxtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEVpTENKbWFXeGxJam9pWjJWdVpYSmhkR1ZrTG1weklpd2ljMjkxY21ObFVtOXZkQ0k2SWlJc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYklpZDFjMlVnYzNSeWFXTjBKenRjYmx4dWRtRnlJRjhnUFNCN1hHNGdJR2x6VUd4aGFXNVBZbXBsWTNRNklISmxjWFZwY21Vb0oyeHZaR0Z6YUMxamIyMXdZWFF2YkdGdVp5OXBjMUJzWVdsdVQySnFaV04wSnlrc1hHNGdJR2x1WkdWNFQyWTZJSEpsY1hWcGNtVW9KMnh2WkdGemFDMWpiMjF3WVhRdllYSnlZWGt2YVc1a1pYaFBaaWNwWEc1OU8xeHVYRzV0YjJSMWJHVXVaWGh3YjNKMGN5NWZYMkpwYm1RZ1BTQm1kVzVqZEdsdmJpQW9abTRzSUcxbEtTQjdYRzRnSUhKbGRIVnliaUJtZFc1amRHbHZiaWdwZTF4dUlDQWdJSEpsZEhWeWJpQm1iaTVoY0hCc2VTaHRaU3dnWVhKbmRXMWxiblJ6S1R0Y2JpQWdmVHRjYm4wN1hHNWNiblpoY2lCc2IyY2dQU0J0YjJSMWJHVXVaWGh3YjNKMGN5NXNiMmNnUFNCbWRXNWpkR2x2YmlncElIdGNiaUFnTHk4Z1QyNXNlU0JzYjJjZ2FXWWdZWFpoYVd4aFlteGxJR0Z1WkNCM1pTZHlaU0J1YjNRZ2RHVnpkR2x1WjF4dUlDQnBaaUFvWTI5dWMyOXNaU0FtSmlCd2NtOWpaWE56TG1WdWRpNU9UMFJGWDBWT1ZpQWhQVDBnSjNSbGMzUW5LU0I3WEc0Z0lDQWdZMjl1YzI5c1pTNXNiMmNvUVhKeVlYa3VjSEp2ZEc5MGVYQmxMbk5zYVdObExtTmhiR3dvWVhKbmRXMWxiblJ6S1Zzd1hTazdYRzRnSUgxY2JuMDdYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpMbVpoYVd3Z1BTQm1kVzVqZEdsdmJpQW9iV1Z6YzJGblpTa2dlMXh1SUNCc2IyY29iV1Z6YzJGblpTazdYRzU5TzF4dVhHNXRiMlIxYkdVdVpYaHdiM0owY3k1dmNIUnBiMjVJZEcxc0lEMGdablZ1WTNScGIyNGdLR3hoWW1Wc0xDQjJZV3gxWlNrZ2UxeHVJQ0J5WlhSMWNtNGdKengwY2o0OGRHUWdZMnhoYzNNOVhDSnZjSFJwYjI1T1lXMWxYQ0krSnlBcklHeGhZbVZzSUNzZ0p6bzhMM1JrUGp4MFpENG5JQ3NnZG1Gc2RXVWdLeUFuUEM5MFpENDhMM1J5UGljN1hHNTlPMXh1WEc1MllYSWdjbVZ6YjJ4MlpWTmphR1Z0WVNBOUlHMXZaSFZzWlM1bGVIQnZjblJ6TG5KbGMyOXNkbVZUWTJobGJXRWdQU0JtZFc1amRHbHZiaUFvYzJOb1pXMWhLU0I3WEc0Z0lHbG1JQ2hmTG1selVHeGhhVzVQWW1wbFkzUW9jMk5vWlcxaExuTmphR1Z0WVNrcElIdGNiaUFnSUNCelkyaGxiV0VnUFNCeVpYTnZiSFpsVTJOb1pXMWhLSE5qYUdWdFlTNXpZMmhsYldFcE8xeHVJQ0I5WEc1Y2JpQWdjbVYwZFhKdUlITmphR1Z0WVR0Y2JuMDdYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpMbk5wYlhCc1pWSmxaaUE5SUdaMWJtTjBhVzl1SUNodVlXMWxLU0I3WEc0Z0lHbG1JQ2gwZVhCbGIyWWdibUZ0WlNBOVBUMGdKM1Z1WkdWbWFXNWxaQ2NwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdiblZzYkR0Y2JpQWdmVnh1WEc0Z0lHbG1JQ2h1WVcxbExtbHVaR1Y0VDJZb0p5TXZaR1ZtYVc1cGRHbHZibk12SnlrZ1BUMDlJREFwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdibUZ0WlM1emRXSnpkSEpwYm1jb0p5TXZaR1ZtYVc1cGRHbHZibk12Snk1c1pXNW5kR2dwTzF4dUlDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUhKbGRIVnliaUJ1WVcxbE8xeHVJQ0I5WEc1OU8xeHVYRzR2S2lwY2JpQXFJR2hsYkhCbGNpQjBieUJ5WlcxdmRtVWdaWGgwWlc1emFXOXVjeUJoYm1RZ1lXUmtJSFJvWlcwZ2RHOGdZVzRnYjJKcVpXTjBYRzRnS2x4dUlDb2dRSEJoY21GdElHdGxlVzVoYldWY2JpQXFJRUJ3WVhKaGJTQnZZbXBjYmlBcUwxeHViVzlrZFd4bExtVjRjRzl5ZEhNdVpYaDBjbUZqZEVWNGRHVnVjMmx2Ym5NZ1BTQm1kVzVqZEdsdmJpQW9hMlY1Ym1GdFpTd2diMkpxTENCMllXeDFaU2tnZTF4dUlDQnBaaWdoYTJWNWJtRnRaU0I4ZkNBaGIySnFLU0I3WEc0Z0lDQWdjbVYwZFhKdU8xeHVJQ0I5WEc1Y2JpQWdhV1lnS0hSNWNHVnZaaUJyWlhsdVlXMWxJRDA5UFNBbmMzUnlhVzVuSnlBbUppQnJaWGx1WVcxbExtbHVaR1Y0VDJZb0ozZ3RKeWtnUFQwOUlEQXBJSHRjYmlBZ0lDQnZZbW91ZG1WdVpHOXlSWGgwWlc1emFXOXVjeUE5SUc5aWFpNTJaVzVrYjNKRmVIUmxibk5wYjI1eklIeDhJSHQ5TzF4dUlDQWdJR2xtS0haaGJIVmxLU0I3WEc0Z0lDQWdJQ0J2WW1vdWRtVnVaRzl5UlhoMFpXNXphVzl1YzF0clpYbHVZVzFsWFNBOUlIWmhiSFZsTzF4dUlDQWdJSDFjYmlBZ0lDQmxiSE5sSUh0Y2JpQWdJQ0FnSUc5aWFpNTJaVzVrYjNKRmVIUmxibk5wYjI1elcydGxlVzVoYldWZElEMGdiMkpxVzJ0bGVXNWhiV1ZkTzF4dUlDQWdJSDFjYmlBZ2ZWeHVmVHNpWFgwPSIsIihmdW5jdGlvbiAoQnVmZmVyKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcbnZhciByZXF1ZXN0ID0gcmVxdWlyZSgnc3VwZXJhZ2VudCcpO1xudmFyIGpzeWFtbCA9IHJlcXVpcmUoJ2pzLXlhbWwnKTtcbnZhciBfID0ge1xuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGtleXM6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXMnKVxufTtcblxuLypcbiAqIEpRdWVyeUh0dHBDbGllbnQgaXMgYSBsaWdodC13ZWlnaHQsIG5vZGUgb3IgYnJvd3NlciBIVFRQIGNsaWVudFxuICovXG52YXIgSlF1ZXJ5SHR0cENsaWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy50eXBlID0gJ0pRdWVyeUh0dHBDbGllbnQnO1xufTtcblxuLypcbiAqIFN1cGVyYWdlbnRIdHRwQ2xpZW50IGlzIGEgbGlnaHQtd2VpZ2h0LCBub2RlIG9yIGJyb3dzZXIgSFRUUCBjbGllbnRcbiAqL1xudmFyIFN1cGVyYWdlbnRIdHRwQ2xpZW50ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnR5cGUgPSAnU3VwZXJhZ2VudEh0dHBDbGllbnQnO1xufTtcblxuLyoqXG4gKiBTd2FnZ2VySHR0cCBpcyBhIHdyYXBwZXIgZm9yIGV4ZWN1dGluZyByZXF1ZXN0c1xuICovXG52YXIgU3dhZ2dlckh0dHAgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHt9O1xuXG5Td2FnZ2VySHR0cC5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChvYmosIG9wdHMpIHtcbiAgdmFyIGNsaWVudDtcblxuICBpZihvcHRzICYmIG9wdHMuY2xpZW50KSB7XG4gICAgY2xpZW50ID0gb3B0cy5jbGllbnQ7XG4gIH1cbiAgZWxzZSB7XG4gICAgY2xpZW50ID0gbmV3IFN1cGVyYWdlbnRIdHRwQ2xpZW50KG9wdHMpO1xuICB9XG4gIGNsaWVudC5vcHRzID0gb3B0cyB8fCB7fTtcblxuICBpZiAob3B0cyAmJiBvcHRzLnJlcXVlc3RBZ2VudCkge1xuICAgIHJlcXVlc3QgPSBvcHRzLnJlcXVlc3RBZ2VudDtcbiAgfVxuXG4gIC8vIGxlZ2FjeSBzdXBwb3J0XG4gIHZhciBoYXNKUXVlcnkgPSBmYWxzZTtcbiAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZih0eXBlb2Ygd2luZG93LmpRdWVyeSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGhhc0pRdWVyeSA9IHRydWU7XG4gICAgfVxuICB9XG4gIC8vIE9QVElPTlMgc3VwcG9ydFxuICBpZihvYmoubWV0aG9kLnRvTG93ZXJDYXNlKCkgPT09ICdvcHRpb25zJyAmJiBjbGllbnQudHlwZSA9PT0gJ1N1cGVyYWdlbnRIdHRwQ2xpZW50Jykge1xuICAgIGxvZygnZm9yY2luZyBqUXVlcnkgYXMgT1BUSU9OUyBhcmUgbm90IHN1cHBvcnRlZCBieSBTdXBlckFnZW50Jyk7XG4gICAgb2JqLnVzZUpRdWVyeSA9IHRydWU7XG4gIH1cbiAgaWYodGhpcy5pc0ludGVybmV0RXhwbG9yZXIoKSAmJiAob2JqLnVzZUpRdWVyeSA9PT0gZmFsc2UgfHwgIWhhc0pRdWVyeSApKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb25maWd1cmF0aW9uISBKUXVlcnkgaXMgcmVxdWlyZWQgYnV0IG5vdCBhdmFpbGFibGUnKTtcbiAgfVxuICBpZiAoKG9iaiAmJiBvYmoudXNlSlF1ZXJ5ID09PSB0cnVlKSB8fCB0aGlzLmlzSW50ZXJuZXRFeHBsb3JlcigpICYmIGhhc0pRdWVyeSkge1xuICAgIGNsaWVudCA9IG5ldyBKUXVlcnlIdHRwQ2xpZW50KG9wdHMpO1xuICB9XG5cbiAgdmFyIHN1Y2Nlc3MgPSBvYmoub24ucmVzcG9uc2U7XG4gIHZhciBlcnJvciA9IG9iai5vbi5lcnJvcjtcblxuICB2YXIgcmVxdWVzdEludGVyY2VwdG9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGlmKG9wdHMgJiYgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IpIHtcbiAgICAgIGRhdGEgPSBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvci5hcHBseShkYXRhKTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH07XG5cbiAgdmFyIHJlc3BvbnNlSW50ZXJjZXB0b3IgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgaWYob3B0cyAmJiBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IpIHtcbiAgICAgIGRhdGEgPSBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IuYXBwbHkoZGF0YSwgW29ial0pO1xuICAgIH1cbiAgICByZXR1cm4gc3VjY2VzcyhkYXRhKTtcbiAgfTtcblxuICB2YXIgZXJyb3JJbnRlcmNlcHRvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZihvcHRzICYmIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvcikge1xuICAgICAgZGF0YSA9IG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvci5hcHBseShkYXRhLCBbb2JqXSk7XG4gICAgfVxuICAgIGVycm9yKGRhdGEpO1xuICB9O1xuXG4gIG9iai5vbi5lcnJvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBlcnJvckludGVyY2VwdG9yKGRhdGEpO1xuICB9O1xuXG4gIG9iai5vbi5yZXNwb25zZSA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZihkYXRhICYmIGRhdGEuc3RhdHVzID49IDQwMCkge1xuICAgICAgZXJyb3JJbnRlcmNlcHRvcihkYXRhKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXNwb25zZUludGVyY2VwdG9yKGRhdGEpO1xuICAgIH1cbiAgfTtcblxuICBpZiAoXy5pc09iamVjdChvYmopICYmIF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgLy8gc3BlY2lhbCBwcm9jZXNzaW5nIGZvciBmaWxlIHVwbG9hZHMgdmlhIGpxdWVyeVxuICAgIGlmIChvYmouYm9keS50eXBlICYmIG9iai5ib2R5LnR5cGUgPT09ICdmb3JtRGF0YScpe1xuICAgICAgaWYob3B0cy51c2VKUXVlcnkpIHtcbiAgICAgICAgb2JqLmNvbnRlbnRUeXBlID0gZmFsc2U7XG4gICAgICAgIG9iai5wcm9jZXNzRGF0YSA9IGZhbHNlO1xuICAgICAgICBkZWxldGUgb2JqLmhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9iaiA9IHJlcXVlc3RJbnRlcmNlcHRvcihvYmopIHx8IG9iajtcbiAgaWYgKG9iai5iZWZvcmVTZW5kKSB7XG4gICAgb2JqLmJlZm9yZVNlbmQoZnVuY3Rpb24oX29iaikge1xuICAgICAgY2xpZW50LmV4ZWN1dGUoX29iaiB8fCBvYmopO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNsaWVudC5leGVjdXRlKG9iaik7XG4gIH1cblxuICByZXR1cm4gKG9iai5kZWZlcnJlZCkgPyBvYmouZGVmZXJyZWQucHJvbWlzZSA6IG9iajtcbn07XG5cblN3YWdnZXJIdHRwLnByb3RvdHlwZS5pc0ludGVybmV0RXhwbG9yZXIgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBkZXRlY3RlZElFID0gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIG5hdmlnYXRvci51c2VyQWdlbnQpIHtcbiAgICB2YXIgbmF2ID0gbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpO1xuXG4gICAgaWYgKG5hdi5pbmRleE9mKCdtc2llJykgIT09IC0xKSB7XG4gICAgICB2YXIgdmVyc2lvbiA9IHBhcnNlSW50KG5hdi5zcGxpdCgnbXNpZScpWzFdKTtcblxuICAgICAgaWYgKHZlcnNpb24gPD0gOCkge1xuICAgICAgICBkZXRlY3RlZElFID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGV0ZWN0ZWRJRTtcbn07XG5cbkpRdWVyeUh0dHBDbGllbnQucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBqcSA9IHRoaXMualF1ZXJ5IHx8ICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cualF1ZXJ5KTtcbiAgdmFyIGNiID0gb2JqLm9uO1xuICB2YXIgcmVxdWVzdCA9IG9iajtcblxuICBpZih0eXBlb2YganEgPT09ICd1bmRlZmluZWQnIHx8IGpxID09PSBmYWxzZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgY29uZmlndXJhdGlvbiEgSlF1ZXJ5IGlzIHJlcXVpcmVkIGJ1dCBub3QgYXZhaWxhYmxlJyk7XG4gIH1cblxuICBvYmoudHlwZSA9IG9iai5tZXRob2Q7XG4gIG9iai5jYWNoZSA9IG9iai5qcXVlcnlBamF4Q2FjaGU7XG4gIG9iai5kYXRhID0gb2JqLmJvZHk7XG4gIGRlbGV0ZSBvYmouanF1ZXJ5QWpheENhY2hlO1xuICBkZWxldGUgb2JqLnVzZUpRdWVyeTtcbiAgZGVsZXRlIG9iai5ib2R5O1xuXG4gIG9iai5jb21wbGV0ZSA9IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgIHZhciBoZWFkZXJzID0ge307XG4gICAgdmFyIGhlYWRlckFycmF5ID0gcmVzcG9uc2UuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkuc3BsaXQoJ1xcbicpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZWFkZXJBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHRvU3BsaXQgPSBoZWFkZXJBcnJheVtpXS50cmltKCk7XG5cbiAgICAgIGlmICh0b1NwbGl0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIHNlcGFyYXRvciA9IHRvU3BsaXQuaW5kZXhPZignOicpO1xuXG4gICAgICBpZiAoc2VwYXJhdG9yID09PSAtMSkge1xuICAgICAgICAvLyBOYW1lIGJ1dCBubyB2YWx1ZSBpbiB0aGUgaGVhZGVyXG4gICAgICAgIGhlYWRlcnNbdG9TcGxpdF0gPSBudWxsO1xuXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgbmFtZSA9IHRvU3BsaXQuc3Vic3RyaW5nKDAsIHNlcGFyYXRvcikudHJpbSgpO1xuICAgICAgdmFyIHZhbHVlID0gdG9TcGxpdC5zdWJzdHJpbmcoc2VwYXJhdG9yICsgMSkudHJpbSgpO1xuXG4gICAgICBoZWFkZXJzW25hbWVdID0gdmFsdWU7XG4gICAgfVxuXG4gICAgdmFyIG91dCA9IHtcbiAgICAgIHVybDogcmVxdWVzdC51cmwsXG4gICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICBzdGF0dXNUZXh0OiByZXNwb25zZS5zdGF0dXNUZXh0LFxuICAgICAgZGF0YTogcmVzcG9uc2UucmVzcG9uc2VUZXh0LFxuICAgICAgaGVhZGVyczogaGVhZGVyc1xuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgdmFyIHBvc3NpYmxlT2JqID0gIHJlc3BvbnNlLnJlc3BvbnNlSlNPTiB8fCBqc3lhbWwuc2FmZUxvYWQocmVzcG9uc2UucmVzcG9uc2VUZXh0KTtcbiAgICAgIG91dC5vYmogPSAodHlwZW9mIHBvc3NpYmxlT2JqID09PSAnc3RyaW5nJykgPyB7fSA6IHBvc3NpYmxlT2JqO1xuICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICAvLyBkbyBub3Qgc2V0IG91dC5vYmpcbiAgICAgIGhlbHBlcnMubG9nKCd1bmFibGUgdG8gcGFyc2UgSlNPTi9ZQU1MIGNvbnRlbnQnKTtcbiAgICB9XG5cbiAgICAvLyBJIGNhbiB0aHJvdywgb3IgcGFyc2UgbnVsbD9cbiAgICBvdXQub2JqID0gb3V0Lm9iaiB8fCBudWxsO1xuXG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA+PSAyMDAgJiYgcmVzcG9uc2Uuc3RhdHVzIDwgMzAwKSB7XG4gICAgICBjYi5yZXNwb25zZShvdXQpO1xuICAgIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSAwIHx8IChyZXNwb25zZS5zdGF0dXMgPj0gNDAwICYmIHJlc3BvbnNlLnN0YXR1cyA8IDU5OSkpIHtcbiAgICAgIGNiLmVycm9yKG91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjYi5yZXNwb25zZShvdXQpO1xuICAgIH1cbiAgfTtcblxuICBqcS5zdXBwb3J0LmNvcnMgPSB0cnVlO1xuXG4gIHJldHVybiBqcS5hamF4KG9iaik7XG59O1xuXG5TdXBlcmFnZW50SHR0cENsaWVudC5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIG1ldGhvZCA9IG9iai5tZXRob2QudG9Mb3dlckNhc2UoKTtcbiAgdmFyIHRpbWVvdXQgPSBvYmoudGltZW91dDtcblxuICBpZiAobWV0aG9kID09PSAnZGVsZXRlJykge1xuICAgIG1ldGhvZCA9ICdkZWwnO1xuICB9XG4gIHZhciBoZWFkZXJzID0gb2JqLmhlYWRlcnMgfHwge307XG5cbiAgdmFyIHIgPSByZXF1ZXN0W21ldGhvZF0ob2JqLnVybCk7XG5cbiAgaWYgKG9iai5jb25uZWN0aW9uQWdlbnQpIHtcbiAgICByLmFnZW50KG9iai5jb25uZWN0aW9uQWdlbnQpO1xuICB9XG5cbiAgaWYgKHRpbWVvdXQpIHtcbiAgICByLnRpbWVvdXQodGltZW91dCk7XG4gIH1cblxuICBpZiAob2JqLmVuYWJsZUNvb2tpZXMpIHtcbiAgICByLndpdGhDcmVkZW50aWFscygpO1xuICB9XG5cbiAgdmFyIGFjY2VwdCA9IG9iai5oZWFkZXJzLkFjY2VwdDtcblxuICBpZih0aGlzLmJpbmFyeVJlcXVlc3QoYWNjZXB0KSkge1xuICAgIHIub24oJ3JlcXVlc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpZih0aGlzLnhocikge1xuICAgICAgICB0aGlzLnhoci5yZXNwb25zZVR5cGUgPSAnYmxvYic7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBpZihvYmouYm9keSkge1xuICAgIGlmKF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgICB2YXIgY29udGVudFR5cGUgPSBvYmouaGVhZGVyc1snQ29udGVudC1UeXBlJ10gfHwgJyc7XG4gICAgICBpZiAoY29udGVudFR5cGUuaW5kZXhPZignbXVsdGlwYXJ0L2Zvcm0tZGF0YScpID09PSAwKSB7XG4gICAgICAgIGRlbGV0ZSBoZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgICAgICAgaWYoe30udG9TdHJpbmcuYXBwbHkob2JqLmJvZHkpID09PSAnW29iamVjdCBGb3JtRGF0YV0nKSB7XG4gICAgICAgICAgci5zZW5kKG9iai5ib2R5KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB2YXIga2V5bmFtZSwgdmFsdWUsIHY7XG4gICAgICAgICAgZm9yIChrZXluYW1lIGluIG9iai5ib2R5KSB7XG4gICAgICAgICAgICB2YWx1ZSA9IG9iai5ib2R5W2tleW5hbWVdO1xuICAgICAgICAgICAgaWYoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgZm9yKHYgaW4gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICByLmZpZWxkKGtleW5hbWUsIHYpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgci5maWVsZChrZXluYW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChfLmlzT2JqZWN0KG9iai5ib2R5KSkge1xuICAgICAgICAvLyBub24gbXVsdGlwYXJ0L2Zvcm0tZGF0YVxuICAgICAgICBvYmouYm9keSA9IEpTT04uc3RyaW5naWZ5KG9iai5ib2R5KTtcbiAgICAgICAgci5zZW5kKG9iai5ib2R5KTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByLnNlbmQob2JqLmJvZHkpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBuYW1lO1xuICBmb3IgKG5hbWUgaW4gaGVhZGVycykge1xuICAgIHIuc2V0KG5hbWUsIGhlYWRlcnNbbmFtZV0pO1xuICB9XG5cbiAgaWYodHlwZW9mIHIuYnVmZmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgci5idWZmZXIoKTsgLy8gZm9yY2Ugc3VwZXJhZ2VudCB0byBwb3B1bGF0ZSByZXMudGV4dCB3aXRoIHRoZSByYXcgcmVzcG9uc2UgZGF0YVxuICB9XG5cbiAgci5lbmQoZnVuY3Rpb24gKGVyciwgcmVzKSB7XG4gICAgcmVzID0gcmVzIHx8IHtcbiAgICAgIHN0YXR1czogMCxcbiAgICAgIGhlYWRlcnM6IHtlcnJvcjogJ25vIHJlc3BvbnNlIGZyb20gc2VydmVyJ31cbiAgICB9O1xuICAgIHZhciByZXNwb25zZSA9IHtcbiAgICAgIHVybDogb2JqLnVybCxcbiAgICAgIG1ldGhvZDogb2JqLm1ldGhvZCxcbiAgICAgIGhlYWRlcnM6IHJlcy5oZWFkZXJzXG4gICAgfTtcbiAgICB2YXIgY2I7XG5cbiAgICBpZiAoIWVyciAmJiByZXMuZXJyb3IpIHtcbiAgICAgIGVyciA9IHJlcy5lcnJvcjtcbiAgICB9XG5cbiAgICBpZiAoZXJyICYmIG9iai5vbiAmJiBvYmoub24uZXJyb3IpIHtcbiAgICAgIHJlc3BvbnNlLmVyck9iaiA9IGVycjtcbiAgICAgIHJlc3BvbnNlLnN0YXR1cyA9IHJlcyA/IHJlcy5zdGF0dXMgOiA1MDA7XG4gICAgICByZXNwb25zZS5zdGF0dXNUZXh0ID0gcmVzID8gcmVzLnRleHQgOiBlcnIubWVzc2FnZTtcbiAgICAgIGlmIChyZXMuaGVhZGVycyAmJiByZXMuaGVhZGVyc1snY29udGVudC10eXBlJ10pIHtcbiAgICAgICAgaWYgKHJlcy5oZWFkZXJzWydjb250ZW50LXR5cGUnXS5pbmRleE9mKCdhcHBsaWNhdGlvbi9qc29uJykgPj0gMCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXNwb25zZS5vYmogPSBKU09OLnBhcnNlKHJlc3BvbnNlLnN0YXR1c1RleHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmVzcG9uc2Uub2JqID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNiID0gb2JqLm9uLmVycm9yO1xuICAgIH0gZWxzZSBpZiAocmVzICYmIG9iai5vbiAmJiBvYmoub24ucmVzcG9uc2UpIHtcbiAgICAgIHZhciBwb3NzaWJsZU9iajtcblxuICAgICAgLy8gQWxyZWFkeSBwYXJzZWQgYnkgYnkgc3VwZXJhZ2VudD9cbiAgICAgIGlmIChyZXMuYm9keSAmJiBfLmtleXMocmVzLmJvZHkpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcG9zc2libGVPYmogPSByZXMuYm9keTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcG9zc2libGVPYmogPSBqc3lhbWwuc2FmZUxvYWQocmVzLnRleHQpO1xuICAgICAgICAgIC8vIGNhbiBwYXJzZSBpbnRvIGEgc3RyaW5nLi4uIHdoaWNoIHdlIGRvbid0IG5lZWQgcnVubmluZyBhcm91bmQgaW4gdGhlIHN5c3RlbVxuICAgICAgICAgIHBvc3NpYmxlT2JqID0gKHR5cGVvZiBwb3NzaWJsZU9iaiA9PT0gJ3N0cmluZycpID8gbnVsbCA6IHBvc3NpYmxlT2JqO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ2Nhbm5vdCBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIG51bGwgbWVhbnMgd2UgY2FuJ3QgcGFyc2UgaW50byBvYmplY3RcbiAgICAgIGlmKHR5cGVvZiBCdWZmZXIgPT09ICdmdW5jdGlvbicgJiYgQnVmZmVyLmlzQnVmZmVyKHBvc3NpYmxlT2JqKSkge1xuICAgICAgICByZXNwb25zZS5kYXRhID0gcG9zc2libGVPYmo7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcmVzcG9uc2Uub2JqID0gKHR5cGVvZiBwb3NzaWJsZU9iaiA9PT0gJ29iamVjdCcpID8gcG9zc2libGVPYmogOiBudWxsO1xuICAgICAgfVxuXG4gICAgICByZXNwb25zZS5zdGF0dXMgPSByZXMuc3RhdHVzO1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzVGV4dCA9IHJlcy50ZXh0O1xuICAgICAgY2IgPSBvYmoub24ucmVzcG9uc2U7XG4gICAgfVxuICAgIGlmIChyZXMueGhyICYmIHJlcy54aHIucmVzcG9uc2UpIHtcbiAgICAgIHJlc3BvbnNlLmRhdGEgPSByZXMueGhyLnJlc3BvbnNlO1xuICAgIH1cbiAgICBlbHNlIGlmKCFyZXNwb25zZS5kYXRhKSB7XG4gICAgICByZXNwb25zZS5kYXRhID0gcmVzcG9uc2Uuc3RhdHVzVGV4dDtcbiAgICB9XG5cbiAgICBpZiAoY2IpIHtcbiAgICAgIGNiKHJlc3BvbnNlKTtcbiAgICB9XG4gIH0pO1xufTtcblxuU3VwZXJhZ2VudEh0dHBDbGllbnQucHJvdG90eXBlLiBiaW5hcnlSZXF1ZXN0ID0gZnVuY3Rpb24gKGFjY2VwdCkge1xuICBpZighYWNjZXB0KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAoL15pbWFnZS9pKS50ZXN0KGFjY2VwdClcbiAgICB8fCAoL15hcHBsaWNhdGlvblxcL3BkZi8pLnRlc3QoYWNjZXB0KVxuICAgIHx8ICgvXmFwcGxpY2F0aW9uXFwvb2N0ZXQtc3RyZWFtLykudGVzdChhY2NlcHQpO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW14cFlpOW9kSFJ3TG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SW5kWE5sSUhOMGNtbGpkQ2M3WEc1Y2JuWmhjaUJvWld4d1pYSnpJRDBnY21WeGRXbHlaU2duTGk5b1pXeHdaWEp6SnlrN1hHNTJZWElnY21WeGRXVnpkQ0E5SUhKbGNYVnBjbVVvSjNOMWNHVnlZV2RsYm5RbktUdGNiblpoY2lCcWMzbGhiV3dnUFNCeVpYRjFhWEpsS0NkcWN5MTVZVzFzSnlrN1hHNTJZWElnWHlBOUlIdGNiaUFnYVhOUFltcGxZM1E2SUhKbGNYVnBjbVVvSjJ4dlpHRnphQzFqYjIxd1lYUXZiR0Z1Wnk5cGMwOWlhbVZqZENjcExGeHVJQ0JyWlhsek9pQnlaWEYxYVhKbEtDZHNiMlJoYzJndFkyOXRjR0YwTDI5aWFtVmpkQzlyWlhsekp5bGNibjA3WEc1Y2JpOHFYRzRnS2lCS1VYVmxjbmxJZEhSd1EyeHBaVzUwSUdseklHRWdiR2xuYUhRdGQyVnBaMmgwTENCdWIyUmxJRzl5SUdKeWIzZHpaWElnU0ZSVVVDQmpiR2xsYm5SY2JpQXFMMXh1ZG1GeUlFcFJkV1Z5ZVVoMGRIQkRiR2xsYm5RZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lIUm9hWE11ZEhsd1pTQTlJQ2RLVVhWbGNubElkSFJ3UTJ4cFpXNTBKenRjYm4wN1hHNWNiaThxWEc0Z0tpQlRkWEJsY21GblpXNTBTSFIwY0VOc2FXVnVkQ0JwY3lCaElHeHBaMmgwTFhkbGFXZG9kQ3dnYm05a1pTQnZjaUJpY205M2MyVnlJRWhVVkZBZ1kyeHBaVzUwWEc0Z0tpOWNiblpoY2lCVGRYQmxjbUZuWlc1MFNIUjBjRU5zYVdWdWRDQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdkR2hwY3k1MGVYQmxJRDBnSjFOMWNHVnlZV2RsYm5SSWRIUndRMnhwWlc1MEp6dGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1UzZGhaMmRsY2toMGRIQWdhWE1nWVNCM2NtRndjR1Z5SUdadmNpQmxlR1ZqZFhScGJtY2djbVZ4ZFdWemRITmNiaUFxTDF4dWRtRnlJRk4zWVdkblpYSklkSFJ3SUQwZ2JXOWtkV3hsTG1WNGNHOXlkSE1nUFNCbWRXNWpkR2x2YmlBb0tTQjdmVHRjYmx4dVUzZGhaMmRsY2toMGRIQXVjSEp2ZEc5MGVYQmxMbVY0WldOMWRHVWdQU0JtZFc1amRHbHZiaUFvYjJKcUxDQnZjSFJ6S1NCN1hHNGdJSFpoY2lCamJHbGxiblE3WEc1Y2JpQWdhV1lvYjNCMGN5QW1KaUJ2Y0hSekxtTnNhV1Z1ZENrZ2UxeHVJQ0FnSUdOc2FXVnVkQ0E5SUc5d2RITXVZMnhwWlc1ME8xeHVJQ0I5WEc0Z0lHVnNjMlVnZTF4dUlDQWdJR05zYVdWdWRDQTlJRzVsZHlCVGRYQmxjbUZuWlc1MFNIUjBjRU5zYVdWdWRDaHZjSFJ6S1R0Y2JpQWdmVnh1SUNCamJHbGxiblF1YjNCMGN5QTlJRzl3ZEhNZ2ZId2dlMzA3WEc1Y2JpQWdhV1lnS0c5d2RITWdKaVlnYjNCMGN5NXlaWEYxWlhOMFFXZGxiblFwSUh0Y2JpQWdJQ0J5WlhGMVpYTjBJRDBnYjNCMGN5NXlaWEYxWlhOMFFXZGxiblE3WEc0Z0lIMWNibHh1SUNBdkx5QnNaV2RoWTNrZ2MzVndjRzl5ZEZ4dUlDQjJZWElnYUdGelNsRjFaWEo1SUQwZ1ptRnNjMlU3WEc0Z0lHbG1LSFI1Y0dWdlppQjNhVzVrYjNjZ0lUMDlJQ2QxYm1SbFptbHVaV1FuS1NCN1hHNGdJQ0FnYVdZb2RIbHdaVzltSUhkcGJtUnZkeTVxVVhWbGNua2dJVDA5SUNkMWJtUmxabWx1WldRbktTQjdYRzRnSUNBZ0lDQm9ZWE5LVVhWbGNua2dQU0IwY25WbE8xeHVJQ0FnSUgxY2JpQWdmVnh1SUNBdkx5QlBVRlJKVDA1VElITjFjSEJ2Y25SY2JpQWdhV1lvYjJKcUxtMWxkR2h2WkM1MGIweHZkMlZ5UTJGelpTZ3BJRDA5UFNBbmIzQjBhVzl1Y3ljZ0ppWWdZMnhwWlc1MExuUjVjR1VnUFQwOUlDZFRkWEJsY21GblpXNTBTSFIwY0VOc2FXVnVkQ2NwSUh0Y2JpQWdJQ0JzYjJjb0oyWnZjbU5wYm1jZ2FsRjFaWEo1SUdGeklFOVFWRWxQVGxNZ1lYSmxJRzV2ZENCemRYQndiM0owWldRZ1lua2dVM1Z3WlhKQloyVnVkQ2NwTzF4dUlDQWdJRzlpYWk1MWMyVktVWFZsY25rZ1BTQjBjblZsTzF4dUlDQjlYRzRnSUdsbUtIUm9hWE11YVhOSmJuUmxjbTVsZEVWNGNHeHZjbVZ5S0NrZ0ppWWdLRzlpYWk1MWMyVktVWFZsY25rZ1BUMDlJR1poYkhObElIeDhJQ0ZvWVhOS1VYVmxjbmtnS1NrZ2UxeHVJQ0FnSUhSb2NtOTNJRzVsZHlCRmNuSnZjaWduVlc1emRYQndiM0owWldRZ1kyOXVabWxuZFhKaGRHbHZiaUVnU2xGMVpYSjVJR2x6SUhKbGNYVnBjbVZrSUdKMWRDQnViM1FnWVhaaGFXeGhZbXhsSnlrN1hHNGdJSDFjYmlBZ2FXWWdLQ2h2WW1vZ0ppWWdiMkpxTG5WelpVcFJkV1Z5ZVNBOVBUMGdkSEoxWlNrZ2ZId2dkR2hwY3k1cGMwbHVkR1Z5Ym1WMFJYaHdiRzl5WlhJb0tTQW1KaUJvWVhOS1VYVmxjbmtwSUh0Y2JpQWdJQ0JqYkdsbGJuUWdQU0J1WlhjZ1NsRjFaWEo1U0hSMGNFTnNhV1Z1ZENodmNIUnpLVHRjYmlBZ2ZWeHVYRzRnSUhaaGNpQnpkV05qWlhOeklEMGdiMkpxTG05dUxuSmxjM0J2Ym5ObE8xeHVJQ0IyWVhJZ1pYSnliM0lnUFNCdlltb3ViMjR1WlhKeWIzSTdYRzVjYmlBZ2RtRnlJSEpsY1hWbGMzUkpiblJsY21ObGNIUnZjaUE5SUdaMWJtTjBhVzl1S0dSaGRHRXBJSHRjYmlBZ0lDQnBaaWh2Y0hSeklDWW1JRzl3ZEhNdWNtVnhkV1Z6ZEVsdWRHVnlZMlZ3ZEc5eUtTQjdYRzRnSUNBZ0lDQmtZWFJoSUQwZ2IzQjBjeTV5WlhGMVpYTjBTVzUwWlhKalpYQjBiM0l1WVhCd2JIa29aR0YwWVNrN1hHNGdJQ0FnZlZ4dUlDQWdJSEpsZEhWeWJpQmtZWFJoTzF4dUlDQjlPMXh1WEc0Z0lIWmhjaUJ5WlhOd2IyNXpaVWx1ZEdWeVkyVndkRzl5SUQwZ1puVnVZM1JwYjI0b1pHRjBZU2tnZTF4dUlDQWdJR2xtS0c5d2RITWdKaVlnYjNCMGN5NXlaWE53YjI1elpVbHVkR1Z5WTJWd2RHOXlLU0I3WEc0Z0lDQWdJQ0JrWVhSaElEMGdiM0IwY3k1eVpYTndiMjV6WlVsdWRHVnlZMlZ3ZEc5eUxtRndjR3g1S0dSaGRHRXNJRnR2WW1wZEtUdGNiaUFnSUNCOVhHNGdJQ0FnY21WMGRYSnVJSE4xWTJObGMzTW9aR0YwWVNrN1hHNGdJSDA3WEc1Y2JpQWdkbUZ5SUdWeWNtOXlTVzUwWlhKalpYQjBiM0lnUFNCbWRXNWpkR2x2Ymloa1lYUmhLU0I3WEc0Z0lDQWdhV1lvYjNCMGN5QW1KaUJ2Y0hSekxuSmxjM0J2Ym5ObFNXNTBaWEpqWlhCMGIzSXBJSHRjYmlBZ0lDQWdJR1JoZEdFZ1BTQnZjSFJ6TG5KbGMzQnZibk5sU1c1MFpYSmpaWEIwYjNJdVlYQndiSGtvWkdGMFlTd2dXMjlpYWwwcE8xeHVJQ0FnSUgxY2JpQWdJQ0JsY25KdmNpaGtZWFJoS1R0Y2JpQWdmVHRjYmx4dUlDQnZZbW91YjI0dVpYSnliM0lnUFNCbWRXNWpkR2x2Ymloa1lYUmhLU0I3WEc0Z0lDQWdaWEp5YjNKSmJuUmxjbU5sY0hSdmNpaGtZWFJoS1R0Y2JpQWdmVHRjYmx4dUlDQnZZbW91YjI0dWNtVnpjRzl1YzJVZ1BTQm1kVzVqZEdsdmJpaGtZWFJoS1NCN1hHNGdJQ0FnYVdZb1pHRjBZU0FtSmlCa1lYUmhMbk4wWVhSMWN5QStQU0EwTURBcElIdGNiaUFnSUNBZ0lHVnljbTl5U1c1MFpYSmpaWEIwYjNJb1pHRjBZU2s3WEc0Z0lDQWdmVnh1SUNBZ0lHVnNjMlVnZTF4dUlDQWdJQ0FnY21WemNHOXVjMlZKYm5SbGNtTmxjSFJ2Y2loa1lYUmhLVHRjYmlBZ0lDQjlYRzRnSUgwN1hHNWNiaUFnYVdZZ0tGOHVhWE5QWW1wbFkzUW9iMkpxS1NBbUppQmZMbWx6VDJKcVpXTjBLRzlpYWk1aWIyUjVLU2tnZTF4dUlDQWdJQzh2SUhOd1pXTnBZV3dnY0hKdlkyVnpjMmx1WnlCbWIzSWdabWxzWlNCMWNHeHZZV1J6SUhacFlTQnFjWFZsY25sY2JpQWdJQ0JwWmlBb2IySnFMbUp2WkhrdWRIbHdaU0FtSmlCdlltb3VZbTlrZVM1MGVYQmxJRDA5UFNBblptOXliVVJoZEdFbktYdGNiaUFnSUNBZ0lHbG1LRzl3ZEhNdWRYTmxTbEYxWlhKNUtTQjdYRzRnSUNBZ0lDQWdJRzlpYWk1amIyNTBaVzUwVkhsd1pTQTlJR1poYkhObE8xeHVJQ0FnSUNBZ0lDQnZZbW91Y0hKdlkyVnpjMFJoZEdFZ1BTQm1ZV3h6WlR0Y2JpQWdJQ0FnSUNBZ1pHVnNaWFJsSUc5aWFpNW9aV0ZrWlhKeld5ZERiMjUwWlc1MExWUjVjR1VuWFR0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNCdlltb2dQU0J5WlhGMVpYTjBTVzUwWlhKalpYQjBiM0lvYjJKcUtTQjhmQ0J2WW1vN1hHNGdJR2xtSUNodlltb3VZbVZtYjNKbFUyVnVaQ2tnZTF4dUlDQWdJRzlpYWk1aVpXWnZjbVZUWlc1a0tHWjFibU4wYVc5dUtGOXZZbW9wSUh0Y2JpQWdJQ0FnSUdOc2FXVnVkQzVsZUdWamRYUmxLRjl2WW1vZ2ZId2diMkpxS1R0Y2JpQWdJQ0I5S1R0Y2JpQWdmU0JsYkhObElIdGNiaUFnSUNCamJHbGxiblF1WlhobFkzVjBaU2h2WW1vcE8xeHVJQ0I5WEc1Y2JpQWdjbVYwZFhKdUlDaHZZbW91WkdWbVpYSnlaV1FwSUQ4Z2IySnFMbVJsWm1WeWNtVmtMbkJ5YjIxcGMyVWdPaUJ2WW1vN1hHNTlPMXh1WEc1VGQyRm5aMlZ5U0hSMGNDNXdjbTkwYjNSNWNHVXVhWE5KYm5SbGNtNWxkRVY0Y0d4dmNtVnlJRDBnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0IyWVhJZ1pHVjBaV04wWldSSlJTQTlJR1poYkhObE8xeHVYRzRnSUdsbUlDaDBlWEJsYjJZZ2JtRjJhV2RoZEc5eUlDRTlQU0FuZFc1a1pXWnBibVZrSnlBbUppQnVZWFpwWjJGMGIzSXVkWE5sY2tGblpXNTBLU0I3WEc0Z0lDQWdkbUZ5SUc1aGRpQTlJRzVoZG1sbllYUnZjaTUxYzJWeVFXZGxiblF1ZEc5TWIzZGxja05oYzJVb0tUdGNibHh1SUNBZ0lHbG1JQ2h1WVhZdWFXNWtaWGhQWmlnbmJYTnBaU2NwSUNFOVBTQXRNU2tnZTF4dUlDQWdJQ0FnZG1GeUlIWmxjbk5wYjI0Z1BTQndZWEp6WlVsdWRDaHVZWFl1YzNCc2FYUW9KMjF6YVdVbktWc3hYU2s3WEc1Y2JpQWdJQ0FnSUdsbUlDaDJaWEp6YVc5dUlEdzlJRGdwSUh0Y2JpQWdJQ0FnSUNBZ1pHVjBaV04wWldSSlJTQTlJSFJ5ZFdVN1hHNGdJQ0FnSUNCOVhHNGdJQ0FnZlZ4dUlDQjlYRzVjYmlBZ2NtVjBkWEp1SUdSbGRHVmpkR1ZrU1VVN1hHNTlPMXh1WEc1S1VYVmxjbmxJZEhSd1EyeHBaVzUwTG5CeWIzUnZkSGx3WlM1bGVHVmpkWFJsSUQwZ1puVnVZM1JwYjI0Z0tHOWlhaWtnZTF4dUlDQjJZWElnYW5FZ1BTQjBhR2x6TG1wUmRXVnllU0I4ZkNBb2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ0ozVnVaR1ZtYVc1bFpDY2dKaVlnZDJsdVpHOTNMbXBSZFdWeWVTazdYRzRnSUhaaGNpQmpZaUE5SUc5aWFpNXZianRjYmlBZ2RtRnlJSEpsY1hWbGMzUWdQU0J2WW1vN1hHNWNiaUFnYVdZb2RIbHdaVzltSUdweElEMDlQU0FuZFc1a1pXWnBibVZrSnlCOGZDQnFjU0E5UFQwZ1ptRnNjMlVwSUh0Y2JpQWdJQ0IwYUhKdmR5QnVaWGNnUlhKeWIzSW9KMVZ1YzNWd2NHOXlkR1ZrSUdOdmJtWnBaM1Z5WVhScGIyNGhJRXBSZFdWeWVTQnBjeUJ5WlhGMWFYSmxaQ0JpZFhRZ2JtOTBJR0YyWVdsc1lXSnNaU2NwTzF4dUlDQjlYRzVjYmlBZ2IySnFMblI1Y0dVZ1BTQnZZbW91YldWMGFHOWtPMXh1SUNCdlltb3VZMkZqYUdVZ1BTQnZZbW91YW5GMVpYSjVRV3BoZUVOaFkyaGxPMXh1SUNCdlltb3VaR0YwWVNBOUlHOWlhaTVpYjJSNU8xeHVJQ0JrWld4bGRHVWdiMkpxTG1weGRXVnllVUZxWVhoRFlXTm9aVHRjYmlBZ1pHVnNaWFJsSUc5aWFpNTFjMlZLVVhWbGNuazdYRzRnSUdSbGJHVjBaU0J2WW1vdVltOWtlVHRjYmx4dUlDQnZZbW91WTI5dGNHeGxkR1VnUFNCbWRXNWpkR2x2YmlBb2NtVnpjRzl1YzJVcElIdGNiaUFnSUNCMllYSWdhR1ZoWkdWeWN5QTlJSHQ5TzF4dUlDQWdJSFpoY2lCb1pXRmtaWEpCY25KaGVTQTlJSEpsYzNCdmJuTmxMbWRsZEVGc2JGSmxjM0J2Ym5ObFNHVmhaR1Z5Y3lncExuTndiR2wwS0NkY1hHNG5LVHRjYmx4dUlDQWdJR1p2Y2lBb2RtRnlJR2tnUFNBd095QnBJRHdnYUdWaFpHVnlRWEp5WVhrdWJHVnVaM1JvT3lCcEt5c3BJSHRjYmlBZ0lDQWdJSFpoY2lCMGIxTndiR2wwSUQwZ2FHVmhaR1Z5UVhKeVlYbGJhVjB1ZEhKcGJTZ3BPMXh1WEc0Z0lDQWdJQ0JwWmlBb2RHOVRjR3hwZEM1c1pXNW5kR2dnUFQwOUlEQXBJSHRjYmlBZ0lDQWdJQ0FnWTI5dWRHbHVkV1U3WEc0Z0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUhaaGNpQnpaWEJoY21GMGIzSWdQU0IwYjFOd2JHbDBMbWx1WkdWNFQyWW9Kem9uS1R0Y2JseHVJQ0FnSUNBZ2FXWWdLSE5sY0dGeVlYUnZjaUE5UFQwZ0xURXBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z1RtRnRaU0JpZFhRZ2JtOGdkbUZzZFdVZ2FXNGdkR2hsSUdobFlXUmxjbHh1SUNBZ0lDQWdJQ0JvWldGa1pYSnpXM1J2VTNCc2FYUmRJRDBnYm5Wc2JEdGNibHh1SUNBZ0lDQWdJQ0JqYjI1MGFXNTFaVHRjYmlBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnZG1GeUlHNWhiV1VnUFNCMGIxTndiR2wwTG5OMVluTjBjbWx1Wnlnd0xDQnpaWEJoY21GMGIzSXBMblJ5YVcwb0tUdGNiaUFnSUNBZ0lIWmhjaUIyWVd4MVpTQTlJSFJ2VTNCc2FYUXVjM1ZpYzNSeWFXNW5LSE5sY0dGeVlYUnZjaUFySURFcExuUnlhVzBvS1R0Y2JseHVJQ0FnSUNBZ2FHVmhaR1Z5YzF0dVlXMWxYU0E5SUhaaGJIVmxPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIWmhjaUJ2ZFhRZ1BTQjdYRzRnSUNBZ0lDQjFjbXc2SUhKbGNYVmxjM1F1ZFhKc0xGeHVJQ0FnSUNBZ2JXVjBhRzlrT2lCeVpYRjFaWE4wTG0xbGRHaHZaQ3hjYmlBZ0lDQWdJSE4wWVhSMWN6b2djbVZ6Y0c5dWMyVXVjM1JoZEhWekxGeHVJQ0FnSUNBZ2MzUmhkSFZ6VkdWNGREb2djbVZ6Y0c5dWMyVXVjM1JoZEhWelZHVjRkQ3hjYmlBZ0lDQWdJR1JoZEdFNklISmxjM0J2Ym5ObExuSmxjM0J2Ym5ObFZHVjRkQ3hjYmlBZ0lDQWdJR2hsWVdSbGNuTTZJR2hsWVdSbGNuTmNiaUFnSUNCOU8xeHVYRzRnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJSFpoY2lCd2IzTnphV0pzWlU5aWFpQTlJQ0J5WlhOd2IyNXpaUzV5WlhOd2IyNXpaVXBUVDA0Z2ZId2dhbk41WVcxc0xuTmhabVZNYjJGa0tISmxjM0J2Ym5ObExuSmxjM0J2Ym5ObFZHVjRkQ2s3WEc0Z0lDQWdJQ0J2ZFhRdWIySnFJRDBnS0hSNWNHVnZaaUJ3YjNOemFXSnNaVTlpYWlBOVBUMGdKM04wY21sdVp5Y3BJRDhnZTMwZ09pQndiM056YVdKc1pVOWlhanRjYmlBZ0lDQjlJR05oZEdOb0lDaGxlQ2tnZTF4dUlDQWdJQ0FnTHk4Z1pHOGdibTkwSUhObGRDQnZkWFF1YjJKcVhHNGdJQ0FnSUNCb1pXeHdaWEp6TG14dlp5Z25kVzVoWW14bElIUnZJSEJoY25ObElFcFRUMDR2V1VGTlRDQmpiMjUwWlc1MEp5azdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ0x5OGdTU0JqWVc0Z2RHaHliM2NzSUc5eUlIQmhjbk5sSUc1MWJHdy9YRzRnSUNBZ2IzVjBMbTlpYWlBOUlHOTFkQzV2WW1vZ2ZId2diblZzYkR0Y2JseHVJQ0FnSUdsbUlDaHlaWE53YjI1elpTNXpkR0YwZFhNZ1BqMGdNakF3SUNZbUlISmxjM0J2Ym5ObExuTjBZWFIxY3lBOElETXdNQ2tnZTF4dUlDQWdJQ0FnWTJJdWNtVnpjRzl1YzJVb2IzVjBLVHRjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSEpsYzNCdmJuTmxMbk4wWVhSMWN5QTlQVDBnTUNCOGZDQW9jbVZ6Y0c5dWMyVXVjM1JoZEhWeklENDlJRFF3TUNBbUppQnlaWE53YjI1elpTNXpkR0YwZFhNZ1BDQTFPVGtwS1NCN1hHNGdJQ0FnSUNCallpNWxjbkp2Y2lodmRYUXBPMXh1SUNBZ0lIMGdaV3h6WlNCN1hHNGdJQ0FnSUNCeVpYUjFjbTRnWTJJdWNtVnpjRzl1YzJVb2IzVjBLVHRjYmlBZ0lDQjlYRzRnSUgwN1hHNWNiaUFnYW5FdWMzVndjRzl5ZEM1amIzSnpJRDBnZEhKMVpUdGNibHh1SUNCeVpYUjFjbTRnYW5FdVlXcGhlQ2h2WW1vcE8xeHVmVHRjYmx4dVUzVndaWEpoWjJWdWRFaDBkSEJEYkdsbGJuUXVjSEp2ZEc5MGVYQmxMbVY0WldOMWRHVWdQU0JtZFc1amRHbHZiaUFvYjJKcUtTQjdYRzRnSUhaaGNpQnRaWFJvYjJRZ1BTQnZZbW91YldWMGFHOWtMblJ2VEc5M1pYSkRZWE5sS0NrN1hHNGdJSFpoY2lCMGFXMWxiM1YwSUQwZ2IySnFMblJwYldWdmRYUTdYRzVjYmlBZ2FXWWdLRzFsZEdodlpDQTlQVDBnSjJSbGJHVjBaU2NwSUh0Y2JpQWdJQ0J0WlhSb2IyUWdQU0FuWkdWc0p6dGNiaUFnZlZ4dUlDQjJZWElnYUdWaFpHVnljeUE5SUc5aWFpNW9aV0ZrWlhKeklIeDhJSHQ5TzF4dVhHNGdJSFpoY2lCeUlEMGdjbVZ4ZFdWemRGdHRaWFJvYjJSZEtHOWlhaTUxY213cE8xeHVYRzRnSUdsbUlDaHZZbW91WTI5dWJtVmpkR2x2YmtGblpXNTBLU0I3WEc0Z0lDQWdjaTVoWjJWdWRDaHZZbW91WTI5dWJtVmpkR2x2YmtGblpXNTBLVHRjYmlBZ2ZWeHVYRzRnSUdsbUlDaDBhVzFsYjNWMEtTQjdYRzRnSUNBZ2NpNTBhVzFsYjNWMEtIUnBiV1Z2ZFhRcE8xeHVJQ0I5WEc1Y2JpQWdhV1lnS0c5aWFpNWxibUZpYkdWRGIyOXJhV1Z6S1NCN1hHNGdJQ0FnY2k1M2FYUm9RM0psWkdWdWRHbGhiSE1vS1R0Y2JpQWdmVnh1WEc0Z0lIWmhjaUJoWTJObGNIUWdQU0J2WW1vdWFHVmhaR1Z5Y3k1QlkyTmxjSFE3WEc1Y2JpQWdhV1lvZEdocGN5NWlhVzVoY25sU1pYRjFaWE4wS0dGalkyVndkQ2twSUh0Y2JpQWdJQ0J5TG05dUtDZHlaWEYxWlhOMEp5d2dablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnYVdZb2RHaHBjeTU0YUhJcElIdGNiaUFnSUNBZ0lDQWdkR2hwY3k1NGFISXVjbVZ6Y0c5dWMyVlVlWEJsSUQwZ0oySnNiMkluTzF4dUlDQWdJQ0FnZlZ4dUlDQWdJSDBwTzF4dUlDQjlYRzVjYmlBZ2FXWW9iMkpxTG1KdlpIa3BJSHRjYmlBZ0lDQnBaaWhmTG1selQySnFaV04wS0c5aWFpNWliMlI1S1NrZ2UxeHVJQ0FnSUNBZ2RtRnlJR052Ym5SbGJuUlVlWEJsSUQwZ2IySnFMbWhsWVdSbGNuTmJKME52Ym5SbGJuUXRWSGx3WlNkZElIeDhJQ2NuTzF4dUlDQWdJQ0FnYVdZZ0tHTnZiblJsYm5SVWVYQmxMbWx1WkdWNFQyWW9KMjExYkhScGNHRnlkQzltYjNKdExXUmhkR0VuS1NBOVBUMGdNQ2tnZTF4dUlDQWdJQ0FnSUNCa1pXeGxkR1VnYUdWaFpHVnljMXNuUTI5dWRHVnVkQzFVZVhCbEoxMDdYRzRnSUNBZ0lDQWdJR2xtS0h0OUxuUnZVM1J5YVc1bkxtRndjR3g1S0c5aWFpNWliMlI1S1NBOVBUMGdKMXR2WW1wbFkzUWdSbTl5YlVSaGRHRmRKeWtnZTF4dUlDQWdJQ0FnSUNBZ0lISXVjMlZ1WkNodlltb3VZbTlrZVNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lDQWdkbUZ5SUd0bGVXNWhiV1VzSUhaaGJIVmxMQ0IyTzF4dUlDQWdJQ0FnSUNBZ0lHWnZjaUFvYTJWNWJtRnRaU0JwYmlCdlltb3VZbTlrZVNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnZG1Gc2RXVWdQU0J2WW1vdVltOWtlVnRyWlhsdVlXMWxYVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHbG1LRUZ5Y21GNUxtbHpRWEp5WVhrb2RtRnNkV1VwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUdadmNpaDJJR2x1SUhaaGJIVmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY2k1bWFXVnNaQ2hyWlhsdVlXMWxMQ0IyS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJSEl1Wm1sbGJHUW9hMlY1Ym1GdFpTd2dkbUZzZFdVcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdaV3h6WlNCcFppQW9YeTVwYzA5aWFtVmpkQ2h2WW1vdVltOWtlU2twSUh0Y2JpQWdJQ0FnSUNBZ0x5OGdibTl1SUcxMWJIUnBjR0Z5ZEM5bWIzSnRMV1JoZEdGY2JpQWdJQ0FnSUNBZ2IySnFMbUp2WkhrZ1BTQktVMDlPTG5OMGNtbHVaMmxtZVNodlltb3VZbTlrZVNrN1hHNGdJQ0FnSUNBZ0lISXVjMlZ1WkNodlltb3VZbTlrZVNrN1hHNGdJQ0FnSUNCOVhHNGdJQ0FnZlZ4dUlDQWdJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ2NpNXpaVzVrS0c5aWFpNWliMlI1S1R0Y2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNCMllYSWdibUZ0WlR0Y2JpQWdabTl5SUNodVlXMWxJR2x1SUdobFlXUmxjbk1wSUh0Y2JpQWdJQ0J5TG5ObGRDaHVZVzFsTENCb1pXRmtaWEp6VzI1aGJXVmRLVHRjYmlBZ2ZWeHVYRzRnSUdsbUtIUjVjR1Z2WmlCeUxtSjFabVpsY2lBOVBUMGdKMloxYm1OMGFXOXVKeWtnZTF4dUlDQWdJSEl1WW5WbVptVnlLQ2s3SUM4dklHWnZjbU5sSUhOMWNHVnlZV2RsYm5RZ2RHOGdjRzl3ZFd4aGRHVWdjbVZ6TG5SbGVIUWdkMmwwYUNCMGFHVWdjbUYzSUhKbGMzQnZibk5sSUdSaGRHRmNiaUFnZlZ4dVhHNGdJSEl1Wlc1a0tHWjFibU4wYVc5dUlDaGxjbklzSUhKbGN5a2dlMXh1SUNBZ0lISmxjeUE5SUhKbGN5QjhmQ0I3WEc0Z0lDQWdJQ0J6ZEdGMGRYTTZJREFzWEc0Z0lDQWdJQ0JvWldGa1pYSnpPaUI3WlhKeWIzSTZJQ2R1YnlCeVpYTndiMjV6WlNCbWNtOXRJSE5sY25abGNpZDlYRzRnSUNBZ2ZUdGNiaUFnSUNCMllYSWdjbVZ6Y0c5dWMyVWdQU0I3WEc0Z0lDQWdJQ0IxY213NklHOWlhaTUxY213c1hHNGdJQ0FnSUNCdFpYUm9iMlE2SUc5aWFpNXRaWFJvYjJRc1hHNGdJQ0FnSUNCb1pXRmtaWEp6T2lCeVpYTXVhR1ZoWkdWeWMxeHVJQ0FnSUgwN1hHNGdJQ0FnZG1GeUlHTmlPMXh1WEc0Z0lDQWdhV1lnS0NGbGNuSWdKaVlnY21WekxtVnljbTl5S1NCN1hHNGdJQ0FnSUNCbGNuSWdQU0J5WlhNdVpYSnliM0k3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdhV1lnS0dWeWNpQW1KaUJ2WW1vdWIyNGdKaVlnYjJKcUxtOXVMbVZ5Y205eUtTQjdYRzRnSUNBZ0lDQnlaWE53YjI1elpTNWxjbkpQWW1vZ1BTQmxjbkk3WEc0Z0lDQWdJQ0J5WlhOd2IyNXpaUzV6ZEdGMGRYTWdQU0J5WlhNZ1B5QnlaWE11YzNSaGRIVnpJRG9nTlRBd08xeHVJQ0FnSUNBZ2NtVnpjRzl1YzJVdWMzUmhkSFZ6VkdWNGRDQTlJSEpsY3lBL0lISmxjeTUwWlhoMElEb2daWEp5TG0xbGMzTmhaMlU3WEc0Z0lDQWdJQ0JwWmlBb2NtVnpMbWhsWVdSbGNuTWdKaVlnY21WekxtaGxZV1JsY25OYkoyTnZiblJsYm5RdGRIbHdaU2RkS1NCN1hHNGdJQ0FnSUNBZ0lHbG1JQ2h5WlhNdWFHVmhaR1Z5YzFzblkyOXVkR1Z1ZEMxMGVYQmxKMTB1YVc1a1pYaFBaaWduWVhCd2JHbGpZWFJwYjI0dmFuTnZiaWNwSUQ0OUlEQXBJSHRjYmlBZ0lDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVnpjRzl1YzJVdWIySnFJRDBnU2xOUFRpNXdZWEp6WlNoeVpYTndiMjV6WlM1emRHRjBkWE5VWlhoMEtUdGNiaUFnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ1kyRjBZMmdnS0dVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGMzQnZibk5sTG05aWFpQTlJRzUxYkd3N1hHNGdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdJQ0JqWWlBOUlHOWlhaTV2Ymk1bGNuSnZjanRjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSEpsY3lBbUppQnZZbW91YjI0Z0ppWWdiMkpxTG05dUxuSmxjM0J2Ym5ObEtTQjdYRzRnSUNBZ0lDQjJZWElnY0c5emMybGliR1ZQWW1vN1hHNWNiaUFnSUNBZ0lDOHZJRUZzY21WaFpIa2djR0Z5YzJWa0lHSjVJR0o1SUhOMWNHVnlZV2RsYm5RL1hHNGdJQ0FnSUNCcFppQW9jbVZ6TG1KdlpIa2dKaVlnWHk1clpYbHpLSEpsY3k1aWIyUjVLUzVzWlc1bmRHZ2dQaUF3S1NCN1hHNGdJQ0FnSUNBZ0lIQnZjM05wWW14bFQySnFJRDBnY21WekxtSnZaSGs3WEc0Z0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJSEJ2YzNOcFlteGxUMkpxSUQwZ2FuTjVZVzFzTG5OaFptVk1iMkZrS0hKbGN5NTBaWGgwS1R0Y2JpQWdJQ0FnSUNBZ0lDQXZMeUJqWVc0Z2NHRnljMlVnYVc1MGJ5QmhJSE4wY21sdVp5NHVMaUIzYUdsamFDQjNaU0JrYjI0bmRDQnVaV1ZrSUhKMWJtNXBibWNnWVhKdmRXNWtJR2x1SUhSb1pTQnplWE4wWlcxY2JpQWdJQ0FnSUNBZ0lDQndiM056YVdKc1pVOWlhaUE5SUNoMGVYQmxiMllnY0c5emMybGliR1ZQWW1vZ1BUMDlJQ2R6ZEhKcGJtY25LU0EvSUc1MWJHd2dPaUJ3YjNOemFXSnNaVTlpYWp0Y2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pTa2dlMXh1SUNBZ0lDQWdJQ0FnSUdobGJIQmxjbk11Ykc5bktDZGpZVzV1YjNRZ2NHRnljMlVnU2xOUFRpOVpRVTFNSUdOdmJuUmxiblFuS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ0lDQXZMeUJ1ZFd4c0lHMWxZVzV6SUhkbElHTmhiaWQwSUhCaGNuTmxJR2x1ZEc4Z2IySnFaV04wWEc0Z0lDQWdJQ0JwWmloMGVYQmxiMllnUW5WbVptVnlJRDA5UFNBblpuVnVZM1JwYjI0bklDWW1JRUoxWm1abGNpNXBjMEoxWm1abGNpaHdiM056YVdKc1pVOWlhaWtwSUh0Y2JpQWdJQ0FnSUNBZ2NtVnpjRzl1YzJVdVpHRjBZU0E5SUhCdmMzTnBZbXhsVDJKcU8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUhKbGMzQnZibk5sTG05aWFpQTlJQ2gwZVhCbGIyWWdjRzl6YzJsaWJHVlBZbW9nUFQwOUlDZHZZbXBsWTNRbktTQS9JSEJ2YzNOcFlteGxUMkpxSURvZ2JuVnNiRHRjYmlBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnY21WemNHOXVjMlV1YzNSaGRIVnpJRDBnY21WekxuTjBZWFIxY3p0Y2JpQWdJQ0FnSUhKbGMzQnZibk5sTG5OMFlYUjFjMVJsZUhRZ1BTQnlaWE11ZEdWNGREdGNiaUFnSUNBZ0lHTmlJRDBnYjJKcUxtOXVMbkpsYzNCdmJuTmxPMXh1SUNBZ0lIMWNiaUFnSUNCcFppQW9jbVZ6TG5ob2NpQW1KaUJ5WlhNdWVHaHlMbkpsYzNCdmJuTmxLU0I3WEc0Z0lDQWdJQ0J5WlhOd2IyNXpaUzVrWVhSaElEMGdjbVZ6TG5ob2NpNXlaWE53YjI1elpUdGNiaUFnSUNCOVhHNGdJQ0FnWld4elpTQnBaaWdoY21WemNHOXVjMlV1WkdGMFlTa2dlMXh1SUNBZ0lDQWdjbVZ6Y0c5dWMyVXVaR0YwWVNBOUlISmxjM0J2Ym5ObExuTjBZWFIxYzFSbGVIUTdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2FXWWdLR05pS1NCN1hHNGdJQ0FnSUNCallpaHlaWE53YjI1elpTazdYRzRnSUNBZ2ZWeHVJQ0I5S1R0Y2JuMDdYRzVjYmxOMWNHVnlZV2RsYm5SSWRIUndRMnhwWlc1MExuQnliM1J2ZEhsd1pTNGdZbWx1WVhKNVVtVnhkV1Z6ZENBOUlHWjFibU4wYVc5dUlDaGhZMk5sY0hRcElIdGNiaUFnYVdZb0lXRmpZMlZ3ZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUJtWVd4elpUdGNiaUFnZlZ4dUlDQnlaWFIxY200Z0tDOWVhVzFoWjJVdmFTa3VkR1Z6ZENoaFkyTmxjSFFwWEc0Z0lDQWdmSHdnS0M5ZVlYQndiR2xqWVhScGIyNWNYQzl3WkdZdktTNTBaWE4wS0dGalkyVndkQ2xjYmlBZ0lDQjhmQ0FvTDE1aGNIQnNhV05oZEdsdmJseGNMMjlqZEdWMExYTjBjbVZoYlM4cExuUmxjM1FvWVdOalpYQjBLVHRjYm4wN1hHNGlYWDA9IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgU3dhZ2dlckh0dHAgPSByZXF1aXJlKCcuL2h0dHAnKTtcbnZhciBfID0ge1xuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGNsb25lRGVlcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2Nsb25lRGVlcCcpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpLFxuICBpc1N0cmluZzogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzU3RyaW5nJylcbn07XG5cblxuLyoqXG4gKiBSZXNvbHZlcyBhIHNwZWMncyByZW1vdGUgcmVmZXJlbmNlc1xuICovXG52YXIgUmVzb2x2ZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5mYWlsZWRVcmxzID0gW107XG4gIHRoaXMucmVzb2x2ZXJDYWNoZSA9IHt9O1xuICB0aGlzLnBlbmRpbmdVcmxzID0ge307XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucHJvY2Vzc0FsbE9mID0gZnVuY3Rpb24ocm9vdCwgbmFtZSwgZGVmaW5pdGlvbiwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYykge1xuICB2YXIgaSwgbG9jYXRpb24sIHByb3BlcnR5O1xuXG4gIGRlZmluaXRpb25bJ3gtcmVzb2x2ZWQtZnJvbSddID0gWyAnIy9kZWZpbml0aW9ucy8nICsgbmFtZSBdO1xuICB2YXIgYWxsT2YgPSBkZWZpbml0aW9uLmFsbE9mO1xuICAvLyB0aGUgcmVmcyBnbyBmaXJzdFxuICBhbGxPZi5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICBpZihhLiRyZWYgJiYgYi4kcmVmKSB7IHJldHVybiAwOyB9XG4gICAgZWxzZSBpZihhLiRyZWYpIHsgcmV0dXJuIC0xOyB9XG4gICAgZWxzZSB7IHJldHVybiAxOyB9XG4gIH0pO1xuICBmb3IgKGkgPSAwOyBpIDwgYWxsT2YubGVuZ3RoOyBpKyspIHtcbiAgICBwcm9wZXJ0eSA9IGFsbE9mW2ldO1xuICAgIGxvY2F0aW9uID0gJy9kZWZpbml0aW9ucy8nICsgbmFtZSArICcvYWxsT2YnO1xuICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgbG9jYXRpb24pO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZSA9IGZ1bmN0aW9uIChzcGVjLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gIHRoaXMuc3BlYyA9IHNwZWM7XG4gIHZhciByb290ID0gYXJnMSwgY2FsbGJhY2sgPSBhcmcyLCBzY29wZSA9IGFyZzMsIG9wdHMgPSB7fSwgbG9jYXRpb24sIGk7XG4gIGlmKHR5cGVvZiBhcmcxID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcm9vdCA9IG51bGw7XG4gICAgY2FsbGJhY2sgPSBhcmcxO1xuICAgIHNjb3BlID0gYXJnMjtcbiAgfVxuICB2YXIgX3Jvb3QgPSByb290LCBtb2RlbE5hbWU7XG4gIHRoaXMuc2NvcGUgPSAoc2NvcGUgfHwgdGhpcyk7XG4gIHRoaXMuaXRlcmF0aW9uID0gdGhpcy5pdGVyYXRpb24gfHwgMDtcblxuICBpZih0aGlzLnNjb3BlLm9wdGlvbnMgJiYgdGhpcy5zY29wZS5vcHRpb25zLnJlcXVlc3RJbnRlcmNlcHRvcil7XG4gICAgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgPSB0aGlzLnNjb3BlLm9wdGlvbnMucmVxdWVzdEludGVyY2VwdG9yO1xuICB9XG5cbiAgaWYodGhpcy5zY29wZS5vcHRpb25zICYmIHRoaXMuc2NvcGUub3B0aW9ucy5yZXNwb25zZUludGVyY2VwdG9yKXtcbiAgICBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IgPSB0aGlzLnNjb3BlLm9wdGlvbnMucmVzcG9uc2VJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIHZhciBuYW1lLCBwYXRoLCBwcm9wZXJ0eSwgcHJvcGVydHlOYW1lLCBwYXJhbWV0ZXIsIGRvbmUsIGNvdW50ZXI7XG4gIHZhciBwcm9jZXNzZWRDYWxscyA9IDAsIHJlc29sdmVkUmVmcyA9IHt9LCB1bnJlc29sdmVkUmVmcyA9IHt9O1xuICB2YXIgcmVzb2x1dGlvblRhYmxlID0gW107IC8vIHN0b3JlIG9iamVjdHMgZm9yIGRlcmVmZXJlbmNpbmdcblxuICBzcGVjLmRlZmluaXRpb25zID0gc3BlYy5kZWZpbml0aW9ucyB8fCB7fTtcbiAgLy8gZGVmaW5pdGlvbnNcbiAgZm9yIChuYW1lIGluIHNwZWMuZGVmaW5pdGlvbnMpIHtcbiAgICB2YXIgZGVmaW5pdGlvbiA9IHNwZWMuZGVmaW5pdGlvbnNbbmFtZV07XG4gICAgaWYoZGVmaW5pdGlvbi4kcmVmKSB7XG4gICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgZGVmaW5pdGlvbiwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgZGVmaW5pdGlvbik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgZm9yIChwcm9wZXJ0eU5hbWUgaW4gZGVmaW5pdGlvbi5wcm9wZXJ0aWVzKSB7XG4gICAgICAgIHByb3BlcnR5ID0gZGVmaW5pdGlvbi5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV07XG4gICAgICAgIGlmIChfLmlzQXJyYXkocHJvcGVydHkuYWxsT2YpKSB7XG4gICAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgcHJvcGVydHksIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHNwZWMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsICcvZGVmaW5pdGlvbnMnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZGVmaW5pdGlvbi5hbGxPZikge1xuICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBkZWZpbml0aW9uLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBzaGFyZWQgcGFyYW1ldGVyc1xuICBzcGVjLnBhcmFtZXRlcnMgPSBzcGVjLnBhcmFtZXRlcnMgfHwge307XG4gIGZvcihuYW1lIGluIHNwZWMucGFyYW1ldGVycykge1xuICAgIHBhcmFtZXRlciA9IHNwZWMucGFyYW1ldGVyc1tuYW1lXTtcbiAgICBpZiAocGFyYW1ldGVyLmluID09PSAnYm9keScgJiYgcGFyYW1ldGVyLnNjaGVtYSkge1xuICAgICAgaWYoXy5pc0FycmF5KHBhcmFtZXRlci5zY2hlbWEuYWxsT2YpKSB7XG4gICAgICAgIC8vIG1vdmUgdG8gYSBkZWZpbml0aW9uXG4gICAgICAgIG1vZGVsTmFtZSA9ICdpbmxpbmVfbW9kZWwnO1xuICAgICAgICB2YXIgX25hbWUgPSBtb2RlbE5hbWU7XG4gICAgICAgIGRvbmUgPSBmYWxzZTsgY291bnRlciA9IDA7XG4gICAgICAgIHdoaWxlKCFkb25lKSB7XG4gICAgICAgICAgaWYodHlwZW9mIHNwZWMuZGVmaW5pdGlvbnNbX25hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgX25hbWUgPSBtb2RlbE5hbWUgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICAgIGNvdW50ZXIgKys7XG4gICAgICAgIH1cbiAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tfbmFtZV0gPSB7IGFsbE9mOiBwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mIH07XG4gICAgICAgIGRlbGV0ZSBwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mO1xuICAgICAgICBwYXJhbWV0ZXIuc2NoZW1hLiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgX25hbWU7XG4gICAgICAgIHRoaXMucHJvY2Vzc0FsbE9mKHJvb3QsIF9uYW1lLCBzcGVjLmRlZmluaXRpb25zW19uYW1lXSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcGFyYW1ldGVyLnNjaGVtYSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtZXRlci4kcmVmKSB7XG4gICAgICAvLyBwYXJhbWV0ZXIgcmVmZXJlbmNlXG4gICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcGFyYW1ldGVyLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBwYXJhbWV0ZXIuJHJlZik7XG4gICAgfVxuICB9XG5cbiAgLy8gb3BlcmF0aW9uc1xuICBmb3IgKG5hbWUgaW4gc3BlYy5wYXRocykge1xuICAgIHZhciBtZXRob2QsIG9wZXJhdGlvbiwgcmVzcG9uc2VDb2RlO1xuICAgIHBhdGggPSBzcGVjLnBhdGhzW25hbWVdO1xuXG4gICAgaWYodHlwZW9mIHBhdGggPT09ICdvYmplY3QnKSB7XG4gICAgICBmb3IgKG1ldGhvZCBpbiBwYXRoKSB7XG4gICAgICAgIC8vIG9wZXJhdGlvbiByZWZlcmVuY2VcbiAgICAgICAgaWYgKG1ldGhvZCA9PT0gJyRyZWYnKSB7XG4gICAgICAgICAgLy8gbG9jYXRpb24gPSBwYXRoW21ldGhvZF07XG4gICAgICAgICAgbG9jYXRpb24gPSAnL3BhdGhzJyArIG5hbWU7XG4gICAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHBhdGgsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGxvY2F0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBvcGVyYXRpb24gPSBwYXRoW21ldGhvZF07XG4gICAgICAgICAgdmFyIHNoYXJlZFBhcmFtZXRlcnMgPSBwYXRoLnBhcmFtZXRlcnMgfHwgW107XG4gICAgICAgICAgdmFyIHBhcmFtZXRlcnMgPSBvcGVyYXRpb24ucGFyYW1ldGVycyB8fCBbXTtcblxuICAgICAgICAgIHNoYXJlZFBhcmFtZXRlcnMuZm9yRWFjaChmdW5jdGlvbihwYXJhbWV0ZXIpIHtcbiAgICAgICAgICAgIHBhcmFtZXRlcnMudW5zaGlmdChwYXJhbWV0ZXIpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKG1ldGhvZCAhPT0gJ3BhcmFtZXRlcnMnICYmIF8uaXNPYmplY3Qob3BlcmF0aW9uKSkge1xuICAgICAgICAgICAgb3BlcmF0aW9uLnBhcmFtZXRlcnMgPSBvcGVyYXRpb24ucGFyYW1ldGVycyB8fCBwYXJhbWV0ZXJzO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvciAoaSBpbiBwYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgICBwYXJhbWV0ZXIgPSBwYXJhbWV0ZXJzW2ldO1xuICAgICAgICAgICAgbG9jYXRpb24gPSAnL3BhdGhzJyArIG5hbWUgKyAnLycgKyBtZXRob2QgKyAnL3BhcmFtZXRlcnMnO1xuXG4gICAgICAgICAgICBpZiAocGFyYW1ldGVyLmluID09PSAnYm9keScgJiYgcGFyYW1ldGVyLnNjaGVtYSkge1xuICAgICAgICAgICAgICBpZiAoXy5pc0FycmF5KHBhcmFtZXRlci5zY2hlbWEuYWxsT2YpKSB7XG4gICAgICAgICAgICAgICAgLy8gbW92ZSB0byBhIGRlZmluaXRpb25cbiAgICAgICAgICAgICAgICBtb2RlbE5hbWUgPSAnaW5saW5lX21vZGVsJztcbiAgICAgICAgICAgICAgICBuYW1lID0gbW9kZWxOYW1lO1xuICAgICAgICAgICAgICAgIGRvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjb3VudGVyID0gMDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHtcbiAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgbmFtZSA9IG1vZGVsTmFtZSArICdfJyArIGNvdW50ZXI7XG4gICAgICAgICAgICAgICAgICBjb3VudGVyKys7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPSB7YWxsT2Y6IHBhcmFtZXRlci5zY2hlbWEuYWxsT2Z9O1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mO1xuICAgICAgICAgICAgICAgIHBhcmFtZXRlci5zY2hlbWEuJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyBuYW1lO1xuICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0FsbE9mKHJvb3QsIG5hbWUsIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHNwZWMpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHBhcmFtZXRlci5zY2hlbWEsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwYXJhbWV0ZXIuJHJlZikge1xuICAgICAgICAgICAgICAvLyBwYXJhbWV0ZXIgcmVmZXJlbmNlXG4gICAgICAgICAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwYXJhbWV0ZXIsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHBhcmFtZXRlci4kcmVmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKHJlc3BvbnNlQ29kZSBpbiBvcGVyYXRpb24ucmVzcG9uc2VzKSB7XG4gICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSBvcGVyYXRpb24ucmVzcG9uc2VzW3Jlc3BvbnNlQ29kZV07XG4gICAgICAgICAgICBsb2NhdGlvbiA9ICcvcGF0aHMnICsgbmFtZSArICcvJyArIG1ldGhvZCArICcvcmVzcG9uc2VzLycgKyByZXNwb25zZUNvZGU7XG5cbiAgICAgICAgICAgIGlmIChfLmlzT2JqZWN0KHJlc3BvbnNlKSkge1xuICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuJHJlZikge1xuICAgICAgICAgICAgICAgIC8vIHJlc3BvbnNlIHJlZmVyZW5jZVxuICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCByZXNwb25zZSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgbG9jYXRpb24pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChyZXNwb25zZS5zY2hlbWEpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVzcG9uc2VPYmogPSByZXNwb25zZTtcbiAgICAgICAgICAgICAgICBpZiAoXy5pc0FycmF5KHJlc3BvbnNlT2JqLnNjaGVtYS5hbGxPZikpIHtcbiAgICAgICAgICAgICAgICAgIC8vIG1vdmUgdG8gYSBkZWZpbml0aW9uXG4gICAgICAgICAgICAgICAgICBtb2RlbE5hbWUgPSAnaW5saW5lX21vZGVsJztcbiAgICAgICAgICAgICAgICAgIG5hbWUgPSBtb2RlbE5hbWU7XG4gICAgICAgICAgICAgICAgICBkb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICBjb3VudGVyID0gMDtcbiAgICAgICAgICAgICAgICAgIHdoaWxlICghZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IG1vZGVsTmFtZSArICdfJyArIGNvdW50ZXI7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPSB7YWxsT2Y6IHJlc3BvbnNlT2JqLnNjaGVtYS5hbGxPZn07XG4gICAgICAgICAgICAgICAgICBkZWxldGUgcmVzcG9uc2VPYmouc2NoZW1hLmFsbE9mO1xuICAgICAgICAgICAgICAgICAgZGVsZXRlIHJlc3BvbnNlT2JqLnNjaGVtYS50eXBlO1xuICAgICAgICAgICAgICAgICAgcmVzcG9uc2VPYmouc2NoZW1hLiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgbmFtZTtcbiAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0FsbE9mKHJvb3QsIG5hbWUsIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHNwZWMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICgnYXJyYXknID09PSByZXNwb25zZU9iai5zY2hlbWEudHlwZSkge1xuICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlT2JqLnNjaGVtYS5pdGVtcyAmJiByZXNwb25zZU9iai5zY2hlbWEuaXRlbXMuJHJlZikge1xuICAgICAgICAgICAgICAgICAgICAvLyByZXNwb25zZSByZWZlcmVuY2VcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHJlc3BvbnNlT2JqLnNjaGVtYS5pdGVtcywgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgbG9jYXRpb24pO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHJlc3BvbnNlLnNjaGVtYSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBjbGVhciB0aGVtIG91dCB0byBhdm9pZCBtdWx0aXBsZSByZXNvbHV0aW9uc1xuICAgICAgcGF0aC5wYXJhbWV0ZXJzID0gW107XG4gICAgfVxuICB9XG5cbiAgdmFyIGV4cGVjdGVkQ2FsbHMgPSAwLCB0b1Jlc29sdmUgPSBbXTtcbiAgLy8gaWYgdGhlIHJvb3QgaXMgc2FtZSBhcyBvYmpbaV0ucm9vdCB3ZSBjYW4gcmVzb2x2ZSBsb2NhbGx5XG4gIHZhciBhbGwgPSByZXNvbHV0aW9uVGFibGU7XG5cbiAgdmFyIHBhcnRzO1xuICBmb3IoaSA9IDA7IGkgPCBhbGwubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYSA9IGFsbFtpXTtcbiAgICBpZihyb290ID09PSBhLnJvb3QpIHtcbiAgICAgIGlmKGEucmVzb2x2ZUFzID09PSAncmVmJykge1xuICAgICAgICAvLyByZXNvbHZlIGFueSBwYXRoIHdhbGtpbmdcbiAgICAgICAgdmFyIGpvaW5lZCA9ICgoYS5yb290IHx8ICcnKSArICcvJyArIGEua2V5KS5zcGxpdCgnLycpO1xuICAgICAgICB2YXIgbm9ybWFsaXplZCA9IFtdO1xuICAgICAgICB2YXIgdXJsID0gJyc7XG4gICAgICAgIHZhciBrO1xuXG4gICAgICAgIGlmKGEua2V5LmluZGV4T2YoJy4uLycpID49IDApIHtcbiAgICAgICAgICBmb3IodmFyIGogPSAwOyBqIDwgam9pbmVkLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBpZihqb2luZWRbal0gPT09ICcuLicpIHtcbiAgICAgICAgICAgICAgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZWQuc2xpY2UoMCwgbm9ybWFsaXplZC5sZW5ndGgtMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgbm9ybWFsaXplZC5wdXNoKGpvaW5lZFtqXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGZvcihrID0gMDsgayA8IG5vcm1hbGl6ZWQubGVuZ3RoOyBrICsrKSB7XG4gICAgICAgICAgICBpZihrID4gMCkge1xuICAgICAgICAgICAgICB1cmwgKz0gJy8nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXJsICs9IG5vcm1hbGl6ZWRba107XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHdlIG5vdyBoYXZlIHRvIHJlbW90ZSByZXNvbHZlIHRoaXMgYmVjYXVzZSB0aGUgcGF0aCBoYXMgY2hhbmdlZFxuICAgICAgICAgIGEucm9vdCA9IHVybDtcbiAgICAgICAgICB0b1Jlc29sdmUucHVzaChhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBwYXJ0cyA9IGEua2V5LnNwbGl0KCcjJyk7XG4gICAgICAgICAgaWYocGFydHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBpZihwYXJ0c1swXS5pbmRleE9mKCdodHRwOicpID09PSAwIHx8IHBhcnRzWzBdLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgICAgICAgICAgIGEucm9vdCA9IHBhcnRzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24gPSBwYXJ0c1sxXS5zcGxpdCgnLycpO1xuICAgICAgICAgICAgdmFyIHI7XG4gICAgICAgICAgICB2YXIgcyA9IHNwZWM7XG4gICAgICAgICAgICBmb3IoayA9IDA7IGsgPCBsb2NhdGlvbi5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgICB2YXIgcGFydCA9IGxvY2F0aW9uW2tdO1xuICAgICAgICAgICAgICBpZihwYXJ0ICE9PSAnJykge1xuICAgICAgICAgICAgICAgIHMgPSBzW3BhcnRdO1xuICAgICAgICAgICAgICAgIGlmKHR5cGVvZiBzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgciA9IHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgciA9IG51bGw7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmKHIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gbXVzdCByZXNvbHZlIHRoaXMgdG9vXG4gICAgICAgICAgICAgIHRvUmVzb2x2ZS5wdXNoKGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGlmIChhLnJlc29sdmVBcyA9PT0gJ2lubGluZScpIHtcbiAgICAgICAgICBpZihhLmtleSAmJiBhLmtleS5pbmRleE9mKCcjJykgPT09IC0xICYmIGEua2V5LmNoYXJBdCgwKSAhPT0gJy8nKSB7XG4gICAgICAgICAgICAvLyBoYW5kbGUgcmVsYXRpdmUgc2NoZW1hXG4gICAgICAgICAgICBwYXJ0cyA9IGEucm9vdC5zcGxpdCgnLycpO1xuICAgICAgICAgICAgbG9jYXRpb24gPSAnJztcbiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IHBhcnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgICAgICBsb2NhdGlvbiArPSBwYXJ0c1tpXSArICcvJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvY2F0aW9uICs9IGEua2V5O1xuICAgICAgICAgICAgYS5yb290ID0gbG9jYXRpb247XG4gICAgICAgICAgICBhLmxvY2F0aW9uID0gJyc7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRvUmVzb2x2ZS5wdXNoKGEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgfVxuICB9XG4gIGV4cGVjdGVkQ2FsbHMgPSB0b1Jlc29sdmUubGVuZ3RoO1xuXG4gIC8vIHJlc29sdmUgYW55dGhpbmcgdGhhdCBpcyBsb2NhbFxuXG4gIHZhciBsb2NrID0ge307XG4gIGZvcih2YXIgaWkgPSAwOyBpaSA8IHRvUmVzb2x2ZS5sZW5ndGg7IGlpKyspIHtcbiAgICAoZnVuY3Rpb24oaXRlbSwgc3BlYywgc2VsZiwgbG9jaywgaWkpIHtcbiAgICAgIGlmKCFpdGVtLnJvb3QgfHwgaXRlbS5yb290ID09PSByb290KSB7XG4gICAgICAgIC8vIGxvY2FsIHJlc29sdmVcbiAgICAgICAgc2VsZi5yZXNvbHZlSXRlbShzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBpdGVtKTtcbiAgICAgICAgcHJvY2Vzc2VkQ2FsbHMgKz0gMTtcblxuICAgICAgICBpZihwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIHJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2ssIHRydWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIGlmKHNlbGYuZmFpbGVkVXJscy5pbmRleE9mKGl0ZW0ucm9vdCkgPT09IC0xKSB7XG4gICAgICAgIHZhciBvYmogPSB7XG4gICAgICAgICAgdXNlSlF1ZXJ5OiBmYWxzZSwgIC8vIFRPRE9cbiAgICAgICAgICB1cmw6IGl0ZW0ucm9vdCxcbiAgICAgICAgICBtZXRob2Q6ICdnZXQnLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgIGFjY2VwdDogc2VsZi5zY29wZS5zd2FnZ2VyUmVxdWVzdEhlYWRlcnMgfHwgJ2FwcGxpY2F0aW9uL2pzb24nXG4gICAgICAgICAgfSxcbiAgICAgICAgICBvbjoge1xuICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZygnZmFpbGVkIHVybDogJyArIG9iai51cmwpO1xuICAgICAgICAgICAgICBzZWxmLmZhaWxlZFVybHMucHVzaChvYmoudXJsKTtcbiAgICAgICAgICAgICAgaWYgKGxvY2spIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgbG9ja1tpdGVtLnJvb3RdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHVucmVzb2x2ZWRSZWZzW2l0ZW0ua2V5XSA9IHtcbiAgICAgICAgICAgICAgICByb290OiBpdGVtLnJvb3QsXG4gICAgICAgICAgICAgICAgbG9jYXRpb246IGl0ZW0ubG9jYXRpb25cbiAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICBpZiAocHJvY2Vzc2VkQ2FsbHMgPT09IGV4cGVjdGVkQ2FsbHMpIHtcbiAgICAgICAgICAgICAgICBzZWxmLmZpbmlzaChzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICAgICAgICAgIHJlc3BvbnNlOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgdmFyIHN3YWdnZXIgPSByZXNwb25zZS5vYmo7XG4gICAgICAgICAgICAgIGlmIChsb2NrKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGxvY2tbaXRlbS5yb290XTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoc2VsZi5yZXNvbHZlckNhY2hlKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5yZXNvbHZlckNhY2hlW2l0ZW0ucm9vdF0gPSBzd2FnZ2VyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHNlbGYucmVzb2x2ZUl0ZW0oc3dhZ2dlciwgaXRlbS5yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGl0ZW0pO1xuICAgICAgICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuXG4gICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gYXBwbHkgdGltZW91dCBvbmx5IHdoZW4gc3BlY2lmaWVkXG4gICAgICAgIGlmIChzY29wZSAmJiBzY29wZS5mZXRjaFNwZWNUaW1lb3V0KSB7XG4gICAgICAgICAgb2JqLnRpbWVvdXQgPSBzY29wZS5mZXRjaFNwZWNUaW1lb3V0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjb3BlICYmIHNjb3BlLmNsaWVudEF1dGhvcml6YXRpb25zKSB7XG4gICAgICAgICAgc2NvcGUuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkob2JqKTtcbiAgICAgICAgfVxuXG4gICAgICAgIChmdW5jdGlvbiB3YWl0Rm9yVW5sb2NrKCkge1xuICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBpZiAobG9ja1tvYmoudXJsXSkge1xuICAgICAgICAgICAgICB3YWl0Rm9yVW5sb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgdmFyIGNhY2hlZCA9IHNlbGYucmVzb2x2ZXJDYWNoZVtvYmoudXJsXTtcbiAgICAgICAgICAgICAgaWYgKF8uaXNPYmplY3QoY2FjaGVkKSkge1xuICAgICAgICAgICAgICAgIG9iai5vbi5yZXNwb25zZSh7b2JqOiBjYWNoZWR9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2NrW29iai51cmxdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBuZXcgU3dhZ2dlckh0dHAoKS5leGVjdXRlKG9iaiwgb3B0cyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfSkoKTtcbiAgICAgIH1cblxuICAgICAgZWxzZSB7XG4gICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG4gICAgICAgIHVucmVzb2x2ZWRSZWZzW2l0ZW0ua2V5XSA9IHtcbiAgICAgICAgICByb290OiBpdGVtLnJvb3QsXG4gICAgICAgICAgbG9jYXRpb246IGl0ZW0ubG9jYXRpb25cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSh0b1Jlc29sdmVbaWldLCBzcGVjLCB0aGlzLCBsb2NrLCBpaSkpO1xuICB9XG5cbiAgaWYgKE9iamVjdC5rZXlzKHRvUmVzb2x2ZSkubGVuZ3RoID09PSAwKSB7XG4gICAgdGhpcy5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZUl0ZW0gPSBmdW5jdGlvbihzcGVjLCByb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGl0ZW0pIHtcbiAgdmFyIHBhdGggPSBpdGVtLmxvY2F0aW9uO1xuICB2YXIgbG9jYXRpb24gPSBzcGVjLCBwYXJ0cyA9IHBhdGguc3BsaXQoJy8nKTtcbiAgaWYocGF0aCAhPT0gJycpIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHBhcnRzLmxlbmd0aDsgaisrKSB7XG4gICAgICB2YXIgc2VnbWVudCA9IHBhcnRzW2pdO1xuICAgICAgaWYgKHNlZ21lbnQuaW5kZXhPZignfjEnKSAhPT0gLTEpIHtcbiAgICAgICAgc2VnbWVudCA9IHBhcnRzW2pdLnJlcGxhY2UoL34wL2csICd+JykucmVwbGFjZSgvfjEvZywgJy8nKTtcbiAgICAgICAgaWYgKHNlZ21lbnQuY2hhckF0KDApICE9PSAnLycpIHtcbiAgICAgICAgICBzZWdtZW50ID0gJy8nICsgc2VnbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBsb2NhdGlvbiA9PT0gJ3VuZGVmaW5lZCcgfHwgbG9jYXRpb24gPT09IG51bGwpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoc2VnbWVudCA9PT0gJycgJiYgaiA9PT0gKHBhcnRzLmxlbmd0aCAtIDEpICYmIHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgbG9jYXRpb24gPSBudWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzZWdtZW50Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgbG9jYXRpb24gPSBsb2NhdGlvbltzZWdtZW50XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIHJlc29sdmVkID0gaXRlbS5rZXk7XG4gIHBhcnRzID0gaXRlbS5rZXkuc3BsaXQoJy8nKTtcbiAgdmFyIHJlc29sdmVkTmFtZSA9IHBhcnRzW3BhcnRzLmxlbmd0aC0xXTtcblxuICBpZihyZXNvbHZlZE5hbWUuaW5kZXhPZignIycpID49IDApIHtcbiAgICByZXNvbHZlZE5hbWUgPSByZXNvbHZlZE5hbWUuc3BsaXQoJyMnKVsxXTtcbiAgfVxuXG4gIGlmIChsb2NhdGlvbiAhPT0gbnVsbCAmJiB0eXBlb2YgbG9jYXRpb24gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmVzb2x2ZWRSZWZzW3Jlc29sdmVkXSA9IHtcbiAgICAgIG5hbWU6IHJlc29sdmVkTmFtZSxcbiAgICAgIG9iajogbG9jYXRpb24sXG4gICAgICBrZXk6IGl0ZW0ua2V5LFxuICAgICAgcm9vdDogaXRlbS5yb290XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB1bnJlc29sdmVkUmVmc1tyZXNvbHZlZF0gPSB7XG4gICAgICByb290OiBpdGVtLnJvb3QsXG4gICAgICBsb2NhdGlvbjogaXRlbS5sb2NhdGlvblxuICAgIH07XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbiAoc3BlYywgcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjaywgbG9jYWxSZXNvbHZlKSB7XG4gIC8vIHdhbGsgcmVzb2x1dGlvbiB0YWJsZSBhbmQgcmVwbGFjZSB3aXRoIHJlc29sdmVkIHJlZnNcbiAgdmFyIHJlZiwgYWJzO1xuICBmb3IgKHJlZiBpbiByZXNvbHV0aW9uVGFibGUpIHtcbiAgICB2YXIgaXRlbSA9IHJlc29sdXRpb25UYWJsZVtyZWZdO1xuXG4gICAgdmFyIGtleSA9IGl0ZW0ua2V5O1xuICAgIHZhciByZXNvbHZlZFRvID0gcmVzb2x2ZWRSZWZzW2tleV07XG4gICAgaWYgKHJlc29sdmVkVG8pIHtcbiAgICAgIHNwZWMuZGVmaW5pdGlvbnMgPSBzcGVjLmRlZmluaXRpb25zIHx8IHt9O1xuICAgICAgaWYgKGl0ZW0ucmVzb2x2ZUFzID09PSAncmVmJykge1xuICAgICAgICBpZiAobG9jYWxSZXNvbHZlICE9PSB0cnVlKSB7XG4gICAgICAgICAgLy8gZG9uJ3QgcmV0YWluIHJvb3QgZm9yIGxvY2FsIGRlZmluaXRpb25zXG4gICAgICAgICAgZm9yIChrZXkgaW4gcmVzb2x2ZWRUby5vYmopIHtcbiAgICAgICAgICAgIGFicyA9IHRoaXMucmV0YWluUm9vdChrZXksIHJlc29sdmVkVG8ub2JqW2tleV0sIGl0ZW0ucm9vdCk7XG4gICAgICAgICAgICByZXNvbHZlZFRvLm9ialtrZXldID0gYWJzO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzcGVjLmRlZmluaXRpb25zW3Jlc29sdmVkVG8ubmFtZV0gPSByZXNvbHZlZFRvLm9iajtcbiAgICAgICAgaXRlbS5vYmouJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyByZXNvbHZlZFRvLm5hbWU7XG4gICAgICB9IGVsc2UgaWYgKGl0ZW0ucmVzb2x2ZUFzID09PSAnaW5saW5lJykge1xuICAgICAgICB2YXIgdGFyZ2V0T2JqID0gaXRlbS5vYmo7XG4gICAgICAgIHRhcmdldE9ialsneC1yZXNvbHZlZC1mcm9tJ10gPSBbIGl0ZW0ua2V5IF07XG4gICAgICAgIGRlbGV0ZSB0YXJnZXRPYmouJHJlZjtcblxuICAgICAgICBmb3IgKGtleSBpbiByZXNvbHZlZFRvLm9iaikge1xuICAgICAgICAgIGFicyA9IHJlc29sdmVkVG8ub2JqW2tleV07XG5cbiAgICAgICAgICBpZiAobG9jYWxSZXNvbHZlICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAvLyBkb24ndCByZXRhaW4gcm9vdCBmb3IgbG9jYWwgZGVmaW5pdGlvbnNcbiAgICAgICAgICAgIGFicyA9IHRoaXMucmV0YWluUm9vdChrZXksIHJlc29sdmVkVG8ub2JqW2tleV0sIGl0ZW0ucm9vdCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRhcmdldE9ialtrZXldID0gYWJzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHZhciBleGlzdGluZ1VucmVzb2x2ZWQgPSB0aGlzLmNvdW50VW5yZXNvbHZlZFJlZnMoc3BlYyk7XG5cbiAgaWYoZXhpc3RpbmdVbnJlc29sdmVkID09PSAwIHx8IHRoaXMuaXRlcmF0aW9uID4gNSkge1xuICAgIHRoaXMucmVzb2x2ZUFsbE9mKHNwZWMuZGVmaW5pdGlvbnMpO1xuICAgIHRoaXMucmVzb2x2ZXJDYWNoZSA9IG51bGw7XG4gICAgY2FsbGJhY2suY2FsbCh0aGlzLnNjb3BlLCBzcGVjLCB1bnJlc29sdmVkUmVmcyk7XG4gIH1cbiAgZWxzZSB7XG4gICAgdGhpcy5pdGVyYXRpb24gKz0gMTtcbiAgICB0aGlzLnJlc29sdmUoc3BlYywgcm9vdCwgY2FsbGJhY2ssIHRoaXMuc2NvcGUpO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUuY291bnRVbnJlc29sdmVkUmVmcyA9IGZ1bmN0aW9uKHNwZWMpIHtcbiAgdmFyIGk7XG4gIHZhciByZWZzID0gdGhpcy5nZXRSZWZzKHNwZWMpO1xuICB2YXIga2V5cyA9IFtdO1xuICB2YXIgdW5yZXNvbHZlZEtleXMgPSBbXTtcbiAgZm9yKGkgaW4gcmVmcykge1xuICAgIGlmKGkuaW5kZXhPZignIycpID09PSAwKSB7XG4gICAgICBrZXlzLnB1c2goaS5zdWJzdHJpbmcoMSkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHVucmVzb2x2ZWRLZXlzLnB1c2goaSk7XG4gICAgfVxuICB9XG5cbiAgLy8gdmVyaWZ5IHBvc3NpYmxlIGtleXNcbiAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFydCA9IGtleXNbaV07XG4gICAgdmFyIHBhcnRzID0gcGFydC5zcGxpdCgnLycpO1xuICAgIHZhciBvYmogPSBzcGVjO1xuXG4gICAgZm9yICh2YXIgayA9IDA7IGsgPCBwYXJ0cy5sZW5ndGg7IGsrKykge1xuICAgICAgdmFyIGtleSA9IHBhcnRzW2tdO1xuICAgICAgaWYoa2V5ICE9PSAnJykge1xuICAgICAgICBvYmogPSBvYmpba2V5XTtcbiAgICAgICAgaWYodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB1bnJlc29sdmVkS2V5cy5wdXNoKHBhcnQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB1bnJlc29sdmVkS2V5cy5sZW5ndGg7XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUuZ2V0UmVmcyA9IGZ1bmN0aW9uKHNwZWMsIG9iaikge1xuICBvYmogPSBvYmogfHwgc3BlYztcbiAgdmFyIG91dHB1dCA9IHt9O1xuICBmb3IodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoIW9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIGl0ZW0gPSBvYmpba2V5XTtcbiAgICBpZihrZXkgPT09ICckcmVmJyAmJiB0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG91dHB1dFtpdGVtXSA9IG51bGw7XG4gICAgfVxuICAgIGVsc2UgaWYoXy5pc09iamVjdChpdGVtKSkge1xuICAgICAgdmFyIG8gPSB0aGlzLmdldFJlZnMoaXRlbSk7XG4gICAgICBmb3IodmFyIGsgaW4gbykge1xuICAgICAgICBvdXRwdXRba10gPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gb3V0cHV0O1xufTtcblxuZnVuY3Rpb24gc3BsaXRVcmwodXJsKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcbiAgdmFyIHByb3RvID0gL1thLXpdKzpcXC9cXC8vaS5leGVjKHVybCk7XG4gIGlmIChwcm90bykge1xuICAgIHJlc3VsdC5wcm90byA9IHByb3RvWzBdLnNsaWNlKDAsIC0zKTtcbiAgICB1cmwgPSB1cmwuc2xpY2UocmVzdWx0LnByb3RvLmxlbmd0aCArIDEpO1xuICB9XG4gIGlmICh1cmwuc2xpY2UoMCwgMikgPT09ICcvLycpIHtcbiAgICByZXN1bHQuZG9tYWluID0gdXJsLnNsaWNlKDIpLnNwbGl0KCcvJylbMF07XG4gICAgdXJsID0gdXJsLnNsaWNlKDIgKyByZXN1bHQuZG9tYWluLmxlbmd0aCk7XG4gIH1cbiAgdmFyIHAgPSB1cmwuc3BsaXQoJyMnKTtcbiAgaWYgKHBbMF0ubGVuZ3RoKSB7XG4gICAgcmVzdWx0LnBhdGggPSBwWzBdO1xuICB9XG4gIGlmIChwLmxlbmd0aCA+IDEpIHtcbiAgICByZXN1bHQuZnJhZ21lbnQgPSBwLnNsaWNlKDEpLmpvaW4oJyMnKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiB1bnNwbGl0VXJsKHVybCkge1xuICB2YXIgcmVzdWx0ID0gdXJsLnBhdGg7XG4gIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgIHJlc3VsdCA9ICcnO1xuICB9XG4gIGlmICh1cmwuZnJhZ21lbnQgIT09IHVuZGVmaW5lZCkge1xuICAgIHJlc3VsdCArPSAnIycgKyB1cmwuZnJhZ21lbnQ7XG4gIH1cbiAgaWYgKHVybC5kb21haW4gIT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChyZXN1bHQuc2xpY2UoMCwgMSkgPT09ICcvJykge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0LnNsaWNlKDEpO1xuICAgIH1cbiAgICByZXN1bHQgPSAnLy8nICsgdXJsLmRvbWFpbiArICcvJyArIHJlc3VsdDtcbiAgICBpZiAodXJsLnByb3RvICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJlc3VsdCA9IHVybC5wcm90byArICc6JyArIHJlc3VsdDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gam9pblVybChiYXNlLCByZWwpIHtcbiAgdmFyIHJlbHNwID0gc3BsaXRVcmwocmVsKTtcbiAgaWYgKHJlbHNwLmRvbWFpbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHJlbDtcbiAgfVxuICB2YXIgcmVzdWx0ID0gc3BsaXRVcmwoYmFzZSk7XG4gIGlmIChyZWxzcC5wYXRoID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBjaGFuZ2Ugb25seSBmcmFnbWVudCBwYXJ0XG4gICAgcmVzdWx0LmZyYWdtZW50ID0gcmVsc3AuZnJhZ21lbnQ7XG4gIH0gZWxzZSBpZiAocmVsc3AucGF0aC5zbGljZSgwLCAxKSA9PT0gJy8nKSB7XG4gICAgLy8gcmVsYXRpdmUgdG8gZG9tYWluXG4gICAgcmVzdWx0LnBhdGggPSByZWxzcC5wYXRoO1xuICAgIHJlc3VsdC5mcmFnbWVudCA9IHJlbHNwLmZyYWdtZW50O1xuICB9IGVsc2Uge1xuICAgIC8vIHJlbGF0aXZlIHRvIHBhdGhcbiAgICB2YXIgcGF0aCA9IHJlc3VsdC5wYXRoID09PSB1bmRlZmluZWQgPyBbXSA6IHJlc3VsdC5wYXRoLnNwbGl0KCcvJyk7XG4gICAgdmFyIHJlbHBhdGggPSByZWxzcC5wYXRoLnNwbGl0KCcvJyk7XG4gICAgaWYgKHBhdGgubGVuZ3RoKSB7XG4gICAgICBwYXRoLnBvcCgpO1xuICAgIH1cbiAgICB3aGlsZSAocmVscGF0aFswXSA9PT0gJy4uJyB8fCByZWxwYXRoWzBdID09PSAnLicpIHtcbiAgICAgIGlmIChyZWxwYXRoWzBdID09PSAnLi4nKSB7XG4gICAgICAgIHBhdGgucG9wKCk7XG4gICAgICB9XG4gICAgICByZWxwYXRoLnNoaWZ0KCk7XG4gICAgfVxuICAgIHJlc3VsdC5wYXRoID0gcGF0aC5jb25jYXQocmVscGF0aCkuam9pbignLycpO1xuICAgIHJlc3VsdC5mcmFnbWVudCA9IHJlbHNwLmZyYWdtZW50O1xuICB9XG4gIHJldHVybiB1bnNwbGl0VXJsKHJlc3VsdCk7XG59XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXRhaW5Sb290ID0gZnVuY3Rpb24ob3JpZ0tleSwgb2JqLCByb290KSB7XG4gIC8vIHdhbGsgb2JqZWN0IGFuZCBsb29rIGZvciByZWxhdGl2ZSAkcmVmc1xuICBpZihfLmlzT2JqZWN0KG9iaikpIHtcbiAgICBmb3IodmFyIGtleSBpbiBvYmopIHtcbiAgICAgIHZhciBpdGVtID0gb2JqW2tleV07XG4gICAgICBpZiAoa2V5ID09PSAnJHJlZicgJiYgdHlwZW9mIGl0ZW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG9ialtrZXldID0gam9pblVybChyb290LCBpdGVtKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKF8uaXNPYmplY3QoaXRlbSkpIHtcbiAgICAgICAgdGhpcy5yZXRhaW5Sb290KGtleSwgaXRlbSwgcm9vdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2UgaWYoXy5pc1N0cmluZyhvYmopICYmIG9yaWdLZXkgPT09ICckcmVmJykge1xuICAgIG9iaiA9IGpvaW5Vcmwocm9vdCwgb2JqKTtcbiAgfVxuICByZXR1cm4gb2JqO1xufTtcblxuLyoqXG4gKiBpbW1lZGlhdGVseSBpbi1saW5lcyBsb2NhbCByZWZzLCBxdWV1ZXMgcmVtb3RlIHJlZnNcbiAqIGZvciBpbmxpbmUgcmVzb2x1dGlvblxuICovXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZUlubGluZSA9IGZ1bmN0aW9uIChyb290LCBzcGVjLCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgbG9jYXRpb24pIHtcbiAgdmFyIGtleSA9IHByb3BlcnR5LiRyZWYsIHJlZiA9IHByb3BlcnR5LiRyZWYsIGksIHAsIHAyLCBycztcbiAgdmFyIHJvb3RUcmltbWVkID0gZmFsc2U7XG5cbiAgcm9vdCA9IHJvb3QgfHwgJyc7IC8vIEd1YXJkIGFnYWluc3QgLnNwbGl0LiBAZmVoZ3V5LCB5b3UnbGwgbmVlZCB0byBjaGVjayBpZiB0aGlzIGxvZ2ljIGZpdHNcbiAgLy8gTW9yZSBpbXBvcmFudGx5IGlzIGhvdyBkbyB3ZSBncmFjZWZ1bGx5IGhhbmRsZSByZWxhdGl2ZSB1cmxzLCB3aGVuIHByb3ZpZGVkIGp1c3QgYSAnc3BlYycsIG5vdCBhICd1cmwnID9cblxuICBpZiAocmVmKSB7XG4gICAgaWYocmVmLmluZGV4T2YoJy4uLycpID09PSAwKSB7XG4gICAgICAvLyByZXNldCByb290XG4gICAgICBwID0gcmVmLnNwbGl0KCcuLi8nKTtcbiAgICAgIHAyID0gcm9vdC5zcGxpdCgnLycpO1xuICAgICAgcmVmID0gJyc7XG4gICAgICBmb3IoaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmKHBbaV0gPT09ICcnKSB7XG4gICAgICAgICAgcDIgPSBwMi5zbGljZSgwLCBwMi5sZW5ndGgtMSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgcmVmICs9IHBbaV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJvb3QgPSAnJztcbiAgICAgIGZvcihpID0gMDsgaSA8IHAyLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBpZihpID4gMCkgeyByb290ICs9ICcvJzsgfVxuICAgICAgICByb290ICs9IHAyW2ldO1xuICAgICAgfVxuICAgICAgcm9vdFRyaW1tZWQgPSB0cnVlO1xuICAgIH1cbiAgICBpZihyZWYuaW5kZXhPZignIycpID49IDApIHtcbiAgICAgIGlmKHJlZi5pbmRleE9mKCcvJykgPT09IDApIHtcbiAgICAgICAgcnMgPSByZWYuc3BsaXQoJyMnKTtcbiAgICAgICAgcCAgPSByb290LnNwbGl0KCcvLycpO1xuICAgICAgICBwMiA9IHBbMV0uc3BsaXQoJy8nKTtcbiAgICAgICAgcm9vdCA9IHBbMF0gKyAnLy8nICsgcDJbMF0gKyByc1swXTtcbiAgICAgICAgbG9jYXRpb24gPSByc1sxXTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBycyA9IHJlZi5zcGxpdCgnIycpO1xuICAgICAgICBpZihyc1swXSAhPT0gJycpIHtcbiAgICAgICAgICBwMiA9IHJvb3Quc3BsaXQoJy8nKTtcbiAgICAgICAgICBwMiA9IHAyLnNsaWNlKDAsIHAyLmxlbmd0aCAtIDEpO1xuICAgICAgICAgIGlmKCFyb290VHJpbW1lZCkge1xuICAgICAgICAgICAgcm9vdCA9ICcnO1xuICAgICAgICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCBwMi5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgICBpZihrID4gMCkgeyByb290ICs9ICcvJzsgfVxuICAgICAgICAgICAgICByb290ICs9IHAyW2tdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByb290ICs9ICcvJyArIHJlZi5zcGxpdCgnIycpWzBdO1xuICAgICAgICB9XG4gICAgICAgIGxvY2F0aW9uID0gcnNbMV07XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChyZWYuaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCByZWYuaW5kZXhPZignaHR0cHM6JykgPT09IDApIHtcbiAgICAgIGlmKHJlZi5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgICAgICByb290ID0gcmVmLnNwbGl0KCcjJylbMF07XG4gICAgICAgIGxvY2F0aW9uID0gcmVmLnNwbGl0KCcjJylbMV07XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcm9vdCA9IHJlZjtcbiAgICAgICAgbG9jYXRpb24gPSAnJztcbiAgICAgIH1cbiAgICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdpbmxpbmUnLCByb290OiByb290LCBrZXk6IGtleSwgbG9jYXRpb246IGxvY2F0aW9ufSk7XG4gICAgfSBlbHNlIGlmIChyZWYuaW5kZXhPZignIycpID09PSAwKSB7XG4gICAgICBsb2NhdGlvbiA9IHJlZi5zcGxpdCgnIycpWzFdO1xuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9IGVsc2UgaWYgKHJlZi5pbmRleE9mKCcvJykgPT09IDAgJiYgcmVmLmluZGV4T2YoJyMnKSA9PT0gLTEpIHtcbiAgICAgIGxvY2F0aW9uID0gcmVmO1xuICAgICAgdmFyIG1hdGNoZXMgPSByb290Lm1hdGNoKC9eaHR0cHM/XFw6XFwvXFwvKFteXFwvPyNdKykoPzpbXFwvPyNdfCQpL2kpO1xuICAgICAgaWYobWF0Y2hlcykge1xuICAgICAgICByb290ID0gbWF0Y2hlc1swXSArIHJlZi5zdWJzdHJpbmcoMSk7XG4gICAgICAgIGxvY2F0aW9uID0gJyc7XG4gICAgICB9XG4gICAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7b2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAnaW5saW5lJywgcm9vdDogcm9vdCwga2V5OiBrZXksIGxvY2F0aW9uOiBsb2NhdGlvbn0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdpbmxpbmUnLCByb290OiByb290LCBrZXk6IGtleSwgbG9jYXRpb246IGxvY2F0aW9ufSk7XG4gICAgfVxuICB9XG4gIGVsc2UgaWYgKHByb3BlcnR5LnR5cGUgPT09ICdhcnJheScpIHtcbiAgICB0aGlzLnJlc29sdmVUbyhyb290LCBwcm9wZXJ0eS5pdGVtcywgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlVG8gPSBmdW5jdGlvbiAocm9vdCwgcHJvcGVydHksIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pIHtcbiAgdmFyIHNwLCBpO1xuICB2YXIgcmVmID0gcHJvcGVydHkuJHJlZjtcbiAgdmFyIGxyb290ID0gcm9vdDtcbiAgaWYgKCh0eXBlb2YgcmVmICE9PSAndW5kZWZpbmVkJykgJiYgKHJlZiAhPT0gbnVsbCkpIHtcbiAgICBpZihyZWYuaW5kZXhPZignIycpID49IDApIHtcbiAgICAgIHZhciBwYXJ0cyA9IHJlZi5zcGxpdCgnIycpO1xuXG4gICAgICAvLyAjL2RlZmluaXRpb25zL2Zvb1xuICAgICAgLy8gZm9vLmpzb24jL2JhclxuICAgICAgaWYocGFydHNbMF0gJiYgcmVmLmluZGV4T2YoJy8nKSA9PT0gMCkge1xuXG4gICAgICB9XG4gICAgICBlbHNlIGlmKHBhcnRzWzBdICYmIChwYXJ0c1swXS5pbmRleE9mKCdodHRwOicpID09PSAwIHx8IHBhcnRzWzBdLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSkge1xuICAgICAgICBscm9vdCA9IHBhcnRzWzBdO1xuICAgICAgICByZWYgPSBwYXJ0c1sxXTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYocGFydHNbMF0gJiYgcGFydHNbMF0ubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyByZWxhdGl2ZSBmaWxlXG4gICAgICAgIHNwID0gcm9vdC5zcGxpdCgnLycpO1xuICAgICAgICBscm9vdCA9ICcnO1xuICAgICAgICBmb3IoaSA9IDA7IGkgPCBzcC5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgICBscm9vdCArPSBzcFtpXSArICcvJztcbiAgICAgICAgfVxuICAgICAgICBscm9vdCArPSBwYXJ0c1swXTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuXG4gICAgICB9XG5cbiAgICAgIGxvY2F0aW9uID0gcGFydHNbMV07XG4gICAgfVxuICAgIGVsc2UgaWYgKHJlZi5pbmRleE9mKCdodHRwOicpID09PSAwIHx8IHJlZi5pbmRleE9mKCdodHRwczonKSA9PT0gMCkge1xuICAgICAgbHJvb3QgPSByZWY7XG4gICAgICBsb2NhdGlvbiA9ICcnO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIC8vIHJlbGF0aXZlIGZpbGVcbiAgICAgIHNwID0gcm9vdC5zcGxpdCgnLycpO1xuICAgICAgbHJvb3QgPSAnJztcbiAgICAgIGZvcihpID0gMDsgaSA8IHNwLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBscm9vdCArPSBzcFtpXSArICcvJztcbiAgICAgIH1cbiAgICAgIGxyb290ICs9IHJlZjtcbiAgICAgIGxvY2F0aW9uID0gJyc7XG4gICAgfVxuICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtcbiAgICAgIG9iajogcHJvcGVydHksIHJlc29sdmVBczogJ3JlZicsIHJvb3Q6IGxyb290LCBrZXk6IHJlZiwgbG9jYXRpb246IGxvY2F0aW9uXG4gICAgfSk7XG4gIH0gZWxzZSBpZiAocHJvcGVydHkudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIHZhciBpdGVtcyA9IHByb3BlcnR5Lml0ZW1zO1xuICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIGl0ZW1zLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICBpZihwcm9wZXJ0eSAmJiAocHJvcGVydHkucHJvcGVydGllcyB8fCBwcm9wZXJ0eS5hZGRpdGlvbmFsUHJvcGVydGllcykpIHtcbiAgICAgIHZhciBuYW1lID0gdGhpcy51bmlxdWVOYW1lKCdpbmxpbmVfbW9kZWwnKTtcbiAgICAgIGlmIChwcm9wZXJ0eS50aXRsZSkge1xuICAgICAgICBuYW1lID0gdGhpcy51bmlxdWVOYW1lKHByb3BlcnR5LnRpdGxlKTtcbiAgICAgIH1cbiAgICAgIGRlbGV0ZSBwcm9wZXJ0eS50aXRsZTtcbiAgICAgIHRoaXMuc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcbiAgICAgIHByb3BlcnR5LiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgbmFtZTtcbiAgICAgIGRlbGV0ZSBwcm9wZXJ0eS50eXBlO1xuICAgICAgZGVsZXRlIHByb3BlcnR5LnByb3BlcnRpZXM7XG4gICAgfVxuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUudW5pcXVlTmFtZSA9IGZ1bmN0aW9uKGJhc2UpIHtcbiAgdmFyIG5hbWUgPSBiYXNlO1xuICB2YXIgY291bnQgPSAwO1xuICB3aGlsZSh0cnVlKSB7XG4gICAgaWYoIV8uaXNPYmplY3QodGhpcy5zcGVjLmRlZmluaXRpb25zW25hbWVdKSkge1xuICAgICAgcmV0dXJuIG5hbWU7XG4gICAgfVxuICAgIG5hbWUgPSBiYXNlICsgJ18nICsgY291bnQ7XG4gICAgY291bnQrKztcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnJlc29sdmVBbGxPZiA9IGZ1bmN0aW9uKHNwZWMsIG9iaiwgZGVwdGgpIHtcbiAgZGVwdGggPSBkZXB0aCB8fCAwO1xuICBvYmogPSBvYmogfHwgc3BlYztcbiAgdmFyIG5hbWU7XG4gIGZvcih2YXIga2V5IGluIG9iaikge1xuICAgIGlmICghb2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgaXRlbSA9IG9ialtrZXldO1xuICAgIGlmKGl0ZW0gPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1N3YWdnZXIgMi4wIGRvZXMgbm90IHN1cHBvcnQgbnVsbCB0eXBlcyAoJyArIG9iaiArICcpLiAgU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9zd2FnZ2VyLWFwaS9zd2FnZ2VyLXNwZWMvaXNzdWVzLzIyOS4nKTtcbiAgICB9XG4gICAgaWYodHlwZW9mIGl0ZW0gPT09ICdvYmplY3QnKSB7XG4gICAgICB0aGlzLnJlc29sdmVBbGxPZihzcGVjLCBpdGVtLCBkZXB0aCArIDEpO1xuICAgIH1cbiAgICBpZihpdGVtICYmIHR5cGVvZiBpdGVtLmFsbE9mICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIGFsbE9mID0gaXRlbS5hbGxPZjtcbiAgICAgIGlmKF8uaXNBcnJheShhbGxPZikpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IF8uY2xvbmVEZWVwKGl0ZW0pO1xuICAgICAgICBkZWxldGUgb3V0cHV0LmFsbE9mO1xuXG4gICAgICAgIG91dHB1dFsneC1jb21wb3NlZCddID0gdHJ1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiBpdGVtWyd4LXJlc29sdmVkLWZyb20nXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBvdXRwdXRbJ3gtcmVzb2x2ZWQtZnJvbSddID0gaXRlbVsneC1yZXNvbHZlZC1mcm9tJ107XG4gICAgICAgIH1cblxuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgYWxsT2YubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2YXIgY29tcG9uZW50ID0gYWxsT2ZbaV07XG4gICAgICAgICAgdmFyIHNvdXJjZSA9ICdzZWxmJztcbiAgICAgICAgICBpZih0eXBlb2YgY29tcG9uZW50Wyd4LXJlc29sdmVkLWZyb20nXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHNvdXJjZSA9IGNvbXBvbmVudFsneC1yZXNvbHZlZC1mcm9tJ11bMF07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yKHZhciBwYXJ0IGluIGNvbXBvbmVudCkge1xuICAgICAgICAgICAgaWYoIW91dHB1dC5oYXNPd25Qcm9wZXJ0eShwYXJ0KSkge1xuICAgICAgICAgICAgICBvdXRwdXRbcGFydF0gPSBfLmNsb25lRGVlcChjb21wb25lbnRbcGFydF0pO1xuICAgICAgICAgICAgICBpZihwYXJ0ID09PSAncHJvcGVydGllcycpIHtcbiAgICAgICAgICAgICAgICBmb3IobmFtZSBpbiBvdXRwdXRbcGFydF0pIHtcbiAgICAgICAgICAgICAgICAgIG91dHB1dFtwYXJ0XVtuYW1lXVsneC1yZXNvbHZlZC1mcm9tJ10gPSBzb3VyY2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgaWYocGFydCA9PT0gJ3Byb3BlcnRpZXMnKSB7XG4gICAgICAgICAgICAgICAgdmFyIHByb3BlcnRpZXMgPSBjb21wb25lbnRbcGFydF07XG4gICAgICAgICAgICAgICAgZm9yKG5hbWUgaW4gcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgICAgb3V0cHV0LnByb3BlcnRpZXNbbmFtZV0gPSBfLmNsb25lRGVlcChwcm9wZXJ0aWVzW25hbWVdKTtcbiAgICAgICAgICAgICAgICAgIHZhciByZXNvbHZlZEZyb20gPSBwcm9wZXJ0aWVzW25hbWVdWyd4LXJlc29sdmVkLWZyb20nXTtcbiAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzb2x2ZWRGcm9tID09PSAndW5kZWZpbmVkJyB8fCByZXNvbHZlZEZyb20gPT09ICdzZWxmJykge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlZEZyb20gPSBzb3VyY2U7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBvdXRwdXQucHJvcGVydGllc1tuYW1lXVsneC1yZXNvbHZlZC1mcm9tJ10gPSByZXNvbHZlZEZyb207XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2UgaWYocGFydCA9PT0gJ3JlcXVpcmVkJykge1xuICAgICAgICAgICAgICAgIC8vIG1lcmdlICYgZGVkdXAgdGhlIHJlcXVpcmVkIGFycmF5XG4gICAgICAgICAgICAgICAgdmFyIGEgPSBvdXRwdXQucmVxdWlyZWQuY29uY2F0KGNvbXBvbmVudFtwYXJ0XSk7XG4gICAgICAgICAgICAgICAgZm9yKHZhciBrID0gMDsgayA8IGEubGVuZ3RoOyArK2spIHtcbiAgICAgICAgICAgICAgICAgIGZvcih2YXIgaiA9IGsgKyAxOyBqIDwgYS5sZW5ndGg7ICsraikge1xuICAgICAgICAgICAgICAgICAgICBpZihhW2tdID09PSBhW2pdKSB7IGEuc3BsaWNlKGotLSwgMSk7IH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb3V0cHV0LnJlcXVpcmVkID0gYTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIGlmKHBhcnQgPT09ICd4LXJlc29sdmVkLWZyb20nKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0Wyd4LXJlc29sdmVkLWZyb20nXS5wdXNoKHNvdXJjZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogbmVlZCB0byBtZXJnZSB0aGlzIHByb3BlcnR5XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ3doYXQgdG8gZG8gd2l0aCAnICsgcGFydClcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBvYmpba2V5XSA9IG91dHB1dDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBIZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG5cbnZhciBfID0ge1xuICBpc1BsYWluT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdCcpLFxuICBpc1VuZGVmaW5lZDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzVW5kZWZpbmVkJyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5JyksXG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgaXNFbXB0eTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzRW1wdHknKSxcbiAgbWFwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vbWFwJyksXG4gIGluZGV4T2Y6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZicpLFxuICBjbG9uZURlZXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAnKSxcbiAga2V5czogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9vYmplY3Qva2V5cycpLFxuICBmb3JFYWNoOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZm9yRWFjaCcpXG59O1xuXG52YXIgb3B0aW9uSHRtbCA9IG1vZHVsZS5leHBvcnRzLm9wdGlvbkh0bWwgPSBmdW5jdGlvbiAgKGxhYmVsLCB2YWx1ZSkge1xuICByZXR1cm4gJzx0cj48dGQgY2xhc3M9XCJvcHRpb25OYW1lXCI+JyArIGxhYmVsICsgJzo8L3RkPjx0ZD4nICsgdmFsdWUgKyAnPC90ZD48L3RyPic7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy50eXBlRnJvbUpzb25TY2hlbWEgPSBmdW5jdGlvbiAodHlwZSwgZm9ybWF0KSB7XG4gIHZhciBzdHI7XG5cbiAgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQzMicpIHtcbiAgICBzdHIgPSAnaW50ZWdlcic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDY0Jykge1xuICAgIHN0ciA9ICdsb25nJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgdHlwZW9mIGZvcm1hdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgPSAnbG9uZyc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgZm9ybWF0ID09PSAnZGF0ZS10aW1lJykge1xuICAgIHN0ciA9ICdkYXRlLXRpbWUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIGZvcm1hdCA9PT0gJ2RhdGUnKSB7XG4gICAgc3RyID0gJ2RhdGUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2Zsb2F0Jykge1xuICAgIHN0ciA9ICdmbG9hdCc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZG91YmxlJykge1xuICAgIHN0ciA9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmIHR5cGVvZiBmb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyID0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgc3RyID0gJ2Jvb2xlYW4nO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgc3RyID0gJ3N0cmluZyc7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufTtcblxudmFyIGdldFN0cmluZ1NpZ25hdHVyZSA9IG1vZHVsZS5leHBvcnRzLmdldFN0cmluZ1NpZ25hdHVyZSA9IGZ1bmN0aW9uIChvYmosIGJhc2VDb21wb25lbnQpIHtcbiAgdmFyIHN0ciA9ICcnO1xuXG4gIGlmICh0eXBlb2Ygb2JqLiRyZWYgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9IEhlbHBlcnMuc2ltcGxlUmVmKG9iai4kcmVmKTtcbiAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqLnR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdvYmplY3QnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnYXJyYXknKSB7XG4gICAgaWYgKGJhc2VDb21wb25lbnQpIHtcbiAgICAgIHN0ciArPSBnZXRTdHJpbmdTaWduYXR1cmUoKG9iai5pdGVtcyB8fCBvYmouJHJlZiB8fCB7fSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJ0FycmF5Wyc7XG4gICAgICBzdHIgKz0gZ2V0U3RyaW5nU2lnbmF0dXJlKChvYmouaXRlbXMgfHwgb2JqLiRyZWYgfHwge30pKTtcbiAgICAgIHN0ciArPSAnXSc7XG4gICAgfVxuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnaW50ZWdlcicgJiYgb2JqLmZvcm1hdCA9PT0gJ2ludDMyJykge1xuICAgIHN0ciArPSAnaW50ZWdlcic7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdpbnRlZ2VyJyAmJiBvYmouZm9ybWF0ID09PSAnaW50NjQnKSB7XG4gICAgc3RyICs9ICdsb25nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2ludGVnZXInICYmIHR5cGVvZiBvYmouZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSAnbG9uZyc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIG9iai5mb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgc3RyICs9ICdkYXRlLXRpbWUnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnc3RyaW5nJyAmJiBvYmouZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICBzdHIgKz0gJ2RhdGUnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnc3RyaW5nJyAmJiB0eXBlb2Ygb2JqLmZvcm1hdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gJ3N0cmluZyc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdudW1iZXInICYmIG9iai5mb3JtYXQgPT09ICdmbG9hdCcpIHtcbiAgICBzdHIgKz0gJ2Zsb2F0JztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgb2JqLmZvcm1hdCA9PT0gJ2RvdWJsZScpIHtcbiAgICBzdHIgKz0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdudW1iZXInICYmIHR5cGVvZiBvYmouZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgc3RyICs9ICdib29sZWFuJztcbiAgfSBlbHNlIGlmIChvYmouJHJlZikge1xuICAgIHN0ciArPSBIZWxwZXJzLnNpbXBsZVJlZihvYmouJHJlZik7XG4gIH0gZWxzZSB7XG4gICAgc3RyICs9IG9iai50eXBlO1xuICB9XG5cbiAgcmV0dXJuIHN0cjtcbn07XG5cbnZhciBzY2hlbWFUb0pTT04gPSBtb2R1bGUuZXhwb3J0cy5zY2hlbWFUb0pTT04gPSBmdW5jdGlvbiAoc2NoZW1hLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gIHNjaGVtYSA9IEhlbHBlcnMucmVzb2x2ZVNjaGVtYShzY2hlbWEpO1xuXG4gIGlmKHR5cGVvZiBtb2RlbFByb3BlcnR5TWFjcm8gIT09ICdmdW5jdGlvbicpIHtcbiAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBmdW5jdGlvbihwcm9wKXtcbiAgICAgIHJldHVybiAocHJvcCB8fCB7fSkuZGVmYXVsdDtcbiAgICB9O1xuICB9XG5cbiAgbW9kZWxzVG9JZ25vcmU9IG1vZGVsc1RvSWdub3JlIHx8IHt9O1xuXG4gIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gIHZhciBmb3JtYXQgPSBzY2hlbWEuZm9ybWF0O1xuICB2YXIgbW9kZWw7XG4gIHZhciBvdXRwdXQ7XG5cbiAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5leGFtcGxlKSkge1xuICAgIG91dHB1dCA9IHNjaGVtYS5leGFtcGxlO1xuICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSAmJiBfLmlzQXJyYXkoc2NoZW1hLmVudW0pKSB7XG4gICAgb3V0cHV0ID0gc2NoZW1hLmVudW1bMF07XG4gIH1cblxuICBpZiAoXy5pc1VuZGVmaW5lZChvdXRwdXQpKSB7XG4gICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICBtb2RlbCA9IG1vZGVsc1tIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZildO1xuXG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQobW9kZWwpKSB7XG4gICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdKSkge1xuICAgICAgICAgIG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdID0gbW9kZWw7XG4gICAgICAgICAgb3V0cHV0ID0gc2NoZW1hVG9KU09OKG1vZGVsLmRlZmluaXRpb24sIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICAgICAgZGVsZXRlIG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChtb2RlbC50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICAgICAgICBvdXRwdXQgPSBbXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb3V0cHV0ID0ge307XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuZGVmYXVsdCkpIHtcbiAgICAgIG91dHB1dCA9IHNjaGVtYS5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgICAgIG91dHB1dCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICAgICAgb3V0cHV0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQgPSAnc3RyaW5nJztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgb3V0cHV0ID0gMDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICBvdXRwdXQgPSAwLjA7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgIG91dHB1dCA9IHRydWU7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgb3V0cHV0ID0ge307XG5cbiAgICAgIF8uZm9yRWFjaChzY2hlbWEucHJvcGVydGllcywgZnVuY3Rpb24gKHByb3BlcnR5LCBuYW1lKSB7XG4gICAgICAgIHZhciBjUHJvcGVydHkgPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG5cbiAgICAgICAgLy8gQWxsb3cgbWFjcm8gdG8gc2V0IHRoZSBkZWZhdWx0IHZhbHVlXG4gICAgICAgIGNQcm9wZXJ0eS5kZWZhdWx0ID0gbW9kZWxQcm9wZXJ0eU1hY3JvKHByb3BlcnR5KTtcblxuICAgICAgICBvdXRwdXRbbmFtZV0gPSBzY2hlbWFUb0pTT04oY1Byb3BlcnR5LCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBvdXRwdXQgPSBbXTtcblxuICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIF8uZm9yRWFjaChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgb3V0cHV0LnB1c2goc2NoZW1hVG9KU09OKGl0ZW0sIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgb3V0cHV0LnB1c2goc2NoZW1hVG9KU09OKHNjaGVtYS5pdGVtcywgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSk7XG4gICAgICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBvdXRwdXQucHVzaCh7fSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBIZWxwZXJzLmxvZygnQXJyYXkgdHlwZVxcJ3MgXFwnaXRlbXNcXCcgcHJvcGVydHkgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufTtcblxubW9kdWxlLmV4cG9ydHMuc2NoZW1hVG9IVE1MID1mdW5jdGlvbiAobmFtZSwgc2NoZW1hLCBtb2RlbHMsIG1vZGVsUHJvcGVydHlNYWNybykge1xuICB2YXIgc3Ryb25nT3BlbiA9ICc8c3BhbiBjbGFzcz1cInN0cm9uZ1wiPic7XG4gIHZhciBzdHJvbmdDbG9zZSA9ICc8L3NwYW4+JztcblxuICAvLyBBbGxvdyBmb3IgaWdub3JpbmcgdGhlICduYW1lJyBhcmd1bWVudC4uLi4gc2hpZnRpbmcgdGhlIHJlc3RcbiAgaWYoXy5pc09iamVjdChhcmd1bWVudHNbMF0pKSB7XG4gICAgbmFtZSA9IHZvaWQgMDtcbiAgICBzY2hlbWEgPSBhcmd1bWVudHNbMF07XG4gICAgbW9kZWxzID0gYXJndW1lbnRzWzFdO1xuICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGFyZ3VtZW50c1syXTtcbiAgfVxuXG4gIG1vZGVscyA9IG1vZGVscyB8fCB7fTtcblxuICAvLyBSZXNvbHZlIHRoZSBzY2hlbWEgKEhhbmRsZSBuZXN0ZWQgc2NoZW1hcylcbiAgc2NoZW1hID0gSGVscGVycy5yZXNvbHZlU2NoZW1hKHNjaGVtYSk7XG5cbiAgLy8gUmV0dXJuIGZvciBlbXB0eSBvYmplY3RcbiAgaWYoXy5pc0VtcHR5KHNjaGVtYSkpIHtcbiAgICByZXR1cm4gc3Ryb25nT3BlbiArICdFbXB0eScgKyBzdHJvbmdDbG9zZTtcbiAgfVxuXG4gIC8vIERlcmVmZXJlbmNlICRyZWYgZnJvbSAnbW9kZWxzJ1xuICBpZih0eXBlb2Ygc2NoZW1hLiRyZWYgPT09ICdzdHJpbmcnKSB7XG4gICAgbmFtZSA9IEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS4kcmVmKTtcbiAgICBzY2hlbWEgPSBtb2RlbHNbbmFtZV07XG4gICAgaWYodHlwZW9mIHNjaGVtYSA9PT0gJ3VuZGVmaW5lZCcpXG4gICAge1xuICAgICAgcmV0dXJuIHN0cm9uZ09wZW4gKyBuYW1lICsgJyBpcyBub3QgZGVmaW5lZCEnICsgc3Ryb25nQ2xvc2U7XG4gICAgfVxuICB9XG5cbiAgaWYodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgbmFtZSA9IHNjaGVtYS50aXRsZSB8fCAnSW5saW5lIE1vZGVsJztcbiAgfVxuXG4gIC8vIElmIHdlIGFyZSBhIE1vZGVsIG9iamVjdC4uLiBhZGp1c3QgYWNjb3JkaW5nbHlcbiAgaWYoc2NoZW1hLmRlZmluaXRpb24pIHtcbiAgICBzY2hlbWEgPSBzY2hlbWEuZGVmaW5pdGlvbjtcbiAgfVxuXG4gIGlmKHR5cGVvZiBtb2RlbFByb3BlcnR5TWFjcm8gIT09ICdmdW5jdGlvbicpIHtcbiAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBmdW5jdGlvbihwcm9wKXtcbiAgICAgIHJldHVybiAocHJvcCB8fCB7fSkuZGVmYXVsdDtcbiAgICB9O1xuICB9XG5cbiAgdmFyIHJlZmVyZW5jZXMgPSB7fTtcbiAgdmFyIHNlZW5Nb2RlbHMgPSBbXTtcbiAgdmFyIGlubGluZU1vZGVscyA9IDA7XG5cblxuXG4gIC8vIEdlbmVyYXRlIGN1cnJlbnQgSFRNTFxuICB2YXIgaHRtbCA9IHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpO1xuXG4gIC8vIEdlbmVyYXRlIHJlZmVyZW5jZXMgSFRNTFxuICB3aGlsZSAoXy5rZXlzKHJlZmVyZW5jZXMpLmxlbmd0aCA+IDApIHtcbiAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgXy5mb3JFYWNoKHJlZmVyZW5jZXMsIGZ1bmN0aW9uIChzY2hlbWEsIG5hbWUpIHtcbiAgICAgIHZhciBzZWVuTW9kZWwgPSBfLmluZGV4T2Yoc2Vlbk1vZGVscywgbmFtZSkgPiAtMTtcblxuICAgICAgZGVsZXRlIHJlZmVyZW5jZXNbbmFtZV07XG5cbiAgICAgIGlmICghc2Vlbk1vZGVsKSB7XG4gICAgICAgIHNlZW5Nb2RlbHMucHVzaChuYW1lKTtcblxuICAgICAgICBodG1sICs9ICc8YnIgLz4nICsgcHJvY2Vzc01vZGVsKHNjaGVtYSwgbmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgfVxuXG4gIHJldHVybiBodG1sO1xuXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIGZ1bmN0aW9uIGFkZFJlZmVyZW5jZShzY2hlbWEsIG5hbWUsIHNraXBSZWYpIHtcbiAgICB2YXIgbW9kZWxOYW1lID0gbmFtZTtcbiAgICB2YXIgbW9kZWw7XG5cbiAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgIG1vZGVsTmFtZSA9IHNjaGVtYS50aXRsZSB8fCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZik7XG4gICAgICBtb2RlbCA9IG1vZGVsc1ttb2RlbE5hbWVdO1xuICAgIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChuYW1lKSkge1xuICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwgJyArICgrK2lubGluZU1vZGVscyk7XG4gICAgICBtb2RlbCA9IHtkZWZpbml0aW9uOiBzY2hlbWF9O1xuICAgIH1cblxuICAgIGlmIChza2lwUmVmICE9PSB0cnVlKSB7XG4gICAgICByZWZlcmVuY2VzW21vZGVsTmFtZV0gPSBfLmlzVW5kZWZpbmVkKG1vZGVsKSA/IHt9IDogbW9kZWwuZGVmaW5pdGlvbjtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9kZWxOYW1lO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJpbWl0aXZlVG9IVE1MKHNjaGVtYSkge1xuICAgIHZhciBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcFR5cGVcIj4nO1xuICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG5cbiAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYSwgSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLiRyZWYpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLnByb3BlcnRpZXMpKSB7XG4gICAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBodG1sICs9ICdvYmplY3QnO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgaHRtbCArPSAnQXJyYXlbJztcblxuICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIGh0bWwgKz0gXy5tYXAoc2NoZW1hLml0ZW1zLCBhZGRSZWZlcmVuY2UpLmpvaW4oJywnKTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLiRyZWYpKSB7XG4gICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSAmJiBfLmluZGV4T2YoWydhcnJheScsICdvYmplY3QnXSwgc2NoZW1hLml0ZW1zLnR5cGUpID09PSAtMSkge1xuICAgICAgICAgICAgaHRtbCArPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zLCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuaXRlbXMuJHJlZikpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBIZWxwZXJzLmxvZygnQXJyYXkgdHlwZVxcJ3MgXFwnaXRlbXNcXCcgc2NoZW1hIGlzIG5vdCBhbiBhcnJheSBvciBhbiBvYmplY3QsIGNhbm5vdCBwcm9jZXNzJyk7XG4gICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICB9XG5cbiAgICAgIGh0bWwgKz0gJ10nO1xuICAgIH0gZWxzZSB7XG4gICAgICBodG1sICs9IHNjaGVtYS50eXBlO1xuICAgIH1cblxuICAgIGh0bWwgKz0gJzwvc3Bhbj4nO1xuXG4gICAgcmV0dXJuIGh0bWw7XG4gIH1cblxuICBmdW5jdGlvbiBwcmltaXRpdmVUb09wdGlvbnNIVE1MKHNjaGVtYSwgaHRtbCkge1xuICAgIHZhciBvcHRpb25zID0gJyc7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcbiAgICB2YXIgaXNBcnJheSA9IHR5cGUgPT09ICdhcnJheSc7XG5cbiAgICBpZiAoaXNBcnJheSkge1xuICAgICAgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpICYmICFfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSkge1xuICAgICAgICB0eXBlID0gc2NoZW1hLml0ZW1zLnR5cGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0eXBlID0gJ29iamVjdCc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5kZWZhdWx0KSkge1xuICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdEZWZhdWx0Jywgc2NoZW1hLmRlZmF1bHQpO1xuICAgIH1cblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICBpZiAoc2NoZW1hLm1pbkxlbmd0aCkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gTGVuZ3RoJywgc2NoZW1hLm1pbkxlbmd0aCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEubWF4TGVuZ3RoKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBMZW5ndGgnLCBzY2hlbWEubWF4TGVuZ3RoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5wYXR0ZXJuKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnUmVnLiBFeHAuJywgc2NoZW1hLnBhdHRlcm4pO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnaW50ZWdlcic6XG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgIGlmIChzY2hlbWEubWluaW11bSkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gVmFsdWUnLCBzY2hlbWEubWluaW11bSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEuZXhjbHVzaXZlTWluaW11bSkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0V4Y2x1c2l2ZSBNaW4uJywgJ3RydWUnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5tYXhpbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBWYWx1ZScsIHNjaGVtYS5tYXhpbXVtKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5leGNsdXNpdmVNYXhpbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1heC4nLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm11bHRpcGxlT2YpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNdWx0aXBsZSBPZicsIHNjaGVtYS5tdWx0aXBsZU9mKTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgIGlmIChzY2hlbWEubWluSXRlbXMpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNaW4uIEl0ZW1zJywgc2NoZW1hLm1pbkl0ZW1zKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5tYXhJdGVtcykge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01heC4gSXRlbXMnLCBzY2hlbWEubWF4SXRlbXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLnVuaXF1ZUl0ZW1zKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnVW5pcXVlIEl0ZW1zJywgJ3RydWUnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5jb2xsZWN0aW9uRm9ybWF0KSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnQ29sbC4gRm9ybWF0Jywgc2NoZW1hLmNvbGxlY3Rpb25Gb3JtYXQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykpIHtcbiAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLmVudW0pKSB7XG4gICAgICAgIHZhciBlbnVtU3RyaW5nO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAnbnVtYmVyJyB8fCB0eXBlID09PSAnaW50ZWdlcicpIHtcbiAgICAgICAgICBlbnVtU3RyaW5nID0gc2NoZW1hLmVudW0uam9pbignLCAnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbnVtU3RyaW5nID0gJ1wiJyArIHNjaGVtYS5lbnVtLmpvaW4oJ1wiLCBcIicpICsgJ1wiJztcbiAgICAgICAgfVxuXG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRW51bScsIGVudW1TdHJpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wV3JhcFwiPicgKyBodG1sICsgJzx0YWJsZSBjbGFzcz1cIm9wdGlvbnNXcmFwcGVyXCI+PHRyPjx0aCBjb2xzcGFuPVwiMlwiPicgKyB0eXBlICsgJzwvdGg+PC90cj4nICsgb3B0aW9ucyArICc8L3RhYmxlPjwvc3Bhbj4nO1xuICAgIH1cblxuICAgIHJldHVybiBodG1sO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJvY2Vzc01vZGVsKHNjaGVtYSwgbmFtZSkge1xuICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgdmFyIGlzQXJyYXkgPSBzY2hlbWEudHlwZSA9PT0gJ2FycmF5JztcbiAgICB2YXIgaHRtbCA9IHN0cm9uZ09wZW4gKyBuYW1lICsgJyAnICsgKGlzQXJyYXkgPyAnWycgOiAneycpICsgc3Ryb25nQ2xvc2U7XG5cbiAgICBpZiAobmFtZSkge1xuICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChpc0FycmF5KSB7XG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgXy5tYXAoc2NoZW1hLml0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgIHZhciB0eXBlID0gaXRlbS50eXBlIHx8ICdvYmplY3QnO1xuXG4gICAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoaXRlbS4kcmVmKSkge1xuICAgICAgICAgICAgaWYgKF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCB0eXBlKSA+IC0xKSB7XG4gICAgICAgICAgICAgIGlmICh0eXBlID09PSAnb2JqZWN0JyAmJiBfLmlzVW5kZWZpbmVkKGl0ZW0ucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJ29iamVjdCc7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFkZFJlZmVyZW5jZShpdGVtKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoaXRlbSwgdHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBhZGRSZWZlcmVuY2UoaXRlbSwgSGVscGVycy5zaW1wbGVSZWYoaXRlbS4kcmVmKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KS5qb2luKCcsPC9kaXY+PGRpdj4nKTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLiRyZWYpKSB7XG4gICAgICAgICAgaWYgKF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCBzY2hlbWEuaXRlbXMudHlwZSB8fCAnb2JqZWN0JykgPiAtMSkge1xuICAgICAgICAgICAgaWYgKChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSB8fCBzY2hlbWEuaXRlbXMudHlwZSA9PT0gJ29iamVjdCcpICYmIF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+b2JqZWN0PC9kaXY+JztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMpICsgJzwvZGl2Pic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoc2NoZW1hLml0ZW1zLCBzY2hlbWEuaXRlbXMudHlwZSkgKyAnPC9kaXY+JztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcywgSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLml0ZW1zLiRyZWYpKSArICc8L2Rpdj4nO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBIZWxwZXJzLmxvZygnQXJyYXkgdHlwZVxcJ3MgXFwnaXRlbXNcXCcgcHJvcGVydHkgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgaHRtbCArPSAnPGRpdj5vYmplY3Q8L2Rpdj4nO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSkgKyAnPC9kaXY+JztcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEucHJvcGVydGllcykpIHtcbiAgICAgICAgICB2YXIgY29udGVudHMgPSBfLm1hcChzY2hlbWEucHJvcGVydGllcywgZnVuY3Rpb24gKHByb3BlcnR5LCBuYW1lKSB7XG4gICAgICAgICAgICB2YXIgcHJvcGVydHlJc1JlcXVpcmVkID0gKF8uaW5kZXhPZihzY2hlbWEucmVxdWlyZWQsIG5hbWUpID49IDApO1xuICAgICAgICAgICAgdmFyIGNQcm9wZXJ0eSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcblxuICAgICAgICAgICAgdmFyIHJlcXVpcmVkQ2xhc3MgPSBwcm9wZXJ0eUlzUmVxdWlyZWQgPyAncmVxdWlyZWQnIDogJyc7XG4gICAgICAgICAgICB2YXIgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BOYW1lICcgKyByZXF1aXJlZENsYXNzICsgJ1wiPicgKyBuYW1lICsgJzwvc3Bhbj4gKCc7XG4gICAgICAgICAgICB2YXIgbW9kZWw7XG4gICAgICAgICAgICB2YXIgcHJvcERlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAvLyBBbGxvdyBtYWNybyB0byBzZXQgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICAgICAgICAgIGNQcm9wZXJ0eS5kZWZhdWx0ID0gbW9kZWxQcm9wZXJ0eU1hY3JvKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICAgICAgICAgICAgY1Byb3BlcnR5ID0gSGVscGVycy5yZXNvbHZlU2NoZW1hKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgIHByb3BEZXNjcmlwdGlvbiA9IHByb3BlcnR5LmRlc2NyaXB0aW9uIHx8IGNQcm9wZXJ0eS5kZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBoYW5kbGUgcHJvcGVydHkgcmVmZXJlbmNlcyB0byBwcmltaXRpdmVzIChJc3N1ZSAzMzkpXG4gICAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoY1Byb3BlcnR5LiRyZWYpKSB7XG4gICAgICAgICAgICAgIG1vZGVsID0gbW9kZWxzW0hlbHBlcnMuc2ltcGxlUmVmKGNQcm9wZXJ0eS4kcmVmKV07XG5cbiAgICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKG1vZGVsKSAmJiBfLmluZGV4T2YoW3VuZGVmaW5lZCwgJ2FycmF5JywgJ29iamVjdCddLCBtb2RlbC5kZWZpbml0aW9uLnR5cGUpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIC8vIFVzZSByZWZlcmVuY2VkIHNjaGVtYVxuICAgICAgICAgICAgICAgIGNQcm9wZXJ0eSA9IEhlbHBlcnMucmVzb2x2ZVNjaGVtYShtb2RlbC5kZWZpbml0aW9uKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBodG1sICs9IHByaW1pdGl2ZVRvSFRNTChjUHJvcGVydHkpO1xuXG4gICAgICAgICAgICBpZighcHJvcGVydHlJc1JlcXVpcmVkKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJywgPHNwYW4gY2xhc3M9XCJwcm9wT3B0S2V5XCI+b3B0aW9uYWw8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYocHJvcGVydHkucmVhZE9ubHkpIHtcbiAgICAgICAgICAgICAgICBodG1sICs9ICcsIDxzcGFuIGNsYXNzPVwicHJvcFJlYWRPbmx5XCI+cmVhZCBvbmx5PC9zcGFuPic7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGh0bWwgKz0gJyknO1xuXG4gICAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQocHJvcERlc2NyaXB0aW9uKSkge1xuICAgICAgICAgICAgICBodG1sICs9ICc6ICcgKyAnPHNwYW4gY2xhc3M9XCJwcm9wRGVzY1wiPicgKyBwcm9wRGVzY3JpcHRpb24gKyAnPC9zcGFuPic7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjUHJvcGVydHkuZW51bSkge1xuICAgICAgICAgICAgICBodG1sICs9ICcgPSA8c3BhbiBjbGFzcz1cInByb3BWYWxzXCI+W1xcJycgKyBjUHJvcGVydHkuZW51bS5qb2luKCdcXCcsIFxcJycpICsgJ1xcJ108L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuICc8ZGl2JyArIChwcm9wZXJ0eS5yZWFkT25seSA/ICcgY2xhc3M9XCJyZWFkT25seVwiJyA6ICcnKSArICc+JyArIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoY1Byb3BlcnR5LCBodG1sKTtcbiAgICAgICAgICB9KS5qb2luKCcsPC9kaXY+Jyk7XG5cbiAgICAgICAgICBpZiAoY29udGVudHMpIHtcbiAgICAgICAgICAgIGh0bWwgKz0gY29udGVudHMgKyAnPC9kaXY+JztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoc2NoZW1hLCB0eXBlKSArICc8L2Rpdj4nO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBodG1sICsgc3Ryb25nT3BlbiArIChpc0FycmF5ID8gJ10nIDogJ30nKSArIHN0cm9uZ0Nsb3NlO1xuICB9XG59OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIFN3YWdnZXJIdHRwID0gcmVxdWlyZSgnLi9odHRwJyk7XG52YXIgXyA9IHtcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpXG59O1xuXG52YXIgU3dhZ2dlclNwZWNDb252ZXJ0ZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lcnJvcnMgPSBbXTtcbiAgdGhpcy53YXJuaW5ncyA9IFtdO1xuICB0aGlzLm1vZGVsTWFwID0ge307XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuc2V0RG9jdW1lbnRhdGlvbkxvY2F0aW9uID0gZnVuY3Rpb24gKGxvY2F0aW9uKSB7XG4gIHRoaXMuZG9jTG9jYXRpb24gPSBsb2NhdGlvbjtcbn07XG5cbi8qKlxuICogY29udmVydHMgYSByZXNvdXJjZSBsaXN0aW5nIE9SIGFwaSBkZWNsYXJhdGlvblxuICoqL1xuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmNvbnZlcnQgPSBmdW5jdGlvbiAob2JqLCBjbGllbnRBdXRob3JpemF0aW9ucywgb3B0cywgY2FsbGJhY2spIHtcbiAgLy8gbm90IGEgdmFsaWQgc3BlY1xuICBpZighb2JqIHx8ICFBcnJheS5pc0FycmF5KG9iai5hcGlzKSkge1xuICAgIHJldHVybiB0aGlzLmZpbmlzaChjYWxsYmFjaywgbnVsbCk7XG4gIH1cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IGNsaWVudEF1dGhvcml6YXRpb25zO1xuXG4gIC8vIGNyZWF0ZSBhIG5ldyBzd2FnZ2VyIG9iamVjdCB0byByZXR1cm5cbiAgdmFyIHN3YWdnZXIgPSB7IHN3YWdnZXI6ICcyLjAnIH07XG5cbiAgc3dhZ2dlci5vcmlnaW5hbFZlcnNpb24gPSBvYmouc3dhZ2dlclZlcnNpb247XG5cbiAgLy8gYWRkIHRoZSBpbmZvXG4gIHRoaXMuYXBpSW5mbyhvYmosIHN3YWdnZXIpO1xuXG4gIC8vIGFkZCBzZWN1cml0eSBkZWZpbml0aW9uc1xuICB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMob2JqLCBzd2FnZ2VyKTtcblxuICAvLyB0YWtlIGJhc2VQYXRoIGludG8gYWNjb3VudFxuICBpZiAob2JqLmJhc2VQYXRoKSB7XG4gICAgdGhpcy5zZXREb2N1bWVudGF0aW9uTG9jYXRpb24ob2JqLmJhc2VQYXRoKTtcbiAgfVxuXG4gIC8vIHNlZSBpZiB0aGlzIGlzIGEgc2luZ2xlLWZpbGUgc3dhZ2dlciBkZWZpbml0aW9uXG4gIHZhciBpc1NpbmdsZUZpbGVTd2FnZ2VyID0gZmFsc2U7XG4gIHZhciBpO1xuICBmb3IoaSA9IDA7IGkgPCBvYmouYXBpcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBhcGkgPSBvYmouYXBpc1tpXTtcbiAgICBpZihBcnJheS5pc0FycmF5KGFwaS5vcGVyYXRpb25zKSkge1xuICAgICAgaXNTaW5nbGVGaWxlU3dhZ2dlciA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmKGlzU2luZ2xlRmlsZVN3YWdnZXIpIHtcbiAgICB0aGlzLmRlY2xhcmF0aW9uKG9iaiwgc3dhZ2dlcik7XG4gICAgdGhpcy5maW5pc2goY2FsbGJhY2ssIHN3YWdnZXIpO1xuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMucmVzb3VyY2VMaXN0aW5nKG9iaiwgc3dhZ2dlciwgb3B0cywgY2FsbGJhY2spO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZGVjbGFyYXRpb24gPSBmdW5jdGlvbihvYmosIHN3YWdnZXIpIHtcbiAgdmFyIG5hbWUsIGksIHAsIHBvcztcbiAgaWYoIW9iai5hcGlzKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKG9iai5iYXNlUGF0aC5pbmRleE9mKCdodHRwOi8vJykgPT09IDApIHtcbiAgICBwID0gb2JqLmJhc2VQYXRoLnN1YnN0cmluZygnaHR0cDovLycubGVuZ3RoKTtcbiAgICBwb3MgPSBwLmluZGV4T2YoJy8nKTtcbiAgICBpZiAocG9zID4gMCkge1xuICAgICAgc3dhZ2dlci5ob3N0ID0gcC5zdWJzdHJpbmcoMCwgcG9zKTtcbiAgICAgIHN3YWdnZXIuYmFzZVBhdGggPSBwLnN1YnN0cmluZyhwb3MpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHA7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gJy8nO1xuICAgIH1cbiAgfSBlbHNlIGlmIChvYmouYmFzZVBhdGguaW5kZXhPZignaHR0cHM6Ly8nKSA9PT0gMCkge1xuICAgIHAgPSBvYmouYmFzZVBhdGguc3Vic3RyaW5nKCdodHRwczovLycubGVuZ3RoKTtcbiAgICBwb3MgPSBwLmluZGV4T2YoJy8nKTtcbiAgICBpZiAocG9zID4gMCkge1xuICAgICAgc3dhZ2dlci5ob3N0ID0gcC5zdWJzdHJpbmcoMCwgcG9zKTtcbiAgICAgIHN3YWdnZXIuYmFzZVBhdGggPSBwLnN1YnN0cmluZyhwb3MpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHA7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gJy8nO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzd2FnZ2VyLmJhc2VQYXRoID0gb2JqLmJhc2VQYXRoO1xuICB9XG5cbiAgdmFyIHJlc291cmNlTGV2ZWxBdXRoO1xuICBpZihvYmouYXV0aG9yaXphdGlvbnMpIHtcbiAgICByZXNvdXJjZUxldmVsQXV0aCA9IG9iai5hdXRob3JpemF0aW9ucztcbiAgfVxuICBpZihvYmouY29uc3VtZXMpIHtcbiAgICBzd2FnZ2VyLmNvbnN1bWVzID0gb2JqLmNvbnN1bWVzO1xuICB9XG4gIGlmKG9iai5wcm9kdWNlcykge1xuICAgIHN3YWdnZXIucHJvZHVjZXMgPSBvYmoucHJvZHVjZXM7XG4gIH1cblxuICAvLyBidWlsZCBhIG1hcHBpbmcgb2YgaWQgdG8gbmFtZSBmb3IgMS4wIG1vZGVsIHJlc29sdXRpb25zXG4gIGlmKF8uaXNPYmplY3Qob2JqKSkge1xuICAgIGZvcihuYW1lIGluIG9iai5tb2RlbHMpIHtcbiAgICAgIHZhciBleGlzdGluZ01vZGVsID0gb2JqLm1vZGVsc1tuYW1lXTtcbiAgICAgIHZhciBrZXkgPSAoZXhpc3RpbmdNb2RlbC5pZCB8fCBuYW1lKTtcbiAgICAgIHRoaXMubW9kZWxNYXBba2V5XSA9IG5hbWU7XG4gICAgfVxuICB9XG5cbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmFwaXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYXBpID0gb2JqLmFwaXNbaV07XG4gICAgdmFyIHBhdGggPSBhcGkucGF0aDtcbiAgICB2YXIgb3BlcmF0aW9ucyA9IGFwaS5vcGVyYXRpb25zO1xuICAgIHRoaXMub3BlcmF0aW9ucyhwYXRoLCBvYmoucmVzb3VyY2VQYXRoLCBvcGVyYXRpb25zLCByZXNvdXJjZUxldmVsQXV0aCwgc3dhZ2dlcik7XG4gIH1cblxuICB2YXIgbW9kZWxzID0gb2JqLm1vZGVscyB8fCB7fTtcbiAgdGhpcy5tb2RlbHMobW9kZWxzLCBzd2FnZ2VyKTtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5tb2RlbHMgPSBmdW5jdGlvbihvYmosIHN3YWdnZXIpIHtcbiAgaWYoIV8uaXNPYmplY3Qob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgbmFtZTtcblxuICBzd2FnZ2VyLmRlZmluaXRpb25zID0gc3dhZ2dlci5kZWZpbml0aW9ucyB8fCB7fTtcbiAgZm9yKG5hbWUgaW4gb2JqKSB7XG4gICAgdmFyIGV4aXN0aW5nTW9kZWwgPSBvYmpbbmFtZV07XG4gICAgdmFyIF9yZXF1aXJlZCA9IFtdO1xuICAgIHZhciBzY2hlbWEgPSB7IHByb3BlcnRpZXM6IHt9fTtcbiAgICB2YXIgcHJvcGVydHlOYW1lO1xuICAgIGZvcihwcm9wZXJ0eU5hbWUgaW4gZXhpc3RpbmdNb2RlbC5wcm9wZXJ0aWVzKSB7XG4gICAgICB2YXIgZXhpc3RpbmdQcm9wZXJ0eSA9IGV4aXN0aW5nTW9kZWwucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuICAgICAgdmFyIHByb3BlcnR5ID0ge307XG4gICAgICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nUHJvcGVydHksIHByb3BlcnR5KTtcbiAgICAgIGlmKGV4aXN0aW5nUHJvcGVydHkuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgcHJvcGVydHkuZGVzY3JpcHRpb24gPSBleGlzdGluZ1Byb3BlcnR5LmRlc2NyaXB0aW9uO1xuICAgICAgfVxuICAgICAgaWYoZXhpc3RpbmdQcm9wZXJ0eVsnZW51bSddKSB7XG4gICAgICAgIHByb3BlcnR5WydlbnVtJ10gPSBleGlzdGluZ1Byb3BlcnR5WydlbnVtJ107XG4gICAgICB9XG4gICAgICBpZih0eXBlb2YgZXhpc3RpbmdQcm9wZXJ0eS5yZXF1aXJlZCA9PT0gJ2Jvb2xlYW4nICYmIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgICAgX3JlcXVpcmVkLnB1c2gocHJvcGVydHlOYW1lKTtcbiAgICAgIH1cbiAgICAgIGlmKHR5cGVvZiBleGlzdGluZ1Byb3BlcnR5LnJlcXVpcmVkID09PSAnc3RyaW5nJyAmJiBleGlzdGluZ1Byb3BlcnR5LnJlcXVpcmVkID09PSAndHJ1ZScpIHtcbiAgICAgICAgX3JlcXVpcmVkLnB1c2gocHJvcGVydHlOYW1lKTtcbiAgICAgIH1cbiAgICAgIHNjaGVtYS5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV0gPSBwcm9wZXJ0eTtcbiAgICB9XG4gICAgaWYoX3JlcXVpcmVkLmxlbmd0aCA+IDApIHtcbiAgICAgIHNjaGVtYS5yZXF1aXJlZCA9IF9yZXF1aXJlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2NoZW1hLnJlcXVpcmVkID0gZXhpc3RpbmdNb2RlbC5yZXF1aXJlZDtcbiAgICB9XG4gICAgc3dhZ2dlci5kZWZpbml0aW9uc1tuYW1lXSA9IHNjaGVtYTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmV4dHJhY3RUYWcgPSBmdW5jdGlvbihyZXNvdXJjZVBhdGgpIHtcbiAgdmFyIHBhdGhTdHJpbmcgPSByZXNvdXJjZVBhdGggfHwgJ2RlZmF1bHQnO1xuICBpZihwYXRoU3RyaW5nLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcGF0aFN0cmluZy5pbmRleE9mKCdodHRwczonKSA9PT0gMCkge1xuICAgIHBhdGhTdHJpbmcgPSBwYXRoU3RyaW5nLnNwbGl0KFsnLyddKTtcbiAgICBwYXRoU3RyaW5nID0gcGF0aFN0cmluZ1twYXRoU3RyaW5nLmxlbmd0aCAtMV0uc3Vic3RyaW5nKCk7XG4gIH1cbiAgaWYocGF0aFN0cmluZy5lbmRzV2l0aCgnLmpzb24nKSkge1xuICAgIHBhdGhTdHJpbmcgPSBwYXRoU3RyaW5nLnN1YnN0cmluZygwLCBwYXRoU3RyaW5nLmxlbmd0aCAtICcuanNvbicubGVuZ3RoKTtcbiAgfVxuICByZXR1cm4gcGF0aFN0cmluZy5yZXBsYWNlKCcvJywnJyk7XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUub3BlcmF0aW9ucyA9IGZ1bmN0aW9uKHBhdGgsIHJlc291cmNlUGF0aCwgb2JqLCByZXNvdXJjZUxldmVsQXV0aCwgc3dhZ2dlcikge1xuICBpZighQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBpO1xuXG4gIGlmKCFzd2FnZ2VyLnBhdGhzKSB7XG4gICAgc3dhZ2dlci5wYXRocyA9IHt9O1xuICB9XG5cbiAgdmFyIHBhdGhPYmogPSBzd2FnZ2VyLnBhdGhzW3BhdGhdIHx8IHt9O1xuICB2YXIgdGFnID0gdGhpcy5leHRyYWN0VGFnKHJlc291cmNlUGF0aCk7XG4gIHN3YWdnZXIudGFncyA9IHN3YWdnZXIudGFncyB8fCBbXTtcbiAgdmFyIG1hdGNoZWQgPSBmYWxzZTtcbiAgZm9yKGkgPSAwOyBpIDwgc3dhZ2dlci50YWdzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHRhZ09iamVjdCA9IHN3YWdnZXIudGFnc1tpXTtcbiAgICBpZih0YWdPYmplY3QubmFtZSA9PT0gdGFnKSB7XG4gICAgICBtYXRjaGVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYoIW1hdGNoZWQpIHtcbiAgICBzd2FnZ2VyLnRhZ3MucHVzaCh7bmFtZTogdGFnfSk7XG4gIH1cblxuICBmb3IoaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZXhpc3RpbmdPcGVyYXRpb24gPSBvYmpbaV07XG4gICAgdmFyIG1ldGhvZCA9IChleGlzdGluZ09wZXJhdGlvbi5tZXRob2QgfHwgZXhpc3RpbmdPcGVyYXRpb24uaHR0cE1ldGhvZCkudG9Mb3dlckNhc2UoKTtcbiAgICB2YXIgb3BlcmF0aW9uID0ge3RhZ3M6IFt0YWddfTtcbiAgICB2YXIgZXhpc3RpbmdBdXRob3JpemF0aW9ucyA9IGV4aXN0aW5nT3BlcmF0aW9uLmF1dGhvcml6YXRpb25zO1xuXG4gICAgaWYoZXhpc3RpbmdBdXRob3JpemF0aW9ucyAmJiBPYmplY3Qua2V5cyhleGlzdGluZ0F1dGhvcml6YXRpb25zKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGV4aXN0aW5nQXV0aG9yaXphdGlvbnMgPSByZXNvdXJjZUxldmVsQXV0aDtcbiAgICB9XG5cbiAgICBpZih0eXBlb2YgZXhpc3RpbmdBdXRob3JpemF0aW9ucyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBzY29wZXNPYmplY3Q7XG4gICAgICBmb3IodmFyIGtleSBpbiBleGlzdGluZ0F1dGhvcml6YXRpb25zKSB7XG4gICAgICAgIG9wZXJhdGlvbi5zZWN1cml0eSA9IG9wZXJhdGlvbi5zZWN1cml0eSB8fCBbXTtcbiAgICAgICAgdmFyIHNjb3BlcyA9IGV4aXN0aW5nQXV0aG9yaXphdGlvbnNba2V5XTtcbiAgICAgICAgaWYoc2NvcGVzKSB7XG4gICAgICAgICAgdmFyIHNlY3VyaXR5U2NvcGVzID0gW107XG4gICAgICAgICAgZm9yKHZhciBqIGluIHNjb3Blcykge1xuICAgICAgICAgICAgc2VjdXJpdHlTY29wZXMucHVzaChzY29wZXNbal0uc2NvcGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzY29wZXNPYmplY3QgPSB7fTtcbiAgICAgICAgICBzY29wZXNPYmplY3Rba2V5XSA9IHNlY3VyaXR5U2NvcGVzO1xuICAgICAgICAgIG9wZXJhdGlvbi5zZWN1cml0eS5wdXNoKHNjb3Blc09iamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc2NvcGVzT2JqZWN0ID0ge307XG4gICAgICAgICAgc2NvcGVzT2JqZWN0W2tleV0gPSBbXTtcbiAgICAgICAgICBvcGVyYXRpb24uc2VjdXJpdHkucHVzaChzY29wZXNPYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24uY29uc3VtZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5jb25zdW1lcyA9IGV4aXN0aW5nT3BlcmF0aW9uLmNvbnN1bWVzO1xuICAgIH1cbiAgICBlbHNlIGlmKHN3YWdnZXIuY29uc3VtZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5jb25zdW1lcyA9IHN3YWdnZXIuY29uc3VtZXM7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLnByb2R1Y2VzKSB7XG4gICAgICBvcGVyYXRpb24ucHJvZHVjZXMgPSBleGlzdGluZ09wZXJhdGlvbi5wcm9kdWNlcztcbiAgICB9XG4gICAgZWxzZSBpZihzd2FnZ2VyLnByb2R1Y2VzKSB7XG4gICAgICBvcGVyYXRpb24ucHJvZHVjZXMgPSBzd2FnZ2VyLnByb2R1Y2VzO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5zdW1tYXJ5KSB7XG4gICAgICBvcGVyYXRpb24uc3VtbWFyeSA9IGV4aXN0aW5nT3BlcmF0aW9uLnN1bW1hcnk7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLm5vdGVzKSB7XG4gICAgICBvcGVyYXRpb24uZGVzY3JpcHRpb24gPSBleGlzdGluZ09wZXJhdGlvbi5ub3RlcztcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24ubmlja25hbWUpIHtcbiAgICAgIG9wZXJhdGlvbi5vcGVyYXRpb25JZCA9IGV4aXN0aW5nT3BlcmF0aW9uLm5pY2tuYW1lO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5kZXByZWNhdGVkKSB7XG4gICAgICBvcGVyYXRpb24uZGVwcmVjYXRlZCA9IGV4aXN0aW5nT3BlcmF0aW9uLmRlcHJlY2F0ZWQ7XG4gICAgfVxuXG4gICAgdGhpcy5hdXRob3JpemF0aW9ucyhleGlzdGluZ0F1dGhvcml6YXRpb25zLCBzd2FnZ2VyKTtcbiAgICB0aGlzLnBhcmFtZXRlcnMob3BlcmF0aW9uLCBleGlzdGluZ09wZXJhdGlvbi5wYXJhbWV0ZXJzLCBzd2FnZ2VyKTtcbiAgICB0aGlzLnJlc3BvbnNlTWVzc2FnZXMob3BlcmF0aW9uLCBleGlzdGluZ09wZXJhdGlvbiwgc3dhZ2dlcik7XG5cbiAgICBwYXRoT2JqW21ldGhvZF0gPSBvcGVyYXRpb247XG4gIH1cblxuICBzd2FnZ2VyLnBhdGhzW3BhdGhdID0gcGF0aE9iajtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5yZXNwb25zZU1lc3NhZ2VzID0gZnVuY3Rpb24ob3BlcmF0aW9uLCBleGlzdGluZ09wZXJhdGlvbikge1xuICBpZighXy5pc09iamVjdChleGlzdGluZ09wZXJhdGlvbikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gYnVpbGQgZGVmYXVsdCByZXNwb25zZSBmcm9tIHRoZSBvcGVyYXRpb24gKDEueClcbiAgdmFyIGRlZmF1bHRSZXNwb25zZSA9IHt9O1xuICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nT3BlcmF0aW9uLCBkZWZhdWx0UmVzcG9uc2UpO1xuICAvLyBUT0RPOiBsb29rIGludG8gdGhlIHJlYWwgcHJvYmxlbSBvZiByZW5kZXJpbmcgcmVzcG9uc2VzIGluIHN3YWdnZXItdWlcbiAgLy8gLi4uLnNob3VsZCByZXBvbnNlVHlwZSBoYXZlIGFuIGltcGxpY2l0IHNjaGVtYT9cbiAgaWYoIWRlZmF1bHRSZXNwb25zZS5zY2hlbWEgJiYgZGVmYXVsdFJlc3BvbnNlLnR5cGUpIHtcbiAgICBkZWZhdWx0UmVzcG9uc2UgPSB7c2NoZW1hOiBkZWZhdWx0UmVzcG9uc2V9O1xuICB9XG5cbiAgb3BlcmF0aW9uLnJlc3BvbnNlcyA9IG9wZXJhdGlvbi5yZXNwb25zZXMgfHwge307XG5cbiAgLy8gZ3JhYiBmcm9tIHJlc3BvbnNlTWVzc2FnZXMgKDEuMilcbiAgdmFyIGhhczIwMCA9IGZhbHNlO1xuICBpZihBcnJheS5pc0FycmF5KGV4aXN0aW5nT3BlcmF0aW9uLnJlc3BvbnNlTWVzc2FnZXMpKSB7XG4gICAgdmFyIGk7XG4gICAgdmFyIGV4aXN0aW5nUmVzcG9uc2VzID0gZXhpc3RpbmdPcGVyYXRpb24ucmVzcG9uc2VNZXNzYWdlcztcbiAgICBmb3IoaSA9IDA7IGkgPCBleGlzdGluZ1Jlc3BvbnNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGV4aXN0aW5nUmVzcG9uc2UgPSBleGlzdGluZ1Jlc3BvbnNlc1tpXTtcbiAgICAgIHZhciByZXNwb25zZSA9IHsgZGVzY3JpcHRpb246IGV4aXN0aW5nUmVzcG9uc2UubWVzc2FnZSB9O1xuICAgICAgaWYoZXhpc3RpbmdSZXNwb25zZS5jb2RlID09PSAyMDApIHtcbiAgICAgICAgaGFzMjAwID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2VNb2RlbCAtPiBzY2hlbWF7JHJlZjogcmVzcG9uc2VNb2RlbH1cbiAgICAgIGlmKGV4aXN0aW5nUmVzcG9uc2UucmVzcG9uc2VNb2RlbCkge1xuICAgICAgICByZXNwb25zZS5zY2hlbWEgPSB7JyRyZWYnOiAnIy9kZWZpbml0aW9ucy8nICsgZXhpc3RpbmdSZXNwb25zZS5yZXNwb25zZU1vZGVsfTtcbiAgICAgIH1cbiAgICAgIG9wZXJhdGlvbi5yZXNwb25zZXNbJycgKyBleGlzdGluZ1Jlc3BvbnNlLmNvZGVdID0gcmVzcG9uc2U7XG4gICAgfVxuICB9XG5cbiAgaWYoaGFzMjAwKSB7XG4gICAgb3BlcmF0aW9uLnJlc3BvbnNlc1snZGVmYXVsdCddID0gZGVmYXVsdFJlc3BvbnNlO1xuICB9XG4gIGVsc2Uge1xuICAgIG9wZXJhdGlvbi5yZXNwb25zZXNbJzIwMCddID0gZGVmYXVsdFJlc3BvbnNlO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuYXV0aG9yaXphdGlvbnMgPSBmdW5jdGlvbihvYmopIHtcbiAgLy8gVE9ET1xuICBpZighXy5pc09iamVjdChvYmopKSB7XG4gICAgcmV0dXJuO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUucGFyYW1ldGVycyA9IGZ1bmN0aW9uKG9wZXJhdGlvbiwgb2JqKSB7XG4gIGlmKCFBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGk7XG4gIGZvcihpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgIHZhciBleGlzdGluZ1BhcmFtZXRlciA9IG9ialtpXTtcbiAgICB2YXIgcGFyYW1ldGVyID0ge307XG4gICAgcGFyYW1ldGVyLm5hbWUgPSBleGlzdGluZ1BhcmFtZXRlci5uYW1lO1xuICAgIHBhcmFtZXRlci5kZXNjcmlwdGlvbiA9IGV4aXN0aW5nUGFyYW1ldGVyLmRlc2NyaXB0aW9uO1xuICAgIHBhcmFtZXRlci5yZXF1aXJlZCA9IGV4aXN0aW5nUGFyYW1ldGVyLnJlcXVpcmVkO1xuICAgIHBhcmFtZXRlci5pbiA9IGV4aXN0aW5nUGFyYW1ldGVyLnBhcmFtVHlwZTtcblxuICAgIC8vIHBlciAjMTY4XG4gICAgaWYocGFyYW1ldGVyLmluID09PSAnYm9keScpIHtcbiAgICAgIHBhcmFtZXRlci5uYW1lID0gJ2JvZHknO1xuICAgIH1cbiAgICBpZihwYXJhbWV0ZXIuaW4gPT09ICdmb3JtJykge1xuICAgICAgcGFyYW1ldGVyLmluID0gJ2Zvcm1EYXRhJztcbiAgICB9XG5cbiAgICBpZihleGlzdGluZ1BhcmFtZXRlci5lbnVtKSB7XG4gICAgICBwYXJhbWV0ZXIuZW51bSA9IGV4aXN0aW5nUGFyYW1ldGVyLmVudW07XG4gICAgfVxuXG4gICAgaWYoZXhpc3RpbmdQYXJhbWV0ZXIuYWxsb3dNdWx0aXBsZSA9PT0gdHJ1ZSB8fCBleGlzdGluZ1BhcmFtZXRlci5hbGxvd011bHRpcGxlID09PSAndHJ1ZScpIHtcbiAgICAgIHZhciBpbm5lclR5cGUgPSB7fTtcbiAgICAgIHRoaXMuZGF0YVR5cGUoZXhpc3RpbmdQYXJhbWV0ZXIsIGlubmVyVHlwZSk7XG4gICAgICBwYXJhbWV0ZXIudHlwZSA9ICdhcnJheSc7XG4gICAgICBwYXJhbWV0ZXIuaXRlbXMgPSBpbm5lclR5cGU7XG5cbiAgICAgIGlmKGV4aXN0aW5nUGFyYW1ldGVyLmFsbG93YWJsZVZhbHVlcykge1xuICAgICAgICB2YXIgYXYgPSBleGlzdGluZ1BhcmFtZXRlci5hbGxvd2FibGVWYWx1ZXM7XG4gICAgICAgIGlmKGF2LnZhbHVlVHlwZSA9PT0gJ0xJU1QnKSB7XG4gICAgICAgICAgcGFyYW1ldGVyWydlbnVtJ10gPSBhdi52YWx1ZXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nUGFyYW1ldGVyLCBwYXJhbWV0ZXIpO1xuICAgIH1cbiAgICBpZih0eXBlb2YgZXhpc3RpbmdQYXJhbWV0ZXIuZGVmYXVsdFZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcGFyYW1ldGVyLmRlZmF1bHQgPSBleGlzdGluZ1BhcmFtZXRlci5kZWZhdWx0VmFsdWU7XG4gICAgfVxuXG4gICAgb3BlcmF0aW9uLnBhcmFtZXRlcnMgPSBvcGVyYXRpb24ucGFyYW1ldGVycyB8fCBbXTtcbiAgICBvcGVyYXRpb24ucGFyYW1ldGVycy5wdXNoKHBhcmFtZXRlcik7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5kYXRhVHlwZSA9IGZ1bmN0aW9uKHNvdXJjZSwgdGFyZ2V0KSB7XG4gIGlmKCFfLmlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZihzb3VyY2UubWluaW11bSkge1xuICAgIHRhcmdldC5taW5pbXVtID0gc291cmNlLm1pbmltdW07XG4gIH1cbiAgaWYoc291cmNlLm1heGltdW0pIHtcbiAgICB0YXJnZXQubWF4aW11bSA9IHNvdXJjZS5tYXhpbXVtO1xuICB9XG4gIGlmIChzb3VyY2UuZm9ybWF0KSB7XG4gICAgdGFyZ2V0LmZvcm1hdCA9IHNvdXJjZS5mb3JtYXQ7XG4gIH1cblxuICAvLyBkZWZhdWx0IGNhbiBiZSAnZmFsc2UnXG4gIGlmKHR5cGVvZiBzb3VyY2UuZGVmYXVsdFZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRhcmdldC5kZWZhdWx0ID0gc291cmNlLmRlZmF1bHRWYWx1ZTtcbiAgfVxuXG4gIHZhciBqc29uU2NoZW1hVHlwZSA9IHRoaXMudG9Kc29uU2NoZW1hKHNvdXJjZSk7XG4gIGlmKGpzb25TY2hlbWFUeXBlKSB7XG4gICAgdGFyZ2V0ID0gdGFyZ2V0IHx8IHt9O1xuICAgIGlmKGpzb25TY2hlbWFUeXBlLnR5cGUpIHtcbiAgICAgIHRhcmdldC50eXBlID0ganNvblNjaGVtYVR5cGUudHlwZTtcbiAgICB9XG4gICAgaWYoanNvblNjaGVtYVR5cGUuZm9ybWF0KSB7XG4gICAgICB0YXJnZXQuZm9ybWF0ID0ganNvblNjaGVtYVR5cGUuZm9ybWF0O1xuICAgIH1cbiAgICBpZihqc29uU2NoZW1hVHlwZS4kcmVmKSB7XG4gICAgICB0YXJnZXQuc2NoZW1hID0geyRyZWY6IGpzb25TY2hlbWFUeXBlLiRyZWZ9O1xuICAgIH1cbiAgICBpZihqc29uU2NoZW1hVHlwZS5pdGVtcykge1xuICAgICAgdGFyZ2V0Lml0ZW1zID0ganNvblNjaGVtYVR5cGUuaXRlbXM7XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUudG9Kc29uU2NoZW1hID0gZnVuY3Rpb24oc291cmNlKSB7XG4gIGlmKCFzb3VyY2UpIHtcbiAgICByZXR1cm4gJ29iamVjdCc7XG4gIH1cbiAgdmFyIGRldGVjdGVkVHlwZSA9IChzb3VyY2UudHlwZSB8fCBzb3VyY2UuZGF0YVR5cGUgfHwgc291cmNlLnJlc3BvbnNlQ2xhc3MgfHwgJycpO1xuICB2YXIgbGNUeXBlID0gZGV0ZWN0ZWRUeXBlLnRvTG93ZXJDYXNlKCk7XG4gIHZhciBmb3JtYXQgPSAoc291cmNlLmZvcm1hdCB8fCAnJykudG9Mb3dlckNhc2UoKTtcblxuICBpZihsY1R5cGUuaW5kZXhPZignbGlzdFsnKSA9PT0gMCkge1xuICAgIHZhciBpbm5lclR5cGUgPSBkZXRlY3RlZFR5cGUuc3Vic3RyaW5nKDUsIGRldGVjdGVkVHlwZS5sZW5ndGggLSAxKTtcbiAgICB2YXIganNvblR5cGUgPSB0aGlzLnRvSnNvblNjaGVtYSh7dHlwZTogaW5uZXJUeXBlfSk7XG4gICAgcmV0dXJuIHt0eXBlOiAnYXJyYXknLCBpdGVtczoganNvblR5cGV9O1xuICB9IGVsc2UgaWYobGNUeXBlID09PSAnaW50JyB8fCAobGNUeXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50MzInKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdpbnRlZ2VyJywgZm9ybWF0OiAnaW50MzInfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdsb25nJyB8fCAobGNUeXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50NjQnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdpbnRlZ2VyJywgZm9ybWF0OiAnaW50NjQnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdpbnRlZ2VyJywgZm9ybWF0OiAnaW50NjQnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdmbG9hdCcgfHwgKGxjVHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdudW1iZXInLCBmb3JtYXQ6ICdmbG9hdCd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2RvdWJsZScgfHwgKGxjVHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZG91YmxlJykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnbnVtYmVyJywgZm9ybWF0OiAnZG91YmxlJ307fVxuICB9IGVsc2UgaWYoKGxjVHlwZSA9PT0gJ3N0cmluZycgJiYgZm9ybWF0ID09PSAnZGF0ZS10aW1lJykgfHwgKGxjVHlwZSA9PT0gJ2RhdGUnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdzdHJpbmcnLCBmb3JtYXQ6ICdkYXRlLXRpbWUnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAge3JldHVybiB7dHlwZTogJ3N0cmluZyd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2ZpbGUnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdib29sZWFuJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdib29sZWFuJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnYm9vbGVhbid9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2FycmF5JyB8fCBsY1R5cGUgPT09ICdsaXN0Jykge1xuICAgIGlmKHNvdXJjZS5pdGVtcykge1xuICAgICAgdmFyIGl0ID0gdGhpcy50b0pzb25TY2hlbWEoc291cmNlLml0ZW1zKTtcbiAgICAgIHJldHVybiB7dHlwZTogJ2FycmF5JywgaXRlbXM6IGl0fTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXR1cm4ge3R5cGU6ICdhcnJheScsIGl0ZW1zOiB7dHlwZTogJ29iamVjdCd9fTtcbiAgICB9XG4gIH0gZWxzZSBpZihzb3VyY2UuJHJlZikge1xuICAgIHJldHVybiB7JHJlZjogdGhpcy5tb2RlbE1hcFtzb3VyY2UuJHJlZl0gPyAnIy9kZWZpbml0aW9ucy8nICsgdGhpcy5tb2RlbE1hcFtzb3VyY2UuJHJlZl0gOiBzb3VyY2UuJHJlZn07XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICd2b2lkJyB8fCBsY1R5cGUgPT09ICcnKSB7XG4gICAge3JldHVybiB7fTt9XG4gIH0gZWxzZSBpZiAodGhpcy5tb2RlbE1hcFtzb3VyY2UudHlwZV0pIHtcbiAgICAvLyBJZiB0aGlzIGEgbW9kZWwgdXNpbmcgYHR5cGVgIGluc3RlYWQgb2YgYCRyZWZgLCB0aGF0J3MgZmluZS5cbiAgICByZXR1cm4geyRyZWY6ICcjL2RlZmluaXRpb25zLycgKyB0aGlzLm1vZGVsTWFwW3NvdXJjZS50eXBlXX07XG4gIH0gZWxzZSB7XG4gICAgLy8gVW5rbm93biBtb2RlbCB0eXBlIG9yICdvYmplY3QnLCBwYXNzIGl0IGFsb25nLlxuICAgIHJldHVybiB7dHlwZTogc291cmNlLnR5cGV9O1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUucmVzb3VyY2VMaXN0aW5nID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyLCBvcHRzLCBjYWxsYmFjaykge1xuICB2YXIgaTtcbiAgdmFyIHByb2Nlc3NlZENvdW50ID0gMDsgICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgdmFyIHNlbGYgPSB0aGlzOyAgICAgICAgICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgdmFyIGV4cGVjdGVkQ291bnQgPSBvYmouYXBpcy5sZW5ndGg7XG4gIHZhciBfc3dhZ2dlciA9IHN3YWdnZXI7ICAgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gIHZhciBfb3B0cyA9IHt9O1xuXG4gIGlmKG9wdHMgJiYgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3Ipe1xuICAgIF9vcHRzLnJlcXVlc3RJbnRlcmNlcHRvciA9IG9wdHMucmVxdWVzdEludGVyY2VwdG9yO1xuICB9XG5cbiAgaWYob3B0cyAmJiBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3Ipe1xuICAgIF9vcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IgPSBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3I7XG4gIH1cblxuICB2YXIgc3dhZ2dlclJlcXVlc3RIZWFkZXJzID0gJ2FwcGxpY2F0aW9uL2pzb24nO1xuXG4gIGlmKG9wdHMgJiYgb3B0cy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnMpIHtcbiAgICBzd2FnZ2VyUmVxdWVzdEhlYWRlcnMgPSBvcHRzLnN3YWdnZXJSZXF1ZXN0SGVhZGVycztcbiAgfVxuXG4gIGlmKGV4cGVjdGVkQ291bnQgPT09IDApIHtcbiAgICB0aGlzLmZpbmlzaChjYWxsYmFjaywgc3dhZ2dlcik7XG4gIH1cblxuICBmb3IoaSA9IDA7IGkgPCBleHBlY3RlZENvdW50OyBpKyspIHtcbiAgICB2YXIgYXBpID0gb2JqLmFwaXNbaV07XG4gICAgdmFyIHBhdGggPSBhcGkucGF0aDtcbiAgICB2YXIgYWJzb2x1dGVQYXRoID0gdGhpcy5nZXRBYnNvbHV0ZVBhdGgob2JqLnN3YWdnZXJWZXJzaW9uLCB0aGlzLmRvY0xvY2F0aW9uLCBwYXRoKTtcblxuICAgIGlmKGFwaS5kZXNjcmlwdGlvbikge1xuICAgICAgc3dhZ2dlci50YWdzID0gc3dhZ2dlci50YWdzIHx8IFtdO1xuICAgICAgc3dhZ2dlci50YWdzLnB1c2goe1xuICAgICAgICBuYW1lIDogdGhpcy5leHRyYWN0VGFnKGFwaS5wYXRoKSxcbiAgICAgICAgZGVzY3JpcHRpb24gOiBhcGkuZGVzY3JpcHRpb24gfHwgJydcbiAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgaHR0cCA9IHtcbiAgICAgIHVybDogYWJzb2x1dGVQYXRoLFxuICAgICAgaGVhZGVyczogeyBhY2NlcHQ6IHN3YWdnZXJSZXF1ZXN0SGVhZGVycyB9LFxuICAgICAgb246IHt9LFxuICAgICAgbWV0aG9kOiAnZ2V0JyxcbiAgICAgIHRpbWVvdXQ6IG9wdHMudGltZW91dFxuICAgIH07XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIGh0dHAub24ucmVzcG9uc2UgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgICBwcm9jZXNzZWRDb3VudCArPSAxO1xuICAgICAgdmFyIG9iaiA9IGRhdGEub2JqO1xuICAgICAgaWYob2JqKSB7XG4gICAgICAgIHNlbGYuZGVjbGFyYXRpb24ob2JqLCBfc3dhZ2dlcik7XG4gICAgICB9XG4gICAgICBpZihwcm9jZXNzZWRDb3VudCA9PT0gZXhwZWN0ZWRDb3VudCkge1xuICAgICAgICBzZWxmLmZpbmlzaChjYWxsYmFjaywgX3N3YWdnZXIpO1xuICAgICAgfVxuICAgIH07XG4gICAgaHR0cC5vbi5lcnJvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICBwcm9jZXNzZWRDb3VudCArPSAxO1xuICAgICAgaWYocHJvY2Vzc2VkQ291bnQgPT09IGV4cGVjdGVkQ291bnQpIHtcbiAgICAgICAgc2VsZi5maW5pc2goY2FsbGJhY2ssIF9zd2FnZ2VyKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG5cbiAgICBpZih0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zICYmIHR5cGVvZiB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KGh0dHApO1xuICAgIH1cblxuICAgIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUoaHR0cCwgX29wdHMpO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZ2V0QWJzb2x1dGVQYXRoID0gZnVuY3Rpb24odmVyc2lvbiwgZG9jTG9jYXRpb24sIHBhdGgpICB7XG4gIGlmKHZlcnNpb24gPT09ICcxLjAnKSB7XG4gICAgaWYoZG9jTG9jYXRpb24uZW5kc1dpdGgoJy5qc29uJykpIHtcbiAgICAgIC8vIGdldCByb290IHBhdGhcbiAgICAgIHZhciBwb3MgPSBkb2NMb2NhdGlvbi5sYXN0SW5kZXhPZignLycpO1xuICAgICAgaWYocG9zID4gMCkge1xuICAgICAgICBkb2NMb2NhdGlvbiA9IGRvY0xvY2F0aW9uLnN1YnN0cmluZygwLCBwb3MpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBsb2NhdGlvbiA9IGRvY0xvY2F0aW9uO1xuICBpZihwYXRoLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcGF0aC5pbmRleE9mKCdodHRwczonKSA9PT0gMCkge1xuICAgIGxvY2F0aW9uID0gcGF0aDtcbiAgfVxuICBlbHNlIHtcbiAgICBpZihkb2NMb2NhdGlvbi5lbmRzV2l0aCgnLycpKSB7XG4gICAgICBsb2NhdGlvbiA9IGRvY0xvY2F0aW9uLnN1YnN0cmluZygwLCBkb2NMb2NhdGlvbi5sZW5ndGggLSAxKTtcbiAgICB9XG4gICAgbG9jYXRpb24gKz0gcGF0aDtcbiAgfVxuICBsb2NhdGlvbiA9IGxvY2F0aW9uLnJlcGxhY2UoJ3tmb3JtYXR9JywgJ2pzb24nKTtcbiAgcmV0dXJuIGxvY2F0aW9uO1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSBmdW5jdGlvbihvYmosIHN3YWdnZXIpIHtcbiAgaWYob2JqLmF1dGhvcml6YXRpb25zKSB7XG4gICAgdmFyIG5hbWU7XG4gICAgZm9yKG5hbWUgaW4gb2JqLmF1dGhvcml6YXRpb25zKSB7XG4gICAgICB2YXIgaXNWYWxpZCA9IGZhbHNlO1xuICAgICAgdmFyIHNlY3VyaXR5RGVmaW5pdGlvbiA9IHtcbiAgICAgICAgdmVuZG9yRXh0ZW5zaW9uczoge31cbiAgICAgIH07XG4gICAgICB2YXIgZGVmaW5pdGlvbiA9IG9iai5hdXRob3JpemF0aW9uc1tuYW1lXTtcbiAgICAgIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ2FwaUtleScpIHtcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnR5cGUgPSAnYXBpS2V5JztcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmluID0gZGVmaW5pdGlvbi5wYXNzQXM7XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5uYW1lID0gZGVmaW5pdGlvbi5rZXluYW1lIHx8IG5hbWU7XG4gICAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgZWxzZSBpZihkZWZpbml0aW9uLnR5cGUgPT09ICdiYXNpY0F1dGgnKSB7XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi50eXBlID0gJ2Jhc2ljQXV0aCc7XG4gICAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgZWxzZSBpZihkZWZpbml0aW9uLnR5cGUgPT09ICdvYXV0aDInKSB7XG4gICAgICAgIHZhciBleGlzdGluZ1Njb3BlcyA9IGRlZmluaXRpb24uc2NvcGVzIHx8IFtdO1xuICAgICAgICB2YXIgc2NvcGVzID0ge307XG4gICAgICAgIHZhciBpO1xuICAgICAgICBmb3IoaSBpbiBleGlzdGluZ1Njb3Blcykge1xuICAgICAgICAgIHZhciBzY29wZSA9IGV4aXN0aW5nU2NvcGVzW2ldO1xuICAgICAgICAgIHNjb3Blc1tzY29wZS5zY29wZV0gPSBzY29wZS5kZXNjcmlwdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBzZWN1cml0eURlZmluaXRpb24udHlwZSA9ICdvYXV0aDInO1xuICAgICAgICBpZihpID4gMCkge1xuICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5zY29wZXMgPSBzY29wZXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYoZGVmaW5pdGlvbi5ncmFudFR5cGVzKSB7XG4gICAgICAgICAgaWYoZGVmaW5pdGlvbi5ncmFudFR5cGVzLmltcGxpY2l0KSB7XG4gICAgICAgICAgICB2YXIgaW1wbGljaXQgPSBkZWZpbml0aW9uLmdyYW50VHlwZXMuaW1wbGljaXQ7XG4gICAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24uZmxvdyA9ICdpbXBsaWNpdCc7XG4gICAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24uYXV0aG9yaXphdGlvblVybCA9IGltcGxpY2l0LmxvZ2luRW5kcG9pbnQ7XG4gICAgICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgICAgICAgIGlmKGRlZmluaXRpb24uZ3JhbnRUeXBlc1snYXV0aG9yaXphdGlvbl9jb2RlJ10pIHtcbiAgICAgICAgICAgIGlmKCFzZWN1cml0eURlZmluaXRpb24uZmxvdykge1xuICAgICAgICAgICAgICAvLyBjYW5ub3Qgc2V0IGlmIGZsb3cgaXMgYWxyZWFkeSBkZWZpbmVkXG4gICAgICAgICAgICAgIHZhciBhdXRoQ29kZSA9IGRlZmluaXRpb24uZ3JhbnRUeXBlc1snYXV0aG9yaXphdGlvbl9jb2RlJ107XG4gICAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5mbG93ID0gJ2FjY2Vzc0NvZGUnO1xuICAgICAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24uYXV0aG9yaXphdGlvblVybCA9IGF1dGhDb2RlLnRva2VuUmVxdWVzdEVuZHBvaW50LnVybDtcbiAgICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnRva2VuVXJsID0gYXV0aENvZGUudG9rZW5FbmRwb2ludC51cmw7XG4gICAgICAgICAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZihpc1ZhbGlkKSB7XG4gICAgICAgIHN3YWdnZXIuc2VjdXJpdHlEZWZpbml0aW9ucyA9IHN3YWdnZXIuc2VjdXJpdHlEZWZpbml0aW9ucyB8fCB7fTtcbiAgICAgICAgc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zW25hbWVdID0gc2VjdXJpdHlEZWZpbml0aW9uO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmFwaUluZm8gPSBmdW5jdGlvbihvYmosIHN3YWdnZXIpIHtcbiAgLy8gaW5mbyBzZWN0aW9uXG4gIGlmKG9iai5pbmZvKSB7XG4gICAgdmFyIGluZm8gPSBvYmouaW5mbztcbiAgICBzd2FnZ2VyLmluZm8gPSB7fTtcblxuICAgIGlmKGluZm8uY29udGFjdCkge1xuICAgICAgc3dhZ2dlci5pbmZvLmNvbnRhY3QgPSB7fTtcbiAgICAgIHN3YWdnZXIuaW5mby5jb250YWN0LmVtYWlsID0gaW5mby5jb250YWN0O1xuICAgIH1cbiAgICBpZihpbmZvLmRlc2NyaXB0aW9uKSB7XG4gICAgICBzd2FnZ2VyLmluZm8uZGVzY3JpcHRpb24gPSBpbmZvLmRlc2NyaXB0aW9uO1xuICAgIH1cbiAgICBpZihpbmZvLnRpdGxlKSB7XG4gICAgICBzd2FnZ2VyLmluZm8udGl0bGUgPSBpbmZvLnRpdGxlO1xuICAgIH1cbiAgICBpZihpbmZvLnRlcm1zT2ZTZXJ2aWNlVXJsKSB7XG4gICAgICBzd2FnZ2VyLmluZm8udGVybXNPZlNlcnZpY2UgPSBpbmZvLnRlcm1zT2ZTZXJ2aWNlVXJsO1xuICAgIH1cbiAgICBpZihpbmZvLmxpY2Vuc2UgfHwgaW5mby5saWNlbnNlVXJsKSB7XG4gICAgICBzd2FnZ2VyLmxpY2Vuc2UgPSB7fTtcbiAgICAgIGlmKGluZm8ubGljZW5zZSkge1xuICAgICAgICBzd2FnZ2VyLmxpY2Vuc2UubmFtZSA9IGluZm8ubGljZW5zZTtcbiAgICAgIH1cbiAgICAgIGlmKGluZm8ubGljZW5zZVVybCkge1xuICAgICAgICBzd2FnZ2VyLmxpY2Vuc2UudXJsID0gaW5mby5saWNlbnNlVXJsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLndhcm5pbmdzLnB1c2goJ21pc3NpbmcgaW5mbyBzZWN0aW9uJyk7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbiAoY2FsbGJhY2ssIG9iaikge1xuICBjYWxsYmFjayhvYmopO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGxvZyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMnKS5sb2c7XG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaXNTdHJpbmc6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1N0cmluZycpLFxufTtcblxudmFyIFNjaGVtYU1hcmt1cCA9IHJlcXVpcmUoJy4uL3NjaGVtYS1tYXJrdXAuanMnKTtcbnZhciBqc3lhbWwgPSByZXF1aXJlKCdqcy15YW1sJyk7XG5cbnZhciBNb2RlbCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG5hbWUsIGRlZmluaXRpb24sIG1vZGVscywgbW9kZWxQcm9wZXJ0eU1hY3JvKSB7XG4gIHRoaXMuZGVmaW5pdGlvbiA9IGRlZmluaXRpb24gfHwge307XG4gIHRoaXMuaXNBcnJheSA9IGRlZmluaXRpb24udHlwZSA9PT0gJ2FycmF5JztcbiAgdGhpcy5tb2RlbHMgPSBtb2RlbHMgfHwge307XG4gIHRoaXMubmFtZSA9IG5hbWUgfHwgZGVmaW5pdGlvbi50aXRsZSB8fCAnSW5saW5lIE1vZGVsJztcbiAgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8gPSBtb2RlbFByb3BlcnR5TWFjcm8gfHwgZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgcmV0dXJuIHByb3BlcnR5LmRlZmF1bHQ7XG4gIH07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBOb3RlISAgVGhpcyBmdW5jdGlvbiB3aWxsIGJlIHJlbW92ZWQgaW4gMi4yLnghXG5Nb2RlbC5wcm90b3R5cGUuY3JlYXRlSlNPTlNhbXBsZSA9IE1vZGVsLnByb3RvdHlwZS5nZXRTYW1wbGVWYWx1ZSA9IGZ1bmN0aW9uIChtb2RlbHNUb0lnbm9yZSkge1xuICBtb2RlbHNUb0lnbm9yZSA9IG1vZGVsc1RvSWdub3JlIHx8IHt9O1xuXG4gIG1vZGVsc1RvSWdub3JlW3RoaXMubmFtZV0gPSB0aGlzO1xuXG4gIC8vIFJlc3BvbnNlIHN1cHBvcnRcbiAgaWYgKHRoaXMuZXhhbXBsZXMgJiYgXy5pc1BsYWluT2JqZWN0KHRoaXMuZXhhbXBsZXMpICYmIHRoaXMuZXhhbXBsZXNbJ2FwcGxpY2F0aW9uL2pzb24nXSkge1xuICAgIHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlID0gdGhpcy5leGFtcGxlc1snYXBwbGljYXRpb24vanNvbiddO1xuXG4gICAgaWYgKF8uaXNTdHJpbmcodGhpcy5kZWZpbml0aW9uLmV4YW1wbGUpKSB7XG4gICAgICB0aGlzLmRlZmluaXRpb24uZXhhbXBsZSA9IGpzeWFtbC5zYWZlTG9hZCh0aGlzLmRlZmluaXRpb24uZXhhbXBsZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCF0aGlzLmRlZmluaXRpb24uZXhhbXBsZSkge1xuICAgIHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlID0gdGhpcy5leGFtcGxlcztcbiAgfVxuXG4gIHJldHVybiBTY2hlbWFNYXJrdXAuc2NoZW1hVG9KU09OKHRoaXMuZGVmaW5pdGlvbiwgdGhpcy5tb2RlbHMsIG1vZGVsc1RvSWdub3JlLCB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyk7XG59O1xuXG5Nb2RlbC5wcm90b3R5cGUuZ2V0TW9ja1NpZ25hdHVyZSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIFNjaGVtYU1hcmt1cC5zY2hlbWFUb0hUTUwodGhpcy5uYW1lLCB0aGlzLmRlZmluaXRpb24sIHRoaXMubW9kZWxzLCB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHtcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGlzVW5kZWZpbmVkOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNVbmRlZmluZWQnKSxcbiAgaXNFbXB0eTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzRW1wdHknKSxcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpXG59O1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzJyk7XG52YXIgTW9kZWwgPSByZXF1aXJlKCcuL21vZGVsJyk7XG52YXIgU3dhZ2dlckh0dHAgPSByZXF1aXJlKCcuLi9odHRwJyk7XG52YXIgUSA9IHJlcXVpcmUoJ3EnKTtcblxudmFyIE9wZXJhdGlvbiA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHBhcmVudCwgc2NoZW1lLCBvcGVyYXRpb25JZCwgaHR0cE1ldGhvZCwgcGF0aCwgYXJncywgZGVmaW5pdGlvbnMsIG1vZGVscywgY2xpZW50QXV0aG9yaXphdGlvbnMpIHtcbiAgdmFyIGVycm9ycyA9IFtdO1xuXG4gIHBhcmVudCA9IHBhcmVudCB8fCB7fTtcbiAgYXJncyA9IGFyZ3MgfHwge307XG5cbiAgaWYocGFyZW50ICYmIHBhcmVudC5vcHRpb25zKSB7XG4gICAgdGhpcy5jbGllbnQgPSBwYXJlbnQub3B0aW9ucy5jbGllbnQgfHwgbnVsbDtcbiAgICB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvciA9IHBhcmVudC5vcHRpb25zLnJlcXVlc3RJbnRlcmNlcHRvciB8fCBudWxsO1xuICAgIHRoaXMucmVzcG9uc2VJbnRlcmNlcHRvciA9IHBhcmVudC5vcHRpb25zLnJlc3BvbnNlSW50ZXJjZXB0b3IgfHwgbnVsbDtcbiAgICB0aGlzLnJlcXVlc3RBZ2VudCA9IHBhcmVudC5vcHRpb25zLnJlcXVlc3RBZ2VudDtcbiAgfVxuICB0aGlzLmF1dGhvcml6YXRpb25zID0gYXJncy5zZWN1cml0eTtcbiAgdGhpcy5iYXNlUGF0aCA9IHBhcmVudC5iYXNlUGF0aCB8fCAnLyc7XG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMgPSBjbGllbnRBdXRob3JpemF0aW9ucztcbiAgdGhpcy5jb25zdW1lcyA9IGFyZ3MuY29uc3VtZXMgfHwgcGFyZW50LmNvbnN1bWVzIHx8IFsnYXBwbGljYXRpb24vanNvbiddO1xuICB0aGlzLnByb2R1Y2VzID0gYXJncy5wcm9kdWNlcyB8fCBwYXJlbnQucHJvZHVjZXMgfHwgWydhcHBsaWNhdGlvbi9qc29uJ107XG4gIHRoaXMuZGVwcmVjYXRlZCA9IGFyZ3MuZGVwcmVjYXRlZDtcbiAgdGhpcy5kZXNjcmlwdGlvbiA9IGFyZ3MuZGVzY3JpcHRpb247XG4gIHRoaXMuaG9zdCA9IHBhcmVudC5ob3N0O1xuICB0aGlzLm1ldGhvZCA9IChodHRwTWV0aG9kIHx8IGVycm9ycy5wdXNoKCdPcGVyYXRpb24gJyArIG9wZXJhdGlvbklkICsgJyBpcyBtaXNzaW5nIG1ldGhvZC4nKSk7XG4gIHRoaXMubW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuICB0aGlzLm5pY2tuYW1lID0gKG9wZXJhdGlvbklkIHx8IGVycm9ycy5wdXNoKCdPcGVyYXRpb25zIG11c3QgaGF2ZSBhIG5pY2tuYW1lLicpKTtcbiAgdGhpcy5vcGVyYXRpb24gPSBhcmdzO1xuICB0aGlzLm9wZXJhdGlvbnMgPSB7fTtcbiAgdGhpcy5wYXJhbWV0ZXJzID0gYXJncyAhPT0gbnVsbCA/IChhcmdzLnBhcmFtZXRlcnMgfHwgW10pIDoge307XG4gIHRoaXMucGFyZW50ID0gcGFyZW50O1xuICB0aGlzLnBhdGggPSAocGF0aCB8fCBlcnJvcnMucHVzaCgnT3BlcmF0aW9uICcgKyB0aGlzLm5pY2tuYW1lICsgJyBpcyBtaXNzaW5nIHBhdGguJykpO1xuICB0aGlzLnJlc3BvbnNlcyA9IChhcmdzLnJlc3BvbnNlcyB8fCB7fSk7XG4gIHRoaXMuc2NoZW1lID0gc2NoZW1lIHx8IHBhcmVudC5zY2hlbWUgfHwgJ2h0dHAnO1xuICB0aGlzLnNjaGVtZXMgPSBhcmdzLnNjaGVtZXMgfHwgcGFyZW50LnNjaGVtZXM7XG4gIHRoaXMuc2VjdXJpdHkgPSBhcmdzLnNlY3VyaXR5IHx8IHBhcmVudC5zZWN1cml0eTtcbiAgdGhpcy5zdW1tYXJ5ID0gYXJncy5zdW1tYXJ5IHx8ICcnO1xuICB0aGlzLnRpbWVvdXQgPSBwYXJlbnQudGltZW91dDtcbiAgdGhpcy50eXBlID0gbnVsbDtcbiAgdGhpcy51c2VKUXVlcnkgPSBwYXJlbnQudXNlSlF1ZXJ5O1xuICB0aGlzLmpxdWVyeUFqYXhDYWNoZSA9IHBhcmVudC5qcXVlcnlBamF4Q2FjaGU7XG4gIHRoaXMuZW5hYmxlQ29va2llcyA9IHBhcmVudC5lbmFibGVDb29raWVzO1xuXG4gIHZhciBrZXk7XG5cbiAgaWYoIXRoaXMuaG9zdCkge1xuICAgIGlmKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLmhvc3QgPSB3aW5kb3cubG9jYXRpb24uaG9zdDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLmhvc3QgPSAnbG9jYWxob3N0JztcbiAgICB9XG4gIH1cbiAgdGhpcy5wYXJhbWV0ZXJNYWNybyA9IHBhcmVudC5wYXJhbWV0ZXJNYWNybyB8fCBmdW5jdGlvbiAob3BlcmF0aW9uLCBwYXJhbWV0ZXIpIHtcbiAgICByZXR1cm4gcGFyYW1ldGVyLmRlZmF1bHQ7XG4gIH07XG5cbiAgdGhpcy5pbmxpbmVNb2RlbHMgPSBbXTtcblxuICBpZih0aGlzLmJhc2VQYXRoICE9PSAnLycgJiYgdGhpcy5iYXNlUGF0aC5zbGljZSgtMSkgPT09ICcvJykge1xuICAgIHRoaXMuYmFzZVBhdGggPSB0aGlzLmJhc2VQYXRoLnNsaWNlKDAsIC0xKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdGhpcy5kZXByZWNhdGVkID09PSAnc3RyaW5nJykge1xuICAgIHN3aXRjaCh0aGlzLmRlcHJlY2F0ZWQudG9Mb3dlckNhc2UoKSkge1xuICAgICAgY2FzZSAndHJ1ZSc6IGNhc2UgJ3llcyc6IGNhc2UgJzEnOiB7XG4gICAgICAgIHRoaXMuZGVwcmVjYXRlZCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdmYWxzZSc6IGNhc2UgJ25vJzogY2FzZSAnMCc6IGNhc2UgbnVsbDoge1xuICAgICAgICB0aGlzLmRlcHJlY2F0ZWQgPSBmYWxzZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGRlZmF1bHQ6IHRoaXMuZGVwcmVjYXRlZCA9IEJvb2xlYW4odGhpcy5kZXByZWNhdGVkKTtcbiAgICB9XG4gIH1cblxuICB2YXIgaSwgbW9kZWw7XG5cbiAgaWYgKGRlZmluaXRpb25zKSB7XG4gICAgLy8gYWRkIHRvIGdsb2JhbCBtb2RlbHNcbiAgICBmb3IgKGtleSBpbiBkZWZpbml0aW9ucykge1xuICAgICAgbW9kZWwgPSBuZXcgTW9kZWwoa2V5LCBkZWZpbml0aW9uc1trZXldLCB0aGlzLm1vZGVscywgcGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG5cbiAgICAgIGlmIChtb2RlbCkge1xuICAgICAgICB0aGlzLm1vZGVsc1trZXldID0gbW9kZWw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGRlZmluaXRpb25zID0ge307XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGQsIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgLy8gQWxsb3cgbWFjcm8gdG8gc2V0IHRoZSBkZWZhdWx0IHZhbHVlXG4gICAgcGFyYW0uZGVmYXVsdCA9IHRoaXMucGFyYW1ldGVyTWFjcm8odGhpcywgcGFyYW0pO1xuXG4gICAgaWYgKHBhcmFtLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIHBhcmFtLmlzTGlzdCA9IHRydWU7XG4gICAgICBwYXJhbS5hbGxvd011bHRpcGxlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgaW5uZXJUeXBlID0gdGhpcy5nZXRUeXBlKHBhcmFtKTtcblxuICAgIGlmIChpbm5lclR5cGUgJiYgaW5uZXJUeXBlLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMgPSB7fTtcbiAgICAgIHBhcmFtLmlzTGlzdCA9IHRydWU7XG4gICAgICBwYXJhbVsnZW51bSddID0gW3RydWUsIGZhbHNlXTsgLy8gdXNlIGFjdHVhbCBwcmltaXRpdmVzXG4gICAgfVxuXG4gICAgZm9yKGtleSBpbiBwYXJhbSkge1xuICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhrZXksIHBhcmFtKTtcbiAgICB9XG4gICAgaWYodHlwZW9mIHBhcmFtWyd4LWV4YW1wbGUnXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGQgPSBwYXJhbVsneC1leGFtcGxlJ107XG4gICAgICBwYXJhbS5kZWZhdWx0ID0gZDtcbiAgICB9XG4gICAgaWYocGFyYW1bJ3gtZXhhbXBsZXMnXSkge1xuICAgICAgZCA9IHBhcmFtWyd4LWV4YW1wbGVzJ10uZGVmYXVsdDtcbiAgICAgIGlmKHR5cGVvZiBkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBwYXJhbS5kZWZhdWx0ID0gZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZW51bVZhbHVlcyA9IHBhcmFtWydlbnVtJ10gfHwgKHBhcmFtLml0ZW1zICYmIHBhcmFtLml0ZW1zWydlbnVtJ10pO1xuXG4gICAgaWYgKHR5cGVvZiBlbnVtVmFsdWVzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIGlkO1xuXG4gICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMgPSB7fTtcbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy52YWx1ZXMgPSBbXTtcbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy5kZXNjcmlwdGl2ZVZhbHVlcyA9IFtdO1xuXG4gICAgICBmb3IgKGlkID0gMDsgaWQgPCBlbnVtVmFsdWVzLmxlbmd0aDsgaWQrKykge1xuICAgICAgICB2YXIgdmFsdWUgPSBlbnVtVmFsdWVzW2lkXTtcbiAgICAgICAgdmFyIGlzRGVmYXVsdCA9ICh2YWx1ZSA9PT0gcGFyYW0uZGVmYXVsdCB8fCB2YWx1ZSsnJyA9PT0gcGFyYW0uZGVmYXVsdCk7XG5cbiAgICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLnZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICAgICAgLy8gQWx3YXlzIGhhdmUgc3RyaW5nIGZvciBkZXNjcmlwdGl2ZSB2YWx1ZXMuLi4uXG4gICAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy5kZXNjcmlwdGl2ZVZhbHVlcy5wdXNoKHt2YWx1ZSA6IHZhbHVlKycnLCBpc0RlZmF1bHQ6IGlzRGVmYXVsdH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwYXJhbS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBpbm5lclR5cGUgPSBbaW5uZXJUeXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBwYXJhbS5hbGxvd2FibGVWYWx1ZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIGNhbid0IHNob3cgYXMgYSBsaXN0IGlmIG5vIHZhbHVlcyB0byBzZWxlY3QgZnJvbVxuICAgICAgICBkZWxldGUgcGFyYW0uaXNMaXN0O1xuICAgICAgICBkZWxldGUgcGFyYW0uYWxsb3dNdWx0aXBsZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYXJhbS5tb2RlbFNpZ25hdHVyZSA9IHt0eXBlOiBpbm5lclR5cGUsIGRlZmluaXRpb25zOiB0aGlzLm1vZGVsc307XG4gICAgcGFyYW0uc2lnbmF0dXJlID0gdGhpcy5nZXRNb2RlbFNpZ25hdHVyZShpbm5lclR5cGUsIHRoaXMubW9kZWxzKS50b1N0cmluZygpO1xuICAgIHBhcmFtLnNhbXBsZUpTT04gPSB0aGlzLmdldE1vZGVsU2FtcGxlSlNPTihpbm5lclR5cGUsIHRoaXMubW9kZWxzKTtcbiAgICBwYXJhbS5yZXNwb25zZUNsYXNzU2lnbmF0dXJlID0gcGFyYW0uc2lnbmF0dXJlO1xuICB9XG5cbiAgdmFyIGtleW5hbWUsIGRlZmF1bHRSZXNwb25zZUNvZGUsIHJlc3BvbnNlLCByZXNwb25zZXMgPSB0aGlzLnJlc3BvbnNlcztcblxuICBpZiAocmVzcG9uc2VzWycyMDAnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDAnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMCc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDEnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDEnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMSc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDInXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDInXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMic7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDMnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDMnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMyc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDQnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDQnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwNCc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDUnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDUnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwNSc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDYnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDYnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwNic7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWydkZWZhdWx0J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snZGVmYXVsdCddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnZGVmYXVsdCc7XG4gIH1cblxuICBmb3Ioa2V5bmFtZSBpbiByZXNwb25zZXMpIHtcbiAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKGtleW5hbWUsIHJlc3BvbnNlcyk7XG4gICAgaWYodHlwZW9mIGtleW5hbWUgPT09ICdzdHJpbmcnICYmIGtleW5hbWUuaW5kZXhPZigneC0nKSA9PT0gLTEpIHtcbiAgICAgIHZhciByZXNwb25zZU9iamVjdCA9IHJlc3BvbnNlc1trZXluYW1lXTtcbiAgICAgIGlmKHR5cGVvZiByZXNwb25zZU9iamVjdCA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHJlc3BvbnNlT2JqZWN0LmhlYWRlcnMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHZhciBoZWFkZXJzID0gcmVzcG9uc2VPYmplY3QuaGVhZGVycztcbiAgICAgICAgZm9yKHZhciBoZWFkZXJOYW1lIGluIGhlYWRlcnMpIHtcbiAgICAgICAgICB2YXIgaGVhZGVyID0gaGVhZGVyc1toZWFkZXJOYW1lXTtcbiAgICAgICAgICBpZih0eXBlb2YgaGVhZGVyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgZm9yKHZhciBoZWFkZXJLZXkgaW4gaGVhZGVyKSB7XG4gICAgICAgICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaGVhZGVyS2V5LCBoZWFkZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChyZXNwb25zZSkge1xuICAgIGZvcihrZXluYW1lIGluIHJlc3BvbnNlKSB7XG4gICAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKGtleW5hbWUsIHJlc3BvbnNlKTtcbiAgICB9XG4gIH1cblxuICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2Uuc2NoZW1hKSB7XG4gICAgdmFyIHJlc29sdmVkTW9kZWwgPSB0aGlzLnJlc29sdmVNb2RlbChyZXNwb25zZS5zY2hlbWEsIGRlZmluaXRpb25zKTtcbiAgICB2YXIgc3VjY2Vzc1Jlc3BvbnNlO1xuXG4gICAgZGVsZXRlIHJlc3BvbnNlc1tkZWZhdWx0UmVzcG9uc2VDb2RlXTtcblxuICAgIGlmIChyZXNvbHZlZE1vZGVsKSB7XG4gICAgICB0aGlzLnN1Y2Nlc3NSZXNwb25zZSA9IHt9O1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5zdWNjZXNzUmVzcG9uc2VbZGVmYXVsdFJlc3BvbnNlQ29kZV0gPSByZXNvbHZlZE1vZGVsO1xuICAgIH0gZWxzZSBpZiAoIXJlc3BvbnNlLnNjaGVtYS50eXBlIHx8IHJlc3BvbnNlLnNjaGVtYS50eXBlID09PSAnb2JqZWN0JyB8fCByZXNwb25zZS5zY2hlbWEudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgLy8gSW5saW5lIG1vZGVsXG4gICAgICB0aGlzLnN1Y2Nlc3NSZXNwb25zZSA9IHt9O1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5zdWNjZXNzUmVzcG9uc2VbZGVmYXVsdFJlc3BvbnNlQ29kZV0gPSBuZXcgTW9kZWwodW5kZWZpbmVkLCByZXNwb25zZS5zY2hlbWEgfHwge30sIHRoaXMubW9kZWxzLCBwYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUHJpbWl0aXZlXG4gICAgICB0aGlzLnN1Y2Nlc3NSZXNwb25zZSA9IHt9O1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5zdWNjZXNzUmVzcG9uc2VbZGVmYXVsdFJlc3BvbnNlQ29kZV0gPSByZXNwb25zZS5zY2hlbWE7XG4gICAgfVxuXG4gICAgaWYgKHN1Y2Nlc3NSZXNwb25zZSkge1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlLnZlbmRvckV4dGVuc2lvbnMgPSByZXNwb25zZS52ZW5kb3JFeHRlbnNpb25zO1xuICAgICAgLy8gQXR0YWNoIHJlc3BvbnNlIHByb3BlcnRpZXNcbiAgICAgIGlmIChyZXNwb25zZS5kZXNjcmlwdGlvbikge1xuICAgICAgICBzdWNjZXNzUmVzcG9uc2UuZGVzY3JpcHRpb24gPSByZXNwb25zZS5kZXNjcmlwdGlvbjtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3BvbnNlLmV4YW1wbGVzKSB7XG4gICAgICAgIHN1Y2Nlc3NSZXNwb25zZS5leGFtcGxlcyA9IHJlc3BvbnNlLmV4YW1wbGVzO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzcG9uc2UuaGVhZGVycykge1xuICAgICAgICBzdWNjZXNzUmVzcG9uc2UuaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy50eXBlID0gcmVzcG9uc2U7XG4gIH1cblxuICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICBpZiAodGhpcy5yZXNvdXJjZSAmJiB0aGlzLnJlc291cmNlLmFwaSAmJiB0aGlzLnJlc291cmNlLmFwaS5mYWlsKSB7XG4gICAgICB0aGlzLnJlc291cmNlLmFwaS5mYWlsKGVycm9ycyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmlzRGVmYXVsdEFycmF5SXRlbVZhbHVlID0gZnVuY3Rpb24odmFsdWUsIHBhcmFtKSB7XG4gIGlmIChwYXJhbS5kZWZhdWx0ICYmIEFycmF5LmlzQXJyYXkocGFyYW0uZGVmYXVsdCkpIHtcbiAgICByZXR1cm4gcGFyYW0uZGVmYXVsdC5pbmRleE9mKHZhbHVlKSAhPT0gLTE7XG4gIH1cbiAgcmV0dXJuIHZhbHVlID09PSBwYXJhbS5kZWZhdWx0O1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKHBhcmFtKSB7XG4gIHZhciB0eXBlID0gcGFyYW0udHlwZTtcbiAgdmFyIGZvcm1hdCA9IHBhcmFtLmZvcm1hdDtcbiAgdmFyIGlzQXJyYXkgPSBmYWxzZTtcbiAgdmFyIHN0cjtcblxuICBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDMyJykge1xuICAgIHN0ciA9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50NjQnKSB7XG4gICAgc3RyID0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgIHN0ciA9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgIGlmIChmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgICBzdHIgPSAnZGF0ZS10aW1lJztcbiAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2RhdGUnKSB7XG4gICAgICBzdHIgPSAnZGF0ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9ICdzdHJpbmcnO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdmbG9hdCcpIHtcbiAgICBzdHIgPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2RvdWJsZScpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgIHN0ciA9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgIHN0ciA9ICdib29sZWFuJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgaXNBcnJheSA9IHRydWU7XG5cbiAgICBpZiAocGFyYW0uaXRlbXMpIHtcbiAgICAgIHN0ciA9IHRoaXMuZ2V0VHlwZShwYXJhbS5pdGVtcyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdmaWxlJykge1xuICAgIHN0ciA9ICdmaWxlJztcbiAgfVxuXG4gIGlmIChwYXJhbS4kcmVmKSB7XG4gICAgc3RyID0gaGVscGVycy5zaW1wbGVSZWYocGFyYW0uJHJlZik7XG4gIH1cblxuICB2YXIgc2NoZW1hID0gcGFyYW0uc2NoZW1hO1xuXG4gIGlmIChzY2hlbWEpIHtcbiAgICB2YXIgcmVmID0gc2NoZW1hLiRyZWY7XG5cbiAgICBpZiAocmVmKSB7XG4gICAgICByZWYgPSBoZWxwZXJzLnNpbXBsZVJlZihyZWYpO1xuXG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICByZXR1cm4gWyByZWYgXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZWY7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIGlubGluZSBzY2hlbWEsIHdlIGFkZCBpdCBvdXIgaW50ZXJhbCBoYXNoIC0+IHdoaWNoIGdpdmVzIHVzIGl0J3MgSUQgKGludClcbiAgICAgIGlmKHNjaGVtYS50eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRJbmxpbmVNb2RlbChzY2hlbWEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZ2V0VHlwZShzY2hlbWEpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNBcnJheSkge1xuICAgIHJldHVybiBbIHN0ciBdO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn07XG5cbi8qKlxuICogYWRkcyBhbiBpbmxpbmUgc2NoZW1hIChtb2RlbCkgdG8gYSBoYXNoLCB3aGVyZSB3ZSBjYW4gcmVmIGl0IGxhdGVyXG4gKiBAcGFyYW0ge29iamVjdH0gc2NoZW1hIGEgc2NoZW1hXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHRoZSBJRCBvZiB0aGUgc2NoZW1hIGJlaW5nIGFkZGVkLCBvciBudWxsXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmFkZElubGluZU1vZGVsID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICB2YXIgbGVuID0gdGhpcy5pbmxpbmVNb2RlbHMubGVuZ3RoO1xuICB2YXIgbW9kZWwgPSB0aGlzLnJlc29sdmVNb2RlbChzY2hlbWEsIHt9KTtcbiAgaWYobW9kZWwpIHtcbiAgICB0aGlzLmlubGluZU1vZGVscy5wdXNoKG1vZGVsKTtcbiAgICByZXR1cm4gJ0lubGluZSBNb2RlbCAnK2xlbjsgLy8gcmV0dXJuIHN0cmluZyByZWYgb2YgdGhlIGlubGluZSBtb2RlbCAodXNlZCB3aXRoICNnZXRJbmxpbmVNb2RlbClcbiAgfVxuICByZXR1cm4gbnVsbDsgLy8gcmVwb3J0IGVycm9ycz9cbn07XG5cbi8qKlxuICogZ2V0cyB0aGUgaW50ZXJuYWwgcmVmIHRvIGFuIGlubGluZSBtb2RlbFxuICogQHBhcmFtIHtzdHJpbmd9IGlubGluZV9zdHIgYSBzdHJpbmcgcmVmZXJlbmNlIHRvIGFuIGlubGluZSBtb2RlbFxuICogQHJldHVybiB7TW9kZWx9IHRoZSBtb2RlbCBiZWluZyByZWZlcmVuY2VkLiBPciBudWxsXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldElubGluZU1vZGVsID0gZnVuY3Rpb24oaW5saW5lU3RyKSB7XG4gIGlmKC9eSW5saW5lIE1vZGVsIFxcZCskLy50ZXN0KGlubGluZVN0cikpIHtcbiAgICB2YXIgaWQgPSBwYXJzZUludChpbmxpbmVTdHIuc3Vic3RyKCdJbmxpbmUgTW9kZWwnLmxlbmd0aCkudHJpbSgpLDEwKTsgLy9cbiAgICB2YXIgbW9kZWwgPSB0aGlzLmlubGluZU1vZGVsc1tpZF07XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG4gIC8vIEknbSByZXR1cm5pbmcgbnVsbCBoZXJlLCBzaG91bGQgSSByYXRoZXIgdGhyb3cgYW4gZXJyb3I/XG4gIHJldHVybiBudWxsO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5yZXNvbHZlTW9kZWwgPSBmdW5jdGlvbiAoc2NoZW1hLCBkZWZpbml0aW9ucykge1xuICBpZiAodHlwZW9mIHNjaGVtYS4kcmVmICE9PSAndW5kZWZpbmVkJykge1xuICAgIHZhciByZWYgPSBzY2hlbWEuJHJlZjtcblxuICAgIGlmIChyZWYuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgICAgcmVmID0gcmVmLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgaWYgKGRlZmluaXRpb25zW3JlZl0pIHtcbiAgICAgIHJldHVybiBuZXcgTW9kZWwocmVmLCBkZWZpbml0aW9uc1tyZWZdLCB0aGlzLm1vZGVscywgdGhpcy5wYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICB9XG4gIC8vIHNjaGVtYSBtdXN0IGF0IGxlYXN0IGJlIGFuIG9iamVjdCB0byBnZXQgcmVzb2x2ZWQgdG8gYW4gaW5saW5lIE1vZGVsXG4gIH0gZWxzZSBpZiAoc2NoZW1hICYmIHR5cGVvZiBzY2hlbWEgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICAoc2NoZW1hLnR5cGUgPT09ICdvYmplY3QnIHx8IF8uaXNVbmRlZmluZWQoc2NoZW1hLnR5cGUpKSkge1xuICAgIHJldHVybiBuZXcgTW9kZWwodW5kZWZpbmVkLCBzY2hlbWEsIHRoaXMubW9kZWxzLCB0aGlzLnBhcmVudC5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmhlbHAgPSBmdW5jdGlvbiAoZG9udFByaW50KSB7XG4gIHZhciBvdXQgPSB0aGlzLm5pY2tuYW1lICsgJzogJyArIHRoaXMuc3VtbWFyeSArICdcXG4nO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuICAgIHZhciB0eXBlSW5mbyA9IHBhcmFtLnNpZ25hdHVyZTtcblxuICAgIG91dCArPSAnXFxuICAqICcgKyBwYXJhbS5uYW1lICsgJyAoJyArIHR5cGVJbmZvICsgJyk6ICcgKyBwYXJhbS5kZXNjcmlwdGlvbjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZG9udFByaW50ID09PSAndW5kZWZpbmVkJykge1xuICAgIGhlbHBlcnMubG9nKG91dCk7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNb2RlbFNpZ25hdHVyZSA9IGZ1bmN0aW9uICh0eXBlLCBkZWZpbml0aW9ucykge1xuICB2YXIgaXNQcmltaXRpdmUsIGxpc3RUeXBlO1xuXG4gIGlmICh0eXBlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICBsaXN0VHlwZSA9IHRydWU7XG4gICAgdHlwZSA9IHR5cGVbMF07XG4gIH1cblxuICAvLyBDb252ZXJ0IHVuZGVmaW5lZCB0byBzdHJpbmcgb2YgJ3VuZGVmaW5lZCdcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgIHR5cGUgPSAndW5kZWZpbmVkJztcbiAgICBpc1ByaW1pdGl2ZSA9IHRydWU7XG5cbiAgfSBlbHNlIGlmIChkZWZpbml0aW9uc1t0eXBlXSl7XG4gICAgLy8gYSBtb2RlbCBkZWYgZXhpc3RzP1xuICAgIHR5cGUgPSBkZWZpbml0aW9uc1t0eXBlXTsgLyogTW9kZWwgKi9cbiAgICBpc1ByaW1pdGl2ZSA9IGZhbHNlO1xuXG4gIH0gZWxzZSBpZiAodGhpcy5nZXRJbmxpbmVNb2RlbCh0eXBlKSkge1xuICAgIHR5cGUgPSB0aGlzLmdldElubGluZU1vZGVsKHR5cGUpOyAvKiBNb2RlbCAqL1xuICAgIGlzUHJpbWl0aXZlID0gZmFsc2U7XG5cbiAgfSBlbHNlIHtcbiAgICAvLyBXZSBkZWZhdWx0IHRvIHByaW1pdGl2ZVxuICAgIGlzUHJpbWl0aXZlID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChpc1ByaW1pdGl2ZSkge1xuICAgIGlmIChsaXN0VHlwZSkge1xuICAgICAgcmV0dXJuICdBcnJheVsnICsgdHlwZSArICddJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGUudG9TdHJpbmcoKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICByZXR1cm4gJ0FycmF5WycgKyB0eXBlLmdldE1vY2tTaWduYXR1cmUoKSArICddJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGUuZ2V0TW9ja1NpZ25hdHVyZSgpO1xuICAgIH1cbiAgfVxufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5zdXBwb3J0SGVhZGVyUGFyYW1zID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc3VwcG9ydGVkU3VibWl0TWV0aG9kcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMucGFyZW50LnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldEhlYWRlclBhcmFtcyA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gIHZhciBoZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywge30pO1xuICB2YXIgaGVhZGVyUGFyYW1zQnlMb3dlckNhc2UgPSB7fTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIGlmIChwYXJhbS5pbiA9PT0gJ2hlYWRlcicpIHtcbiAgICAgIGhlYWRlclBhcmFtc0J5TG93ZXJDYXNlW3BhcmFtLm5hbWUudG9Mb3dlckNhc2UoKV0gPSBwYXJhbTtcbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBhcmcgaW4gYXJncykge1xuICAgIHZhciBoZWFkZXJQYXJhbSA9IGhlYWRlclBhcmFtc0J5TG93ZXJDYXNlW2FyZy50b0xvd2VyQ2FzZSgpXTtcbiAgICBpZiAodHlwZW9mIGhlYWRlclBhcmFtICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIHZhbHVlID0gYXJnc1thcmddO1xuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS50b1N0cmluZygpO1xuICAgICAgfVxuXG4gICAgICBoZWFkZXJzW2hlYWRlclBhcmFtLm5hbWVdID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGhlYWRlcnM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLnVybGlmeSA9IGZ1bmN0aW9uIChhcmdzLCBtYXNrUGFzc3dvcmRzKSB7XG4gIHZhciBmb3JtUGFyYW1zID0ge307XG4gIHZhciByZXF1ZXN0VXJsID0gdGhpcy5wYXRoLnJlcGxhY2UoLyMuKi8sICcnKTsgLy8gcmVtb3ZlIFVSTCBmcmFnbWVudFxuICB2YXIgcXVlcnlzdHJpbmcgPSAnJzsgLy8gZ3JhYiBwYXJhbXMgZnJvbSB0aGUgYXJncywgYnVpbGQgdGhlIHF1ZXJ5c3RyaW5nIGFsb25nIHRoZSB3YXlcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBpc1Bhc3N3b3JkO1xuICAgICAgaWYocGFyYW0udHlwZSA9PT0gJ3N0cmluZycgJiYgcGFyYW0uZm9ybWF0ID09PSAncGFzc3dvcmQnICYmIG1hc2tQYXNzd29yZHMpIHtcbiAgICAgICAgaXNQYXNzd29yZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbS5pbiA9PT0gJ3BhdGgnKSB7XG4gICAgICAgIHZhciByZWcgPSBuZXcgUmVnRXhwKCdcXHsnICsgcGFyYW0ubmFtZSArICdcXH0nLCAnZ2knKTtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJnc1twYXJhbS5uYW1lXTtcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICB2YWx1ZSA9IHRoaXMuZW5jb2RlUGF0aENvbGxlY3Rpb24ocGFyYW0uY29sbGVjdGlvbkZvcm1hdCwgcGFyYW0ubmFtZSwgdmFsdWUsIGlzUGFzc3dvcmQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlID0gdGhpcy5lbmNvZGVQYXRoUGFyYW0odmFsdWUsIGlzUGFzc3dvcmQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVxdWVzdFVybCA9IHJlcXVlc3RVcmwucmVwbGFjZShyZWcsIHZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAocGFyYW0uaW4gPT09ICdxdWVyeScgJiYgdHlwZW9mIGFyZ3NbcGFyYW0ubmFtZV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmIChxdWVyeXN0cmluZyA9PT0gJycgJiYgcmVxdWVzdFVybC5pbmRleE9mKCc/JykgPCAwKSB7XG4gICAgICAgICAgcXVlcnlzdHJpbmcgKz0gJz8nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9ICcmJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgcGFyYW0uY29sbGVjdGlvbkZvcm1hdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB2YXIgcXAgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocXApKSB7XG4gICAgICAgICAgICBxdWVyeXN0cmluZyArPSB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBwYXJhbS5uYW1lLCBxcCwgaXNQYXNzd29yZCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW0ubmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0oYXJnc1twYXJhbS5uYW1lXSwgaXNQYXNzd29yZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW0ubmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0oYXJnc1twYXJhbS5uYW1lXSwgaXNQYXNzd29yZCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAocGFyYW0uaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgICAgZm9ybVBhcmFtc1twYXJhbS5uYW1lXSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHZhciB1cmwgPSB0aGlzLnNjaGVtZSArICc6Ly8nICsgdGhpcy5ob3N0O1xuXG4gIGlmICh0aGlzLmJhc2VQYXRoICE9PSAnLycpIHtcbiAgICB1cmwgKz0gdGhpcy5iYXNlUGF0aDtcbiAgfVxuICByZXR1cm4gdXJsICsgcmVxdWVzdFVybCArIHF1ZXJ5c3RyaW5nO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNaXNzaW5nUGFyYW1zID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgdmFyIG1pc3NpbmdQYXJhbXMgPSBbXTsgLy8gY2hlY2sgcmVxdWlyZWQgcGFyYW1zLCB0cmFjayB0aGUgb25lcyB0aGF0IGFyZSBtaXNzaW5nXG4gIHZhciBpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG5cbiAgICBpZiAocGFyYW0ucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgbWlzc2luZ1BhcmFtcyA9IHBhcmFtLm5hbWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1pc3NpbmdQYXJhbXM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldEJvZHkgPSBmdW5jdGlvbiAoaGVhZGVycywgYXJncykge1xuICB2YXIgZm9ybVBhcmFtcyA9IHt9LCBoYXNGb3JtUGFyYW1zLCBwYXJhbSwgYm9keSwga2V5LCB2YWx1ZSwgaGFzQm9keSA9IGZhbHNlO1xuXG4gIC8vIGxvb2sgYXQgZWFjaCBwYXJhbSBhbmQgcHV0IGZvcm0gcGFyYW1zIGluIGFuIG9iamVjdFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBpc1Bhc3N3b3JkO1xuICAgICAgaWYocGFyYW0udHlwZSA9PT0gJ3N0cmluZycgJiYgcGFyYW0uZm9ybWF0ID09PSAncGFzc3dvcmQnKSB7XG4gICAgICAgIGlzUGFzc3dvcmQgPSAncGFzc3dvcmQnO1xuICAgICAgfVxuICAgICAgaWYgKHBhcmFtLmluID09PSAnYm9keScpIHtcbiAgICAgICAgYm9keSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnZm9ybURhdGEnKSB7XG4gICAgICAgIGZvcm1QYXJhbXNbcGFyYW0ubmFtZV0gPSB7XG4gICAgICAgICAgcGFyYW06IHBhcmFtLFxuICAgICAgICAgIHZhbHVlOiBhcmdzW3BhcmFtLm5hbWVdLFxuICAgICAgICAgIHBhc3N3b3JkOiBpc1Bhc3N3b3JkXG4gICAgICAgIH07XG4gICAgICAgIGhhc0Zvcm1QYXJhbXMgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmKHBhcmFtLmluID09PSAnYm9keScpIHtcbiAgICAgICAgaGFzQm9keSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgYm9keSBpcyBudWxsIGFuZCBoYXNCb2R5IGlzIHRydWUsIEFORCBhIEpTT04gYm9keSBpcyByZXF1ZXN0ZWQsIHNlbmQgZW1wdHkge31cbiAgaWYoaGFzQm9keSAmJiB0eXBlb2YgYm9keSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIgY29udGVudFR5cGUgPSBoZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgICBpZihjb250ZW50VHlwZSAmJiBjb250ZW50VHlwZS5pbmRleE9mKCdhcHBsaWNhdGlvbi9qc29uJykgPT09IDApIHtcbiAgICAgIGJvZHkgPSAne30nO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpc011bHRpUGFydCA9IGZhbHNlO1xuICBpZihoZWFkZXJzWydDb250ZW50LVR5cGUnXSAmJiBoZWFkZXJzWydDb250ZW50LVR5cGUnXS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPj0gMCkge1xuICAgIGlzTXVsdGlQYXJ0ID0gdHJ1ZTtcbiAgfVxuXG4gIC8vIGhhbmRsZSBmb3JtIHBhcmFtc1xuICBpZiAoaGFzRm9ybVBhcmFtcyAmJiAhaXNNdWx0aVBhcnQpIHtcbiAgICB2YXIgZW5jb2RlZCA9ICcnO1xuXG4gICAgZm9yIChrZXkgaW4gZm9ybVBhcmFtcykge1xuICAgICAgcGFyYW0gPSBmb3JtUGFyYW1zW2tleV0ucGFyYW07XG4gICAgICB2YWx1ZSA9IGZvcm1QYXJhbXNba2V5XS52YWx1ZTtcbiAgICAgIHZhciBwYXNzd29yZCA9IGZvcm1QYXJhbXNba2V5XS5wYXNzd29yZDtcblxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgaWYgKGVuY29kZWQgIT09ICcnKSB7XG4gICAgICAgICAgICBlbmNvZGVkICs9ICcmJztcbiAgICAgICAgICB9XG4gICAgICAgICAgZW5jb2RlZCArPSB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBrZXksIHZhbHVlLCBwYXNzd29yZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgaWYgKGVuY29kZWQgIT09ICcnKSB7XG4gICAgICAgICAgICBlbmNvZGVkICs9ICcmJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlbmNvZGVkICs9IGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsgJz0nICsgbWFzayhlbmNvZGVVUklDb21wb25lbnQodmFsdWUpLCBwYXNzd29yZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBib2R5ID0gZW5jb2RlZDtcbiAgfSBlbHNlIGlmIChpc011bHRpUGFydCkge1xuICAgIHZhciBib2R5UGFyYW07XG4gICAgaWYgKHR5cGVvZiBGb3JtRGF0YSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgYm9keVBhcmFtID0gbmV3IEZvcm1EYXRhKCk7XG5cbiAgICAgIGJvZHlQYXJhbS50eXBlID0gJ2Zvcm1EYXRhJztcblxuICAgICAgZm9yIChrZXkgaW4gZm9ybVBhcmFtcykge1xuICAgICAgICBwYXJhbSA9IGZvcm1QYXJhbXNba2V5XS5wYXJhbTtcbiAgICAgICAgdmFsdWUgPSBhcmdzW2tleV07XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBpZih7fS50b1N0cmluZy5hcHBseSh2YWx1ZSkgPT09ICdbb2JqZWN0IEZpbGVdJykge1xuICAgICAgICAgICAgYm9keVBhcmFtLmFwcGVuZChrZXksIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAodmFsdWUudHlwZSA9PT0gJ2ZpbGUnICYmIHZhbHVlLnZhbHVlKSB7XG4gICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdmFsdWUudmFsdWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgaWYocGFyYW0uY29sbGVjdGlvbkZvcm1hdCA9PT0gJ211bHRpJykge1xuICAgICAgICAgICAgICAgIGJvZHlQYXJhbS5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgICAgICBmb3IodmFyIHYgaW4gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB2YWx1ZVt2XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBrZXksIHZhbHVlKS5zcGxpdCgnPScpLnNsaWNlKDEpLmpvaW4oJz0nKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYm9keSA9IGJvZHlQYXJhbTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBib2R5UGFyYW0gPSB7fTtcbiAgICAgIGZvciAoa2V5IGluIGZvcm1QYXJhbXMpIHtcbiAgICAgICAgdmFsdWUgPSBhcmdzW2tleV07XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhciBkZWxpbWV0ZXI7XG4gICAgICAgICAgdmFyIGZvcm1hdCA9IHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgfHwgJ211bHRpJztcbiAgICAgICAgICBpZihmb3JtYXQgPT09ICdzc3YnKSB7XG4gICAgICAgICAgICBkZWxpbWV0ZXIgPSAnICc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoZm9ybWF0ID09PSAncGlwZXMnKSB7XG4gICAgICAgICAgICBkZWxpbWV0ZXIgPSAnfCc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoZm9ybWF0ID09PSAndHN2Jykge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJ1xcdCc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoZm9ybWF0ID09PSAnbXVsdGknKSB7XG4gICAgICAgICAgICBib2R5UGFyYW1ba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJywnO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgZGF0YTtcbiAgICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKHYpIHtcbiAgICAgICAgICAgIGlmKGRhdGEpIHtcbiAgICAgICAgICAgICAgZGF0YSArPSBkZWxpbWV0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgZGF0YSA9ICcnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGF0YSArPSB2O1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJvZHlQYXJhbVtrZXldID0gZGF0YTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBib2R5UGFyYW1ba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBib2R5ID0gYm9keVBhcmFtO1xuICAgIH1cbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJztcbiAgfVxuXG4gIHJldHVybiBib2R5O1xufTtcblxuLyoqXG4gKiBnZXRzIHNhbXBsZSByZXNwb25zZSBmb3IgYSBzaW5nbGUgb3BlcmF0aW9uXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldE1vZGVsU2FtcGxlSlNPTiA9IGZ1bmN0aW9uICh0eXBlLCBtb2RlbHMpIHtcbiAgdmFyIGxpc3RUeXBlLCBzYW1wbGVKc29uLCBpbm5lclR5cGU7XG4gIG1vZGVscyA9IG1vZGVscyB8fCB7fTtcblxuICBsaXN0VHlwZSA9ICh0eXBlIGluc3RhbmNlb2YgQXJyYXkpO1xuICBpbm5lclR5cGUgPSBsaXN0VHlwZSA/IHR5cGVbMF0gOiB0eXBlO1xuXG4gIGlmKG1vZGVsc1tpbm5lclR5cGVdKSB7XG4gICAgc2FtcGxlSnNvbiA9IG1vZGVsc1tpbm5lclR5cGVdLmNyZWF0ZUpTT05TYW1wbGUoKTtcbiAgfSBlbHNlIGlmICh0aGlzLmdldElubGluZU1vZGVsKGlubmVyVHlwZSkpe1xuICAgIHNhbXBsZUpzb24gPSB0aGlzLmdldElubGluZU1vZGVsKGlubmVyVHlwZSkuY3JlYXRlSlNPTlNhbXBsZSgpOyAvLyBtYXkgcmV0dXJuIG51bGwsIGlmIHR5cGUgaXNuJ3QgY29ycmVjdFxuICB9XG5cblxuICBpZiAoc2FtcGxlSnNvbikge1xuICAgIHNhbXBsZUpzb24gPSBsaXN0VHlwZSA/IFtzYW1wbGVKc29uXSA6IHNhbXBsZUpzb247XG5cbiAgICBpZiAodHlwZW9mIHNhbXBsZUpzb24gPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICB9IGVsc2UgaWYgKF8uaXNPYmplY3Qoc2FtcGxlSnNvbikpIHtcbiAgICAgIHZhciB0ID0gc2FtcGxlSnNvbjtcblxuICAgICAgaWYgKHNhbXBsZUpzb24gaW5zdGFuY2VvZiBBcnJheSAmJiBzYW1wbGVKc29uLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdCA9IHNhbXBsZUpzb25bMF07XG4gICAgICB9XG5cbiAgICAgIGlmICh0Lm5vZGVOYW1lICYmIHR5cGVvZiB0ID09PSAnTm9kZScpIHtcbiAgICAgICAgdmFyIHhtbFN0cmluZyA9IG5ldyBYTUxTZXJpYWxpemVyKCkuc2VyaWFsaXplVG9TdHJpbmcodCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0WG1sKHhtbFN0cmluZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc2FtcGxlSnNvbiwgbnVsbCwgMik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzYW1wbGVKc29uO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBsZWdhY3kgYmluZGluZ1xuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5kbyA9IGZ1bmN0aW9uIChhcmdzLCBvcHRzLCBjYWxsYmFjaywgZXJyb3IsIHBhcmVudCkge1xuICByZXR1cm4gdGhpcy5leGVjdXRlKGFyZ3MsIG9wdHMsIGNhbGxiYWNrLCBlcnJvciwgcGFyZW50KTtcbn07XG5cbi8qKlxuICogZXhlY3V0ZXMgYW4gb3BlcmF0aW9uXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAoYXJnMSwgYXJnMiwgYXJnMywgYXJnNCwgcGFyZW50KSB7XG4gIHZhciBhcmdzID0gYXJnMSB8fCB7fTtcbiAgdmFyIG9wdHMgPSB7fSwgc3VjY2VzcywgZXJyb3IsIGRlZmVycmVkLCB0aW1lb3V0O1xuXG4gIGlmIChfLmlzT2JqZWN0KGFyZzIpKSB7XG4gICAgb3B0cyA9IGFyZzI7XG4gICAgc3VjY2VzcyA9IGFyZzM7XG4gICAgZXJyb3IgPSBhcmc0O1xuICB9XG5cbiAgdGltZW91dCA9IHR5cGVvZiBvcHRzLnRpbWVvdXQgIT09ICd1bmRlZmluZWQnID8gb3B0cy50aW1lb3V0IDogdGhpcy50aW1lb3V0O1xuXG4gIGlmKHRoaXMuY2xpZW50KSB7XG4gICAgb3B0cy5jbGllbnQgPSB0aGlzLmNsaWVudDtcbiAgfVxuXG4gIGlmKHRoaXMucmVxdWVzdEFnZW50KSB7XG4gICAgb3B0cy5yZXF1ZXN0QWdlbnQgPSB0aGlzLnJlcXVlc3RBZ2VudDtcbiAgfVxuXG4gIC8vIGFkZCB0aGUgcmVxdWVzdCBpbnRlcmNlcHRvciBmcm9tIHBhcmVudCwgaWYgbm9uZSBzZW50IGZyb20gY2xpZW50XG4gIGlmKCFvcHRzLnJlcXVlc3RJbnRlcmNlcHRvciAmJiB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvciApIHtcbiAgICBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvciA9IHRoaXMucmVxdWVzdEludGVyY2VwdG9yIDtcbiAgfVxuXG4gIGlmKCFvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IgJiYgdGhpcy5yZXNwb25zZUludGVyY2VwdG9yKSB7XG4gICAgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yID0gdGhpcy5yZXNwb25zZUludGVyY2VwdG9yO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBhcmcyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgc3VjY2VzcyA9IGFyZzI7XG4gICAgZXJyb3IgPSBhcmczO1xuICB9XG5cbiAgaWYgKHRoaXMucGFyZW50LnVzZVByb21pc2UpIHtcbiAgICBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgfSBlbHNlIHtcbiAgICBzdWNjZXNzID0gKHN1Y2Nlc3MgfHwgdGhpcy5wYXJlbnQuZGVmYXVsdFN1Y2Nlc3NDYWxsYmFjayB8fCBoZWxwZXJzLmxvZyk7XG4gICAgZXJyb3IgPSAoZXJyb3IgfHwgdGhpcy5wYXJlbnQuZGVmYXVsdEVycm9yQ2FsbGJhY2sgfHwgaGVscGVycy5sb2cpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLnVzZUpRdWVyeSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLnVzZUpRdWVyeSA9IHRoaXMudXNlSlF1ZXJ5O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLmpxdWVyeUFqYXhDYWNoZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLmpxdWVyeUFqYXhDYWNoZSA9IHRoaXMuanF1ZXJ5QWpheENhY2hlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLmVuYWJsZUNvb2tpZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0cy5lbmFibGVDb29raWVzID0gdGhpcy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdmFyIG1pc3NpbmdQYXJhbXMgPSB0aGlzLmdldE1pc3NpbmdQYXJhbXMoYXJncyk7XG5cbiAgaWYgKG1pc3NpbmdQYXJhbXMubGVuZ3RoID4gMCkge1xuICAgIHZhciBtZXNzYWdlID0gJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW1zOiAnICsgbWlzc2luZ1BhcmFtcztcblxuICAgIGhlbHBlcnMuZmFpbChtZXNzYWdlKTtcblxuICAgIGlmICh0aGlzLnBhcmVudC51c2VQcm9taXNlKSB7XG4gICAgICBkZWZlcnJlZC5yZWplY3QobWVzc2FnZSk7XG4gICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3IobWVzc2FnZSwgcGFyZW50KTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cblxuICB2YXIgYWxsSGVhZGVycyA9IHRoaXMuZ2V0SGVhZGVyUGFyYW1zKGFyZ3MpO1xuICB2YXIgY29udGVudFR5cGVIZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywgb3B0cyk7XG4gIHZhciBoZWFkZXJzID0ge30sIGF0dHJuYW1lO1xuXG4gIGZvciAoYXR0cm5hbWUgaW4gYWxsSGVhZGVycykgeyBoZWFkZXJzW2F0dHJuYW1lXSA9IGFsbEhlYWRlcnNbYXR0cm5hbWVdOyB9XG4gIGZvciAoYXR0cm5hbWUgaW4gY29udGVudFR5cGVIZWFkZXJzKSB7IGhlYWRlcnNbYXR0cm5hbWVdID0gY29udGVudFR5cGVIZWFkZXJzW2F0dHJuYW1lXTsgfVxuXG4gIHZhciBib2R5ID0gdGhpcy5nZXRCb2R5KGNvbnRlbnRUeXBlSGVhZGVycywgYXJncywgb3B0cyk7XG4gIHZhciB1cmwgPSB0aGlzLnVybGlmeShhcmdzLCBvcHRzLm1hc2tQYXNzd29yZHMpO1xuXG4gIGlmKHVybC5pbmRleE9mKCcue2Zvcm1hdH0nKSA+IDApIHtcbiAgICBpZihoZWFkZXJzKSB7XG4gICAgICB2YXIgZm9ybWF0ID0gaGVhZGVycy5BY2NlcHQgfHwgaGVhZGVycy5hY2NlcHQ7XG4gICAgICBpZihmb3JtYXQgJiYgZm9ybWF0LmluZGV4T2YoJ2pzb24nKSA+IDApIHtcbiAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoJy57Zm9ybWF0fScsICcuanNvbicpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZihmb3JtYXQgJiYgZm9ybWF0LmluZGV4T2YoJ3htbCcpID4gMCkge1xuICAgICAgICB1cmwgPSB1cmwucmVwbGFjZSgnLntmb3JtYXR9JywgJy54bWwnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgb2JqID0ge1xuICAgIHVybDogdXJsLFxuICAgIG1ldGhvZDogdGhpcy5tZXRob2QudG9VcHBlckNhc2UoKSxcbiAgICBib2R5OiBib2R5LFxuICAgIGVuYWJsZUNvb2tpZXM6IG9wdHMuZW5hYmxlQ29va2llcyxcbiAgICB1c2VKUXVlcnk6IG9wdHMudXNlSlF1ZXJ5LFxuICAgIGpxdWVyeUFqYXhDYWNoZTogb3B0cy5qcXVlcnlBamF4Q2FjaGUsXG4gICAgZGVmZXJyZWQ6IGRlZmVycmVkLFxuICAgIGhlYWRlcnM6IGhlYWRlcnMsXG4gICAgY2xpZW50QXV0aG9yaXphdGlvbnM6IG9wdHMuY2xpZW50QXV0aG9yaXphdGlvbnMsXG4gICAgb3BlcmF0aW9uOiB0aGlzLFxuICAgIGNvbm5lY3Rpb25BZ2VudDogdGhpcy5jb25uZWN0aW9uQWdlbnQsXG4gICAgb246IHtcbiAgICAgIHJlc3BvbnNlOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKGRlZmVycmVkKSB7XG4gICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHN1Y2Nlc3MocmVzcG9uc2UsIHBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnJvcjogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChkZWZlcnJlZCkge1xuICAgICAgICAgIGRlZmVycmVkLnJlamVjdChyZXNwb25zZSk7XG4gICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yKHJlc3BvbnNlLCBwYXJlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGlmICh0aW1lb3V0KSB7XG4gICAgb2JqLnRpbWVvdXQgPSB0aW1lb3V0O1xuICB9XG5cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmosIHRoaXMub3BlcmF0aW9uLnNlY3VyaXR5KTtcbiAgaWYgKG9wdHMubW9jayA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBvYmo7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUob2JqLCBvcHRzKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gaXRlbUJ5UHJpb3JpdHkoY29sLCBpdGVtUHJpb3JpdHkpIHtcblxuICAvLyBObyBwcmlvcml0aWVzPyByZXR1cm4gZmlyc3QuLi5cbiAgaWYoXy5pc0VtcHR5KGl0ZW1Qcmlvcml0eSkpIHtcbiAgICByZXR1cm4gY29sWzBdO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGl0ZW1Qcmlvcml0eS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmKGNvbC5pbmRleE9mKGl0ZW1Qcmlvcml0eVtpXSkgPiAtMSkge1xuICAgICAgcmV0dXJuIGl0ZW1Qcmlvcml0eVtpXTtcbiAgICB9XG4gIH1cblxuICAvLyBPdGhlcndpc2UgcmV0dXJuIGZpcnN0XG4gIHJldHVybiBjb2xbMF07XG59XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc2V0Q29udGVudFR5cGVzID0gZnVuY3Rpb24gKGFyZ3MsIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCB0eXBlXG4gIHZhciBhbGxEZWZpbmVkUGFyYW1zID0gdGhpcy5wYXJhbWV0ZXJzO1xuICB2YXIgYm9keTtcbiAgdmFyIGNvbnN1bWVzID0gYXJncy5wYXJhbWV0ZXJDb250ZW50VHlwZSB8fCBpdGVtQnlQcmlvcml0eSh0aGlzLmNvbnN1bWVzLCBbJ2FwcGxpY2F0aW9uL2pzb24nLCAnYXBwbGljYXRpb24veWFtbCddKTtcbiAgdmFyIGFjY2VwdHMgPSBvcHRzLnJlc3BvbnNlQ29udGVudFR5cGUgfHwgaXRlbUJ5UHJpb3JpdHkodGhpcy5wcm9kdWNlcywgWydhcHBsaWNhdGlvbi9qc29uJywgJ2FwcGxpY2F0aW9uL3lhbWwnXSk7XG4gIHZhciBkZWZpbmVkRmlsZVBhcmFtcyA9IFtdO1xuICB2YXIgZGVmaW5lZEZvcm1QYXJhbXMgPSBbXTtcbiAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgdmFyIGk7XG5cbiAgLy8gZ2V0IHBhcmFtcyBmcm9tIHRoZSBvcGVyYXRpb24gYW5kIHNldCB0aGVtIGluIGRlZmluZWRGaWxlUGFyYW1zLCBkZWZpbmVkRm9ybVBhcmFtcywgaGVhZGVyc1xuICBmb3IgKGkgPSAwOyBpIDwgYWxsRGVmaW5lZFBhcmFtcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IGFsbERlZmluZWRQYXJhbXNbaV07XG5cbiAgICBpZiAocGFyYW0uaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgIGlmIChwYXJhbS50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgZGVmaW5lZEZpbGVQYXJhbXMucHVzaChwYXJhbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWZpbmVkRm9ybVBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJyAmJiBvcHRzKSB7XG4gICAgICB2YXIga2V5ID0gcGFyYW0ubmFtZTtcbiAgICAgIHZhciBoZWFkZXJWYWx1ZSA9IG9wdHNbcGFyYW0ubmFtZV07XG5cbiAgICAgIGlmICh0eXBlb2Ygb3B0c1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaGVhZGVyc1trZXldID0gaGVhZGVyVmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2JvZHknICYmIHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgYm9keSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlcmUncyBhIGJvZHksIG5lZWQgdG8gc2V0IHRoZSBjb25zdW1lcyBoZWFkZXIgdmlhIHJlcXVlc3RDb250ZW50VHlwZVxuICB2YXIgaGFzQm9keSA9IGJvZHkgfHwgZGVmaW5lZEZpbGVQYXJhbXMubGVuZ3RoIHx8IGRlZmluZWRGb3JtUGFyYW1zLmxlbmd0aDtcbiAgaWYgKHRoaXMubWV0aG9kID09PSAncG9zdCcgfHwgdGhpcy5tZXRob2QgPT09ICdwdXQnIHx8IHRoaXMubWV0aG9kID09PSAncGF0Y2gnIHx8XG4gICAgICAoKHRoaXMubWV0aG9kID09PSAnZGVsZXRlJyB8fCB0aGlzLm1ldGhvZCA9PT0gJ2dldCcpICYmIGhhc0JvZHkpKSB7XG4gICAgaWYgKG9wdHMucmVxdWVzdENvbnRlbnRUeXBlKSB7XG4gICAgICBjb25zdW1lcyA9IG9wdHMucmVxdWVzdENvbnRlbnRUeXBlO1xuICAgIH1cbiAgICAvLyBpZiBhbnkgZm9ybSBwYXJhbXMsIGNvbnRlbnQgdHlwZSBtdXN0IGJlIHNldFxuICAgIGlmIChkZWZpbmVkRm9ybVBhcmFtcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdW1lcyA9IHVuZGVmaW5lZDtcbiAgICAgIGlmIChvcHRzLnJlcXVlc3RDb250ZW50VHlwZSkgeyAgICAgICAgICAgICAvLyBvdmVycmlkZSBpZiBzZXRcbiAgICAgICAgY29uc3VtZXMgPSBvcHRzLnJlcXVlc3RDb250ZW50VHlwZTtcbiAgICAgIH0gZWxzZSBpZiAoZGVmaW5lZEZpbGVQYXJhbXMubGVuZ3RoID4gMCkgeyAvLyBpZiBhIGZpbGUsIG11c3QgYmUgbXVsdGlwYXJ0L2Zvcm0tZGF0YVxuICAgICAgICBjb25zdW1lcyA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnN1bWVzICYmIHRoaXMuY29uc3VtZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIC8vIHVzZSB0aGUgY29uc3VtZXMgc2V0dGluZ1xuICAgICAgICAgIGZvcih2YXIgYyBpbiB0aGlzLmNvbnN1bWVzKSB7XG4gICAgICAgICAgICB2YXIgY2hrID0gdGhpcy5jb25zdW1lc1tjXTtcbiAgICAgICAgICAgIGlmKGNoay5pbmRleE9mKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSA9PT0gMCB8fCBjaGsuaW5kZXhPZignbXVsdGlwYXJ0L2Zvcm0tZGF0YScpID09PSAwKSB7XG4gICAgICAgICAgICAgIGNvbnN1bWVzID0gY2hrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYodHlwZW9mIGNvbnN1bWVzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAvLyBkZWZhdWx0IHRvIHgtd3d3LWZyb20tdXJsZW5jb2RlZFxuICAgICAgICBjb25zdW1lcyA9ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBjb25zdW1lcyA9IG51bGw7XG4gIH1cblxuICBpZiAoY29uc3VtZXMgJiYgdGhpcy5jb25zdW1lcykge1xuICAgIGlmICh0aGlzLmNvbnN1bWVzLmluZGV4T2YoY29uc3VtZXMpID09PSAtMSkge1xuICAgICAgaGVscGVycy5sb2coJ3NlcnZlciBkb2VzblxcJ3QgY29uc3VtZSAnICsgY29uc3VtZXMgKyAnLCB0cnkgJyArIEpTT04uc3RyaW5naWZ5KHRoaXMuY29uc3VtZXMpKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXRoaXMubWF0Y2hlc0FjY2VwdChhY2NlcHRzKSkge1xuICAgIGhlbHBlcnMubG9nKCdzZXJ2ZXIgY2FuXFwndCBwcm9kdWNlICcgKyBhY2NlcHRzKTtcbiAgfVxuXG4gIGlmICgoY29uc3VtZXMgJiYgYm9keSAhPT0gJycpIHx8IChjb25zdW1lcyA9PT0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpKSB7XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSBjb25zdW1lcztcbiAgfVxuICBlbHNlIGlmKHRoaXMuY29uc3VtZXMgJiYgdGhpcy5jb25zdW1lcy5sZW5ndGggPiAwICYmIHRoaXMuY29uc3VtZXNbMF0gPT09ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSB7XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSB0aGlzLmNvbnN1bWVzWzBdO1xuICB9XG5cbiAgaWYgKGFjY2VwdHMpIHtcbiAgICBoZWFkZXJzLkFjY2VwdCA9IGFjY2VwdHM7XG4gIH1cblxuICByZXR1cm4gaGVhZGVycztcbn07XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSByZXF1ZXN0IGFjY2VwdHMgaGVhZGVyIG1hdGNoZXMgYW55dGhpbmcgaW4gdGhpcy5wcm9kdWNlcy5cbiAqICBJZiB0aGlzLnByb2R1Y2VzIGNvbnRhaW5zICogLyAqLCBpZ25vcmUgdGhlIGFjY2VwdCBoZWFkZXIuXG4gKiBAcGFyYW0ge3N0cmluZz19IGFjY2VwdHMgVGhlIGNsaWVudCByZXF1ZXN0IGFjY2VwdCBoZWFkZXIuXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5PcGVyYXRpb24ucHJvdG90eXBlLm1hdGNoZXNBY2NlcHQgPSBmdW5jdGlvbihhY2NlcHRzKSB7XG4gIC8vIG5vIGFjY2VwdHMgb3IgcHJvZHVjZXMsIG5vIHByb2JsZW0hXG4gIGlmICghYWNjZXB0cyB8fCAhdGhpcy5wcm9kdWNlcykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiB0aGlzLnByb2R1Y2VzLmluZGV4T2YoYWNjZXB0cykgIT09IC0xIHx8IHRoaXMucHJvZHVjZXMuaW5kZXhPZignKi8qJykgIT09IC0xO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5hc0N1cmwgPSBmdW5jdGlvbiAoYXJnczEsIGFyZ3MyKSB7XG4gIHZhciBvcHRzID0ge21vY2s6IHRydWUsIG1hc2tQYXNzd29yZHM6IHRydWV9O1xuICBpZiAodHlwZW9mIGFyZ3MyID09PSAnb2JqZWN0Jykge1xuICAgIGZvciAodmFyIGFyZ0tleSBpbiBhcmdzMikge1xuICAgICAgb3B0c1thcmdLZXldID0gYXJnczJbYXJnS2V5XTtcbiAgICB9XG4gIH1cbiAgdmFyIG9iaiA9IHRoaXMuZXhlY3V0ZShhcmdzMSwgb3B0cyk7XG5cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmosIHRoaXMub3BlcmF0aW9uLnNlY3VyaXR5KTtcblxuICB2YXIgcmVzdWx0cyA9IFtdO1xuXG4gIHJlc3VsdHMucHVzaCgnLVggJyArIHRoaXMubWV0aG9kLnRvVXBwZXJDYXNlKCkpO1xuXG4gIGlmICh0eXBlb2Ygb2JqLmhlYWRlcnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIGtleTtcblxuICAgIGZvciAoa2V5IGluIG9iai5oZWFkZXJzKSB7XG4gICAgICB2YXIgdmFsdWUgPSBvYmouaGVhZGVyc1trZXldO1xuICAgICAgaWYodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyl7XG4gICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXFwnL2csICdcXFxcdTAwMjcnKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdHMucHVzaCgnLS1oZWFkZXIgXFwnJyArIGtleSArICc6ICcgKyB2YWx1ZSArICdcXCcnKTtcbiAgICB9XG4gIH1cbiAgdmFyIGlzRm9ybURhdGEgPSBmYWxzZTtcbiAgdmFyIGlzTXVsdGlwYXJ0ID0gZmFsc2U7XG5cbiAgdmFyIHR5cGUgPSBvYmouaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gIGlmKHR5cGUgJiYgdHlwZS5pbmRleE9mKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSA9PT0gMCkge1xuICAgIGlzRm9ybURhdGEgPSB0cnVlO1xuICB9XG4gIGVsc2UgaWYgKHR5cGUgJiYgdHlwZS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPT09IDApIHtcbiAgICBpc0Zvcm1EYXRhID0gdHJ1ZTtcbiAgICBpc011bHRpcGFydCA9IHRydWU7XG4gIH1cblxuICBpZiAob2JqLmJvZHkpIHtcbiAgICB2YXIgYm9keTtcbiAgICBpZiAoXy5pc09iamVjdChvYmouYm9keSkpIHtcbiAgICAgIGlmKGlzTXVsdGlwYXJ0KSB7XG4gICAgICAgIGlzTXVsdGlwYXJ0ID0gdHJ1ZTtcbiAgICAgICAgLy8gYWRkIHRoZSBmb3JtIGRhdGFcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBwYXJhbWV0ZXIgPSB0aGlzLnBhcmFtZXRlcnNbaV07XG4gICAgICAgICAgaWYocGFyYW1ldGVyLmluID09PSAnZm9ybURhdGEnKSB7XG4gICAgICAgICAgICBpZiAoIWJvZHkpIHtcbiAgICAgICAgICAgICAgYm9keSA9ICcnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcGFyYW1WYWx1ZTtcbiAgICAgICAgICAgIGlmKHR5cGVvZiBGb3JtRGF0YSA9PT0gJ2Z1bmN0aW9uJyAmJiBvYmouYm9keSBpbnN0YW5jZW9mIEZvcm1EYXRhKSB7XG4gICAgICAgICAgICAgIHBhcmFtVmFsdWUgPSBvYmouYm9keS5nZXRBbGwocGFyYW1ldGVyLm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIHBhcmFtVmFsdWUgPSBvYmouYm9keVtwYXJhbWV0ZXIubmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocGFyYW1WYWx1ZSkge1xuICAgICAgICAgICAgICBpZiAocGFyYW1ldGVyLnR5cGUgPT09ICdmaWxlJykge1xuICAgICAgICAgICAgICAgIGlmKHBhcmFtVmFsdWUubmFtZSkge1xuICAgICAgICAgICAgICAgICAgYm9keSArPSAnLUYgJyArIHBhcmFtZXRlci5uYW1lICsgJz1AXCInICsgcGFyYW1WYWx1ZS5uYW1lICsgJ1wiICc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHBhcmFtVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICBpZihwYXJhbWV0ZXIuY29sbGVjdGlvbkZvcm1hdCA9PT0gJ211bHRpJykge1xuICAgICAgICAgICAgICAgICAgICBmb3IodmFyIHYgaW4gcGFyYW1WYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgIGJvZHkgKz0gJy1GICcgKyB0aGlzLmVuY29kZVF1ZXJ5S2V5KHBhcmFtZXRlci5uYW1lKSArICc9JyArIG1hc2socGFyYW1WYWx1ZVt2XSwgcGFyYW1ldGVyLmZvcm1hdCkgKyAnICc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBib2R5ICs9ICctRiAnICsgdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24ocGFyYW1ldGVyLmNvbGxlY3Rpb25Gb3JtYXQsIHBhcmFtZXRlci5uYW1lLCBtYXNrKHBhcmFtVmFsdWUsIHBhcmFtZXRlci5mb3JtYXQpKSArICcgJztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgYm9keSArPSAnLUYgJyArIHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW1ldGVyLm5hbWUpICsgJz0nICsgbWFzayhwYXJhbVZhbHVlLCBwYXJhbWV0ZXIuZm9ybWF0KSArICcgJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKCFib2R5KSB7XG4gICAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShvYmouYm9keSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGJvZHkgPSBvYmouYm9keTtcbiAgICB9XG4gICAgLy8gZXNjYXBlIEAgPT4gJTQwLCAnID0+ICUyN1xuICAgIGJvZHkgPSBib2R5LnJlcGxhY2UoL1xcJy9nLCAnJTI3JykucmVwbGFjZSgvXFxuL2csICcgXFxcXCBcXG4gJyk7XG5cbiAgICBpZighaXNGb3JtRGF0YSkge1xuICAgICAgLy8gZXNjYXBlICYgPT4gJTI2XG4gICAgICBib2R5ID0gYm9keS5yZXBsYWNlKC8mL2csICclMjYnKTtcbiAgICB9XG4gICAgaWYoaXNNdWx0aXBhcnQpIHtcbiAgICAgIHJlc3VsdHMucHVzaChib2R5KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXN1bHRzLnB1c2goJy1kIFxcJycgKyBib2R5LnJlcGxhY2UoL0AvZywgJyU0MCcpICsgJ1xcJycpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAnY3VybCAnICsgKHJlc3VsdHMuam9pbignICcpKSArICcgXFwnJyArIG9iai51cmwgKyAnXFwnJztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUGF0aENvbGxlY3Rpb24gPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgdmFsdWUsIG1hc2tQYXNzd29yZHMpIHtcbiAgdmFyIGVuY29kZWQgPSAnJztcbiAgdmFyIGk7XG4gIHZhciBzZXBhcmF0b3IgPSAnJztcblxuICBpZiAodHlwZSA9PT0gJ3NzdicpIHtcbiAgICBzZXBhcmF0b3IgPSAnJTIwJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAndHN2Jykge1xuICAgIHNlcGFyYXRvciA9ICclMDknO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdwaXBlcycpIHtcbiAgICBzZXBhcmF0b3IgPSAnfCc7XG4gIH0gZWxzZSB7XG4gICAgc2VwYXJhdG9yID0gJywnO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGVuY29kZWQgPSB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0sIG1hc2tQYXNzd29yZHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGVkICs9IHNlcGFyYXRvciArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSwgbWFza1Bhc3N3b3Jkcyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVuY29kZWQ7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbiA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCB2YWx1ZSwgbWFza1Bhc3N3b3Jkcykge1xuICB2YXIgZW5jb2RlZCA9ICcnO1xuICB2YXIgaTtcblxuICB0eXBlID0gdHlwZSB8fCAnZGVmYXVsdCc7XG4gIGlmICh0eXBlID09PSAnZGVmYXVsdCcgfHwgdHlwZSA9PT0gJ211bHRpJykge1xuICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGkgPiAwKSB7ZW5jb2RlZCArPSAnJic7fVxuXG4gICAgICBlbmNvZGVkICs9IHRoaXMuZW5jb2RlUXVlcnlLZXkobmFtZSkgKyAnPScgKyBtYXNrKHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSksIG1hc2tQYXNzd29yZHMpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgc2VwYXJhdG9yID0gJyc7XG5cbiAgICBpZiAodHlwZSA9PT0gJ2NzdicpIHtcbiAgICAgIHNlcGFyYXRvciA9ICcsJztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzc3YnKSB7XG4gICAgICBzZXBhcmF0b3IgPSAnJTIwJztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICd0c3YnKSB7XG4gICAgICBzZXBhcmF0b3IgPSAnJTA5JztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdwaXBlcycpIHtcbiAgICAgIHNlcGFyYXRvciA9ICd8JztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdicmFja2V0cycpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaSAhPT0gMCkge1xuICAgICAgICAgIGVuY29kZWQgKz0gJyYnO1xuICAgICAgICB9XG4gICAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShuYW1lKSArICdbXT0nICsgbWFzayh0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pLCBtYXNrUGFzc3dvcmRzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2VwYXJhdG9yICE9PSAnJykge1xuICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgICAgZW5jb2RlZCA9IHRoaXMuZW5jb2RlUXVlcnlLZXkobmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuY29kZWQgKz0gc2VwYXJhdG9yICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbmNvZGVkO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVRdWVyeUtleSA9IGZ1bmN0aW9uIChhcmcpIHtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChhcmcpXG4gICAgICAucmVwbGFjZSgnJTVCJywnWycpLnJlcGxhY2UoJyU1RCcsICddJykucmVwbGFjZSgnJTI0JywgJyQnKTtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUXVlcnlQYXJhbSA9IGZ1bmN0aW9uIChhcmcsIG1hc2tQYXNzd29yZHMpIHtcbiAgaWYobWFza1Bhc3N3b3Jkcykge1xuICAgIHJldHVybiBcIioqKioqKlwiO1xuICB9XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoYXJnKTtcbn07XG5cbi8qKlxuICogVE9ETyByZXZpc2l0LCBtaWdodCBub3Qgd2FudCB0byBsZWF2ZSAnLydcbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUGF0aFBhcmFtID0gZnVuY3Rpb24gKHBhdGhQYXJhbSwgbWFza1Bhc3N3b3Jkcykge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHBhdGhQYXJhbSwgbWFza1Bhc3N3b3Jkcyk7XG59O1xuXG52YXIgbWFzayA9IGZ1bmN0aW9uKHZhbHVlLCBmb3JtYXQpIHtcbiAgaWYodHlwZW9mIGZvcm1hdCA9PT0gJ3N0cmluZycgJiYgZm9ybWF0ID09PSAncGFzc3dvcmQnKSB7XG4gICAgcmV0dXJuICcqKioqKionO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn0iLCIndXNlIHN0cmljdCc7XG5cbnZhciBPcGVyYXRpb25Hcm91cCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRhZywgZGVzY3JpcHRpb24sIGV4dGVybmFsRG9jcywgb3BlcmF0aW9uKSB7XG4gIHRoaXMuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjtcbiAgdGhpcy5leHRlcm5hbERvY3MgPSBleHRlcm5hbERvY3M7XG4gIHRoaXMubmFtZSA9IHRhZztcbiAgdGhpcy5vcGVyYXRpb24gPSBvcGVyYXRpb247XG4gIHRoaXMub3BlcmF0aW9uc0FycmF5ID0gW107XG4gIHRoaXMucGF0aCA9IHRhZztcbiAgdGhpcy50YWcgPSB0YWc7XG59O1xuXG5PcGVyYXRpb25Hcm91cC5wcm90b3R5cGUuc29ydCA9IGZ1bmN0aW9uICgpIHtcblxufTtcblxuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuICAgIHZhciBjdXJyZW50UXVldWU7XG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHZhciBpID0gLTE7XG4gICAgICAgIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtpXSgpO1xuICAgICAgICB9XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbn1cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgcXVldWUucHVzaChmdW4pO1xuICAgIGlmICghZHJhaW5pbmcpIHtcbiAgICAgICAgc2V0VGltZW91dChkcmFpblF1ZXVlLCAwKTtcbiAgICB9XG59O1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIihmdW5jdGlvbiAoQnVmZmVyKXtcbihmdW5jdGlvbiAoKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuXG4gIGZ1bmN0aW9uIGJ0b2Eoc3RyKSB7XG4gICAgdmFyIGJ1ZmZlclxuICAgICAgO1xuXG4gICAgaWYgKHN0ciBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgYnVmZmVyID0gc3RyO1xuICAgIH0gZWxzZSB7XG4gICAgICBidWZmZXIgPSBuZXcgQnVmZmVyKHN0ci50b1N0cmluZygpLCAnYmluYXJ5Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygnYmFzZTY0Jyk7XG4gIH1cblxuICBtb2R1bGUuZXhwb3J0cyA9IGJ0b2E7XG59KCkpO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5aWRHOWhMMmx1WkdWNExtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVNJc0ltWnBiR1VpT2lKblpXNWxjbUYwWldRdWFuTWlMQ0p6YjNWeVkyVlNiMjkwSWpvaUlpd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sc2lLR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdYQ0oxYzJVZ2MzUnlhV04wWENJN1hHNWNiaUFnWm5WdVkzUnBiMjRnWW5SdllTaHpkSElwSUh0Y2JpQWdJQ0IyWVhJZ1luVm1abVZ5WEc0Z0lDQWdJQ0E3WEc1Y2JpQWdJQ0JwWmlBb2MzUnlJR2x1YzNSaGJtTmxiMllnUW5WbVptVnlLU0I3WEc0Z0lDQWdJQ0JpZFdabVpYSWdQU0J6ZEhJN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJR0oxWm1abGNpQTlJRzVsZHlCQ2RXWm1aWElvYzNSeUxuUnZVM1J5YVc1bktDa3NJQ2RpYVc1aGNua25LVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQnlaWFIxY200Z1luVm1abVZ5TG5SdlUzUnlhVzVuS0NkaVlYTmxOalFuS1R0Y2JpQWdmVnh1WEc0Z0lHMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ1luUnZZVHRjYm4wb0tTazdYRzRpWFgwPSIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpcy1hcnJheScpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBTbG93QnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG52YXIgcm9vdFBhcmVudCA9IHt9XG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIER1ZSB0byB2YXJpb3VzIGJyb3dzZXIgYnVncywgc29tZXRpbWVzIHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24gd2lsbCBiZSB1c2VkIGV2ZW5cbiAqIHdoZW4gdGhlIGJyb3dzZXIgc3VwcG9ydHMgdHlwZWQgYXJyYXlzLlxuICpcbiAqIE5vdGU6XG4gKlxuICogICAtIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcyxcbiAqICAgICBTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOC5cbiAqXG4gKiAgIC0gU2FmYXJpIDUtNyBsYWNrcyBzdXBwb3J0IGZvciBjaGFuZ2luZyB0aGUgYE9iamVjdC5wcm90b3R5cGUuY29uc3RydWN0b3JgIHByb3BlcnR5XG4gKiAgICAgb24gb2JqZWN0cy5cbiAqXG4gKiAgIC0gQ2hyb21lIDktMTAgaXMgbWlzc2luZyB0aGUgYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbi5cbiAqXG4gKiAgIC0gSUUxMCBoYXMgYSBicm9rZW4gYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFycmF5cyBvZlxuICogICAgIGluY29ycmVjdCBsZW5ndGggaW4gc29tZSBzaXR1YXRpb25zLlxuXG4gKiBXZSBkZXRlY3QgdGhlc2UgYnVnZ3kgYnJvd3NlcnMgYW5kIHNldCBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgIHRvIGBmYWxzZWAgc28gdGhleVxuICogZ2V0IHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHNsb3dlciBidXQgYmVoYXZlcyBjb3JyZWN0bHkuXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gKGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gQmFyICgpIHt9XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLmZvbyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH1cbiAgICBhcnIuY29uc3RydWN0b3IgPSBCYXJcbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MiAmJiAvLyB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZFxuICAgICAgICBhcnIuY29uc3RydWN0b3IgPT09IEJhciAmJiAvLyBjb25zdHJ1Y3RvciBjYW4gYmUgc2V0XG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgJiYgLy8gY2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gICAgICAgIGFyci5zdWJhcnJheSgxLCAxKS5ieXRlTGVuZ3RoID09PSAwIC8vIGllMTAgaGFzIGJyb2tlbiBgc3ViYXJyYXlgXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufSkoKVxuXG5mdW5jdGlvbiBrTWF4TGVuZ3RoICgpIHtcbiAgcmV0dXJuIEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gICAgPyAweDdmZmZmZmZmXG4gICAgOiAweDNmZmZmZmZmXG59XG5cbi8qKlxuICogQ2xhc3M6IEJ1ZmZlclxuICogPT09PT09PT09PT09PVxuICpcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgYXJlIGF1Z21lbnRlZFxuICogd2l0aCBmdW5jdGlvbiBwcm9wZXJ0aWVzIGZvciBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgQVBJIGZ1bmN0aW9ucy4gV2UgdXNlXG4gKiBgVWludDhBcnJheWAgc28gdGhhdCBzcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdCByZXR1cm5zXG4gKiBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBCeSBhdWdtZW50aW5nIHRoZSBpbnN0YW5jZXMsIHdlIGNhbiBhdm9pZCBtb2RpZnlpbmcgdGhlIGBVaW50OEFycmF5YFxuICogcHJvdG90eXBlLlxuICovXG5mdW5jdGlvbiBCdWZmZXIgKGFyZykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIC8vIEF2b2lkIGdvaW5nIHRocm91Z2ggYW4gQXJndW1lbnRzQWRhcHRvclRyYW1wb2xpbmUgaW4gdGhlIGNvbW1vbiBjYXNlLlxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgcmV0dXJuIG5ldyBCdWZmZXIoYXJnLCBhcmd1bWVudHNbMV0pXG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoYXJnKVxuICB9XG5cbiAgdGhpcy5sZW5ndGggPSAwXG4gIHRoaXMucGFyZW50ID0gdW5kZWZpbmVkXG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBmcm9tTnVtYmVyKHRoaXMsIGFyZylcbiAgfVxuXG4gIC8vIFNsaWdodGx5IGxlc3MgY29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHRoaXMsIGFyZywgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiAndXRmOCcpXG4gIH1cblxuICAvLyBVbnVzdWFsLlxuICByZXR1cm4gZnJvbU9iamVjdCh0aGlzLCBhcmcpXG59XG5cbmZ1bmN0aW9uIGZyb21OdW1iZXIgKHRoYXQsIGxlbmd0aCkge1xuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGxlbmd0aCkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgdGhhdFtpXSA9IDBcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgLy8gQXNzdW1wdGlvbjogYnl0ZUxlbmd0aCgpIHJldHVybiB2YWx1ZSBpcyBhbHdheXMgPCBrTWF4TGVuZ3RoLlxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICB0aGF0LndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21PYmplY3QgKHRoYXQsIG9iamVjdCkge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iamVjdCkpIHJldHVybiBmcm9tQnVmZmVyKHRoYXQsIG9iamVjdClcblxuICBpZiAoaXNBcnJheShvYmplY3QpKSByZXR1cm4gZnJvbUFycmF5KHRoYXQsIG9iamVjdClcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdtdXN0IHN0YXJ0IHdpdGggbnVtYmVyLCBidWZmZXIsIGFycmF5IG9yIHN0cmluZycpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChvYmplY3QuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tVHlwZWRBcnJheSh0aGF0LCBvYmplY3QpXG4gICAgfVxuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCBvYmplY3QpXG4gICAgfVxuICB9XG5cbiAgaWYgKG9iamVjdC5sZW5ndGgpIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iamVjdClcblxuICByZXR1cm4gZnJvbUpzb25PYmplY3QodGhhdCwgb2JqZWN0KVxufVxuXG5mdW5jdGlvbiBmcm9tQnVmZmVyICh0aGF0LCBidWZmZXIpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYnVmZmVyLmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGJ1ZmZlci5jb3B5KHRoYXQsIDAsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5ICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuLy8gRHVwbGljYXRlIG9mIGZyb21BcnJheSgpIHRvIGtlZXAgZnJvbUFycmF5KCkgbW9ub21vcnBoaWMuXG5mdW5jdGlvbiBmcm9tVHlwZWRBcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgLy8gVHJ1bmNhdGluZyB0aGUgZWxlbWVudHMgaXMgcHJvYmFibHkgbm90IHdoYXQgcGVvcGxlIGV4cGVjdCBmcm9tIHR5cGVkXG4gIC8vIGFycmF5cyB3aXRoIEJZVEVTX1BFUl9FTEVNRU5UID4gMSBidXQgaXQncyBjb21wYXRpYmxlIHdpdGggdGhlIGJlaGF2aW9yXG4gIC8vIG9mIHRoZSBvbGQgQnVmZmVyIGNvbnN0cnVjdG9yLlxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyICh0aGF0LCBhcnJheSkge1xuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICBhcnJheS5ieXRlTGVuZ3RoXG4gICAgdGhhdCA9IEJ1ZmZlci5fYXVnbWVudChuZXcgVWludDhBcnJheShhcnJheSkpXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQgPSBmcm9tVHlwZWRBcnJheSh0aGF0LCBuZXcgVWludDhBcnJheShhcnJheSkpXG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5TGlrZSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIERlc2VyaWFsaXplIHsgdHlwZTogJ0J1ZmZlcicsIGRhdGE6IFsxLDIsMywuLi5dIH0gaW50byBhIEJ1ZmZlciBvYmplY3QuXG4vLyBSZXR1cm5zIGEgemVyby1sZW5ndGggYnVmZmVyIGZvciBpbnB1dHMgdGhhdCBkb24ndCBjb25mb3JtIHRvIHRoZSBzcGVjLlxuZnVuY3Rpb24gZnJvbUpzb25PYmplY3QgKHRoYXQsIG9iamVjdCkge1xuICB2YXIgYXJyYXlcbiAgdmFyIGxlbmd0aCA9IDBcblxuICBpZiAob2JqZWN0LnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkob2JqZWN0LmRhdGEpKSB7XG4gICAgYXJyYXkgPSBvYmplY3QuZGF0YVxuICAgIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgfVxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBhbGxvY2F0ZSAodGhhdCwgbGVuZ3RoKSB7XG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkobGVuZ3RoKSlcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgdGhhdC5sZW5ndGggPSBsZW5ndGhcbiAgICB0aGF0Ll9pc0J1ZmZlciA9IHRydWVcbiAgfVxuXG4gIHZhciBmcm9tUG9vbCA9IGxlbmd0aCAhPT0gMCAmJiBsZW5ndGggPD0gQnVmZmVyLnBvb2xTaXplID4+PiAxXG4gIGlmIChmcm9tUG9vbCkgdGhhdC5wYXJlbnQgPSByb290UGFyZW50XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IGtNYXhMZW5ndGhgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChzdWJqZWN0LCBlbmNvZGluZykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU2xvd0J1ZmZlcikpIHJldHVybiBuZXcgU2xvd0J1ZmZlcihzdWJqZWN0LCBlbmNvZGluZylcblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihzdWJqZWN0LCBlbmNvZGluZylcbiAgZGVsZXRlIGJ1Zi5wYXJlbnRcbiAgcmV0dXJuIGJ1ZlxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgdmFyIGkgPSAwXG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSBicmVha1xuXG4gICAgKytpXG4gIH1cblxuICBpZiAoaSAhPT0gbGVuKSB7XG4gICAgeCA9IGFbaV1cbiAgICB5ID0gYltpXVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIGlzRW5jb2RpbmcgKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICdyYXcnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gY29uY2F0IChsaXN0LCBsZW5ndGgpIHtcbiAgaWYgKCFpc0FycmF5KGxpc3QpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0IGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycy4nKVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV1cbiAgICBpdGVtLmNvcHkoYnVmLCBwb3MpXG4gICAgcG9zICs9IGl0ZW0ubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykgc3RyaW5nID0gJycgKyBzdHJpbmdcblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIC8vIERlcHJlY2F0ZWRcbiAgICAgIGNhc2UgJ3Jhdyc6XG4gICAgICBjYXNlICdyYXdzJzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbi8vIHByZS1zZXQgZm9yIHZhbHVlcyB0aGF0IG1heSBleGlzdCBpbiB0aGUgZnV0dXJlXG5CdWZmZXIucHJvdG90eXBlLmxlbmd0aCA9IHVuZGVmaW5lZFxuQnVmZmVyLnByb3RvdHlwZS5wYXJlbnQgPSB1bmRlZmluZWRcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIHN0YXJ0ID0gc3RhcnQgfCAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA9PT0gSW5maW5pdHkgPyB0aGlzLmxlbmd0aCA6IGVuZCB8IDBcblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAoZW5kIDw9IHN0YXJ0KSByZXR1cm4gJydcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBiaW5hcnlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIDBcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCkge1xuICBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIGJ5dGVPZmZzZXQgPj49IDBcblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAtMVxuICBpZiAoYnl0ZU9mZnNldCA+PSB0aGlzLmxlbmd0aCkgcmV0dXJuIC0xXG5cbiAgLy8gTmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBNYXRoLm1heCh0aGlzLmxlbmd0aCArIGJ5dGVPZmZzZXQsIDApXG5cbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHJldHVybiAtMSAvLyBzcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZyBhbHdheXMgZmFpbHNcbiAgICByZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mLmNhbGwodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZih0aGlzLCBbIHZhbCBdLCBieXRlT2Zmc2V0KVxuICB9XG5cbiAgZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCkge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKHZhciBpID0gMDsgYnl0ZU9mZnNldCArIGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhcnJbYnl0ZU9mZnNldCArIGldID09PSB2YWxbZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXhdKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsLmxlbmd0aCkgcmV0dXJuIGJ5dGVPZmZzZXQgKyBmb3VuZEluZGV4XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG4vLyBgZ2V0YCBpcyBkZXByZWNhdGVkXG5CdWZmZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldCAob2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuZ2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy5yZWFkVUludDgob2Zmc2V0KVxufVxuXG4vLyBgc2V0YCBpcyBkZXByZWNhdGVkXG5CdWZmZXIucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIHNldCAodiwgb2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuc2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy53cml0ZVVJbnQ4KHYsIG9mZnNldClcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChpc05hTihwYXJzZWQpKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiaW5hcnlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdmFyIHN3YXAgPSBlbmNvZGluZ1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgb2Zmc2V0ID0gbGVuZ3RoIHwgMFxuICAgIGxlbmd0aCA9IHN3YXBcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdhdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBiaW5hcnlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gQnVmZmVyLl9hdWdtZW50KHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZCkpXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgaSsrKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICBpZiAobmV3QnVmLmxlbmd0aCkgbmV3QnVmLnBhcmVudCA9IHRoaXMucGFyZW50IHx8IHRoaXNcblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2J1ZmZlciBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndmFsdWUgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgaSsrKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IHZhbHVlIDwgMCA/IDEgOiAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9IHZhbHVlXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcbiAgdmFyIGlcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBhc2NlbmRpbmcgY29weSBmcm9tIHN0YXJ0XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQuX3NldCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksIHRhcmdldFN0YXJ0KVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBmaWxsKHZhbHVlLCBzdGFydD0wLCBlbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbHVlLCBzdGFydCwgZW5kKSB7XG4gIGlmICghdmFsdWUpIHZhbHVlID0gMFxuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQpIGVuZCA9IHRoaXMubGVuZ3RoXG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignZW5kIDwgc3RhcnQnKVxuXG4gIC8vIEZpbGwgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuXG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3N0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCBvdXQgb2YgYm91bmRzJylcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIHRoaXNbaV0gPSB2YWx1ZVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSB1dGY4VG9CeXRlcyh2YWx1ZS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgYEFycmF5QnVmZmVyYCB3aXRoIHRoZSAqY29waWVkKiBtZW1vcnkgb2YgdGhlIGJ1ZmZlciBpbnN0YW5jZS5cbiAqIEFkZGVkIGluIE5vZGUgMC4xMi4gT25seSBhdmFpbGFibGUgaW4gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IEFycmF5QnVmZmVyLlxuICovXG5CdWZmZXIucHJvdG90eXBlLnRvQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiB0b0FycmF5QnVmZmVyICgpIHtcbiAgaWYgKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgICAgcmV0dXJuIChuZXcgQnVmZmVyKHRoaXMpKS5idWZmZXJcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGJ1ZiA9IG5ldyBVaW50OEFycmF5KHRoaXMubGVuZ3RoKVxuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGJ1Zi5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgICBidWZbaV0gPSB0aGlzW2ldXG4gICAgICB9XG4gICAgICByZXR1cm4gYnVmLmJ1ZmZlclxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCdWZmZXIudG9BcnJheUJ1ZmZlciBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlcicpXG4gIH1cbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgQlAgPSBCdWZmZXIucHJvdG90eXBlXG5cbi8qKlxuICogQXVnbWVudCBhIFVpbnQ4QXJyYXkgKmluc3RhbmNlKiAobm90IHRoZSBVaW50OEFycmF5IGNsYXNzISkgd2l0aCBCdWZmZXIgbWV0aG9kc1xuICovXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiBfYXVnbWVudCAoYXJyKSB7XG4gIGFyci5jb25zdHJ1Y3RvciA9IEJ1ZmZlclxuICBhcnIuX2lzQnVmZmVyID0gdHJ1ZVxuXG4gIC8vIHNhdmUgcmVmZXJlbmNlIHRvIG9yaWdpbmFsIFVpbnQ4QXJyYXkgc2V0IG1ldGhvZCBiZWZvcmUgb3ZlcndyaXRpbmdcbiAgYXJyLl9zZXQgPSBhcnIuc2V0XG5cbiAgLy8gZGVwcmVjYXRlZFxuICBhcnIuZ2V0ID0gQlAuZ2V0XG4gIGFyci5zZXQgPSBCUC5zZXRcblxuICBhcnIud3JpdGUgPSBCUC53cml0ZVxuICBhcnIudG9TdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9Mb2NhbGVTdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9KU09OID0gQlAudG9KU09OXG4gIGFyci5lcXVhbHMgPSBCUC5lcXVhbHNcbiAgYXJyLmNvbXBhcmUgPSBCUC5jb21wYXJlXG4gIGFyci5pbmRleE9mID0gQlAuaW5kZXhPZlxuICBhcnIuY29weSA9IEJQLmNvcHlcbiAgYXJyLnNsaWNlID0gQlAuc2xpY2VcbiAgYXJyLnJlYWRVSW50TEUgPSBCUC5yZWFkVUludExFXG4gIGFyci5yZWFkVUludEJFID0gQlAucmVhZFVJbnRCRVxuICBhcnIucmVhZFVJbnQ4ID0gQlAucmVhZFVJbnQ4XG4gIGFyci5yZWFkVUludDE2TEUgPSBCUC5yZWFkVUludDE2TEVcbiAgYXJyLnJlYWRVSW50MTZCRSA9IEJQLnJlYWRVSW50MTZCRVxuICBhcnIucmVhZFVJbnQzMkxFID0gQlAucmVhZFVJbnQzMkxFXG4gIGFyci5yZWFkVUludDMyQkUgPSBCUC5yZWFkVUludDMyQkVcbiAgYXJyLnJlYWRJbnRMRSA9IEJQLnJlYWRJbnRMRVxuICBhcnIucmVhZEludEJFID0gQlAucmVhZEludEJFXG4gIGFyci5yZWFkSW50OCA9IEJQLnJlYWRJbnQ4XG4gIGFyci5yZWFkSW50MTZMRSA9IEJQLnJlYWRJbnQxNkxFXG4gIGFyci5yZWFkSW50MTZCRSA9IEJQLnJlYWRJbnQxNkJFXG4gIGFyci5yZWFkSW50MzJMRSA9IEJQLnJlYWRJbnQzMkxFXG4gIGFyci5yZWFkSW50MzJCRSA9IEJQLnJlYWRJbnQzMkJFXG4gIGFyci5yZWFkRmxvYXRMRSA9IEJQLnJlYWRGbG9hdExFXG4gIGFyci5yZWFkRmxvYXRCRSA9IEJQLnJlYWRGbG9hdEJFXG4gIGFyci5yZWFkRG91YmxlTEUgPSBCUC5yZWFkRG91YmxlTEVcbiAgYXJyLnJlYWREb3VibGVCRSA9IEJQLnJlYWREb3VibGVCRVxuICBhcnIud3JpdGVVSW50OCA9IEJQLndyaXRlVUludDhcbiAgYXJyLndyaXRlVUludExFID0gQlAud3JpdGVVSW50TEVcbiAgYXJyLndyaXRlVUludEJFID0gQlAud3JpdGVVSW50QkVcbiAgYXJyLndyaXRlVUludDE2TEUgPSBCUC53cml0ZVVJbnQxNkxFXG4gIGFyci53cml0ZVVJbnQxNkJFID0gQlAud3JpdGVVSW50MTZCRVxuICBhcnIud3JpdGVVSW50MzJMRSA9IEJQLndyaXRlVUludDMyTEVcbiAgYXJyLndyaXRlVUludDMyQkUgPSBCUC53cml0ZVVJbnQzMkJFXG4gIGFyci53cml0ZUludExFID0gQlAud3JpdGVJbnRMRVxuICBhcnIud3JpdGVJbnRCRSA9IEJQLndyaXRlSW50QkVcbiAgYXJyLndyaXRlSW50OCA9IEJQLndyaXRlSW50OFxuICBhcnIud3JpdGVJbnQxNkxFID0gQlAud3JpdGVJbnQxNkxFXG4gIGFyci53cml0ZUludDE2QkUgPSBCUC53cml0ZUludDE2QkVcbiAgYXJyLndyaXRlSW50MzJMRSA9IEJQLndyaXRlSW50MzJMRVxuICBhcnIud3JpdGVJbnQzMkJFID0gQlAud3JpdGVJbnQzMkJFXG4gIGFyci53cml0ZUZsb2F0TEUgPSBCUC53cml0ZUZsb2F0TEVcbiAgYXJyLndyaXRlRmxvYXRCRSA9IEJQLndyaXRlRmxvYXRCRVxuICBhcnIud3JpdGVEb3VibGVMRSA9IEJQLndyaXRlRG91YmxlTEVcbiAgYXJyLndyaXRlRG91YmxlQkUgPSBCUC53cml0ZURvdWJsZUJFXG4gIGFyci5maWxsID0gQlAuZmlsbFxuICBhcnIuaW5zcGVjdCA9IEJQLmluc3BlY3RcbiAgYXJyLnRvQXJyYXlCdWZmZXIgPSBCUC50b0FycmF5QnVmZmVyXG5cbiAgcmV0dXJuIGFyclxufVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSBsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwIHwgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG4iLCJ2YXIgbG9va3VwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuICB2YXIgQXJyID0gKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJylcbiAgICA/IFVpbnQ4QXJyYXlcbiAgICA6IEFycmF5XG5cblx0dmFyIFBMVVMgICA9ICcrJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSCAgPSAnLycuY2hhckNvZGVBdCgwKVxuXHR2YXIgTlVNQkVSID0gJzAnLmNoYXJDb2RlQXQoMClcblx0dmFyIExPV0VSICA9ICdhJy5jaGFyQ29kZUF0KDApXG5cdHZhciBVUFBFUiAgPSAnQScuY2hhckNvZGVBdCgwKVxuXHR2YXIgUExVU19VUkxfU0FGRSA9ICctJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSF9VUkxfU0FGRSA9ICdfJy5jaGFyQ29kZUF0KDApXG5cblx0ZnVuY3Rpb24gZGVjb2RlIChlbHQpIHtcblx0XHR2YXIgY29kZSA9IGVsdC5jaGFyQ29kZUF0KDApXG5cdFx0aWYgKGNvZGUgPT09IFBMVVMgfHxcblx0XHQgICAgY29kZSA9PT0gUExVU19VUkxfU0FGRSlcblx0XHRcdHJldHVybiA2MiAvLyAnKydcblx0XHRpZiAoY29kZSA9PT0gU0xBU0ggfHxcblx0XHQgICAgY29kZSA9PT0gU0xBU0hfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjMgLy8gJy8nXG5cdFx0aWYgKGNvZGUgPCBOVU1CRVIpXG5cdFx0XHRyZXR1cm4gLTEgLy9ubyBtYXRjaFxuXHRcdGlmIChjb2RlIDwgTlVNQkVSICsgMTApXG5cdFx0XHRyZXR1cm4gY29kZSAtIE5VTUJFUiArIDI2ICsgMjZcblx0XHRpZiAoY29kZSA8IFVQUEVSICsgMjYpXG5cdFx0XHRyZXR1cm4gY29kZSAtIFVQUEVSXG5cdFx0aWYgKGNvZGUgPCBMT1dFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBMT1dFUiArIDI2XG5cdH1cblxuXHRmdW5jdGlvbiBiNjRUb0J5dGVBcnJheSAoYjY0KSB7XG5cdFx0dmFyIGksIGosIGwsIHRtcCwgcGxhY2VIb2xkZXJzLCBhcnJcblxuXHRcdGlmIChiNjQubGVuZ3RoICUgNCA+IDApIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG5cdFx0fVxuXG5cdFx0Ly8gdGhlIG51bWJlciBvZiBlcXVhbCBzaWducyAocGxhY2UgaG9sZGVycylcblx0XHQvLyBpZiB0aGVyZSBhcmUgdHdvIHBsYWNlaG9sZGVycywgdGhhbiB0aGUgdHdvIGNoYXJhY3RlcnMgYmVmb3JlIGl0XG5cdFx0Ly8gcmVwcmVzZW50IG9uZSBieXRlXG5cdFx0Ly8gaWYgdGhlcmUgaXMgb25seSBvbmUsIHRoZW4gdGhlIHRocmVlIGNoYXJhY3RlcnMgYmVmb3JlIGl0IHJlcHJlc2VudCAyIGJ5dGVzXG5cdFx0Ly8gdGhpcyBpcyBqdXN0IGEgY2hlYXAgaGFjayB0byBub3QgZG8gaW5kZXhPZiB0d2ljZVxuXHRcdHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cdFx0cGxhY2VIb2xkZXJzID0gJz0nID09PSBiNjQuY2hhckF0KGxlbiAtIDIpID8gMiA6ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAxKSA/IDEgOiAwXG5cblx0XHQvLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcblx0XHRhcnIgPSBuZXcgQXJyKGI2NC5sZW5ndGggKiAzIC8gNCAtIHBsYWNlSG9sZGVycylcblxuXHRcdC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcblx0XHRsID0gcGxhY2VIb2xkZXJzID4gMCA/IGI2NC5sZW5ndGggLSA0IDogYjY0Lmxlbmd0aFxuXG5cdFx0dmFyIEwgPSAwXG5cblx0XHRmdW5jdGlvbiBwdXNoICh2KSB7XG5cdFx0XHRhcnJbTCsrXSA9IHZcblx0XHR9XG5cblx0XHRmb3IgKGkgPSAwLCBqID0gMDsgaSA8IGw7IGkgKz0gNCwgaiArPSAzKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDE4KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDEyKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpIDw8IDYpIHwgZGVjb2RlKGI2NC5jaGFyQXQoaSArIDMpKVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwMDApID4+IDE2KVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwKSA+PiA4KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA+PiA0KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH0gZWxzZSBpZiAocGxhY2VIb2xkZXJzID09PSAxKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDEwKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDQpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAyKSkgPj4gMilcblx0XHRcdHB1c2goKHRtcCA+PiA4KSAmIDB4RkYpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFyclxuXHR9XG5cblx0ZnVuY3Rpb24gdWludDhUb0Jhc2U2NCAodWludDgpIHtcblx0XHR2YXIgaSxcblx0XHRcdGV4dHJhQnl0ZXMgPSB1aW50OC5sZW5ndGggJSAzLCAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuXHRcdFx0b3V0cHV0ID0gXCJcIixcblx0XHRcdHRlbXAsIGxlbmd0aFxuXG5cdFx0ZnVuY3Rpb24gZW5jb2RlIChudW0pIHtcblx0XHRcdHJldHVybiBsb29rdXAuY2hhckF0KG51bSlcblx0XHR9XG5cblx0XHRmdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuXHRcdFx0cmV0dXJuIGVuY29kZShudW0gPj4gMTggJiAweDNGKSArIGVuY29kZShudW0gPj4gMTIgJiAweDNGKSArIGVuY29kZShudW0gPj4gNiAmIDB4M0YpICsgZW5jb2RlKG51bSAmIDB4M0YpXG5cdFx0fVxuXG5cdFx0Ly8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuXHRcdGZvciAoaSA9IDAsIGxlbmd0aCA9IHVpbnQ4Lmxlbmd0aCAtIGV4dHJhQnl0ZXM7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuXHRcdFx0dGVtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSlcblx0XHRcdG91dHB1dCArPSB0cmlwbGV0VG9CYXNlNjQodGVtcClcblx0XHR9XG5cblx0XHQvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG5cdFx0c3dpdGNoIChleHRyYUJ5dGVzKSB7XG5cdFx0XHRjYXNlIDE6XG5cdFx0XHRcdHRlbXAgPSB1aW50OFt1aW50OC5sZW5ndGggLSAxXVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMilcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSAnPT0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0XHRjYXNlIDI6XG5cdFx0XHRcdHRlbXAgPSAodWludDhbdWludDgubGVuZ3RoIC0gMl0gPDwgOCkgKyAodWludDhbdWludDgubGVuZ3RoIC0gMV0pXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAxMClcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA+PiA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgMikgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dFxuXHR9XG5cblx0ZXhwb3J0cy50b0J5dGVBcnJheSA9IGI2NFRvQnl0ZUFycmF5XG5cdGV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IHVpbnQ4VG9CYXNlNjRcbn0odHlwZW9mIGV4cG9ydHMgPT09ICd1bmRlZmluZWQnID8gKHRoaXMuYmFzZTY0anMgPSB7fSkgOiBleHBvcnRzKSlcbiIsImV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwiXG4vKipcbiAqIGlzQXJyYXlcbiAqL1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbi8qKlxuICogdG9TdHJpbmdcbiAqL1xuXG52YXIgc3RyID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLyoqXG4gKiBXaGV0aGVyIG9yIG5vdCB0aGUgZ2l2ZW4gYHZhbGBcbiAqIGlzIGFuIGFycmF5LlxuICpcbiAqIGV4YW1wbGU6XG4gKlxuICogICAgICAgIGlzQXJyYXkoW10pO1xuICogICAgICAgIC8vID4gdHJ1ZVxuICogICAgICAgIGlzQXJyYXkoYXJndW1lbnRzKTtcbiAqICAgICAgICAvLyA+IGZhbHNlXG4gKiAgICAgICAgaXNBcnJheSgnJyk7XG4gKiAgICAgICAgLy8gPiBmYWxzZVxuICpcbiAqIEBwYXJhbSB7bWl4ZWR9IHZhbFxuICogQHJldHVybiB7Ym9vbH1cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJyYXkgfHwgZnVuY3Rpb24gKHZhbCkge1xuICByZXR1cm4gISEgdmFsICYmICdbb2JqZWN0IEFycmF5XScgPT0gc3RyLmNhbGwodmFsKTtcbn07XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuKGZ1bmN0aW9uICgpIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIGZ1bmN0aW9uIENvb2tpZUFjY2Vzc0luZm8oZG9tYWluLCBwYXRoLCBzZWN1cmUsIHNjcmlwdCkge1xuICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIENvb2tpZUFjY2Vzc0luZm8pIHtcbiAgICAgICAgICAgIHRoaXMuZG9tYWluID0gZG9tYWluIHx8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMucGF0aCA9IHBhdGggfHwgXCIvXCI7XG4gICAgICAgICAgICB0aGlzLnNlY3VyZSA9ICEhc2VjdXJlO1xuICAgICAgICAgICAgdGhpcy5zY3JpcHQgPSAhIXNjcmlwdDtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ29va2llQWNjZXNzSW5mbyhkb21haW4sIHBhdGgsIHNlY3VyZSwgc2NyaXB0KTtcbiAgICB9XG4gICAgZXhwb3J0cy5Db29raWVBY2Nlc3NJbmZvID0gQ29va2llQWNjZXNzSW5mbztcblxuICAgIGZ1bmN0aW9uIENvb2tpZShjb29raWVzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpIHtcbiAgICAgICAgaWYgKGNvb2tpZXN0ciBpbnN0YW5jZW9mIENvb2tpZSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvb2tpZXN0cjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIENvb2tpZSkge1xuICAgICAgICAgICAgdGhpcy5uYW1lID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5leHBpcmF0aW9uX2RhdGUgPSBJbmZpbml0eTtcbiAgICAgICAgICAgIHRoaXMucGF0aCA9IFN0cmluZyhyZXF1ZXN0X3BhdGggfHwgXCIvXCIpO1xuICAgICAgICAgICAgdGhpcy5leHBsaWNpdF9wYXRoID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmRvbWFpbiA9IHJlcXVlc3RfZG9tYWluIHx8IG51bGw7XG4gICAgICAgICAgICB0aGlzLmV4cGxpY2l0X2RvbWFpbiA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSBmYWxzZTsgLy9ob3cgdG8gZGVmaW5lIGRlZmF1bHQ/XG4gICAgICAgICAgICB0aGlzLm5vc2NyaXB0ID0gZmFsc2U7IC8vaHR0cG9ubHlcbiAgICAgICAgICAgIGlmIChjb29raWVzdHIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBhcnNlKGNvb2tpZXN0ciwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZShjb29raWVzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgIH1cbiAgICBleHBvcnRzLkNvb2tpZSA9IENvb2tpZTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgdmFyIHN0ciA9IFt0aGlzLm5hbWUgKyBcIj1cIiArIHRoaXMudmFsdWVdO1xuICAgICAgICBpZiAodGhpcy5leHBpcmF0aW9uX2RhdGUgIT09IEluZmluaXR5KSB7XG4gICAgICAgICAgICBzdHIucHVzaChcImV4cGlyZXM9XCIgKyAobmV3IERhdGUodGhpcy5leHBpcmF0aW9uX2RhdGUpKS50b0dNVFN0cmluZygpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5kb21haW4pIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwiZG9tYWluPVwiICsgdGhpcy5kb21haW4pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnBhdGgpIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwicGF0aD1cIiArIHRoaXMucGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc2VjdXJlKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcInNlY3VyZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5ub3NjcmlwdCkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJodHRwb25seVwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RyLmpvaW4oXCI7IFwiKTtcbiAgICB9O1xuXG4gICAgQ29va2llLnByb3RvdHlwZS50b1ZhbHVlU3RyaW5nID0gZnVuY3Rpb24gdG9WYWx1ZVN0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZSArIFwiPVwiICsgdGhpcy52YWx1ZTtcbiAgICB9O1xuXG4gICAgdmFyIGNvb2tpZV9zdHJfc3BsaXR0ZXIgPSAvWzpdKD89XFxzKlthLXpBLVowLTlfXFwtXStcXHMqWz1dKS9nO1xuICAgIENvb2tpZS5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiBwYXJzZShzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpIHtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdChcIjtcIikuZmlsdGVyKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gISF2YWx1ZTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBwYWlyID0gcGFydHNbMF0ubWF0Y2goLyhbXj1dKyk9KFtcXHNcXFNdKikvKSxcbiAgICAgICAgICAgICAgICBrZXkgPSBwYWlyWzFdLFxuICAgICAgICAgICAgICAgIHZhbHVlID0gcGFpclsyXSxcbiAgICAgICAgICAgICAgICBpO1xuICAgICAgICAgICAgdGhpcy5uYW1lID0ga2V5O1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgcGFydHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBwYWlyID0gcGFydHNbaV0ubWF0Y2goLyhbXj1dKykoPzo9KFtcXHNcXFNdKikpPy8pO1xuICAgICAgICAgICAgICAgIGtleSA9IHBhaXJbMV0udHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwYWlyWzJdO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcImh0dHBvbmx5XCI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubm9zY3JpcHQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwiZXhwaXJlc1wiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cGlyYXRpb25fZGF0ZSA9IHZhbHVlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1iZXIoRGF0ZS5wYXJzZSh2YWx1ZSkpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmZpbml0eTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInBhdGhcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXRoID0gdmFsdWUgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnRyaW0oKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJcIjtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBsaWNpdF9wYXRoID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImRvbWFpblwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRvbWFpbiA9IHZhbHVlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS50cmltKCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXCI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfZG9tYWluID0gISF0aGlzLmRvbWFpbjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInNlY3VyZVwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlY3VyZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF0aGlzLmV4cGxpY2l0X3BhdGgpIHtcbiAgICAgICAgICAgICAgIHRoaXMucGF0aCA9IHJlcXVlc3RfcGF0aCB8fCBcIi9cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdGhpcy5leHBsaWNpdF9kb21haW4pIHtcbiAgICAgICAgICAgICAgIHRoaXMuZG9tYWluID0gcmVxdWVzdF9kb21haW47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ29va2llKCkucGFyc2Uoc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICB9O1xuXG4gICAgQ29va2llLnByb3RvdHlwZS5tYXRjaGVzID0gZnVuY3Rpb24gbWF0Y2hlcyhhY2Nlc3NfaW5mbykge1xuICAgICAgICBpZiAodGhpcy5ub3NjcmlwdCAmJiBhY2Nlc3NfaW5mby5zY3JpcHQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLnNlY3VyZSAmJiAhYWNjZXNzX2luZm8uc2VjdXJlIHx8XG4gICAgICAgICAgICAgICAgIXRoaXMuY29sbGlkZXNXaXRoKGFjY2Vzc19pbmZvKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG5cbiAgICBDb29raWUucHJvdG90eXBlLmNvbGxpZGVzV2l0aCA9IGZ1bmN0aW9uIGNvbGxpZGVzV2l0aChhY2Nlc3NfaW5mbykge1xuICAgICAgICBpZiAoKHRoaXMucGF0aCAmJiAhYWNjZXNzX2luZm8ucGF0aCkgfHwgKHRoaXMuZG9tYWluICYmICFhY2Nlc3NfaW5mby5kb21haW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucGF0aCAmJiBhY2Nlc3NfaW5mby5wYXRoLmluZGV4T2YodGhpcy5wYXRoKSAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmV4cGxpY2l0X3BhdGggJiYgYWNjZXNzX2luZm8ucGF0aC5pbmRleE9mKCB0aGlzLnBhdGggKSAhPT0gMCkge1xuICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFjY2Vzc19kb21haW4gPSBhY2Nlc3NfaW5mby5kb21haW4gJiYgYWNjZXNzX2luZm8uZG9tYWluLnJlcGxhY2UoL15bXFwuXS8sJycpO1xuICAgICAgICB2YXIgY29va2llX2RvbWFpbiA9IHRoaXMuZG9tYWluICYmIHRoaXMuZG9tYWluLnJlcGxhY2UoL15bXFwuXS8sJycpO1xuICAgICAgICBpZiAoY29va2llX2RvbWFpbiA9PT0gYWNjZXNzX2RvbWFpbikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvb2tpZV9kb21haW4pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5leHBsaWNpdF9kb21haW4pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIHdlIGFscmVhZHkgY2hlY2tlZCBpZiB0aGUgZG9tYWlucyB3ZXJlIGV4YWN0bHkgdGhlIHNhbWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB3aWxkY2FyZCA9IGFjY2Vzc19kb21haW4uaW5kZXhPZihjb29raWVfZG9tYWluKTtcbiAgICAgICAgICAgIGlmICh3aWxkY2FyZCA9PT0gLTEgfHwgd2lsZGNhcmQgIT09IGFjY2Vzc19kb21haW4ubGVuZ3RoIC0gY29va2llX2RvbWFpbi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gQ29va2llSmFyKCkge1xuICAgICAgICB2YXIgY29va2llcywgY29va2llc19saXN0LCBjb2xsaWRhYmxlX2Nvb2tpZTtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWVKYXIpIHtcbiAgICAgICAgICAgIGNvb2tpZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpOyAvL25hbWU6IFtDb29raWVdXG5cbiAgICAgICAgICAgIHRoaXMuc2V0Q29va2llID0gZnVuY3Rpb24gc2V0Q29va2llKGNvb2tpZSwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICAgICAgICAgIHZhciByZW1vdmUsIGk7XG4gICAgICAgICAgICAgICAgY29va2llID0gbmV3IENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICAgICAgICAgIC8vRGVsZXRlIHRoZSBjb29raWUgaWYgdGhlIHNldCBpcyBwYXN0IHRoZSBjdXJyZW50IHRpbWVcbiAgICAgICAgICAgICAgICByZW1vdmUgPSBjb29raWUuZXhwaXJhdGlvbl9kYXRlIDw9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNbY29va2llLm5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0ID0gY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb29raWVzX2xpc3QubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxpZGFibGVfY29va2llID0gY29va2llc19saXN0W2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbGxpZGFibGVfY29va2llLmNvbGxpZGVzV2l0aChjb29raWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29raWVzX2xpc3Quc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llc19saXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0W2ldID0gY29va2llO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb29raWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdC5wdXNoKGNvb2tpZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb29raWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb29raWVzW2Nvb2tpZS5uYW1lXSA9IFtjb29raWVdO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb29raWVzW2Nvb2tpZS5uYW1lXTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvL3JldHVybnMgYSBjb29raWVcbiAgICAgICAgICAgIHRoaXMuZ2V0Q29va2llID0gZnVuY3Rpb24gZ2V0Q29va2llKGNvb2tpZV9uYW1lLCBhY2Nlc3NfaW5mbykge1xuICAgICAgICAgICAgICAgIHZhciBjb29raWUsIGk7XG4gICAgICAgICAgICAgICAgY29va2llc19saXN0ID0gY29va2llc1tjb29raWVfbmFtZV07XG4gICAgICAgICAgICAgICAgaWYgKCFjb29raWVzX2xpc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llc19saXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZSA9IGNvb2tpZXNfbGlzdFtpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZS5leHBpcmF0aW9uX2RhdGUgPD0gRGF0ZS5ub3coKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNfbGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUubWF0Y2hlcyhhY2Nlc3NfaW5mbykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb29raWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy9yZXR1cm5zIGEgbGlzdCBvZiBjb29raWVzXG4gICAgICAgICAgICB0aGlzLmdldENvb2tpZXMgPSBmdW5jdGlvbiBnZXRDb29raWVzKGFjY2Vzc19pbmZvKSB7XG4gICAgICAgICAgICAgICAgdmFyIG1hdGNoZXMgPSBbXSwgY29va2llX25hbWUsIGNvb2tpZTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvb2tpZV9uYW1lIGluIGNvb2tpZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29va2llID0gdGhpcy5nZXRDb29raWUoY29va2llX25hbWUsIGFjY2Vzc19pbmZvKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hlcy5wdXNoKGNvb2tpZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbWF0Y2hlcy50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcy5qb2luKFwiOlwiKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG1hdGNoZXMudG9WYWx1ZVN0cmluZyA9IGZ1bmN0aW9uIHRvVmFsdWVTdHJpbmcoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaGVzLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMudG9WYWx1ZVN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICB9KS5qb2luKCc7Jyk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcztcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQ29va2llSmFyKCk7XG4gICAgfVxuICAgIGV4cG9ydHMuQ29va2llSmFyID0gQ29va2llSmFyO1xuXG4gICAgLy9yZXR1cm5zIGxpc3Qgb2YgY29va2llcyB0aGF0IHdlcmUgc2V0IGNvcnJlY3RseS4gQ29va2llcyB0aGF0IGFyZSBleHBpcmVkIGFuZCByZW1vdmVkIGFyZSBub3QgcmV0dXJuZWQuXG4gICAgQ29va2llSmFyLnByb3RvdHlwZS5zZXRDb29raWVzID0gZnVuY3Rpb24gc2V0Q29va2llcyhjb29raWVzLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGNvb2tpZXMgPSBBcnJheS5pc0FycmF5KGNvb2tpZXMpID9cbiAgICAgICAgICAgICAgICBjb29raWVzIDpcbiAgICAgICAgICAgICAgICBjb29raWVzLnNwbGl0KGNvb2tpZV9zdHJfc3BsaXR0ZXIpO1xuICAgICAgICB2YXIgc3VjY2Vzc2Z1bCA9IFtdLFxuICAgICAgICAgICAgaSxcbiAgICAgICAgICAgIGNvb2tpZTtcbiAgICAgICAgY29va2llcyA9IGNvb2tpZXMubWFwKGZ1bmN0aW9uKGl0ZW0pe1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBDb29raWUoaXRlbSwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCk7XG4gICAgICAgIH0pO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgY29va2llID0gY29va2llc1tpXTtcbiAgICAgICAgICAgIGlmICh0aGlzLnNldENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpKSB7XG4gICAgICAgICAgICAgICAgc3VjY2Vzc2Z1bC5wdXNoKGNvb2tpZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3NmdWw7XG4gICAgfTtcbn0oKSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIHlhbWwgPSByZXF1aXJlKCcuL2xpYi9qcy15YW1sLmpzJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB5YW1sO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBsb2FkZXIgPSByZXF1aXJlKCcuL2pzLXlhbWwvbG9hZGVyJyk7XG52YXIgZHVtcGVyID0gcmVxdWlyZSgnLi9qcy15YW1sL2R1bXBlcicpO1xuXG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZWQobmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRnVuY3Rpb24gJyArIG5hbWUgKyAnIGlzIGRlcHJlY2F0ZWQgYW5kIGNhbm5vdCBiZSB1c2VkLicpO1xuICB9O1xufVxuXG5cbm1vZHVsZS5leHBvcnRzLlR5cGUgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvdHlwZScpO1xubW9kdWxlLmV4cG9ydHMuU2NoZW1hICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEnKTtcbm1vZHVsZS5leHBvcnRzLkZBSUxTQUZFX1NDSEVNQSAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2ZhaWxzYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5KU09OX1NDSEVNQSAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9qc29uJyk7XG5tb2R1bGUuZXhwb3J0cy5DT1JFX1NDSEVNQSAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9jb3JlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTtcbm1vZHVsZS5leHBvcnRzLkRFRkFVTFRfRlVMTF9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbCcpO1xubW9kdWxlLmV4cG9ydHMubG9hZCAgICAgICAgICAgICAgICA9IGxvYWRlci5sb2FkO1xubW9kdWxlLmV4cG9ydHMubG9hZEFsbCAgICAgICAgICAgICA9IGxvYWRlci5sb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMuc2FmZUxvYWQgICAgICAgICAgICA9IGxvYWRlci5zYWZlTG9hZDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkQWxsICAgICAgICAgPSBsb2FkZXIuc2FmZUxvYWRBbGw7XG5tb2R1bGUuZXhwb3J0cy5kdW1wICAgICAgICAgICAgICAgID0gZHVtcGVyLmR1bXA7XG5tb2R1bGUuZXhwb3J0cy5zYWZlRHVtcCAgICAgICAgICAgID0gZHVtcGVyLnNhZmVEdW1wO1xubW9kdWxlLmV4cG9ydHMuWUFNTEV4Y2VwdGlvbiAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9leGNlcHRpb24nKTtcblxuLy8gRGVwcmVjYXRlZCBzY2hlbWEgbmFtZXMgZnJvbSBKUy1ZQU1MIDIuMC54XG5tb2R1bGUuZXhwb3J0cy5NSU5JTUFMX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZmFpbHNhZmUnKTtcbm1vZHVsZS5leHBvcnRzLlNBRkVfU0NIRU1BICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTtcbm1vZHVsZS5leHBvcnRzLkRFRkFVTFRfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTtcblxuLy8gRGVwcmVjYXRlZCBmdW5jdGlvbnMgZnJvbSBKUy1ZQU1MIDEueC54XG5tb2R1bGUuZXhwb3J0cy5zY2FuICAgICAgICAgICA9IGRlcHJlY2F0ZWQoJ3NjYW4nKTtcbm1vZHVsZS5leHBvcnRzLnBhcnNlICAgICAgICAgID0gZGVwcmVjYXRlZCgncGFyc2UnKTtcbm1vZHVsZS5leHBvcnRzLmNvbXBvc2UgICAgICAgID0gZGVwcmVjYXRlZCgnY29tcG9zZScpO1xubW9kdWxlLmV4cG9ydHMuYWRkQ29uc3RydWN0b3IgPSBkZXByZWNhdGVkKCdhZGRDb25zdHJ1Y3RvcicpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbmZ1bmN0aW9uIGlzTm90aGluZyhzdWJqZWN0KSB7XG4gIHJldHVybiAodHlwZW9mIHN1YmplY3QgPT09ICd1bmRlZmluZWQnKSB8fCAoc3ViamVjdCA9PT0gbnVsbCk7XG59XG5cblxuZnVuY3Rpb24gaXNPYmplY3Qoc3ViamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBzdWJqZWN0ID09PSAnb2JqZWN0JykgJiYgKHN1YmplY3QgIT09IG51bGwpO1xufVxuXG5cbmZ1bmN0aW9uIHRvQXJyYXkoc2VxdWVuY2UpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoc2VxdWVuY2UpKSByZXR1cm4gc2VxdWVuY2U7XG4gIGVsc2UgaWYgKGlzTm90aGluZyhzZXF1ZW5jZSkpIHJldHVybiBbXTtcblxuICByZXR1cm4gWyBzZXF1ZW5jZSBdO1xufVxuXG5cbmZ1bmN0aW9uIGV4dGVuZCh0YXJnZXQsIHNvdXJjZSkge1xuICB2YXIgaW5kZXgsIGxlbmd0aCwga2V5LCBzb3VyY2VLZXlzO1xuXG4gIGlmIChzb3VyY2UpIHtcbiAgICBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBzb3VyY2VLZXlzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGtleSA9IHNvdXJjZUtleXNbaW5kZXhdO1xuICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5cbmZ1bmN0aW9uIHJlcGVhdChzdHJpbmcsIGNvdW50KSB7XG4gIHZhciByZXN1bHQgPSAnJywgY3ljbGU7XG5cbiAgZm9yIChjeWNsZSA9IDA7IGN5Y2xlIDwgY291bnQ7IGN5Y2xlICs9IDEpIHtcbiAgICByZXN1bHQgKz0gc3RyaW5nO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG5mdW5jdGlvbiBpc05lZ2F0aXZlWmVybyhudW1iZXIpIHtcbiAgcmV0dXJuIChudW1iZXIgPT09IDApICYmIChOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkgPT09IDEgLyBudW1iZXIpO1xufVxuXG5cbm1vZHVsZS5leHBvcnRzLmlzTm90aGluZyAgICAgID0gaXNOb3RoaW5nO1xubW9kdWxlLmV4cG9ydHMuaXNPYmplY3QgICAgICAgPSBpc09iamVjdDtcbm1vZHVsZS5leHBvcnRzLnRvQXJyYXkgICAgICAgID0gdG9BcnJheTtcbm1vZHVsZS5leHBvcnRzLnJlcGVhdCAgICAgICAgID0gcmVwZWF0O1xubW9kdWxlLmV4cG9ydHMuaXNOZWdhdGl2ZVplcm8gPSBpc05lZ2F0aXZlWmVybztcbm1vZHVsZS5leHBvcnRzLmV4dGVuZCAgICAgICAgID0gZXh0ZW5kO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG5vLXVzZS1iZWZvcmUtZGVmaW5lKi9cblxudmFyIGNvbW1vbiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIFlBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xudmFyIERFRkFVTFRfRlVMTF9TQ0hFTUEgPSByZXF1aXJlKCcuL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTtcbnZhciBERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5cbnZhciBfdG9TdHJpbmcgICAgICAgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIF9oYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBDSEFSX1RBQiAgICAgICAgICAgICAgICAgID0gMHgwOTsgLyogVGFiICovXG52YXIgQ0hBUl9MSU5FX0ZFRUQgICAgICAgICAgICA9IDB4MEE7IC8qIExGICovXG52YXIgQ0hBUl9TUEFDRSAgICAgICAgICAgICAgICA9IDB4MjA7IC8qIFNwYWNlICovXG52YXIgQ0hBUl9FWENMQU1BVElPTiAgICAgICAgICA9IDB4MjE7IC8qICEgKi9cbnZhciBDSEFSX0RPVUJMRV9RVU9URSAgICAgICAgID0gMHgyMjsgLyogXCIgKi9cbnZhciBDSEFSX1NIQVJQICAgICAgICAgICAgICAgID0gMHgyMzsgLyogIyAqL1xudmFyIENIQVJfUEVSQ0VOVCAgICAgICAgICAgICAgPSAweDI1OyAvKiAlICovXG52YXIgQ0hBUl9BTVBFUlNBTkQgICAgICAgICAgICA9IDB4MjY7IC8qICYgKi9cbnZhciBDSEFSX1NJTkdMRV9RVU9URSAgICAgICAgID0gMHgyNzsgLyogJyAqL1xudmFyIENIQVJfQVNURVJJU0sgICAgICAgICAgICAgPSAweDJBOyAvKiAqICovXG52YXIgQ0hBUl9DT01NQSAgICAgICAgICAgICAgICA9IDB4MkM7IC8qICwgKi9cbnZhciBDSEFSX01JTlVTICAgICAgICAgICAgICAgID0gMHgyRDsgLyogLSAqL1xudmFyIENIQVJfQ09MT04gICAgICAgICAgICAgICAgPSAweDNBOyAvKiA6ICovXG52YXIgQ0hBUl9HUkVBVEVSX1RIQU4gICAgICAgICA9IDB4M0U7IC8qID4gKi9cbnZhciBDSEFSX1FVRVNUSU9OICAgICAgICAgICAgID0gMHgzRjsgLyogPyAqL1xudmFyIENIQVJfQ09NTUVSQ0lBTF9BVCAgICAgICAgPSAweDQwOyAvKiBAICovXG52YXIgQ0hBUl9MRUZUX1NRVUFSRV9CUkFDS0VUICA9IDB4NUI7IC8qIFsgKi9cbnZhciBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUID0gMHg1RDsgLyogXSAqL1xudmFyIENIQVJfR1JBVkVfQUNDRU5UICAgICAgICAgPSAweDYwOyAvKiBgICovXG52YXIgQ0hBUl9MRUZUX0NVUkxZX0JSQUNLRVQgICA9IDB4N0I7IC8qIHsgKi9cbnZhciBDSEFSX1ZFUlRJQ0FMX0xJTkUgICAgICAgID0gMHg3QzsgLyogfCAqL1xudmFyIENIQVJfUklHSFRfQ1VSTFlfQlJBQ0tFVCAgPSAweDdEOyAvKiB9ICovXG5cbnZhciBFU0NBUEVfU0VRVUVOQ0VTID0ge307XG5cbkVTQ0FQRV9TRVFVRU5DRVNbMHgwMF0gICA9ICdcXFxcMCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDddICAgPSAnXFxcXGEnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDA4XSAgID0gJ1xcXFxiJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwOV0gICA9ICdcXFxcdCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MEFdICAgPSAnXFxcXG4nO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBCXSAgID0gJ1xcXFx2JztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwQ10gICA9ICdcXFxcZic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MERdICAgPSAnXFxcXHInO1xuRVNDQVBFX1NFUVVFTkNFU1sweDFCXSAgID0gJ1xcXFxlJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgyMl0gICA9ICdcXFxcXCInO1xuRVNDQVBFX1NFUVVFTkNFU1sweDVDXSAgID0gJ1xcXFxcXFxcJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHg4NV0gICA9ICdcXFxcTic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4QTBdICAgPSAnXFxcXF8nO1xuRVNDQVBFX1NFUVVFTkNFU1sweDIwMjhdID0gJ1xcXFxMJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgyMDI5XSA9ICdcXFxcUCc7XG5cbnZhciBERVBSRUNBVEVEX0JPT0xFQU5TX1NZTlRBWCA9IFtcbiAgJ3knLCAnWScsICd5ZXMnLCAnWWVzJywgJ1lFUycsICdvbicsICdPbicsICdPTicsXG4gICduJywgJ04nLCAnbm8nLCAnTm8nLCAnTk8nLCAnb2ZmJywgJ09mZicsICdPRkYnXG5dO1xuXG5mdW5jdGlvbiBjb21waWxlU3R5bGVNYXAoc2NoZW1hLCBtYXApIHtcbiAgdmFyIHJlc3VsdCwga2V5cywgaW5kZXgsIGxlbmd0aCwgdGFnLCBzdHlsZSwgdHlwZTtcblxuICBpZiAobWFwID09PSBudWxsKSByZXR1cm4ge307XG5cbiAgcmVzdWx0ID0ge307XG4gIGtleXMgPSBPYmplY3Qua2V5cyhtYXApO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICB0YWcgPSBrZXlzW2luZGV4XTtcbiAgICBzdHlsZSA9IFN0cmluZyhtYXBbdGFnXSk7XG5cbiAgICBpZiAodGFnLnNsaWNlKDAsIDIpID09PSAnISEnKSB7XG4gICAgICB0YWcgPSAndGFnOnlhbWwub3JnLDIwMDI6JyArIHRhZy5zbGljZSgyKTtcbiAgICB9XG5cbiAgICB0eXBlID0gc2NoZW1hLmNvbXBpbGVkVHlwZU1hcFt0YWddO1xuXG4gICAgaWYgKHR5cGUgJiYgX2hhc093blByb3BlcnR5LmNhbGwodHlwZS5zdHlsZUFsaWFzZXMsIHN0eWxlKSkge1xuICAgICAgc3R5bGUgPSB0eXBlLnN0eWxlQWxpYXNlc1tzdHlsZV07XG4gICAgfVxuXG4gICAgcmVzdWx0W3RhZ10gPSBzdHlsZTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGVuY29kZUhleChjaGFyYWN0ZXIpIHtcbiAgdmFyIHN0cmluZywgaGFuZGxlLCBsZW5ndGg7XG5cbiAgc3RyaW5nID0gY2hhcmFjdGVyLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xuXG4gIGlmIChjaGFyYWN0ZXIgPD0gMHhGRikge1xuICAgIGhhbmRsZSA9ICd4JztcbiAgICBsZW5ndGggPSAyO1xuICB9IGVsc2UgaWYgKGNoYXJhY3RlciA8PSAweEZGRkYpIHtcbiAgICBoYW5kbGUgPSAndSc7XG4gICAgbGVuZ3RoID0gNDtcbiAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPD0gMHhGRkZGRkZGRikge1xuICAgIGhhbmRsZSA9ICdVJztcbiAgICBsZW5ndGggPSA4O1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdjb2RlIHBvaW50IHdpdGhpbiBhIHN0cmluZyBtYXkgbm90IGJlIGdyZWF0ZXIgdGhhbiAweEZGRkZGRkZGJyk7XG4gIH1cblxuICByZXR1cm4gJ1xcXFwnICsgaGFuZGxlICsgY29tbW9uLnJlcGVhdCgnMCcsIGxlbmd0aCAtIHN0cmluZy5sZW5ndGgpICsgc3RyaW5nO1xufVxuXG5mdW5jdGlvbiBTdGF0ZShvcHRpb25zKSB7XG4gIHRoaXMuc2NoZW1hICAgICAgID0gb3B0aW9uc1snc2NoZW1hJ10gfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5pbmRlbnQgICAgICAgPSBNYXRoLm1heCgxLCAob3B0aW9uc1snaW5kZW50J10gfHwgMikpO1xuICB0aGlzLnNraXBJbnZhbGlkICA9IG9wdGlvbnNbJ3NraXBJbnZhbGlkJ10gfHwgZmFsc2U7XG4gIHRoaXMuZmxvd0xldmVsICAgID0gKGNvbW1vbi5pc05vdGhpbmcob3B0aW9uc1snZmxvd0xldmVsJ10pID8gLTEgOiBvcHRpb25zWydmbG93TGV2ZWwnXSk7XG4gIHRoaXMuc3R5bGVNYXAgICAgID0gY29tcGlsZVN0eWxlTWFwKHRoaXMuc2NoZW1hLCBvcHRpb25zWydzdHlsZXMnXSB8fCBudWxsKTtcbiAgdGhpcy5zb3J0S2V5cyAgICAgPSBvcHRpb25zWydzb3J0S2V5cyddIHx8IGZhbHNlO1xuICB0aGlzLmxpbmVXaWR0aCAgICA9IG9wdGlvbnNbJ2xpbmVXaWR0aCddIHx8IDgwO1xuICB0aGlzLm5vUmVmcyAgICAgICA9IG9wdGlvbnNbJ25vUmVmcyddIHx8IGZhbHNlO1xuICB0aGlzLm5vQ29tcGF0TW9kZSA9IG9wdGlvbnNbJ25vQ29tcGF0TW9kZSddIHx8IGZhbHNlO1xuXG4gIHRoaXMuaW1wbGljaXRUeXBlcyA9IHRoaXMuc2NoZW1hLmNvbXBpbGVkSW1wbGljaXQ7XG4gIHRoaXMuZXhwbGljaXRUeXBlcyA9IHRoaXMuc2NoZW1hLmNvbXBpbGVkRXhwbGljaXQ7XG5cbiAgdGhpcy50YWcgPSBudWxsO1xuICB0aGlzLnJlc3VsdCA9ICcnO1xuXG4gIHRoaXMuZHVwbGljYXRlcyA9IFtdO1xuICB0aGlzLnVzZWREdXBsaWNhdGVzID0gbnVsbDtcbn1cblxuLy8gSW5kZW50cyBldmVyeSBsaW5lIGluIGEgc3RyaW5nLiBFbXB0eSBsaW5lcyAoXFxuIG9ubHkpIGFyZSBub3QgaW5kZW50ZWQuXG5mdW5jdGlvbiBpbmRlbnRTdHJpbmcoc3RyaW5nLCBzcGFjZXMpIHtcbiAgdmFyIGluZCA9IGNvbW1vbi5yZXBlYXQoJyAnLCBzcGFjZXMpLFxuICAgICAgcG9zaXRpb24gPSAwLFxuICAgICAgbmV4dCA9IC0xLFxuICAgICAgcmVzdWx0ID0gJycsXG4gICAgICBsaW5lLFxuICAgICAgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcblxuICB3aGlsZSAocG9zaXRpb24gPCBsZW5ndGgpIHtcbiAgICBuZXh0ID0gc3RyaW5nLmluZGV4T2YoJ1xcbicsIHBvc2l0aW9uKTtcbiAgICBpZiAobmV4dCA9PT0gLTEpIHtcbiAgICAgIGxpbmUgPSBzdHJpbmcuc2xpY2UocG9zaXRpb24pO1xuICAgICAgcG9zaXRpb24gPSBsZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpbmUgPSBzdHJpbmcuc2xpY2UocG9zaXRpb24sIG5leHQgKyAxKTtcbiAgICAgIHBvc2l0aW9uID0gbmV4dCArIDE7XG4gICAgfVxuXG4gICAgaWYgKGxpbmUubGVuZ3RoICYmIGxpbmUgIT09ICdcXG4nKSByZXN1bHQgKz0gaW5kO1xuXG4gICAgcmVzdWx0ICs9IGxpbmU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZU5leHRMaW5lKHN0YXRlLCBsZXZlbCkge1xuICByZXR1cm4gJ1xcbicgKyBjb21tb24ucmVwZWF0KCcgJywgc3RhdGUuaW5kZW50ICogbGV2ZWwpO1xufVxuXG5mdW5jdGlvbiB0ZXN0SW1wbGljaXRSZXNvbHZpbmcoc3RhdGUsIHN0cikge1xuICB2YXIgaW5kZXgsIGxlbmd0aCwgdHlwZTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gc3RhdGUuaW1wbGljaXRUeXBlcy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdHlwZSA9IHN0YXRlLmltcGxpY2l0VHlwZXNbaW5kZXhdO1xuXG4gICAgaWYgKHR5cGUucmVzb2x2ZShzdHIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIFszM10gcy13aGl0ZSA6Oj0gcy1zcGFjZSB8IHMtdGFiXG5mdW5jdGlvbiBpc1doaXRlc3BhY2UoYykge1xuICByZXR1cm4gYyA9PT0gQ0hBUl9TUEFDRSB8fCBjID09PSBDSEFSX1RBQjtcbn1cblxuLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBjaGFyYWN0ZXIgY2FuIGJlIHByaW50ZWQgd2l0aG91dCBlc2NhcGluZy5cbi8vIEZyb20gWUFNTCAxLjI6IFwiYW55IGFsbG93ZWQgY2hhcmFjdGVycyBrbm93biB0byBiZSBub24tcHJpbnRhYmxlXG4vLyBzaG91bGQgYWxzbyBiZSBlc2NhcGVkLiBbSG93ZXZlcixdIFRoaXMgaXNu4oCZdCBtYW5kYXRvcnlcIlxuLy8gRGVyaXZlZCBmcm9tIG5iLWNoYXIgLSBcXHQgLSAjeDg1IC0gI3hBMCAtICN4MjAyOCAtICN4MjAyOS5cbmZ1bmN0aW9uIGlzUHJpbnRhYmxlKGMpIHtcbiAgcmV0dXJuICAoMHgwMDAyMCA8PSBjICYmIGMgPD0gMHgwMDAwN0UpXG4gICAgICB8fCAoKDB4MDAwQTEgPD0gYyAmJiBjIDw9IDB4MDBEN0ZGKSAmJiBjICE9PSAweDIwMjggJiYgYyAhPT0gMHgyMDI5KVxuICAgICAgfHwgKCgweDBFMDAwIDw9IGMgJiYgYyA8PSAweDAwRkZGRCkgJiYgYyAhPT0gMHhGRUZGIC8qIEJPTSAqLylcbiAgICAgIHx8ICAoMHgxMDAwMCA8PSBjICYmIGMgPD0gMHgxMEZGRkYpO1xufVxuXG4vLyBTaW1wbGlmaWVkIHRlc3QgZm9yIHZhbHVlcyBhbGxvd2VkIGFmdGVyIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gcGxhaW4gc3R5bGUuXG5mdW5jdGlvbiBpc1BsYWluU2FmZShjKSB7XG4gIC8vIFVzZXMgYSBzdWJzZXQgb2YgbmItY2hhciAtIGMtZmxvdy1pbmRpY2F0b3IgLSBcIjpcIiAtIFwiI1wiXG4gIC8vIHdoZXJlIG5iLWNoYXIgOjo9IGMtcHJpbnRhYmxlIC0gYi1jaGFyIC0gYy1ieXRlLW9yZGVyLW1hcmsuXG4gIHJldHVybiBpc1ByaW50YWJsZShjKSAmJiBjICE9PSAweEZFRkZcbiAgICAvLyAtIGMtZmxvdy1pbmRpY2F0b3JcbiAgICAmJiBjICE9PSBDSEFSX0NPTU1BXG4gICAgJiYgYyAhPT0gQ0hBUl9MRUZUX1NRVUFSRV9CUkFDS0VUXG4gICAgJiYgYyAhPT0gQ0hBUl9SSUdIVF9TUVVBUkVfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUXG4gICAgJiYgYyAhPT0gQ0hBUl9SSUdIVF9DVVJMWV9CUkFDS0VUXG4gICAgLy8gLSBcIjpcIiAtIFwiI1wiXG4gICAgJiYgYyAhPT0gQ0hBUl9DT0xPTlxuICAgICYmIGMgIT09IENIQVJfU0hBUlA7XG59XG5cbi8vIFNpbXBsaWZpZWQgdGVzdCBmb3IgdmFsdWVzIGFsbG93ZWQgYXMgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiBwbGFpbiBzdHlsZS5cbmZ1bmN0aW9uIGlzUGxhaW5TYWZlRmlyc3QoYykge1xuICAvLyBVc2VzIGEgc3Vic2V0IG9mIG5zLWNoYXIgLSBjLWluZGljYXRvclxuICAvLyB3aGVyZSBucy1jaGFyID0gbmItY2hhciAtIHMtd2hpdGUuXG4gIHJldHVybiBpc1ByaW50YWJsZShjKSAmJiBjICE9PSAweEZFRkZcbiAgICAmJiAhaXNXaGl0ZXNwYWNlKGMpIC8vIC0gcy13aGl0ZVxuICAgIC8vIC0gKGMtaW5kaWNhdG9yIDo6PVxuICAgIC8vIOKAnC3igJ0gfCDigJw/4oCdIHwg4oCcOuKAnSB8IOKAnCzigJ0gfCDigJxb4oCdIHwg4oCcXeKAnSB8IOKAnHvigJ0gfCDigJx94oCdXG4gICAgJiYgYyAhPT0gQ0hBUl9NSU5VU1xuICAgICYmIGMgIT09IENIQVJfUVVFU1RJT05cbiAgICAmJiBjICE9PSBDSEFSX0NPTE9OXG4gICAgJiYgYyAhPT0gQ0hBUl9DT01NQVxuICAgICYmIGMgIT09IENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfUklHSFRfU1FVQVJFX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX0xFRlRfQ1VSTFlfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfUklHSFRfQ1VSTFlfQlJBQ0tFVFxuICAgIC8vIHwg4oCcI+KAnSB8IOKAnCbigJ0gfCDigJwq4oCdIHwg4oCcIeKAnSB8IOKAnHzigJ0gfCDigJw+4oCdIHwg4oCcJ+KAnSB8IOKAnFwi4oCdXG4gICAgJiYgYyAhPT0gQ0hBUl9TSEFSUFxuICAgICYmIGMgIT09IENIQVJfQU1QRVJTQU5EXG4gICAgJiYgYyAhPT0gQ0hBUl9BU1RFUklTS1xuICAgICYmIGMgIT09IENIQVJfRVhDTEFNQVRJT05cbiAgICAmJiBjICE9PSBDSEFSX1ZFUlRJQ0FMX0xJTkVcbiAgICAmJiBjICE9PSBDSEFSX0dSRUFURVJfVEhBTlxuICAgICYmIGMgIT09IENIQVJfU0lOR0xFX1FVT1RFXG4gICAgJiYgYyAhPT0gQ0hBUl9ET1VCTEVfUVVPVEVcbiAgICAvLyB8IOKAnCXigJ0gfCDigJxA4oCdIHwg4oCcYOKAnSlcbiAgICAmJiBjICE9PSBDSEFSX1BFUkNFTlRcbiAgICAmJiBjICE9PSBDSEFSX0NPTU1FUkNJQUxfQVRcbiAgICAmJiBjICE9PSBDSEFSX0dSQVZFX0FDQ0VOVDtcbn1cblxudmFyIFNUWUxFX1BMQUlOICAgPSAxLFxuICAgIFNUWUxFX1NJTkdMRSAgPSAyLFxuICAgIFNUWUxFX0xJVEVSQUwgPSAzLFxuICAgIFNUWUxFX0ZPTERFRCAgPSA0LFxuICAgIFNUWUxFX0RPVUJMRSAgPSA1O1xuXG4vLyBEZXRlcm1pbmVzIHdoaWNoIHNjYWxhciBzdHlsZXMgYXJlIHBvc3NpYmxlIGFuZCByZXR1cm5zIHRoZSBwcmVmZXJyZWQgc3R5bGUuXG4vLyBsaW5lV2lkdGggPSAtMSA9PiBubyBsaW1pdC5cbi8vIFByZS1jb25kaXRpb25zOiBzdHIubGVuZ3RoID4gMC5cbi8vIFBvc3QtY29uZGl0aW9uczpcbi8vICAgIFNUWUxFX1BMQUlOIG9yIFNUWUxFX1NJTkdMRSA9PiBubyBcXG4gYXJlIGluIHRoZSBzdHJpbmcuXG4vLyAgICBTVFlMRV9MSVRFUkFMID0+IG5vIGxpbmVzIGFyZSBzdWl0YWJsZSBmb3IgZm9sZGluZyAob3IgbGluZVdpZHRoIGlzIC0xKS5cbi8vICAgIFNUWUxFX0ZPTERFRCA9PiBhIGxpbmUgPiBsaW5lV2lkdGggYW5kIGNhbiBiZSBmb2xkZWQgKGFuZCBsaW5lV2lkdGggIT0gLTEpLlxuZnVuY3Rpb24gY2hvb3NlU2NhbGFyU3R5bGUoc3RyaW5nLCBzaW5nbGVMaW5lT25seSwgaW5kZW50UGVyTGV2ZWwsIGxpbmVXaWR0aCwgdGVzdEFtYmlndW91c1R5cGUpIHtcbiAgdmFyIGk7XG4gIHZhciBjaGFyO1xuICB2YXIgaGFzTGluZUJyZWFrID0gZmFsc2U7XG4gIHZhciBoYXNGb2xkYWJsZUxpbmUgPSBmYWxzZTsgLy8gb25seSBjaGVja2VkIGlmIHNob3VsZFRyYWNrV2lkdGhcbiAgdmFyIHNob3VsZFRyYWNrV2lkdGggPSBsaW5lV2lkdGggIT09IC0xO1xuICB2YXIgcHJldmlvdXNMaW5lQnJlYWsgPSAtMTsgLy8gY291bnQgdGhlIGZpcnN0IGxpbmUgY29ycmVjdGx5XG4gIHZhciBwbGFpbiA9IGlzUGxhaW5TYWZlRmlyc3Qoc3RyaW5nLmNoYXJDb2RlQXQoMCkpXG4gICAgICAgICAgJiYgIWlzV2hpdGVzcGFjZShzdHJpbmcuY2hhckNvZGVBdChzdHJpbmcubGVuZ3RoIC0gMSkpO1xuXG4gIGlmIChzaW5nbGVMaW5lT25seSkge1xuICAgIC8vIENhc2U6IG5vIGJsb2NrIHN0eWxlcy5cbiAgICAvLyBDaGVjayBmb3IgZGlzYWxsb3dlZCBjaGFyYWN0ZXJzIHRvIHJ1bGUgb3V0IHBsYWluIGFuZCBzaW5nbGUuXG4gICAgZm9yIChpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgY2hhciA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWYgKCFpc1ByaW50YWJsZShjaGFyKSkge1xuICAgICAgICByZXR1cm4gU1RZTEVfRE9VQkxFO1xuICAgICAgfVxuICAgICAgcGxhaW4gPSBwbGFpbiAmJiBpc1BsYWluU2FmZShjaGFyKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gQ2FzZTogYmxvY2sgc3R5bGVzIHBlcm1pdHRlZC5cbiAgICBmb3IgKGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjaGFyID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gICAgICBpZiAoY2hhciA9PT0gQ0hBUl9MSU5FX0ZFRUQpIHtcbiAgICAgICAgaGFzTGluZUJyZWFrID0gdHJ1ZTtcbiAgICAgICAgLy8gQ2hlY2sgaWYgYW55IGxpbmUgY2FuIGJlIGZvbGRlZC5cbiAgICAgICAgaWYgKHNob3VsZFRyYWNrV2lkdGgpIHtcbiAgICAgICAgICBoYXNGb2xkYWJsZUxpbmUgPSBoYXNGb2xkYWJsZUxpbmUgfHxcbiAgICAgICAgICAgIC8vIEZvbGRhYmxlIGxpbmUgPSB0b28gbG9uZywgYW5kIG5vdCBtb3JlLWluZGVudGVkLlxuICAgICAgICAgICAgKGkgLSBwcmV2aW91c0xpbmVCcmVhayAtIDEgPiBsaW5lV2lkdGggJiZcbiAgICAgICAgICAgICBzdHJpbmdbcHJldmlvdXNMaW5lQnJlYWsgKyAxXSAhPT0gJyAnKTtcbiAgICAgICAgICBwcmV2aW91c0xpbmVCcmVhayA9IGk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIWlzUHJpbnRhYmxlKGNoYXIpKSB7XG4gICAgICAgIHJldHVybiBTVFlMRV9ET1VCTEU7XG4gICAgICB9XG4gICAgICBwbGFpbiA9IHBsYWluICYmIGlzUGxhaW5TYWZlKGNoYXIpO1xuICAgIH1cbiAgICAvLyBpbiBjYXNlIHRoZSBlbmQgaXMgbWlzc2luZyBhIFxcblxuICAgIGhhc0ZvbGRhYmxlTGluZSA9IGhhc0ZvbGRhYmxlTGluZSB8fCAoc2hvdWxkVHJhY2tXaWR0aCAmJlxuICAgICAgKGkgLSBwcmV2aW91c0xpbmVCcmVhayAtIDEgPiBsaW5lV2lkdGggJiZcbiAgICAgICBzdHJpbmdbcHJldmlvdXNMaW5lQnJlYWsgKyAxXSAhPT0gJyAnKSk7XG4gIH1cbiAgLy8gQWx0aG91Z2ggZXZlcnkgc3R5bGUgY2FuIHJlcHJlc2VudCBcXG4gd2l0aG91dCBlc2NhcGluZywgcHJlZmVyIGJsb2NrIHN0eWxlc1xuICAvLyBmb3IgbXVsdGlsaW5lLCBzaW5jZSB0aGV5J3JlIG1vcmUgcmVhZGFibGUgYW5kIHRoZXkgZG9uJ3QgYWRkIGVtcHR5IGxpbmVzLlxuICAvLyBBbHNvIHByZWZlciBmb2xkaW5nIGEgc3VwZXItbG9uZyBsaW5lLlxuICBpZiAoIWhhc0xpbmVCcmVhayAmJiAhaGFzRm9sZGFibGVMaW5lKSB7XG4gICAgLy8gU3RyaW5ncyBpbnRlcnByZXRhYmxlIGFzIGFub3RoZXIgdHlwZSBoYXZlIHRvIGJlIHF1b3RlZDtcbiAgICAvLyBlLmcuIHRoZSBzdHJpbmcgJ3RydWUnIHZzLiB0aGUgYm9vbGVhbiB0cnVlLlxuICAgIHJldHVybiBwbGFpbiAmJiAhdGVzdEFtYmlndW91c1R5cGUoc3RyaW5nKVxuICAgICAgPyBTVFlMRV9QTEFJTiA6IFNUWUxFX1NJTkdMRTtcbiAgfVxuICAvLyBFZGdlIGNhc2U6IGJsb2NrIGluZGVudGF0aW9uIGluZGljYXRvciBjYW4gb25seSBoYXZlIG9uZSBkaWdpdC5cbiAgaWYgKHN0cmluZ1swXSA9PT0gJyAnICYmIGluZGVudFBlckxldmVsID4gOSkge1xuICAgIHJldHVybiBTVFlMRV9ET1VCTEU7XG4gIH1cbiAgLy8gQXQgdGhpcyBwb2ludCB3ZSBrbm93IGJsb2NrIHN0eWxlcyBhcmUgdmFsaWQuXG4gIC8vIFByZWZlciBsaXRlcmFsIHN0eWxlIHVubGVzcyB3ZSB3YW50IHRvIGZvbGQuXG4gIHJldHVybiBoYXNGb2xkYWJsZUxpbmUgPyBTVFlMRV9GT0xERUQgOiBTVFlMRV9MSVRFUkFMO1xufVxuXG4vLyBOb3RlOiBsaW5lIGJyZWFraW5nL2ZvbGRpbmcgaXMgaW1wbGVtZW50ZWQgZm9yIG9ubHkgdGhlIGZvbGRlZCBzdHlsZS5cbi8vIE5CLiBXZSBkcm9wIHRoZSBsYXN0IHRyYWlsaW5nIG5ld2xpbmUgKGlmIGFueSkgb2YgYSByZXR1cm5lZCBibG9jayBzY2FsYXJcbi8vICBzaW5jZSB0aGUgZHVtcGVyIGFkZHMgaXRzIG93biBuZXdsaW5lLiBUaGlzIGFsd2F5cyB3b3Jrczpcbi8vICAgIOKAoiBObyBlbmRpbmcgbmV3bGluZSA9PiB1bmFmZmVjdGVkOyBhbHJlYWR5IHVzaW5nIHN0cmlwIFwiLVwiIGNob21waW5nLlxuLy8gICAg4oCiIEVuZGluZyBuZXdsaW5lICAgID0+IHJlbW92ZWQgdGhlbiByZXN0b3JlZC5cbi8vICBJbXBvcnRhbnRseSwgdGhpcyBrZWVwcyB0aGUgXCIrXCIgY2hvbXAgaW5kaWNhdG9yIGZyb20gZ2FpbmluZyBhbiBleHRyYSBsaW5lLlxuZnVuY3Rpb24gd3JpdGVTY2FsYXIoc3RhdGUsIHN0cmluZywgbGV2ZWwsIGlza2V5KSB7XG4gIHN0YXRlLmR1bXAgPSAoZnVuY3Rpb24gKCkge1xuICAgIGlmIChzdHJpbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gXCInJ1wiO1xuICAgIH1cbiAgICBpZiAoIXN0YXRlLm5vQ29tcGF0TW9kZSAmJlxuICAgICAgICBERVBSRUNBVEVEX0JPT0xFQU5TX1NZTlRBWC5pbmRleE9mKHN0cmluZykgIT09IC0xKSB7XG4gICAgICByZXR1cm4gXCInXCIgKyBzdHJpbmcgKyBcIidcIjtcbiAgICB9XG5cbiAgICB2YXIgaW5kZW50ID0gc3RhdGUuaW5kZW50ICogTWF0aC5tYXgoMSwgbGV2ZWwpOyAvLyBubyAwLWluZGVudCBzY2FsYXJzXG4gICAgLy8gQXMgaW5kZW50YXRpb24gZ2V0cyBkZWVwZXIsIGxldCB0aGUgd2lkdGggZGVjcmVhc2UgbW9ub3RvbmljYWxseVxuICAgIC8vIHRvIHRoZSBsb3dlciBib3VuZCBtaW4oc3RhdGUubGluZVdpZHRoLCA0MCkuXG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgaW1wbGllc1xuICAgIC8vICBzdGF0ZS5saW5lV2lkdGgg4omkIDQwICsgc3RhdGUuaW5kZW50OiB3aWR0aCBpcyBmaXhlZCBhdCB0aGUgbG93ZXIgYm91bmQuXG4gICAgLy8gIHN0YXRlLmxpbmVXaWR0aCA+IDQwICsgc3RhdGUuaW5kZW50OiB3aWR0aCBkZWNyZWFzZXMgdW50aWwgdGhlIGxvd2VyIGJvdW5kLlxuICAgIC8vIFRoaXMgYmVoYXZlcyBiZXR0ZXIgdGhhbiBhIGNvbnN0YW50IG1pbmltdW0gd2lkdGggd2hpY2ggZGlzYWxsb3dzIG5hcnJvd2VyIG9wdGlvbnMsXG4gICAgLy8gb3IgYW4gaW5kZW50IHRocmVzaG9sZCB3aGljaCBjYXVzZXMgdGhlIHdpZHRoIHRvIHN1ZGRlbmx5IGluY3JlYXNlLlxuICAgIHZhciBsaW5lV2lkdGggPSBzdGF0ZS5saW5lV2lkdGggPT09IC0xXG4gICAgICA/IC0xIDogTWF0aC5tYXgoTWF0aC5taW4oc3RhdGUubGluZVdpZHRoLCA0MCksIHN0YXRlLmxpbmVXaWR0aCAtIGluZGVudCk7XG5cbiAgICAvLyBXaXRob3V0IGtub3dpbmcgaWYga2V5cyBhcmUgaW1wbGljaXQvZXhwbGljaXQsIGFzc3VtZSBpbXBsaWNpdCBmb3Igc2FmZXR5LlxuICAgIHZhciBzaW5nbGVMaW5lT25seSA9IGlza2V5XG4gICAgICAvLyBObyBibG9jayBzdHlsZXMgaW4gZmxvdyBtb2RlLlxuICAgICAgfHwgKHN0YXRlLmZsb3dMZXZlbCA+IC0xICYmIGxldmVsID49IHN0YXRlLmZsb3dMZXZlbCk7XG4gICAgZnVuY3Rpb24gdGVzdEFtYmlndWl0eShzdHJpbmcpIHtcbiAgICAgIHJldHVybiB0ZXN0SW1wbGljaXRSZXNvbHZpbmcoc3RhdGUsIHN0cmluZyk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChjaG9vc2VTY2FsYXJTdHlsZShzdHJpbmcsIHNpbmdsZUxpbmVPbmx5LCBzdGF0ZS5pbmRlbnQsIGxpbmVXaWR0aCwgdGVzdEFtYmlndWl0eSkpIHtcbiAgICAgIGNhc2UgU1RZTEVfUExBSU46XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICBjYXNlIFNUWUxFX1NJTkdMRTpcbiAgICAgICAgcmV0dXJuIFwiJ1wiICsgc3RyaW5nLnJlcGxhY2UoLycvZywgXCInJ1wiKSArIFwiJ1wiO1xuICAgICAgY2FzZSBTVFlMRV9MSVRFUkFMOlxuICAgICAgICByZXR1cm4gJ3wnICsgYmxvY2tIZWFkZXIoc3RyaW5nLCBzdGF0ZS5pbmRlbnQpXG4gICAgICAgICAgKyBkcm9wRW5kaW5nTmV3bGluZShpbmRlbnRTdHJpbmcoc3RyaW5nLCBpbmRlbnQpKTtcbiAgICAgIGNhc2UgU1RZTEVfRk9MREVEOlxuICAgICAgICByZXR1cm4gJz4nICsgYmxvY2tIZWFkZXIoc3RyaW5nLCBzdGF0ZS5pbmRlbnQpXG4gICAgICAgICAgKyBkcm9wRW5kaW5nTmV3bGluZShpbmRlbnRTdHJpbmcoZm9sZFN0cmluZyhzdHJpbmcsIGxpbmVXaWR0aCksIGluZGVudCkpO1xuICAgICAgY2FzZSBTVFlMRV9ET1VCTEU6XG4gICAgICAgIHJldHVybiAnXCInICsgZXNjYXBlU3RyaW5nKHN0cmluZywgbGluZVdpZHRoKSArICdcIic7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignaW1wb3NzaWJsZSBlcnJvcjogaW52YWxpZCBzY2FsYXIgc3R5bGUnKTtcbiAgICB9XG4gIH0oKSk7XG59XG5cbi8vIFByZS1jb25kaXRpb25zOiBzdHJpbmcgaXMgdmFsaWQgZm9yIGEgYmxvY2sgc2NhbGFyLCAxIDw9IGluZGVudFBlckxldmVsIDw9IDkuXG5mdW5jdGlvbiBibG9ja0hlYWRlcihzdHJpbmcsIGluZGVudFBlckxldmVsKSB7XG4gIHZhciBpbmRlbnRJbmRpY2F0b3IgPSAoc3RyaW5nWzBdID09PSAnICcpID8gU3RyaW5nKGluZGVudFBlckxldmVsKSA6ICcnO1xuXG4gIC8vIG5vdGUgdGhlIHNwZWNpYWwgY2FzZTogdGhlIHN0cmluZyAnXFxuJyBjb3VudHMgYXMgYSBcInRyYWlsaW5nXCIgZW1wdHkgbGluZS5cbiAgdmFyIGNsaXAgPSAgICAgICAgICBzdHJpbmdbc3RyaW5nLmxlbmd0aCAtIDFdID09PSAnXFxuJztcbiAgdmFyIGtlZXAgPSBjbGlwICYmIChzdHJpbmdbc3RyaW5nLmxlbmd0aCAtIDJdID09PSAnXFxuJyB8fCBzdHJpbmcgPT09ICdcXG4nKTtcbiAgdmFyIGNob21wID0ga2VlcCA/ICcrJyA6IChjbGlwID8gJycgOiAnLScpO1xuXG4gIHJldHVybiBpbmRlbnRJbmRpY2F0b3IgKyBjaG9tcCArICdcXG4nO1xufVxuXG4vLyAoU2VlIHRoZSBub3RlIGZvciB3cml0ZVNjYWxhci4pXG5mdW5jdGlvbiBkcm9wRW5kaW5nTmV3bGluZShzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZ1tzdHJpbmcubGVuZ3RoIC0gMV0gPT09ICdcXG4nID8gc3RyaW5nLnNsaWNlKDAsIC0xKSA6IHN0cmluZztcbn1cblxuLy8gTm90ZTogYSBsb25nIGxpbmUgd2l0aG91dCBhIHN1aXRhYmxlIGJyZWFrIHBvaW50IHdpbGwgZXhjZWVkIHRoZSB3aWR0aCBsaW1pdC5cbi8vIFByZS1jb25kaXRpb25zOiBldmVyeSBjaGFyIGluIHN0ciBpc1ByaW50YWJsZSwgc3RyLmxlbmd0aCA+IDAsIHdpZHRoID4gMC5cbmZ1bmN0aW9uIGZvbGRTdHJpbmcoc3RyaW5nLCB3aWR0aCkge1xuICAvLyBJbiBmb2xkZWQgc3R5bGUsICRrJCBjb25zZWN1dGl2ZSBuZXdsaW5lcyBvdXRwdXQgYXMgJGsrMSQgbmV3bGluZXPigJRcbiAgLy8gdW5sZXNzIHRoZXkncmUgYmVmb3JlIG9yIGFmdGVyIGEgbW9yZS1pbmRlbnRlZCBsaW5lLCBvciBhdCB0aGUgdmVyeVxuICAvLyBiZWdpbm5pbmcgb3IgZW5kLCBpbiB3aGljaCBjYXNlICRrJCBtYXBzIHRvICRrJC5cbiAgLy8gVGhlcmVmb3JlLCBwYXJzZSBlYWNoIGNodW5rIGFzIG5ld2xpbmUocykgZm9sbG93ZWQgYnkgYSBjb250ZW50IGxpbmUuXG4gIHZhciBsaW5lUmUgPSAvKFxcbispKFteXFxuXSopL2c7XG5cbiAgLy8gZmlyc3QgbGluZSAocG9zc2libHkgYW4gZW1wdHkgbGluZSlcbiAgdmFyIHJlc3VsdCA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG5leHRMRiA9IHN0cmluZy5pbmRleE9mKCdcXG4nKTtcbiAgICBuZXh0TEYgPSBuZXh0TEYgIT09IC0xID8gbmV4dExGIDogc3RyaW5nLmxlbmd0aDtcbiAgICBsaW5lUmUubGFzdEluZGV4ID0gbmV4dExGO1xuICAgIHJldHVybiBmb2xkTGluZShzdHJpbmcuc2xpY2UoMCwgbmV4dExGKSwgd2lkdGgpO1xuICB9KCkpO1xuICAvLyBJZiB3ZSBoYXZlbid0IHJlYWNoZWQgdGhlIGZpcnN0IGNvbnRlbnQgbGluZSB5ZXQsIGRvbid0IGFkZCBhbiBleHRyYSBcXG4uXG4gIHZhciBwcmV2TW9yZUluZGVudGVkID0gc3RyaW5nWzBdID09PSAnXFxuJyB8fCBzdHJpbmdbMF0gPT09ICcgJztcbiAgdmFyIG1vcmVJbmRlbnRlZDtcblxuICAvLyByZXN0IG9mIHRoZSBsaW5lc1xuICB2YXIgbWF0Y2g7XG4gIHdoaWxlICgobWF0Y2ggPSBsaW5lUmUuZXhlYyhzdHJpbmcpKSkge1xuICAgIHZhciBwcmVmaXggPSBtYXRjaFsxXSwgbGluZSA9IG1hdGNoWzJdO1xuICAgIG1vcmVJbmRlbnRlZCA9IChsaW5lWzBdID09PSAnICcpO1xuICAgIHJlc3VsdCArPSBwcmVmaXhcbiAgICAgICsgKCFwcmV2TW9yZUluZGVudGVkICYmICFtb3JlSW5kZW50ZWQgJiYgbGluZSAhPT0gJydcbiAgICAgICAgPyAnXFxuJyA6ICcnKVxuICAgICAgKyBmb2xkTGluZShsaW5lLCB3aWR0aCk7XG4gICAgcHJldk1vcmVJbmRlbnRlZCA9IG1vcmVJbmRlbnRlZDtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIEdyZWVkeSBsaW5lIGJyZWFraW5nLlxuLy8gUGlja3MgdGhlIGxvbmdlc3QgbGluZSB1bmRlciB0aGUgbGltaXQgZWFjaCB0aW1lLFxuLy8gb3RoZXJ3aXNlIHNldHRsZXMgZm9yIHRoZSBzaG9ydGVzdCBsaW5lIG92ZXIgdGhlIGxpbWl0LlxuLy8gTkIuIE1vcmUtaW5kZW50ZWQgbGluZXMgKmNhbm5vdCogYmUgZm9sZGVkLCBhcyB0aGF0IHdvdWxkIGFkZCBhbiBleHRyYSBcXG4uXG5mdW5jdGlvbiBmb2xkTGluZShsaW5lLCB3aWR0aCkge1xuICBpZiAobGluZSA9PT0gJycgfHwgbGluZVswXSA9PT0gJyAnKSByZXR1cm4gbGluZTtcblxuICAvLyBTaW5jZSBhIG1vcmUtaW5kZW50ZWQgbGluZSBhZGRzIGEgXFxuLCBicmVha3MgY2FuJ3QgYmUgZm9sbG93ZWQgYnkgYSBzcGFjZS5cbiAgdmFyIGJyZWFrUmUgPSAvIFteIF0vZzsgLy8gbm90ZTogdGhlIG1hdGNoIGluZGV4IHdpbGwgYWx3YXlzIGJlIDw9IGxlbmd0aC0yLlxuICB2YXIgbWF0Y2g7XG4gIC8vIHN0YXJ0IGlzIGFuIGluY2x1c2l2ZSBpbmRleC4gZW5kLCBjdXJyLCBhbmQgbmV4dCBhcmUgZXhjbHVzaXZlLlxuICB2YXIgc3RhcnQgPSAwLCBlbmQsIGN1cnIgPSAwLCBuZXh0ID0gMDtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuXG4gIC8vIEludmFyaWFudHM6IDAgPD0gc3RhcnQgPD0gbGVuZ3RoLTEuXG4gIC8vICAgMCA8PSBjdXJyIDw9IG5leHQgPD0gbWF4KDAsIGxlbmd0aC0yKS4gY3VyciAtIHN0YXJ0IDw9IHdpZHRoLlxuICAvLyBJbnNpZGUgdGhlIGxvb3A6XG4gIC8vICAgQSBtYXRjaCBpbXBsaWVzIGxlbmd0aCA+PSAyLCBzbyBjdXJyIGFuZCBuZXh0IGFyZSA8PSBsZW5ndGgtMi5cbiAgd2hpbGUgKChtYXRjaCA9IGJyZWFrUmUuZXhlYyhsaW5lKSkpIHtcbiAgICBuZXh0ID0gbWF0Y2guaW5kZXg7XG4gICAgLy8gbWFpbnRhaW4gaW52YXJpYW50OiBjdXJyIC0gc3RhcnQgPD0gd2lkdGhcbiAgICBpZiAobmV4dCAtIHN0YXJ0ID4gd2lkdGgpIHtcbiAgICAgIGVuZCA9IChjdXJyID4gc3RhcnQpID8gY3VyciA6IG5leHQ7IC8vIGRlcml2ZSBlbmQgPD0gbGVuZ3RoLTJcbiAgICAgIHJlc3VsdCArPSAnXFxuJyArIGxpbmUuc2xpY2Uoc3RhcnQsIGVuZCk7XG4gICAgICAvLyBza2lwIHRoZSBzcGFjZSB0aGF0IHdhcyBvdXRwdXQgYXMgXFxuXG4gICAgICBzdGFydCA9IGVuZCArIDE7ICAgICAgICAgICAgICAgICAgICAvLyBkZXJpdmUgc3RhcnQgPD0gbGVuZ3RoLTFcbiAgICB9XG4gICAgY3VyciA9IG5leHQ7XG4gIH1cblxuICAvLyBCeSB0aGUgaW52YXJpYW50cywgc3RhcnQgPD0gbGVuZ3RoLTEsIHNvIHRoZXJlIGlzIHNvbWV0aGluZyBsZWZ0IG92ZXIuXG4gIC8vIEl0IGlzIGVpdGhlciB0aGUgd2hvbGUgc3RyaW5nIG9yIGEgcGFydCBzdGFydGluZyBmcm9tIG5vbi13aGl0ZXNwYWNlLlxuICByZXN1bHQgKz0gJ1xcbic7XG4gIC8vIEluc2VydCBhIGJyZWFrIGlmIHRoZSByZW1haW5kZXIgaXMgdG9vIGxvbmcgYW5kIHRoZXJlIGlzIGEgYnJlYWsgYXZhaWxhYmxlLlxuICBpZiAobGluZS5sZW5ndGggLSBzdGFydCA+IHdpZHRoICYmIGN1cnIgPiBzdGFydCkge1xuICAgIHJlc3VsdCArPSBsaW5lLnNsaWNlKHN0YXJ0LCBjdXJyKSArICdcXG4nICsgbGluZS5zbGljZShjdXJyICsgMSk7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0ICs9IGxpbmUuc2xpY2Uoc3RhcnQpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdC5zbGljZSgxKTsgLy8gZHJvcCBleHRyYSBcXG4gam9pbmVyXG59XG5cbi8vIEVzY2FwZXMgYSBkb3VibGUtcXVvdGVkIHN0cmluZy5cbmZ1bmN0aW9uIGVzY2FwZVN0cmluZyhzdHJpbmcpIHtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuICB2YXIgY2hhcjtcbiAgdmFyIGVzY2FwZVNlcTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgIGNoYXIgPSBzdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICBlc2NhcGVTZXEgPSBFU0NBUEVfU0VRVUVOQ0VTW2NoYXJdO1xuICAgIHJlc3VsdCArPSAhZXNjYXBlU2VxICYmIGlzUHJpbnRhYmxlKGNoYXIpXG4gICAgICA/IHN0cmluZ1tpXVxuICAgICAgOiBlc2NhcGVTZXEgfHwgZW5jb2RlSGV4KGNoYXIpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG93U2VxdWVuY2Uoc3RhdGUsIGxldmVsLCBvYmplY3QpIHtcbiAgdmFyIF9yZXN1bHQgPSAnJyxcbiAgICAgIF90YWcgICAgPSBzdGF0ZS50YWcsXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAvLyBXcml0ZSBvbmx5IHZhbGlkIGVsZW1lbnRzLlxuICAgIGlmICh3cml0ZU5vZGUoc3RhdGUsIGxldmVsLCBvYmplY3RbaW5kZXhdLCBmYWxzZSwgZmFsc2UpKSB7XG4gICAgICBpZiAoaW5kZXggIT09IDApIF9yZXN1bHQgKz0gJywgJztcbiAgICAgIF9yZXN1bHQgKz0gc3RhdGUuZHVtcDtcbiAgICB9XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gJ1snICsgX3Jlc3VsdCArICddJztcbn1cblxuZnVuY3Rpb24gd3JpdGVCbG9ja1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgb2JqZWN0LCBjb21wYWN0KSB7XG4gIHZhciBfcmVzdWx0ID0gJycsXG4gICAgICBfdGFnICAgID0gc3RhdGUudGFnLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgLy8gV3JpdGUgb25seSB2YWxpZCBlbGVtZW50cy5cbiAgICBpZiAod3JpdGVOb2RlKHN0YXRlLCBsZXZlbCArIDEsIG9iamVjdFtpbmRleF0sIHRydWUsIHRydWUpKSB7XG4gICAgICBpZiAoIWNvbXBhY3QgfHwgaW5kZXggIT09IDApIHtcbiAgICAgICAgX3Jlc3VsdCArPSBnZW5lcmF0ZU5leHRMaW5lKHN0YXRlLCBsZXZlbCk7XG4gICAgICB9XG4gICAgICBfcmVzdWx0ICs9ICctICcgKyBzdGF0ZS5kdW1wO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRlLnRhZyA9IF90YWc7XG4gIHN0YXRlLmR1bXAgPSBfcmVzdWx0IHx8ICdbXSc7IC8vIEVtcHR5IHNlcXVlbmNlIGlmIG5vIHZhbGlkIHZhbHVlcy5cbn1cblxuZnVuY3Rpb24gd3JpdGVGbG93TWFwcGluZyhzdGF0ZSwgbGV2ZWwsIG9iamVjdCkge1xuICB2YXIgX3Jlc3VsdCAgICAgICA9ICcnLFxuICAgICAgX3RhZyAgICAgICAgICA9IHN0YXRlLnRhZyxcbiAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGgsXG4gICAgICBvYmplY3RLZXksXG4gICAgICBvYmplY3RWYWx1ZSxcbiAgICAgIHBhaXJCdWZmZXI7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdEtleUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXJCdWZmZXIgPSAnJztcblxuICAgIGlmIChpbmRleCAhPT0gMCkgcGFpckJ1ZmZlciArPSAnLCAnO1xuXG4gICAgb2JqZWN0S2V5ID0gb2JqZWN0S2V5TGlzdFtpbmRleF07XG4gICAgb2JqZWN0VmFsdWUgPSBvYmplY3Rbb2JqZWN0S2V5XTtcblxuICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0S2V5LCBmYWxzZSwgZmFsc2UpKSB7XG4gICAgICBjb250aW51ZTsgLy8gU2tpcCB0aGlzIHBhaXIgYmVjYXVzZSBvZiBpbnZhbGlkIGtleTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUuZHVtcC5sZW5ndGggPiAxMDI0KSBwYWlyQnVmZmVyICs9ICc/ICc7XG5cbiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXAgKyAnOiAnO1xuXG4gICAgaWYgKCF3cml0ZU5vZGUoc3RhdGUsIGxldmVsLCBvYmplY3RWYWx1ZSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCB2YWx1ZS5cbiAgICB9XG5cbiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXA7XG5cbiAgICAvLyBCb3RoIGtleSBhbmQgdmFsdWUgYXJlIHZhbGlkLlxuICAgIF9yZXN1bHQgKz0gcGFpckJ1ZmZlcjtcbiAgfVxuXG4gIHN0YXRlLnRhZyA9IF90YWc7XG4gIHN0YXRlLmR1bXAgPSAneycgKyBfcmVzdWx0ICsgJ30nO1xufVxuXG5mdW5jdGlvbiB3cml0ZUJsb2NrTWFwcGluZyhzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgY29tcGFjdCkge1xuICB2YXIgX3Jlc3VsdCAgICAgICA9ICcnLFxuICAgICAgX3RhZyAgICAgICAgICA9IHN0YXRlLnRhZyxcbiAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGgsXG4gICAgICBvYmplY3RLZXksXG4gICAgICBvYmplY3RWYWx1ZSxcbiAgICAgIGV4cGxpY2l0UGFpcixcbiAgICAgIHBhaXJCdWZmZXI7XG5cbiAgLy8gQWxsb3cgc29ydGluZyBrZXlzIHNvIHRoYXQgdGhlIG91dHB1dCBmaWxlIGlzIGRldGVybWluaXN0aWNcbiAgaWYgKHN0YXRlLnNvcnRLZXlzID09PSB0cnVlKSB7XG4gICAgLy8gRGVmYXVsdCBzb3J0aW5nXG4gICAgb2JqZWN0S2V5TGlzdC5zb3J0KCk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHN0YXRlLnNvcnRLZXlzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgLy8gQ3VzdG9tIHNvcnQgZnVuY3Rpb25cbiAgICBvYmplY3RLZXlMaXN0LnNvcnQoc3RhdGUuc29ydEtleXMpO1xuICB9IGVsc2UgaWYgKHN0YXRlLnNvcnRLZXlzKSB7XG4gICAgLy8gU29tZXRoaW5nIGlzIHdyb25nXG4gICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ3NvcnRLZXlzIG11c3QgYmUgYSBib29sZWFuIG9yIGEgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyQnVmZmVyID0gJyc7XG5cbiAgICBpZiAoIWNvbXBhY3QgfHwgaW5kZXggIT09IDApIHtcbiAgICAgIHBhaXJCdWZmZXIgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpO1xuICAgIH1cblxuICAgIG9iamVjdEtleSA9IG9iamVjdEtleUxpc3RbaW5kZXhdO1xuICAgIG9iamVjdFZhbHVlID0gb2JqZWN0W29iamVjdEtleV07XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RLZXksIHRydWUsIHRydWUsIHRydWUpKSB7XG4gICAgICBjb250aW51ZTsgLy8gU2tpcCB0aGlzIHBhaXIgYmVjYXVzZSBvZiBpbnZhbGlkIGtleS5cbiAgICB9XG5cbiAgICBleHBsaWNpdFBhaXIgPSAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB8fFxuICAgICAgICAgICAgICAgICAgIChzdGF0ZS5kdW1wICYmIHN0YXRlLmR1bXAubGVuZ3RoID4gMTAyNCk7XG5cbiAgICBpZiAoZXhwbGljaXRQYWlyKSB7XG4gICAgICBpZiAoc3RhdGUuZHVtcCAmJiBDSEFSX0xJTkVfRkVFRCA9PT0gc3RhdGUuZHVtcC5jaGFyQ29kZUF0KDApKSB7XG4gICAgICAgIHBhaXJCdWZmZXIgKz0gJz8nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFpckJ1ZmZlciArPSAnPyAnO1xuICAgICAgfVxuICAgIH1cblxuICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcDtcblxuICAgIGlmIChleHBsaWNpdFBhaXIpIHtcbiAgICAgIHBhaXJCdWZmZXIgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpO1xuICAgIH1cblxuICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCArIDEsIG9iamVjdFZhbHVlLCB0cnVlLCBleHBsaWNpdFBhaXIpKSB7XG4gICAgICBjb250aW51ZTsgLy8gU2tpcCB0aGlzIHBhaXIgYmVjYXVzZSBvZiBpbnZhbGlkIHZhbHVlLlxuICAgIH1cblxuICAgIGlmIChzdGF0ZS5kdW1wICYmIENIQVJfTElORV9GRUVEID09PSBzdGF0ZS5kdW1wLmNoYXJDb2RlQXQoMCkpIHtcbiAgICAgIHBhaXJCdWZmZXIgKz0gJzonO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYWlyQnVmZmVyICs9ICc6ICc7XG4gICAgfVxuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wO1xuXG4gICAgLy8gQm90aCBrZXkgYW5kIHZhbHVlIGFyZSB2YWxpZC5cbiAgICBfcmVzdWx0ICs9IHBhaXJCdWZmZXI7XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gX3Jlc3VsdCB8fCAne30nOyAvLyBFbXB0eSBtYXBwaW5nIGlmIG5vIHZhbGlkIHBhaXJzLlxufVxuXG5mdW5jdGlvbiBkZXRlY3RUeXBlKHN0YXRlLCBvYmplY3QsIGV4cGxpY2l0KSB7XG4gIHZhciBfcmVzdWx0LCB0eXBlTGlzdCwgaW5kZXgsIGxlbmd0aCwgdHlwZSwgc3R5bGU7XG5cbiAgdHlwZUxpc3QgPSBleHBsaWNpdCA/IHN0YXRlLmV4cGxpY2l0VHlwZXMgOiBzdGF0ZS5pbXBsaWNpdFR5cGVzO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSB0eXBlTGlzdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdHlwZSA9IHR5cGVMaXN0W2luZGV4XTtcblxuICAgIGlmICgodHlwZS5pbnN0YW5jZU9mICB8fCB0eXBlLnByZWRpY2F0ZSkgJiZcbiAgICAgICAgKCF0eXBlLmluc3RhbmNlT2YgfHwgKCh0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JykgJiYgKG9iamVjdCBpbnN0YW5jZW9mIHR5cGUuaW5zdGFuY2VPZikpKSAmJlxuICAgICAgICAoIXR5cGUucHJlZGljYXRlICB8fCB0eXBlLnByZWRpY2F0ZShvYmplY3QpKSkge1xuXG4gICAgICBzdGF0ZS50YWcgPSBleHBsaWNpdCA/IHR5cGUudGFnIDogJz8nO1xuXG4gICAgICBpZiAodHlwZS5yZXByZXNlbnQpIHtcbiAgICAgICAgc3R5bGUgPSBzdGF0ZS5zdHlsZU1hcFt0eXBlLnRhZ10gfHwgdHlwZS5kZWZhdWx0U3R5bGU7XG5cbiAgICAgICAgaWYgKF90b1N0cmluZy5jYWxsKHR5cGUucmVwcmVzZW50KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJykge1xuICAgICAgICAgIF9yZXN1bHQgPSB0eXBlLnJlcHJlc2VudChvYmplY3QsIHN0eWxlKTtcbiAgICAgICAgfSBlbHNlIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbCh0eXBlLnJlcHJlc2VudCwgc3R5bGUpKSB7XG4gICAgICAgICAgX3Jlc3VsdCA9IHR5cGUucmVwcmVzZW50W3N0eWxlXShvYmplY3QsIHN0eWxlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignITwnICsgdHlwZS50YWcgKyAnPiB0YWcgcmVzb2x2ZXIgYWNjZXB0cyBub3QgXCInICsgc3R5bGUgKyAnXCIgc3R5bGUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRlLmR1bXAgPSBfcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIFNlcmlhbGl6ZXMgYG9iamVjdGAgYW5kIHdyaXRlcyBpdCB0byBnbG9iYWwgYHJlc3VsdGAuXG4vLyBSZXR1cm5zIHRydWUgb24gc3VjY2Vzcywgb3IgZmFsc2Ugb24gaW52YWxpZCBvYmplY3QuXG4vL1xuZnVuY3Rpb24gd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0LCBibG9jaywgY29tcGFjdCwgaXNrZXkpIHtcbiAgc3RhdGUudGFnID0gbnVsbDtcbiAgc3RhdGUuZHVtcCA9IG9iamVjdDtcblxuICBpZiAoIWRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgZmFsc2UpKSB7XG4gICAgZGV0ZWN0VHlwZShzdGF0ZSwgb2JqZWN0LCB0cnVlKTtcbiAgfVxuXG4gIHZhciB0eXBlID0gX3RvU3RyaW5nLmNhbGwoc3RhdGUuZHVtcCk7XG5cbiAgaWYgKGJsb2NrKSB7XG4gICAgYmxvY2sgPSAoc3RhdGUuZmxvd0xldmVsIDwgMCB8fCBzdGF0ZS5mbG93TGV2ZWwgPiBsZXZlbCk7XG4gIH1cblxuICB2YXIgb2JqZWN0T3JBcnJheSA9IHR5cGUgPT09ICdbb2JqZWN0IE9iamVjdF0nIHx8IHR5cGUgPT09ICdbb2JqZWN0IEFycmF5XScsXG4gICAgICBkdXBsaWNhdGVJbmRleCxcbiAgICAgIGR1cGxpY2F0ZTtcblxuICBpZiAob2JqZWN0T3JBcnJheSkge1xuICAgIGR1cGxpY2F0ZUluZGV4ID0gc3RhdGUuZHVwbGljYXRlcy5pbmRleE9mKG9iamVjdCk7XG4gICAgZHVwbGljYXRlID0gZHVwbGljYXRlSW5kZXggIT09IC0xO1xuICB9XG5cbiAgaWYgKChzdGF0ZS50YWcgIT09IG51bGwgJiYgc3RhdGUudGFnICE9PSAnPycpIHx8IGR1cGxpY2F0ZSB8fCAoc3RhdGUuaW5kZW50ICE9PSAyICYmIGxldmVsID4gMCkpIHtcbiAgICBjb21wYWN0ID0gZmFsc2U7XG4gIH1cblxuICBpZiAoZHVwbGljYXRlICYmIHN0YXRlLnVzZWREdXBsaWNhdGVzW2R1cGxpY2F0ZUluZGV4XSkge1xuICAgIHN0YXRlLmR1bXAgPSAnKnJlZl8nICsgZHVwbGljYXRlSW5kZXg7XG4gIH0gZWxzZSB7XG4gICAgaWYgKG9iamVjdE9yQXJyYXkgJiYgZHVwbGljYXRlICYmICFzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0pIHtcbiAgICAgIHN0YXRlLnVzZWREdXBsaWNhdGVzW2R1cGxpY2F0ZUluZGV4XSA9IHRydWU7XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgICAgaWYgKGJsb2NrICYmIChPYmplY3Qua2V5cyhzdGF0ZS5kdW1wKS5sZW5ndGggIT09IDApKSB7XG4gICAgICAgIHdyaXRlQmxvY2tNYXBwaW5nKHN0YXRlLCBsZXZlbCwgc3RhdGUuZHVtcCwgY29tcGFjdCk7XG4gICAgICAgIGlmIChkdXBsaWNhdGUpIHtcbiAgICAgICAgICBzdGF0ZS5kdW1wID0gJyZyZWZfJyArIGR1cGxpY2F0ZUluZGV4ICsgc3RhdGUuZHVtcDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd3JpdGVGbG93TWFwcGluZyhzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXApO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArICcgJyArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IEFycmF5XScpIHtcbiAgICAgIGlmIChibG9jayAmJiAoc3RhdGUuZHVtcC5sZW5ndGggIT09IDApKSB7XG4gICAgICAgIHdyaXRlQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXAsIGNvbXBhY3QpO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdyaXRlRmxvd1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgc3RhdGUuZHVtcCk7XG4gICAgICAgIGlmIChkdXBsaWNhdGUpIHtcbiAgICAgICAgICBzdGF0ZS5kdW1wID0gJyZyZWZfJyArIGR1cGxpY2F0ZUluZGV4ICsgJyAnICsgc3RhdGUuZHVtcDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ1tvYmplY3QgU3RyaW5nXScpIHtcbiAgICAgIGlmIChzdGF0ZS50YWcgIT09ICc/Jykge1xuICAgICAgICB3cml0ZVNjYWxhcihzdGF0ZSwgc3RhdGUuZHVtcCwgbGV2ZWwsIGlza2V5KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN0YXRlLnNraXBJbnZhbGlkKSByZXR1cm4gZmFsc2U7XG4gICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbigndW5hY2NlcHRhYmxlIGtpbmQgb2YgYW4gb2JqZWN0IHRvIGR1bXAgJyArIHR5cGUpO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS50YWcgIT09IG51bGwgJiYgc3RhdGUudGFnICE9PSAnPycpIHtcbiAgICAgIHN0YXRlLmR1bXAgPSAnITwnICsgc3RhdGUudGFnICsgJz4gJyArIHN0YXRlLmR1bXA7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldER1cGxpY2F0ZVJlZmVyZW5jZXMob2JqZWN0LCBzdGF0ZSkge1xuICB2YXIgb2JqZWN0cyA9IFtdLFxuICAgICAgZHVwbGljYXRlc0luZGV4ZXMgPSBbXSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoO1xuXG4gIGluc3BlY3ROb2RlKG9iamVjdCwgb2JqZWN0cywgZHVwbGljYXRlc0luZGV4ZXMpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBkdXBsaWNhdGVzSW5kZXhlcy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgc3RhdGUuZHVwbGljYXRlcy5wdXNoKG9iamVjdHNbZHVwbGljYXRlc0luZGV4ZXNbaW5kZXhdXSk7XG4gIH1cbiAgc3RhdGUudXNlZER1cGxpY2F0ZXMgPSBuZXcgQXJyYXkobGVuZ3RoKTtcbn1cblxuZnVuY3Rpb24gaW5zcGVjdE5vZGUob2JqZWN0LCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcykge1xuICB2YXIgb2JqZWN0S2V5TGlzdCxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoO1xuXG4gIGlmIChvYmplY3QgIT09IG51bGwgJiYgdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcpIHtcbiAgICBpbmRleCA9IG9iamVjdHMuaW5kZXhPZihvYmplY3QpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIGlmIChkdXBsaWNhdGVzSW5kZXhlcy5pbmRleE9mKGluZGV4KSA9PT0gLTEpIHtcbiAgICAgICAgZHVwbGljYXRlc0luZGV4ZXMucHVzaChpbmRleCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG9iamVjdHMucHVzaChvYmplY3QpO1xuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmplY3QpKSB7XG4gICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgICAgIGluc3BlY3ROb2RlKG9iamVjdFtpbmRleF0sIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqZWN0S2V5TGlzdCA9IE9iamVjdC5rZXlzKG9iamVjdCk7XG5cbiAgICAgICAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdEtleUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgICAgIGluc3BlY3ROb2RlKG9iamVjdFtvYmplY3RLZXlMaXN0W2luZGV4XV0sIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkdW1wKGlucHV0LCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBzdGF0ZSA9IG5ldyBTdGF0ZShvcHRpb25zKTtcblxuICBpZiAoIXN0YXRlLm5vUmVmcykgZ2V0RHVwbGljYXRlUmVmZXJlbmNlcyhpbnB1dCwgc3RhdGUpO1xuXG4gIGlmICh3cml0ZU5vZGUoc3RhdGUsIDAsIGlucHV0LCB0cnVlLCB0cnVlKSkgcmV0dXJuIHN0YXRlLmR1bXAgKyAnXFxuJztcblxuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIHNhZmVEdW1wKGlucHV0LCBvcHRpb25zKSB7XG4gIHJldHVybiBkdW1wKGlucHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuZHVtcCAgICAgPSBkdW1wO1xubW9kdWxlLmV4cG9ydHMuc2FmZUR1bXAgPSBzYWZlRHVtcDtcbiIsIi8vIFlBTUwgZXJyb3IgY2xhc3MuIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvODQ1ODk4NFxuLy9cbid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gWUFNTEV4Y2VwdGlvbihyZWFzb24sIG1hcmspIHtcbiAgLy8gU3VwZXIgY29uc3RydWN0b3JcbiAgRXJyb3IuY2FsbCh0aGlzKTtcblxuICAvLyBJbmNsdWRlIHN0YWNrIHRyYWNlIGluIGVycm9yIG9iamVjdFxuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICAvLyBDaHJvbWUgYW5kIE5vZGVKU1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHRoaXMuY29uc3RydWN0b3IpO1xuICB9IGVsc2Uge1xuICAgIC8vIEZGLCBJRSAxMCsgYW5kIFNhZmFyaSA2Ky4gRmFsbGJhY2sgZm9yIG90aGVyc1xuICAgIHRoaXMuc3RhY2sgPSAobmV3IEVycm9yKCkpLnN0YWNrIHx8ICcnO1xuICB9XG5cbiAgdGhpcy5uYW1lID0gJ1lBTUxFeGNlcHRpb24nO1xuICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgdGhpcy5tYXJrID0gbWFyaztcbiAgdGhpcy5tZXNzYWdlID0gKHRoaXMucmVhc29uIHx8ICcodW5rbm93biByZWFzb24pJykgKyAodGhpcy5tYXJrID8gJyAnICsgdGhpcy5tYXJrLnRvU3RyaW5nKCkgOiAnJyk7XG59XG5cblxuLy8gSW5oZXJpdCBmcm9tIEVycm9yXG5ZQU1MRXhjZXB0aW9uLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTtcbllBTUxFeGNlcHRpb24ucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gWUFNTEV4Y2VwdGlvbjtcblxuXG5ZQU1MRXhjZXB0aW9uLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKGNvbXBhY3QpIHtcbiAgdmFyIHJlc3VsdCA9IHRoaXMubmFtZSArICc6ICc7XG5cbiAgcmVzdWx0ICs9IHRoaXMucmVhc29uIHx8ICcodW5rbm93biByZWFzb24pJztcblxuICBpZiAoIWNvbXBhY3QgJiYgdGhpcy5tYXJrKSB7XG4gICAgcmVzdWx0ICs9ICcgJyArIHRoaXMubWFyay50b1N0cmluZygpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBZQU1MRXhjZXB0aW9uO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG1heC1sZW4sbm8tdXNlLWJlZm9yZS1kZWZpbmUqL1xuXG52YXIgY29tbW9uICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgWUFNTEV4Y2VwdGlvbiAgICAgICA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7XG52YXIgTWFyayAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vbWFyaycpO1xudmFyIERFRkFVTFRfU0FGRV9TQ0hFTUEgPSByZXF1aXJlKCcuL3NjaGVtYS9kZWZhdWx0X3NhZmUnKTtcbnZhciBERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG5cblxudmFyIF9oYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cblxudmFyIENPTlRFWFRfRkxPV19JTiAgID0gMTtcbnZhciBDT05URVhUX0ZMT1dfT1VUICA9IDI7XG52YXIgQ09OVEVYVF9CTE9DS19JTiAgPSAzO1xudmFyIENPTlRFWFRfQkxPQ0tfT1VUID0gNDtcblxuXG52YXIgQ0hPTVBJTkdfQ0xJUCAgPSAxO1xudmFyIENIT01QSU5HX1NUUklQID0gMjtcbnZhciBDSE9NUElOR19LRUVQICA9IDM7XG5cblxudmFyIFBBVFRFUk5fTk9OX1BSSU5UQUJMRSAgICAgICAgID0gL1tcXHgwMC1cXHgwOFxceDBCXFx4MENcXHgwRS1cXHgxRlxceDdGLVxceDg0XFx4ODYtXFx4OUZcXHVGRkZFXFx1RkZGRl18W1xcdUQ4MDAtXFx1REJGRl0oPyFbXFx1REMwMC1cXHVERkZGXSl8KD86W15cXHVEODAwLVxcdURCRkZdfF4pW1xcdURDMDAtXFx1REZGRl0vO1xudmFyIFBBVFRFUk5fTk9OX0FTQ0lJX0xJTkVfQlJFQUtTID0gL1tcXHg4NVxcdTIwMjhcXHUyMDI5XS87XG52YXIgUEFUVEVSTl9GTE9XX0lORElDQVRPUlMgICAgICAgPSAvWyxcXFtcXF1cXHtcXH1dLztcbnZhciBQQVRURVJOX1RBR19IQU5ETEUgICAgICAgICAgICA9IC9eKD86IXwhIXwhW2EtelxcLV0rISkkL2k7XG52YXIgUEFUVEVSTl9UQUdfVVJJICAgICAgICAgICAgICAgPSAvXig/OiF8W14sXFxbXFxdXFx7XFx9XSkoPzolWzAtOWEtZl17Mn18WzAtOWEtelxcLSM7XFwvXFw/OkAmPVxcK1xcJCxfXFwuIX5cXConXFwoXFwpXFxbXFxdXSkqJC9pO1xuXG5cbmZ1bmN0aW9uIGlzX0VPTChjKSB7XG4gIHJldHVybiAoYyA9PT0gMHgwQS8qIExGICovKSB8fCAoYyA9PT0gMHgwRC8qIENSICovKTtcbn1cblxuZnVuY3Rpb24gaXNfV0hJVEVfU1BBQ0UoYykge1xuICByZXR1cm4gKGMgPT09IDB4MDkvKiBUYWIgKi8pIHx8IChjID09PSAweDIwLyogU3BhY2UgKi8pO1xufVxuXG5mdW5jdGlvbiBpc19XU19PUl9FT0woYykge1xuICByZXR1cm4gKGMgPT09IDB4MDkvKiBUYWIgKi8pIHx8XG4gICAgICAgICAoYyA9PT0gMHgyMC8qIFNwYWNlICovKSB8fFxuICAgICAgICAgKGMgPT09IDB4MEEvKiBMRiAqLykgfHxcbiAgICAgICAgIChjID09PSAweDBELyogQ1IgKi8pO1xufVxuXG5mdW5jdGlvbiBpc19GTE9XX0lORElDQVRPUihjKSB7XG4gIHJldHVybiBjID09PSAweDJDLyogLCAqLyB8fFxuICAgICAgICAgYyA9PT0gMHg1Qi8qIFsgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4NUQvKiBdICovIHx8XG4gICAgICAgICBjID09PSAweDdCLyogeyAqLyB8fFxuICAgICAgICAgYyA9PT0gMHg3RC8qIH0gKi87XG59XG5cbmZ1bmN0aW9uIGZyb21IZXhDb2RlKGMpIHtcbiAgdmFyIGxjO1xuXG4gIGlmICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKSB7XG4gICAgcmV0dXJuIGMgLSAweDMwO1xuICB9XG5cbiAgLyplc2xpbnQtZGlzYWJsZSBuby1iaXR3aXNlKi9cbiAgbGMgPSBjIHwgMHgyMDtcblxuICBpZiAoKDB4NjEvKiBhICovIDw9IGxjKSAmJiAobGMgPD0gMHg2Ni8qIGYgKi8pKSB7XG4gICAgcmV0dXJuIGxjIC0gMHg2MSArIDEwO1xuICB9XG5cbiAgcmV0dXJuIC0xO1xufVxuXG5mdW5jdGlvbiBlc2NhcGVkSGV4TGVuKGMpIHtcbiAgaWYgKGMgPT09IDB4NzgvKiB4ICovKSB7IHJldHVybiAyOyB9XG4gIGlmIChjID09PSAweDc1LyogdSAqLykgeyByZXR1cm4gNDsgfVxuICBpZiAoYyA9PT0gMHg1NS8qIFUgKi8pIHsgcmV0dXJuIDg7IH1cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIGZyb21EZWNpbWFsQ29kZShjKSB7XG4gIGlmICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKSB7XG4gICAgcmV0dXJuIGMgLSAweDMwO1xuICB9XG5cbiAgcmV0dXJuIC0xO1xufVxuXG5mdW5jdGlvbiBzaW1wbGVFc2NhcGVTZXF1ZW5jZShjKSB7XG4gIHJldHVybiAoYyA9PT0gMHgzMC8qIDAgKi8pID8gJ1xceDAwJyA6XG4gICAgICAgIChjID09PSAweDYxLyogYSAqLykgPyAnXFx4MDcnIDpcbiAgICAgICAgKGMgPT09IDB4NjIvKiBiICovKSA/ICdcXHgwOCcgOlxuICAgICAgICAoYyA9PT0gMHg3NC8qIHQgKi8pID8gJ1xceDA5JyA6XG4gICAgICAgIChjID09PSAweDA5LyogVGFiICovKSA/ICdcXHgwOScgOlxuICAgICAgICAoYyA9PT0gMHg2RS8qIG4gKi8pID8gJ1xceDBBJyA6XG4gICAgICAgIChjID09PSAweDc2LyogdiAqLykgPyAnXFx4MEInIDpcbiAgICAgICAgKGMgPT09IDB4NjYvKiBmICovKSA/ICdcXHgwQycgOlxuICAgICAgICAoYyA9PT0gMHg3Mi8qIHIgKi8pID8gJ1xceDBEJyA6XG4gICAgICAgIChjID09PSAweDY1LyogZSAqLykgPyAnXFx4MUInIDpcbiAgICAgICAgKGMgPT09IDB4MjAvKiBTcGFjZSAqLykgPyAnICcgOlxuICAgICAgICAoYyA9PT0gMHgyMi8qIFwiICovKSA/ICdcXHgyMicgOlxuICAgICAgICAoYyA9PT0gMHgyRi8qIC8gKi8pID8gJy8nIDpcbiAgICAgICAgKGMgPT09IDB4NUMvKiBcXCAqLykgPyAnXFx4NUMnIDpcbiAgICAgICAgKGMgPT09IDB4NEUvKiBOICovKSA/ICdcXHg4NScgOlxuICAgICAgICAoYyA9PT0gMHg1Ri8qIF8gKi8pID8gJ1xceEEwJyA6XG4gICAgICAgIChjID09PSAweDRDLyogTCAqLykgPyAnXFx1MjAyOCcgOlxuICAgICAgICAoYyA9PT0gMHg1MC8qIFAgKi8pID8gJ1xcdTIwMjknIDogJyc7XG59XG5cbmZ1bmN0aW9uIGNoYXJGcm9tQ29kZXBvaW50KGMpIHtcbiAgaWYgKGMgPD0gMHhGRkZGKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7XG4gIH1cbiAgLy8gRW5jb2RlIFVURi0xNiBzdXJyb2dhdGUgcGFpclxuICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VVEYtMTYjQ29kZV9wb2ludHNfVS4yQjAxMDAwMF90b19VLjJCMTBGRkZGXG4gIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAtIDB4MDEwMDAwKSA+PiAxMCkgKyAweEQ4MDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoYyAtIDB4MDEwMDAwKSAmIDB4MDNGRikgKyAweERDMDApO1xufVxuXG52YXIgc2ltcGxlRXNjYXBlQ2hlY2sgPSBuZXcgQXJyYXkoMjU2KTsgLy8gaW50ZWdlciwgZm9yIGZhc3QgYWNjZXNzXG52YXIgc2ltcGxlRXNjYXBlTWFwID0gbmV3IEFycmF5KDI1Nik7XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgaSsrKSB7XG4gIHNpbXBsZUVzY2FwZUNoZWNrW2ldID0gc2ltcGxlRXNjYXBlU2VxdWVuY2UoaSkgPyAxIDogMDtcbiAgc2ltcGxlRXNjYXBlTWFwW2ldID0gc2ltcGxlRXNjYXBlU2VxdWVuY2UoaSk7XG59XG5cblxuZnVuY3Rpb24gU3RhdGUoaW5wdXQsIG9wdGlvbnMpIHtcbiAgdGhpcy5pbnB1dCA9IGlucHV0O1xuXG4gIHRoaXMuZmlsZW5hbWUgID0gb3B0aW9uc1snZmlsZW5hbWUnXSAgfHwgbnVsbDtcbiAgdGhpcy5zY2hlbWEgICAgPSBvcHRpb25zWydzY2hlbWEnXSAgICB8fCBERUZBVUxUX0ZVTExfU0NIRU1BO1xuICB0aGlzLm9uV2FybmluZyA9IG9wdGlvbnNbJ29uV2FybmluZyddIHx8IG51bGw7XG4gIHRoaXMubGVnYWN5ICAgID0gb3B0aW9uc1snbGVnYWN5J10gICAgfHwgZmFsc2U7XG4gIHRoaXMuanNvbiAgICAgID0gb3B0aW9uc1snanNvbiddICAgICAgfHwgZmFsc2U7XG4gIHRoaXMubGlzdGVuZXIgID0gb3B0aW9uc1snbGlzdGVuZXInXSAgfHwgbnVsbDtcblxuICB0aGlzLmltcGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEltcGxpY2l0O1xuICB0aGlzLnR5cGVNYXAgICAgICAgPSB0aGlzLnNjaGVtYS5jb21waWxlZFR5cGVNYXA7XG5cbiAgdGhpcy5sZW5ndGggICAgID0gaW5wdXQubGVuZ3RoO1xuICB0aGlzLnBvc2l0aW9uICAgPSAwO1xuICB0aGlzLmxpbmUgICAgICAgPSAwO1xuICB0aGlzLmxpbmVTdGFydCAgPSAwO1xuICB0aGlzLmxpbmVJbmRlbnQgPSAwO1xuXG4gIHRoaXMuZG9jdW1lbnRzID0gW107XG5cbiAgLypcbiAgdGhpcy52ZXJzaW9uO1xuICB0aGlzLmNoZWNrTGluZUJyZWFrcztcbiAgdGhpcy50YWdNYXA7XG4gIHRoaXMuYW5jaG9yTWFwO1xuICB0aGlzLnRhZztcbiAgdGhpcy5hbmNob3I7XG4gIHRoaXMua2luZDtcbiAgdGhpcy5yZXN1bHQ7Ki9cblxufVxuXG5cbmZ1bmN0aW9uIGdlbmVyYXRlRXJyb3Ioc3RhdGUsIG1lc3NhZ2UpIHtcbiAgcmV0dXJuIG5ldyBZQU1MRXhjZXB0aW9uKFxuICAgIG1lc3NhZ2UsXG4gICAgbmV3IE1hcmsoc3RhdGUuZmlsZW5hbWUsIHN0YXRlLmlucHV0LCBzdGF0ZS5wb3NpdGlvbiwgc3RhdGUubGluZSwgKHN0YXRlLnBvc2l0aW9uIC0gc3RhdGUubGluZVN0YXJ0KSkpO1xufVxuXG5mdW5jdGlvbiB0aHJvd0Vycm9yKHN0YXRlLCBtZXNzYWdlKSB7XG4gIHRocm93IGdlbmVyYXRlRXJyb3Ioc3RhdGUsIG1lc3NhZ2UpO1xufVxuXG5mdW5jdGlvbiB0aHJvd1dhcm5pbmcoc3RhdGUsIG1lc3NhZ2UpIHtcbiAgaWYgKHN0YXRlLm9uV2FybmluZykge1xuICAgIHN0YXRlLm9uV2FybmluZy5jYWxsKG51bGwsIGdlbmVyYXRlRXJyb3Ioc3RhdGUsIG1lc3NhZ2UpKTtcbiAgfVxufVxuXG5cbnZhciBkaXJlY3RpdmVIYW5kbGVycyA9IHtcblxuICBZQU1MOiBmdW5jdGlvbiBoYW5kbGVZYW1sRGlyZWN0aXZlKHN0YXRlLCBuYW1lLCBhcmdzKSB7XG5cbiAgICB2YXIgbWF0Y2gsIG1ham9yLCBtaW5vcjtcblxuICAgIGlmIChzdGF0ZS52ZXJzaW9uICE9PSBudWxsKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRpb24gb2YgJVlBTUwgZGlyZWN0aXZlJyk7XG4gICAgfVxuXG4gICAgaWYgKGFyZ3MubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnWUFNTCBkaXJlY3RpdmUgYWNjZXB0cyBleGFjdGx5IG9uZSBhcmd1bWVudCcpO1xuICAgIH1cblxuICAgIG1hdGNoID0gL14oWzAtOV0rKVxcLihbMC05XSspJC8uZXhlYyhhcmdzWzBdKTtcblxuICAgIGlmIChtYXRjaCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2lsbC1mb3JtZWQgYXJndW1lbnQgb2YgdGhlIFlBTUwgZGlyZWN0aXZlJyk7XG4gICAgfVxuXG4gICAgbWFqb3IgPSBwYXJzZUludChtYXRjaFsxXSwgMTApO1xuICAgIG1pbm9yID0gcGFyc2VJbnQobWF0Y2hbMl0sIDEwKTtcblxuICAgIGlmIChtYWpvciAhPT0gMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuYWNjZXB0YWJsZSBZQU1MIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50Jyk7XG4gICAgfVxuXG4gICAgc3RhdGUudmVyc2lvbiA9IGFyZ3NbMF07XG4gICAgc3RhdGUuY2hlY2tMaW5lQnJlYWtzID0gKG1pbm9yIDwgMik7XG5cbiAgICBpZiAobWlub3IgIT09IDEgJiYgbWlub3IgIT09IDIpIHtcbiAgICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ3Vuc3VwcG9ydGVkIFlBTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQnKTtcbiAgICB9XG4gIH0sXG5cbiAgVEFHOiBmdW5jdGlvbiBoYW5kbGVUYWdEaXJlY3RpdmUoc3RhdGUsIG5hbWUsIGFyZ3MpIHtcblxuICAgIHZhciBoYW5kbGUsIHByZWZpeDtcblxuICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMikge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ1RBRyBkaXJlY3RpdmUgYWNjZXB0cyBleGFjdGx5IHR3byBhcmd1bWVudHMnKTtcbiAgICB9XG5cbiAgICBoYW5kbGUgPSBhcmdzWzBdO1xuICAgIHByZWZpeCA9IGFyZ3NbMV07XG5cbiAgICBpZiAoIVBBVFRFUk5fVEFHX0hBTkRMRS50ZXN0KGhhbmRsZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIHRhZyBoYW5kbGUgKGZpcnN0IGFyZ3VtZW50KSBvZiB0aGUgVEFHIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChzdGF0ZS50YWdNYXAsIGhhbmRsZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0aGVyZSBpcyBhIHByZXZpb3VzbHkgZGVjbGFyZWQgc3VmZml4IGZvciBcIicgKyBoYW5kbGUgKyAnXCIgdGFnIGhhbmRsZScpO1xuICAgIH1cblxuICAgIGlmICghUEFUVEVSTl9UQUdfVVJJLnRlc3QocHJlZml4KSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2lsbC1mb3JtZWQgdGFnIHByZWZpeCAoc2Vjb25kIGFyZ3VtZW50KSBvZiB0aGUgVEFHIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIHN0YXRlLnRhZ01hcFtoYW5kbGVdID0gcHJlZml4O1xuICB9XG59O1xuXG5cbmZ1bmN0aW9uIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBzdGFydCwgZW5kLCBjaGVja0pzb24pIHtcbiAgdmFyIF9wb3NpdGlvbiwgX2xlbmd0aCwgX2NoYXJhY3RlciwgX3Jlc3VsdDtcblxuICBpZiAoc3RhcnQgPCBlbmQpIHtcbiAgICBfcmVzdWx0ID0gc3RhdGUuaW5wdXQuc2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBpZiAoY2hlY2tKc29uKSB7XG4gICAgICBmb3IgKF9wb3NpdGlvbiA9IDAsIF9sZW5ndGggPSBfcmVzdWx0Lmxlbmd0aDtcbiAgICAgICAgICAgX3Bvc2l0aW9uIDwgX2xlbmd0aDtcbiAgICAgICAgICAgX3Bvc2l0aW9uICs9IDEpIHtcbiAgICAgICAgX2NoYXJhY3RlciA9IF9yZXN1bHQuY2hhckNvZGVBdChfcG9zaXRpb24pO1xuICAgICAgICBpZiAoIShfY2hhcmFjdGVyID09PSAweDA5IHx8XG4gICAgICAgICAgICAgICgweDIwIDw9IF9jaGFyYWN0ZXIgJiYgX2NoYXJhY3RlciA8PSAweDEwRkZGRikpKSB7XG4gICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2V4cGVjdGVkIHZhbGlkIEpTT04gY2hhcmFjdGVyJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKFBBVFRFUk5fTk9OX1BSSU5UQUJMRS50ZXN0KF9yZXN1bHQpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGhlIHN0cmVhbSBjb250YWlucyBub24tcHJpbnRhYmxlIGNoYXJhY3RlcnMnKTtcbiAgICB9XG5cbiAgICBzdGF0ZS5yZXN1bHQgKz0gX3Jlc3VsdDtcbiAgfVxufVxuXG5mdW5jdGlvbiBtZXJnZU1hcHBpbmdzKHN0YXRlLCBkZXN0aW5hdGlvbiwgc291cmNlLCBvdmVycmlkYWJsZUtleXMpIHtcbiAgdmFyIHNvdXJjZUtleXMsIGtleSwgaW5kZXgsIHF1YW50aXR5O1xuXG4gIGlmICghY29tbW9uLmlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2Fubm90IG1lcmdlIG1hcHBpbmdzOyB0aGUgcHJvdmlkZWQgc291cmNlIG9iamVjdCBpcyB1bmFjY2VwdGFibGUnKTtcbiAgfVxuXG4gIHNvdXJjZUtleXMgPSBPYmplY3Qua2V5cyhzb3VyY2UpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBxdWFudGl0eSA9IHNvdXJjZUtleXMubGVuZ3RoOyBpbmRleCA8IHF1YW50aXR5OyBpbmRleCArPSAxKSB7XG4gICAga2V5ID0gc291cmNlS2V5c1tpbmRleF07XG5cbiAgICBpZiAoIV9oYXNPd25Qcm9wZXJ0eS5jYWxsKGRlc3RpbmF0aW9uLCBrZXkpKSB7XG4gICAgICBkZXN0aW5hdGlvbltrZXldID0gc291cmNlW2tleV07XG4gICAgICBvdmVycmlkYWJsZUtleXNba2V5XSA9IHRydWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIF9yZXN1bHQsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCB2YWx1ZU5vZGUpIHtcbiAgdmFyIGluZGV4LCBxdWFudGl0eTtcblxuICBrZXlOb2RlID0gU3RyaW5nKGtleU5vZGUpO1xuXG4gIGlmIChfcmVzdWx0ID09PSBudWxsKSB7XG4gICAgX3Jlc3VsdCA9IHt9O1xuICB9XG5cbiAgaWYgKGtleVRhZyA9PT0gJ3RhZzp5YW1sLm9yZywyMDAyOm1lcmdlJykge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlTm9kZSkpIHtcbiAgICAgIGZvciAoaW5kZXggPSAwLCBxdWFudGl0eSA9IHZhbHVlTm9kZS5sZW5ndGg7IGluZGV4IDwgcXVhbnRpdHk7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgbWVyZ2VNYXBwaW5ncyhzdGF0ZSwgX3Jlc3VsdCwgdmFsdWVOb2RlW2luZGV4XSwgb3ZlcnJpZGFibGVLZXlzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbWVyZ2VNYXBwaW5ncyhzdGF0ZSwgX3Jlc3VsdCwgdmFsdWVOb2RlLCBvdmVycmlkYWJsZUtleXMpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoIXN0YXRlLmpzb24gJiZcbiAgICAgICAgIV9oYXNPd25Qcm9wZXJ0eS5jYWxsKG92ZXJyaWRhYmxlS2V5cywga2V5Tm9kZSkgJiZcbiAgICAgICAgX2hhc093blByb3BlcnR5LmNhbGwoX3Jlc3VsdCwga2V5Tm9kZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGVkIG1hcHBpbmcga2V5Jyk7XG4gICAgfVxuICAgIF9yZXN1bHRba2V5Tm9kZV0gPSB2YWx1ZU5vZGU7XG4gICAgZGVsZXRlIG92ZXJyaWRhYmxlS2V5c1trZXlOb2RlXTtcbiAgfVxuXG4gIHJldHVybiBfcmVzdWx0O1xufVxuXG5mdW5jdGlvbiByZWFkTGluZUJyZWFrKHN0YXRlKSB7XG4gIHZhciBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHgwQS8qIExGICovKSB7XG4gICAgc3RhdGUucG9zaXRpb24rKztcbiAgfSBlbHNlIGlmIChjaCA9PT0gMHgwRC8qIENSICovKSB7XG4gICAgc3RhdGUucG9zaXRpb24rKztcbiAgICBpZiAoc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikgPT09IDB4MEEvKiBMRiAqLykge1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2EgbGluZSBicmVhayBpcyBleHBlY3RlZCcpO1xuICB9XG5cbiAgc3RhdGUubGluZSArPSAxO1xuICBzdGF0ZS5saW5lU3RhcnQgPSBzdGF0ZS5wb3NpdGlvbjtcbn1cblxuZnVuY3Rpb24gc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgYWxsb3dDb21tZW50cywgY2hlY2tJbmRlbnQpIHtcbiAgdmFyIGxpbmVCcmVha3MgPSAwLFxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKGFsbG93Q29tbWVudHMgJiYgY2ggPT09IDB4MjMvKiAjICovKSB7XG4gICAgICBkbyB7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH0gd2hpbGUgKGNoICE9PSAweDBBLyogTEYgKi8gJiYgY2ggIT09IDB4MEQvKiBDUiAqLyAmJiBjaCAhPT0gMCk7XG4gICAgfVxuXG4gICAgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIHJlYWRMaW5lQnJlYWsoc3RhdGUpO1xuXG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgICAgbGluZUJyZWFrcysrO1xuICAgICAgc3RhdGUubGluZUluZGVudCA9IDA7XG5cbiAgICAgIHdoaWxlIChjaCA9PT0gMHgyMC8qIFNwYWNlICovKSB7XG4gICAgICAgIHN0YXRlLmxpbmVJbmRlbnQrKztcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoY2hlY2tJbmRlbnQgIT09IC0xICYmIGxpbmVCcmVha3MgIT09IDAgJiYgc3RhdGUubGluZUluZGVudCA8IGNoZWNrSW5kZW50KSB7XG4gICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAnZGVmaWNpZW50IGluZGVudGF0aW9uJyk7XG4gIH1cblxuICByZXR1cm4gbGluZUJyZWFrcztcbn1cblxuZnVuY3Rpb24gdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSB7XG4gIHZhciBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbixcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24pO1xuXG4gIC8vIENvbmRpdGlvbiBzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0IGlzIHRlc3RlZFxuICAvLyBpbiBwYXJlbnQgb24gZWFjaCBjYWxsLCBmb3IgZWZmaWNpZW5jeS4gTm8gbmVlZHMgdG8gdGVzdCBoZXJlIGFnYWluLlxuICBpZiAoKGNoID09PSAweDJELyogLSAqLyB8fCBjaCA9PT0gMHgyRS8qIC4gKi8pICYmXG4gICAgICBjaCA9PT0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24gKyAxKSAmJlxuICAgICAgY2ggPT09IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uICsgMikpIHtcblxuICAgIF9wb3NpdGlvbiArPSAzO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KF9wb3NpdGlvbik7XG5cbiAgICBpZiAoY2ggPT09IDAgfHwgaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBjb3VudCkge1xuICBpZiAoY291bnQgPT09IDEpIHtcbiAgICBzdGF0ZS5yZXN1bHQgKz0gJyAnO1xuICB9IGVsc2UgaWYgKGNvdW50ID4gMSkge1xuICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBjb3VudCAtIDEpO1xuICB9XG59XG5cblxuZnVuY3Rpb24gcmVhZFBsYWluU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50LCB3aXRoaW5GbG93Q29sbGVjdGlvbikge1xuICB2YXIgcHJlY2VkaW5nLFxuICAgICAgZm9sbG93aW5nLFxuICAgICAgY2FwdHVyZVN0YXJ0LFxuICAgICAgY2FwdHVyZUVuZCxcbiAgICAgIGhhc1BlbmRpbmdDb250ZW50LFxuICAgICAgX2xpbmUsXG4gICAgICBfbGluZVN0YXJ0LFxuICAgICAgX2xpbmVJbmRlbnQsXG4gICAgICBfa2luZCA9IHN0YXRlLmtpbmQsXG4gICAgICBfcmVzdWx0ID0gc3RhdGUucmVzdWx0LFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoaXNfV1NfT1JfRU9MKGNoKSAgICAgIHx8XG4gICAgICBpc19GTE9XX0lORElDQVRPUihjaCkgfHxcbiAgICAgIGNoID09PSAweDIzLyogIyAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MjYvKiAmICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyQS8qICogKi8gICAgfHxcbiAgICAgIGNoID09PSAweDIxLyogISAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4N0MvKiB8ICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgzRS8qID4gKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI3LyogJyAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MjIvKiBcIiAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MjUvKiAlICovICAgIHx8XG4gICAgICBjaCA9PT0gMHg0MC8qIEAgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDYwLyogYCAqLykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChjaCA9PT0gMHgzRi8qID8gKi8gfHwgY2ggPT09IDB4MkQvKiAtICovKSB7XG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpIHx8XG4gICAgICAgIHdpdGhpbkZsb3dDb2xsZWN0aW9uICYmIGlzX0ZMT1dfSU5ESUNBVE9SKGZvbGxvd2luZykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBzdGF0ZS5raW5kID0gJ3NjYWxhcic7XG4gIHN0YXRlLnJlc3VsdCA9ICcnO1xuICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gIGhhc1BlbmRpbmdDb250ZW50ID0gZmFsc2U7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgaWYgKGNoID09PSAweDNBLyogOiAqLykge1xuICAgICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgICBpZiAoaXNfV1NfT1JfRU9MKGZvbGxvd2luZykgfHxcbiAgICAgICAgICB3aXRoaW5GbG93Q29sbGVjdGlvbiAmJiBpc19GTE9XX0lORElDQVRPUihmb2xsb3dpbmcpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHtcbiAgICAgIHByZWNlZGluZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gLSAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChwcmVjZWRpbmcpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIGlmICgoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB8fFxuICAgICAgICAgICAgICAgd2l0aGluRmxvd0NvbGxlY3Rpb24gJiYgaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgICBicmVhaztcblxuICAgIH0gZWxzZSBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgICAgX2xpbmVTdGFydCA9IHN0YXRlLmxpbmVTdGFydDtcbiAgICAgIF9saW5lSW5kZW50ID0gc3RhdGUubGluZUluZGVudDtcbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGZhbHNlLCAtMSk7XG5cbiAgICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID49IG5vZGVJbmRlbnQpIHtcbiAgICAgICAgaGFzUGVuZGluZ0NvbnRlbnQgPSB0cnVlO1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnBvc2l0aW9uID0gY2FwdHVyZUVuZDtcbiAgICAgICAgc3RhdGUubGluZSA9IF9saW5lO1xuICAgICAgICBzdGF0ZS5saW5lU3RhcnQgPSBfbGluZVN0YXJ0O1xuICAgICAgICBzdGF0ZS5saW5lSW5kZW50ID0gX2xpbmVJbmRlbnQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChoYXNQZW5kaW5nQ29udGVudCkge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgZmFsc2UpO1xuICAgICAgd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgc3RhdGUubGluZSAtIF9saW5lKTtcbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcbiAgICAgIGhhc1BlbmRpbmdDb250ZW50ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCFpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICAgIGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbiArIDE7XG4gICAgfVxuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgZmFsc2UpO1xuXG4gIGlmIChzdGF0ZS5yZXN1bHQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHN0YXRlLmtpbmQgPSBfa2luZDtcbiAgc3RhdGUucmVzdWx0ID0gX3Jlc3VsdDtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiByZWFkU2luZ2xlUXVvdGVkU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjaCxcbiAgICAgIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyNy8qICcgKi8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzdGF0ZS5raW5kID0gJ3NjYWxhcic7XG4gIHN0YXRlLnJlc3VsdCA9ICcnO1xuICBzdGF0ZS5wb3NpdGlvbisrO1xuICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG5cbiAgd2hpbGUgKChjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pKSAhPT0gMCkge1xuICAgIGlmIChjaCA9PT0gMHgyNy8qICcgKi8pIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCB0cnVlKTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgaWYgKGNoID09PSAweDI3LyogJyAqLykge1xuICAgICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgdHJ1ZSk7XG4gICAgICB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCkpO1xuICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgfSBlbHNlIGlmIChzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0ICYmIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgZG9jdW1lbnQgd2l0aGluIGEgc2luZ2xlIHF1b3RlZCBzY2FsYXInKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgIH1cbiAgfVxuXG4gIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIHNpbmdsZSBxdW90ZWQgc2NhbGFyJyk7XG59XG5cbmZ1bmN0aW9uIHJlYWREb3VibGVRdW90ZWRTY2FsYXIoc3RhdGUsIG5vZGVJbmRlbnQpIHtcbiAgdmFyIGNhcHR1cmVTdGFydCxcbiAgICAgIGNhcHR1cmVFbmQsXG4gICAgICBoZXhMZW5ndGgsXG4gICAgICBoZXhSZXN1bHQsXG4gICAgICB0bXAsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyMi8qIFwiICovKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgc3RhdGUucG9zaXRpb24rKztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlICgoY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkgIT09IDApIHtcbiAgICBpZiAoY2ggPT09IDB4MjIvKiBcIiAqLykge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIHRydWUpO1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgfSBlbHNlIGlmIChjaCA9PT0gMHg1Qy8qIFxcICovKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGZhbHNlLCBub2RlSW5kZW50KTtcblxuICAgICAgICAvLyBUT0RPOiByZXdvcmsgdG8gaW5saW5lIGZuIHdpdGggbm8gdHlwZSBjYXN0P1xuICAgICAgfSBlbHNlIGlmIChjaCA8IDI1NiAmJiBzaW1wbGVFc2NhcGVDaGVja1tjaF0pIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IHNpbXBsZUVzY2FwZU1hcFtjaF07XG4gICAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG5cbiAgICAgIH0gZWxzZSBpZiAoKHRtcCA9IGVzY2FwZWRIZXhMZW4oY2gpKSA+IDApIHtcbiAgICAgICAgaGV4TGVuZ3RoID0gdG1wO1xuICAgICAgICBoZXhSZXN1bHQgPSAwO1xuXG4gICAgICAgIGZvciAoOyBoZXhMZW5ndGggPiAwOyBoZXhMZW5ndGgtLSkge1xuICAgICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICAgIGlmICgodG1wID0gZnJvbUhleENvZGUoY2gpKSA+PSAwKSB7XG4gICAgICAgICAgICBoZXhSZXN1bHQgPSAoaGV4UmVzdWx0IDw8IDQpICsgdG1wO1xuXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdleHBlY3RlZCBoZXhhZGVjaW1hbCBjaGFyYWN0ZXInKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY2hhckZyb21Db2RlcG9pbnQoaGV4UmVzdWx0KTtcblxuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5rbm93biBlc2NhcGUgc2VxdWVuY2UnKTtcbiAgICAgIH1cblxuICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgfSBlbHNlIGlmIChpc19FT0woY2gpKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBjYXB0dXJlRW5kLCB0cnVlKTtcbiAgICAgIHdyaXRlRm9sZGVkTGluZXMoc3RhdGUsIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGZhbHNlLCBub2RlSW5kZW50KSk7XG4gICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB9IGVsc2UgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZXhwZWN0ZWQgZW5kIG9mIHRoZSBkb2N1bWVudCB3aXRoaW4gYSBkb3VibGUgcXVvdGVkIHNjYWxhcicpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgfVxuICB9XG5cbiAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZXhwZWN0ZWQgZW5kIG9mIHRoZSBzdHJlYW0gd2l0aGluIGEgZG91YmxlIHF1b3RlZCBzY2FsYXInKTtcbn1cblxuZnVuY3Rpb24gcmVhZEZsb3dDb2xsZWN0aW9uKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciByZWFkTmV4dCA9IHRydWUsXG4gICAgICBfbGluZSxcbiAgICAgIF90YWcgICAgID0gc3RhdGUudGFnLFxuICAgICAgX3Jlc3VsdCxcbiAgICAgIF9hbmNob3IgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgZm9sbG93aW5nLFxuICAgICAgdGVybWluYXRvcixcbiAgICAgIGlzUGFpcixcbiAgICAgIGlzRXhwbGljaXRQYWlyLFxuICAgICAgaXNNYXBwaW5nLFxuICAgICAgb3ZlcnJpZGFibGVLZXlzID0ge30sXG4gICAgICBrZXlOb2RlLFxuICAgICAga2V5VGFnLFxuICAgICAgdmFsdWVOb2RlLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggPT09IDB4NUIvKiBbICovKSB7XG4gICAgdGVybWluYXRvciA9IDB4NUQ7LyogXSAqL1xuICAgIGlzTWFwcGluZyA9IGZhbHNlO1xuICAgIF9yZXN1bHQgPSBbXTtcbiAgfSBlbHNlIGlmIChjaCA9PT0gMHg3Qi8qIHsgKi8pIHtcbiAgICB0ZXJtaW5hdG9yID0gMHg3RDsvKiB9ICovXG4gICAgaXNNYXBwaW5nID0gdHJ1ZTtcbiAgICBfcmVzdWx0ID0ge307XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoY2ggPT09IHRlcm1pbmF0b3IpIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICBzdGF0ZS50YWcgPSBfdGFnO1xuICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICAgIHN0YXRlLmtpbmQgPSBpc01hcHBpbmcgPyAnbWFwcGluZycgOiAnc2VxdWVuY2UnO1xuICAgICAgc3RhdGUucmVzdWx0ID0gX3Jlc3VsdDtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAoIXJlYWROZXh0KSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbWlzc2VkIGNvbW1hIGJldHdlZW4gZmxvdyBjb2xsZWN0aW9uIGVudHJpZXMnKTtcbiAgICB9XG5cbiAgICBrZXlUYWcgPSBrZXlOb2RlID0gdmFsdWVOb2RlID0gbnVsbDtcbiAgICBpc1BhaXIgPSBpc0V4cGxpY2l0UGFpciA9IGZhbHNlO1xuXG4gICAgaWYgKGNoID09PSAweDNGLyogPyAqLykge1xuICAgICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgICBpZiAoaXNfV1NfT1JfRU9MKGZvbGxvd2luZykpIHtcbiAgICAgICAgaXNQYWlyID0gaXNFeHBsaWNpdFBhaXIgPSB0cnVlO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBfbGluZSA9IHN0YXRlLmxpbmU7XG4gICAgY29tcG9zZU5vZGUoc3RhdGUsIG5vZGVJbmRlbnQsIENPTlRFWFRfRkxPV19JTiwgZmFsc2UsIHRydWUpO1xuICAgIGtleVRhZyA9IHN0YXRlLnRhZztcbiAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmICgoaXNFeHBsaWNpdFBhaXIgfHwgc3RhdGUubGluZSA9PT0gX2xpbmUpICYmIGNoID09PSAweDNBLyogOiAqLykge1xuICAgICAgaXNQYWlyID0gdHJ1ZTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpO1xuICAgICAgY29tcG9zZU5vZGUoc3RhdGUsIG5vZGVJbmRlbnQsIENPTlRFWFRfRkxPV19JTiwgZmFsc2UsIHRydWUpO1xuICAgICAgdmFsdWVOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgIH1cblxuICAgIGlmIChpc01hcHBpbmcpIHtcbiAgICAgIHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIF9yZXN1bHQsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCB2YWx1ZU5vZGUpO1xuICAgIH0gZWxzZSBpZiAoaXNQYWlyKSB7XG4gICAgICBfcmVzdWx0LnB1c2goc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgbnVsbCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBfcmVzdWx0LnB1c2goa2V5Tm9kZSk7XG4gICAgfVxuXG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSAweDJDLyogLCAqLykge1xuICAgICAgcmVhZE5leHQgPSB0cnVlO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZWFkTmV4dCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIGZsb3cgY29sbGVjdGlvbicpO1xufVxuXG5mdW5jdGlvbiByZWFkQmxvY2tTY2FsYXIoc3RhdGUsIG5vZGVJbmRlbnQpIHtcbiAgdmFyIGNhcHR1cmVTdGFydCxcbiAgICAgIGZvbGRpbmcsXG4gICAgICBjaG9tcGluZyAgICAgICA9IENIT01QSU5HX0NMSVAsXG4gICAgICBkaWRSZWFkQ29udGVudCA9IGZhbHNlLFxuICAgICAgZGV0ZWN0ZWRJbmRlbnQgPSBmYWxzZSxcbiAgICAgIHRleHRJbmRlbnQgICAgID0gbm9kZUluZGVudCxcbiAgICAgIGVtcHR5TGluZXMgICAgID0gMCxcbiAgICAgIGF0TW9yZUluZGVudGVkID0gZmFsc2UsXG4gICAgICB0bXAsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHg3Qy8qIHwgKi8pIHtcbiAgICBmb2xkaW5nID0gZmFsc2U7XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4M0UvKiA+ICovKSB7XG4gICAgZm9sZGluZyA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoY2ggPT09IDB4MkIvKiArICovIHx8IGNoID09PSAweDJELyogLSAqLykge1xuICAgICAgaWYgKENIT01QSU5HX0NMSVAgPT09IGNob21waW5nKSB7XG4gICAgICAgIGNob21waW5nID0gKGNoID09PSAweDJCLyogKyAqLykgPyBDSE9NUElOR19LRUVQIDogQ0hPTVBJTkdfU1RSSVA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAncmVwZWF0IG9mIGEgY2hvbXBpbmcgbW9kZSBpZGVudGlmaWVyJyk7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKCh0bXAgPSBmcm9tRGVjaW1hbENvZGUoY2gpKSA+PSAwKSB7XG4gICAgICBpZiAodG1wID09PSAwKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgZXhwbGljaXQgaW5kZW50YXRpb24gd2lkdGggb2YgYSBibG9jayBzY2FsYXI7IGl0IGNhbm5vdCBiZSBsZXNzIHRoYW4gb25lJyk7XG4gICAgICB9IGVsc2UgaWYgKCFkZXRlY3RlZEluZGVudCkge1xuICAgICAgICB0ZXh0SW5kZW50ID0gbm9kZUluZGVudCArIHRtcCAtIDE7XG4gICAgICAgIGRldGVjdGVkSW5kZW50ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdyZXBlYXQgb2YgYW4gaW5kZW50YXRpb24gd2lkdGggaWRlbnRpZmllcicpO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgIHdoaWxlIChpc19XSElURV9TUEFDRShjaCkpO1xuXG4gICAgaWYgKGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICAgIHdoaWxlICghaXNfRU9MKGNoKSAmJiAoY2ggIT09IDApKTtcbiAgICB9XG4gIH1cblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICByZWFkTGluZUJyZWFrKHN0YXRlKTtcbiAgICBzdGF0ZS5saW5lSW5kZW50ID0gMDtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICB3aGlsZSAoKCFkZXRlY3RlZEluZGVudCB8fCBzdGF0ZS5saW5lSW5kZW50IDwgdGV4dEluZGVudCkgJiZcbiAgICAgICAgICAgKGNoID09PSAweDIwLyogU3BhY2UgKi8pKSB7XG4gICAgICBzdGF0ZS5saW5lSW5kZW50Kys7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKCFkZXRlY3RlZEluZGVudCAmJiBzdGF0ZS5saW5lSW5kZW50ID4gdGV4dEluZGVudCkge1xuICAgICAgdGV4dEluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7XG4gICAgfVxuXG4gICAgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIGVtcHR5TGluZXMrKztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIEVuZCBvZiB0aGUgc2NhbGFyLlxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgdGV4dEluZGVudCkge1xuXG4gICAgICAvLyBQZXJmb3JtIHRoZSBjaG9tcGluZy5cbiAgICAgIGlmIChjaG9tcGluZyA9PT0gQ0hPTVBJTkdfS0VFUCkge1xuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZGlkUmVhZENvbnRlbnQgPyAxICsgZW1wdHlMaW5lcyA6IGVtcHR5TGluZXMpO1xuICAgICAgfSBlbHNlIGlmIChjaG9tcGluZyA9PT0gQ0hPTVBJTkdfQ0xJUCkge1xuICAgICAgICBpZiAoZGlkUmVhZENvbnRlbnQpIHsgLy8gaS5lLiBvbmx5IGlmIHRoZSBzY2FsYXIgaXMgbm90IGVtcHR5LlxuICAgICAgICAgIHN0YXRlLnJlc3VsdCArPSAnXFxuJztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBCcmVhayB0aGlzIGB3aGlsZWAgY3ljbGUgYW5kIGdvIHRvIHRoZSBmdW5jaXRvbidzIGVwaWxvZ3VlLlxuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gRm9sZGVkIHN0eWxlOiB1c2UgZmFuY3kgcnVsZXMgdG8gaGFuZGxlIGxpbmUgYnJlYWtzLlxuICAgIGlmIChmb2xkaW5nKSB7XG5cbiAgICAgIC8vIExpbmVzIHN0YXJ0aW5nIHdpdGggd2hpdGUgc3BhY2UgY2hhcmFjdGVycyAobW9yZS1pbmRlbnRlZCBsaW5lcykgYXJlIG5vdCBmb2xkZWQuXG4gICAgICBpZiAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICAgIGF0TW9yZUluZGVudGVkID0gdHJ1ZTtcbiAgICAgICAgLy8gZXhjZXB0IGZvciB0aGUgZmlyc3QgY29udGVudCBsaW5lIChjZi4gRXhhbXBsZSA4LjEpXG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBkaWRSZWFkQ29udGVudCA/IDEgKyBlbXB0eUxpbmVzIDogZW1wdHlMaW5lcyk7XG5cbiAgICAgIC8vIEVuZCBvZiBtb3JlLWluZGVudGVkIGJsb2NrLlxuICAgICAgfSBlbHNlIGlmIChhdE1vcmVJbmRlbnRlZCkge1xuICAgICAgICBhdE1vcmVJbmRlbnRlZCA9IGZhbHNlO1xuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZW1wdHlMaW5lcyArIDEpO1xuXG4gICAgICAvLyBKdXN0IG9uZSBsaW5lIGJyZWFrIC0gcGVyY2VpdmUgYXMgdGhlIHNhbWUgbGluZS5cbiAgICAgIH0gZWxzZSBpZiAoZW1wdHlMaW5lcyA9PT0gMCkge1xuICAgICAgICBpZiAoZGlkUmVhZENvbnRlbnQpIHsgLy8gaS5lLiBvbmx5IGlmIHdlIGhhdmUgYWxyZWFkeSByZWFkIHNvbWUgc2NhbGFyIGNvbnRlbnQuXG4gICAgICAgICAgc3RhdGUucmVzdWx0ICs9ICcgJztcbiAgICAgICAgfVxuXG4gICAgICAvLyBTZXZlcmFsIGxpbmUgYnJlYWtzIC0gcGVyY2VpdmUgYXMgZGlmZmVyZW50IGxpbmVzLlxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGVtcHR5TGluZXMpO1xuICAgICAgfVxuXG4gICAgLy8gTGl0ZXJhbCBzdHlsZToganVzdCBhZGQgZXhhY3QgbnVtYmVyIG9mIGxpbmUgYnJlYWtzIGJldHdlZW4gY29udGVudCBsaW5lcy5cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gS2VlcCBhbGwgbGluZSBicmVha3MgZXhjZXB0IHRoZSBoZWFkZXIgbGluZSBicmVhay5cbiAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBkaWRSZWFkQ29udGVudCA/IDEgKyBlbXB0eUxpbmVzIDogZW1wdHlMaW5lcyk7XG4gICAgfVxuXG4gICAgZGlkUmVhZENvbnRlbnQgPSB0cnVlO1xuICAgIGRldGVjdGVkSW5kZW50ID0gdHJ1ZTtcbiAgICBlbXB0eUxpbmVzID0gMDtcbiAgICBjYXB0dXJlU3RhcnQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIHdoaWxlICghaXNfRU9MKGNoKSAmJiAoY2ggIT09IDApKSB7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIGZhbHNlKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgX2xpbmUsXG4gICAgICBfdGFnICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBfYW5jaG9yICAgPSBzdGF0ZS5hbmNob3IsXG4gICAgICBfcmVzdWx0ICAgPSBbXSxcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIGRldGVjdGVkICA9IGZhbHNlLFxuICAgICAgY2g7XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG5cbiAgICBpZiAoY2ggIT09IDB4MkQvKiAtICovKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBmb2xsb3dpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMSk7XG5cbiAgICBpZiAoIWlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgc3RhdGUucG9zaXRpb24rKztcblxuICAgIGlmIChza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSkpIHtcbiAgICAgIGlmIChzdGF0ZS5saW5lSW5kZW50IDw9IG5vZGVJbmRlbnQpIHtcbiAgICAgICAgX3Jlc3VsdC5wdXNoKG51bGwpO1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBfbGluZSA9IHN0YXRlLmxpbmU7XG4gICAgY29tcG9zZU5vZGUoc3RhdGUsIG5vZGVJbmRlbnQsIENPTlRFWFRfQkxPQ0tfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICBfcmVzdWx0LnB1c2goc3RhdGUucmVzdWx0KTtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKChzdGF0ZS5saW5lID09PSBfbGluZSB8fCBzdGF0ZS5saW5lSW5kZW50ID4gbm9kZUluZGVudCkgJiYgKGNoICE9PSAwKSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2JhZCBpbmRlbnRhdGlvbiBvZiBhIHNlcXVlbmNlIGVudHJ5Jyk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgbm9kZUluZGVudCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGRldGVjdGVkKSB7XG4gICAgc3RhdGUudGFnID0gX3RhZztcbiAgICBzdGF0ZS5hbmNob3IgPSBfYW5jaG9yO1xuICAgIHN0YXRlLmtpbmQgPSAnc2VxdWVuY2UnO1xuICAgIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiByZWFkQmxvY2tNYXBwaW5nKHN0YXRlLCBub2RlSW5kZW50LCBmbG93SW5kZW50KSB7XG4gIHZhciBmb2xsb3dpbmcsXG4gICAgICBhbGxvd0NvbXBhY3QsXG4gICAgICBfbGluZSxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBfYW5jaG9yICAgICAgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgX3Jlc3VsdCAgICAgICA9IHt9LFxuICAgICAgb3ZlcnJpZGFibGVLZXlzID0ge30sXG4gICAgICBrZXlUYWcgICAgICAgID0gbnVsbCxcbiAgICAgIGtleU5vZGUgICAgICAgPSBudWxsLFxuICAgICAgdmFsdWVOb2RlICAgICA9IG51bGwsXG4gICAgICBhdEV4cGxpY2l0S2V5ID0gZmFsc2UsXG4gICAgICBkZXRlY3RlZCAgICAgID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgc3RhdGUuYW5jaG9yTWFwW3N0YXRlLmFuY2hvcl0gPSBfcmVzdWx0O1xuICB9XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICBmb2xsb3dpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMSk7XG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lOyAvLyBTYXZlIHRoZSBjdXJyZW50IGxpbmUuXG5cbiAgICAvL1xuICAgIC8vIEV4cGxpY2l0IG5vdGF0aW9uIGNhc2UuIFRoZXJlIGFyZSB0d28gc2VwYXJhdGUgYmxvY2tzOlxuICAgIC8vIGZpcnN0IGZvciB0aGUga2V5IChkZW5vdGVkIGJ5IFwiP1wiKSBhbmQgc2Vjb25kIGZvciB0aGUgdmFsdWUgKGRlbm90ZWQgYnkgXCI6XCIpXG4gICAgLy9cbiAgICBpZiAoKGNoID09PSAweDNGLyogPyAqLyB8fCBjaCA9PT0gMHgzQS8qIDogKi8pICYmIGlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgzRi8qID8gKi8pIHtcbiAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gICAgICAgICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgICAgIGF0RXhwbGljaXRLZXkgPSB0cnVlO1xuICAgICAgICBhbGxvd0NvbXBhY3QgPSB0cnVlO1xuXG4gICAgICB9IGVsc2UgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgLy8gaS5lLiAweDNBLyogOiAqLyA9PT0gY2hhcmFjdGVyIGFmdGVyIHRoZSBleHBsaWNpdCBrZXkuXG4gICAgICAgIGF0RXhwbGljaXRLZXkgPSBmYWxzZTtcbiAgICAgICAgYWxsb3dDb21wYWN0ID0gdHJ1ZTtcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2luY29tcGxldGUgZXhwbGljaXQgbWFwcGluZyBwYWlyOyBhIGtleSBub2RlIGlzIG1pc3NlZCcpO1xuICAgICAgfVxuXG4gICAgICBzdGF0ZS5wb3NpdGlvbiArPSAxO1xuICAgICAgY2ggPSBmb2xsb3dpbmc7XG5cbiAgICAvL1xuICAgIC8vIEltcGxpY2l0IG5vdGF0aW9uIGNhc2UuIEZsb3ctc3R5bGUgbm9kZSBhcyB0aGUga2V5IGZpcnN0LCB0aGVuIFwiOlwiLCBhbmQgdGhlIHZhbHVlLlxuICAgIC8vXG4gICAgfSBlbHNlIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgZmxvd0luZGVudCwgQ09OVEVYVF9GTE9XX09VVCwgZmFsc2UsIHRydWUpKSB7XG5cbiAgICAgIGlmIChzdGF0ZS5saW5lID09PSBfbGluZSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICAgIHdoaWxlIChpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2ggPT09IDB4M0EvKiA6ICovKSB7XG4gICAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICAgICAgaWYgKCFpc19XU19PUl9FT0woY2gpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYSB3aGl0ZXNwYWNlIGNoYXJhY3RlciBpcyBleHBlY3RlZCBhZnRlciB0aGUga2V5LXZhbHVlIHNlcGFyYXRvciB3aXRoaW4gYSBibG9jayBtYXBwaW5nJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICAgIHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIF9yZXN1bHQsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCBudWxsKTtcbiAgICAgICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRldGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICBhdEV4cGxpY2l0S2V5ID0gZmFsc2U7XG4gICAgICAgICAgYWxsb3dDb21wYWN0ID0gZmFsc2U7XG4gICAgICAgICAga2V5VGFnID0gc3RhdGUudGFnO1xuICAgICAgICAgIGtleU5vZGUgPSBzdGF0ZS5yZXN1bHQ7XG5cbiAgICAgICAgfSBlbHNlIGlmIChkZXRlY3RlZCkge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW4gbm90IHJlYWQgYW4gaW1wbGljaXQgbWFwcGluZyBwYWlyOyBhIGNvbG9uIGlzIG1pc3NlZCcpO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RhdGUudGFnID0gX3RhZztcbiAgICAgICAgICBzdGF0ZS5hbmNob3IgPSBfYW5jaG9yO1xuICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIHRoZSByZXN1bHQgb2YgYGNvbXBvc2VOb2RlYC5cbiAgICAgICAgfVxuXG4gICAgICB9IGVsc2UgaWYgKGRldGVjdGVkKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW4gbm90IHJlYWQgYSBibG9jayBtYXBwaW5nIGVudHJ5OyBhIG11bHRpbGluZSBrZXkgbWF5IG5vdCBiZSBhbiBpbXBsaWNpdCBrZXknKTtcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUudGFnID0gX3RhZztcbiAgICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICAgICAgcmV0dXJuIHRydWU7IC8vIEtlZXAgdGhlIHJlc3VsdCBvZiBgY29tcG9zZU5vZGVgLlxuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrOyAvLyBSZWFkaW5nIGlzIGRvbmUuIEdvIHRvIHRoZSBlcGlsb2d1ZS5cbiAgICB9XG5cbiAgICAvL1xuICAgIC8vIENvbW1vbiByZWFkaW5nIGNvZGUgZm9yIGJvdGggZXhwbGljaXQgYW5kIGltcGxpY2l0IG5vdGF0aW9ucy5cbiAgICAvL1xuICAgIGlmIChzdGF0ZS5saW5lID09PSBfbGluZSB8fCBzdGF0ZS5saW5lSW5kZW50ID4gbm9kZUluZGVudCkge1xuICAgICAgaWYgKGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0JMT0NLX09VVCwgdHJ1ZSwgYWxsb3dDb21wYWN0KSkge1xuICAgICAgICBpZiAoYXRFeHBsaWNpdEtleSkge1xuICAgICAgICAgIGtleU5vZGUgPSBzdGF0ZS5yZXN1bHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWVOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghYXRFeHBsaWNpdEtleSkge1xuICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKTtcbiAgICAgICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPiBub2RlSW5kZW50ICYmIChjaCAhPT0gMCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgaW5kZW50YXRpb24gb2YgYSBtYXBwaW5nIGVudHJ5Jyk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgbm9kZUluZGVudCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLy9cbiAgLy8gRXBpbG9ndWUuXG4gIC8vXG5cbiAgLy8gU3BlY2lhbCBjYXNlOiBsYXN0IG1hcHBpbmcncyBub2RlIGNvbnRhaW5zIG9ubHkgdGhlIGtleSBpbiBleHBsaWNpdCBub3RhdGlvbi5cbiAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gIH1cblxuICAvLyBFeHBvc2UgdGhlIHJlc3VsdGluZyBtYXBwaW5nLlxuICBpZiAoZGV0ZWN0ZWQpIHtcbiAgICBzdGF0ZS50YWcgPSBfdGFnO1xuICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgc3RhdGUua2luZCA9ICdtYXBwaW5nJztcbiAgICBzdGF0ZS5yZXN1bHQgPSBfcmVzdWx0O1xuICB9XG5cbiAgcmV0dXJuIGRldGVjdGVkO1xufVxuXG5mdW5jdGlvbiByZWFkVGFnUHJvcGVydHkoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbixcbiAgICAgIGlzVmVyYmF0aW0gPSBmYWxzZSxcbiAgICAgIGlzTmFtZWQgICAgPSBmYWxzZSxcbiAgICAgIHRhZ0hhbmRsZSxcbiAgICAgIHRhZ05hbWUsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyMS8qICEgKi8pIHJldHVybiBmYWxzZTtcblxuICBpZiAoc3RhdGUudGFnICE9PSBudWxsKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2R1cGxpY2F0aW9uIG9mIGEgdGFnIHByb3BlcnR5Jyk7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoID09PSAweDNDLyogPCAqLykge1xuICAgIGlzVmVyYmF0aW0gPSB0cnVlO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICB9IGVsc2UgaWYgKGNoID09PSAweDIxLyogISAqLykge1xuICAgIGlzTmFtZWQgPSB0cnVlO1xuICAgIHRhZ0hhbmRsZSA9ICchISc7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gIH0gZWxzZSB7XG4gICAgdGFnSGFuZGxlID0gJyEnO1xuICB9XG5cbiAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgaWYgKGlzVmVyYmF0aW0pIHtcbiAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgIHdoaWxlIChjaCAhPT0gMCAmJiBjaCAhPT0gMHgzRS8qID4gKi8pO1xuXG4gICAgaWYgKHN0YXRlLnBvc2l0aW9uIDwgc3RhdGUubGVuZ3RoKSB7XG4gICAgICB0YWdOYW1lID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIHZlcmJhdGltIHRhZycpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgIWlzX1dTX09SX0VPTChjaCkpIHtcblxuICAgICAgaWYgKGNoID09PSAweDIxLyogISAqLykge1xuICAgICAgICBpZiAoIWlzTmFtZWQpIHtcbiAgICAgICAgICB0YWdIYW5kbGUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24gLSAxLCBzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgICAgICAgaWYgKCFQQVRURVJOX1RBR19IQU5ETEUudGVzdCh0YWdIYW5kbGUpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZWQgdGFnIGhhbmRsZSBjYW5ub3QgY29udGFpbiBzdWNoIGNoYXJhY3RlcnMnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpc05hbWVkID0gdHJ1ZTtcbiAgICAgICAgICBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbiArIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RhZyBzdWZmaXggY2Fubm90IGNvbnRhaW4gZXhjbGFtYXRpb24gbWFya3MnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgdGFnTmFtZSA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKFBBVFRFUk5fRkxPV19JTkRJQ0FUT1JTLnRlc3QodGFnTmFtZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0YWcgc3VmZml4IGNhbm5vdCBjb250YWluIGZsb3cgaW5kaWNhdG9yIGNoYXJhY3RlcnMnKTtcbiAgICB9XG4gIH1cblxuICBpZiAodGFnTmFtZSAmJiAhUEFUVEVSTl9UQUdfVVJJLnRlc3QodGFnTmFtZSkpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGFnIG5hbWUgY2Fubm90IGNvbnRhaW4gc3VjaCBjaGFyYWN0ZXJzOiAnICsgdGFnTmFtZSk7XG4gIH1cblxuICBpZiAoaXNWZXJiYXRpbSkge1xuICAgIHN0YXRlLnRhZyA9IHRhZ05hbWU7XG5cbiAgfSBlbHNlIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChzdGF0ZS50YWdNYXAsIHRhZ0hhbmRsZSkpIHtcbiAgICBzdGF0ZS50YWcgPSBzdGF0ZS50YWdNYXBbdGFnSGFuZGxlXSArIHRhZ05hbWU7XG5cbiAgfSBlbHNlIGlmICh0YWdIYW5kbGUgPT09ICchJykge1xuICAgIHN0YXRlLnRhZyA9ICchJyArIHRhZ05hbWU7XG5cbiAgfSBlbHNlIGlmICh0YWdIYW5kbGUgPT09ICchIScpIHtcbiAgICBzdGF0ZS50YWcgPSAndGFnOnlhbWwub3JnLDIwMDI6JyArIHRhZ05hbWU7XG5cbiAgfSBlbHNlIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5kZWNsYXJlZCB0YWcgaGFuZGxlIFwiJyArIHRhZ0hhbmRsZSArICdcIicpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJlYWRBbmNob3JQcm9wZXJ0eShzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjYvKiAmICovKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGlvbiBvZiBhbiBhbmNob3IgcHJvcGVydHknKTtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpICYmICFpc19GTE9XX0lORElDQVRPUihjaCkpIHtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIH1cblxuICBpZiAoc3RhdGUucG9zaXRpb24gPT09IF9wb3NpdGlvbikge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICduYW1lIG9mIGFuIGFuY2hvciBub2RlIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyJyk7XG4gIH1cblxuICBzdGF0ZS5hbmNob3IgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJlYWRBbGlhcyhzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uLCBhbGlhcyxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoICE9PSAweDJBLyogKiAqLykgcmV0dXJuIGZhbHNlO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpICYmICFpc19GTE9XX0lORElDQVRPUihjaCkpIHtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIH1cblxuICBpZiAoc3RhdGUucG9zaXRpb24gPT09IF9wb3NpdGlvbikge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICduYW1lIG9mIGFuIGFsaWFzIG5vZGUgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBjaGFyYWN0ZXInKTtcbiAgfVxuXG4gIGFsaWFzID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKCFzdGF0ZS5hbmNob3JNYXAuaGFzT3duUHJvcGVydHkoYWxpYXMpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuaWRlbnRpZmllZCBhbGlhcyBcIicgKyBhbGlhcyArICdcIicpO1xuICB9XG5cbiAgc3RhdGUucmVzdWx0ID0gc3RhdGUuYW5jaG9yTWFwW2FsaWFzXTtcbiAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29tcG9zZU5vZGUoc3RhdGUsIHBhcmVudEluZGVudCwgbm9kZUNvbnRleHQsIGFsbG93VG9TZWVrLCBhbGxvd0NvbXBhY3QpIHtcbiAgdmFyIGFsbG93QmxvY2tTdHlsZXMsXG4gICAgICBhbGxvd0Jsb2NrU2NhbGFycyxcbiAgICAgIGFsbG93QmxvY2tDb2xsZWN0aW9ucyxcbiAgICAgIGluZGVudFN0YXR1cyA9IDEsIC8vIDE6IHRoaXM+cGFyZW50LCAwOiB0aGlzPXBhcmVudCwgLTE6IHRoaXM8cGFyZW50XG4gICAgICBhdE5ld0xpbmUgID0gZmFsc2UsXG4gICAgICBoYXNDb250ZW50ID0gZmFsc2UsXG4gICAgICB0eXBlSW5kZXgsXG4gICAgICB0eXBlUXVhbnRpdHksXG4gICAgICB0eXBlLFxuICAgICAgZmxvd0luZGVudCxcbiAgICAgIGJsb2NrSW5kZW50O1xuXG4gIGlmIChzdGF0ZS5saXN0ZW5lciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmxpc3RlbmVyKCdvcGVuJywgc3RhdGUpO1xuICB9XG5cbiAgc3RhdGUudGFnICAgID0gbnVsbDtcbiAgc3RhdGUuYW5jaG9yID0gbnVsbDtcbiAgc3RhdGUua2luZCAgID0gbnVsbDtcbiAgc3RhdGUucmVzdWx0ID0gbnVsbDtcblxuICBhbGxvd0Jsb2NrU3R5bGVzID0gYWxsb3dCbG9ja1NjYWxhcnMgPSBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPVxuICAgIENPTlRFWFRfQkxPQ0tfT1VUID09PSBub2RlQ29udGV4dCB8fFxuICAgIENPTlRFWFRfQkxPQ0tfSU4gID09PSBub2RlQ29udGV4dDtcblxuICBpZiAoYWxsb3dUb1NlZWspIHtcbiAgICBpZiAoc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpKSB7XG4gICAgICBhdE5ld0xpbmUgPSB0cnVlO1xuXG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IHBhcmVudEluZGVudCkge1xuICAgICAgICBpbmRlbnRTdGF0dXMgPSAxO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50ID09PSBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gMDtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IHBhcmVudEluZGVudCkge1xuICAgICAgICBpbmRlbnRTdGF0dXMgPSAtMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoaW5kZW50U3RhdHVzID09PSAxKSB7XG4gICAgd2hpbGUgKHJlYWRUYWdQcm9wZXJ0eShzdGF0ZSkgfHwgcmVhZEFuY2hvclByb3BlcnR5KHN0YXRlKSkge1xuICAgICAgaWYgKHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKSkge1xuICAgICAgICBhdE5ld0xpbmUgPSB0cnVlO1xuICAgICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPSBhbGxvd0Jsb2NrU3R5bGVzO1xuXG4gICAgICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gMTtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50ID09PSBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgICBpbmRlbnRTdGF0dXMgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgICBpbmRlbnRTdGF0dXMgPSAtMTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWxsb3dCbG9ja0NvbGxlY3Rpb25zID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGFsbG93QmxvY2tDb2xsZWN0aW9ucykge1xuICAgIGFsbG93QmxvY2tDb2xsZWN0aW9ucyA9IGF0TmV3TGluZSB8fCBhbGxvd0NvbXBhY3Q7XG4gIH1cblxuICBpZiAoaW5kZW50U3RhdHVzID09PSAxIHx8IENPTlRFWFRfQkxPQ0tfT1VUID09PSBub2RlQ29udGV4dCkge1xuICAgIGlmIChDT05URVhUX0ZMT1dfSU4gPT09IG5vZGVDb250ZXh0IHx8IENPTlRFWFRfRkxPV19PVVQgPT09IG5vZGVDb250ZXh0KSB7XG4gICAgICBmbG93SW5kZW50ID0gcGFyZW50SW5kZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICBmbG93SW5kZW50ID0gcGFyZW50SW5kZW50ICsgMTtcbiAgICB9XG5cbiAgICBibG9ja0luZGVudCA9IHN0YXRlLnBvc2l0aW9uIC0gc3RhdGUubGluZVN0YXJ0O1xuXG4gICAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSkge1xuICAgICAgaWYgKGFsbG93QmxvY2tDb2xsZWN0aW9ucyAmJlxuICAgICAgICAgIChyZWFkQmxvY2tTZXF1ZW5jZShzdGF0ZSwgYmxvY2tJbmRlbnQpIHx8XG4gICAgICAgICAgIHJlYWRCbG9ja01hcHBpbmcoc3RhdGUsIGJsb2NrSW5kZW50LCBmbG93SW5kZW50KSkgfHxcbiAgICAgICAgICByZWFkRmxvd0NvbGxlY3Rpb24oc3RhdGUsIGZsb3dJbmRlbnQpKSB7XG4gICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKChhbGxvd0Jsb2NrU2NhbGFycyAmJiByZWFkQmxvY2tTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpKSB8fFxuICAgICAgICAgICAgcmVhZFNpbmdsZVF1b3RlZFNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCkgfHxcbiAgICAgICAgICAgIHJlYWREb3VibGVRdW90ZWRTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpKSB7XG4gICAgICAgICAgaGFzQ29udGVudCA9IHRydWU7XG5cbiAgICAgICAgfSBlbHNlIGlmIChyZWFkQWxpYXMoc3RhdGUpKSB7XG4gICAgICAgICAgaGFzQ29udGVudCA9IHRydWU7XG5cbiAgICAgICAgICBpZiAoc3RhdGUudGFnICE9PSBudWxsIHx8IHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2FsaWFzIG5vZGUgc2hvdWxkIG5vdCBoYXZlIGFueSBwcm9wZXJ0aWVzJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgIH0gZWxzZSBpZiAocmVhZFBsYWluU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50LCBDT05URVhUX0ZMT1dfSU4gPT09IG5vZGVDb250ZXh0KSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgICAgaWYgKHN0YXRlLnRhZyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgc3RhdGUudGFnID0gJz8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaW5kZW50U3RhdHVzID09PSAwKSB7XG4gICAgICAvLyBTcGVjaWFsIGNhc2U6IGJsb2NrIHNlcXVlbmNlcyBhcmUgYWxsb3dlZCB0byBoYXZlIHNhbWUgaW5kZW50YXRpb24gbGV2ZWwgYXMgdGhlIHBhcmVudC5cbiAgICAgIC8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjc5OTc4NFxuICAgICAgaGFzQ29udGVudCA9IGFsbG93QmxvY2tDb2xsZWN0aW9ucyAmJiByZWFkQmxvY2tTZXF1ZW5jZShzdGF0ZSwgYmxvY2tJbmRlbnQpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdGF0ZS50YWcgIT09IG51bGwgJiYgc3RhdGUudGFnICE9PSAnIScpIHtcbiAgICBpZiAoc3RhdGUudGFnID09PSAnPycpIHtcbiAgICAgIGZvciAodHlwZUluZGV4ID0gMCwgdHlwZVF1YW50aXR5ID0gc3RhdGUuaW1wbGljaXRUeXBlcy5sZW5ndGg7XG4gICAgICAgICAgIHR5cGVJbmRleCA8IHR5cGVRdWFudGl0eTtcbiAgICAgICAgICAgdHlwZUluZGV4ICs9IDEpIHtcbiAgICAgICAgdHlwZSA9IHN0YXRlLmltcGxpY2l0VHlwZXNbdHlwZUluZGV4XTtcblxuICAgICAgICAvLyBJbXBsaWNpdCByZXNvbHZpbmcgaXMgbm90IGFsbG93ZWQgZm9yIG5vbi1zY2FsYXIgdHlwZXMsIGFuZCAnPydcbiAgICAgICAgLy8gbm9uLXNwZWNpZmljIHRhZyBpcyBvbmx5IGFzc2lnbmVkIHRvIHBsYWluIHNjYWxhcnMuIFNvLCBpdCBpc24ndFxuICAgICAgICAvLyBuZWVkZWQgdG8gY2hlY2sgZm9yICdraW5kJyBjb25mb3JtaXR5LlxuXG4gICAgICAgIGlmICh0eXBlLnJlc29sdmUoc3RhdGUucmVzdWx0KSkgeyAvLyBgc3RhdGUucmVzdWx0YCB1cGRhdGVkIGluIHJlc29sdmVyIGlmIG1hdGNoZWRcbiAgICAgICAgICBzdGF0ZS5yZXN1bHQgPSB0eXBlLmNvbnN0cnVjdChzdGF0ZS5yZXN1bHQpO1xuICAgICAgICAgIHN0YXRlLnRhZyA9IHR5cGUudGFnO1xuICAgICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gc3RhdGUucmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudHlwZU1hcCwgc3RhdGUudGFnKSkge1xuICAgICAgdHlwZSA9IHN0YXRlLnR5cGVNYXBbc3RhdGUudGFnXTtcblxuICAgICAgaWYgKHN0YXRlLnJlc3VsdCAhPT0gbnVsbCAmJiB0eXBlLmtpbmQgIT09IHN0YXRlLmtpbmQpIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuYWNjZXB0YWJsZSBub2RlIGtpbmQgZm9yICE8JyArIHN0YXRlLnRhZyArICc+IHRhZzsgaXQgc2hvdWxkIGJlIFwiJyArIHR5cGUua2luZCArICdcIiwgbm90IFwiJyArIHN0YXRlLmtpbmQgKyAnXCInKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0eXBlLnJlc29sdmUoc3RhdGUucmVzdWx0KSkgeyAvLyBgc3RhdGUucmVzdWx0YCB1cGRhdGVkIGluIHJlc29sdmVyIGlmIG1hdGNoZWRcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Nhbm5vdCByZXNvbHZlIGEgbm9kZSB3aXRoICE8JyArIHN0YXRlLnRhZyArICc+IGV4cGxpY2l0IHRhZycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ID0gdHlwZS5jb25zdHJ1Y3Qoc3RhdGUucmVzdWx0KTtcbiAgICAgICAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgICAgICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmtub3duIHRhZyAhPCcgKyBzdGF0ZS50YWcgKyAnPicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzdGF0ZS5saXN0ZW5lciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmxpc3RlbmVyKCdjbG9zZScsIHN0YXRlKTtcbiAgfVxuICByZXR1cm4gc3RhdGUudGFnICE9PSBudWxsIHx8ICBzdGF0ZS5hbmNob3IgIT09IG51bGwgfHwgaGFzQ29udGVudDtcbn1cblxuZnVuY3Rpb24gcmVhZERvY3VtZW50KHN0YXRlKSB7XG4gIHZhciBkb2N1bWVudFN0YXJ0ID0gc3RhdGUucG9zaXRpb24sXG4gICAgICBfcG9zaXRpb24sXG4gICAgICBkaXJlY3RpdmVOYW1lLFxuICAgICAgZGlyZWN0aXZlQXJncyxcbiAgICAgIGhhc0RpcmVjdGl2ZXMgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIHN0YXRlLnZlcnNpb24gPSBudWxsO1xuICBzdGF0ZS5jaGVja0xpbmVCcmVha3MgPSBzdGF0ZS5sZWdhY3k7XG4gIHN0YXRlLnRhZ01hcCA9IHt9O1xuICBzdGF0ZS5hbmNob3JNYXAgPSB7fTtcblxuICB3aGlsZSAoKGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikpICE9PSAwKSB7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gMCB8fCBjaCAhPT0gMHgyNS8qICUgKi8pIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGhhc0RpcmVjdGl2ZXMgPSB0cnVlO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGRpcmVjdGl2ZU5hbWUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcbiAgICBkaXJlY3RpdmVBcmdzID0gW107XG5cbiAgICBpZiAoZGlyZWN0aXZlTmFtZS5sZW5ndGggPCAxKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZGlyZWN0aXZlIG5hbWUgbXVzdCBub3QgYmUgbGVzcyB0aGFuIG9uZSBjaGFyYWN0ZXIgaW4gbGVuZ3RoJyk7XG4gICAgfVxuXG4gICAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgICAgICB3aGlsZSAoY2ggIT09IDAgJiYgIWlzX0VPTChjaCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKGlzX0VPTChjaCkpIGJyZWFrO1xuXG4gICAgICBfcG9zaXRpb24gPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpKSB7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH1cblxuICAgICAgZGlyZWN0aXZlQXJncy5wdXNoKHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pKTtcbiAgICB9XG5cbiAgICBpZiAoY2ggIT09IDApIHJlYWRMaW5lQnJlYWsoc3RhdGUpO1xuXG4gICAgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKGRpcmVjdGl2ZUhhbmRsZXJzLCBkaXJlY3RpdmVOYW1lKSkge1xuICAgICAgZGlyZWN0aXZlSGFuZGxlcnNbZGlyZWN0aXZlTmFtZV0oc3RhdGUsIGRpcmVjdGl2ZU5hbWUsIGRpcmVjdGl2ZUFyZ3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICd1bmtub3duIGRvY3VtZW50IGRpcmVjdGl2ZSBcIicgKyBkaXJlY3RpdmVOYW1lICsgJ1wiJyk7XG4gICAgfVxuICB9XG5cbiAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gIGlmIChzdGF0ZS5saW5lSW5kZW50ID09PSAwICYmXG4gICAgICBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSAgICAgPT09IDB4MkQvKiAtICovICYmXG4gICAgICBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMSkgPT09IDB4MkQvKiAtICovICYmXG4gICAgICBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uICsgMikgPT09IDB4MkQvKiAtICovKSB7XG4gICAgc3RhdGUucG9zaXRpb24gKz0gMztcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG5cbiAgfSBlbHNlIGlmIChoYXNEaXJlY3RpdmVzKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2RpcmVjdGl2ZXMgZW5kIG1hcmsgaXMgZXhwZWN0ZWQnKTtcbiAgfVxuXG4gIGNvbXBvc2VOb2RlKHN0YXRlLCBzdGF0ZS5saW5lSW5kZW50IC0gMSwgQ09OVEVYVF9CTE9DS19PVVQsIGZhbHNlLCB0cnVlKTtcbiAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gIGlmIChzdGF0ZS5jaGVja0xpbmVCcmVha3MgJiZcbiAgICAgIFBBVFRFUk5fTk9OX0FTQ0lJX0xJTkVfQlJFQUtTLnRlc3Qoc3RhdGUuaW5wdXQuc2xpY2UoZG9jdW1lbnRTdGFydCwgc3RhdGUucG9zaXRpb24pKSkge1xuICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ25vbi1BU0NJSSBsaW5lIGJyZWFrcyBhcmUgaW50ZXJwcmV0ZWQgYXMgY29udGVudCcpO1xuICB9XG5cbiAgc3RhdGUuZG9jdW1lbnRzLnB1c2goc3RhdGUucmVzdWx0KTtcblxuICBpZiAoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB7XG5cbiAgICBpZiAoc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikgPT09IDB4MkUvKiAuICovKSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbiArPSAzO1xuICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoc3RhdGUucG9zaXRpb24gPCAoc3RhdGUubGVuZ3RoIC0gMSkpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZW5kIG9mIHRoZSBzdHJlYW0gb3IgYSBkb2N1bWVudCBzZXBhcmF0b3IgaXMgZXhwZWN0ZWQnKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm47XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBsb2FkRG9jdW1lbnRzKGlucHV0LCBvcHRpb25zKSB7XG4gIGlucHV0ID0gU3RyaW5nKGlucHV0KTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgaWYgKGlucHV0Lmxlbmd0aCAhPT0gMCkge1xuXG4gICAgLy8gQWRkIHRhaWxpbmcgYFxcbmAgaWYgbm90IGV4aXN0c1xuICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KGlucHV0Lmxlbmd0aCAtIDEpICE9PSAweDBBLyogTEYgKi8gJiZcbiAgICAgICAgaW5wdXQuY2hhckNvZGVBdChpbnB1dC5sZW5ndGggLSAxKSAhPT0gMHgwRC8qIENSICovKSB7XG4gICAgICBpbnB1dCArPSAnXFxuJztcbiAgICB9XG5cbiAgICAvLyBTdHJpcCBCT01cbiAgICBpZiAoaW5wdXQuY2hhckNvZGVBdCgwKSA9PT0gMHhGRUZGKSB7XG4gICAgICBpbnB1dCA9IGlucHV0LnNsaWNlKDEpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBzdGF0ZSA9IG5ldyBTdGF0ZShpbnB1dCwgb3B0aW9ucyk7XG5cbiAgLy8gVXNlIDAgYXMgc3RyaW5nIHRlcm1pbmF0b3IuIFRoYXQgc2lnbmlmaWNhbnRseSBzaW1wbGlmaWVzIGJvdW5kcyBjaGVjay5cbiAgc3RhdGUuaW5wdXQgKz0gJ1xcMCc7XG5cbiAgd2hpbGUgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDIwLyogU3BhY2UgKi8pIHtcbiAgICBzdGF0ZS5saW5lSW5kZW50ICs9IDE7XG4gICAgc3RhdGUucG9zaXRpb24gKz0gMTtcbiAgfVxuXG4gIHdoaWxlIChzdGF0ZS5wb3NpdGlvbiA8IChzdGF0ZS5sZW5ndGggLSAxKSkge1xuICAgIHJlYWREb2N1bWVudChzdGF0ZSk7XG4gIH1cblxuICByZXR1cm4gc3RhdGUuZG9jdW1lbnRzO1xufVxuXG5cbmZ1bmN0aW9uIGxvYWRBbGwoaW5wdXQsIGl0ZXJhdG9yLCBvcHRpb25zKSB7XG4gIHZhciBkb2N1bWVudHMgPSBsb2FkRG9jdW1lbnRzKGlucHV0LCBvcHRpb25zKSwgaW5kZXgsIGxlbmd0aDtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gZG9jdW1lbnRzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBpdGVyYXRvcihkb2N1bWVudHNbaW5kZXhdKTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIGxvYWQoaW5wdXQsIG9wdGlvbnMpIHtcbiAgdmFyIGRvY3VtZW50cyA9IGxvYWREb2N1bWVudHMoaW5wdXQsIG9wdGlvbnMpO1xuXG4gIGlmIChkb2N1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgLyplc2xpbnQtZGlzYWJsZSBuby11bmRlZmluZWQqL1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH0gZWxzZSBpZiAoZG9jdW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBkb2N1bWVudHNbMF07XG4gIH1cbiAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ2V4cGVjdGVkIGEgc2luZ2xlIGRvY3VtZW50IGluIHRoZSBzdHJlYW0sIGJ1dCBmb3VuZCBtb3JlJyk7XG59XG5cblxuZnVuY3Rpb24gc2FmZUxvYWRBbGwoaW5wdXQsIG91dHB1dCwgb3B0aW9ucykge1xuICBsb2FkQWxsKGlucHV0LCBvdXRwdXQsIGNvbW1vbi5leHRlbmQoeyBzY2hlbWE6IERFRkFVTFRfU0FGRV9TQ0hFTUEgfSwgb3B0aW9ucykpO1xufVxuXG5cbmZ1bmN0aW9uIHNhZmVMb2FkKGlucHV0LCBvcHRpb25zKSB7XG4gIHJldHVybiBsb2FkKGlucHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5sb2FkQWxsICAgICA9IGxvYWRBbGw7XG5tb2R1bGUuZXhwb3J0cy5sb2FkICAgICAgICA9IGxvYWQ7XG5tb2R1bGUuZXhwb3J0cy5zYWZlTG9hZEFsbCA9IHNhZmVMb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMuc2FmZUxvYWQgICAgPSBzYWZlTG9hZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxuXG5mdW5jdGlvbiBNYXJrKG5hbWUsIGJ1ZmZlciwgcG9zaXRpb24sIGxpbmUsIGNvbHVtbikge1xuICB0aGlzLm5hbWUgICAgID0gbmFtZTtcbiAgdGhpcy5idWZmZXIgICA9IGJ1ZmZlcjtcbiAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xuICB0aGlzLmxpbmUgICAgID0gbGluZTtcbiAgdGhpcy5jb2x1bW4gICA9IGNvbHVtbjtcbn1cblxuXG5NYXJrLnByb3RvdHlwZS5nZXRTbmlwcGV0ID0gZnVuY3Rpb24gZ2V0U25pcHBldChpbmRlbnQsIG1heExlbmd0aCkge1xuICB2YXIgaGVhZCwgc3RhcnQsIHRhaWwsIGVuZCwgc25pcHBldDtcblxuICBpZiAoIXRoaXMuYnVmZmVyKSByZXR1cm4gbnVsbDtcblxuICBpbmRlbnQgPSBpbmRlbnQgfHwgNDtcbiAgbWF4TGVuZ3RoID0gbWF4TGVuZ3RoIHx8IDc1O1xuXG4gIGhlYWQgPSAnJztcbiAgc3RhcnQgPSB0aGlzLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChzdGFydCA+IDAgJiYgJ1xceDAwXFxyXFxuXFx4ODVcXHUyMDI4XFx1MjAyOScuaW5kZXhPZih0aGlzLmJ1ZmZlci5jaGFyQXQoc3RhcnQgLSAxKSkgPT09IC0xKSB7XG4gICAgc3RhcnQgLT0gMTtcbiAgICBpZiAodGhpcy5wb3NpdGlvbiAtIHN0YXJ0ID4gKG1heExlbmd0aCAvIDIgLSAxKSkge1xuICAgICAgaGVhZCA9ICcgLi4uICc7XG4gICAgICBzdGFydCArPSA1O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgdGFpbCA9ICcnO1xuICBlbmQgPSB0aGlzLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChlbmQgPCB0aGlzLmJ1ZmZlci5sZW5ndGggJiYgJ1xceDAwXFxyXFxuXFx4ODVcXHUyMDI4XFx1MjAyOScuaW5kZXhPZih0aGlzLmJ1ZmZlci5jaGFyQXQoZW5kKSkgPT09IC0xKSB7XG4gICAgZW5kICs9IDE7XG4gICAgaWYgKGVuZCAtIHRoaXMucG9zaXRpb24gPiAobWF4TGVuZ3RoIC8gMiAtIDEpKSB7XG4gICAgICB0YWlsID0gJyAuLi4gJztcbiAgICAgIGVuZCAtPSA1O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgc25pcHBldCA9IHRoaXMuYnVmZmVyLnNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gIHJldHVybiBjb21tb24ucmVwZWF0KCcgJywgaW5kZW50KSArIGhlYWQgKyBzbmlwcGV0ICsgdGFpbCArICdcXG4nICtcbiAgICAgICAgIGNvbW1vbi5yZXBlYXQoJyAnLCBpbmRlbnQgKyB0aGlzLnBvc2l0aW9uIC0gc3RhcnQgKyBoZWFkLmxlbmd0aCkgKyAnXic7XG59O1xuXG5cbk1hcmsucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoY29tcGFjdCkge1xuICB2YXIgc25pcHBldCwgd2hlcmUgPSAnJztcblxuICBpZiAodGhpcy5uYW1lKSB7XG4gICAgd2hlcmUgKz0gJ2luIFwiJyArIHRoaXMubmFtZSArICdcIiAnO1xuICB9XG5cbiAgd2hlcmUgKz0gJ2F0IGxpbmUgJyArICh0aGlzLmxpbmUgKyAxKSArICcsIGNvbHVtbiAnICsgKHRoaXMuY29sdW1uICsgMSk7XG5cbiAgaWYgKCFjb21wYWN0KSB7XG4gICAgc25pcHBldCA9IHRoaXMuZ2V0U25pcHBldCgpO1xuXG4gICAgaWYgKHNuaXBwZXQpIHtcbiAgICAgIHdoZXJlICs9ICc6XFxuJyArIHNuaXBwZXQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdoZXJlO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcms7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qZXNsaW50LWRpc2FibGUgbWF4LWxlbiovXG5cbnZhciBjb21tb24gICAgICAgID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBZQU1MRXhjZXB0aW9uID0gcmVxdWlyZSgnLi9leGNlcHRpb24nKTtcbnZhciBUeXBlICAgICAgICAgID0gcmVxdWlyZSgnLi90eXBlJyk7XG5cblxuZnVuY3Rpb24gY29tcGlsZUxpc3Qoc2NoZW1hLCBuYW1lLCByZXN1bHQpIHtcbiAgdmFyIGV4Y2x1ZGUgPSBbXTtcblxuICBzY2hlbWEuaW5jbHVkZS5mb3JFYWNoKGZ1bmN0aW9uIChpbmNsdWRlZFNjaGVtYSkge1xuICAgIHJlc3VsdCA9IGNvbXBpbGVMaXN0KGluY2x1ZGVkU2NoZW1hLCBuYW1lLCByZXN1bHQpO1xuICB9KTtcblxuICBzY2hlbWFbbmFtZV0uZm9yRWFjaChmdW5jdGlvbiAoY3VycmVudFR5cGUpIHtcbiAgICByZXN1bHQuZm9yRWFjaChmdW5jdGlvbiAocHJldmlvdXNUeXBlLCBwcmV2aW91c0luZGV4KSB7XG4gICAgICBpZiAocHJldmlvdXNUeXBlLnRhZyA9PT0gY3VycmVudFR5cGUudGFnKSB7XG4gICAgICAgIGV4Y2x1ZGUucHVzaChwcmV2aW91c0luZGV4KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJlc3VsdC5wdXNoKGN1cnJlbnRUeXBlKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdC5maWx0ZXIoZnVuY3Rpb24gKHR5cGUsIGluZGV4KSB7XG4gICAgcmV0dXJuIGV4Y2x1ZGUuaW5kZXhPZihpbmRleCkgPT09IC0xO1xuICB9KTtcbn1cblxuXG5mdW5jdGlvbiBjb21waWxlTWFwKC8qIGxpc3RzLi4uICovKSB7XG4gIHZhciByZXN1bHQgPSB7fSwgaW5kZXgsIGxlbmd0aDtcblxuICBmdW5jdGlvbiBjb2xsZWN0VHlwZSh0eXBlKSB7XG4gICAgcmVzdWx0W3R5cGUudGFnXSA9IHR5cGU7XG4gIH1cblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBhcmd1bWVudHNbaW5kZXhdLmZvckVhY2goY29sbGVjdFR5cGUpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG5mdW5jdGlvbiBTY2hlbWEoZGVmaW5pdGlvbikge1xuICB0aGlzLmluY2x1ZGUgID0gZGVmaW5pdGlvbi5pbmNsdWRlICB8fCBbXTtcbiAgdGhpcy5pbXBsaWNpdCA9IGRlZmluaXRpb24uaW1wbGljaXQgfHwgW107XG4gIHRoaXMuZXhwbGljaXQgPSBkZWZpbml0aW9uLmV4cGxpY2l0IHx8IFtdO1xuXG4gIHRoaXMuaW1wbGljaXQuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgIGlmICh0eXBlLmxvYWRLaW5kICYmIHR5cGUubG9hZEtpbmQgIT09ICdzY2FsYXInKSB7XG4gICAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignVGhlcmUgaXMgYSBub24tc2NhbGFyIHR5cGUgaW4gdGhlIGltcGxpY2l0IGxpc3Qgb2YgYSBzY2hlbWEuIEltcGxpY2l0IHJlc29sdmluZyBvZiBzdWNoIHR5cGVzIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgfVxuICB9KTtcblxuICB0aGlzLmNvbXBpbGVkSW1wbGljaXQgPSBjb21waWxlTGlzdCh0aGlzLCAnaW1wbGljaXQnLCBbXSk7XG4gIHRoaXMuY29tcGlsZWRFeHBsaWNpdCA9IGNvbXBpbGVMaXN0KHRoaXMsICdleHBsaWNpdCcsIFtdKTtcbiAgdGhpcy5jb21waWxlZFR5cGVNYXAgID0gY29tcGlsZU1hcCh0aGlzLmNvbXBpbGVkSW1wbGljaXQsIHRoaXMuY29tcGlsZWRFeHBsaWNpdCk7XG59XG5cblxuU2NoZW1hLkRFRkFVTFQgPSBudWxsO1xuXG5cblNjaGVtYS5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGVTY2hlbWEoKSB7XG4gIHZhciBzY2hlbWFzLCB0eXBlcztcblxuICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICBjYXNlIDE6XG4gICAgICBzY2hlbWFzID0gU2NoZW1hLkRFRkFVTFQ7XG4gICAgICB0eXBlcyA9IGFyZ3VtZW50c1swXTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAyOlxuICAgICAgc2NoZW1hcyA9IGFyZ3VtZW50c1swXTtcbiAgICAgIHR5cGVzID0gYXJndW1lbnRzWzFdO1xuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1dyb25nIG51bWJlciBvZiBhcmd1bWVudHMgZm9yIFNjaGVtYS5jcmVhdGUgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIHNjaGVtYXMgPSBjb21tb24udG9BcnJheShzY2hlbWFzKTtcbiAgdHlwZXMgPSBjb21tb24udG9BcnJheSh0eXBlcyk7XG5cbiAgaWYgKCFzY2hlbWFzLmV2ZXJ5KGZ1bmN0aW9uIChzY2hlbWEpIHsgcmV0dXJuIHNjaGVtYSBpbnN0YW5jZW9mIFNjaGVtYTsgfSkpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignU3BlY2lmaWVkIGxpc3Qgb2Ygc3VwZXIgc2NoZW1hcyAob3IgYSBzaW5nbGUgU2NoZW1hIG9iamVjdCkgY29udGFpbnMgYSBub24tU2NoZW1hIG9iamVjdC4nKTtcbiAgfVxuXG4gIGlmICghdHlwZXMuZXZlcnkoZnVuY3Rpb24gKHR5cGUpIHsgcmV0dXJuIHR5cGUgaW5zdGFuY2VvZiBUeXBlOyB9KSkge1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdTcGVjaWZpZWQgbGlzdCBvZiBZQU1MIHR5cGVzIChvciBhIHNpbmdsZSBUeXBlIG9iamVjdCkgY29udGFpbnMgYSBub24tVHlwZSBvYmplY3QuJyk7XG4gIH1cblxuICByZXR1cm4gbmV3IFNjaGVtYSh7XG4gICAgaW5jbHVkZTogc2NoZW1hcyxcbiAgICBleHBsaWNpdDogdHlwZXNcbiAgfSk7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gU2NoZW1hO1xuIiwiLy8gU3RhbmRhcmQgWUFNTCdzIENvcmUgc2NoZW1hLlxuLy8gaHR0cDovL3d3dy55YW1sLm9yZy9zcGVjLzEuMi9zcGVjLmh0bWwjaWQyODA0OTIzXG4vL1xuLy8gTk9URTogSlMtWUFNTCBkb2VzIG5vdCBzdXBwb3J0IHNjaGVtYS1zcGVjaWZpYyB0YWcgcmVzb2x1dGlvbiByZXN0cmljdGlvbnMuXG4vLyBTbywgQ29yZSBzY2hlbWEgaGFzIG5vIGRpc3RpbmN0aW9ucyBmcm9tIEpTT04gc2NoZW1hIGlzIEpTLVlBTUwuXG5cblxuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBTY2hlbWEgPSByZXF1aXJlKCcuLi9zY2hlbWEnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBTY2hlbWEoe1xuICBpbmNsdWRlOiBbXG4gICAgcmVxdWlyZSgnLi9qc29uJylcbiAgXVxufSk7XG4iLCIvLyBKUy1ZQU1MJ3MgZGVmYXVsdCBzY2hlbWEgZm9yIGBsb2FkYCBmdW5jdGlvbi5cbi8vIEl0IGlzIG5vdCBkZXNjcmliZWQgaW4gdGhlIFlBTUwgc3BlY2lmaWNhdGlvbi5cbi8vXG4vLyBUaGlzIHNjaGVtYSBpcyBiYXNlZCBvbiBKUy1ZQU1MJ3MgZGVmYXVsdCBzYWZlIHNjaGVtYSBhbmQgaW5jbHVkZXNcbi8vIEphdmFTY3JpcHQtc3BlY2lmaWMgdHlwZXM6ICEhanMvdW5kZWZpbmVkLCAhIWpzL3JlZ2V4cCBhbmQgISFqcy9mdW5jdGlvbi5cbi8vXG4vLyBBbHNvIHRoaXMgc2NoZW1hIGlzIHVzZWQgYXMgZGVmYXVsdCBiYXNlIHNjaGVtYSBhdCBgU2NoZW1hLmNyZWF0ZWAgZnVuY3Rpb24uXG5cblxuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBTY2hlbWEgPSByZXF1aXJlKCcuLi9zY2hlbWEnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNjaGVtYS5ERUZBVUxUID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2RlZmF1bHRfc2FmZScpXG4gIF0sXG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9qcy91bmRlZmluZWQnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2pzL3JlZ2V4cCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvanMvZnVuY3Rpb24nKVxuICBdXG59KTtcbiIsIi8vIEpTLVlBTUwncyBkZWZhdWx0IHNjaGVtYSBmb3IgYHNhZmVMb2FkYCBmdW5jdGlvbi5cbi8vIEl0IGlzIG5vdCBkZXNjcmliZWQgaW4gdGhlIFlBTUwgc3BlY2lmaWNhdGlvbi5cbi8vXG4vLyBUaGlzIHNjaGVtYSBpcyBiYXNlZCBvbiBzdGFuZGFyZCBZQU1MJ3MgQ29yZSBzY2hlbWEgYW5kIGluY2x1ZGVzIG1vc3Qgb2Zcbi8vIGV4dHJhIHR5cGVzIGRlc2NyaWJlZCBhdCBZQU1MIHRhZyByZXBvc2l0b3J5LiAoaHR0cDovL3lhbWwub3JnL3R5cGUvKVxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vY29yZScpXG4gIF0sXG4gIGltcGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS90aW1lc3RhbXAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL21lcmdlJylcbiAgXSxcbiAgZXhwbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL2JpbmFyeScpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvb21hcCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvcGFpcnMnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3NldCcpXG4gIF1cbn0pO1xuIiwiLy8gU3RhbmRhcmQgWUFNTCdzIEZhaWxzYWZlIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwMjM0NlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgZXhwbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL3N0cicpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvc2VxJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9tYXAnKVxuICBdXG59KTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBKU09OIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwMzIzMVxuLy9cbi8vIE5PVEU6IEpTLVlBTUwgZG9lcyBub3Qgc3VwcG9ydCBzY2hlbWEtc3BlY2lmaWMgdGFnIHJlc29sdXRpb24gcmVzdHJpY3Rpb25zLlxuLy8gU28sIHRoaXMgc2NoZW1hIGlzIG5vdCBzdWNoIHN0cmljdCBhcyBkZWZpbmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vLyBJdCBhbGxvd3MgbnVtYmVycyBpbiBiaW5hcnkgbm90YWlvbiwgdXNlIGBOdWxsYCBhbmQgYE5VTExgIGFzIGBudWxsYCwgZXRjLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vZmFpbHNhZmUnKVxuICBdLFxuICBpbXBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvbnVsbCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvYm9vbCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvaW50JyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9mbG9hdCcpXG4gIF1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgWUFNTEV4Y2VwdGlvbiA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7XG5cbnZhciBUWVBFX0NPTlNUUlVDVE9SX09QVElPTlMgPSBbXG4gICdraW5kJyxcbiAgJ3Jlc29sdmUnLFxuICAnY29uc3RydWN0JyxcbiAgJ2luc3RhbmNlT2YnLFxuICAncHJlZGljYXRlJyxcbiAgJ3JlcHJlc2VudCcsXG4gICdkZWZhdWx0U3R5bGUnLFxuICAnc3R5bGVBbGlhc2VzJ1xuXTtcblxudmFyIFlBTUxfTk9ERV9LSU5EUyA9IFtcbiAgJ3NjYWxhcicsXG4gICdzZXF1ZW5jZScsXG4gICdtYXBwaW5nJ1xuXTtcblxuZnVuY3Rpb24gY29tcGlsZVN0eWxlQWxpYXNlcyhtYXApIHtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuXG4gIGlmIChtYXAgIT09IG51bGwpIHtcbiAgICBPYmplY3Qua2V5cyhtYXApLmZvckVhY2goZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgICBtYXBbc3R5bGVdLmZvckVhY2goZnVuY3Rpb24gKGFsaWFzKSB7XG4gICAgICAgIHJlc3VsdFtTdHJpbmcoYWxpYXMpXSA9IHN0eWxlO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBUeXBlKHRhZywgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICBPYmplY3Qua2V5cyhvcHRpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgaWYgKFRZUEVfQ09OU1RSVUNUT1JfT1BUSU9OUy5pbmRleE9mKG5hbWUpID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1Vua25vd24gb3B0aW9uIFwiJyArIG5hbWUgKyAnXCIgaXMgbWV0IGluIGRlZmluaXRpb24gb2YgXCInICsgdGFnICsgJ1wiIFlBTUwgdHlwZS4nKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIFRPRE86IEFkZCB0YWcgZm9ybWF0IGNoZWNrLlxuICB0aGlzLnRhZyAgICAgICAgICA9IHRhZztcbiAgdGhpcy5raW5kICAgICAgICAgPSBvcHRpb25zWydraW5kJ10gICAgICAgICB8fCBudWxsO1xuICB0aGlzLnJlc29sdmUgICAgICA9IG9wdGlvbnNbJ3Jlc29sdmUnXSAgICAgIHx8IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH07XG4gIHRoaXMuY29uc3RydWN0ICAgID0gb3B0aW9uc1snY29uc3RydWN0J10gICAgfHwgZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGE7IH07XG4gIHRoaXMuaW5zdGFuY2VPZiAgID0gb3B0aW9uc1snaW5zdGFuY2VPZiddICAgfHwgbnVsbDtcbiAgdGhpcy5wcmVkaWNhdGUgICAgPSBvcHRpb25zWydwcmVkaWNhdGUnXSAgICB8fCBudWxsO1xuICB0aGlzLnJlcHJlc2VudCAgICA9IG9wdGlvbnNbJ3JlcHJlc2VudCddICAgIHx8IG51bGw7XG4gIHRoaXMuZGVmYXVsdFN0eWxlID0gb3B0aW9uc1snZGVmYXVsdFN0eWxlJ10gfHwgbnVsbDtcbiAgdGhpcy5zdHlsZUFsaWFzZXMgPSBjb21waWxlU3R5bGVBbGlhc2VzKG9wdGlvbnNbJ3N0eWxlQWxpYXNlcyddIHx8IG51bGwpO1xuXG4gIGlmIChZQU1MX05PREVfS0lORFMuaW5kZXhPZih0aGlzLmtpbmQpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdVbmtub3duIGtpbmQgXCInICsgdGhpcy5raW5kICsgJ1wiIGlzIHNwZWNpZmllZCBmb3IgXCInICsgdGFnICsgJ1wiIFlBTUwgdHlwZS4nKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFR5cGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSovXG5cbnZhciBOb2RlQnVmZmVyO1xuXG50cnkge1xuICAvLyBBIHRyaWNrIGZvciBicm93c2VyaWZpZWQgdmVyc2lvbiwgdG8gbm90IGluY2x1ZGUgYEJ1ZmZlcmAgc2hpbVxuICB2YXIgX3JlcXVpcmUgPSByZXF1aXJlO1xuICBOb2RlQnVmZmVyID0gX3JlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbn0gY2F0Y2ggKF9fKSB7fVxuXG52YXIgVHlwZSAgICAgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuXG4vLyBbIDY0LCA2NSwgNjYgXSAtPiBbIHBhZGRpbmcsIENSLCBMRiBdXG52YXIgQkFTRTY0X01BUCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVxcblxccic7XG5cblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxCaW5hcnkoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBjb2RlLCBpZHgsIGJpdGxlbiA9IDAsIG1heCA9IGRhdGEubGVuZ3RoLCBtYXAgPSBCQVNFNjRfTUFQO1xuXG4gIC8vIENvbnZlcnQgb25lIGJ5IG9uZS5cbiAgZm9yIChpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7XG4gICAgY29kZSA9IG1hcC5pbmRleE9mKGRhdGEuY2hhckF0KGlkeCkpO1xuXG4gICAgLy8gU2tpcCBDUi9MRlxuICAgIGlmIChjb2RlID4gNjQpIGNvbnRpbnVlO1xuXG4gICAgLy8gRmFpbCBvbiBpbGxlZ2FsIGNoYXJhY3RlcnNcbiAgICBpZiAoY29kZSA8IDApIHJldHVybiBmYWxzZTtcblxuICAgIGJpdGxlbiArPSA2O1xuICB9XG5cbiAgLy8gSWYgdGhlcmUgYXJlIGFueSBiaXRzIGxlZnQsIHNvdXJjZSB3YXMgY29ycnVwdGVkXG4gIHJldHVybiAoYml0bGVuICUgOCkgPT09IDA7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxCaW5hcnkoZGF0YSkge1xuICB2YXIgaWR4LCB0YWlsYml0cyxcbiAgICAgIGlucHV0ID0gZGF0YS5yZXBsYWNlKC9bXFxyXFxuPV0vZywgJycpLCAvLyByZW1vdmUgQ1IvTEYgJiBwYWRkaW5nIHRvIHNpbXBsaWZ5IHNjYW5cbiAgICAgIG1heCA9IGlucHV0Lmxlbmd0aCxcbiAgICAgIG1hcCA9IEJBU0U2NF9NQVAsXG4gICAgICBiaXRzID0gMCxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIC8vIENvbGxlY3QgYnkgNio0IGJpdHMgKDMgYnl0ZXMpXG5cbiAgZm9yIChpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7XG4gICAgaWYgKChpZHggJSA0ID09PSAwKSAmJiBpZHgpIHtcbiAgICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDE2KSAmIDB4RkYpO1xuICAgICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gOCkgJiAweEZGKTtcbiAgICAgIHJlc3VsdC5wdXNoKGJpdHMgJiAweEZGKTtcbiAgICB9XG5cbiAgICBiaXRzID0gKGJpdHMgPDwgNikgfCBtYXAuaW5kZXhPZihpbnB1dC5jaGFyQXQoaWR4KSk7XG4gIH1cblxuICAvLyBEdW1wIHRhaWxcblxuICB0YWlsYml0cyA9IChtYXggJSA0KSAqIDY7XG5cbiAgaWYgKHRhaWxiaXRzID09PSAwKSB7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gMTYpICYgMHhGRik7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gOCkgJiAweEZGKTtcbiAgICByZXN1bHQucHVzaChiaXRzICYgMHhGRik7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDE4KSB7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gMTApICYgMHhGRik7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gMikgJiAweEZGKTtcbiAgfSBlbHNlIGlmICh0YWlsYml0cyA9PT0gMTIpIHtcbiAgICByZXN1bHQucHVzaCgoYml0cyA+PiA0KSAmIDB4RkYpO1xuICB9XG5cbiAgLy8gV3JhcCBpbnRvIEJ1ZmZlciBmb3IgTm9kZUpTIGFuZCBsZWF2ZSBBcnJheSBmb3IgYnJvd3NlclxuICBpZiAoTm9kZUJ1ZmZlcikgcmV0dXJuIG5ldyBOb2RlQnVmZmVyKHJlc3VsdCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50WWFtbEJpbmFyeShvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgdmFyIHJlc3VsdCA9ICcnLCBiaXRzID0gMCwgaWR4LCB0YWlsLFxuICAgICAgbWF4ID0gb2JqZWN0Lmxlbmd0aCxcbiAgICAgIG1hcCA9IEJBU0U2NF9NQVA7XG5cbiAgLy8gQ29udmVydCBldmVyeSB0aHJlZSBieXRlcyB0byA0IEFTQ0lJIGNoYXJhY3RlcnMuXG5cbiAgZm9yIChpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7XG4gICAgaWYgKChpZHggJSAzID09PSAwKSAmJiBpZHgpIHtcbiAgICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTgpICYgMHgzRl07XG4gICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDEyKSAmIDB4M0ZdO1xuICAgICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiA2KSAmIDB4M0ZdO1xuICAgICAgcmVzdWx0ICs9IG1hcFtiaXRzICYgMHgzRl07XG4gICAgfVxuXG4gICAgYml0cyA9IChiaXRzIDw8IDgpICsgb2JqZWN0W2lkeF07XG4gIH1cblxuICAvLyBEdW1wIHRhaWxcblxuICB0YWlsID0gbWF4ICUgMztcblxuICBpZiAodGFpbCA9PT0gMCkge1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTgpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxMikgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDYpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFtiaXRzICYgMHgzRl07XG4gIH0gZWxzZSBpZiAodGFpbCA9PT0gMikge1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTApICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiA0KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPDwgMikgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWzY0XTtcbiAgfSBlbHNlIGlmICh0YWlsID09PSAxKSB7XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAyKSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPDwgNCkgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWzY0XTtcbiAgICByZXN1bHQgKz0gbWFwWzY0XTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGlzQmluYXJ5KG9iamVjdCkge1xuICByZXR1cm4gTm9kZUJ1ZmZlciAmJiBOb2RlQnVmZmVyLmlzQnVmZmVyKG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmJpbmFyeScsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sQmluYXJ5LFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxCaW5hcnksXG4gIHByZWRpY2F0ZTogaXNCaW5hcnksXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbEJpbmFyeVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbEJvb2xlYW4oZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBtYXggPSBkYXRhLmxlbmd0aDtcblxuICByZXR1cm4gKG1heCA9PT0gNCAmJiAoZGF0YSA9PT0gJ3RydWUnIHx8IGRhdGEgPT09ICdUcnVlJyB8fCBkYXRhID09PSAnVFJVRScpKSB8fFxuICAgICAgICAgKG1heCA9PT0gNSAmJiAoZGF0YSA9PT0gJ2ZhbHNlJyB8fCBkYXRhID09PSAnRmFsc2UnIHx8IGRhdGEgPT09ICdGQUxTRScpKTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbEJvb2xlYW4oZGF0YSkge1xuICByZXR1cm4gZGF0YSA9PT0gJ3RydWUnIHx8XG4gICAgICAgICBkYXRhID09PSAnVHJ1ZScgfHxcbiAgICAgICAgIGRhdGEgPT09ICdUUlVFJztcbn1cblxuZnVuY3Rpb24gaXNCb29sZWFuKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IEJvb2xlYW5dJztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6Ym9vbCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sQm9vbGVhbixcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sQm9vbGVhbixcbiAgcHJlZGljYXRlOiBpc0Jvb2xlYW4sXG4gIHJlcHJlc2VudDoge1xuICAgIGxvd2VyY2FzZTogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gb2JqZWN0ID8gJ3RydWUnIDogJ2ZhbHNlJzsgfSxcbiAgICB1cHBlcmNhc2U6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuIG9iamVjdCA/ICdUUlVFJyA6ICdGQUxTRSc7IH0sXG4gICAgY2FtZWxjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAnVHJ1ZScgOiAnRmFsc2UnOyB9XG4gIH0sXG4gIGRlZmF1bHRTdHlsZTogJ2xvd2VyY2FzZSdcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgVHlwZSAgID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgWUFNTF9GTE9BVF9QQVRURVJOID0gbmV3IFJlZ0V4cChcbiAgJ14oPzpbLStdPyg/OlswLTldWzAtOV9dKilcXFxcLlswLTlfXSooPzpbZUVdWy0rXVswLTldKyk/JyArXG4gICd8XFxcXC5bMC05X10rKD86W2VFXVstK11bMC05XSspPycgK1xuICAnfFstK10/WzAtOV1bMC05X10qKD86OlswLTVdP1swLTldKStcXFxcLlswLTlfXSonICtcbiAgJ3xbLStdP1xcXFwuKD86aW5mfEluZnxJTkYpJyArXG4gICd8XFxcXC4oPzpuYW58TmFOfE5BTikpJCcpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbEZsb2F0KGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICBpZiAoIVlBTUxfRkxPQVRfUEFUVEVSTi50ZXN0KGRhdGEpKSByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxGbG9hdChkYXRhKSB7XG4gIHZhciB2YWx1ZSwgc2lnbiwgYmFzZSwgZGlnaXRzO1xuXG4gIHZhbHVlICA9IGRhdGEucmVwbGFjZSgvXy9nLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgc2lnbiAgID0gdmFsdWVbMF0gPT09ICctJyA/IC0xIDogMTtcbiAgZGlnaXRzID0gW107XG5cbiAgaWYgKCcrLScuaW5kZXhPZih2YWx1ZVswXSkgPj0gMCkge1xuICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMSk7XG4gIH1cblxuICBpZiAodmFsdWUgPT09ICcuaW5mJykge1xuICAgIHJldHVybiAoc2lnbiA9PT0gMSkgPyBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgOiBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XG5cbiAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJy5uYW4nKSB7XG4gICAgcmV0dXJuIE5hTjtcblxuICB9IGVsc2UgaWYgKHZhbHVlLmluZGV4T2YoJzonKSA+PSAwKSB7XG4gICAgdmFsdWUuc3BsaXQoJzonKS5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG4gICAgICBkaWdpdHMudW5zaGlmdChwYXJzZUZsb2F0KHYsIDEwKSk7XG4gICAgfSk7XG5cbiAgICB2YWx1ZSA9IDAuMDtcbiAgICBiYXNlID0gMTtcblxuICAgIGRpZ2l0cy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICB2YWx1ZSArPSBkICogYmFzZTtcbiAgICAgIGJhc2UgKj0gNjA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2lnbiAqIHZhbHVlO1xuXG4gIH1cbiAgcmV0dXJuIHNpZ24gKiBwYXJzZUZsb2F0KHZhbHVlLCAxMCk7XG59XG5cblxudmFyIFNDSUVOVElGSUNfV0lUSE9VVF9ET1QgPSAvXlstK10/WzAtOV0rZS87XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxGbG9hdChvYmplY3QsIHN0eWxlKSB7XG4gIHZhciByZXM7XG5cbiAgaWYgKGlzTmFOKG9iamVjdCkpIHtcbiAgICBzd2l0Y2ggKHN0eWxlKSB7XG4gICAgICBjYXNlICdsb3dlcmNhc2UnOiByZXR1cm4gJy5uYW4nO1xuICAgICAgY2FzZSAndXBwZXJjYXNlJzogcmV0dXJuICcuTkFOJztcbiAgICAgIGNhc2UgJ2NhbWVsY2FzZSc6IHJldHVybiAnLk5hTic7XG4gICAgfVxuICB9IGVsc2UgaWYgKE51bWJlci5QT1NJVElWRV9JTkZJTklUWSA9PT0gb2JqZWN0KSB7XG4gICAgc3dpdGNoIChzdHlsZSkge1xuICAgICAgY2FzZSAnbG93ZXJjYXNlJzogcmV0dXJuICcuaW5mJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLklORic7XG4gICAgICBjYXNlICdjYW1lbGNhc2UnOiByZXR1cm4gJy5JbmYnO1xuICAgIH1cbiAgfSBlbHNlIGlmIChOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkgPT09IG9iamVjdCkge1xuICAgIHN3aXRjaCAoc3R5bGUpIHtcbiAgICAgIGNhc2UgJ2xvd2VyY2FzZSc6IHJldHVybiAnLS5pbmYnO1xuICAgICAgY2FzZSAndXBwZXJjYXNlJzogcmV0dXJuICctLklORic7XG4gICAgICBjYXNlICdjYW1lbGNhc2UnOiByZXR1cm4gJy0uSW5mJztcbiAgICB9XG4gIH0gZWxzZSBpZiAoY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpIHtcbiAgICByZXR1cm4gJy0wLjAnO1xuICB9XG5cbiAgcmVzID0gb2JqZWN0LnRvU3RyaW5nKDEwKTtcblxuICAvLyBKUyBzdHJpbmdpZmllciBjYW4gYnVpbGQgc2NpZW50aWZpYyBmb3JtYXQgd2l0aG91dCBkb3RzOiA1ZS0xMDAsXG4gIC8vIHdoaWxlIFlBTUwgcmVxdXJlcyBkb3Q6IDUuZS0xMDAuIEZpeCBpdCB3aXRoIHNpbXBsZSBoYWNrXG5cbiAgcmV0dXJuIFNDSUVOVElGSUNfV0lUSE9VVF9ET1QudGVzdChyZXMpID8gcmVzLnJlcGxhY2UoJ2UnLCAnLmUnKSA6IHJlcztcbn1cblxuZnVuY3Rpb24gaXNGbG9hdChvYmplY3QpIHtcbiAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgTnVtYmVyXScpICYmXG4gICAgICAgICAob2JqZWN0ICUgMSAhPT0gMCB8fCBjb21tb24uaXNOZWdhdGl2ZVplcm8ob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmZsb2F0Jywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxGbG9hdCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sRmxvYXQsXG4gIHByZWRpY2F0ZTogaXNGbG9hdCxcbiAgcmVwcmVzZW50OiByZXByZXNlbnRZYW1sRmxvYXQsXG4gIGRlZmF1bHRTdHlsZTogJ2xvd2VyY2FzZSdcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgVHlwZSAgID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiBpc0hleENvZGUoYykge1xuICByZXR1cm4gKCgweDMwLyogMCAqLyA8PSBjKSAmJiAoYyA8PSAweDM5LyogOSAqLykpIHx8XG4gICAgICAgICAoKDB4NDEvKiBBICovIDw9IGMpICYmIChjIDw9IDB4NDYvKiBGICovKSkgfHxcbiAgICAgICAgICgoMHg2MS8qIGEgKi8gPD0gYykgJiYgKGMgPD0gMHg2Ni8qIGYgKi8pKTtcbn1cblxuZnVuY3Rpb24gaXNPY3RDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzNy8qIDcgKi8pKTtcbn1cblxuZnVuY3Rpb24gaXNEZWNDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxJbnRlZ2VyKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGgsXG4gICAgICBpbmRleCA9IDAsXG4gICAgICBoYXNEaWdpdHMgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIGlmICghbWF4KSByZXR1cm4gZmFsc2U7XG5cbiAgY2ggPSBkYXRhW2luZGV4XTtcblxuICAvLyBzaWduXG4gIGlmIChjaCA9PT0gJy0nIHx8IGNoID09PSAnKycpIHtcbiAgICBjaCA9IGRhdGFbKytpbmRleF07XG4gIH1cblxuICBpZiAoY2ggPT09ICcwJykge1xuICAgIC8vIDBcbiAgICBpZiAoaW5kZXggKyAxID09PSBtYXgpIHJldHVybiB0cnVlO1xuICAgIGNoID0gZGF0YVsrK2luZGV4XTtcblxuICAgIC8vIGJhc2UgMiwgYmFzZSA4LCBiYXNlIDE2XG5cbiAgICBpZiAoY2ggPT09ICdiJykge1xuICAgICAgLy8gYmFzZSAyXG4gICAgICBpbmRleCsrO1xuXG4gICAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICAgICAgaWYgKGNoID09PSAnXycpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoY2ggIT09ICcwJyAmJiBjaCAhPT0gJzEnKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGhhc0RpZ2l0cyA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzRGlnaXRzO1xuICAgIH1cblxuXG4gICAgaWYgKGNoID09PSAneCcpIHtcbiAgICAgIC8vIGJhc2UgMTZcbiAgICAgIGluZGV4Kys7XG5cbiAgICAgIGZvciAoOyBpbmRleCA8IG1heDsgaW5kZXgrKykge1xuICAgICAgICBjaCA9IGRhdGFbaW5kZXhdO1xuICAgICAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgICAgIGlmICghaXNIZXhDb2RlKGRhdGEuY2hhckNvZGVBdChpbmRleCkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGhhc0RpZ2l0cyA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzRGlnaXRzO1xuICAgIH1cblxuICAgIC8vIGJhc2UgOFxuICAgIGZvciAoOyBpbmRleCA8IG1heDsgaW5kZXgrKykge1xuICAgICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICAgIGlmIChjaCA9PT0gJ18nKSBjb250aW51ZTtcbiAgICAgIGlmICghaXNPY3RDb2RlKGRhdGEuY2hhckNvZGVBdChpbmRleCkpKSByZXR1cm4gZmFsc2U7XG4gICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gaGFzRGlnaXRzO1xuICB9XG5cbiAgLy8gYmFzZSAxMCAoZXhjZXB0IDApIG9yIGJhc2UgNjBcblxuICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICBjaCA9IGRhdGFbaW5kZXhdO1xuICAgIGlmIChjaCA9PT0gJ18nKSBjb250aW51ZTtcbiAgICBpZiAoY2ggPT09ICc6JykgYnJlYWs7XG4gICAgaWYgKCFpc0RlY0NvZGUoZGF0YS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaGFzRGlnaXRzID0gdHJ1ZTtcbiAgfVxuXG4gIGlmICghaGFzRGlnaXRzKSByZXR1cm4gZmFsc2U7XG5cbiAgLy8gaWYgIWJhc2U2MCAtIGRvbmU7XG4gIGlmIChjaCAhPT0gJzonKSByZXR1cm4gdHJ1ZTtcblxuICAvLyBiYXNlNjAgYWxtb3N0IG5vdCB1c2VkLCBubyBuZWVkcyB0byBvcHRpbWl6ZVxuICByZXR1cm4gL14oOlswLTVdP1swLTldKSskLy50ZXN0KGRhdGEuc2xpY2UoaW5kZXgpKTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbEludGVnZXIoZGF0YSkge1xuICB2YXIgdmFsdWUgPSBkYXRhLCBzaWduID0gMSwgY2gsIGJhc2UsIGRpZ2l0cyA9IFtdO1xuXG4gIGlmICh2YWx1ZS5pbmRleE9mKCdfJykgIT09IC0xKSB7XG4gICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9fL2csICcnKTtcbiAgfVxuXG4gIGNoID0gdmFsdWVbMF07XG5cbiAgaWYgKGNoID09PSAnLScgfHwgY2ggPT09ICcrJykge1xuICAgIGlmIChjaCA9PT0gJy0nKSBzaWduID0gLTE7XG4gICAgdmFsdWUgPSB2YWx1ZS5zbGljZSgxKTtcbiAgICBjaCA9IHZhbHVlWzBdO1xuICB9XG5cbiAgaWYgKHZhbHVlID09PSAnMCcpIHJldHVybiAwO1xuXG4gIGlmIChjaCA9PT0gJzAnKSB7XG4gICAgaWYgKHZhbHVlWzFdID09PSAnYicpIHJldHVybiBzaWduICogcGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIDIpO1xuICAgIGlmICh2YWx1ZVsxXSA9PT0gJ3gnKSByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLCAxNik7XG4gICAgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZSwgOCk7XG4gIH1cblxuICBpZiAodmFsdWUuaW5kZXhPZignOicpICE9PSAtMSkge1xuICAgIHZhbHVlLnNwbGl0KCc6JykuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgICAgZGlnaXRzLnVuc2hpZnQocGFyc2VJbnQodiwgMTApKTtcbiAgICB9KTtcblxuICAgIHZhbHVlID0gMDtcbiAgICBiYXNlID0gMTtcblxuICAgIGRpZ2l0cy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICB2YWx1ZSArPSAoZCAqIGJhc2UpO1xuICAgICAgYmFzZSAqPSA2MDtcbiAgICB9KTtcblxuICAgIHJldHVybiBzaWduICogdmFsdWU7XG5cbiAgfVxuXG4gIHJldHVybiBzaWduICogcGFyc2VJbnQodmFsdWUsIDEwKTtcbn1cblxuZnVuY3Rpb24gaXNJbnRlZ2VyKG9iamVjdCkge1xuICByZXR1cm4gKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpKSA9PT0gJ1tvYmplY3QgTnVtYmVyXScgJiZcbiAgICAgICAgIChvYmplY3QgJSAxID09PSAwICYmICFjb21tb24uaXNOZWdhdGl2ZVplcm8ob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmludCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sSW50ZWdlcixcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sSW50ZWdlcixcbiAgcHJlZGljYXRlOiBpc0ludGVnZXIsXG4gIHJlcHJlc2VudDoge1xuICAgIGJpbmFyeTogICAgICBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiAnMGInICsgb2JqZWN0LnRvU3RyaW5nKDIpOyB9LFxuICAgIG9jdGFsOiAgICAgICBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiAnMCcgICsgb2JqZWN0LnRvU3RyaW5nKDgpOyB9LFxuICAgIGRlY2ltYWw6ICAgICBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiAgICAgICAgb2JqZWN0LnRvU3RyaW5nKDEwKTsgfSxcbiAgICBoZXhhZGVjaW1hbDogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzB4JyArIG9iamVjdC50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTsgfVxuICB9LFxuICBkZWZhdWx0U3R5bGU6ICdkZWNpbWFsJyxcbiAgc3R5bGVBbGlhc2VzOiB7XG4gICAgYmluYXJ5OiAgICAgIFsgMiwgICdiaW4nIF0sXG4gICAgb2N0YWw6ICAgICAgIFsgOCwgICdvY3QnIF0sXG4gICAgZGVjaW1hbDogICAgIFsgMTAsICdkZWMnIF0sXG4gICAgaGV4YWRlY2ltYWw6IFsgMTYsICdoZXgnIF1cbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBlc3ByaW1hO1xuXG4vLyBCcm93c2VyaWZpZWQgdmVyc2lvbiBkb2VzIG5vdCBoYXZlIGVzcHJpbWFcbi8vXG4vLyAxLiBGb3Igbm9kZS5qcyBqdXN0IHJlcXVpcmUgbW9kdWxlIGFzIGRlcHNcbi8vIDIuIEZvciBicm93c2VyIHRyeSB0byByZXF1aXJlIG11ZHVsZSB2aWEgZXh0ZXJuYWwgQU1EIHN5c3RlbS5cbi8vICAgIElmIG5vdCBmb3VuZCAtIHRyeSB0byBmYWxsYmFjayB0byB3aW5kb3cuZXNwcmltYS4gSWYgbm90XG4vLyAgICBmb3VuZCB0b28gLSB0aGVuIGZhaWwgdG8gcGFyc2UuXG4vL1xudHJ5IHtcbiAgLy8gd29ya2Fyb3VuZCB0byBleGNsdWRlIHBhY2thZ2UgZnJvbSBicm93c2VyaWZ5IGxpc3QuXG4gIHZhciBfcmVxdWlyZSA9IHJlcXVpcmU7XG4gIGVzcHJpbWEgPSBfcmVxdWlyZSgnZXNwcmltYScpO1xufSBjYXRjaCAoXykge1xuICAvKmdsb2JhbCB3aW5kb3cgKi9cbiAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSBlc3ByaW1hID0gd2luZG93LmVzcHJpbWE7XG59XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdEZ1bmN0aW9uKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB0cnkge1xuICAgIHZhciBzb3VyY2UgPSAnKCcgKyBkYXRhICsgJyknLFxuICAgICAgICBhc3QgICAgPSBlc3ByaW1hLnBhcnNlKHNvdXJjZSwgeyByYW5nZTogdHJ1ZSB9KTtcblxuICAgIGlmIChhc3QudHlwZSAgICAgICAgICAgICAgICAgICAgIT09ICdQcm9ncmFtJyAgICAgICAgICAgICB8fFxuICAgICAgICBhc3QuYm9keS5sZW5ndGggICAgICAgICAgICAgIT09IDEgICAgICAgICAgICAgICAgICAgICB8fFxuICAgICAgICBhc3QuYm9keVswXS50eXBlICAgICAgICAgICAgIT09ICdFeHByZXNzaW9uU3RhdGVtZW50JyB8fFxuICAgICAgICBhc3QuYm9keVswXS5leHByZXNzaW9uLnR5cGUgIT09ICdGdW5jdGlvbkV4cHJlc3Npb24nKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RKYXZhc2NyaXB0RnVuY3Rpb24oZGF0YSkge1xuICAvKmpzbGludCBldmlsOnRydWUqL1xuXG4gIHZhciBzb3VyY2UgPSAnKCcgKyBkYXRhICsgJyknLFxuICAgICAgYXN0ICAgID0gZXNwcmltYS5wYXJzZShzb3VyY2UsIHsgcmFuZ2U6IHRydWUgfSksXG4gICAgICBwYXJhbXMgPSBbXSxcbiAgICAgIGJvZHk7XG5cbiAgaWYgKGFzdC50eXBlICAgICAgICAgICAgICAgICAgICAhPT0gJ1Byb2dyYW0nICAgICAgICAgICAgIHx8XG4gICAgICBhc3QuYm9keS5sZW5ndGggICAgICAgICAgICAgIT09IDEgICAgICAgICAgICAgICAgICAgICB8fFxuICAgICAgYXN0LmJvZHlbMF0udHlwZSAgICAgICAgICAgICE9PSAnRXhwcmVzc2lvblN0YXRlbWVudCcgfHxcbiAgICAgIGFzdC5ib2R5WzBdLmV4cHJlc3Npb24udHlwZSAhPT0gJ0Z1bmN0aW9uRXhwcmVzc2lvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZXNvbHZlIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBhc3QuYm9keVswXS5leHByZXNzaW9uLnBhcmFtcy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJhbSkge1xuICAgIHBhcmFtcy5wdXNoKHBhcmFtLm5hbWUpO1xuICB9KTtcblxuICBib2R5ID0gYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi5ib2R5LnJhbmdlO1xuXG4gIC8vIEVzcHJpbWEncyByYW5nZXMgaW5jbHVkZSB0aGUgZmlyc3QgJ3snIGFuZCB0aGUgbGFzdCAnfScgY2hhcmFjdGVycyBvblxuICAvLyBmdW5jdGlvbiBleHByZXNzaW9ucy4gU28gY3V0IHRoZW0gb3V0LlxuICAvKmVzbGludC1kaXNhYmxlIG5vLW5ldy1mdW5jKi9cbiAgcmV0dXJuIG5ldyBGdW5jdGlvbihwYXJhbXMsIHNvdXJjZS5zbGljZShib2R5WzBdICsgMSwgYm9keVsxXSAtIDEpKTtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdEZ1bmN0aW9uKG9iamVjdCAvKiwgc3R5bGUqLykge1xuICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCk7XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24ob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6anMvZnVuY3Rpb24nLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdEZ1bmN0aW9uLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRGdW5jdGlvbixcbiAgcHJlZGljYXRlOiBpc0Z1bmN0aW9uLFxuICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRGdW5jdGlvblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdFJlZ0V4cChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciByZWdleHAgPSBkYXRhLFxuICAgICAgdGFpbCAgID0gL1xcLyhbZ2ltXSopJC8uZXhlYyhkYXRhKSxcbiAgICAgIG1vZGlmaWVycyA9ICcnO1xuXG4gIC8vIGlmIHJlZ2V4cCBzdGFydHMgd2l0aCAnLycgaXQgY2FuIGhhdmUgbW9kaWZpZXJzIGFuZCBtdXN0IGJlIHByb3Blcmx5IGNsb3NlZFxuICAvLyBgL2Zvby9naW1gIC0gbW9kaWZpZXJzIHRhaWwgY2FuIGJlIG1heGltdW0gMyBjaGFyc1xuICBpZiAocmVnZXhwWzBdID09PSAnLycpIHtcbiAgICBpZiAodGFpbCkgbW9kaWZpZXJzID0gdGFpbFsxXTtcblxuICAgIGlmIChtb2RpZmllcnMubGVuZ3RoID4gMykgcmV0dXJuIGZhbHNlO1xuICAgIC8vIGlmIGV4cHJlc3Npb24gc3RhcnRzIHdpdGggLywgaXMgc2hvdWxkIGJlIHByb3Blcmx5IHRlcm1pbmF0ZWRcbiAgICBpZiAocmVnZXhwW3JlZ2V4cC5sZW5ndGggLSBtb2RpZmllcnMubGVuZ3RoIC0gMV0gIT09ICcvJykgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdEphdmFzY3JpcHRSZWdFeHAoZGF0YSkge1xuICB2YXIgcmVnZXhwID0gZGF0YSxcbiAgICAgIHRhaWwgICA9IC9cXC8oW2dpbV0qKSQvLmV4ZWMoZGF0YSksXG4gICAgICBtb2RpZmllcnMgPSAnJztcblxuICAvLyBgL2Zvby9naW1gIC0gdGFpbCBjYW4gYmUgbWF4aW11bSA0IGNoYXJzXG4gIGlmIChyZWdleHBbMF0gPT09ICcvJykge1xuICAgIGlmICh0YWlsKSBtb2RpZmllcnMgPSB0YWlsWzFdO1xuICAgIHJlZ2V4cCA9IHJlZ2V4cC5zbGljZSgxLCByZWdleHAubGVuZ3RoIC0gbW9kaWZpZXJzLmxlbmd0aCAtIDEpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBSZWdFeHAocmVnZXhwLCBtb2RpZmllcnMpO1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRKYXZhc2NyaXB0UmVnRXhwKG9iamVjdCAvKiwgc3R5bGUqLykge1xuICB2YXIgcmVzdWx0ID0gJy8nICsgb2JqZWN0LnNvdXJjZSArICcvJztcblxuICBpZiAob2JqZWN0Lmdsb2JhbCkgcmVzdWx0ICs9ICdnJztcbiAgaWYgKG9iamVjdC5tdWx0aWxpbmUpIHJlc3VsdCArPSAnbSc7XG4gIGlmIChvYmplY3QuaWdub3JlQ2FzZSkgcmVzdWx0ICs9ICdpJztcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpc1JlZ0V4cChvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6anMvcmVnZXhwJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZUphdmFzY3JpcHRSZWdFeHAsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0SmF2YXNjcmlwdFJlZ0V4cCxcbiAgcHJlZGljYXRlOiBpc1JlZ0V4cCxcbiAgcmVwcmVzZW50OiByZXByZXNlbnRKYXZhc2NyaXB0UmVnRXhwXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi8uLi90eXBlJyk7XG5cbmZ1bmN0aW9uIHJlc29sdmVKYXZhc2NyaXB0VW5kZWZpbmVkKCkge1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0SmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgLyplc2xpbnQtZGlzYWJsZSBuby11bmRlZmluZWQqL1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRKYXZhc2NyaXB0VW5kZWZpbmVkKCkge1xuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKG9iamVjdCkge1xuICByZXR1cm4gdHlwZW9mIG9iamVjdCA9PT0gJ3VuZGVmaW5lZCc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL3VuZGVmaW5lZCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVKYXZhc2NyaXB0VW5kZWZpbmVkLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRVbmRlZmluZWQsXG4gIHByZWRpY2F0ZTogaXNVbmRlZmluZWQsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50SmF2YXNjcmlwdFVuZGVmaW5lZFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjptYXAnLCB7XG4gIGtpbmQ6ICdtYXBwaW5nJyxcbiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiB7fTsgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE1lcmdlKGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEgPT09ICc8PCcgfHwgZGF0YSA9PT0gbnVsbDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6bWVyZ2UnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbE1lcmdlXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sTnVsbChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gdHJ1ZTtcblxuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGg7XG5cbiAgcmV0dXJuIChtYXggPT09IDEgJiYgZGF0YSA9PT0gJ34nKSB8fFxuICAgICAgICAgKG1heCA9PT0gNCAmJiAoZGF0YSA9PT0gJ251bGwnIHx8IGRhdGEgPT09ICdOdWxsJyB8fCBkYXRhID09PSAnTlVMTCcpKTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbE51bGwoKSB7XG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBpc051bGwob2JqZWN0KSB7XG4gIHJldHVybiBvYmplY3QgPT09IG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOm51bGwnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbE51bGwsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbE51bGwsXG4gIHByZWRpY2F0ZTogaXNOdWxsLFxuICByZXByZXNlbnQ6IHtcbiAgICBjYW5vbmljYWw6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICd+JzsgICAgfSxcbiAgICBsb3dlcmNhc2U6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICdudWxsJzsgfSxcbiAgICB1cHBlcmNhc2U6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICdOVUxMJzsgfSxcbiAgICBjYW1lbGNhc2U6IGZ1bmN0aW9uICgpIHsgcmV0dXJuICdOdWxsJzsgfVxuICB9LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIF90b1N0cmluZyAgICAgICA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sT21hcChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gdHJ1ZTtcblxuICB2YXIgb2JqZWN0S2V5cyA9IFtdLCBpbmRleCwgbGVuZ3RoLCBwYWlyLCBwYWlyS2V5LCBwYWlySGFzS2V5LFxuICAgICAgb2JqZWN0ID0gZGF0YTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyID0gb2JqZWN0W2luZGV4XTtcbiAgICBwYWlySGFzS2V5ID0gZmFsc2U7XG5cbiAgICBpZiAoX3RvU3RyaW5nLmNhbGwocGFpcikgIT09ICdbb2JqZWN0IE9iamVjdF0nKSByZXR1cm4gZmFsc2U7XG5cbiAgICBmb3IgKHBhaXJLZXkgaW4gcGFpcikge1xuICAgICAgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhaXIsIHBhaXJLZXkpKSB7XG4gICAgICAgIGlmICghcGFpckhhc0tleSkgcGFpckhhc0tleSA9IHRydWU7XG4gICAgICAgIGVsc2UgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghcGFpckhhc0tleSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKG9iamVjdEtleXMuaW5kZXhPZihwYWlyS2V5KSA9PT0gLTEpIG9iamVjdEtleXMucHVzaChwYWlyS2V5KTtcbiAgICBlbHNlIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sT21hcChkYXRhKSB7XG4gIHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IFtdO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpvbWFwJywge1xuICBraW5kOiAnc2VxdWVuY2UnLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbE9tYXAsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbE9tYXBcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIF90b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sUGFpcnMoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIGluZGV4LCBsZW5ndGgsIHBhaXIsIGtleXMsIHJlc3VsdCxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgcmVzdWx0ID0gbmV3IEFycmF5KG9iamVjdC5sZW5ndGgpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXIgPSBvYmplY3RbaW5kZXhdO1xuXG4gICAgaWYgKF90b1N0cmluZy5jYWxsKHBhaXIpICE9PSAnW29iamVjdCBPYmplY3RdJykgcmV0dXJuIGZhbHNlO1xuXG4gICAga2V5cyA9IE9iamVjdC5rZXlzKHBhaXIpO1xuXG4gICAgaWYgKGtleXMubGVuZ3RoICE9PSAxKSByZXR1cm4gZmFsc2U7XG5cbiAgICByZXN1bHRbaW5kZXhdID0gWyBrZXlzWzBdLCBwYWlyW2tleXNbMF1dIF07XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFBhaXJzKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBbXTtcblxuICB2YXIgaW5kZXgsIGxlbmd0aCwgcGFpciwga2V5cywgcmVzdWx0LFxuICAgICAgb2JqZWN0ID0gZGF0YTtcblxuICByZXN1bHQgPSBuZXcgQXJyYXkob2JqZWN0Lmxlbmd0aCk7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpciA9IG9iamVjdFtpbmRleF07XG5cbiAgICBrZXlzID0gT2JqZWN0LmtleXMocGFpcik7XG5cbiAgICByZXN1bHRbaW5kZXhdID0gWyBrZXlzWzBdLCBwYWlyW2tleXNbMF1dIF07XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpwYWlycycsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxQYWlycyxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sUGFpcnNcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6c2VxJywge1xuICBraW5kOiAnc2VxdWVuY2UnLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IFtdOyB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFNldChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gdHJ1ZTtcblxuICB2YXIga2V5LCBvYmplY3QgPSBkYXRhO1xuXG4gIGZvciAoa2V5IGluIG9iamVjdCkge1xuICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgIGlmIChvYmplY3Rba2V5XSAhPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sU2V0KGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEgIT09IG51bGwgPyBkYXRhIDoge307XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnNldCcsIHtcbiAga2luZDogJ21hcHBpbmcnLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbFNldCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sU2V0XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnN0cicsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGEgIT09IG51bGwgPyBkYXRhIDogJyc7IH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIFlBTUxfREFURV9SRUdFWFAgPSBuZXcgUmVnRXhwKFxuICAnXihbMC05XVswLTldWzAtOV1bMC05XSknICAgICAgICAgICsgLy8gWzFdIHllYXJcbiAgJy0oWzAtOV1bMC05XSknICAgICAgICAgICAgICAgICAgICArIC8vIFsyXSBtb250aFxuICAnLShbMC05XVswLTldKSQnKTsgICAgICAgICAgICAgICAgICAgLy8gWzNdIGRheVxuXG52YXIgWUFNTF9USU1FU1RBTVBfUkVHRVhQID0gbmV3IFJlZ0V4cChcbiAgJ14oWzAtOV1bMC05XVswLTldWzAtOV0pJyAgICAgICAgICArIC8vIFsxXSB5ZWFyXG4gICctKFswLTldWzAtOV0/KScgICAgICAgICAgICAgICAgICAgKyAvLyBbMl0gbW9udGhcbiAgJy0oWzAtOV1bMC05XT8pJyAgICAgICAgICAgICAgICAgICArIC8vIFszXSBkYXlcbiAgJyg/OltUdF18WyBcXFxcdF0rKScgICAgICAgICAgICAgICAgICsgLy8gLi4uXG4gICcoWzAtOV1bMC05XT8pJyAgICAgICAgICAgICAgICAgICAgKyAvLyBbNF0gaG91clxuICAnOihbMC05XVswLTldKScgICAgICAgICAgICAgICAgICAgICsgLy8gWzVdIG1pbnV0ZVxuICAnOihbMC05XVswLTldKScgICAgICAgICAgICAgICAgICAgICsgLy8gWzZdIHNlY29uZFxuICAnKD86XFxcXC4oWzAtOV0qKSk/JyAgICAgICAgICAgICAgICAgKyAvLyBbN10gZnJhY3Rpb25cbiAgJyg/OlsgXFxcXHRdKihafChbLStdKShbMC05XVswLTldPyknICsgLy8gWzhdIHR6IFs5XSB0el9zaWduIFsxMF0gdHpfaG91clxuICAnKD86OihbMC05XVswLTldKSk/KSk/JCcpOyAgICAgICAgICAgLy8gWzExXSB0el9taW51dGVcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxUaW1lc3RhbXAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoWUFNTF9EQVRFX1JFR0VYUC5leGVjKGRhdGEpICE9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgaWYgKFlBTUxfVElNRVNUQU1QX1JFR0VYUC5leGVjKGRhdGEpICE9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sVGltZXN0YW1wKGRhdGEpIHtcbiAgdmFyIG1hdGNoLCB5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIHNlY29uZCwgZnJhY3Rpb24gPSAwLFxuICAgICAgZGVsdGEgPSBudWxsLCB0el9ob3VyLCB0el9taW51dGUsIGRhdGU7XG5cbiAgbWF0Y2ggPSBZQU1MX0RBVEVfUkVHRVhQLmV4ZWMoZGF0YSk7XG4gIGlmIChtYXRjaCA9PT0gbnVsbCkgbWF0Y2ggPSBZQU1MX1RJTUVTVEFNUF9SRUdFWFAuZXhlYyhkYXRhKTtcblxuICBpZiAobWF0Y2ggPT09IG51bGwpIHRocm93IG5ldyBFcnJvcignRGF0ZSByZXNvbHZlIGVycm9yJyk7XG5cbiAgLy8gbWF0Y2g6IFsxXSB5ZWFyIFsyXSBtb250aCBbM10gZGF5XG5cbiAgeWVhciA9ICsobWF0Y2hbMV0pO1xuICBtb250aCA9ICsobWF0Y2hbMl0pIC0gMTsgLy8gSlMgbW9udGggc3RhcnRzIHdpdGggMFxuICBkYXkgPSArKG1hdGNoWzNdKTtcblxuICBpZiAoIW1hdGNoWzRdKSB7IC8vIG5vIGhvdXJcbiAgICByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoeWVhciwgbW9udGgsIGRheSkpO1xuICB9XG5cbiAgLy8gbWF0Y2g6IFs0XSBob3VyIFs1XSBtaW51dGUgWzZdIHNlY29uZCBbN10gZnJhY3Rpb25cblxuICBob3VyID0gKyhtYXRjaFs0XSk7XG4gIG1pbnV0ZSA9ICsobWF0Y2hbNV0pO1xuICBzZWNvbmQgPSArKG1hdGNoWzZdKTtcblxuICBpZiAobWF0Y2hbN10pIHtcbiAgICBmcmFjdGlvbiA9IG1hdGNoWzddLnNsaWNlKDAsIDMpO1xuICAgIHdoaWxlIChmcmFjdGlvbi5sZW5ndGggPCAzKSB7IC8vIG1pbGxpLXNlY29uZHNcbiAgICAgIGZyYWN0aW9uICs9ICcwJztcbiAgICB9XG4gICAgZnJhY3Rpb24gPSArZnJhY3Rpb247XG4gIH1cblxuICAvLyBtYXRjaDogWzhdIHR6IFs5XSB0el9zaWduIFsxMF0gdHpfaG91ciBbMTFdIHR6X21pbnV0ZVxuXG4gIGlmIChtYXRjaFs5XSkge1xuICAgIHR6X2hvdXIgPSArKG1hdGNoWzEwXSk7XG4gICAgdHpfbWludXRlID0gKyhtYXRjaFsxMV0gfHwgMCk7XG4gICAgZGVsdGEgPSAodHpfaG91ciAqIDYwICsgdHpfbWludXRlKSAqIDYwMDAwOyAvLyBkZWx0YSBpbiBtaWxpLXNlY29uZHNcbiAgICBpZiAobWF0Y2hbOV0gPT09ICctJykgZGVsdGEgPSAtZGVsdGE7XG4gIH1cblxuICBkYXRlID0gbmV3IERhdGUoRGF0ZS5VVEMoeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIGZyYWN0aW9uKSk7XG5cbiAgaWYgKGRlbHRhKSBkYXRlLnNldFRpbWUoZGF0ZS5nZXRUaW1lKCkgLSBkZWx0YSk7XG5cbiAgcmV0dXJuIGRhdGU7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxUaW1lc3RhbXAob2JqZWN0IC8qLCBzdHlsZSovKSB7XG4gIHJldHVybiBvYmplY3QudG9JU09TdHJpbmcoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6dGltZXN0YW1wJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxUaW1lc3RhbXAsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFRpbWVzdGFtcCxcbiAgaW5zdGFuY2VPZjogRGF0ZSxcbiAgcmVwcmVzZW50OiByZXByZXNlbnRZYW1sVGltZXN0YW1wXG59KTtcbiIsInZhciBiYXNlSW5kZXhPZiA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VJbmRleE9mJyksXG4gICAgYmluYXJ5SW5kZXggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iaW5hcnlJbmRleCcpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGB2YWx1ZWAgaXMgZm91bmQgaW4gYGFycmF5YFxuICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhcyB0aGUgb2Zmc2V0XG4gKiBmcm9tIHRoZSBlbmQgb2YgYGFycmF5YC4gSWYgYGFycmF5YCBpcyBzb3J0ZWQgcHJvdmlkaW5nIGB0cnVlYCBmb3IgYGZyb21JbmRleGBcbiAqIHBlcmZvcm1zIGEgZmFzdGVyIGJpbmFyeSBzZWFyY2guXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBBcnJheVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge2Jvb2xlYW58bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbSBvciBgdHJ1ZWBcbiAqICB0byBwZXJmb3JtIGEgYmluYXJ5IHNlYXJjaCBvbiBhIHNvcnRlZCBhcnJheS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaW5kZXhPZihbMSwgMiwgMSwgMl0sIDIpO1xuICogLy8gPT4gMVxuICpcbiAqIC8vIHVzaW5nIGBmcm9tSW5kZXhgXG4gKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyLCAyKTtcbiAqIC8vID0+IDNcbiAqXG4gKiAvLyBwZXJmb3JtaW5nIGEgYmluYXJ5IHNlYXJjaFxuICogXy5pbmRleE9mKFsxLCAxLCAyLCAyXSwgMiwgdHJ1ZSk7XG4gKiAvLyA9PiAyXG4gKi9cbmZ1bmN0aW9uIGluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgaWYgKHR5cGVvZiBmcm9tSW5kZXggPT0gJ251bWJlcicpIHtcbiAgICBmcm9tSW5kZXggPSBmcm9tSW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGZyb21JbmRleCwgMCkgOiBmcm9tSW5kZXg7XG4gIH0gZWxzZSBpZiAoZnJvbUluZGV4KSB7XG4gICAgdmFyIGluZGV4ID0gYmluYXJ5SW5kZXgoYXJyYXksIHZhbHVlKTtcbiAgICBpZiAoaW5kZXggPCBsZW5ndGggJiZcbiAgICAgICAgKHZhbHVlID09PSB2YWx1ZSA/ICh2YWx1ZSA9PT0gYXJyYXlbaW5kZXhdKSA6IChhcnJheVtpbmRleF0gIT09IGFycmF5W2luZGV4XSkpKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuICByZXR1cm4gYmFzZUluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXggfHwgMCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5kZXhPZjtcbiIsIi8qKlxuICogR2V0cyB0aGUgbGFzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBBcnJheVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmxhc3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IDNcbiAqL1xuZnVuY3Rpb24gbGFzdChhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwO1xuICByZXR1cm4gbGVuZ3RoID8gYXJyYXlbbGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbGFzdDtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4uL2ludGVybmFsL0xhenlXcmFwcGVyJyksXG4gICAgTG9kYXNoV3JhcHBlciA9IHJlcXVpcmUoJy4uL2ludGVybmFsL0xvZGFzaFdyYXBwZXInKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUxvZGFzaCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICB3cmFwcGVyQ2xvbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC93cmFwcGVyQ2xvbmUnKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGBsb2Rhc2hgIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBpbXBsaWNpdCBjaGFpbmluZy5cbiAqIE1ldGhvZHMgdGhhdCBvcGVyYXRlIG9uIGFuZCByZXR1cm4gYXJyYXlzLCBjb2xsZWN0aW9ucywgYW5kIGZ1bmN0aW9ucyBjYW5cbiAqIGJlIGNoYWluZWQgdG9nZXRoZXIuIE1ldGhvZHMgdGhhdCByZXRyaWV2ZSBhIHNpbmdsZSB2YWx1ZSBvciBtYXkgcmV0dXJuIGFcbiAqIHByaW1pdGl2ZSB2YWx1ZSB3aWxsIGF1dG9tYXRpY2FsbHkgZW5kIHRoZSBjaGFpbiByZXR1cm5pbmcgdGhlIHVud3JhcHBlZFxuICogdmFsdWUuIEV4cGxpY2l0IGNoYWluaW5nIG1heSBiZSBlbmFibGVkIHVzaW5nIGBfLmNoYWluYC4gVGhlIGV4ZWN1dGlvbiBvZlxuICogY2hhaW5lZCBtZXRob2RzIGlzIGxhenksIHRoYXQgaXMsIGV4ZWN1dGlvbiBpcyBkZWZlcnJlZCB1bnRpbCBgXyN2YWx1ZWBcbiAqIGlzIGltcGxpY2l0bHkgb3IgZXhwbGljaXRseSBjYWxsZWQuXG4gKlxuICogTGF6eSBldmFsdWF0aW9uIGFsbG93cyBzZXZlcmFsIG1ldGhvZHMgdG8gc3VwcG9ydCBzaG9ydGN1dCBmdXNpb24uIFNob3J0Y3V0XG4gKiBmdXNpb24gaXMgYW4gb3B0aW1pemF0aW9uIHN0cmF0ZWd5IHdoaWNoIG1lcmdlIGl0ZXJhdGVlIGNhbGxzOyB0aGlzIGNhbiBoZWxwXG4gKiB0byBhdm9pZCB0aGUgY3JlYXRpb24gb2YgaW50ZXJtZWRpYXRlIGRhdGEgc3RydWN0dXJlcyBhbmQgZ3JlYXRseSByZWR1Y2UgdGhlXG4gKiBudW1iZXIgb2YgaXRlcmF0ZWUgZXhlY3V0aW9ucy5cbiAqXG4gKiBDaGFpbmluZyBpcyBzdXBwb3J0ZWQgaW4gY3VzdG9tIGJ1aWxkcyBhcyBsb25nIGFzIHRoZSBgXyN2YWx1ZWAgbWV0aG9kIGlzXG4gKiBkaXJlY3RseSBvciBpbmRpcmVjdGx5IGluY2x1ZGVkIGluIHRoZSBidWlsZC5cbiAqXG4gKiBJbiBhZGRpdGlvbiB0byBsb2Rhc2ggbWV0aG9kcywgd3JhcHBlcnMgaGF2ZSBgQXJyYXlgIGFuZCBgU3RyaW5nYCBtZXRob2RzLlxuICpcbiAqIFRoZSB3cmFwcGVyIGBBcnJheWAgbWV0aG9kcyBhcmU6XG4gKiBgY29uY2F0YCwgYGpvaW5gLCBgcG9wYCwgYHB1c2hgLCBgcmV2ZXJzZWAsIGBzaGlmdGAsIGBzbGljZWAsIGBzb3J0YCxcbiAqIGBzcGxpY2VgLCBhbmQgYHVuc2hpZnRgXG4gKlxuICogVGhlIHdyYXBwZXIgYFN0cmluZ2AgbWV0aG9kcyBhcmU6XG4gKiBgcmVwbGFjZWAgYW5kIGBzcGxpdGBcbiAqXG4gKiBUaGUgd3JhcHBlciBtZXRob2RzIHRoYXQgc3VwcG9ydCBzaG9ydGN1dCBmdXNpb24gYXJlOlxuICogYGNvbXBhY3RgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZHJvcFJpZ2h0V2hpbGVgLCBgZHJvcFdoaWxlYCwgYGZpbHRlcmAsXG4gKiBgZmlyc3RgLCBgaW5pdGlhbGAsIGBsYXN0YCwgYG1hcGAsIGBwbHVja2AsIGByZWplY3RgLCBgcmVzdGAsIGByZXZlcnNlYCxcbiAqIGBzbGljZWAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBgdG9BcnJheWAsXG4gKiBhbmQgYHdoZXJlYFxuICpcbiAqIFRoZSBjaGFpbmFibGUgd3JhcHBlciBtZXRob2RzIGFyZTpcbiAqIGBhZnRlcmAsIGBhcnlgLCBgYXNzaWduYCwgYGF0YCwgYGJlZm9yZWAsIGBiaW5kYCwgYGJpbmRBbGxgLCBgYmluZEtleWAsXG4gKiBgY2FsbGJhY2tgLCBgY2hhaW5gLCBgY2h1bmtgLCBgY29tbWl0YCwgYGNvbXBhY3RgLCBgY29uY2F0YCwgYGNvbnN0YW50YCxcbiAqIGBjb3VudEJ5YCwgYGNyZWF0ZWAsIGBjdXJyeWAsIGBkZWJvdW5jZWAsIGBkZWZhdWx0c2AsIGBkZWZhdWx0c0RlZXBgLFxuICogYGRlZmVyYCwgYGRlbGF5YCwgYGRpZmZlcmVuY2VgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZHJvcFJpZ2h0V2hpbGVgLFxuICogYGRyb3BXaGlsZWAsIGBmaWxsYCwgYGZpbHRlcmAsIGBmbGF0dGVuYCwgYGZsYXR0ZW5EZWVwYCwgYGZsb3dgLCBgZmxvd1JpZ2h0YCxcbiAqIGBmb3JFYWNoYCwgYGZvckVhY2hSaWdodGAsIGBmb3JJbmAsIGBmb3JJblJpZ2h0YCwgYGZvck93bmAsIGBmb3JPd25SaWdodGAsXG4gKiBgZnVuY3Rpb25zYCwgYGdyb3VwQnlgLCBgaW5kZXhCeWAsIGBpbml0aWFsYCwgYGludGVyc2VjdGlvbmAsIGBpbnZlcnRgLFxuICogYGludm9rZWAsIGBrZXlzYCwgYGtleXNJbmAsIGBtYXBgLCBgbWFwS2V5c2AsIGBtYXBWYWx1ZXNgLCBgbWF0Y2hlc2AsXG4gKiBgbWF0Y2hlc1Byb3BlcnR5YCwgYG1lbW9pemVgLCBgbWVyZ2VgLCBgbWV0aG9kYCwgYG1ldGhvZE9mYCwgYG1peGluYCxcbiAqIGBtb2RBcmdzYCwgYG5lZ2F0ZWAsIGBvbWl0YCwgYG9uY2VgLCBgcGFpcnNgLCBgcGFydGlhbGAsIGBwYXJ0aWFsUmlnaHRgLFxuICogYHBhcnRpdGlvbmAsIGBwaWNrYCwgYHBsYW50YCwgYHBsdWNrYCwgYHByb3BlcnR5YCwgYHByb3BlcnR5T2ZgLCBgcHVsbGAsXG4gKiBgcHVsbEF0YCwgYHB1c2hgLCBgcmFuZ2VgLCBgcmVhcmdgLCBgcmVqZWN0YCwgYHJlbW92ZWAsIGByZXN0YCwgYHJlc3RQYXJhbWAsXG4gKiBgcmV2ZXJzZWAsIGBzZXRgLCBgc2h1ZmZsZWAsIGBzbGljZWAsIGBzb3J0YCwgYHNvcnRCeWAsIGBzb3J0QnlBbGxgLFxuICogYHNvcnRCeU9yZGVyYCwgYHNwbGljZWAsIGBzcHJlYWRgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGFrZVJpZ2h0V2hpbGVgLFxuICogYHRha2VXaGlsZWAsIGB0YXBgLCBgdGhyb3R0bGVgLCBgdGhydWAsIGB0aW1lc2AsIGB0b0FycmF5YCwgYHRvUGxhaW5PYmplY3RgLFxuICogYHRyYW5zZm9ybWAsIGB1bmlvbmAsIGB1bmlxYCwgYHVuc2hpZnRgLCBgdW56aXBgLCBgdW56aXBXaXRoYCwgYHZhbHVlc2AsXG4gKiBgdmFsdWVzSW5gLCBgd2hlcmVgLCBgd2l0aG91dGAsIGB3cmFwYCwgYHhvcmAsIGB6aXBgLCBgemlwT2JqZWN0YCwgYHppcFdpdGhgXG4gKlxuICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IGFyZSAqKm5vdCoqIGNoYWluYWJsZSBieSBkZWZhdWx0IGFyZTpcbiAqIGBhZGRgLCBgYXR0ZW1wdGAsIGBjYW1lbENhc2VgLCBgY2FwaXRhbGl6ZWAsIGBjZWlsYCwgYGNsb25lYCwgYGNsb25lRGVlcGAsXG4gKiBgZGVidXJyYCwgYGVuZHNXaXRoYCwgYGVzY2FwZWAsIGBlc2NhcGVSZWdFeHBgLCBgZXZlcnlgLCBgZmluZGAsIGBmaW5kSW5kZXhgLFxuICogYGZpbmRLZXlgLCBgZmluZExhc3RgLCBgZmluZExhc3RJbmRleGAsIGBmaW5kTGFzdEtleWAsIGBmaW5kV2hlcmVgLCBgZmlyc3RgLFxuICogYGZsb29yYCwgYGdldGAsIGBndGAsIGBndGVgLCBgaGFzYCwgYGlkZW50aXR5YCwgYGluY2x1ZGVzYCwgYGluZGV4T2ZgLFxuICogYGluUmFuZ2VgLCBgaXNBcmd1bWVudHNgLCBgaXNBcnJheWAsIGBpc0Jvb2xlYW5gLCBgaXNEYXRlYCwgYGlzRWxlbWVudGAsXG4gKiBgaXNFbXB0eWAsIGBpc0VxdWFsYCwgYGlzRXJyb3JgLCBgaXNGaW5pdGVgIGBpc0Z1bmN0aW9uYCwgYGlzTWF0Y2hgLFxuICogYGlzTmF0aXZlYCwgYGlzTmFOYCwgYGlzTnVsbGAsIGBpc051bWJlcmAsIGBpc09iamVjdGAsIGBpc1BsYWluT2JqZWN0YCxcbiAqIGBpc1JlZ0V4cGAsIGBpc1N0cmluZ2AsIGBpc1VuZGVmaW5lZGAsIGBpc1R5cGVkQXJyYXlgLCBgam9pbmAsIGBrZWJhYkNhc2VgLFxuICogYGxhc3RgLCBgbGFzdEluZGV4T2ZgLCBgbHRgLCBgbHRlYCwgYG1heGAsIGBtaW5gLCBgbm9Db25mbGljdGAsIGBub29wYCxcbiAqIGBub3dgLCBgcGFkYCwgYHBhZExlZnRgLCBgcGFkUmlnaHRgLCBgcGFyc2VJbnRgLCBgcG9wYCwgYHJhbmRvbWAsIGByZWR1Y2VgLFxuICogYHJlZHVjZVJpZ2h0YCwgYHJlcGVhdGAsIGByZXN1bHRgLCBgcm91bmRgLCBgcnVuSW5Db250ZXh0YCwgYHNoaWZ0YCwgYHNpemVgLFxuICogYHNuYWtlQ2FzZWAsIGBzb21lYCwgYHNvcnRlZEluZGV4YCwgYHNvcnRlZExhc3RJbmRleGAsIGBzdGFydENhc2VgLFxuICogYHN0YXJ0c1dpdGhgLCBgc3VtYCwgYHRlbXBsYXRlYCwgYHRyaW1gLCBgdHJpbUxlZnRgLCBgdHJpbVJpZ2h0YCwgYHRydW5jYCxcbiAqIGB1bmVzY2FwZWAsIGB1bmlxdWVJZGAsIGB2YWx1ZWAsIGFuZCBgd29yZHNgXG4gKlxuICogVGhlIHdyYXBwZXIgbWV0aG9kIGBzYW1wbGVgIHdpbGwgcmV0dXJuIGEgd3JhcHBlZCB2YWx1ZSB3aGVuIGBuYCBpcyBwcm92aWRlZCxcbiAqIG90aGVyd2lzZSBhbiB1bndyYXBwZWQgdmFsdWUgaXMgcmV0dXJuZWQuXG4gKlxuICogQG5hbWUgX1xuICogQGNvbnN0cnVjdG9yXG4gKiBAY2F0ZWdvcnkgQ2hhaW5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAgaW4gYSBgbG9kYXNoYCBpbnN0YW5jZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgd3JhcHBlZCA9IF8oWzEsIDIsIDNdKTtcbiAqXG4gKiAvLyByZXR1cm5zIGFuIHVud3JhcHBlZCB2YWx1ZVxuICogd3JhcHBlZC5yZWR1Y2UoZnVuY3Rpb24odG90YWwsIG4pIHtcbiAqICAgcmV0dXJuIHRvdGFsICsgbjtcbiAqIH0pO1xuICogLy8gPT4gNlxuICpcbiAqIC8vIHJldHVybnMgYSB3cmFwcGVkIHZhbHVlXG4gKiB2YXIgc3F1YXJlcyA9IHdyYXBwZWQubWFwKGZ1bmN0aW9uKG4pIHtcbiAqICAgcmV0dXJuIG4gKiBuO1xuICogfSk7XG4gKlxuICogXy5pc0FycmF5KHNxdWFyZXMpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoc3F1YXJlcy52YWx1ZSgpKTtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gbG9kYXNoKHZhbHVlKSB7XG4gIGlmIChpc09iamVjdExpa2UodmFsdWUpICYmICFpc0FycmF5KHZhbHVlKSAmJiAhKHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpKSB7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTG9kYXNoV3JhcHBlcikge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ19fY2hhaW5fXycpICYmIGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdfX3dyYXBwZWRfXycpKSB7XG4gICAgICByZXR1cm4gd3JhcHBlckNsb25lKHZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5ldyBMb2Rhc2hXcmFwcGVyKHZhbHVlKTtcbn1cblxuLy8gRW5zdXJlIHdyYXBwZXJzIGFyZSBpbnN0YW5jZXMgb2YgYGJhc2VMb2Rhc2hgLlxubG9kYXNoLnByb3RvdHlwZSA9IGJhc2VMb2Rhc2gucHJvdG90eXBlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGxvZGFzaDtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9mb3JFYWNoJyk7XG4iLCJ2YXIgYmFzZUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRWFjaCcpLFxuICAgIGNyZWF0ZUZpbmQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVGaW5kJyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAsIHJldHVybmluZyB0aGUgZmlyc3QgZWxlbWVudFxuICogYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmRcbiAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAqXG4gKiBJZiBhIHByb3BlcnR5IG5hbWUgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1hdGNoaW5nIHByb3BlcnR5XG4gKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICpcbiAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYHByZWRpY2F0ZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGFsaWFzIGRldGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzZWFyY2guXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAqICBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBwcmVkaWNhdGVgLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1hdGNoZWQgZWxlbWVudCwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHVzZXJzID0gW1xuICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IHRydWUgfVxuICogXTtcbiAqXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsIGZ1bmN0aW9uKGNocikge1xuICogICByZXR1cm4gY2hyLmFnZSA8IDQwO1xuICogfSksICd1c2VyJyk7XG4gKiAvLyA9PiAnYmFybmV5J1xuICpcbiAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzYCBjYWxsYmFjayBzaG9ydGhhbmRcbiAqIF8ucmVzdWx0KF8uZmluZCh1c2VycywgeyAnYWdlJzogMSwgJ2FjdGl2ZSc6IHRydWUgfSksICd1c2VyJyk7XG4gKiAvLyA9PiAncGViYmxlcydcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAqIF8ucmVzdWx0KF8uZmluZCh1c2VycywgJ2FjdGl2ZScsIGZhbHNlKSwgJ3VzZXInKTtcbiAqIC8vID0+ICdmcmVkJ1xuICpcbiAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsICdhY3RpdmUnKSwgJ3VzZXInKTtcbiAqIC8vID0+ICdiYXJuZXknXG4gKi9cbnZhciBmaW5kID0gY3JlYXRlRmluZChiYXNlRWFjaCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZmluZDtcbiIsInZhciBhcnJheUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9hcnJheUVhY2gnKSxcbiAgICBiYXNlRWFjaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VFYWNoJyksXG4gICAgY3JlYXRlRm9yRWFjaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2NyZWF0ZUZvckVhY2gnKTtcblxuLyoqXG4gKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCBpbnZva2luZyBgaXRlcmF0ZWVgIGZvciBlYWNoIGVsZW1lbnQuXG4gKiBUaGUgYGl0ZXJhdGVlYCBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6XG4gKiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHlcbiAqIGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogKipOb3RlOioqIEFzIHdpdGggb3RoZXIgXCJDb2xsZWN0aW9uc1wiIG1ldGhvZHMsIG9iamVjdHMgd2l0aCBhIFwibGVuZ3RoXCIgcHJvcGVydHlcbiAqIGFyZSBpdGVyYXRlZCBsaWtlIGFycmF5cy4gVG8gYXZvaWQgdGhpcyBiZWhhdmlvciBgXy5mb3JJbmAgb3IgYF8uZm9yT3duYFxuICogbWF5IGJlIHVzZWQgZm9yIG9iamVjdCBpdGVyYXRpb24uXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBlYWNoXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fHN0cmluZ30gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8oWzEsIDJdKS5mb3JFYWNoKGZ1bmN0aW9uKG4pIHtcbiAqICAgY29uc29sZS5sb2cobik7XG4gKiB9KS52YWx1ZSgpO1xuICogLy8gPT4gbG9ncyBlYWNoIHZhbHVlIGZyb20gbGVmdCB0byByaWdodCBhbmQgcmV0dXJucyB0aGUgYXJyYXlcbiAqXG4gKiBfLmZvckVhY2goeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbihuLCBrZXkpIHtcbiAqICAgY29uc29sZS5sb2cobiwga2V5KTtcbiAqIH0pO1xuICogLy8gPT4gbG9ncyBlYWNoIHZhbHVlLWtleSBwYWlyIGFuZCByZXR1cm5zIHRoZSBvYmplY3QgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqL1xudmFyIGZvckVhY2ggPSBjcmVhdGVGb3JFYWNoKGFycmF5RWFjaCwgYmFzZUVhY2gpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZvckVhY2g7XG4iLCJ2YXIgYmFzZUluZGV4T2YgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlSW5kZXhPZicpLFxuICAgIGdldExlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldExlbmd0aCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0l0ZXJhdGVlQ2FsbCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzSXRlcmF0ZWVDYWxsJyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0xlbmd0aCcpLFxuICAgIGlzU3RyaW5nID0gcmVxdWlyZSgnLi4vbGFuZy9pc1N0cmluZycpLFxuICAgIHZhbHVlcyA9IHJlcXVpcmUoJy4uL29iamVjdC92YWx1ZXMnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHRhcmdldGAgaXMgaW4gYGNvbGxlY3Rpb25gIHVzaW5nXG4gKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLiBJZiBgZnJvbUluZGV4YCBpcyBuZWdhdGl2ZSwgaXQncyB1c2VkIGFzIHRoZSBvZmZzZXRcbiAqIGZyb20gdGhlIGVuZCBvZiBgY29sbGVjdGlvbmAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBjb250YWlucywgaW5jbHVkZVxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHRhcmdldCBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhIGNhbGxiYWNrIGZvciBmdW5jdGlvbnMgbGlrZSBgXy5yZWR1Y2VgLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGEgbWF0Y2hpbmcgZWxlbWVudCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmluY2x1ZGVzKFsxLCAyLCAzXSwgMSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEsIDIpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmluY2x1ZGVzKHsgJ3VzZXInOiAnZnJlZCcsICdhZ2UnOiA0MCB9LCAnZnJlZCcpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaW5jbHVkZXMoJ3BlYmJsZXMnLCAnZWInKTtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaW5jbHVkZXMoY29sbGVjdGlvbiwgdGFyZ2V0LCBmcm9tSW5kZXgsIGd1YXJkKSB7XG4gIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uID8gZ2V0TGVuZ3RoKGNvbGxlY3Rpb24pIDogMDtcbiAgaWYgKCFpc0xlbmd0aChsZW5ndGgpKSB7XG4gICAgY29sbGVjdGlvbiA9IHZhbHVlcyhjb2xsZWN0aW9uKTtcbiAgICBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aDtcbiAgfVxuICBpZiAodHlwZW9mIGZyb21JbmRleCAhPSAnbnVtYmVyJyB8fCAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwodGFyZ2V0LCBmcm9tSW5kZXgsIGd1YXJkKSkpIHtcbiAgICBmcm9tSW5kZXggPSAwO1xuICB9IGVsc2Uge1xuICAgIGZyb21JbmRleCA9IGZyb21JbmRleCA8IDAgPyBuYXRpdmVNYXgobGVuZ3RoICsgZnJvbUluZGV4LCAwKSA6IChmcm9tSW5kZXggfHwgMCk7XG4gIH1cbiAgcmV0dXJuICh0eXBlb2YgY29sbGVjdGlvbiA9PSAnc3RyaW5nJyB8fCAhaXNBcnJheShjb2xsZWN0aW9uKSAmJiBpc1N0cmluZyhjb2xsZWN0aW9uKSlcbiAgICA/IChmcm9tSW5kZXggPD0gbGVuZ3RoICYmIGNvbGxlY3Rpb24uaW5kZXhPZih0YXJnZXQsIGZyb21JbmRleCkgPiAtMSlcbiAgICA6ICghIWxlbmd0aCAmJiBiYXNlSW5kZXhPZihjb2xsZWN0aW9uLCB0YXJnZXQsIGZyb21JbmRleCkgPiAtMSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5jbHVkZXM7XG4iLCJ2YXIgYXJyYXlNYXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9hcnJheU1hcCcpLFxuICAgIGJhc2VDYWxsYmFjayA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VDYWxsYmFjaycpLFxuICAgIGJhc2VNYXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlTWFwJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdmFsdWVzIGJ5IHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCB0aHJvdWdoXG4gKiBgaXRlcmF0ZWVgLiBUaGUgYGl0ZXJhdGVlYCBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZVxuICogYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gKlxuICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1hdGNoaW5nIHByb3BlcnR5XG4gKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICpcbiAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzYCBzdHlsZVxuICogY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgZ2l2ZW5cbiAqIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICpcbiAqIE1hbnkgbG9kYXNoIG1ldGhvZHMgYXJlIGd1YXJkZWQgdG8gd29yayBhcyBpdGVyYXRlZXMgZm9yIG1ldGhvZHMgbGlrZVxuICogYF8uZXZlcnlgLCBgXy5maWx0ZXJgLCBgXy5tYXBgLCBgXy5tYXBWYWx1ZXNgLCBgXy5yZWplY3RgLCBhbmQgYF8uc29tZWAuXG4gKlxuICogVGhlIGd1YXJkZWQgbWV0aG9kcyBhcmU6XG4gKiBgYXJ5YCwgYGNhbGxiYWNrYCwgYGNodW5rYCwgYGNsb25lYCwgYGNyZWF0ZWAsIGBjdXJyeWAsIGBjdXJyeVJpZ2h0YCxcbiAqIGBkcm9wYCwgYGRyb3BSaWdodGAsIGBldmVyeWAsIGBmaWxsYCwgYGZsYXR0ZW5gLCBgaW52ZXJ0YCwgYG1heGAsIGBtaW5gLFxuICogYHBhcnNlSW50YCwgYHNsaWNlYCwgYHNvcnRCeWAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0ZW1wbGF0ZWAsIGB0cmltYCxcbiAqIGB0cmltTGVmdGAsIGB0cmltUmlnaHRgLCBgdHJ1bmNgLCBgcmFuZG9tYCwgYHJhbmdlYCwgYHNhbXBsZWAsIGBzb21lYCxcbiAqIGBzdW1gLCBgdW5pcWAsIGFuZCBgd29yZHNgXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBjb2xsZWN0XG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fHN0cmluZ30gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gKiAgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiB0aW1lc1RocmVlKG4pIHtcbiAqICAgcmV0dXJuIG4gKiAzO1xuICogfVxuICpcbiAqIF8ubWFwKFsxLCAyXSwgdGltZXNUaHJlZSk7XG4gKiAvLyA9PiBbMywgNl1cbiAqXG4gKiBfLm1hcCh7ICdhJzogMSwgJ2InOiAyIH0sIHRpbWVzVGhyZWUpO1xuICogLy8gPT4gWzMsIDZdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogdmFyIHVzZXJzID0gW1xuICogICB7ICd1c2VyJzogJ2Jhcm5leScgfSxcbiAqICAgeyAndXNlcic6ICdmcmVkJyB9XG4gKiBdO1xuICpcbiAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLm1hcCh1c2VycywgJ3VzZXInKTtcbiAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXVxuICovXG5mdW5jdGlvbiBtYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIHRoaXNBcmcpIHtcbiAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlNYXAgOiBiYXNlTWFwO1xuICBpdGVyYXRlZSA9IGJhc2VDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMyk7XG4gIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXA7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvZ2V0TmF0aXZlJyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTm93ID0gZ2V0TmF0aXZlKERhdGUsICdub3cnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRoYXQgaGF2ZSBlbGFwc2VkIHNpbmNlIHRoZSBVbml4IGVwb2NoXG4gKiAoMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IERhdGVcbiAqIEBleGFtcGxlXG4gKlxuICogXy5kZWZlcihmdW5jdGlvbihzdGFtcCkge1xuICogICBjb25zb2xlLmxvZyhfLm5vdygpIC0gc3RhbXApO1xuICogfSwgXy5ub3coKSk7XG4gKiAvLyA9PiBsb2dzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGl0IHRvb2sgZm9yIHRoZSBkZWZlcnJlZCBmdW5jdGlvbiB0byBiZSBpbnZva2VkXG4gKi9cbnZhciBub3cgPSBuYXRpdmVOb3cgfHwgZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbm93O1xuIiwidmFyIGNyZWF0ZVdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVXcmFwcGVyJyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9yZXBsYWNlSG9sZGVycycpLFxuICAgIHJlc3RQYXJhbSA9IHJlcXVpcmUoJy4vcmVzdFBhcmFtJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMSxcbiAgICBQQVJUSUFMX0ZMQUcgPSAzMjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiBgdGhpc0FyZ2BcbiAqIGFuZCBwcmVwZW5kcyBhbnkgYWRkaXRpb25hbCBgXy5iaW5kYCBhcmd1bWVudHMgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlXG4gKiBib3VuZCBmdW5jdGlvbi5cbiAqXG4gKiBUaGUgYF8uYmluZC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljIGJ1aWxkcyxcbiAqIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAqXG4gKiAqKk5vdGU6KiogVW5saWtlIG5hdGl2ZSBgRnVuY3Rpb24jYmluZGAgdGhpcyBtZXRob2QgZG9lcyBub3Qgc2V0IHRoZSBcImxlbmd0aFwiXG4gKiBwcm9wZXJ0eSBvZiBib3VuZCBmdW5jdGlvbnMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYmluZC5cbiAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHsuLi4qfSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIGdyZWV0ID0gZnVuY3Rpb24oZ3JlZXRpbmcsIHB1bmN0dWF0aW9uKSB7XG4gKiAgIHJldHVybiBncmVldGluZyArICcgJyArIHRoaXMudXNlciArIHB1bmN0dWF0aW9uO1xuICogfTtcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAndXNlcic6ICdmcmVkJyB9O1xuICpcbiAqIHZhciBib3VuZCA9IF8uYmluZChncmVldCwgb2JqZWN0LCAnaGknKTtcbiAqIGJvdW5kKCchJyk7XG4gKiAvLyA9PiAnaGkgZnJlZCEnXG4gKlxuICogLy8gdXNpbmcgcGxhY2Vob2xkZXJzXG4gKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgXywgJyEnKTtcbiAqIGJvdW5kKCdoaScpO1xuICogLy8gPT4gJ2hpIGZyZWQhJ1xuICovXG52YXIgYmluZCA9IHJlc3RQYXJhbShmdW5jdGlvbihmdW5jLCB0aGlzQXJnLCBwYXJ0aWFscykge1xuICB2YXIgYml0bWFzayA9IEJJTkRfRkxBRztcbiAgaWYgKHBhcnRpYWxzLmxlbmd0aCkge1xuICAgIHZhciBob2xkZXJzID0gcmVwbGFjZUhvbGRlcnMocGFydGlhbHMsIGJpbmQucGxhY2Vob2xkZXIpO1xuICAgIGJpdG1hc2sgfD0gUEFSVElBTF9GTEFHO1xuICB9XG4gIHJldHVybiBjcmVhdGVXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzKTtcbn0pO1xuXG4vLyBBc3NpZ24gZGVmYXVsdCBwbGFjZWhvbGRlcnMuXG5iaW5kLnBsYWNlaG9sZGVyID0ge307XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZDtcbiIsIi8qKiBVc2VkIGFzIHRoZSBgVHlwZUVycm9yYCBtZXNzYWdlIGZvciBcIkZ1bmN0aW9uc1wiIG1ldGhvZHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIHRoZVxuICogY3JlYXRlZCBmdW5jdGlvbiBhbmQgYXJndW1lbnRzIGZyb20gYHN0YXJ0YCBhbmQgYmV5b25kIHByb3ZpZGVkIGFzIGFuIGFycmF5LlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvbiB0aGUgW3Jlc3QgcGFyYW1ldGVyXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvRnVuY3Rpb25zL3Jlc3RfcGFyYW1ldGVycykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgYSByZXN0IHBhcmFtZXRlciB0by5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgc2F5ID0gXy5yZXN0UGFyYW0oZnVuY3Rpb24od2hhdCwgbmFtZXMpIHtcbiAqICAgcmV0dXJuIHdoYXQgKyAnICcgKyBfLmluaXRpYWwobmFtZXMpLmpvaW4oJywgJykgK1xuICogICAgIChfLnNpemUobmFtZXMpID4gMSA/ICcsICYgJyA6ICcnKSArIF8ubGFzdChuYW1lcyk7XG4gKiB9KTtcbiAqXG4gKiBzYXkoJ2hlbGxvJywgJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnKTtcbiAqIC8vID0+ICdoZWxsbyBmcmVkLCBiYXJuZXksICYgcGViYmxlcydcbiAqL1xuZnVuY3Rpb24gcmVzdFBhcmFtKGZ1bmMsIHN0YXJ0KSB7XG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHN0YXJ0ID0gbmF0aXZlTWF4KHN0YXJ0ID09PSB1bmRlZmluZWQgPyAoZnVuYy5sZW5ndGggLSAxKSA6ICgrc3RhcnQgfHwgMCksIDApO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIHN0YXJ0LCAwKSxcbiAgICAgICAgcmVzdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdFtpbmRleF0gPSBhcmdzW3N0YXJ0ICsgaW5kZXhdO1xuICAgIH1cbiAgICBzd2l0Y2ggKHN0YXJ0KSB7XG4gICAgICBjYXNlIDA6IHJldHVybiBmdW5jLmNhbGwodGhpcywgcmVzdCk7XG4gICAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgcmVzdCk7XG4gICAgICBjYXNlIDI6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgYXJnc1sxXSwgcmVzdCk7XG4gICAgfVxuICAgIHZhciBvdGhlckFyZ3MgPSBBcnJheShzdGFydCArIDEpO1xuICAgIGluZGV4ID0gLTE7XG4gICAgd2hpbGUgKCsraW5kZXggPCBzdGFydCkge1xuICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgIH1cbiAgICBvdGhlckFyZ3Nbc3RhcnRdID0gcmVzdDtcbiAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBvdGhlckFyZ3MpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlc3RQYXJhbTtcbiIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9iYXNlQ3JlYXRlJyksXG4gICAgYmFzZUxvZGFzaCA9IHJlcXVpcmUoJy4vYmFzZUxvZGFzaCcpO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciBgLUluZmluaXR5YCBhbmQgYEluZmluaXR5YC4gKi9cbnZhciBQT1NJVElWRV9JTkZJTklUWSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbGF6eSB3cmFwcGVyIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBsYXp5IGV2YWx1YXRpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gKi9cbmZ1bmN0aW9uIExhenlXcmFwcGVyKHZhbHVlKSB7XG4gIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgdGhpcy5fX2FjdGlvbnNfXyA9IFtdO1xuICB0aGlzLl9fZGlyX18gPSAxO1xuICB0aGlzLl9fZmlsdGVyZWRfXyA9IGZhbHNlO1xuICB0aGlzLl9faXRlcmF0ZWVzX18gPSBbXTtcbiAgdGhpcy5fX3Rha2VDb3VudF9fID0gUE9TSVRJVkVfSU5GSU5JVFk7XG4gIHRoaXMuX192aWV3c19fID0gW107XG59XG5cbkxhenlXcmFwcGVyLnByb3RvdHlwZSA9IGJhc2VDcmVhdGUoYmFzZUxvZGFzaC5wcm90b3R5cGUpO1xuTGF6eVdyYXBwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTGF6eVdyYXBwZXI7XG5cbm1vZHVsZS5leHBvcnRzID0gTGF6eVdyYXBwZXI7XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vYmFzZUNyZWF0ZScpLFxuICAgIGJhc2VMb2Rhc2ggPSByZXF1aXJlKCcuL2Jhc2VMb2Rhc2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBjb25zdHJ1Y3RvciBmb3IgY3JlYXRpbmcgYGxvZGFzaGAgd3JhcHBlciBvYmplY3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICogQHBhcmFtIHtib29sZWFufSBbY2hhaW5BbGxdIEVuYWJsZSBjaGFpbmluZyBmb3IgYWxsIHdyYXBwZXIgbWV0aG9kcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthY3Rpb25zPVtdXSBBY3Rpb25zIHRvIHBlZm9ybSB0byByZXNvbHZlIHRoZSB1bndyYXBwZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIExvZGFzaFdyYXBwZXIodmFsdWUsIGNoYWluQWxsLCBhY3Rpb25zKSB7XG4gIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgdGhpcy5fX2FjdGlvbnNfXyA9IGFjdGlvbnMgfHwgW107XG4gIHRoaXMuX19jaGFpbl9fID0gISFjaGFpbkFsbDtcbn1cblxuTG9kYXNoV3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbkxvZGFzaFdyYXBwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTG9kYXNoV3JhcHBlcjtcblxubW9kdWxlLmV4cG9ydHMgPSBMb2Rhc2hXcmFwcGVyO1xuIiwiLyoqXG4gKiBDb3BpZXMgdGhlIHZhbHVlcyBvZiBgc291cmNlYCB0byBgYXJyYXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBzb3VyY2UgVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIGZyb20uXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXk9W11dIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyB0by5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiBhcnJheUNvcHkoc291cmNlLCBhcnJheSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG5cbiAgYXJyYXkgfHwgKGFycmF5ID0gQXJyYXkobGVuZ3RoKSk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgYXJyYXlbaW5kZXhdID0gc291cmNlW2luZGV4XTtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlDb3B5O1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlFYWNoKGFycmF5LCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5RWFjaDtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLm1hcGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGFycmF5TWFwKGFycmF5LCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlNYXA7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zb21lYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2tcbiAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gKiAgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBhcnJheVNvbWUoYXJyYXksIHByZWRpY2F0ZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5U29tZTtcbiIsInZhciBiYXNlQ29weSA9IHJlcXVpcmUoJy4vYmFzZUNvcHknKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hc3NpZ25gIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXJndW1lbnQganVnZ2xpbmcsXG4gKiBtdWx0aXBsZSBzb3VyY2VzLCBhbmQgYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VBc3NpZ24ob2JqZWN0LCBzb3VyY2UpIHtcbiAgcmV0dXJuIHNvdXJjZSA9PSBudWxsXG4gICAgPyBvYmplY3RcbiAgICA6IGJhc2VDb3B5KHNvdXJjZSwga2V5cyhzb3VyY2UpLCBvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VBc3NpZ247XG4iLCJ2YXIgYmFzZU1hdGNoZXMgPSByZXF1aXJlKCcuL2Jhc2VNYXRjaGVzJyksXG4gICAgYmFzZU1hdGNoZXNQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vYmFzZU1hdGNoZXNQcm9wZXJ0eScpLFxuICAgIGJpbmRDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmluZENhbGxiYWNrJyksXG4gICAgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5JyksXG4gICAgcHJvcGVydHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L3Byb3BlcnR5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY2FsbGJhY2tgIHdoaWNoIHN1cHBvcnRzIHNwZWNpZnlpbmcgdGhlXG4gKiBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IFtmdW5jPV8uaWRlbnRpdHldIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGEgY2FsbGJhY2suXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcmdDb3VudF0gVGhlIG51bWJlciBvZiBhcmd1bWVudHMgdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGNhbGxiYWNrLlxuICovXG5mdW5jdGlvbiBiYXNlQ2FsbGJhY2soZnVuYywgdGhpc0FyZywgYXJnQ291bnQpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgZnVuYztcbiAgaWYgKHR5cGUgPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB0aGlzQXJnID09PSB1bmRlZmluZWRcbiAgICAgID8gZnVuY1xuICAgICAgOiBiaW5kQ2FsbGJhY2soZnVuYywgdGhpc0FyZywgYXJnQ291bnQpO1xuICB9XG4gIGlmIChmdW5jID09IG51bGwpIHtcbiAgICByZXR1cm4gaWRlbnRpdHk7XG4gIH1cbiAgaWYgKHR5cGUgPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gYmFzZU1hdGNoZXMoZnVuYyk7XG4gIH1cbiAgcmV0dXJuIHRoaXNBcmcgPT09IHVuZGVmaW5lZFxuICAgID8gcHJvcGVydHkoZnVuYylcbiAgICA6IGJhc2VNYXRjaGVzUHJvcGVydHkoZnVuYywgdGhpc0FyZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNhbGxiYWNrO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi9hcnJheUVhY2gnKSxcbiAgICBiYXNlQXNzaWduID0gcmVxdWlyZSgnLi9iYXNlQXNzaWduJyksXG4gICAgYmFzZUZvck93biA9IHJlcXVpcmUoJy4vYmFzZUZvck93bicpLFxuICAgIGluaXRDbG9uZUFycmF5ID0gcmVxdWlyZSgnLi9pbml0Q2xvbmVBcnJheScpLFxuICAgIGluaXRDbG9uZUJ5VGFnID0gcmVxdWlyZSgnLi9pbml0Q2xvbmVCeVRhZycpLFxuICAgIGluaXRDbG9uZU9iamVjdCA9IHJlcXVpcmUoJy4vaW5pdENsb25lT2JqZWN0JyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzSG9zdE9iamVjdCA9IHJlcXVpcmUoJy4vaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgc3VwcG9ydGVkIGJ5IGBfLmNsb25lYC4gKi9cbnZhciBjbG9uZWFibGVUYWdzID0ge307XG5jbG9uZWFibGVUYWdzW2FyZ3NUYWddID0gY2xvbmVhYmxlVGFnc1thcnJheVRhZ10gPVxuY2xvbmVhYmxlVGFnc1thcnJheUJ1ZmZlclRhZ10gPSBjbG9uZWFibGVUYWdzW2Jvb2xUYWddID1cbmNsb25lYWJsZVRhZ3NbZGF0ZVRhZ10gPSBjbG9uZWFibGVUYWdzW2Zsb2F0MzJUYWddID1cbmNsb25lYWJsZVRhZ3NbZmxvYXQ2NFRhZ10gPSBjbG9uZWFibGVUYWdzW2ludDhUYWddID1cbmNsb25lYWJsZVRhZ3NbaW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQzMlRhZ10gPVxuY2xvbmVhYmxlVGFnc1tudW1iZXJUYWddID0gY2xvbmVhYmxlVGFnc1tvYmplY3RUYWddID1cbmNsb25lYWJsZVRhZ3NbcmVnZXhwVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc3RyaW5nVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQ4VGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQxNlRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xuY2xvbmVhYmxlVGFnc1tlcnJvclRhZ10gPSBjbG9uZWFibGVUYWdzW2Z1bmNUYWddID1cbmNsb25lYWJsZVRhZ3NbbWFwVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc2V0VGFnXSA9XG5jbG9uZWFibGVUYWdzW3dlYWtNYXBUYWddID0gZmFsc2U7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNsb25lYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nXG4gKiBhbmQgYHRoaXNgIGJpbmRpbmcgYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gW2tleV0gVGhlIGtleSBvZiBgdmFsdWVgLlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgYHZhbHVlYCBiZWxvbmdzIHRvLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQT1bXV0gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2Ugb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0I9W11dIEFzc29jaWF0ZXMgY2xvbmVzIHdpdGggc291cmNlIGNvdW50ZXJwYXJ0cy5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBjbG9uZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VDbG9uZSh2YWx1ZSwgaXNEZWVwLCBjdXN0b21pemVyLCBrZXksIG9iamVjdCwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIHJlc3VsdDtcbiAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICByZXN1bHQgPSBvYmplY3QgPyBjdXN0b21pemVyKHZhbHVlLCBrZXksIG9iamVjdCkgOiBjdXN0b21pemVyKHZhbHVlKTtcbiAgfVxuICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGlmICghaXNPYmplY3QodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHZhciBpc0FyciA9IGlzQXJyYXkodmFsdWUpO1xuICBpZiAoaXNBcnIpIHtcbiAgICByZXN1bHQgPSBpbml0Q2xvbmVBcnJheSh2YWx1ZSk7XG4gICAgaWYgKCFpc0RlZXApIHtcbiAgICAgIHJldHVybiBhcnJheUNvcHkodmFsdWUsIHJlc3VsdCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciB0YWcgPSBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSxcbiAgICAgICAgaXNGdW5jID0gdGFnID09IGZ1bmNUYWc7XG5cbiAgICBpZiAodGFnID09IG9iamVjdFRhZyB8fCB0YWcgPT0gYXJnc1RhZyB8fCAoaXNGdW5jICYmICFvYmplY3QpKSB7XG4gICAgICBpZiAoaXNIb3N0T2JqZWN0KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gb2JqZWN0ID8gdmFsdWUgOiB7fTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdCA9IGluaXRDbG9uZU9iamVjdChpc0Z1bmMgPyB7fSA6IHZhbHVlKTtcbiAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgIHJldHVybiBiYXNlQXNzaWduKHJlc3VsdCwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY2xvbmVhYmxlVGFnc1t0YWddXG4gICAgICAgID8gaW5pdENsb25lQnlUYWcodmFsdWUsIHRhZywgaXNEZWVwKVxuICAgICAgICA6IChvYmplY3QgPyB2YWx1ZSA6IHt9KTtcbiAgICB9XG4gIH1cbiAgLy8gQ2hlY2sgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgYW5kIHJldHVybiBpdHMgY29ycmVzcG9uZGluZyBjbG9uZS5cbiAgc3RhY2tBIHx8IChzdGFja0EgPSBbXSk7XG4gIHN0YWNrQiB8fCAoc3RhY2tCID0gW10pO1xuXG4gIHZhciBsZW5ndGggPSBzdGFja0EubGVuZ3RoO1xuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICBpZiAoc3RhY2tBW2xlbmd0aF0gPT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiBzdGFja0JbbGVuZ3RoXTtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIHRoZSBzb3VyY2UgdmFsdWUgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzIGFuZCBhc3NvY2lhdGUgaXQgd2l0aCBpdHMgY2xvbmUuXG4gIHN0YWNrQS5wdXNoKHZhbHVlKTtcbiAgc3RhY2tCLnB1c2gocmVzdWx0KTtcblxuICAvLyBSZWN1cnNpdmVseSBwb3B1bGF0ZSBjbG9uZSAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAoaXNBcnIgPyBhcnJheUVhY2ggOiBiYXNlRm9yT3duKSh2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgIHJlc3VsdFtrZXldID0gYmFzZUNsb25lKHN1YlZhbHVlLCBpc0RlZXAsIGN1c3RvbWl6ZXIsIGtleSwgdmFsdWUsIHN0YWNrQSwgc3RhY2tCKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNsb25lO1xuIiwiLyoqXG4gKiBDb3BpZXMgcHJvcGVydGllcyBvZiBgc291cmNlYCB0byBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyBmcm9tLlxuICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGNvcHkuXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgdG8uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQ29weShzb3VyY2UsIHByb3BzLCBvYmplY3QpIHtcbiAgb2JqZWN0IHx8IChvYmplY3QgPSB7fSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgIG9iamVjdFtrZXldID0gc291cmNlW2tleV07XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ29weTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jcmVhdGVgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXNzaWduaW5nXG4gKiBwcm9wZXJ0aWVzIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHByb3RvdHlwZSBUaGUgb2JqZWN0IHRvIGluaGVyaXQgZnJvbS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gKi9cbnZhciBiYXNlQ3JlYXRlID0gKGZ1bmN0aW9uKCkge1xuICBmdW5jdGlvbiBvYmplY3QoKSB7fVxuICByZXR1cm4gZnVuY3Rpb24ocHJvdG90eXBlKSB7XG4gICAgaWYgKGlzT2JqZWN0KHByb3RvdHlwZSkpIHtcbiAgICAgIG9iamVjdC5wcm90b3R5cGUgPSBwcm90b3R5cGU7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IG9iamVjdDtcbiAgICAgIG9iamVjdC5wcm90b3R5cGUgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQgfHwge307XG4gIH07XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDcmVhdGU7XG4iLCJ2YXIgYmFzZUZvck93biA9IHJlcXVpcmUoJy4vYmFzZUZvck93bicpLFxuICAgIGNyZWF0ZUJhc2VFYWNoID0gcmVxdWlyZSgnLi9jcmVhdGVCYXNlRWFjaCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckVhY2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2tcbiAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R8c3RyaW5nfSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAqL1xudmFyIGJhc2VFYWNoID0gY3JlYXRlQmFzZUVhY2goYmFzZUZvck93bik7XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUVhY2g7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbmRgLCBgXy5maW5kTGFzdGAsIGBfLmZpbmRLZXlgLCBhbmQgYF8uZmluZExhc3RLZXlgLFxuICogd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFjayBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZywgd2hpY2ggaXRlcmF0ZXNcbiAqIG92ZXIgYGNvbGxlY3Rpb25gIHVzaW5nIHRoZSBwcm92aWRlZCBgZWFjaEZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGBjb2xsZWN0aW9uYC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldEtleV0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGtleSBvZiB0aGUgZm91bmQgZWxlbWVudFxuICogIGluc3RlYWQgb2YgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZvdW5kIGVsZW1lbnQgb3IgaXRzIGtleSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZpbmQoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBlYWNoRnVuYywgcmV0S2V5KSB7XG4gIHZhciByZXN1bHQ7XG4gIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pKSB7XG4gICAgICByZXN1bHQgPSByZXRLZXkgPyBrZXkgOiB2YWx1ZTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGaW5kO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kSW5kZXhgIGFuZCBgXy5maW5kTGFzdEluZGV4YCB3aXRob3V0XG4gKiBzdXBwb3J0IGZvciBjYWxsYmFjayBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlRmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21SaWdodCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMTtcblxuICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRmluZEluZGV4O1xuIiwidmFyIGNyZWF0ZUJhc2VGb3IgPSByZXF1aXJlKCcuL2NyZWF0ZUJhc2VGb3InKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgYmFzZUZvckluYCBhbmQgYGJhc2VGb3JPd25gIHdoaWNoIGl0ZXJhdGVzXG4gKiBvdmVyIGBvYmplY3RgIHByb3BlcnRpZXMgcmV0dXJuZWQgYnkgYGtleXNGdW5jYCBpbnZva2luZyBgaXRlcmF0ZWVgIGZvclxuICogZWFjaCBwcm9wZXJ0eS4gSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5XG4gKiByZXR1cm5pbmcgYGZhbHNlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xudmFyIGJhc2VGb3IgPSBjcmVhdGVCYXNlRm9yKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZvcjtcbiIsInZhciBiYXNlRm9yID0gcmVxdWlyZSgnLi9iYXNlRm9yJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXNJbicpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckluYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlRm9ySW4ob2JqZWN0LCBpdGVyYXRlZSkge1xuICByZXR1cm4gYmFzZUZvcihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzSW4pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3JJbjtcbiIsInZhciBiYXNlRm9yID0gcmVxdWlyZSgnLi9iYXNlRm9yJyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlRm9yT3duKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgcmV0dXJuIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5cyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZvck93bjtcbiIsInZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgZ2V0YCB3aXRob3V0IHN1cHBvcnQgZm9yIHN0cmluZyBwYXRoc1xuICogYW5kIGRlZmF1bHQgdmFsdWVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0FycmF5fSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3BhdGhLZXldIFRoZSBrZXkgcmVwcmVzZW50YXRpb24gb2YgcGF0aC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gYmFzZUdldChvYmplY3QsIHBhdGgsIHBhdGhLZXkpIHtcbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIG9iamVjdCA9IHRvT2JqZWN0KG9iamVjdCk7XG4gIGlmIChwYXRoS2V5ICE9PSB1bmRlZmluZWQgJiYgcGF0aEtleSBpbiBvYmplY3QpIHtcbiAgICBwYXRoID0gW3BhdGhLZXldO1xuICB9XG4gIHZhciBpbmRleCA9IDAsXG4gICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aDtcblxuICB3aGlsZSAob2JqZWN0ICE9IG51bGwgJiYgaW5kZXggPCBsZW5ndGgpIHtcbiAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpW3BhdGhbaW5kZXgrK11dO1xuICB9XG4gIHJldHVybiAoaW5kZXggJiYgaW5kZXggPT0gbGVuZ3RoKSA/IG9iamVjdCA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlR2V0O1xuIiwidmFyIGluZGV4T2ZOYU4gPSByZXF1aXJlKCcuL2luZGV4T2ZOYU4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pbmRleE9mYCB3aXRob3V0IHN1cHBvcnQgZm9yIGJpbmFyeSBzZWFyY2hlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gIGlmICh2YWx1ZSAhPT0gdmFsdWUpIHtcbiAgICByZXR1cm4gaW5kZXhPZk5hTihhcnJheSwgZnJvbUluZGV4KTtcbiAgfVxuICB2YXIgaW5kZXggPSBmcm9tSW5kZXggLSAxLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKGFycmF5W2luZGV4XSA9PT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJbmRleE9mO1xuIiwidmFyIGJhc2VJc0VxdWFsRGVlcCA9IHJlcXVpcmUoJy4vYmFzZUlzRXF1YWxEZWVwJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aXRob3V0IHN1cHBvcnQgZm9yIGB0aGlzYCBiaW5kaW5nXG4gKiBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0FdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQl0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNFcXVhbCh2YWx1ZSwgb3RoZXIsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIGlmICh2YWx1ZSA9PT0gb3RoZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAodmFsdWUgPT0gbnVsbCB8fCBvdGhlciA9PSBudWxsIHx8ICghaXNPYmplY3QodmFsdWUpICYmICFpc09iamVjdExpa2Uob3RoZXIpKSkge1xuICAgIHJldHVybiB2YWx1ZSAhPT0gdmFsdWUgJiYgb3RoZXIgIT09IG90aGVyO1xuICB9XG4gIHJldHVybiBiYXNlSXNFcXVhbERlZXAodmFsdWUsIG90aGVyLCBiYXNlSXNFcXVhbCwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc0VxdWFsO1xuIiwidmFyIGVxdWFsQXJyYXlzID0gcmVxdWlyZSgnLi9lcXVhbEFycmF5cycpLFxuICAgIGVxdWFsQnlUYWcgPSByZXF1aXJlKCcuL2VxdWFsQnlUYWcnKSxcbiAgICBlcXVhbE9iamVjdHMgPSByZXF1aXJlKCcuL2VxdWFsT2JqZWN0cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuL2lzSG9zdE9iamVjdCcpLFxuICAgIGlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNUeXBlZEFycmF5Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsYCBmb3IgYXJyYXlzIGFuZCBvYmplY3RzIHdoaWNoIHBlcmZvcm1zXG4gKiBkZWVwIGNvbXBhcmlzb25zIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMgZW5hYmxpbmcgb2JqZWN0cyB3aXRoIGNpcmN1bGFyXG4gKiByZWZlcmVuY2VzIHRvIGJlIGNvbXBhcmVkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgb2JqZWN0cy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQT1bXV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNFcXVhbERlZXAob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgb2JqSXNBcnIgPSBpc0FycmF5KG9iamVjdCksXG4gICAgICBvdGhJc0FyciA9IGlzQXJyYXkob3RoZXIpLFxuICAgICAgb2JqVGFnID0gYXJyYXlUYWcsXG4gICAgICBvdGhUYWcgPSBhcnJheVRhZztcblxuICBpZiAoIW9iaklzQXJyKSB7XG4gICAgb2JqVGFnID0gb2JqVG9TdHJpbmcuY2FsbChvYmplY3QpO1xuICAgIGlmIChvYmpUYWcgPT0gYXJnc1RhZykge1xuICAgICAgb2JqVGFnID0gb2JqZWN0VGFnO1xuICAgIH0gZWxzZSBpZiAob2JqVGFnICE9IG9iamVjdFRhZykge1xuICAgICAgb2JqSXNBcnIgPSBpc1R5cGVkQXJyYXkob2JqZWN0KTtcbiAgICB9XG4gIH1cbiAgaWYgKCFvdGhJc0Fycikge1xuICAgIG90aFRhZyA9IG9ialRvU3RyaW5nLmNhbGwob3RoZXIpO1xuICAgIGlmIChvdGhUYWcgPT0gYXJnc1RhZykge1xuICAgICAgb3RoVGFnID0gb2JqZWN0VGFnO1xuICAgIH0gZWxzZSBpZiAob3RoVGFnICE9IG9iamVjdFRhZykge1xuICAgICAgb3RoSXNBcnIgPSBpc1R5cGVkQXJyYXkob3RoZXIpO1xuICAgIH1cbiAgfVxuICB2YXIgb2JqSXNPYmogPSBvYmpUYWcgPT0gb2JqZWN0VGFnICYmICFpc0hvc3RPYmplY3Qob2JqZWN0KSxcbiAgICAgIG90aElzT2JqID0gb3RoVGFnID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KG90aGVyKSxcbiAgICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7XG5cbiAgaWYgKGlzU2FtZVRhZyAmJiAhKG9iaklzQXJyIHx8IG9iaklzT2JqKSkge1xuICAgIHJldHVybiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIG9ialRhZyk7XG4gIH1cbiAgaWYgKCFpc0xvb3NlKSB7XG4gICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSxcbiAgICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7XG5cbiAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkge1xuICAgICAgcmV0dXJuIGVxdWFsRnVuYyhvYmpJc1dyYXBwZWQgPyBvYmplY3QudmFsdWUoKSA6IG9iamVjdCwgb3RoSXNXcmFwcGVkID8gb3RoZXIudmFsdWUoKSA6IG90aGVyLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG4gICAgfVxuICB9XG4gIGlmICghaXNTYW1lVGFnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgLy8gRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gZGV0ZWN0aW5nIGNpcmN1bGFyIHJlZmVyZW5jZXMgc2VlIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jSk8uXG4gIHN0YWNrQSB8fCAoc3RhY2tBID0gW10pO1xuICBzdGFja0IgfHwgKHN0YWNrQiA9IFtdKTtcblxuICB2YXIgbGVuZ3RoID0gc3RhY2tBLmxlbmd0aDtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKHN0YWNrQVtsZW5ndGhdID09IG9iamVjdCkge1xuICAgICAgcmV0dXJuIHN0YWNrQltsZW5ndGhdID09IG90aGVyO1xuICAgIH1cbiAgfVxuICAvLyBBZGQgYG9iamVjdGAgYW5kIGBvdGhlcmAgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLlxuICBzdGFja0EucHVzaChvYmplY3QpO1xuICBzdGFja0IucHVzaChvdGhlcik7XG5cbiAgdmFyIHJlc3VsdCA9IChvYmpJc0FyciA/IGVxdWFsQXJyYXlzIDogZXF1YWxPYmplY3RzKShvYmplY3QsIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcblxuICBzdGFja0EucG9wKCk7XG4gIHN0YWNrQi5wb3AoKTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc0VxdWFsRGVlcDtcbiIsInZhciBiYXNlSXNFcXVhbCA9IHJlcXVpcmUoJy4vYmFzZUlzRXF1YWwnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc01hdGNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge0FycmF5fSBtYXRjaERhdGEgVGhlIHByb3BlcnkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3MgdG8gbWF0Y2guXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBpcyBhIG1hdGNoLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc01hdGNoKG9iamVjdCwgbWF0Y2hEYXRhLCBjdXN0b21pemVyKSB7XG4gIHZhciBpbmRleCA9IG1hdGNoRGF0YS5sZW5ndGgsXG4gICAgICBsZW5ndGggPSBpbmRleCxcbiAgICAgIG5vQ3VzdG9taXplciA9ICFjdXN0b21pemVyO1xuXG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybiAhbGVuZ3RoO1xuICB9XG4gIG9iamVjdCA9IHRvT2JqZWN0KG9iamVjdCk7XG4gIHdoaWxlIChpbmRleC0tKSB7XG4gICAgdmFyIGRhdGEgPSBtYXRjaERhdGFbaW5kZXhdO1xuICAgIGlmICgobm9DdXN0b21pemVyICYmIGRhdGFbMl0pXG4gICAgICAgICAgPyBkYXRhWzFdICE9PSBvYmplY3RbZGF0YVswXV1cbiAgICAgICAgICA6ICEoZGF0YVswXSBpbiBvYmplY3QpXG4gICAgICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGRhdGEgPSBtYXRjaERhdGFbaW5kZXhdO1xuICAgIHZhciBrZXkgPSBkYXRhWzBdLFxuICAgICAgICBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICBzcmNWYWx1ZSA9IGRhdGFbMV07XG5cbiAgICBpZiAobm9DdXN0b21pemVyICYmIGRhdGFbMl0pIHtcbiAgICAgIGlmIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXkpIDogdW5kZWZpbmVkO1xuICAgICAgaWYgKCEocmVzdWx0ID09PSB1bmRlZmluZWQgPyBiYXNlSXNFcXVhbChzcmNWYWx1ZSwgb2JqVmFsdWUsIGN1c3RvbWl6ZXIsIHRydWUpIDogcmVzdWx0KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc01hdGNoO1xuIiwiLyoqXG4gKiBUaGUgZnVuY3Rpb24gd2hvc2UgcHJvdG90eXBlIGFsbCBjaGFpbmluZyB3cmFwcGVycyBpbmhlcml0IGZyb20uXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYmFzZUxvZGFzaCgpIHtcbiAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTG9kYXNoO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi9iYXNlRWFjaCcpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hcGAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFjayBzaG9ydGhhbmRzXG4gKiBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlTWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gaXNBcnJheUxpa2UoY29sbGVjdGlvbikgPyBBcnJheShjb2xsZWN0aW9uLmxlbmd0aCkgOiBbXTtcblxuICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgcmVzdWx0WysraW5kZXhdID0gaXRlcmF0ZWUodmFsdWUsIGtleSwgY29sbGVjdGlvbik7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VNYXA7XG4iLCJ2YXIgYmFzZUlzTWF0Y2ggPSByZXF1aXJlKCcuL2Jhc2VJc01hdGNoJyksXG4gICAgZ2V0TWF0Y2hEYXRhID0gcmVxdWlyZSgnLi9nZXRNYXRjaERhdGEnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzYCB3aGljaCBkb2VzIG5vdCBjbG9uZSBgc291cmNlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlTWF0Y2hlcyhzb3VyY2UpIHtcbiAgdmFyIG1hdGNoRGF0YSA9IGdldE1hdGNoRGF0YShzb3VyY2UpO1xuICBpZiAobWF0Y2hEYXRhLmxlbmd0aCA9PSAxICYmIG1hdGNoRGF0YVswXVsyXSkge1xuICAgIHZhciBrZXkgPSBtYXRjaERhdGFbMF1bMF0sXG4gICAgICAgIHZhbHVlID0gbWF0Y2hEYXRhWzBdWzFdO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IHRvT2JqZWN0KG9iamVjdCk7XG4gICAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IHZhbHVlICYmICh2YWx1ZSAhPT0gdW5kZWZpbmVkIHx8IChrZXkgaW4gb2JqZWN0KSk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgcmV0dXJuIGJhc2VJc01hdGNoKG9iamVjdCwgbWF0Y2hEYXRhKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWF0Y2hlcztcbiIsInZhciBiYXNlR2V0ID0gcmVxdWlyZSgnLi9iYXNlR2V0JyksXG4gICAgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsJyksXG4gICAgYmFzZVNsaWNlID0gcmVxdWlyZSgnLi9iYXNlU2xpY2UnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuL2lzS2V5JyksXG4gICAgaXNTdHJpY3RDb21wYXJhYmxlID0gcmVxdWlyZSgnLi9pc1N0cmljdENvbXBhcmFibGUnKSxcbiAgICBsYXN0ID0gcmVxdWlyZSgnLi4vYXJyYXkvbGFzdCcpLFxuICAgIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpLFxuICAgIHRvUGF0aCA9IHJlcXVpcmUoJy4vdG9QYXRoJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc1Byb3BlcnR5YCB3aGljaCBkb2VzIG5vdCBjbG9uZSBgc3JjVmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlTWF0Y2hlc1Byb3BlcnR5KHBhdGgsIHNyY1ZhbHVlKSB7XG4gIHZhciBpc0FyciA9IGlzQXJyYXkocGF0aCksXG4gICAgICBpc0NvbW1vbiA9IGlzS2V5KHBhdGgpICYmIGlzU3RyaWN0Q29tcGFyYWJsZShzcmNWYWx1ZSksXG4gICAgICBwYXRoS2V5ID0gKHBhdGggKyAnJyk7XG5cbiAgcGF0aCA9IHRvUGF0aChwYXRoKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIga2V5ID0gcGF0aEtleTtcbiAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICAgIGlmICgoaXNBcnIgfHwgIWlzQ29tbW9uKSAmJiAhKGtleSBpbiBvYmplY3QpKSB7XG4gICAgICBvYmplY3QgPSBwYXRoLmxlbmd0aCA9PSAxID8gb2JqZWN0IDogYmFzZUdldChvYmplY3QsIGJhc2VTbGljZShwYXRoLCAwLCAtMSkpO1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGtleSA9IGxhc3QocGF0aCk7XG4gICAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IHNyY1ZhbHVlXG4gICAgICA/IChzcmNWYWx1ZSAhPT0gdW5kZWZpbmVkIHx8IChrZXkgaW4gb2JqZWN0KSlcbiAgICAgIDogYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9iamVjdFtrZXldLCB1bmRlZmluZWQsIHRydWUpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VNYXRjaGVzUHJvcGVydHk7XG4iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHJvcGVydHlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZVByb3BlcnR5KGtleSkge1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogdG9PYmplY3Qob2JqZWN0KVtrZXldO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eTtcbiIsInZhciBiYXNlR2V0ID0gcmVxdWlyZSgnLi9iYXNlR2V0JyksXG4gICAgdG9QYXRoID0gcmVxdWlyZSgnLi90b1BhdGgnKTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VQcm9wZXJ0eWAgd2hpY2ggc3VwcG9ydHMgZGVlcCBwYXRocy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlUHJvcGVydHlEZWVwKHBhdGgpIHtcbiAgdmFyIHBhdGhLZXkgPSAocGF0aCArICcnKTtcbiAgcGF0aCA9IHRvUGF0aChwYXRoKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBiYXNlR2V0KG9iamVjdCwgcGF0aCwgcGF0aEtleSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVByb3BlcnR5RGVlcDtcbiIsInZhciBpZGVudGl0eSA9IHJlcXVpcmUoJy4uL3V0aWxpdHkvaWRlbnRpdHknKSxcbiAgICBtZXRhTWFwID0gcmVxdWlyZSgnLi9tZXRhTWFwJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYHNldERhdGFgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaG90IGxvb3AgZGV0ZWN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhc3NvY2lhdGUgbWV0YWRhdGEgd2l0aC5cbiAqIEBwYXJhbSB7Kn0gZGF0YSBUaGUgbWV0YWRhdGEuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGZ1bmNgLlxuICovXG52YXIgYmFzZVNldERhdGEgPSAhbWV0YU1hcCA/IGlkZW50aXR5IDogZnVuY3Rpb24oZnVuYywgZGF0YSkge1xuICBtZXRhTWFwLnNldChmdW5jLCBkYXRhKTtcbiAgcmV0dXJuIGZ1bmM7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VTZXREYXRhO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zbGljZWAgd2l0aG91dCBhbiBpdGVyYXRlZSBjYWxsIGd1YXJkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2xpY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBwb3NpdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gIHN0YXJ0ID0gc3RhcnQgPT0gbnVsbCA/IDAgOiAoK3N0YXJ0IHx8IDApO1xuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAtc3RhcnQgPiBsZW5ndGggPyAwIDogKGxlbmd0aCArIHN0YXJ0KTtcbiAgfVxuICBlbmQgPSAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gbGVuZ3RoKSA/IGxlbmd0aCA6ICgrZW5kIHx8IDApO1xuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5ndGg7XG4gIH1cbiAgbGVuZ3RoID0gc3RhcnQgPiBlbmQgPyAwIDogKChlbmQgLSBzdGFydCkgPj4+IDApO1xuICBzdGFydCA+Pj49IDA7XG5cbiAgdmFyIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IGFycmF5W2luZGV4ICsgc3RhcnRdO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVNsaWNlO1xuIiwiLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIGlmIGl0J3Mgbm90IG9uZS4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkXG4gKiBmb3IgYG51bGxgIG9yIGB1bmRlZmluZWRgIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gYmFzZVRvU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiAodmFsdWUgKyAnJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVRvU3RyaW5nO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy52YWx1ZXNgIGFuZCBgXy52YWx1ZXNJbmAgd2hpY2ggY3JlYXRlcyBhblxuICogYXJyYXkgb2YgYG9iamVjdGAgcHJvcGVydHkgdmFsdWVzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHByb3BlcnR5IG5hbWVzXG4gKiBvZiBgcHJvcHNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gZ2V0IHZhbHVlcyBmb3IuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VWYWx1ZXMob2JqZWN0LCBwcm9wcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gb2JqZWN0W3Byb3BzW2luZGV4XV07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlVmFsdWVzO1xuIiwidmFyIGJpbmFyeUluZGV4QnkgPSByZXF1aXJlKCcuL2JpbmFyeUluZGV4QnknKSxcbiAgICBpZGVudGl0eSA9IHJlcXVpcmUoJy4uL3V0aWxpdHkvaWRlbnRpdHknKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdGhlIG1heGltdW0gbGVuZ3RoIGFuZCBpbmRleCBvZiBhbiBhcnJheS4gKi9cbnZhciBNQVhfQVJSQVlfTEVOR1RIID0gNDI5NDk2NzI5NSxcbiAgICBIQUxGX01BWF9BUlJBWV9MRU5HVEggPSBNQVhfQVJSQVlfTEVOR1RIID4+PiAxO1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBvZiBgYXJyYXlgIHRvIGRldGVybWluZSB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYFxuICogc2hvdWxkIGJlIGluc2VydGVkIGludG8gYGFycmF5YCBpbiBvcmRlciB0byBtYWludGFpbiBpdHMgc29ydCBvcmRlci5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRIaWdoZXN0XSBTcGVjaWZ5IHJldHVybmluZyB0aGUgaGlnaGVzdCBxdWFsaWZpZWQgaW5kZXguXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICogIGludG8gYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYmluYXJ5SW5kZXgoYXJyYXksIHZhbHVlLCByZXRIaWdoZXN0KSB7XG4gIHZhciBsb3cgPSAwLFxuICAgICAgaGlnaCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogbG93O1xuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiYgdmFsdWUgPT09IHZhbHVlICYmIGhpZ2ggPD0gSEFMRl9NQVhfQVJSQVlfTEVOR1RIKSB7XG4gICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgIHZhciBtaWQgPSAobG93ICsgaGlnaCkgPj4+IDEsXG4gICAgICAgICAgY29tcHV0ZWQgPSBhcnJheVttaWRdO1xuXG4gICAgICBpZiAoKHJldEhpZ2hlc3QgPyAoY29tcHV0ZWQgPD0gdmFsdWUpIDogKGNvbXB1dGVkIDwgdmFsdWUpKSAmJiBjb21wdXRlZCAhPT0gbnVsbCkge1xuICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaGlnaCA9IG1pZDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGhpZ2g7XG4gIH1cbiAgcmV0dXJuIGJpbmFyeUluZGV4QnkoYXJyYXksIHZhbHVlLCBpZGVudGl0eSwgcmV0SGlnaGVzdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluYXJ5SW5kZXg7XG4iLCIvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZUZsb29yID0gTWF0aC5mbG9vcixcbiAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdGhlIG1heGltdW0gbGVuZ3RoIGFuZCBpbmRleCBvZiBhbiBhcnJheS4gKi9cbnZhciBNQVhfQVJSQVlfTEVOR1RIID0gNDI5NDk2NzI5NSxcbiAgICBNQVhfQVJSQVlfSU5ERVggPSBNQVhfQVJSQVlfTEVOR1RIIC0gMTtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGJpbmFyeUluZGV4YCBleGNlcHQgdGhhdCBpdCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yXG4gKiBgdmFsdWVgIGFuZCBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCB0byBjb21wdXRlIHRoZWlyIHNvcnQgcmFua2luZy4gVGhlXG4gKiBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OyAodmFsdWUpLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRIaWdoZXN0XSBTcGVjaWZ5IHJldHVybmluZyB0aGUgaGlnaGVzdCBxdWFsaWZpZWQgaW5kZXguXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICogIGludG8gYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYmluYXJ5SW5kZXhCeShhcnJheSwgdmFsdWUsIGl0ZXJhdGVlLCByZXRIaWdoZXN0KSB7XG4gIHZhbHVlID0gaXRlcmF0ZWUodmFsdWUpO1xuXG4gIHZhciBsb3cgPSAwLFxuICAgICAgaGlnaCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMCxcbiAgICAgIHZhbElzTmFOID0gdmFsdWUgIT09IHZhbHVlLFxuICAgICAgdmFsSXNOdWxsID0gdmFsdWUgPT09IG51bGwsXG4gICAgICB2YWxJc1VuZGVmID0gdmFsdWUgPT09IHVuZGVmaW5lZDtcblxuICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgIHZhciBtaWQgPSBuYXRpdmVGbG9vcigobG93ICsgaGlnaCkgLyAyKSxcbiAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZShhcnJheVttaWRdKSxcbiAgICAgICAgaXNEZWYgPSBjb21wdXRlZCAhPT0gdW5kZWZpbmVkLFxuICAgICAgICBpc1JlZmxleGl2ZSA9IGNvbXB1dGVkID09PSBjb21wdXRlZDtcblxuICAgIGlmICh2YWxJc05hTikge1xuICAgICAgdmFyIHNldExvdyA9IGlzUmVmbGV4aXZlIHx8IHJldEhpZ2hlc3Q7XG4gICAgfSBlbHNlIGlmICh2YWxJc051bGwpIHtcbiAgICAgIHNldExvdyA9IGlzUmVmbGV4aXZlICYmIGlzRGVmICYmIChyZXRIaWdoZXN0IHx8IGNvbXB1dGVkICE9IG51bGwpO1xuICAgIH0gZWxzZSBpZiAodmFsSXNVbmRlZikge1xuICAgICAgc2V0TG93ID0gaXNSZWZsZXhpdmUgJiYgKHJldEhpZ2hlc3QgfHwgaXNEZWYpO1xuICAgIH0gZWxzZSBpZiAoY29tcHV0ZWQgPT0gbnVsbCkge1xuICAgICAgc2V0TG93ID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldExvdyA9IHJldEhpZ2hlc3QgPyAoY29tcHV0ZWQgPD0gdmFsdWUpIDogKGNvbXB1dGVkIDwgdmFsdWUpO1xuICAgIH1cbiAgICBpZiAoc2V0TG93KSB7XG4gICAgICBsb3cgPSBtaWQgKyAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBoaWdoID0gbWlkO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmF0aXZlTWluKGhpZ2gsIE1BWF9BUlJBWV9JTkRFWCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluYXJ5SW5kZXhCeTtcbiIsInZhciBpZGVudGl0eSA9IHJlcXVpcmUoJy4uL3V0aWxpdHkvaWRlbnRpdHknKTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VDYWxsYmFja2Agd2hpY2ggb25seSBzdXBwb3J0cyBgdGhpc2AgYmluZGluZ1xuICogYW5kIHNwZWNpZnlpbmcgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJnQ291bnRdIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAqL1xuZnVuY3Rpb24gYmluZENhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSB7XG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGlkZW50aXR5O1xuICB9XG4gIGlmICh0aGlzQXJnID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZnVuYztcbiAgfVxuICBzd2l0Y2ggKGFyZ0NvdW50KSB7XG4gICAgY2FzZSAxOiByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgdmFsdWUpO1xuICAgIH07XG4gICAgY2FzZSAzOiByZXR1cm4gZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgfTtcbiAgICBjYXNlIDQ6IHJldHVybiBmdW5jdGlvbihhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH07XG4gICAgY2FzZSA1OiByZXR1cm4gZnVuY3Rpb24odmFsdWUsIG90aGVyLCBrZXksIG9iamVjdCwgc291cmNlKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiaW5kQ2FsbGJhY2s7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIEFycmF5QnVmZmVyID0gZ2xvYmFsLkFycmF5QnVmZmVyLFxuICAgIFVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGdpdmVuIGFycmF5IGJ1ZmZlci5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gYnVmZmVyIFRoZSBhcnJheSBidWZmZXIgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7QXJyYXlCdWZmZXJ9IFJldHVybnMgdGhlIGNsb25lZCBhcnJheSBidWZmZXIuXG4gKi9cbmZ1bmN0aW9uIGJ1ZmZlckNsb25lKGJ1ZmZlcikge1xuICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5QnVmZmVyKGJ1ZmZlci5ieXRlTGVuZ3RoKSxcbiAgICAgIHZpZXcgPSBuZXcgVWludDhBcnJheShyZXN1bHQpO1xuXG4gIHZpZXcuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZmZlcikpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJ1ZmZlckNsb25lO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wySjFabVpsY2tOc2IyNWxMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRWlMQ0ptYVd4bElqb2laMlZ1WlhKaGRHVmtMbXB6SWl3aWMyOTFjbU5sVW05dmRDSTZJaUlzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiSWk4cUtpQk9ZWFJwZG1VZ2JXVjBhRzlrSUhKbFptVnlaVzVqWlhNdUlDb3ZYRzUyWVhJZ1FYSnlZWGxDZFdabVpYSWdQU0JuYkc5aVlXd3VRWEp5WVhsQ2RXWm1aWElzWEc0Z0lDQWdWV2x1ZERoQmNuSmhlU0E5SUdkc2IySmhiQzVWYVc1ME9FRnljbUY1TzF4dVhHNHZLaXBjYmlBcUlFTnlaV0YwWlhNZ1lTQmpiRzl1WlNCdlppQjBhR1VnWjJsMlpXNGdZWEp5WVhrZ1luVm1abVZ5TGx4dUlDcGNiaUFxSUVCd2NtbDJZWFJsWEc0Z0tpQkFjR0Z5WVcwZ2UwRnljbUY1UW5WbVptVnlmU0JpZFdabVpYSWdWR2hsSUdGeWNtRjVJR0oxWm1abGNpQjBieUJqYkc5dVpTNWNiaUFxSUVCeVpYUjFjbTV6SUh0QmNuSmhlVUoxWm1abGNuMGdVbVYwZFhKdWN5QjBhR1VnWTJ4dmJtVmtJR0Z5Y21GNUlHSjFabVpsY2k1Y2JpQXFMMXh1Wm5WdVkzUnBiMjRnWW5WbVptVnlRMnh2Ym1Vb1luVm1abVZ5S1NCN1hHNGdJSFpoY2lCeVpYTjFiSFFnUFNCdVpYY2dRWEp5WVhsQ2RXWm1aWElvWW5WbVptVnlMbUo1ZEdWTVpXNW5kR2dwTEZ4dUlDQWdJQ0FnZG1sbGR5QTlJRzVsZHlCVmFXNTBPRUZ5Y21GNUtISmxjM1ZzZENrN1hHNWNiaUFnZG1sbGR5NXpaWFFvYm1WM0lGVnBiblE0UVhKeVlYa29ZblZtWm1WeUtTazdYRzRnSUhKbGRIVnliaUJ5WlhOMWJIUTdYRzU5WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ1luVm1abVZ5UTJ4dmJtVTdYRzRpWFgwPSIsIi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSB0aGF0IGlzIHRoZSBjb21wb3NpdGlvbiBvZiBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMsXG4gKiBwbGFjZWhvbGRlcnMsIGFuZCBwcm92aWRlZCBhcmd1bWVudHMgaW50byBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBhcmdzIFRoZSBwcm92aWRlZCBhcmd1bWVudHMuXG4gKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBob2xkZXJzIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjb21wb3NlZCBhcmd1bWVudHMuXG4gKi9cbmZ1bmN0aW9uIGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKSB7XG4gIHZhciBob2xkZXJzTGVuZ3RoID0gaG9sZGVycy5sZW5ndGgsXG4gICAgICBhcmdzSW5kZXggPSAtMSxcbiAgICAgIGFyZ3NMZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBob2xkZXJzTGVuZ3RoLCAwKSxcbiAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgbGVmdExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlZnRMZW5ndGggKyBhcmdzTGVuZ3RoKTtcblxuICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgcmVzdWx0W2xlZnRJbmRleF0gPSBwYXJ0aWFsc1tsZWZ0SW5kZXhdO1xuICB9XG4gIHdoaWxlICgrK2FyZ3NJbmRleCA8IGhvbGRlcnNMZW5ndGgpIHtcbiAgICByZXN1bHRbaG9sZGVyc1thcmdzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgfVxuICB3aGlsZSAoYXJnc0xlbmd0aC0tKSB7XG4gICAgcmVzdWx0W2xlZnRJbmRleCsrXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY29tcG9zZUFyZ3M7XG4iLCIvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gaXMgbGlrZSBgY29tcG9zZUFyZ3NgIGV4Y2VwdCB0aGF0IHRoZSBhcmd1bWVudHMgY29tcG9zaXRpb25cbiAqIGlzIHRhaWxvcmVkIGZvciBgXy5wYXJ0aWFsUmlnaHRgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBob2xkZXJzIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjb21wb3NlZCBhcmd1bWVudHMuXG4gKi9cbmZ1bmN0aW9uIGNvbXBvc2VBcmdzUmlnaHQoYXJncywgcGFydGlhbHMsIGhvbGRlcnMpIHtcbiAgdmFyIGhvbGRlcnNJbmRleCA9IC0xLFxuICAgICAgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgYXJnc0luZGV4ID0gLTEsXG4gICAgICBhcmdzTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICByaWdodEluZGV4ID0gLTEsXG4gICAgICByaWdodExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGFyZ3NMZW5ndGggKyByaWdodExlbmd0aCk7XG5cbiAgd2hpbGUgKCsrYXJnc0luZGV4IDwgYXJnc0xlbmd0aCkge1xuICAgIHJlc3VsdFthcmdzSW5kZXhdID0gYXJnc1thcmdzSW5kZXhdO1xuICB9XG4gIHZhciBvZmZzZXQgPSBhcmdzSW5kZXg7XG4gIHdoaWxlICgrK3JpZ2h0SW5kZXggPCByaWdodExlbmd0aCkge1xuICAgIHJlc3VsdFtvZmZzZXQgKyByaWdodEluZGV4XSA9IHBhcnRpYWxzW3JpZ2h0SW5kZXhdO1xuICB9XG4gIHdoaWxlICgrK2hvbGRlcnNJbmRleCA8IGhvbGRlcnNMZW5ndGgpIHtcbiAgICByZXN1bHRbb2Zmc2V0ICsgaG9sZGVyc1tob2xkZXJzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY29tcG9zZUFyZ3NSaWdodDtcbiIsInZhciBnZXRMZW5ndGggPSByZXF1aXJlKCcuL2dldExlbmd0aCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi9pc0xlbmd0aCcpLFxuICAgIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgYmFzZUVhY2hgIG9yIGBiYXNlRWFjaFJpZ2h0YCBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VFYWNoKGVhY2hGdW5jLCBmcm9tUmlnaHQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGxlbmd0aCA9IGNvbGxlY3Rpb24gPyBnZXRMZW5ndGgoY29sbGVjdGlvbikgOiAwO1xuICAgIGlmICghaXNMZW5ndGgobGVuZ3RoKSkge1xuICAgICAgcmV0dXJuIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKTtcbiAgICB9XG4gICAgdmFyIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTEsXG4gICAgICAgIGl0ZXJhYmxlID0gdG9PYmplY3QoY29sbGVjdGlvbik7XG5cbiAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2luZGV4XSwgaW5kZXgsIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJhc2VFYWNoO1xuIiwidmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBiYXNlIGZ1bmN0aW9uIGZvciBgXy5mb3JJbmAgb3IgYF8uZm9ySW5SaWdodGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYmFzZSBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQmFzZUZvcihmcm9tUmlnaHQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCwgaXRlcmF0ZWUsIGtleXNGdW5jKSB7XG4gICAgdmFyIGl0ZXJhYmxlID0gdG9PYmplY3Qob2JqZWN0KSxcbiAgICAgICAgcHJvcHMgPSBrZXlzRnVuYyhvYmplY3QpLFxuICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmplY3Q7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQmFzZUZvcjtcbiIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBjcmVhdGVDdG9yV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlQ3RvcldyYXBwZXInKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgYW5kIGludm9rZXMgaXQgd2l0aCB0aGUgYHRoaXNgXG4gKiBiaW5kaW5nIG9mIGB0aGlzQXJnYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYmluZC5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQmluZFdyYXBwZXIoZnVuYywgdGhpc0FyZykge1xuICB2YXIgQ3RvciA9IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgdmFyIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gZ2xvYmFsICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQXJnLCBhcmd1bWVudHMpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJpbmRXcmFwcGVyO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wyTnlaV0YwWlVKcGJtUlhjbUZ3Y0dWeUxtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWs3WEc1Y2JpOHFLbHh1SUNvZ1EzSmxZWFJsY3lCaElHWjFibU4wYVc5dUlIUm9ZWFFnZDNKaGNITWdZR1oxYm1OZ0lHRnVaQ0JwYm5admEyVnpJR2wwSUhkcGRHZ2dkR2hsSUdCMGFHbHpZRnh1SUNvZ1ltbHVaR2x1WnlCdlppQmdkR2hwYzBGeVoyQXVYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU5SUdaMWJtTWdWR2hsSUdaMWJtTjBhVzl1SUhSdklHSnBibVF1WEc0Z0tpQkFjR0Z5WVcwZ2V5cDlJRnQwYUdselFYSm5YU0JVYUdVZ1lIUm9hWE5nSUdKcGJtUnBibWNnYjJZZ1lHWjFibU5nTGx4dUlDb2dRSEpsZEhWeWJuTWdlMFoxYm1OMGFXOXVmU0JTWlhSMWNtNXpJSFJvWlNCdVpYY2dZbTkxYm1RZ1puVnVZM1JwYjI0dVhHNGdLaTljYm1aMWJtTjBhVzl1SUdOeVpXRjBaVUpwYm1SWGNtRndjR1Z5S0daMWJtTXNJSFJvYVhOQmNtY3BJSHRjYmlBZ2RtRnlJRU4wYjNJZ1BTQmpjbVZoZEdWRGRHOXlWM0poY0hCbGNpaG1kVzVqS1R0Y2JseHVJQ0JtZFc1amRHbHZiaUIzY21Gd2NHVnlLQ2tnZTF4dUlDQWdJSFpoY2lCbWJpQTlJQ2gwYUdseklDWW1JSFJvYVhNZ0lUMDlJR2RzYjJKaGJDQW1KaUIwYUdseklHbHVjM1JoYm1ObGIyWWdkM0poY0hCbGNpa2dQeUJEZEc5eUlEb2dablZ1WXp0Y2JpQWdJQ0J5WlhSMWNtNGdabTR1WVhCd2JIa29kR2hwYzBGeVp5d2dZWEpuZFcxbGJuUnpLVHRjYmlBZ2ZWeHVJQ0J5WlhSMWNtNGdkM0poY0hCbGNqdGNibjFjYmx4dWJXOWtkV3hsTG1WNGNHOXlkSE1nUFNCamNtVmhkR1ZDYVc1a1YzSmhjSEJsY2p0Y2JpSmRmUT09IiwidmFyIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL2Jhc2VDcmVhdGUnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwcm9kdWNlcyBhbiBpbnN0YW5jZSBvZiBgQ3RvcmAgcmVnYXJkbGVzcyBvZlxuICogd2hldGhlciBpdCB3YXMgaW52b2tlZCBhcyBwYXJ0IG9mIGEgYG5ld2AgZXhwcmVzc2lvbiBvciBieSBgY2FsbGAgb3IgYGFwcGx5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gQ3RvciBUaGUgY29uc3RydWN0b3IgdG8gd3JhcC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUN0b3JXcmFwcGVyKEN0b3IpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIC8vIFVzZSBhIGBzd2l0Y2hgIHN0YXRlbWVudCB0byB3b3JrIHdpdGggY2xhc3MgY29uc3RydWN0b3JzLlxuICAgIC8vIFNlZSBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1lY21hc2NyaXB0LWZ1bmN0aW9uLW9iamVjdHMtY2FsbC10aGlzYXJndW1lbnQtYXJndW1lbnRzbGlzdFxuICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gbmV3IEN0b3I7XG4gICAgICBjYXNlIDE6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdKTtcbiAgICAgIGNhc2UgMjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgY2FzZSAzOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICBjYXNlIDQ6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgICAgIGNhc2UgNTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0pO1xuICAgICAgY2FzZSA2OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSk7XG4gICAgICBjYXNlIDc6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdLCBhcmdzWzZdKTtcbiAgICB9XG4gICAgdmFyIHRoaXNCaW5kaW5nID0gYmFzZUNyZWF0ZShDdG9yLnByb3RvdHlwZSksXG4gICAgICAgIHJlc3VsdCA9IEN0b3IuYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuXG4gICAgLy8gTWltaWMgdGhlIGNvbnN0cnVjdG9yJ3MgYHJldHVybmAgYmVoYXZpb3IuXG4gICAgLy8gU2VlIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDEzLjIuMiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJldHVybiBpc09iamVjdChyZXN1bHQpID8gcmVzdWx0IDogdGhpc0JpbmRpbmc7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQ3RvcldyYXBwZXI7XG4iLCJ2YXIgYmFzZUNhbGxiYWNrID0gcmVxdWlyZSgnLi9iYXNlQ2FsbGJhY2snKSxcbiAgICBiYXNlRmluZCA9IHJlcXVpcmUoJy4vYmFzZUZpbmQnKSxcbiAgICBiYXNlRmluZEluZGV4ID0gcmVxdWlyZSgnLi9iYXNlRmluZEluZGV4JyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgXy5maW5kYCBvciBgXy5maW5kTGFzdGAgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmaW5kIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVGaW5kKGVhY2hGdW5jLCBmcm9tUmlnaHQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgdGhpc0FyZykge1xuICAgIHByZWRpY2F0ZSA9IGJhc2VDYWxsYmFjayhwcmVkaWNhdGUsIHRoaXNBcmcsIDMpO1xuICAgIGlmIChpc0FycmF5KGNvbGxlY3Rpb24pKSB7XG4gICAgICB2YXIgaW5kZXggPSBiYXNlRmluZEluZGV4KGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZnJvbVJpZ2h0KTtcbiAgICAgIHJldHVybiBpbmRleCA+IC0xID8gY29sbGVjdGlvbltpbmRleF0gOiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBiYXNlRmluZChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGVhY2hGdW5jKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVGaW5kO1xuIiwidmFyIGJpbmRDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmluZENhbGxiYWNrJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiBmb3IgYF8uZm9yRWFjaGAgb3IgYF8uZm9yRWFjaFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gYXJyYXlGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYW4gYXJyYXkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGVhY2ggZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUZvckVhY2goYXJyYXlGdW5jLCBlYWNoRnVuYykge1xuICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUsIHRoaXNBcmcpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBpdGVyYXRlZSA9PSAnZnVuY3Rpb24nICYmIHRoaXNBcmcgPT09IHVuZGVmaW5lZCAmJiBpc0FycmF5KGNvbGxlY3Rpb24pKVxuICAgICAgPyBhcnJheUZ1bmMoY29sbGVjdGlvbiwgaXRlcmF0ZWUpXG4gICAgICA6IGVhY2hGdW5jKGNvbGxlY3Rpb24sIGJpbmRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMykpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUZvckVhY2g7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKSxcbiAgICBjb21wb3NlQXJncyA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3MnKSxcbiAgICBjb21wb3NlQXJnc1JpZ2h0ID0gcmVxdWlyZSgnLi9jb21wb3NlQXJnc1JpZ2h0JyksXG4gICAgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyksXG4gICAgaXNMYXppYWJsZSA9IHJlcXVpcmUoJy4vaXNMYXppYWJsZScpLFxuICAgIHJlb3JkZXIgPSByZXF1aXJlKCcuL3Jlb3JkZXInKSxcbiAgICByZXBsYWNlSG9sZGVycyA9IHJlcXVpcmUoJy4vcmVwbGFjZUhvbGRlcnMnKSxcbiAgICBzZXREYXRhID0gcmVxdWlyZSgnLi9zZXREYXRhJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMSxcbiAgICBCSU5EX0tFWV9GTEFHID0gMixcbiAgICBDVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICBDVVJSWV9GTEFHID0gOCxcbiAgICBDVVJSWV9SSUdIVF9GTEFHID0gMTYsXG4gICAgUEFSVElBTF9GTEFHID0gMzIsXG4gICAgUEFSVElBTF9SSUdIVF9GTEFHID0gNjQsXG4gICAgQVJZX0ZMQUcgPSAxMjg7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mLCBwYXJ0aWFsIGFwcGxpY2F0aW9uLCBhbmQgY3VycnlpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBvZiBmbGFncy4gU2VlIGBjcmVhdGVXcmFwcGVyYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc1JpZ2h0XSBUaGUgYXJndW1lbnRzIHRvIGFwcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNSaWdodF0gVGhlIGBwYXJ0aWFsc1JpZ2h0YCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcnldIFRoZSBhcml0eSBjYXAgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUh5YnJpZFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCwgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gIHZhciBpc0FyeSA9IGJpdG1hc2sgJiBBUllfRkxBRyxcbiAgICAgIGlzQmluZCA9IGJpdG1hc2sgJiBCSU5EX0ZMQUcsXG4gICAgICBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRyxcbiAgICAgIGlzQ3VycnkgPSBiaXRtYXNrICYgQ1VSUllfRkxBRyxcbiAgICAgIGlzQ3VycnlCb3VuZCA9IGJpdG1hc2sgJiBDVVJSWV9CT1VORF9GTEFHLFxuICAgICAgaXNDdXJyeVJpZ2h0ID0gYml0bWFzayAmIENVUlJZX1JJR0hUX0ZMQUcsXG4gICAgICBDdG9yID0gaXNCaW5kS2V5ID8gdW5kZWZpbmVkIDogY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgIC8vIGNvbnZlcnRpbmcgaXQgdG8gYW4gYXJyYXkgYmVmb3JlIHByb3ZpZGluZyBpdCB0byBvdGhlciBmdW5jdGlvbnMuXG4gICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKTtcblxuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgfVxuICAgIGlmIChwYXJ0aWFscykge1xuICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9XG4gICAgaWYgKHBhcnRpYWxzUmlnaHQpIHtcbiAgICAgIGFyZ3MgPSBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCk7XG4gICAgfVxuICAgIGlmIChpc0N1cnJ5IHx8IGlzQ3VycnlSaWdodCkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0gd3JhcHBlci5wbGFjZWhvbGRlcixcbiAgICAgICAgICBhcmdzSG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKGFyZ3MsIHBsYWNlaG9sZGVyKTtcblxuICAgICAgbGVuZ3RoIC09IGFyZ3NIb2xkZXJzLmxlbmd0aDtcbiAgICAgIGlmIChsZW5ndGggPCBhcml0eSkge1xuICAgICAgICB2YXIgbmV3QXJnUG9zID0gYXJnUG9zID8gYXJyYXlDb3B5KGFyZ1BvcykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdBcml0eSA9IG5hdGl2ZU1heChhcml0eSAtIGxlbmd0aCwgMCksXG4gICAgICAgICAgICBuZXdzSG9sZGVycyA9IGlzQ3VycnkgPyBhcmdzSG9sZGVycyA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG5ld0hvbGRlcnNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBhcmdzSG9sZGVycyxcbiAgICAgICAgICAgIG5ld1BhcnRpYWxzID0gaXNDdXJyeSA/IGFyZ3MgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdQYXJ0aWFsc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGFyZ3M7XG5cbiAgICAgICAgYml0bWFzayB8PSAoaXNDdXJyeSA/IFBBUlRJQUxfRkxBRyA6IFBBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgICAgIGJpdG1hc2sgJj0gfihpc0N1cnJ5ID8gUEFSVElBTF9SSUdIVF9GTEFHIDogUEFSVElBTF9GTEFHKTtcblxuICAgICAgICBpZiAoIWlzQ3VycnlCb3VuZCkge1xuICAgICAgICAgIGJpdG1hc2sgJj0gfihCSU5EX0ZMQUcgfCBCSU5EX0tFWV9GTEFHKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3c0hvbGRlcnMsIG5ld1BhcnRpYWxzUmlnaHQsIG5ld0hvbGRlcnNSaWdodCwgbmV3QXJnUG9zLCBhcnksIG5ld0FyaXR5XSxcbiAgICAgICAgICAgIHJlc3VsdCA9IGNyZWF0ZUh5YnJpZFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcblxuICAgICAgICBpZiAoaXNMYXppYWJsZShmdW5jKSkge1xuICAgICAgICAgIHNldERhdGEocmVzdWx0LCBuZXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBwbGFjZWhvbGRlcjtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHRoaXNCaW5kaW5nID0gaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsXG4gICAgICAgIGZuID0gaXNCaW5kS2V5ID8gdGhpc0JpbmRpbmdbZnVuY10gOiBmdW5jO1xuXG4gICAgaWYgKGFyZ1Bvcykge1xuICAgICAgYXJncyA9IHJlb3JkZXIoYXJncywgYXJnUG9zKTtcbiAgICB9XG4gICAgaWYgKGlzQXJ5ICYmIGFyeSA8IGFyZ3MubGVuZ3RoKSB7XG4gICAgICBhcmdzLmxlbmd0aCA9IGFyeTtcbiAgICB9XG4gICAgaWYgKHRoaXMgJiYgdGhpcyAhPT0gZ2xvYmFsICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSB7XG4gICAgICBmbiA9IEN0b3IgfHwgY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQmluZGluZywgYXJncyk7XG4gIH1cbiAgcmV0dXJuIHdyYXBwZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlSHlicmlkV3JhcHBlcjtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMk55WldGMFpVaDVZbkpwWkZkeVlYQndaWEl1YW5NaVhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWp0QlFVRkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1lYSnlZWGxEYjNCNUlEMGdjbVZ4ZFdseVpTZ25MaTloY25KaGVVTnZjSGtuS1N4Y2JpQWdJQ0JqYjIxd2IzTmxRWEpuY3lBOUlISmxjWFZwY21Vb0p5NHZZMjl0Y0c5elpVRnlaM01uS1N4Y2JpQWdJQ0JqYjIxd2IzTmxRWEpuYzFKcFoyaDBJRDBnY21WeGRXbHlaU2duTGk5amIyMXdiM05sUVhKbmMxSnBaMmgwSnlrc1hHNGdJQ0FnWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElnUFNCeVpYRjFhWEpsS0NjdUwyTnlaV0YwWlVOMGIzSlhjbUZ3Y0dWeUp5a3NYRzRnSUNBZ2FYTk1ZWHBwWVdKc1pTQTlJSEpsY1hWcGNtVW9KeTR2YVhOTVlYcHBZV0pzWlNjcExGeHVJQ0FnSUhKbGIzSmtaWElnUFNCeVpYRjFhWEpsS0NjdUwzSmxiM0prWlhJbktTeGNiaUFnSUNCeVpYQnNZV05sU0c5c1pHVnljeUE5SUhKbGNYVnBjbVVvSnk0dmNtVndiR0ZqWlVodmJHUmxjbk1uS1N4Y2JpQWdJQ0J6WlhSRVlYUmhJRDBnY21WeGRXbHlaU2duTGk5elpYUkVZWFJoSnlrN1hHNWNiaThxS2lCVmMyVmtJSFJ2SUdOdmJYQnZjMlVnWW1sMGJXRnphM01nWm05eUlIZHlZWEJ3WlhJZ2JXVjBZV1JoZEdFdUlDb3ZYRzUyWVhJZ1FrbE9SRjlHVEVGSElEMGdNU3hjYmlBZ0lDQkNTVTVFWDB0RldWOUdURUZISUQwZ01peGNiaUFnSUNCRFZWSlNXVjlDVDFWT1JGOUdURUZISUQwZ05DeGNiaUFnSUNCRFZWSlNXVjlHVEVGSElEMGdPQ3hjYmlBZ0lDQkRWVkpTV1Y5U1NVZElWRjlHVEVGSElEMGdNVFlzWEc0Z0lDQWdVRUZTVkVsQlRGOUdURUZISUQwZ016SXNYRzRnSUNBZ1VFRlNWRWxCVEY5U1NVZElWRjlHVEVGSElEMGdOalFzWEc0Z0lDQWdRVkpaWDBaTVFVY2dQU0F4TWpnN1hHNWNiaThxSUU1aGRHbDJaU0J0WlhSb2IyUWdjbVZtWlhKbGJtTmxjeUJtYjNJZ2RHaHZjMlVnZDJsMGFDQjBhR1VnYzJGdFpTQnVZVzFsSUdGeklHOTBhR1Z5SUdCc2IyUmhjMmhnSUcxbGRHaHZaSE11SUNvdlhHNTJZWElnYm1GMGFYWmxUV0Y0SUQwZ1RXRjBhQzV0WVhnN1hHNWNiaThxS2x4dUlDb2dRM0psWVhSbGN5QmhJR1oxYm1OMGFXOXVJSFJvWVhRZ2QzSmhjSE1nWUdaMWJtTmdJR0Z1WkNCcGJuWnZhMlZ6SUdsMElIZHBkR2dnYjNCMGFXOXVZV3dnWUhSb2FYTmdYRzRnS2lCaWFXNWthVzVuSUc5bUxDQndZWEowYVdGc0lHRndjR3hwWTJGMGFXOXVMQ0JoYm1RZ1kzVnljbmxwYm1jdVhHNGdLbHh1SUNvZ1FIQnlhWFpoZEdWY2JpQXFJRUJ3WVhKaGJTQjdSblZ1WTNScGIyNThjM1J5YVc1bmZTQm1kVzVqSUZSb1pTQm1kVzVqZEdsdmJpQnZjaUJ0WlhSb2IyUWdibUZ0WlNCMGJ5QnlaV1psY21WdVkyVXVYRzRnS2lCQWNHRnlZVzBnZTI1MWJXSmxjbjBnWW1sMGJXRnpheUJVYUdVZ1ltbDBiV0Z6YXlCdlppQm1iR0ZuY3k0Z1UyVmxJR0JqY21WaGRHVlhjbUZ3Y0dWeVlDQm1iM0lnYlc5eVpTQmtaWFJoYVd4ekxseHVJQ29nUUhCaGNtRnRJSHNxZlNCYmRHaHBjMEZ5WjEwZ1ZHaGxJR0IwYUdsellDQmlhVzVrYVc1bklHOW1JR0JtZFc1allDNWNiaUFxSUVCd1lYSmhiU0I3UVhKeVlYbDlJRnR3WVhKMGFXRnNjMTBnVkdobElHRnlaM1Z0Wlc1MGN5QjBieUJ3Y21Wd1pXNWtJSFJ2SUhSb2IzTmxJSEJ5YjNacFpHVmtJSFJ2SUhSb1pTQnVaWGNnWm5WdVkzUnBiMjR1WEc0Z0tpQkFjR0Z5WVcwZ2UwRnljbUY1ZlNCYmFHOXNaR1Z5YzEwZ1ZHaGxJR0J3WVhKMGFXRnNjMkFnY0d4aFkyVm9iMnhrWlhJZ2FXNWtaWGhsY3k1Y2JpQXFJRUJ3WVhKaGJTQjdRWEp5WVhsOUlGdHdZWEowYVdGc2MxSnBaMmgwWFNCVWFHVWdZWEpuZFcxbGJuUnpJSFJ2SUdGd2NHVnVaQ0IwYnlCMGFHOXpaU0J3Y205MmFXUmxaQ0IwYnlCMGFHVWdibVYzSUdaMWJtTjBhVzl1TGx4dUlDb2dRSEJoY21GdElIdEJjbkpoZVgwZ1cyaHZiR1JsY25OU2FXZG9kRjBnVkdobElHQndZWEowYVdGc2MxSnBaMmgwWUNCd2JHRmpaV2h2YkdSbGNpQnBibVJsZUdWekxseHVJQ29nUUhCaGNtRnRJSHRCY25KaGVYMGdXMkZ5WjFCdmMxMGdWR2hsSUdGeVozVnRaVzUwSUhCdmMybDBhVzl1Y3lCdlppQjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhCaGNtRnRJSHR1ZFcxaVpYSjlJRnRoY25sZElGUm9aU0JoY21sMGVTQmpZWEFnYjJZZ1lHWjFibU5nTGx4dUlDb2dRSEJoY21GdElIdHVkVzFpWlhKOUlGdGhjbWwwZVYwZ1ZHaGxJR0Z5YVhSNUlHOW1JR0JtZFc1allDNWNiaUFxSUVCeVpYUjFjbTV6SUh0R2RXNWpkR2x2Ym4wZ1VtVjBkWEp1Y3lCMGFHVWdibVYzSUhkeVlYQndaV1FnWm5WdVkzUnBiMjR1WEc0Z0tpOWNibVoxYm1OMGFXOXVJR055WldGMFpVaDVZbkpwWkZkeVlYQndaWElvWm5WdVl5d2dZbWwwYldGemF5d2dkR2hwYzBGeVp5d2djR0Z5ZEdsaGJITXNJR2h2YkdSbGNuTXNJSEJoY25ScFlXeHpVbWxuYUhRc0lHaHZiR1JsY25OU2FXZG9kQ3dnWVhKblVHOXpMQ0JoY25rc0lHRnlhWFI1S1NCN1hHNGdJSFpoY2lCcGMwRnllU0E5SUdKcGRHMWhjMnNnSmlCQlVsbGZSa3hCUnl4Y2JpQWdJQ0FnSUdselFtbHVaQ0E5SUdKcGRHMWhjMnNnSmlCQ1NVNUVYMFpNUVVjc1hHNGdJQ0FnSUNCcGMwSnBibVJMWlhrZ1BTQmlhWFJ0WVhOcklDWWdRa2xPUkY5TFJWbGZSa3hCUnl4Y2JpQWdJQ0FnSUdselEzVnljbmtnUFNCaWFYUnRZWE5ySUNZZ1ExVlNVbGxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRM1Z5Y25sQ2IzVnVaQ0E5SUdKcGRHMWhjMnNnSmlCRFZWSlNXVjlDVDFWT1JGOUdURUZITEZ4dUlDQWdJQ0FnYVhORGRYSnllVkpwWjJoMElEMGdZbWwwYldGemF5QW1JRU5WVWxKWlgxSkpSMGhVWDBaTVFVY3NYRzRnSUNBZ0lDQkRkRzl5SUQwZ2FYTkNhVzVrUzJWNUlEOGdkVzVrWldacGJtVmtJRG9nWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElvWm5WdVl5azdYRzVjYmlBZ1puVnVZM1JwYjI0Z2QzSmhjSEJsY2lncElIdGNiaUFnSUNBdkx5QkJkbTlwWkNCZ1lYSm5kVzFsYm5SellDQnZZbXBsWTNRZ2RYTmxJR1JwYzNGMVlXeHBabmxwYm1jZ2IzQjBhVzFwZW1GMGFXOXVjeUJpZVZ4dUlDQWdJQzh2SUdOdmJuWmxjblJwYm1jZ2FYUWdkRzhnWVc0Z1lYSnlZWGtnWW1WbWIzSmxJSEJ5YjNacFpHbHVaeUJwZENCMGJ5QnZkR2hsY2lCbWRXNWpkR2x2Ym5NdVhHNGdJQ0FnZG1GeUlHeGxibWQwYUNBOUlHRnlaM1Z0Wlc1MGN5NXNaVzVuZEdnc1hHNGdJQ0FnSUNBZ0lHbHVaR1Y0SUQwZ2JHVnVaM1JvTEZ4dUlDQWdJQ0FnSUNCaGNtZHpJRDBnUVhKeVlYa29iR1Z1WjNSb0tUdGNibHh1SUNBZ0lIZG9hV3hsSUNocGJtUmxlQzB0S1NCN1hHNGdJQ0FnSUNCaGNtZHpXMmx1WkdWNFhTQTlJR0Z5WjNWdFpXNTBjMXRwYm1SbGVGMDdYRzRnSUNBZ2ZWeHVJQ0FnSUdsbUlDaHdZWEowYVdGc2N5a2dlMXh1SUNBZ0lDQWdZWEpuY3lBOUlHTnZiWEJ2YzJWQmNtZHpLR0Z5WjNNc0lIQmhjblJwWVd4ekxDQm9iMnhrWlhKektUdGNiaUFnSUNCOVhHNGdJQ0FnYVdZZ0tIQmhjblJwWVd4elVtbG5hSFFwSUh0Y2JpQWdJQ0FnSUdGeVozTWdQU0JqYjIxd2IzTmxRWEpuYzFKcFoyaDBLR0Z5WjNNc0lIQmhjblJwWVd4elVtbG5hSFFzSUdodmJHUmxjbk5TYVdkb2RDazdYRzRnSUNBZ2ZWeHVJQ0FnSUdsbUlDaHBjME4xY25KNUlIeDhJR2x6UTNWeWNubFNhV2RvZENrZ2UxeHVJQ0FnSUNBZ2RtRnlJSEJzWVdObGFHOXNaR1Z5SUQwZ2QzSmhjSEJsY2k1d2JHRmpaV2h2YkdSbGNpeGNiaUFnSUNBZ0lDQWdJQ0JoY21kelNHOXNaR1Z5Y3lBOUlISmxjR3hoWTJWSWIyeGtaWEp6S0dGeVozTXNJSEJzWVdObGFHOXNaR1Z5S1R0Y2JseHVJQ0FnSUNBZ2JHVnVaM1JvSUMwOUlHRnlaM05JYjJ4a1pYSnpMbXhsYm1kMGFEdGNiaUFnSUNBZ0lHbG1JQ2hzWlc1bmRHZ2dQQ0JoY21sMGVTa2dlMXh1SUNBZ0lDQWdJQ0IyWVhJZ2JtVjNRWEpuVUc5eklEMGdZWEpuVUc5eklEOGdZWEp5WVhsRGIzQjVLR0Z5WjFCdmN5a2dPaUIxYm1SbFptbHVaV1FzWEc0Z0lDQWdJQ0FnSUNBZ0lDQnVaWGRCY21sMGVTQTlJRzVoZEdsMlpVMWhlQ2hoY21sMGVTQXRJR3hsYm1kMGFDd2dNQ2tzWEc0Z0lDQWdJQ0FnSUNBZ0lDQnVaWGR6U0c5c1pHVnljeUE5SUdselEzVnljbmtnUHlCaGNtZHpTRzlzWkdWeWN5QTZJSFZ1WkdWbWFXNWxaQ3hjYmlBZ0lDQWdJQ0FnSUNBZ0lHNWxkMGh2YkdSbGNuTlNhV2RvZENBOUlHbHpRM1Z5Y25rZ1B5QjFibVJsWm1sdVpXUWdPaUJoY21kelNHOXNaR1Z5Y3l4Y2JpQWdJQ0FnSUNBZ0lDQWdJRzVsZDFCaGNuUnBZV3h6SUQwZ2FYTkRkWEp5ZVNBL0lHRnlaM01nT2lCMWJtUmxabWx1WldRc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkUVlYSjBhV0ZzYzFKcFoyaDBJRDBnYVhORGRYSnllU0EvSUhWdVpHVm1hVzVsWkNBNklHRnlaM003WEc1Y2JpQWdJQ0FnSUNBZ1ltbDBiV0Z6YXlCOFBTQW9hWE5EZFhKeWVTQS9JRkJCVWxSSlFVeGZSa3hCUnlBNklGQkJVbFJKUVV4ZlVrbEhTRlJmUmt4QlJ5azdYRzRnSUNBZ0lDQWdJR0pwZEcxaGMyc2dKajBnZmlocGMwTjFjbko1SUQ4Z1VFRlNWRWxCVEY5U1NVZElWRjlHVEVGSElEb2dVRUZTVkVsQlRGOUdURUZIS1R0Y2JseHVJQ0FnSUNBZ0lDQnBaaUFvSVdselEzVnljbmxDYjNWdVpDa2dlMXh1SUNBZ0lDQWdJQ0FnSUdKcGRHMWhjMnNnSmowZ2ZpaENTVTVFWDBaTVFVY2dmQ0JDU1U1RVgwdEZXVjlHVEVGSEtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0IyWVhJZ2JtVjNSR0YwWVNBOUlGdG1kVzVqTENCaWFYUnRZWE5yTENCMGFHbHpRWEpuTENCdVpYZFFZWEowYVdGc2N5d2dibVYzYzBodmJHUmxjbk1zSUc1bGQxQmhjblJwWVd4elVtbG5hSFFzSUc1bGQwaHZiR1JsY25OU2FXZG9kQ3dnYm1WM1FYSm5VRzl6TENCaGNua3NJRzVsZDBGeWFYUjVYU3hjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxjM1ZzZENBOUlHTnlaV0YwWlVoNVluSnBaRmR5WVhCd1pYSXVZWEJ3Ykhrb2RXNWtaV1pwYm1Wa0xDQnVaWGRFWVhSaEtUdGNibHh1SUNBZ0lDQWdJQ0JwWmlBb2FYTk1ZWHBwWVdKc1pTaG1kVzVqS1NrZ2UxeHVJQ0FnSUNBZ0lDQWdJSE5sZEVSaGRHRW9jbVZ6ZFd4MExDQnVaWGRFWVhSaEtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0J5WlhOMWJIUXVjR3hoWTJWb2IyeGtaWElnUFNCd2JHRmpaV2h2YkdSbGNqdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlISmxjM1ZzZER0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lDQWdkbUZ5SUhSb2FYTkNhVzVrYVc1bklEMGdhWE5DYVc1a0lEOGdkR2hwYzBGeVp5QTZJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lHWnVJRDBnYVhOQ2FXNWtTMlY1SUQ4Z2RHaHBjMEpwYm1ScGJtZGJablZ1WTEwZ09pQm1kVzVqTzF4dVhHNGdJQ0FnYVdZZ0tHRnlaMUJ2Y3lrZ2UxeHVJQ0FnSUNBZ1lYSm5jeUE5SUhKbGIzSmtaWElvWVhKbmN5d2dZWEpuVUc5ektUdGNiaUFnSUNCOVhHNGdJQ0FnYVdZZ0tHbHpRWEo1SUNZbUlHRnllU0E4SUdGeVozTXViR1Z1WjNSb0tTQjdYRzRnSUNBZ0lDQmhjbWR6TG14bGJtZDBhQ0E5SUdGeWVUdGNiaUFnSUNCOVhHNGdJQ0FnYVdZZ0tIUm9hWE1nSmlZZ2RHaHBjeUFoUFQwZ1oyeHZZbUZzSUNZbUlIUm9hWE1nYVc1emRHRnVZMlZ2WmlCM2NtRndjR1Z5S1NCN1hHNGdJQ0FnSUNCbWJpQTlJRU4wYjNJZ2ZId2dZM0psWVhSbFEzUnZjbGR5WVhCd1pYSW9ablZ1WXlrN1hHNGdJQ0FnZlZ4dUlDQWdJSEpsZEhWeWJpQm1iaTVoY0hCc2VTaDBhR2x6UW1sdVpHbHVaeXdnWVhKbmN5azdYRzRnSUgxY2JpQWdjbVYwZFhKdUlIZHlZWEJ3WlhJN1hHNTlYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpJRDBnWTNKbFlYUmxTSGxpY21sa1YzSmhjSEJsY2p0Y2JpSmRmUT09IiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xudmFyIGNyZWF0ZUN0b3JXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVDdG9yV3JhcHBlcicpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDE7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIG9wdGlvbmFsIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AgYW5kIHRoZSBgcGFydGlhbHNgIHByZXBlbmRlZCB0byB0aG9zZSBwcm92aWRlZCB0b1xuICogdGhlIHdyYXBwZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHBhcnRpYWxseSBhcHBseSBhcmd1bWVudHMgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBvZiBmbGFncy4gU2VlIGBjcmVhdGVXcmFwcGVyYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJvdW5kIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVQYXJ0aWFsV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscykge1xuICB2YXIgaXNCaW5kID0gYml0bWFzayAmIEJJTkRfRkxBRyxcbiAgICAgIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIC8vIEF2b2lkIGBhcmd1bWVudHNgIG9iamVjdCB1c2UgZGlzcXVhbGlmeWluZyBvcHRpbWl6YXRpb25zIGJ5XG4gICAgLy8gY29udmVydGluZyBpdCB0byBhbiBhcnJheSBiZWZvcmUgcHJvdmlkaW5nIGl0IGBmdW5jYC5cbiAgICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICAgIGFyZ3NMZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgICAgbGVmdExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlZnRMZW5ndGggKyBhcmdzTGVuZ3RoKTtcblxuICAgIHdoaWxlICgrK2xlZnRJbmRleCA8IGxlZnRMZW5ndGgpIHtcbiAgICAgIGFyZ3NbbGVmdEluZGV4XSA9IHBhcnRpYWxzW2xlZnRJbmRleF07XG4gICAgfVxuICAgIHdoaWxlIChhcmdzTGVuZ3RoLS0pIHtcbiAgICAgIGFyZ3NbbGVmdEluZGV4KytdID0gYXJndW1lbnRzWysrYXJnc0luZGV4XTtcbiAgICB9XG4gICAgdmFyIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gZ2xvYmFsICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgIHJldHVybiBmbi5hcHBseShpc0JpbmQgPyB0aGlzQXJnIDogdGhpcywgYXJncyk7XG4gIH1cbiAgcmV0dXJuIHdyYXBwZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlUGFydGlhbFdyYXBwZXI7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJOeVpXRjBaVkJoY25ScFlXeFhjbUZ3Y0dWeUxtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SjJZWElnWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElnUFNCeVpYRjFhWEpsS0NjdUwyTnlaV0YwWlVOMGIzSlhjbUZ3Y0dWeUp5azdYRzVjYmk4cUtpQlZjMlZrSUhSdklHTnZiWEJ2YzJVZ1ltbDBiV0Z6YTNNZ1ptOXlJSGR5WVhCd1pYSWdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdRa2xPUkY5R1RFRkhJRDBnTVR0Y2JseHVMeW9xWEc0Z0tpQkRjbVZoZEdWeklHRWdablZ1WTNScGIyNGdkR2hoZENCM2NtRndjeUJnWm5WdVkyQWdZVzVrSUdsdWRtOXJaWE1nYVhRZ2QybDBhQ0IwYUdVZ2IzQjBhVzl1WVd3Z1lIUm9hWE5nWEc0Z0tpQmlhVzVrYVc1bklHOW1JR0IwYUdselFYSm5ZQ0JoYm1RZ2RHaGxJR0J3WVhKMGFXRnNjMkFnY0hKbGNHVnVaR1ZrSUhSdklIUm9iM05sSUhCeWIzWnBaR1ZrSUhSdlhHNGdLaUIwYUdVZ2QzSmhjSEJsY2k1Y2JpQXFYRzRnS2lCQWNISnBkbUYwWlZ4dUlDb2dRSEJoY21GdElIdEdkVzVqZEdsdmJuMGdablZ1WXlCVWFHVWdablZ1WTNScGIyNGdkRzhnY0dGeWRHbGhiR3g1SUdGd2NHeDVJR0Z5WjNWdFpXNTBjeUIwYnk1Y2JpQXFJRUJ3WVhKaGJTQjdiblZ0WW1WeWZTQmlhWFJ0WVhOcklGUm9aU0JpYVhSdFlYTnJJRzltSUdac1lXZHpMaUJUWldVZ1lHTnlaV0YwWlZkeVlYQndaWEpnSUdadmNpQnRiM0psSUdSbGRHRnBiSE11WEc0Z0tpQkFjR0Z5WVcwZ2V5cDlJSFJvYVhOQmNtY2dWR2hsSUdCMGFHbHpZQ0JpYVc1a2FXNW5JRzltSUdCbWRXNWpZQzVjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUhCaGNuUnBZV3h6SUZSb1pTQmhjbWQxYldWdWRITWdkRzhnY0hKbGNHVnVaQ0IwYnlCMGFHOXpaU0J3Y205MmFXUmxaQ0IwYnlCMGFHVWdibVYzSUdaMWJtTjBhVzl1TGx4dUlDb2dRSEpsZEhWeWJuTWdlMFoxYm1OMGFXOXVmU0JTWlhSMWNtNXpJSFJvWlNCdVpYY2dZbTkxYm1RZ1puVnVZM1JwYjI0dVhHNGdLaTljYm1aMWJtTjBhVzl1SUdOeVpXRjBaVkJoY25ScFlXeFhjbUZ3Y0dWeUtHWjFibU1zSUdKcGRHMWhjMnNzSUhSb2FYTkJjbWNzSUhCaGNuUnBZV3h6S1NCN1hHNGdJSFpoY2lCcGMwSnBibVFnUFNCaWFYUnRZWE5ySUNZZ1FrbE9SRjlHVEVGSExGeHVJQ0FnSUNBZ1EzUnZjaUE5SUdOeVpXRjBaVU4wYjNKWGNtRndjR1Z5S0daMWJtTXBPMXh1WEc0Z0lHWjFibU4wYVc5dUlIZHlZWEJ3WlhJb0tTQjdYRzRnSUNBZ0x5OGdRWFp2YVdRZ1lHRnlaM1Z0Wlc1MGMyQWdiMkpxWldOMElIVnpaU0JrYVhOeGRXRnNhV1o1YVc1bklHOXdkR2x0YVhwaGRHbHZibk1nWW5sY2JpQWdJQ0F2THlCamIyNTJaWEowYVc1bklHbDBJSFJ2SUdGdUlHRnljbUY1SUdKbFptOXlaU0J3Y205MmFXUnBibWNnYVhRZ1lHWjFibU5nTGx4dUlDQWdJSFpoY2lCaGNtZHpTVzVrWlhnZ1BTQXRNU3hjYmlBZ0lDQWdJQ0FnWVhKbmMweGxibWQwYUNBOUlHRnlaM1Z0Wlc1MGN5NXNaVzVuZEdnc1hHNGdJQ0FnSUNBZ0lHeGxablJKYm1SbGVDQTlJQzB4TEZ4dUlDQWdJQ0FnSUNCc1pXWjBUR1Z1WjNSb0lEMGdjR0Z5ZEdsaGJITXViR1Z1WjNSb0xGeHVJQ0FnSUNBZ0lDQmhjbWR6SUQwZ1FYSnlZWGtvYkdWbWRFeGxibWQwYUNBcklHRnlaM05NWlc1bmRHZ3BPMXh1WEc0Z0lDQWdkMmhwYkdVZ0tDc3JiR1ZtZEVsdVpHVjRJRHdnYkdWbWRFeGxibWQwYUNrZ2UxeHVJQ0FnSUNBZ1lYSm5jMXRzWldaMFNXNWtaWGhkSUQwZ2NHRnlkR2xoYkhOYmJHVm1kRWx1WkdWNFhUdGNiaUFnSUNCOVhHNGdJQ0FnZDJocGJHVWdLR0Z5WjNOTVpXNW5kR2d0TFNrZ2UxeHVJQ0FnSUNBZ1lYSm5jMXRzWldaMFNXNWtaWGdySzEwZ1BTQmhjbWQxYldWdWRITmJLeXRoY21kelNXNWtaWGhkTzF4dUlDQWdJSDFjYmlBZ0lDQjJZWElnWm00Z1BTQW9kR2hwY3lBbUppQjBhR2x6SUNFOVBTQm5iRzlpWVd3Z0ppWWdkR2hwY3lCcGJuTjBZVzVqWlc5bUlIZHlZWEJ3WlhJcElEOGdRM1J2Y2lBNklHWjFibU03WEc0Z0lDQWdjbVYwZFhKdUlHWnVMbUZ3Y0d4NUtHbHpRbWx1WkNBL0lIUm9hWE5CY21jZ09pQjBhR2x6TENCaGNtZHpLVHRjYmlBZ2ZWeHVJQ0J5WlhSMWNtNGdkM0poY0hCbGNqdGNibjFjYmx4dWJXOWtkV3hsTG1WNGNHOXlkSE1nUFNCamNtVmhkR1ZRWVhKMGFXRnNWM0poY0hCbGNqdGNiaUpkZlE9PSIsInZhciBiYXNlU2V0RGF0YSA9IHJlcXVpcmUoJy4vYmFzZVNldERhdGEnKSxcbiAgICBjcmVhdGVCaW5kV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlQmluZFdyYXBwZXInKSxcbiAgICBjcmVhdGVIeWJyaWRXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVIeWJyaWRXcmFwcGVyJyksXG4gICAgY3JlYXRlUGFydGlhbFdyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZVBhcnRpYWxXcmFwcGVyJyksXG4gICAgZ2V0RGF0YSA9IHJlcXVpcmUoJy4vZ2V0RGF0YScpLFxuICAgIG1lcmdlRGF0YSA9IHJlcXVpcmUoJy4vbWVyZ2VEYXRhJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vc2V0RGF0YScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQklORF9LRVlfRkxBRyA9IDIsXG4gICAgUEFSVElBTF9GTEFHID0gMzIsXG4gICAgUEFSVElBTF9SSUdIVF9GTEFHID0gNjQ7XG5cbi8qKiBVc2VkIGFzIHRoZSBgVHlwZUVycm9yYCBtZXNzYWdlIGZvciBcIkZ1bmN0aW9uc1wiIG1ldGhvZHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGVpdGhlciBjdXJyaWVzIG9yIGludm9rZXMgYGZ1bmNgIHdpdGggb3B0aW9uYWxcbiAqIGB0aGlzYCBiaW5kaW5nIGFuZCBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBvZiBmbGFncy5cbiAqICBUaGUgYml0bWFzayBtYXkgYmUgY29tcG9zZWQgb2YgdGhlIGZvbGxvd2luZyBmbGFnczpcbiAqICAgICAxIC0gYF8uYmluZGBcbiAqICAgICAyIC0gYF8uYmluZEtleWBcbiAqICAgICA0IC0gYF8uY3VycnlgIG9yIGBfLmN1cnJ5UmlnaHRgIG9mIGEgYm91bmQgZnVuY3Rpb25cbiAqICAgICA4IC0gYF8uY3VycnlgXG4gKiAgICAxNiAtIGBfLmN1cnJ5UmlnaHRgXG4gKiAgICAzMiAtIGBfLnBhcnRpYWxgXG4gKiAgICA2NCAtIGBfLnBhcnRpYWxSaWdodGBcbiAqICAgMTI4IC0gYF8ucmVhcmdgXG4gKiAgIDI1NiAtIGBfLmFyeWBcbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgdmFyIGlzQmluZEtleSA9IGJpdG1hc2sgJiBCSU5EX0tFWV9GTEFHO1xuICBpZiAoIWlzQmluZEtleSAmJiB0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHZhciBsZW5ndGggPSBwYXJ0aWFscyA/IHBhcnRpYWxzLmxlbmd0aCA6IDA7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgYml0bWFzayAmPSB+KFBBUlRJQUxfRkxBRyB8IFBBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICB9XG4gIGxlbmd0aCAtPSAoaG9sZGVycyA/IGhvbGRlcnMubGVuZ3RoIDogMCk7XG4gIGlmIChiaXRtYXNrICYgUEFSVElBTF9SSUdIVF9GTEFHKSB7XG4gICAgdmFyIHBhcnRpYWxzUmlnaHQgPSBwYXJ0aWFscyxcbiAgICAgICAgaG9sZGVyc1JpZ2h0ID0gaG9sZGVycztcblxuICAgIHBhcnRpYWxzID0gaG9sZGVycyA9IHVuZGVmaW5lZDtcbiAgfVxuICB2YXIgZGF0YSA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGdldERhdGEoZnVuYyksXG4gICAgICBuZXdEYXRhID0gW2Z1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eV07XG5cbiAgaWYgKGRhdGEpIHtcbiAgICBtZXJnZURhdGEobmV3RGF0YSwgZGF0YSk7XG4gICAgYml0bWFzayA9IG5ld0RhdGFbMV07XG4gICAgYXJpdHkgPSBuZXdEYXRhWzldO1xuICB9XG4gIG5ld0RhdGFbOV0gPSBhcml0eSA9PSBudWxsXG4gICAgPyAoaXNCaW5kS2V5ID8gMCA6IGZ1bmMubGVuZ3RoKVxuICAgIDogKG5hdGl2ZU1heChhcml0eSAtIGxlbmd0aCwgMCkgfHwgMCk7XG5cbiAgaWYgKGJpdG1hc2sgPT0gQklORF9GTEFHKSB7XG4gICAgdmFyIHJlc3VsdCA9IGNyZWF0ZUJpbmRXcmFwcGVyKG5ld0RhdGFbMF0sIG5ld0RhdGFbMl0pO1xuICB9IGVsc2UgaWYgKChiaXRtYXNrID09IFBBUlRJQUxfRkxBRyB8fCBiaXRtYXNrID09IChCSU5EX0ZMQUcgfCBQQVJUSUFMX0ZMQUcpKSAmJiAhbmV3RGF0YVs0XS5sZW5ndGgpIHtcbiAgICByZXN1bHQgPSBjcmVhdGVQYXJ0aWFsV3JhcHBlci5hcHBseSh1bmRlZmluZWQsIG5ld0RhdGEpO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdCA9IGNyZWF0ZUh5YnJpZFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgfVxuICB2YXIgc2V0dGVyID0gZGF0YSA/IGJhc2VTZXREYXRhIDogc2V0RGF0YTtcbiAgcmV0dXJuIHNldHRlcihyZXN1bHQsIG5ld0RhdGEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVdyYXBwZXI7XG4iLCJ2YXIgYXJyYXlTb21lID0gcmVxdWlyZSgnLi9hcnJheVNvbWUnKTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGFycmF5cyB3aXRoIHN1cHBvcnQgZm9yXG4gKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb21wYXJlLlxuICogQHBhcmFtIHtBcnJheX0gb3RoZXIgVGhlIG90aGVyIGFycmF5IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgYXJyYXlzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcnJheXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxBcnJheXMoYXJyYXksIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgYXJyTGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgb3RoTGVuZ3RoID0gb3RoZXIubGVuZ3RoO1xuXG4gIGlmIChhcnJMZW5ndGggIT0gb3RoTGVuZ3RoICYmICEoaXNMb29zZSAmJiBvdGhMZW5ndGggPiBhcnJMZW5ndGgpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIElnbm9yZSBub24taW5kZXggcHJvcGVydGllcy5cbiAgd2hpbGUgKCsraW5kZXggPCBhcnJMZW5ndGgpIHtcbiAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdLFxuICAgICAgICByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcihpc0xvb3NlID8gb3RoVmFsdWUgOiBhcnJWYWx1ZSwgaXNMb29zZSA/IGFyclZhbHVlIDogb3RoVmFsdWUsIGluZGV4KSA6IHVuZGVmaW5lZDtcblxuICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoaXNMb29zZSkge1xuICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uKG90aFZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbiAgICAgICAgICB9KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghKGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fCBlcXVhbEZ1bmMoYXJyVmFsdWUsIG90aFZhbHVlLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsQXJyYXlzO1xuIiwiLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBjb21wYXJpbmcgb2JqZWN0cyBvZlxuICogdGhlIHNhbWUgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNvbXBhcmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE51bWJlcmAsIGBSZWdFeHBgLCBvciBgU3RyaW5nYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0cyB0byBjb21wYXJlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgdGFnKSB7XG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSBib29sVGFnOlxuICAgIGNhc2UgZGF0ZVRhZzpcbiAgICAgIC8vIENvZXJjZSBkYXRlcyBhbmQgYm9vbGVhbnMgdG8gbnVtYmVycywgZGF0ZXMgdG8gbWlsbGlzZWNvbmRzIGFuZCBib29sZWFuc1xuICAgICAgLy8gdG8gYDFgIG9yIGAwYCB0cmVhdGluZyBpbnZhbGlkIGRhdGVzIGNvZXJjZWQgdG8gYE5hTmAgYXMgbm90IGVxdWFsLlxuICAgICAgcmV0dXJuICtvYmplY3QgPT0gK290aGVyO1xuXG4gICAgY2FzZSBlcnJvclRhZzpcbiAgICAgIHJldHVybiBvYmplY3QubmFtZSA9PSBvdGhlci5uYW1lICYmIG9iamVjdC5tZXNzYWdlID09IG90aGVyLm1lc3NhZ2U7XG5cbiAgICBjYXNlIG51bWJlclRhZzpcbiAgICAgIC8vIFRyZWF0IGBOYU5gIHZzLiBgTmFOYCBhcyBlcXVhbC5cbiAgICAgIHJldHVybiAob2JqZWN0ICE9ICtvYmplY3QpXG4gICAgICAgID8gb3RoZXIgIT0gK290aGVyXG4gICAgICAgIDogb2JqZWN0ID09ICtvdGhlcjtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgLy8gQ29lcmNlIHJlZ2V4ZXMgdG8gc3RyaW5ncyBhbmQgdHJlYXQgc3RyaW5ncyBwcmltaXRpdmVzIGFuZCBzdHJpbmdcbiAgICAgIC8vIG9iamVjdHMgYXMgZXF1YWwuIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS4xMC42LjQgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgIHJldHVybiBvYmplY3QgPT0gKG90aGVyICsgJycpO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEJ5VGFnO1xuIiwidmFyIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIG9iamVjdHMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgdmFsdWVzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciBvYmpQcm9wcyA9IGtleXMob2JqZWN0KSxcbiAgICAgIG9iakxlbmd0aCA9IG9ialByb3BzLmxlbmd0aCxcbiAgICAgIG90aFByb3BzID0ga2V5cyhvdGhlciksXG4gICAgICBvdGhMZW5ndGggPSBvdGhQcm9wcy5sZW5ndGg7XG5cbiAgaWYgKG9iakxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIWlzTG9vc2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIGluZGV4ID0gb2JqTGVuZ3RoO1xuICB3aGlsZSAoaW5kZXgtLSkge1xuICAgIHZhciBrZXkgPSBvYmpQcm9wc1tpbmRleF07XG4gICAgaWYgKCEoaXNMb29zZSA/IGtleSBpbiBvdGhlciA6IGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsIGtleSkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHZhciBza2lwQ3RvciA9IGlzTG9vc2U7XG4gIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7XG4gICAga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV0sXG4gICAgICAgIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKGlzTG9vc2UgPyBvdGhWYWx1ZSA6IG9ialZhbHVlLCBpc0xvb3NlPyBvYmpWYWx1ZSA6IG90aFZhbHVlLCBrZXkpIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgaWYgKCEocmVzdWx0ID09PSB1bmRlZmluZWQgPyBlcXVhbEZ1bmMob2JqVmFsdWUsIG90aFZhbHVlLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikgOiByZXN1bHQpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTtcbiAgfVxuICBpZiAoIXNraXBDdG9yKSB7XG4gICAgdmFyIG9iakN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICAgIG90aEN0b3IgPSBvdGhlci5jb25zdHJ1Y3RvcjtcblxuICAgIC8vIE5vbiBgT2JqZWN0YCBvYmplY3QgaW5zdGFuY2VzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWFsLlxuICAgIGlmIChvYmpDdG9yICE9IG90aEN0b3IgJiZcbiAgICAgICAgKCdjb25zdHJ1Y3RvcicgaW4gb2JqZWN0ICYmICdjb25zdHJ1Y3RvcicgaW4gb3RoZXIpICYmXG4gICAgICAgICEodHlwZW9mIG9iakN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBvYmpDdG9yIGluc3RhbmNlb2Ygb2JqQ3RvciAmJlxuICAgICAgICAgIHR5cGVvZiBvdGhDdG9yID09ICdmdW5jdGlvbicgJiYgb3RoQ3RvciBpbnN0YW5jZW9mIG90aEN0b3IpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsT2JqZWN0cztcbiIsInZhciBtZXRhTWFwID0gcmVxdWlyZSgnLi9tZXRhTWFwJyksXG4gICAgbm9vcCA9IHJlcXVpcmUoJy4uL3V0aWxpdHkvbm9vcCcpO1xuXG4vKipcbiAqIEdldHMgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAqL1xudmFyIGdldERhdGEgPSAhbWV0YU1hcCA/IG5vb3AgOiBmdW5jdGlvbihmdW5jKSB7XG4gIHJldHVybiBtZXRhTWFwLmdldChmdW5jKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RGF0YTtcbiIsInZhciByZWFsTmFtZXMgPSByZXF1aXJlKCcuL3JlYWxOYW1lcycpO1xuXG4vKipcbiAqIEdldHMgdGhlIG5hbWUgb2YgYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGZ1bmN0aW9uIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIGdldEZ1bmNOYW1lKGZ1bmMpIHtcbiAgdmFyIHJlc3VsdCA9IChmdW5jLm5hbWUgKyAnJyksXG4gICAgICBhcnJheSA9IHJlYWxOYW1lc1tyZXN1bHRdLFxuICAgICAgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwO1xuXG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIHZhciBkYXRhID0gYXJyYXlbbGVuZ3RoXSxcbiAgICAgICAgb3RoZXJGdW5jID0gZGF0YS5mdW5jO1xuICAgIGlmIChvdGhlckZ1bmMgPT0gbnVsbCB8fCBvdGhlckZ1bmMgPT0gZnVuYykge1xuICAgICAgcmV0dXJuIGRhdGEubmFtZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRGdW5jTmFtZTtcbiIsInZhciBiYXNlUHJvcGVydHkgPSByZXF1aXJlKCcuL2Jhc2VQcm9wZXJ0eScpO1xuXG4vKipcbiAqIEdldHMgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgdmFsdWUgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBhdm9pZCBhIFtKSVQgYnVnXShodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTQyNzkyKVxuICogdGhhdCBhZmZlY3RzIFNhZmFyaSBvbiBhdCBsZWFzdCBpT1MgOC4xLTguMyBBUk02NC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIFwibGVuZ3RoXCIgdmFsdWUuXG4gKi9cbnZhciBnZXRMZW5ndGggPSBiYXNlUHJvcGVydHkoJ2xlbmd0aCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGdldExlbmd0aDtcbiIsInZhciBpc1N0cmljdENvbXBhcmFibGUgPSByZXF1aXJlKCcuL2lzU3RyaWN0Q29tcGFyYWJsZScpLFxuICAgIHBhaXJzID0gcmVxdWlyZSgnLi4vb2JqZWN0L3BhaXJzJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgcHJvcGVyeSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBtYXRjaCBkYXRhIG9mIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBnZXRNYXRjaERhdGEob2JqZWN0KSB7XG4gIHZhciByZXN1bHQgPSBwYWlycyhvYmplY3QpLFxuICAgICAgbGVuZ3RoID0gcmVzdWx0Lmxlbmd0aDtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICByZXN1bHRbbGVuZ3RoXVsyXSA9IGlzU3RyaWN0Q29tcGFyYWJsZShyZXN1bHRbbGVuZ3RoXVsxXSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRNYXRjaERhdGE7XG4iLCJ2YXIgaXNOYXRpdmUgPSByZXF1aXJlKCcuLi9sYW5nL2lzTmF0aXZlJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgbmF0aXZlIGZ1bmN0aW9uIGF0IGBrZXlgIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIG1ldGhvZCB0byBnZXQuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZnVuY3Rpb24gaWYgaXQncyBuYXRpdmUsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIGdldE5hdGl2ZShvYmplY3QsIGtleSkge1xuICB2YXIgdmFsdWUgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICByZXR1cm4gaXNOYXRpdmUodmFsdWUpID8gdmFsdWUgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TmF0aXZlO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgTmFOYCBpcyBmb3VuZCBpbiBgYXJyYXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2VhcmNoLlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIGBOYU5gLCBlbHNlIGAtMWAuXG4gKi9cbmZ1bmN0aW9uIGluZGV4T2ZOYU4oYXJyYXksIGZyb21JbmRleCwgZnJvbVJpZ2h0KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBpbmRleCA9IGZyb21JbmRleCArIChmcm9tUmlnaHQgPyAwIDogLTEpO1xuXG4gIHdoaWxlICgoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpKSB7XG4gICAgdmFyIG90aGVyID0gYXJyYXlbaW5kZXhdO1xuICAgIGlmIChvdGhlciAhPT0gb3RoZXIpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluZGV4T2ZOYU47XG4iLCIvKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBhbiBhcnJheSBjbG9uZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQXJyYXkoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IG5ldyBhcnJheS5jb25zdHJ1Y3RvcihsZW5ndGgpO1xuXG4gIC8vIEFkZCBhcnJheSBwcm9wZXJ0aWVzIGFzc2lnbmVkIGJ5IGBSZWdFeHAjZXhlY2AuXG4gIGlmIChsZW5ndGggJiYgdHlwZW9mIGFycmF5WzBdID09ICdzdHJpbmcnICYmIGhhc093blByb3BlcnR5LmNhbGwoYXJyYXksICdpbmRleCcpKSB7XG4gICAgcmVzdWx0LmluZGV4ID0gYXJyYXkuaW5kZXg7XG4gICAgcmVzdWx0LmlucHV0ID0gYXJyYXkuaW5wdXQ7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVBcnJheTtcbiIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBidWZmZXJDbG9uZSA9IHJlcXVpcmUoJy4vYnVmZmVyQ2xvbmUnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGAgZmxhZ3MgZnJvbSB0aGVpciBjb2VyY2VkIHN0cmluZyB2YWx1ZXMuICovXG52YXIgcmVGbGFncyA9IC9cXHcqJC87XG5cbi8qKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5O1xuXG4vKiogVXNlZCB0byBsb29rdXAgYSB0eXBlIGFycmF5IGNvbnN0cnVjdG9ycyBieSBgdG9TdHJpbmdUYWdgLiAqL1xudmFyIGN0b3JCeVRhZyA9IHt9O1xuY3RvckJ5VGFnW2Zsb2F0MzJUYWddID0gZ2xvYmFsLkZsb2F0MzJBcnJheTtcbmN0b3JCeVRhZ1tmbG9hdDY0VGFnXSA9IGdsb2JhbC5GbG9hdDY0QXJyYXk7XG5jdG9yQnlUYWdbaW50OFRhZ10gPSBnbG9iYWwuSW50OEFycmF5O1xuY3RvckJ5VGFnW2ludDE2VGFnXSA9IGdsb2JhbC5JbnQxNkFycmF5O1xuY3RvckJ5VGFnW2ludDMyVGFnXSA9IGdsb2JhbC5JbnQzMkFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4VGFnXSA9IFVpbnQ4QXJyYXk7XG5jdG9yQnlUYWdbdWludDhDbGFtcGVkVGFnXSA9IGdsb2JhbC5VaW50OENsYW1wZWRBcnJheTtcbmN0b3JCeVRhZ1t1aW50MTZUYWddID0gZ2xvYmFsLlVpbnQxNkFycmF5O1xuY3RvckJ5VGFnW3VpbnQzMlRhZ10gPSBnbG9iYWwuVWludDMyQXJyYXk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lIGJhc2VkIG9uIGl0cyBgdG9TdHJpbmdUYWdgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgY2xvbmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE51bWJlcmAsIGBSZWdFeHBgLCBvciBgU3RyaW5nYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNsb25lLlxuICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0IHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGluaXRpYWxpemVkIGNsb25lLlxuICovXG5mdW5jdGlvbiBpbml0Q2xvbmVCeVRhZyhvYmplY3QsIHRhZywgaXNEZWVwKSB7XG4gIHZhciBDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICByZXR1cm4gYnVmZmVyQ2xvbmUob2JqZWN0KTtcblxuICAgIGNhc2UgYm9vbFRhZzpcbiAgICBjYXNlIGRhdGVUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3IoK29iamVjdCk7XG5cbiAgICBjYXNlIGZsb2F0MzJUYWc6IGNhc2UgZmxvYXQ2NFRhZzpcbiAgICBjYXNlIGludDhUYWc6IGNhc2UgaW50MTZUYWc6IGNhc2UgaW50MzJUYWc6XG4gICAgY2FzZSB1aW50OFRhZzogY2FzZSB1aW50OENsYW1wZWRUYWc6IGNhc2UgdWludDE2VGFnOiBjYXNlIHVpbnQzMlRhZzpcbiAgICAgIC8vIFNhZmFyaSA1IG1vYmlsZSBpbmNvcnJlY3RseSBoYXMgYE9iamVjdGAgYXMgdGhlIGNvbnN0cnVjdG9yIG9mIHR5cGVkIGFycmF5cy5cbiAgICAgIGlmIChDdG9yIGluc3RhbmNlb2YgQ3Rvcikge1xuICAgICAgICBDdG9yID0gY3RvckJ5VGFnW3RhZ107XG4gICAgICB9XG4gICAgICB2YXIgYnVmZmVyID0gb2JqZWN0LmJ1ZmZlcjtcbiAgICAgIHJldHVybiBuZXcgQ3Rvcihpc0RlZXAgPyBidWZmZXJDbG9uZShidWZmZXIpIDogYnVmZmVyLCBvYmplY3QuYnl0ZU9mZnNldCwgb2JqZWN0Lmxlbmd0aCk7XG5cbiAgICBjYXNlIG51bWJlclRhZzpcbiAgICBjYXNlIHN0cmluZ1RhZzpcbiAgICAgIHJldHVybiBuZXcgQ3RvcihvYmplY3QpO1xuXG4gICAgY2FzZSByZWdleHBUYWc6XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IEN0b3Iob2JqZWN0LnNvdXJjZSwgcmVGbGFncy5leGVjKG9iamVjdCkpO1xuICAgICAgcmVzdWx0Lmxhc3RJbmRleCA9IG9iamVjdC5sYXN0SW5kZXg7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVCeVRhZztcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMmx1YVhSRGJHOXVaVUo1VkdGbkxtcHpJbDBzSW01aGJXVnpJanBiWFN3aWJXRndjR2x1WjNNaU9pSTdRVUZCUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZblZtWm1WeVEyeHZibVVnUFNCeVpYRjFhWEpsS0NjdUwySjFabVpsY2tOc2IyNWxKeWs3WEc1Y2JpOHFLaUJnVDJKcVpXTjBJM1J2VTNSeWFXNW5ZQ0J5WlhOMWJIUWdjbVZtWlhKbGJtTmxjeTRnS2k5Y2JuWmhjaUJpYjI5c1ZHRm5JRDBnSjF0dlltcGxZM1FnUW05dmJHVmhibDBuTEZ4dUlDQWdJR1JoZEdWVVlXY2dQU0FuVzI5aWFtVmpkQ0JFWVhSbFhTY3NYRzRnSUNBZ2JuVnRZbVZ5VkdGbklEMGdKMXR2WW1wbFkzUWdUblZ0WW1WeVhTY3NYRzRnSUNBZ2NtVm5aWGh3VkdGbklEMGdKMXR2WW1wbFkzUWdVbVZuUlhod1hTY3NYRzRnSUNBZ2MzUnlhVzVuVkdGbklEMGdKMXR2WW1wbFkzUWdVM1J5YVc1blhTYzdYRzVjYm5aaGNpQmhjbkpoZVVKMVptWmxjbFJoWnlBOUlDZGJiMkpxWldOMElFRnljbUY1UW5WbVptVnlYU2NzWEc0Z0lDQWdabXh2WVhRek1sUmhaeUE5SUNkYmIySnFaV04wSUVac2IyRjBNekpCY25KaGVWMG5MRnh1SUNBZ0lHWnNiMkYwTmpSVVlXY2dQU0FuVzI5aWFtVmpkQ0JHYkc5aGREWTBRWEp5WVhsZEp5eGNiaUFnSUNCcGJuUTRWR0ZuSUQwZ0oxdHZZbXBsWTNRZ1NXNTBPRUZ5Y21GNVhTY3NYRzRnSUNBZ2FXNTBNVFpVWVdjZ1BTQW5XMjlpYW1WamRDQkpiblF4TmtGeWNtRjVYU2NzWEc0Z0lDQWdhVzUwTXpKVVlXY2dQU0FuVzI5aWFtVmpkQ0JKYm5Rek1rRnljbUY1WFNjc1hHNGdJQ0FnZFdsdWREaFVZV2NnUFNBblcyOWlhbVZqZENCVmFXNTBPRUZ5Y21GNVhTY3NYRzRnSUNBZ2RXbHVkRGhEYkdGdGNHVmtWR0ZuSUQwZ0oxdHZZbXBsWTNRZ1ZXbHVkRGhEYkdGdGNHVmtRWEp5WVhsZEp5eGNiaUFnSUNCMWFXNTBNVFpVWVdjZ1BTQW5XMjlpYW1WamRDQlZhVzUwTVRaQmNuSmhlVjBuTEZ4dUlDQWdJSFZwYm5Rek1sUmhaeUE5SUNkYmIySnFaV04wSUZWcGJuUXpNa0Z5Y21GNVhTYzdYRzVjYmk4cUtpQlZjMlZrSUhSdklHMWhkR05vSUdCU1pXZEZlSEJnSUdac1lXZHpJR1p5YjIwZ2RHaGxhWElnWTI5bGNtTmxaQ0J6ZEhKcGJtY2dkbUZzZFdWekxpQXFMMXh1ZG1GeUlISmxSbXhoWjNNZ1BTQXZYRngzS2lRdk8xeHVYRzR2S2lvZ1RtRjBhWFpsSUcxbGRHaHZaQ0J5WldabGNtVnVZMlZ6TGlBcUwxeHVkbUZ5SUZWcGJuUTRRWEp5WVhrZ1BTQm5iRzlpWVd3dVZXbHVkRGhCY25KaGVUdGNibHh1THlvcUlGVnpaV1FnZEc4Z2JHOXZhM1Z3SUdFZ2RIbHdaU0JoY25KaGVTQmpiMjV6ZEhKMVkzUnZjbk1nWW5rZ1lIUnZVM1J5YVc1blZHRm5ZQzRnS2k5Y2JuWmhjaUJqZEc5eVFubFVZV2NnUFNCN2ZUdGNibU4wYjNKQ2VWUmhaMXRtYkc5aGRETXlWR0ZuWFNBOUlHZHNiMkpoYkM1R2JHOWhkRE15UVhKeVlYazdYRzVqZEc5eVFubFVZV2RiWm14dllYUTJORlJoWjEwZ1BTQm5iRzlpWVd3dVJteHZZWFEyTkVGeWNtRjVPMXh1WTNSdmNrSjVWR0ZuVzJsdWREaFVZV2RkSUQwZ1oyeHZZbUZzTGtsdWREaEJjbkpoZVR0Y2JtTjBiM0pDZVZSaFoxdHBiblF4TmxSaFoxMGdQU0JuYkc5aVlXd3VTVzUwTVRaQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0cGJuUXpNbFJoWjEwZ1BTQm5iRzlpWVd3dVNXNTBNekpCY25KaGVUdGNibU4wYjNKQ2VWUmhaMXQxYVc1ME9GUmhaMTBnUFNCVmFXNTBPRUZ5Y21GNU8xeHVZM1J2Y2tKNVZHRm5XM1ZwYm5RNFEyeGhiWEJsWkZSaFoxMGdQU0JuYkc5aVlXd3VWV2x1ZERoRGJHRnRjR1ZrUVhKeVlYazdYRzVqZEc5eVFubFVZV2RiZFdsdWRERTJWR0ZuWFNBOUlHZHNiMkpoYkM1VmFXNTBNVFpCY25KaGVUdGNibU4wYjNKQ2VWUmhaMXQxYVc1ME16SlVZV2RkSUQwZ1oyeHZZbUZzTGxWcGJuUXpNa0Z5Y21GNU8xeHVYRzR2S2lwY2JpQXFJRWx1YVhScFlXeHBlbVZ6SUdGdUlHOWlhbVZqZENCamJHOXVaU0JpWVhObFpDQnZiaUJwZEhNZ1lIUnZVM1J5YVc1blZHRm5ZQzVjYmlBcVhHNGdLaUFxS2s1dmRHVTZLaW9nVkdocGN5Qm1kVzVqZEdsdmJpQnZibXg1SUhOMWNIQnZjblJ6SUdOc2IyNXBibWNnZG1Gc2RXVnpJSGRwZEdnZ2RHRm5jeUJ2Wmx4dUlDb2dZRUp2YjJ4bFlXNWdMQ0JnUkdGMFpXQXNJR0JGY25KdmNtQXNJR0JPZFcxaVpYSmdMQ0JnVW1WblJYaHdZQ3dnYjNJZ1lGTjBjbWx1WjJBdVhHNGdLbHh1SUNvZ1FIQnlhWFpoZEdWY2JpQXFJRUJ3WVhKaGJTQjdUMkpxWldOMGZTQnZZbXBsWTNRZ1ZHaGxJRzlpYW1WamRDQjBieUJqYkc5dVpTNWNiaUFxSUVCd1lYSmhiU0I3YzNSeWFXNW5mU0IwWVdjZ1ZHaGxJR0IwYjFOMGNtbHVaMVJoWjJBZ2IyWWdkR2hsSUc5aWFtVmpkQ0IwYnlCamJHOXVaUzVjYmlBcUlFQndZWEpoYlNCN1ltOXZiR1ZoYm4wZ1cybHpSR1ZsY0YwZ1UzQmxZMmxtZVNCaElHUmxaWEFnWTJ4dmJtVXVYRzRnS2lCQWNtVjBkWEp1Y3lCN1QySnFaV04wZlNCU1pYUjFjbTV6SUhSb1pTQnBibWwwYVdGc2FYcGxaQ0JqYkc5dVpTNWNiaUFxTDF4dVpuVnVZM1JwYjI0Z2FXNXBkRU5zYjI1bFFubFVZV2NvYjJKcVpXTjBMQ0IwWVdjc0lHbHpSR1ZsY0NrZ2UxeHVJQ0IyWVhJZ1EzUnZjaUE5SUc5aWFtVmpkQzVqYjI1emRISjFZM1J2Y2p0Y2JpQWdjM2RwZEdOb0lDaDBZV2NwSUh0Y2JpQWdJQ0JqWVhObElHRnljbUY1UW5WbVptVnlWR0ZuT2x4dUlDQWdJQ0FnY21WMGRYSnVJR0oxWm1abGNrTnNiMjVsS0c5aWFtVmpkQ2s3WEc1Y2JpQWdJQ0JqWVhObElHSnZiMnhVWVdjNlhHNGdJQ0FnWTJGelpTQmtZWFJsVkdGbk9seHVJQ0FnSUNBZ2NtVjBkWEp1SUc1bGR5QkRkRzl5S0N0dlltcGxZM1FwTzF4dVhHNGdJQ0FnWTJGelpTQm1iRzloZERNeVZHRm5PaUJqWVhObElHWnNiMkYwTmpSVVlXYzZYRzRnSUNBZ1kyRnpaU0JwYm5RNFZHRm5PaUJqWVhObElHbHVkREUyVkdGbk9pQmpZWE5sSUdsdWRETXlWR0ZuT2x4dUlDQWdJR05oYzJVZ2RXbHVkRGhVWVdjNklHTmhjMlVnZFdsdWREaERiR0Z0Y0dWa1ZHRm5PaUJqWVhObElIVnBiblF4TmxSaFp6b2dZMkZ6WlNCMWFXNTBNekpVWVdjNlhHNGdJQ0FnSUNBdkx5QlRZV1poY21rZ05TQnRiMkpwYkdVZ2FXNWpiM0p5WldOMGJIa2dhR0Z6SUdCUFltcGxZM1JnSUdGeklIUm9aU0JqYjI1emRISjFZM1J2Y2lCdlppQjBlWEJsWkNCaGNuSmhlWE11WEc0Z0lDQWdJQ0JwWmlBb1EzUnZjaUJwYm5OMFlXNWpaVzltSUVOMGIzSXBJSHRjYmlBZ0lDQWdJQ0FnUTNSdmNpQTlJR04wYjNKQ2VWUmhaMXQwWVdkZE8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2RtRnlJR0oxWm1abGNpQTlJRzlpYW1WamRDNWlkV1ptWlhJN1hHNGdJQ0FnSUNCeVpYUjFjbTRnYm1WM0lFTjBiM0lvYVhORVpXVndJRDhnWW5WbVptVnlRMnh2Ym1Vb1luVm1abVZ5S1NBNklHSjFabVpsY2l3Z2IySnFaV04wTG1KNWRHVlBabVp6WlhRc0lHOWlhbVZqZEM1c1pXNW5kR2dwTzF4dVhHNGdJQ0FnWTJGelpTQnVkVzFpWlhKVVlXYzZYRzRnSUNBZ1kyRnpaU0J6ZEhKcGJtZFVZV2M2WEc0Z0lDQWdJQ0J5WlhSMWNtNGdibVYzSUVOMGIzSW9iMkpxWldOMEtUdGNibHh1SUNBZ0lHTmhjMlVnY21WblpYaHdWR0ZuT2x4dUlDQWdJQ0FnZG1GeUlISmxjM1ZzZENBOUlHNWxkeUJEZEc5eUtHOWlhbVZqZEM1emIzVnlZMlVzSUhKbFJteGhaM011WlhobFl5aHZZbXBsWTNRcEtUdGNiaUFnSUNBZ0lISmxjM1ZzZEM1c1lYTjBTVzVrWlhnZ1BTQnZZbXBsWTNRdWJHRnpkRWx1WkdWNE8xeHVJQ0I5WEc0Z0lISmxkSFZ5YmlCeVpYTjFiSFE3WEc1OVhHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdhVzVwZEVOc2IyNWxRbmxVWVdjN1hHNGlYWDA9IiwiLyoqXG4gKiBJbml0aWFsaXplcyBhbiBvYmplY3QgY2xvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGluaXRpYWxpemVkIGNsb25lLlxuICovXG5mdW5jdGlvbiBpbml0Q2xvbmVPYmplY3Qob2JqZWN0KSB7XG4gIHZhciBDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBpZiAoISh0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IgaW5zdGFuY2VvZiBDdG9yKSkge1xuICAgIEN0b3IgPSBPYmplY3Q7XG4gIH1cbiAgcmV0dXJuIG5ldyBDdG9yO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluaXRDbG9uZU9iamVjdDtcbiIsInZhciBnZXRMZW5ndGggPSByZXF1aXJlKCcuL2dldExlbmd0aCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi9pc0xlbmd0aCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0FycmF5TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiBpc0xlbmd0aChnZXRMZW5ndGgodmFsdWUpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5TGlrZTtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBob3N0IG9iamVjdCBpbiBJRSA8IDkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBob3N0IG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICovXG52YXIgaXNIb3N0T2JqZWN0ID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIE9iamVjdCh7ICd0b1N0cmluZyc6IDAgfSArICcnKTtcbiAgfSBjYXRjaChlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkgeyByZXR1cm4gZmFsc2U7IH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgLy8gSUUgPCA5IHByZXNlbnRzIG1hbnkgaG9zdCBvYmplY3RzIGFzIGBPYmplY3RgIG9iamVjdHMgdGhhdCBjYW4gY29lcmNlXG4gICAgLy8gdG8gc3RyaW5ncyBkZXNwaXRlIGhhdmluZyBpbXByb3Blcmx5IGRlZmluZWQgYHRvU3RyaW5nYCBtZXRob2RzLlxuICAgIHJldHVybiB0eXBlb2YgdmFsdWUudG9TdHJpbmcgIT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgKHZhbHVlICsgJycpID09ICdzdHJpbmcnO1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0hvc3RPYmplY3Q7XG4iLCIvKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovXG52YXIgcmVJc1VpbnQgPSAvXlxcZCskLztcblxuLyoqXG4gKiBVc2VkIGFzIHRoZSBbbWF4aW11bSBsZW5ndGhdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW51bWJlci5tYXhfc2FmZV9pbnRlZ2VyKVxuICogb2YgYW4gYXJyYXktbGlrZSB2YWx1ZS5cbiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBpbmRleC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD1NQVhfU0FGRV9JTlRFR0VSXSBUaGUgdXBwZXIgYm91bmRzIG9mIGEgdmFsaWQgaW5kZXguXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGluZGV4LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkge1xuICB2YWx1ZSA9ICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHwgcmVJc1VpbnQudGVzdCh2YWx1ZSkpID8gK3ZhbHVlIDogLTE7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcbiAgcmV0dXJuIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGg7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcbiIsInZhciBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9pc0luZGV4JyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBwcm92aWRlZCBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIHZhbHVlIGFyZ3VtZW50LlxuICogQHBhcmFtIHsqfSBpbmRleCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIGluZGV4IG9yIGtleSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgb2JqZWN0IGFyZ3VtZW50LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgaW5kZXgsIG9iamVjdCkge1xuICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHR5cGUgPSB0eXBlb2YgaW5kZXg7XG4gIGlmICh0eXBlID09ICdudW1iZXInXG4gICAgICA/IChpc0FycmF5TGlrZShvYmplY3QpICYmIGlzSW5kZXgoaW5kZXgsIG9iamVjdC5sZW5ndGgpKVxuICAgICAgOiAodHlwZSA9PSAnc3RyaW5nJyAmJiBpbmRleCBpbiBvYmplY3QpKSB7XG4gICAgdmFyIG90aGVyID0gb2JqZWN0W2luZGV4XTtcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gKHZhbHVlID09PSBvdGhlcikgOiAob3RoZXIgIT09IG90aGVyKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJdGVyYXRlZUNhbGw7XG4iLCJ2YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG52YXIgcmVJc0RlZXBQcm9wID0gL1xcLnxcXFsoPzpbXltcXF1dKnwoW1wiJ10pKD86KD8hXFwxKVteXFxuXFxcXF18XFxcXC4pKj9cXDEpXFxdLyxcbiAgICByZUlzUGxhaW5Qcm9wID0gL15cXHcqJC87XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCBub3QgYSBwcm9wZXJ0eSBwYXRoLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5IGtleXMgb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNLZXkodmFsdWUsIG9iamVjdCkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgaWYgKCh0eXBlID09ICdzdHJpbmcnICYmIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkpIHx8IHR5cGUgPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHJlc3VsdCA9ICFyZUlzRGVlcFByb3AudGVzdCh2YWx1ZSk7XG4gIHJldHVybiByZXN1bHQgfHwgKG9iamVjdCAhPSBudWxsICYmIHZhbHVlIGluIHRvT2JqZWN0KG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzS2V5O1xuIiwidmFyIExhenlXcmFwcGVyID0gcmVxdWlyZSgnLi9MYXp5V3JhcHBlcicpLFxuICAgIGdldERhdGEgPSByZXF1aXJlKCcuL2dldERhdGEnKSxcbiAgICBnZXRGdW5jTmFtZSA9IHJlcXVpcmUoJy4vZ2V0RnVuY05hbWUnKSxcbiAgICBsb2Rhc2ggPSByZXF1aXJlKCcuLi9jaGFpbi9sb2Rhc2gnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBhIGxhenkgY291bnRlcnBhcnQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzTGF6aWFibGUoZnVuYykge1xuICB2YXIgZnVuY05hbWUgPSBnZXRGdW5jTmFtZShmdW5jKSxcbiAgICAgIG90aGVyID0gbG9kYXNoW2Z1bmNOYW1lXTtcblxuICBpZiAodHlwZW9mIG90aGVyICE9ICdmdW5jdGlvbicgfHwgIShmdW5jTmFtZSBpbiBMYXp5V3JhcHBlci5wcm90b3R5cGUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChmdW5jID09PSBvdGhlcikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHZhciBkYXRhID0gZ2V0RGF0YShvdGhlcik7XG4gIHJldHVybiAhIWRhdGEgJiYgZnVuYyA9PT0gZGF0YVswXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xhemlhYmxlO1xuIiwiLyoqXG4gKiBVc2VkIGFzIHRoZSBbbWF4aW11bSBsZW5ndGhdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW51bWJlci5tYXhfc2FmZV9pbnRlZ2VyKVxuICogb2YgYW4gYXJyYXktbGlrZSB2YWx1ZS5cbiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gaXMgYmFzZWQgb24gW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbGVuZ3RoKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xlbmd0aDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiAhIXZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdExpa2U7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpZiBzdWl0YWJsZSBmb3Igc3RyaWN0XG4gKiAgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgJiYgIWlzT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N0cmljdENvbXBhcmFibGU7XG4iLCJ2YXIgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKSxcbiAgICBjb21wb3NlQXJncyA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3MnKSxcbiAgICBjb21wb3NlQXJnc1JpZ2h0ID0gcmVxdWlyZSgnLi9jb21wb3NlQXJnc1JpZ2h0JyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL3JlcGxhY2VIb2xkZXJzJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMSxcbiAgICBDVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICBDVVJSWV9GTEFHID0gOCxcbiAgICBBUllfRkxBRyA9IDEyOCxcbiAgICBSRUFSR19GTEFHID0gMjU2O1xuXG4vKiogVXNlZCBhcyB0aGUgaW50ZXJuYWwgYXJndW1lbnQgcGxhY2Vob2xkZXIuICovXG52YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKlxuICogTWVyZ2VzIHRoZSBmdW5jdGlvbiBtZXRhZGF0YSBvZiBgc291cmNlYCBpbnRvIGBkYXRhYC5cbiAqXG4gKiBNZXJnaW5nIG1ldGFkYXRhIHJlZHVjZXMgdGhlIG51bWJlciBvZiB3cmFwcGVycyByZXF1aXJlZCB0byBpbnZva2UgYSBmdW5jdGlvbi5cbiAqIFRoaXMgaXMgcG9zc2libGUgYmVjYXVzZSBtZXRob2RzIGxpa2UgYF8uYmluZGAsIGBfLmN1cnJ5YCwgYW5kIGBfLnBhcnRpYWxgXG4gKiBtYXkgYmUgYXBwbGllZCByZWdhcmRsZXNzIG9mIGV4ZWN1dGlvbiBvcmRlci4gTWV0aG9kcyBsaWtlIGBfLmFyeWAgYW5kIGBfLnJlYXJnYFxuICogYXVnbWVudCBmdW5jdGlvbiBhcmd1bWVudHMsIG1ha2luZyB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgZXhlY3V0ZWQgaW1wb3J0YW50LFxuICogcHJldmVudGluZyB0aGUgbWVyZ2luZyBvZiBtZXRhZGF0YS4gSG93ZXZlciwgd2UgbWFrZSBhbiBleGNlcHRpb24gZm9yIGEgc2FmZVxuICogY29tbW9uIGNhc2Ugd2hlcmUgY3VycmllZCBmdW5jdGlvbnMgaGF2ZSBgXy5hcnlgIGFuZCBvciBgXy5yZWFyZ2AgYXBwbGllZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gZGF0YSBUaGUgZGVzdGluYXRpb24gbWV0YWRhdGEuXG4gKiBAcGFyYW0ge0FycmF5fSBzb3VyY2UgVGhlIHNvdXJjZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgZGF0YWAuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlRGF0YShkYXRhLCBzb3VyY2UpIHtcbiAgdmFyIGJpdG1hc2sgPSBkYXRhWzFdLFxuICAgICAgc3JjQml0bWFzayA9IHNvdXJjZVsxXSxcbiAgICAgIG5ld0JpdG1hc2sgPSBiaXRtYXNrIHwgc3JjQml0bWFzayxcbiAgICAgIGlzQ29tbW9uID0gbmV3Qml0bWFzayA8IEFSWV9GTEFHO1xuXG4gIHZhciBpc0NvbWJvID1cbiAgICAoc3JjQml0bWFzayA9PSBBUllfRkxBRyAmJiBiaXRtYXNrID09IENVUlJZX0ZMQUcpIHx8XG4gICAgKHNyY0JpdG1hc2sgPT0gQVJZX0ZMQUcgJiYgYml0bWFzayA9PSBSRUFSR19GTEFHICYmIGRhdGFbN10ubGVuZ3RoIDw9IHNvdXJjZVs4XSkgfHxcbiAgICAoc3JjQml0bWFzayA9PSAoQVJZX0ZMQUcgfCBSRUFSR19GTEFHKSAmJiBiaXRtYXNrID09IENVUlJZX0ZMQUcpO1xuXG4gIC8vIEV4aXQgZWFybHkgaWYgbWV0YWRhdGEgY2FuJ3QgYmUgbWVyZ2VkLlxuICBpZiAoIShpc0NvbW1vbiB8fCBpc0NvbWJvKSkge1xuICAgIHJldHVybiBkYXRhO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYHRoaXNBcmdgIGlmIGF2YWlsYWJsZS5cbiAgaWYgKHNyY0JpdG1hc2sgJiBCSU5EX0ZMQUcpIHtcbiAgICBkYXRhWzJdID0gc291cmNlWzJdO1xuICAgIC8vIFNldCB3aGVuIGN1cnJ5aW5nIGEgYm91bmQgZnVuY3Rpb24uXG4gICAgbmV3Qml0bWFzayB8PSAoYml0bWFzayAmIEJJTkRfRkxBRykgPyAwIDogQ1VSUllfQk9VTkRfRkxBRztcbiAgfVxuICAvLyBDb21wb3NlIHBhcnRpYWwgYXJndW1lbnRzLlxuICB2YXIgdmFsdWUgPSBzb3VyY2VbM107XG4gIGlmICh2YWx1ZSkge1xuICAgIHZhciBwYXJ0aWFscyA9IGRhdGFbM107XG4gICAgZGF0YVszXSA9IHBhcnRpYWxzID8gY29tcG9zZUFyZ3MocGFydGlhbHMsIHZhbHVlLCBzb3VyY2VbNF0pIDogYXJyYXlDb3B5KHZhbHVlKTtcbiAgICBkYXRhWzRdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzNdLCBQTEFDRUhPTERFUikgOiBhcnJheUNvcHkoc291cmNlWzRdKTtcbiAgfVxuICAvLyBDb21wb3NlIHBhcnRpYWwgcmlnaHQgYXJndW1lbnRzLlxuICB2YWx1ZSA9IHNvdXJjZVs1XTtcbiAgaWYgKHZhbHVlKSB7XG4gICAgcGFydGlhbHMgPSBkYXRhWzVdO1xuICAgIGRhdGFbNV0gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzUmlnaHQocGFydGlhbHMsIHZhbHVlLCBzb3VyY2VbNl0pIDogYXJyYXlDb3B5KHZhbHVlKTtcbiAgICBkYXRhWzZdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzVdLCBQTEFDRUhPTERFUikgOiBhcnJheUNvcHkoc291cmNlWzZdKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcmdQb3NgIGlmIGF2YWlsYWJsZS5cbiAgdmFsdWUgPSBzb3VyY2VbN107XG4gIGlmICh2YWx1ZSkge1xuICAgIGRhdGFbN10gPSBhcnJheUNvcHkodmFsdWUpO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYGFyeWAgaWYgaXQncyBzbWFsbGVyLlxuICBpZiAoc3JjQml0bWFzayAmIEFSWV9GTEFHKSB7XG4gICAgZGF0YVs4XSA9IGRhdGFbOF0gPT0gbnVsbCA/IHNvdXJjZVs4XSA6IG5hdGl2ZU1pbihkYXRhWzhdLCBzb3VyY2VbOF0pO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYGFyaXR5YCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkLlxuICBpZiAoZGF0YVs5XSA9PSBudWxsKSB7XG4gICAgZGF0YVs5XSA9IHNvdXJjZVs5XTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBmdW5jYCBhbmQgbWVyZ2UgYml0bWFza3MuXG4gIGRhdGFbMF0gPSBzb3VyY2VbMF07XG4gIGRhdGFbMV0gPSBuZXdCaXRtYXNrO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1lcmdlRGF0YTtcbiIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL2dldE5hdGl2ZScpO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFdlYWtNYXAgPSBnZXROYXRpdmUoZ2xvYmFsLCAnV2Vha01hcCcpO1xuXG4vKiogVXNlZCB0byBzdG9yZSBmdW5jdGlvbiBtZXRhZGF0YS4gKi9cbnZhciBtZXRhTWFwID0gV2Vha01hcCAmJiBuZXcgV2Vha01hcDtcblxubW9kdWxlLmV4cG9ydHMgPSBtZXRhTWFwO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wyMWxkR0ZOWVhBdWFuTWlYU3dpYm1GdFpYTWlPbHRkTENKdFlYQndhVzVuY3lJNklqdEJRVUZCTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SjJZWElnWjJWMFRtRjBhWFpsSUQwZ2NtVnhkV2x5WlNnbkxpOW5aWFJPWVhScGRtVW5LVHRjYmx4dUx5b3FJRTVoZEdsMlpTQnRaWFJvYjJRZ2NtVm1aWEpsYm1ObGN5NGdLaTljYm5aaGNpQlhaV0ZyVFdGd0lEMGdaMlYwVG1GMGFYWmxLR2RzYjJKaGJDd2dKMWRsWVd0TllYQW5LVHRjYmx4dUx5b3FJRlZ6WldRZ2RHOGdjM1J2Y21VZ1puVnVZM1JwYjI0Z2JXVjBZV1JoZEdFdUlDb3ZYRzUyWVhJZ2JXVjBZVTFoY0NBOUlGZGxZV3ROWVhBZ0ppWWdibVYzSUZkbFlXdE5ZWEE3WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ2JXVjBZVTFoY0R0Y2JpSmRmUT09IiwiLyoqIFVzZWQgdG8gbG9va3VwIHVubWluaWZpZWQgZnVuY3Rpb24gbmFtZXMuICovXG52YXIgcmVhbE5hbWVzID0ge307XG5cbm1vZHVsZS5leHBvcnRzID0gcmVhbE5hbWVzO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vaXNJbmRleCcpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1pbiA9IE1hdGgubWluO1xuXG4vKipcbiAqIFJlb3JkZXIgYGFycmF5YCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBpbmRleGVzIHdoZXJlIHRoZSBlbGVtZW50IGF0XG4gKiB0aGUgZmlyc3QgaW5kZXggaXMgYXNzaWduZWQgYXMgdGhlIGZpcnN0IGVsZW1lbnQsIHRoZSBlbGVtZW50IGF0XG4gKiB0aGUgc2Vjb25kIGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBzZWNvbmQgZWxlbWVudCwgYW5kIHNvIG9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcmVvcmRlci5cbiAqIEBwYXJhbSB7QXJyYXl9IGluZGV4ZXMgVGhlIGFycmFuZ2VkIGFycmF5IGluZGV4ZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gcmVvcmRlcihhcnJheSwgaW5kZXhlcykge1xuICB2YXIgYXJyTGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gbmF0aXZlTWluKGluZGV4ZXMubGVuZ3RoLCBhcnJMZW5ndGgpLFxuICAgICAgb2xkQXJyYXkgPSBhcnJheUNvcHkoYXJyYXkpO1xuXG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIHZhciBpbmRleCA9IGluZGV4ZXNbbGVuZ3RoXTtcbiAgICBhcnJheVtsZW5ndGhdID0gaXNJbmRleChpbmRleCwgYXJyTGVuZ3RoKSA/IG9sZEFycmF5W2luZGV4XSA6IHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVvcmRlcjtcbiIsIi8qKiBVc2VkIGFzIHRoZSBpbnRlcm5hbCBhcmd1bWVudCBwbGFjZWhvbGRlci4gKi9cbnZhciBQTEFDRUhPTERFUiA9ICdfX2xvZGFzaF9wbGFjZWhvbGRlcl9fJztcblxuLyoqXG4gKiBSZXBsYWNlcyBhbGwgYHBsYWNlaG9sZGVyYCBlbGVtZW50cyBpbiBgYXJyYXlgIHdpdGggYW4gaW50ZXJuYWwgcGxhY2Vob2xkZXJcbiAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZWlyIGluZGV4ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB0byByZXBsYWNlLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqL1xuZnVuY3Rpb24gcmVwbGFjZUhvbGRlcnMoYXJyYXksIHBsYWNlaG9sZGVyKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgcmVzSW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKGFycmF5W2luZGV4XSA9PT0gcGxhY2Vob2xkZXIpIHtcbiAgICAgIGFycmF5W2luZGV4XSA9IFBMQUNFSE9MREVSO1xuICAgICAgcmVzdWx0WysrcmVzSW5kZXhdID0gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVwbGFjZUhvbGRlcnM7XG4iLCJ2YXIgYmFzZVNldERhdGEgPSByZXF1aXJlKCcuL2Jhc2VTZXREYXRhJyksXG4gICAgbm93ID0gcmVxdWlyZSgnLi4vZGF0ZS9ub3cnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IHdoZW4gYSBmdW5jdGlvbiBiZWNvbWVzIGhvdC4gKi9cbnZhciBIT1RfQ09VTlQgPSAxNTAsXG4gICAgSE9UX1NQQU4gPSAxNjtcblxuLyoqXG4gKiBTZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKlxuICogKipOb3RlOioqIElmIHRoaXMgZnVuY3Rpb24gYmVjb21lcyBob3QsIGkuZS4gaXMgaW52b2tlZCBhIGxvdCBpbiBhIHNob3J0XG4gKiBwZXJpb2Qgb2YgdGltZSwgaXQgd2lsbCB0cmlwIGl0cyBicmVha2VyIGFuZCB0cmFuc2l0aW9uIHRvIGFuIGlkZW50aXR5IGZ1bmN0aW9uXG4gKiB0byBhdm9pZCBnYXJiYWdlIGNvbGxlY3Rpb24gcGF1c2VzIGluIFY4LiBTZWUgW1Y4IGlzc3VlIDIwNzBdKGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMDcwKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAqL1xudmFyIHNldERhdGEgPSAoZnVuY3Rpb24oKSB7XG4gIHZhciBjb3VudCA9IDAsXG4gICAgICBsYXN0Q2FsbGVkID0gMDtcblxuICByZXR1cm4gZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIHZhciBzdGFtcCA9IG5vdygpLFxuICAgICAgICByZW1haW5pbmcgPSBIT1RfU1BBTiAtIChzdGFtcCAtIGxhc3RDYWxsZWQpO1xuXG4gICAgbGFzdENhbGxlZCA9IHN0YW1wO1xuICAgIGlmIChyZW1haW5pbmcgPiAwKSB7XG4gICAgICBpZiAoKytjb3VudCA+PSBIT1RfQ09VTlQpIHtcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY291bnQgPSAwO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZVNldERhdGEoa2V5LCB2YWx1ZSk7XG4gIH07XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNldERhdGE7XG4iLCJ2YXIgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJndW1lbnRzJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzSW5kZXggPSByZXF1aXJlKCcuL2lzSW5kZXgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICBrZXlzSW4gPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5c0luJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgZmFsbGJhY2sgaW1wbGVtZW50YXRpb24gb2YgYE9iamVjdC5rZXlzYCB3aGljaCBjcmVhdGVzIGFuIGFycmF5IG9mIHRoZVxuICogb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIHNoaW1LZXlzKG9iamVjdCkge1xuICB2YXIgcHJvcHMgPSBrZXlzSW4ob2JqZWN0KSxcbiAgICAgIHByb3BzTGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gcHJvcHNMZW5ndGggJiYgb2JqZWN0Lmxlbmd0aDtcblxuICB2YXIgYWxsb3dJbmRleGVzID0gISFsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSB8fCBpc1N0cmluZyhvYmplY3QpKTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgcHJvcHNMZW5ndGgpIHtcbiAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgIGlmICgoYWxsb3dJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkge1xuICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaGltS2V5cztcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICBzdXBwb3J0ID0gcmVxdWlyZSgnLi4vc3VwcG9ydCcpO1xuXG4vKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYW4gb2JqZWN0IGlmIGl0J3Mgbm90IG9uZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gdG9PYmplY3QodmFsdWUpIHtcbiAgaWYgKHN1cHBvcnQudW5pbmRleGVkQ2hhcnMgJiYgaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IHZhbHVlLmxlbmd0aCxcbiAgICAgICAgcmVzdWx0ID0gT2JqZWN0KHZhbHVlKTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICByZXN1bHRbaW5kZXhdID0gdmFsdWUuY2hhckF0KGluZGV4KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICByZXR1cm4gaXNPYmplY3QodmFsdWUpID8gdmFsdWUgOiBPYmplY3QodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvT2JqZWN0O1xuIiwidmFyIGJhc2VUb1N0cmluZyA9IHJlcXVpcmUoJy4vYmFzZVRvU3RyaW5nJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpO1xuXG4vKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG52YXIgcmVQcm9wTmFtZSA9IC9bXi5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXG5cXFxcXXxcXFxcLikqPylcXDIpXFxdL2c7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlRXNjYXBlQ2hhciA9IC9cXFxcKFxcXFwpPy9nO1xuXG4vKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gcHJvcGVydHkgcGF0aCBhcnJheSBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIHRvUGF0aCh2YWx1ZSkge1xuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBiYXNlVG9TdHJpbmcodmFsdWUpLnJlcGxhY2UocmVQcm9wTmFtZSwgZnVuY3Rpb24obWF0Y2gsIG51bWJlciwgcXVvdGUsIHN0cmluZykge1xuICAgIHJlc3VsdC5wdXNoKHF1b3RlID8gc3RyaW5nLnJlcGxhY2UocmVFc2NhcGVDaGFyLCAnJDEnKSA6IChudW1iZXIgfHwgbWF0Y2gpKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdG9QYXRoO1xuIiwidmFyIExhenlXcmFwcGVyID0gcmVxdWlyZSgnLi9MYXp5V3JhcHBlcicpLFxuICAgIExvZGFzaFdyYXBwZXIgPSByZXF1aXJlKCcuL0xvZGFzaFdyYXBwZXInKSxcbiAgICBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgd3JhcHBlcmAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSB3cmFwcGVyIFRoZSB3cmFwcGVyIHRvIGNsb25lLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHdyYXBwZXIuXG4gKi9cbmZ1bmN0aW9uIHdyYXBwZXJDbG9uZSh3cmFwcGVyKSB7XG4gIHJldHVybiB3cmFwcGVyIGluc3RhbmNlb2YgTGF6eVdyYXBwZXJcbiAgICA/IHdyYXBwZXIuY2xvbmUoKVxuICAgIDogbmV3IExvZGFzaFdyYXBwZXIod3JhcHBlci5fX3dyYXBwZWRfXywgd3JhcHBlci5fX2NoYWluX18sIGFycmF5Q29weSh3cmFwcGVyLl9fYWN0aW9uc19fKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gd3JhcHBlckNsb25lO1xuIiwidmFyIGJhc2VDbG9uZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VDbG9uZScpLFxuICAgIGJpbmRDYWxsYmFjayA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2JpbmRDYWxsYmFjaycpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBkZWVwIGNsb25lIG9mIGB2YWx1ZWAuIElmIGBjdXN0b21pemVyYCBpcyBwcm92aWRlZCBpdCdzIGludm9rZWRcbiAqIHRvIHByb2R1Y2UgdGhlIGNsb25lZCB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgIGNsb25pbmdcbiAqIGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYFxuICogYW5kIGludm9rZWQgd2l0aCB1cCB0byB0aHJlZSBhcmd1bWVudDsgKHZhbHVlIFssIGluZGV4fGtleSwgb2JqZWN0XSkuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb24gdGhlXG4gKiBbc3RydWN0dXJlZCBjbG9uZSBhbGdvcml0aG1dKGh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw1L2luZnJhc3RydWN0dXJlLmh0bWwjaW50ZXJuYWwtc3RydWN0dXJlZC1jbG9uaW5nLWFsZ29yaXRobSkuXG4gKiBUaGUgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIGBhcmd1bWVudHNgIG9iamVjdHMgYW5kIG9iamVjdHMgY3JlYXRlZCBieVxuICogY29uc3RydWN0b3JzIG90aGVyIHRoYW4gYE9iamVjdGAgYXJlIGNsb25lZCB0byBwbGFpbiBgT2JqZWN0YCBvYmplY3RzLiBBblxuICogZW1wdHkgb2JqZWN0IGlzIHJldHVybmVkIGZvciB1bmNsb25lYWJsZSB2YWx1ZXMgc3VjaCBhcyBmdW5jdGlvbnMsIERPTSBub2RlcyxcbiAqIE1hcHMsIFNldHMsIGFuZCBXZWFrTWFwcy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGRlZXAgY2xvbmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjbG9uaW5nIHZhbHVlcy5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgY3VzdG9taXplcmAuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiB2YXIgZGVlcCA9IF8uY2xvbmVEZWVwKHVzZXJzKTtcbiAqIGRlZXBbMF0gPT09IHVzZXJzWzBdO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiAvLyB1c2luZyBhIGN1c3RvbWl6ZXIgY2FsbGJhY2tcbiAqIHZhciBlbCA9IF8uY2xvbmVEZWVwKGRvY3VtZW50LmJvZHksIGZ1bmN0aW9uKHZhbHVlKSB7XG4gKiAgIGlmIChfLmlzRWxlbWVudCh2YWx1ZSkpIHtcbiAqICAgICByZXR1cm4gdmFsdWUuY2xvbmVOb2RlKHRydWUpO1xuICogICB9XG4gKiB9KTtcbiAqXG4gKiBlbCA9PT0gZG9jdW1lbnQuYm9keVxuICogLy8gPT4gZmFsc2VcbiAqIGVsLm5vZGVOYW1lXG4gKiAvLyA9PiBCT0RZXG4gKiBlbC5jaGlsZE5vZGVzLmxlbmd0aDtcbiAqIC8vID0+IDIwXG4gKi9cbmZ1bmN0aW9uIGNsb25lRGVlcCh2YWx1ZSwgY3VzdG9taXplciwgdGhpc0FyZykge1xuICByZXR1cm4gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJ1xuICAgID8gYmFzZUNsb25lKHZhbHVlLCB0cnVlLCBiaW5kQ2FsbGJhY2soY3VzdG9taXplciwgdGhpc0FyZywgMykpXG4gICAgOiBiYXNlQ2xvbmUodmFsdWUsIHRydWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lRGVlcDtcbiIsInZhciBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8ucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhbiBgYXJndW1lbnRzYCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FyZ3VtZW50cyhbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNBcnJheUxpa2UodmFsdWUpICYmXG4gICAgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmICFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcmd1bWVudHM7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvZ2V0TmF0aXZlJyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0xlbmd0aCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVJc0FycmF5ID0gZ2V0TmF0aXZlKEFycmF5LCAnaXNBcnJheScpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheShmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0FycmF5ID0gbmF0aXZlSXNBcnJheSB8fCBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IGFycmF5VGFnO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5O1xuIiwidmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNGdW5jdGlvbiA9IHJlcXVpcmUoJy4vaXNGdW5jdGlvbicpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpLFxuICAgIGlzU3RyaW5nID0gcmVxdWlyZSgnLi9pc1N0cmluZycpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGVtcHR5LiBBIHZhbHVlIGlzIGNvbnNpZGVyZWQgZW1wdHkgdW5sZXNzIGl0J3MgYW5cbiAqIGBhcmd1bWVudHNgIG9iamVjdCwgYXJyYXksIHN0cmluZywgb3IgalF1ZXJ5LWxpa2UgY29sbGVjdGlvbiB3aXRoIGEgbGVuZ3RoXG4gKiBncmVhdGVyIHRoYW4gYDBgIG9yIGFuIG9iamVjdCB3aXRoIG93biBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZW1wdHksIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0VtcHR5KG51bGwpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNFbXB0eSh0cnVlKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRW1wdHkoMSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0VtcHR5KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNFbXB0eSh7ICdhJzogMSB9KTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRW1wdHkodmFsdWUpIHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoaXNBcnJheUxpa2UodmFsdWUpICYmIChpc0FycmF5KHZhbHVlKSB8fCBpc1N0cmluZyh2YWx1ZSkgfHwgaXNBcmd1bWVudHModmFsdWUpIHx8XG4gICAgICAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBpc0Z1bmN0aW9uKHZhbHVlLnNwbGljZSkpKSkge1xuICAgIHJldHVybiAhdmFsdWUubGVuZ3RoO1xuICB9XG4gIHJldHVybiAha2V5cyh2YWx1ZSkubGVuZ3RoO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRW1wdHk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBGdW5jdGlvbmAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oXyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0Z1bmN0aW9uKC9hYmMvKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHtcbiAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gIC8vIGluIG9sZGVyIHZlcnNpb25zIG9mIENocm9tZSBhbmQgU2FmYXJpIHdoaWNoIHJldHVybiAnZnVuY3Rpb24nIGZvciByZWdleGVzXG4gIC8vIGFuZCBTYWZhcmkgOCB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheSBjb25zdHJ1Y3RvcnMuXG4gIHJldHVybiBpc09iamVjdCh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gZnVuY1RhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0Z1bmN0aW9uO1xuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0hvc3RPYmplY3QnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGhvc3QgY29uc3RydWN0b3JzIChTYWZhcmkgPiA1KS4gKi9cbnZhciByZUlzSG9zdEN0b3IgPSAvXlxcW29iamVjdCAuKz9Db25zdHJ1Y3RvclxcXSQvO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xudmFyIGZuVG9TdHJpbmcgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG52YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICBmblRvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpLnJlcGxhY2UoL1tcXFxcXiQuKis/KClbXFxde318XS9nLCAnXFxcXCQmJylcbiAgLnJlcGxhY2UoL2hhc093blByb3BlcnR5fChmdW5jdGlvbikuKj8oPz1cXFxcXFwoKXwgZm9yIC4rPyg/PVxcXFxcXF0pL2csICckMS4qPycpICsgJyQnXG4pO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbiwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzTmF0aXZlKEFycmF5LnByb3RvdHlwZS5wdXNoKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzTmF0aXZlKF8pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNOYXRpdmUodmFsdWUpIHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgcmV0dXJuIHJlSXNOYXRpdmUudGVzdChmblRvU3RyaW5nLmNhbGwodmFsdWUpKTtcbiAgfVxuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAoaXNIb3N0T2JqZWN0KHZhbHVlKSA/IHJlSXNOYXRpdmUgOiByZUlzSG9zdEN0b3IpLnRlc3QodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzTmF0aXZlO1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGUgW2xhbmd1YWdlIHR5cGVdKGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDgpIG9mIGBPYmplY3RgLlxuICogKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdCgxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gIC8vIEF2b2lkIGEgVjggSklUIGJ1ZyBpbiBDaHJvbWUgMTktMjAuXG4gIC8vIFNlZSBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjI5MSBmb3IgbW9yZSBkZXRhaWxzLlxuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdDtcbiIsInZhciBiYXNlRm9ySW4gPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRm9ySW4nKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0hvc3RPYmplY3QnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICBzdXBwb3J0ID0gcmVxdWlyZSgnLi4vc3VwcG9ydCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcGxhaW4gb2JqZWN0LCB0aGF0IGlzLCBhbiBvYmplY3QgY3JlYXRlZCBieSB0aGVcbiAqIGBPYmplY3RgIGNvbnN0cnVjdG9yIG9yIG9uZSB3aXRoIGEgYFtbUHJvdG90eXBlXV1gIG9mIGBudWxsYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgYXNzdW1lcyBvYmplY3RzIGNyZWF0ZWQgYnkgdGhlIGBPYmplY3RgIGNvbnN0cnVjdG9yXG4gKiBoYXZlIG5vIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcGxhaW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqIH1cbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QobmV3IEZvbyk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNQbGFpbk9iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QoeyAneCc6IDAsICd5JzogMCB9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QoT2JqZWN0LmNyZWF0ZShudWxsKSk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgdmFyIEN0b3I7XG5cbiAgLy8gRXhpdCBlYXJseSBmb3Igbm9uIGBPYmplY3RgIG9iamVjdHMuXG4gIGlmICghKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gb2JqZWN0VGFnICYmICFpc0hvc3RPYmplY3QodmFsdWUpICYmICFpc0FyZ3VtZW50cyh2YWx1ZSkpIHx8XG4gICAgICAoIWhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdjb25zdHJ1Y3RvcicpICYmIChDdG9yID0gdmFsdWUuY29uc3RydWN0b3IsIHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgIShDdG9yIGluc3RhbmNlb2YgQ3RvcikpKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBJRSA8IDkgaXRlcmF0ZXMgaW5oZXJpdGVkIHByb3BlcnRpZXMgYmVmb3JlIG93biBwcm9wZXJ0aWVzLiBJZiB0aGUgZmlyc3RcbiAgLy8gaXRlcmF0ZWQgcHJvcGVydHkgaXMgYW4gb2JqZWN0J3Mgb3duIHByb3BlcnR5IHRoZW4gdGhlcmUgYXJlIG5vIGluaGVyaXRlZFxuICAvLyBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gIHZhciByZXN1bHQ7XG4gIGlmIChzdXBwb3J0Lm93bkxhc3QpIHtcbiAgICBiYXNlRm9ySW4odmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXksIG9iamVjdCkge1xuICAgICAgcmVzdWx0ID0gaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdCAhPT0gZmFsc2U7XG4gIH1cbiAgLy8gSW4gbW9zdCBlbnZpcm9ubWVudHMgYW4gb2JqZWN0J3Mgb3duIHByb3BlcnRpZXMgYXJlIGl0ZXJhdGVkIGJlZm9yZVxuICAvLyBpdHMgaW5oZXJpdGVkIHByb3BlcnRpZXMuIElmIHRoZSBsYXN0IGl0ZXJhdGVkIHByb3BlcnR5IGlzIGFuIG9iamVjdCdzXG4gIC8vIG93biBwcm9wZXJ0eSB0aGVuIHRoZXJlIGFyZSBubyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICBiYXNlRm9ySW4odmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHQgPSBrZXk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgfHwgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgcmVzdWx0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1BsYWluT2JqZWN0O1xuIiwidmFyIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3RyaW5nYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzU3RyaW5nKCdhYmMnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzU3RyaW5nKDEpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTdHJpbmcodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fCAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBzdHJpbmdUYWcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzU3RyaW5nO1xuIiwidmFyIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICB3ZWFrTWFwVGFnID0gJ1tvYmplY3QgV2Vha01hcF0nO1xuXG52YXIgYXJyYXlCdWZmZXJUYWcgPSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovXG52YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTtcbnR5cGVkQXJyYXlUYWdzW2Zsb2F0MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbZmxvYXQ2NFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xudHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gdHlwZWRBcnJheVRhZ3NbYm9vbFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZGF0ZVRhZ10gPSB0eXBlZEFycmF5VGFnc1tlcnJvclRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPSB0eXBlZEFycmF5VGFnc1ttYXBUYWddID1cbnR5cGVkQXJyYXlUYWdzW251bWJlclRhZ10gPSB0eXBlZEFycmF5VGFnc1tvYmplY3RUYWddID1cbnR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZ10gPSB0eXBlZEFycmF5VGFnc1tzZXRUYWddID1cbnR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPSB0eXBlZEFycmF5VGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNUeXBlZEFycmF5KG5ldyBVaW50OEFycmF5KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShbXSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1R5cGVkQXJyYXkodmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhIXR5cGVkQXJyYXlUYWdzW29ialRvU3RyaW5nLmNhbGwodmFsdWUpXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1R5cGVkQXJyYXk7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGB1bmRlZmluZWRgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVW5kZWZpbmVkKHZvaWQgMCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1VuZGVmaW5lZChudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVW5kZWZpbmVkO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNBcnJheUxpa2UnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKSxcbiAgICBzaGltS2V5cyA9IHJlcXVpcmUoJy4uL2ludGVybmFsL3NoaW1LZXlzJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVLZXlzID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2tleXMnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5rZXlzKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy5rZXlzKG5ldyBGb28pO1xuICogLy8gPT4gWydhJywgJ2InXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIF8ua2V5cygnaGknKTtcbiAqIC8vID0+IFsnMCcsICcxJ11cbiAqL1xudmFyIGtleXMgPSAhbmF0aXZlS2V5cyA/IHNoaW1LZXlzIDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIHZhciBDdG9yID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3QuY29uc3RydWN0b3I7XG4gIGlmICgodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSA9PT0gb2JqZWN0KSB8fFxuICAgICAgKHR5cGVvZiBvYmplY3QgPT0gJ2Z1bmN0aW9uJyA/IHN1cHBvcnQuZW51bVByb3RvdHlwZXMgOiBpc0FycmF5TGlrZShvYmplY3QpKSkge1xuICAgIHJldHVybiBzaGltS2V5cyhvYmplY3QpO1xuICB9XG4gIHJldHVybiBpc09iamVjdChvYmplY3QpID8gbmF0aXZlS2V5cyhvYmplY3QpIDogW107XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXM7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlFYWNoJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJndW1lbnRzJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuLi9sYW5nL2lzRnVuY3Rpb24nKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNJbmRleCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICBzdXBwb3J0ID0gcmVxdWlyZSgnLi4vc3VwcG9ydCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbi8qKiBVc2VkIHRvIGZpeCB0aGUgSlNjcmlwdCBgW1tEb250RW51bV1dYCBidWcuICovXG52YXIgc2hhZG93UHJvcHMgPSBbXG4gICdjb25zdHJ1Y3RvcicsICdoYXNPd25Qcm9wZXJ0eScsICdpc1Byb3RvdHlwZU9mJywgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJyxcbiAgJ3RvTG9jYWxlU3RyaW5nJywgJ3RvU3RyaW5nJywgJ3ZhbHVlT2YnXG5dO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGVycm9yUHJvdG8gPSBFcnJvci5wcm90b3R5cGUsXG4gICAgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlLFxuICAgIHN0cmluZ1Byb3RvID0gU3RyaW5nLnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIFVzZWQgdG8gYXZvaWQgaXRlcmF0aW5nIG92ZXIgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBpbiBJRSA8IDkuICovXG52YXIgbm9uRW51bVByb3BzID0ge307XG5ub25FbnVtUHJvcHNbYXJyYXlUYWddID0gbm9uRW51bVByb3BzW2RhdGVUYWddID0gbm9uRW51bVByb3BzW251bWJlclRhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUsICd0b0xvY2FsZVN0cmluZyc6IHRydWUsICd0b1N0cmluZyc6IHRydWUsICd2YWx1ZU9mJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW2Jvb2xUYWddID0gbm9uRW51bVByb3BzW3N0cmluZ1RhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUsICd0b1N0cmluZyc6IHRydWUsICd2YWx1ZU9mJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW2Vycm9yVGFnXSA9IG5vbkVudW1Qcm9wc1tmdW5jVGFnXSA9IG5vbkVudW1Qcm9wc1tyZWdleHBUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlIH07XG5ub25FbnVtUHJvcHNbb2JqZWN0VGFnXSA9IHsgJ2NvbnN0cnVjdG9yJzogdHJ1ZSB9O1xuXG5hcnJheUVhY2goc2hhZG93UHJvcHMsIGZ1bmN0aW9uKGtleSkge1xuICBmb3IgKHZhciB0YWcgaW4gbm9uRW51bVByb3BzKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwobm9uRW51bVByb3BzLCB0YWcpKSB7XG4gICAgICB2YXIgcHJvcHMgPSBub25FbnVtUHJvcHNbdGFnXTtcbiAgICAgIHByb3BzW2tleV0gPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3BzLCBrZXkpO1xuICAgIH1cbiAgfVxufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy5rZXlzSW4obmV3IEZvbyk7XG4gKiAvLyA9PiBbJ2EnLCAnYicsICdjJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqL1xuZnVuY3Rpb24ga2V5c0luKG9iamVjdCkge1xuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gIH1cbiAgdmFyIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7XG5cbiAgbGVuZ3RoID0gKGxlbmd0aCAmJiBpc0xlbmd0aChsZW5ndGgpICYmXG4gICAgKGlzQXJyYXkob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyhvYmplY3QpIHx8IGlzU3RyaW5nKG9iamVjdCkpICYmIGxlbmd0aCkgfHwgMDtcblxuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcixcbiAgICAgIGluZGV4ID0gLTEsXG4gICAgICBwcm90byA9IChpc0Z1bmN0aW9uKEN0b3IpICYmIEN0b3IucHJvdG90eXBlKSB8fCBvYmplY3RQcm90byxcbiAgICAgIGlzUHJvdG8gPSBwcm90byA9PT0gb2JqZWN0LFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgIHNraXBJbmRleGVzID0gbGVuZ3RoID4gMCxcbiAgICAgIHNraXBFcnJvclByb3BzID0gc3VwcG9ydC5lbnVtRXJyb3JQcm9wcyAmJiAob2JqZWN0ID09PSBlcnJvclByb3RvIHx8IG9iamVjdCBpbnN0YW5jZW9mIEVycm9yKSxcbiAgICAgIHNraXBQcm90byA9IHN1cHBvcnQuZW51bVByb3RvdHlwZXMgJiYgaXNGdW5jdGlvbihvYmplY3QpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IChpbmRleCArICcnKTtcbiAgfVxuICAvLyBsb2Rhc2ggc2tpcHMgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgd2hlbiBpdCBpbmZlcnMgaXQncyBpdGVyYXRpbmdcbiAgLy8gb3ZlciBhIGBwcm90b3R5cGVgIG9iamVjdCBiZWNhdXNlIElFIDwgOSBjYW4ndCBzZXQgdGhlIGBbW0VudW1lcmFibGVdXWBcbiAgLy8gYXR0cmlidXRlIG9mIGFuIGV4aXN0aW5nIHByb3BlcnR5IGFuZCB0aGUgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSBvZiBhXG4gIC8vIHByb3RvdHlwZSBkZWZhdWx0cyB0byBub24tZW51bWVyYWJsZS5cbiAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgIGlmICghKHNraXBQcm90byAmJiBrZXkgPT0gJ3Byb3RvdHlwZScpICYmXG4gICAgICAgICEoc2tpcEVycm9yUHJvcHMgJiYgKGtleSA9PSAnbWVzc2FnZScgfHwga2V5ID09ICduYW1lJykpICYmXG4gICAgICAgICEoc2tpcEluZGV4ZXMgJiYgaXNJbmRleChrZXksIGxlbmd0aCkpICYmXG4gICAgICAgICEoa2V5ID09ICdjb25zdHJ1Y3RvcicgJiYgKGlzUHJvdG8gfHwgIWhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIGlmIChzdXBwb3J0Lm5vbkVudW1TaGFkb3dzICYmIG9iamVjdCAhPT0gb2JqZWN0UHJvdG8pIHtcbiAgICB2YXIgdGFnID0gb2JqZWN0ID09PSBzdHJpbmdQcm90byA/IHN0cmluZ1RhZyA6IChvYmplY3QgPT09IGVycm9yUHJvdG8gPyBlcnJvclRhZyA6IG9ialRvU3RyaW5nLmNhbGwob2JqZWN0KSksXG4gICAgICAgIG5vbkVudW1zID0gbm9uRW51bVByb3BzW3RhZ10gfHwgbm9uRW51bVByb3BzW29iamVjdFRhZ107XG5cbiAgICBpZiAodGFnID09IG9iamVjdFRhZykge1xuICAgICAgcHJvdG8gPSBvYmplY3RQcm90bztcbiAgICB9XG4gICAgbGVuZ3RoID0gc2hhZG93UHJvcHMubGVuZ3RoO1xuICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAga2V5ID0gc2hhZG93UHJvcHNbbGVuZ3RoXTtcbiAgICAgIHZhciBub25FbnVtID0gbm9uRW51bXNba2V5XTtcbiAgICAgIGlmICghKGlzUHJvdG8gJiYgbm9uRW51bSkgJiZcbiAgICAgICAgICAobm9uRW51bSA/IGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpIDogb2JqZWN0W2tleV0gIT09IHByb3RvW2tleV0pKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c0luO1xuIiwidmFyIGtleXMgPSByZXF1aXJlKCcuL2tleXMnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHR3byBkaW1lbnNpb25hbCBhcnJheSBvZiB0aGUga2V5LXZhbHVlIHBhaXJzIGZvciBgb2JqZWN0YCxcbiAqIGUuZy4gYFtba2V5MSwgdmFsdWUxXSwgW2tleTIsIHZhbHVlMl1dYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2Yga2V5LXZhbHVlIHBhaXJzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnBhaXJzKHsgJ2Jhcm5leSc6IDM2LCAnZnJlZCc6IDQwIH0pO1xuICogLy8gPT4gW1snYmFybmV5JywgMzZdLCBbJ2ZyZWQnLCA0MF1dIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbmZ1bmN0aW9uIHBhaXJzKG9iamVjdCkge1xuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuXG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcHJvcHMgPSBrZXlzKG9iamVjdCksXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICByZXN1bHRbaW5kZXhdID0gW2tleSwgb2JqZWN0W2tleV1dO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcGFpcnM7XG4iLCJ2YXIgYmFzZVZhbHVlcyA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VWYWx1ZXMnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgdmFsdWVzIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IHZhbHVlcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy52YWx1ZXMobmV3IEZvbyk7XG4gKiAvLyA9PiBbMSwgMl0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLnZhbHVlcygnaGknKTtcbiAqIC8vID0+IFsnaCcsICdpJ11cbiAqL1xuZnVuY3Rpb24gdmFsdWVzKG9iamVjdCkge1xuICByZXR1cm4gYmFzZVZhbHVlcyhvYmplY3QsIGtleXMob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdmFsdWVzO1xuIiwiLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlLFxuICAgIGVycm9yUHJvdG8gPSBFcnJvci5wcm90b3R5cGUsXG4gICAgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8ucHJvcGVydHlJc0VudW1lcmFibGUsXG4gICAgc3BsaWNlID0gYXJyYXlQcm90by5zcGxpY2U7XG5cbi8qKlxuICogQW4gb2JqZWN0IGVudmlyb25tZW50IGZlYXR1cmUgZmxhZ3MuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEB0eXBlIE9iamVjdFxuICovXG52YXIgc3VwcG9ydCA9IHt9O1xuXG4oZnVuY3Rpb24oeCkge1xuICB2YXIgQ3RvciA9IGZ1bmN0aW9uKCkgeyB0aGlzLnggPSB4OyB9LFxuICAgICAgb2JqZWN0ID0geyAnMCc6IHgsICdsZW5ndGgnOiB4IH0sXG4gICAgICBwcm9wcyA9IFtdO1xuXG4gIEN0b3IucHJvdG90eXBlID0geyAndmFsdWVPZic6IHgsICd5JzogeCB9O1xuICBmb3IgKHZhciBrZXkgaW4gbmV3IEN0b3IpIHsgcHJvcHMucHVzaChrZXkpOyB9XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBgbmFtZWAgb3IgYG1lc3NhZ2VgIHByb3BlcnRpZXMgb2YgYEVycm9yLnByb3RvdHlwZWAgYXJlXG4gICAqIGVudW1lcmFibGUgYnkgZGVmYXVsdCAoSUUgPCA5LCBTYWZhcmkgPCA1LjEpLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgXy5zdXBwb3J0XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICovXG4gIHN1cHBvcnQuZW51bUVycm9yUHJvcHMgPSBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKGVycm9yUHJvdG8sICdtZXNzYWdlJykgfHxcbiAgICBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKGVycm9yUHJvdG8sICduYW1lJyk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBgcHJvdG90eXBlYCBwcm9wZXJ0aWVzIGFyZSBlbnVtZXJhYmxlIGJ5IGRlZmF1bHQuXG4gICAqXG4gICAqIEZpcmVmb3ggPCAzLjYsIE9wZXJhID4gOS41MCAtIE9wZXJhIDwgMTEuNjAsIGFuZCBTYWZhcmkgPCA1LjFcbiAgICogKGlmIHRoZSBwcm90b3R5cGUgb3IgYSBwcm9wZXJ0eSBvbiB0aGUgcHJvdG90eXBlIGhhcyBiZWVuIHNldClcbiAgICogaW5jb3JyZWN0bHkgc2V0IHRoZSBgW1tFbnVtZXJhYmxlXV1gIHZhbHVlIG9mIGEgZnVuY3Rpb24ncyBgcHJvdG90eXBlYFxuICAgKiBwcm9wZXJ0eSB0byBgdHJ1ZWAuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5lbnVtUHJvdG90eXBlcyA9IHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoQ3RvciwgJ3Byb3RvdHlwZScpO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgcHJvcGVydGllcyBzaGFkb3dpbmcgdGhvc2Ugb24gYE9iamVjdC5wcm90b3R5cGVgIGFyZSBub24tZW51bWVyYWJsZS5cbiAgICpcbiAgICogSW4gSUUgPCA5IGFuIG9iamVjdCdzIG93biBwcm9wZXJ0aWVzLCBzaGFkb3dpbmcgbm9uLWVudW1lcmFibGUgb25lcyxcbiAgICogYXJlIG1hZGUgbm9uLWVudW1lcmFibGUgYXMgd2VsbCAoYS5rLmEgdGhlIEpTY3JpcHQgYFtbRG9udEVudW1dXWAgYnVnKS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0Lm5vbkVudW1TaGFkb3dzID0gIS92YWx1ZU9mLy50ZXN0KHByb3BzKTtcblxuICAvKipcbiAgICogRGV0ZWN0IGlmIG93biBwcm9wZXJ0aWVzIGFyZSBpdGVyYXRlZCBhZnRlciBpbmhlcml0ZWQgcHJvcGVydGllcyAoSUUgPCA5KS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0Lm93bkxhc3QgPSBwcm9wc1swXSAhPSAneCc7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBgQXJyYXkjc2hpZnRgIGFuZCBgQXJyYXkjc3BsaWNlYCBhdWdtZW50IGFycmF5LWxpa2Ugb2JqZWN0c1xuICAgKiBjb3JyZWN0bHkuXG4gICAqXG4gICAqIEZpcmVmb3ggPCAxMCwgY29tcGF0aWJpbGl0eSBtb2RlcyBvZiBJRSA4LCBhbmQgSUUgPCA5IGhhdmUgYnVnZ3kgQXJyYXlcbiAgICogYHNoaWZ0KClgIGFuZCBgc3BsaWNlKClgIGZ1bmN0aW9ucyB0aGF0IGZhaWwgdG8gcmVtb3ZlIHRoZSBsYXN0IGVsZW1lbnQsXG4gICAqIGB2YWx1ZVswXWAsIG9mIGFycmF5LWxpa2Ugb2JqZWN0cyBldmVuIHRob3VnaCB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSBpc1xuICAgKiBzZXQgdG8gYDBgLiBUaGUgYHNoaWZ0KClgIG1ldGhvZCBpcyBidWdneSBpbiBjb21wYXRpYmlsaXR5IG1vZGVzIG9mIElFIDgsXG4gICAqIHdoaWxlIGBzcGxpY2UoKWAgaXMgYnVnZ3kgcmVnYXJkbGVzcyBvZiBtb2RlIGluIElFIDwgOS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LnNwbGljZU9iamVjdHMgPSAoc3BsaWNlLmNhbGwob2JqZWN0LCAwLCAxKSwgIW9iamVjdFswXSk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBsYWNrIG9mIHN1cHBvcnQgZm9yIGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyBieSBpbmRleC5cbiAgICpcbiAgICogSUUgPCA4IGNhbid0IGFjY2VzcyBjaGFyYWN0ZXJzIGJ5IGluZGV4LiBJRSA4IGNhbiBvbmx5IGFjY2VzcyBjaGFyYWN0ZXJzXG4gICAqIGJ5IGluZGV4IG9uIHN0cmluZyBsaXRlcmFscywgbm90IHN0cmluZyBvYmplY3RzLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgXy5zdXBwb3J0XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICovXG4gIHN1cHBvcnQudW5pbmRleGVkQ2hhcnMgPSAoJ3gnWzBdICsgT2JqZWN0KCd4JylbMF0pICE9ICd4eCc7XG59KDEsIDApKTtcblxubW9kdWxlLmV4cG9ydHMgPSBzdXBwb3J0O1xuIiwiLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBmaXJzdCBhcmd1bWVudCBwcm92aWRlZCB0byBpdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFV0aWxpdHlcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgQW55IHZhbHVlLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgYHZhbHVlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiBfLmlkZW50aXR5KG9iamVjdCkgPT09IG9iamVjdDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaWRlbnRpdHkodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlkZW50aXR5O1xuIiwiLyoqXG4gKiBBIG5vLW9wZXJhdGlvbiBmdW5jdGlvbiB0aGF0IHJldHVybnMgYHVuZGVmaW5lZGAgcmVnYXJkbGVzcyBvZiB0aGVcbiAqIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFV0aWxpdHlcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiBfLm5vb3Aob2JqZWN0KSA9PT0gdW5kZWZpbmVkO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBub29wKCkge1xuICAvLyBObyBvcGVyYXRpb24gcGVyZm9ybWVkLlxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5vb3A7XG4iLCJ2YXIgYmFzZVByb3BlcnR5ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZVByb3BlcnR5JyksXG4gICAgYmFzZVByb3BlcnR5RGVlcCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VQcm9wZXJ0eURlZXAnKSxcbiAgICBpc0tleSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzS2V5Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgYXQgYHBhdGhgIG9uIGFcbiAqIGdpdmVuIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFV0aWxpdHlcbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdHMgPSBbXG4gKiAgIHsgJ2EnOiB7ICdiJzogeyAnYyc6IDIgfSB9IH0sXG4gKiAgIHsgJ2EnOiB7ICdiJzogeyAnYyc6IDEgfSB9IH1cbiAqIF07XG4gKlxuICogXy5tYXAob2JqZWN0cywgXy5wcm9wZXJ0eSgnYS5iLmMnKSk7XG4gKiAvLyA9PiBbMiwgMV1cbiAqXG4gKiBfLnBsdWNrKF8uc29ydEJ5KG9iamVjdHMsIF8ucHJvcGVydHkoWydhJywgJ2InLCAnYyddKSksICdhLmIuYycpO1xuICogLy8gPT4gWzEsIDJdXG4gKi9cbmZ1bmN0aW9uIHByb3BlcnR5KHBhdGgpIHtcbiAgcmV0dXJuIGlzS2V5KHBhdGgpID8gYmFzZVByb3BlcnR5KHBhdGgpIDogYmFzZVByb3BlcnR5RGVlcChwYXRoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBwcm9wZXJ0eTtcbiIsIihmdW5jdGlvbiAocHJvY2Vzcyl7XG4vLyB2aW06dHM9NDpzdHM9NDpzdz00OlxuLyohXG4gKlxuICogQ29weXJpZ2h0IDIwMDktMjAxMiBLcmlzIEtvd2FsIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUXG4gKiBsaWNlbnNlIGZvdW5kIGF0IGh0dHA6Ly9naXRodWIuY29tL2tyaXNrb3dhbC9xL3Jhdy9tYXN0ZXIvTElDRU5TRVxuICpcbiAqIFdpdGggcGFydHMgYnkgVHlsZXIgQ2xvc2VcbiAqIENvcHlyaWdodCAyMDA3LTIwMDkgVHlsZXIgQ2xvc2UgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBNSVQgWCBsaWNlbnNlIGZvdW5kXG4gKiBhdCBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLmh0bWxcbiAqIEZvcmtlZCBhdCByZWZfc2VuZC5qcyB2ZXJzaW9uOiAyMDA5LTA1LTExXG4gKlxuICogV2l0aCBwYXJ0cyBieSBNYXJrIE1pbGxlclxuICogQ29weXJpZ2h0IChDKSAyMDExIEdvb2dsZSBJbmMuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbihmdW5jdGlvbiAoZGVmaW5pdGlvbikge1xuICAgIFwidXNlIHN0cmljdFwiO1xuXG4gICAgLy8gVGhpcyBmaWxlIHdpbGwgZnVuY3Rpb24gcHJvcGVybHkgYXMgYSA8c2NyaXB0PiB0YWcsIG9yIGEgbW9kdWxlXG4gICAgLy8gdXNpbmcgQ29tbW9uSlMgYW5kIE5vZGVKUyBvciBSZXF1aXJlSlMgbW9kdWxlIGZvcm1hdHMuICBJblxuICAgIC8vIENvbW1vbi9Ob2RlL1JlcXVpcmVKUywgdGhlIG1vZHVsZSBleHBvcnRzIHRoZSBRIEFQSSBhbmQgd2hlblxuICAgIC8vIGV4ZWN1dGVkIGFzIGEgc2ltcGxlIDxzY3JpcHQ+LCBpdCBjcmVhdGVzIGEgUSBnbG9iYWwgaW5zdGVhZC5cblxuICAgIC8vIE1vbnRhZ2UgUmVxdWlyZVxuICAgIGlmICh0eXBlb2YgYm9vdHN0cmFwID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgYm9vdHN0cmFwKFwicHJvbWlzZVwiLCBkZWZpbml0aW9uKTtcblxuICAgIC8vIENvbW1vbkpTXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZGVmaW5pdGlvbigpO1xuXG4gICAgLy8gUmVxdWlyZUpTXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoZGVmaW5pdGlvbik7XG5cbiAgICAvLyBTRVMgKFNlY3VyZSBFY21hU2NyaXB0KVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNlcyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBpZiAoIXNlcy5vaygpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXMubWFrZVEgPSBkZWZpbml0aW9uO1xuICAgICAgICB9XG5cbiAgICAvLyA8c2NyaXB0PlxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiB8fCB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBQcmVmZXIgd2luZG93IG92ZXIgc2VsZiBmb3IgYWRkLW9uIHNjcmlwdHMuIFVzZSBzZWxmIGZvclxuICAgICAgICAvLyBub24td2luZG93ZWQgY29udGV4dHMuXG4gICAgICAgIHZhciBnbG9iYWwgPSB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogc2VsZjtcblxuICAgICAgICAvLyBHZXQgdGhlIGB3aW5kb3dgIG9iamVjdCwgc2F2ZSB0aGUgcHJldmlvdXMgUSBnbG9iYWxcbiAgICAgICAgLy8gYW5kIGluaXRpYWxpemUgUSBhcyBhIGdsb2JhbC5cbiAgICAgICAgdmFyIHByZXZpb3VzUSA9IGdsb2JhbC5RO1xuICAgICAgICBnbG9iYWwuUSA9IGRlZmluaXRpb24oKTtcblxuICAgICAgICAvLyBBZGQgYSBub0NvbmZsaWN0IGZ1bmN0aW9uIHNvIFEgY2FuIGJlIHJlbW92ZWQgZnJvbSB0aGVcbiAgICAgICAgLy8gZ2xvYmFsIG5hbWVzcGFjZS5cbiAgICAgICAgZ2xvYmFsLlEubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGdsb2JhbC5RID0gcHJldmlvdXNRO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIGVudmlyb25tZW50IHdhcyBub3QgYW50aWNpcGF0ZWQgYnkgUS4gUGxlYXNlIGZpbGUgYSBidWcuXCIpO1xuICAgIH1cblxufSkoZnVuY3Rpb24gKCkge1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBoYXNTdGFja3MgPSBmYWxzZTtcbnRyeSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCk7XG59IGNhdGNoIChlKSB7XG4gICAgaGFzU3RhY2tzID0gISFlLnN0YWNrO1xufVxuXG4vLyBBbGwgY29kZSBhZnRlciB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMgcmVwb3J0ZWRcbi8vIGJ5IFEuXG52YXIgcVN0YXJ0aW5nTGluZSA9IGNhcHR1cmVMaW5lKCk7XG52YXIgcUZpbGVOYW1lO1xuXG4vLyBzaGltc1xuXG4vLyB1c2VkIGZvciBmYWxsYmFjayBpbiBcImFsbFJlc29sdmVkXCJcbnZhciBub29wID0gZnVuY3Rpb24gKCkge307XG5cbi8vIFVzZSB0aGUgZmFzdGVzdCBwb3NzaWJsZSBtZWFucyB0byBleGVjdXRlIGEgdGFzayBpbiBhIGZ1dHVyZSB0dXJuXG4vLyBvZiB0aGUgZXZlbnQgbG9vcC5cbnZhciBuZXh0VGljayA9KGZ1bmN0aW9uICgpIHtcbiAgICAvLyBsaW5rZWQgbGlzdCBvZiB0YXNrcyAoc2luZ2xlLCB3aXRoIGhlYWQgbm9kZSlcbiAgICB2YXIgaGVhZCA9IHt0YXNrOiB2b2lkIDAsIG5leHQ6IG51bGx9O1xuICAgIHZhciB0YWlsID0gaGVhZDtcbiAgICB2YXIgZmx1c2hpbmcgPSBmYWxzZTtcbiAgICB2YXIgcmVxdWVzdFRpY2sgPSB2b2lkIDA7XG4gICAgdmFyIGlzTm9kZUpTID0gZmFsc2U7XG4gICAgLy8gcXVldWUgZm9yIGxhdGUgdGFza3MsIHVzZWQgYnkgdW5oYW5kbGVkIHJlamVjdGlvbiB0cmFja2luZ1xuICAgIHZhciBsYXRlclF1ZXVlID0gW107XG5cbiAgICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICAgICAgLyoganNoaW50IGxvb3BmdW5jOiB0cnVlICovXG4gICAgICAgIHZhciB0YXNrLCBkb21haW47XG5cbiAgICAgICAgd2hpbGUgKGhlYWQubmV4dCkge1xuICAgICAgICAgICAgaGVhZCA9IGhlYWQubmV4dDtcbiAgICAgICAgICAgIHRhc2sgPSBoZWFkLnRhc2s7XG4gICAgICAgICAgICBoZWFkLnRhc2sgPSB2b2lkIDA7XG4gICAgICAgICAgICBkb21haW4gPSBoZWFkLmRvbWFpbjtcblxuICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgIGhlYWQuZG9tYWluID0gdm9pZCAwO1xuICAgICAgICAgICAgICAgIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcnVuU2luZ2xlKHRhc2ssIGRvbWFpbik7XG5cbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAobGF0ZXJRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRhc2sgPSBsYXRlclF1ZXVlLnBvcCgpO1xuICAgICAgICAgICAgcnVuU2luZ2xlKHRhc2spO1xuICAgICAgICB9XG4gICAgICAgIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgfVxuICAgIC8vIHJ1bnMgYSBzaW5nbGUgZnVuY3Rpb24gaW4gdGhlIGFzeW5jIHF1ZXVlXG4gICAgZnVuY3Rpb24gcnVuU2luZ2xlKHRhc2ssIGRvbWFpbikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGFzaygpO1xuXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChpc05vZGVKUykge1xuICAgICAgICAgICAgICAgIC8vIEluIG5vZGUsIHVuY2F1Z2h0IGV4Y2VwdGlvbnMgYXJlIGNvbnNpZGVyZWQgZmF0YWwgZXJyb3JzLlxuICAgICAgICAgICAgICAgIC8vIFJlLXRocm93IHRoZW0gc3luY2hyb25vdXNseSB0byBpbnRlcnJ1cHQgZmx1c2hpbmchXG5cbiAgICAgICAgICAgICAgICAvLyBFbnN1cmUgY29udGludWF0aW9uIGlmIHRoZSB1bmNhdWdodCBleGNlcHRpb24gaXMgc3VwcHJlc3NlZFxuICAgICAgICAgICAgICAgIC8vIGxpc3RlbmluZyBcInVuY2F1Z2h0RXhjZXB0aW9uXCIgZXZlbnRzIChhcyBkb21haW5zIGRvZXMpLlxuICAgICAgICAgICAgICAgIC8vIENvbnRpbnVlIGluIG5leHQgZXZlbnQgdG8gYXZvaWQgdGljayByZWN1cnNpb24uXG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZsdXNoLCAwKTtcbiAgICAgICAgICAgICAgICBpZiAoZG9tYWluKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IGU7XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gSW4gYnJvd3NlcnMsIHVuY2F1Z2h0IGV4Y2VwdGlvbnMgYXJlIG5vdCBmYXRhbC5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIGFzeW5jaHJvbm91c2x5IHRvIGF2b2lkIHNsb3ctZG93bnMuXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZG9tYWluKSB7XG4gICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmV4dFRpY2sgPSBmdW5jdGlvbiAodGFzaykge1xuICAgICAgICB0YWlsID0gdGFpbC5uZXh0ID0ge1xuICAgICAgICAgICAgdGFzazogdGFzayxcbiAgICAgICAgICAgIGRvbWFpbjogaXNOb2RlSlMgJiYgcHJvY2Vzcy5kb21haW4sXG4gICAgICAgICAgICBuZXh0OiBudWxsXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgcHJvY2Vzcy50b1N0cmluZygpID09PSBcIltvYmplY3QgcHJvY2Vzc11cIiAmJiBwcm9jZXNzLm5leHRUaWNrKSB7XG4gICAgICAgIC8vIEVuc3VyZSBRIGlzIGluIGEgcmVhbCBOb2RlIGVudmlyb25tZW50LCB3aXRoIGEgYHByb2Nlc3MubmV4dFRpY2tgLlxuICAgICAgICAvLyBUbyBzZWUgdGhyb3VnaCBmYWtlIE5vZGUgZW52aXJvbm1lbnRzOlxuICAgICAgICAvLyAqIE1vY2hhIHRlc3QgcnVubmVyIC0gZXhwb3NlcyBhIGBwcm9jZXNzYCBnbG9iYWwgd2l0aG91dCBhIGBuZXh0VGlja2BcbiAgICAgICAgLy8gKiBCcm93c2VyaWZ5IC0gZXhwb3NlcyBhIGBwcm9jZXNzLm5leFRpY2tgIGZ1bmN0aW9uIHRoYXQgdXNlc1xuICAgICAgICAvLyAgIGBzZXRUaW1lb3V0YC4gSW4gdGhpcyBjYXNlIGBzZXRJbW1lZGlhdGVgIGlzIHByZWZlcnJlZCBiZWNhdXNlXG4gICAgICAgIC8vICAgIGl0IGlzIGZhc3Rlci4gQnJvd3NlcmlmeSdzIGBwcm9jZXNzLnRvU3RyaW5nKClgIHlpZWxkc1xuICAgICAgICAvLyAgIFwiW29iamVjdCBPYmplY3RdXCIsIHdoaWxlIGluIGEgcmVhbCBOb2RlIGVudmlyb25tZW50XG4gICAgICAgIC8vICAgYHByb2Nlc3MubmV4dFRpY2soKWAgeWllbGRzIFwiW29iamVjdCBwcm9jZXNzXVwiLlxuICAgICAgICBpc05vZGVKUyA9IHRydWU7XG5cbiAgICAgICAgcmVxdWVzdFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGZsdXNoKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIC8vIEluIElFMTAsIE5vZGUuanMgMC45Kywgb3IgaHR0cHM6Ly9naXRodWIuY29tL05vYmxlSlMvc2V0SW1tZWRpYXRlXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICByZXF1ZXN0VGljayA9IHNldEltbWVkaWF0ZS5iaW5kKHdpbmRvdywgZmx1c2gpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgc2V0SW1tZWRpYXRlKGZsdXNoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAodHlwZW9mIE1lc3NhZ2VDaGFubmVsICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIC8vIG1vZGVybiBicm93c2Vyc1xuICAgICAgICAvLyBodHRwOi8vd3d3Lm5vbmJsb2NraW5nLmlvLzIwMTEvMDYvd2luZG93bmV4dHRpY2suaHRtbFxuICAgICAgICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICAvLyBBdCBsZWFzdCBTYWZhcmkgVmVyc2lvbiA2LjAuNSAoODUzNi4zMC4xKSBpbnRlcm1pdHRlbnRseSBjYW5ub3QgY3JlYXRlXG4gICAgICAgIC8vIHdvcmtpbmcgbWVzc2FnZSBwb3J0cyB0aGUgZmlyc3QgdGltZSBhIHBhZ2UgbG9hZHMuXG4gICAgICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSByZXF1ZXN0UG9ydFRpY2s7XG4gICAgICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZsdXNoO1xuICAgICAgICAgICAgZmx1c2goKTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHJlcXVlc3RQb3J0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIE9wZXJhIHJlcXVpcmVzIHVzIHRvIHByb3ZpZGUgYSBtZXNzYWdlIHBheWxvYWQsIHJlZ2FyZGxlc3Mgb2ZcbiAgICAgICAgICAgIC8vIHdoZXRoZXIgd2UgdXNlIGl0LlxuICAgICAgICAgICAgY2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSgwKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmVxdWVzdFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZsdXNoLCAwKTtcbiAgICAgICAgICAgIHJlcXVlc3RQb3J0VGljaygpO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gb2xkIGJyb3dzZXJzXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8vIHJ1bnMgYSB0YXNrIGFmdGVyIGFsbCBvdGhlciB0YXNrcyBoYXZlIGJlZW4gcnVuXG4gICAgLy8gdGhpcyBpcyB1c2VmdWwgZm9yIHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmcgdGhhdCBuZWVkcyB0byBoYXBwZW5cbiAgICAvLyBhZnRlciBhbGwgYHRoZW5gZCB0YXNrcyBoYXZlIGJlZW4gcnVuLlxuICAgIG5leHRUaWNrLnJ1bkFmdGVyID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgbGF0ZXJRdWV1ZS5wdXNoKHRhc2spO1xuICAgICAgICBpZiAoIWZsdXNoaW5nKSB7XG4gICAgICAgICAgICBmbHVzaGluZyA9IHRydWU7XG4gICAgICAgICAgICByZXF1ZXN0VGljaygpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gbmV4dFRpY2s7XG59KSgpO1xuXG4vLyBBdHRlbXB0IHRvIG1ha2UgZ2VuZXJpY3Mgc2FmZSBpbiB0aGUgZmFjZSBvZiBkb3duc3RyZWFtXG4vLyBtb2RpZmljYXRpb25zLlxuLy8gVGhlcmUgaXMgbm8gc2l0dWF0aW9uIHdoZXJlIHRoaXMgaXMgbmVjZXNzYXJ5LlxuLy8gSWYgeW91IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsIHRoZXNlIHByaW1vcmRpYWxzIG5lZWQgdG8gYmVcbi8vIGRlZXBseSBmcm96ZW4gYW55d2F5LCBhbmQgaWYgeW91IGRvbuKAmXQgbmVlZCBhIHNlY3VyaXR5IGd1YXJhbnRlZSxcbi8vIHRoaXMgaXMganVzdCBwbGFpbiBwYXJhbm9pZC5cbi8vIEhvd2V2ZXIsIHRoaXMgKiptaWdodCoqIGhhdmUgdGhlIG5pY2Ugc2lkZS1lZmZlY3Qgb2YgcmVkdWNpbmcgdGhlIHNpemUgb2Zcbi8vIHRoZSBtaW5pZmllZCBjb2RlIGJ5IHJlZHVjaW5nIHguY2FsbCgpIHRvIG1lcmVseSB4KClcbi8vIFNlZSBNYXJrIE1pbGxlcuKAmXMgZXhwbGFuYXRpb24gb2Ygd2hhdCB0aGlzIGRvZXMuXG4vLyBodHRwOi8vd2lraS5lY21hc2NyaXB0Lm9yZy9kb2t1LnBocD9pZD1jb252ZW50aW9uczpzYWZlX21ldGFfcHJvZ3JhbW1pbmdcbnZhciBjYWxsID0gRnVuY3Rpb24uY2FsbDtcbmZ1bmN0aW9uIHVuY3VycnlUaGlzKGYpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gY2FsbC5hcHBseShmLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG4vLyBUaGlzIGlzIGVxdWl2YWxlbnQsIGJ1dCBzbG93ZXI6XG4vLyB1bmN1cnJ5VGhpcyA9IEZ1bmN0aW9uX2JpbmQuYmluZChGdW5jdGlvbl9iaW5kLmNhbGwpO1xuLy8gaHR0cDovL2pzcGVyZi5jb20vdW5jdXJyeXRoaXNcblxudmFyIGFycmF5X3NsaWNlID0gdW5jdXJyeVRoaXMoQXJyYXkucHJvdG90eXBlLnNsaWNlKTtcblxudmFyIGFycmF5X3JlZHVjZSA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5yZWR1Y2UgfHwgZnVuY3Rpb24gKGNhbGxiYWNrLCBiYXNpcykge1xuICAgICAgICB2YXIgaW5kZXggPSAwLFxuICAgICAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgICAgIC8vIGNvbmNlcm5pbmcgdGhlIGluaXRpYWwgdmFsdWUsIGlmIG9uZSBpcyBub3QgcHJvdmlkZWRcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIC8vIHNlZWsgdG8gdGhlIGZpcnN0IHZhbHVlIGluIHRoZSBhcnJheSwgYWNjb3VudGluZ1xuICAgICAgICAgICAgLy8gZm9yIHRoZSBwb3NzaWJpbGl0eSB0aGF0IGlzIGlzIGEgc3BhcnNlIGFycmF5XG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICAgICAgYmFzaXMgPSB0aGlzW2luZGV4KytdO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCsraW5kZXggPj0gbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IHdoaWxlICgxKTtcbiAgICAgICAgfVxuICAgICAgICAvLyByZWR1Y2VcbiAgICAgICAgZm9yICg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAvLyBhY2NvdW50IGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCB0aGUgYXJyYXkgaXMgc3BhcnNlXG4gICAgICAgICAgICBpZiAoaW5kZXggaW4gdGhpcykge1xuICAgICAgICAgICAgICAgIGJhc2lzID0gY2FsbGJhY2soYmFzaXMsIHRoaXNbaW5kZXhdLCBpbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJhc2lzO1xuICAgIH1cbik7XG5cbnZhciBhcnJheV9pbmRleE9mID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLmluZGV4T2YgfHwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIC8vIG5vdCBhIHZlcnkgZ29vZCBzaGltLCBidXQgZ29vZCBlbm91Z2ggZm9yIG91ciBvbmUgdXNlIG9mIGl0XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHRoaXNbaV0gPT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbik7XG5cbnZhciBhcnJheV9tYXAgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUubWFwIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgdGhpc3ApIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICB2YXIgY29sbGVjdCA9IFtdO1xuICAgICAgICBhcnJheV9yZWR1Y2Uoc2VsZiwgZnVuY3Rpb24gKHVuZGVmaW5lZCwgdmFsdWUsIGluZGV4KSB7XG4gICAgICAgICAgICBjb2xsZWN0LnB1c2goY2FsbGJhY2suY2FsbCh0aGlzcCwgdmFsdWUsIGluZGV4LCBzZWxmKSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG4gICAgICAgIHJldHVybiBjb2xsZWN0O1xuICAgIH1cbik7XG5cbnZhciBvYmplY3RfY3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiAocHJvdG90eXBlKSB7XG4gICAgZnVuY3Rpb24gVHlwZSgpIHsgfVxuICAgIFR5cGUucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICAgIHJldHVybiBuZXcgVHlwZSgpO1xufTtcblxudmFyIG9iamVjdF9oYXNPd25Qcm9wZXJ0eSA9IHVuY3VycnlUaGlzKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkpO1xuXG52YXIgb2JqZWN0X2tleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3RfaGFzT3duUHJvcGVydHkob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5cztcbn07XG5cbnZhciBvYmplY3RfdG9TdHJpbmcgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKTtcblxuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IE9iamVjdCh2YWx1ZSk7XG59XG5cbi8vIGdlbmVyYXRvciByZWxhdGVkIHNoaW1zXG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBmdW5jdGlvbiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpbiBTcGlkZXJNb25rZXkuXG5mdW5jdGlvbiBpc1N0b3BJdGVyYXRpb24oZXhjZXB0aW9uKSB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgb2JqZWN0X3RvU3RyaW5nKGV4Y2VwdGlvbikgPT09IFwiW29iamVjdCBTdG9wSXRlcmF0aW9uXVwiIHx8XG4gICAgICAgIGV4Y2VwdGlvbiBpbnN0YW5jZW9mIFFSZXR1cm5WYWx1ZVxuICAgICk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBoZWxwZXIgYW5kIFEucmV0dXJuIG9uY2UgRVM2IGdlbmVyYXRvcnMgYXJlIGluXG4vLyBTcGlkZXJNb25rZXkuXG52YXIgUVJldHVyblZhbHVlO1xuaWYgKHR5cGVvZiBSZXR1cm5WYWx1ZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIFFSZXR1cm5WYWx1ZSA9IFJldHVyblZhbHVlO1xufSBlbHNlIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH07XG59XG5cbi8vIGxvbmcgc3RhY2sgdHJhY2VzXG5cbnZhciBTVEFDS19KVU1QX1NFUEFSQVRPUiA9IFwiRnJvbSBwcmV2aW91cyBldmVudDpcIjtcblxuZnVuY3Rpb24gbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKSB7XG4gICAgLy8gSWYgcG9zc2libGUsIHRyYW5zZm9ybSB0aGUgZXJyb3Igc3RhY2sgdHJhY2UgYnkgcmVtb3ZpbmcgTm9kZSBhbmQgUVxuICAgIC8vIGNydWZ0LCB0aGVuIGNvbmNhdGVuYXRpbmcgd2l0aCB0aGUgc3RhY2sgdHJhY2Ugb2YgYHByb21pc2VgLiBTZWUgIzU3LlxuICAgIGlmIChoYXNTdGFja3MgJiZcbiAgICAgICAgcHJvbWlzZS5zdGFjayAmJlxuICAgICAgICB0eXBlb2YgZXJyb3IgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgZXJyb3IgIT09IG51bGwgJiZcbiAgICAgICAgZXJyb3Iuc3RhY2sgJiZcbiAgICAgICAgZXJyb3Iuc3RhY2suaW5kZXhPZihTVEFDS19KVU1QX1NFUEFSQVRPUikgPT09IC0xXG4gICAgKSB7XG4gICAgICAgIHZhciBzdGFja3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgcCA9IHByb21pc2U7ICEhcDsgcCA9IHAuc291cmNlKSB7XG4gICAgICAgICAgICBpZiAocC5zdGFjaykge1xuICAgICAgICAgICAgICAgIHN0YWNrcy51bnNoaWZ0KHAuc3RhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0YWNrcy51bnNoaWZ0KGVycm9yLnN0YWNrKTtcblxuICAgICAgICB2YXIgY29uY2F0ZWRTdGFja3MgPSBzdGFja3Muam9pbihcIlxcblwiICsgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgKyBcIlxcblwiKTtcbiAgICAgICAgZXJyb3Iuc3RhY2sgPSBmaWx0ZXJTdGFja1N0cmluZyhjb25jYXRlZFN0YWNrcyk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmaWx0ZXJTdGFja1N0cmluZyhzdGFja1N0cmluZykge1xuICAgIHZhciBsaW5lcyA9IHN0YWNrU3RyaW5nLnNwbGl0KFwiXFxuXCIpO1xuICAgIHZhciBkZXNpcmVkTGluZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBsaW5lID0gbGluZXNbaV07XG5cbiAgICAgICAgaWYgKCFpc0ludGVybmFsRnJhbWUobGluZSkgJiYgIWlzTm9kZUZyYW1lKGxpbmUpICYmIGxpbmUpIHtcbiAgICAgICAgICAgIGRlc2lyZWRMaW5lcy5wdXNoKGxpbmUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZXNpcmVkTGluZXMuam9pbihcIlxcblwiKTtcbn1cblxuZnVuY3Rpb24gaXNOb2RlRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgcmV0dXJuIHN0YWNrTGluZS5pbmRleE9mKFwiKG1vZHVsZS5qczpcIikgIT09IC0xIHx8XG4gICAgICAgICAgIHN0YWNrTGluZS5pbmRleE9mKFwiKG5vZGUuanM6XCIpICE9PSAtMTtcbn1cblxuZnVuY3Rpb24gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKHN0YWNrTGluZSkge1xuICAgIC8vIE5hbWVkIGZ1bmN0aW9uczogXCJhdCBmdW5jdGlvbk5hbWUgKGZpbGVuYW1lOmxpbmVOdW1iZXI6Y29sdW1uTnVtYmVyKVwiXG4gICAgLy8gSW4gSUUxMCBmdW5jdGlvbiBuYW1lIGNhbiBoYXZlIHNwYWNlcyAoXCJBbm9ueW1vdXMgZnVuY3Rpb25cIikgT19vXG4gICAgdmFyIGF0dGVtcHQxID0gL2F0IC4rIFxcKCguKyk6KFxcZCspOig/OlxcZCspXFwpJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0MSkge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQxWzFdLCBOdW1iZXIoYXR0ZW1wdDFbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBBbm9ueW1vdXMgZnVuY3Rpb25zOiBcImF0IGZpbGVuYW1lOmxpbmVOdW1iZXI6Y29sdW1uTnVtYmVyXCJcbiAgICB2YXIgYXR0ZW1wdDIgPSAvYXQgKFteIF0rKTooXFxkKyk6KD86XFxkKykkLy5leGVjKHN0YWNrTGluZSk7XG4gICAgaWYgKGF0dGVtcHQyKSB7XG4gICAgICAgIHJldHVybiBbYXR0ZW1wdDJbMV0sIE51bWJlcihhdHRlbXB0MlsyXSldO1xuICAgIH1cblxuICAgIC8vIEZpcmVmb3ggc3R5bGU6IFwiZnVuY3Rpb25AZmlsZW5hbWU6bGluZU51bWJlciBvciBAZmlsZW5hbWU6bGluZU51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQzID0gLy4qQCguKyk6KFxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mykge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQzWzFdLCBOdW1iZXIoYXR0ZW1wdDNbMl0pXTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzSW50ZXJuYWxGcmFtZShzdGFja0xpbmUpIHtcbiAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKHN0YWNrTGluZSk7XG5cbiAgICBpZiAoIWZpbGVOYW1lQW5kTGluZU51bWJlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGZpbGVOYW1lID0gZmlsZU5hbWVBbmRMaW5lTnVtYmVyWzBdO1xuICAgIHZhciBsaW5lTnVtYmVyID0gZmlsZU5hbWVBbmRMaW5lTnVtYmVyWzFdO1xuXG4gICAgcmV0dXJuIGZpbGVOYW1lID09PSBxRmlsZU5hbWUgJiZcbiAgICAgICAgbGluZU51bWJlciA+PSBxU3RhcnRpbmdMaW5lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPD0gcUVuZGluZ0xpbmU7XG59XG5cbi8vIGRpc2NvdmVyIG93biBmaWxlIG5hbWUgYW5kIGxpbmUgbnVtYmVyIHJhbmdlIGZvciBmaWx0ZXJpbmcgc3RhY2tcbi8vIHRyYWNlc1xuZnVuY3Rpb24gY2FwdHVyZUxpbmUoKSB7XG4gICAgaWYgKCFoYXNTdGFja3MpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdmFyIGxpbmVzID0gZS5zdGFjay5zcGxpdChcIlxcblwiKTtcbiAgICAgICAgdmFyIGZpcnN0TGluZSA9IGxpbmVzWzBdLmluZGV4T2YoXCJAXCIpID4gMCA/IGxpbmVzWzFdIDogbGluZXNbMl07XG4gICAgICAgIHZhciBmaWxlTmFtZUFuZExpbmVOdW1iZXIgPSBnZXRGaWxlTmFtZUFuZExpbmVOdW1iZXIoZmlyc3RMaW5lKTtcbiAgICAgICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHFGaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICAgICAgcmV0dXJuIGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZShjYWxsYmFjaywgbmFtZSwgYWx0ZXJuYXRpdmUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgIHR5cGVvZiBjb25zb2xlLndhcm4gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKG5hbWUgKyBcIiBpcyBkZXByZWNhdGVkLCB1c2UgXCIgKyBhbHRlcm5hdGl2ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgXCIgaW5zdGVhZC5cIiwgbmV3IEVycm9yKFwiXCIpLnN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkoY2FsbGJhY2ssIGFyZ3VtZW50cyk7XG4gICAgfTtcbn1cblxuLy8gZW5kIG9mIHNoaW1zXG4vLyBiZWdpbm5pbmcgb2YgcmVhbCB3b3JrXG5cbi8qKlxuICogQ29uc3RydWN0cyBhIHByb21pc2UgZm9yIGFuIGltbWVkaWF0ZSByZWZlcmVuY2UsIHBhc3NlcyBwcm9taXNlcyB0aHJvdWdoLCBvclxuICogY29lcmNlcyBwcm9taXNlcyBmcm9tIGRpZmZlcmVudCBzeXN0ZW1zLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2Ugb3IgcHJvbWlzZVxuICovXG5mdW5jdGlvbiBRKHZhbHVlKSB7XG4gICAgLy8gSWYgdGhlIG9iamVjdCBpcyBhbHJlYWR5IGEgUHJvbWlzZSwgcmV0dXJuIGl0IGRpcmVjdGx5LiAgVGhpcyBlbmFibGVzXG4gICAgLy8gdGhlIHJlc29sdmUgZnVuY3Rpb24gdG8gYm90aCBiZSB1c2VkIHRvIGNyZWF0ZWQgcmVmZXJlbmNlcyBmcm9tIG9iamVjdHMsXG4gICAgLy8gYnV0IHRvIHRvbGVyYWJseSBjb2VyY2Ugbm9uLXByb21pc2VzIHRvIHByb21pc2VzLlxuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIC8vIGFzc2ltaWxhdGUgdGhlbmFibGVzXG4gICAgaWYgKGlzUHJvbWlzZUFsaWtlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gY29lcmNlKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZnVsZmlsbCh2YWx1ZSk7XG4gICAgfVxufVxuUS5yZXNvbHZlID0gUTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIHRhc2sgaW4gYSBmdXR1cmUgdHVybiBvZiB0aGUgZXZlbnQgbG9vcC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRhc2tcbiAqL1xuUS5uZXh0VGljayA9IG5leHRUaWNrO1xuXG4vKipcbiAqIENvbnRyb2xzIHdoZXRoZXIgb3Igbm90IGxvbmcgc3RhY2sgdHJhY2VzIHdpbGwgYmUgb25cbiAqL1xuUS5sb25nU3RhY2tTdXBwb3J0ID0gZmFsc2U7XG5cbi8vIGVuYWJsZSBsb25nIHN0YWNrcyBpZiBRX0RFQlVHIGlzIHNldFxuaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5lbnYgJiYgcHJvY2Vzcy5lbnYuUV9ERUJVRykge1xuICAgIFEubG9uZ1N0YWNrU3VwcG9ydCA9IHRydWU7XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIHtwcm9taXNlLCByZXNvbHZlLCByZWplY3R9IG9iamVjdC5cbiAqXG4gKiBgcmVzb2x2ZWAgaXMgYSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBhIG1vcmUgcmVzb2x2ZWQgdmFsdWUgZm9yIHRoZVxuICogcHJvbWlzZS4gVG8gZnVsZmlsbCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGFueSB2YWx1ZSB0aGF0IGlzXG4gKiBub3QgYSB0aGVuYWJsZS4gVG8gcmVqZWN0IHRoZSBwcm9taXNlLCBpbnZva2UgYHJlc29sdmVgIHdpdGggYSByZWplY3RlZFxuICogdGhlbmFibGUsIG9yIGludm9rZSBgcmVqZWN0YCB3aXRoIHRoZSByZWFzb24gZGlyZWN0bHkuIFRvIHJlc29sdmUgdGhlXG4gKiBwcm9taXNlIHRvIGFub3RoZXIgdGhlbmFibGUsIHRodXMgcHV0dGluZyBpdCBpbiB0aGUgc2FtZSBzdGF0ZSwgaW52b2tlXG4gKiBgcmVzb2x2ZWAgd2l0aCB0aGF0IG90aGVyIHRoZW5hYmxlLlxuICovXG5RLmRlZmVyID0gZGVmZXI7XG5mdW5jdGlvbiBkZWZlcigpIHtcbiAgICAvLyBpZiBcIm1lc3NhZ2VzXCIgaXMgYW4gXCJBcnJheVwiLCB0aGF0IGluZGljYXRlcyB0aGF0IHRoZSBwcm9taXNlIGhhcyBub3QgeWV0XG4gICAgLy8gYmVlbiByZXNvbHZlZC4gIElmIGl0IGlzIFwidW5kZWZpbmVkXCIsIGl0IGhhcyBiZWVuIHJlc29sdmVkLiAgRWFjaFxuICAgIC8vIGVsZW1lbnQgb2YgdGhlIG1lc3NhZ2VzIGFycmF5IGlzIGl0c2VsZiBhbiBhcnJheSBvZiBjb21wbGV0ZSBhcmd1bWVudHMgdG9cbiAgICAvLyBmb3J3YXJkIHRvIHRoZSByZXNvbHZlZCBwcm9taXNlLiAgV2UgY29lcmNlIHRoZSByZXNvbHV0aW9uIHZhbHVlIHRvIGFcbiAgICAvLyBwcm9taXNlIHVzaW5nIHRoZSBgcmVzb2x2ZWAgZnVuY3Rpb24gYmVjYXVzZSBpdCBoYW5kbGVzIGJvdGggZnVsbHlcbiAgICAvLyBub24tdGhlbmFibGUgdmFsdWVzIGFuZCBvdGhlciB0aGVuYWJsZXMgZ3JhY2VmdWxseS5cbiAgICB2YXIgbWVzc2FnZXMgPSBbXSwgcHJvZ3Jlc3NMaXN0ZW5lcnMgPSBbXSwgcmVzb2x2ZWRQcm9taXNlO1xuXG4gICAgdmFyIGRlZmVycmVkID0gb2JqZWN0X2NyZWF0ZShkZWZlci5wcm90b3R5cGUpO1xuICAgIHZhciBwcm9taXNlID0gb2JqZWN0X2NyZWF0ZShQcm9taXNlLnByb3RvdHlwZSk7XG5cbiAgICBwcm9taXNlLnByb21pc2VEaXNwYXRjaCA9IGZ1bmN0aW9uIChyZXNvbHZlLCBvcCwgb3BlcmFuZHMpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgICAgICBpZiAobWVzc2FnZXMpIHtcbiAgICAgICAgICAgIG1lc3NhZ2VzLnB1c2goYXJncyk7XG4gICAgICAgICAgICBpZiAob3AgPT09IFwid2hlblwiICYmIG9wZXJhbmRzWzFdKSB7IC8vIHByb2dyZXNzIG9wZXJhbmRcbiAgICAgICAgICAgICAgICBwcm9ncmVzc0xpc3RlbmVycy5wdXNoKG9wZXJhbmRzWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZS5wcm9taXNlRGlzcGF0Y2guYXBwbHkocmVzb2x2ZWRQcm9taXNlLCBhcmdzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8vIFhYWCBkZXByZWNhdGVkXG4gICAgcHJvbWlzZS52YWx1ZU9mID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAobWVzc2FnZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBuZWFyZXJWYWx1ZSA9IG5lYXJlcihyZXNvbHZlZFByb21pc2UpO1xuICAgICAgICBpZiAoaXNQcm9taXNlKG5lYXJlclZhbHVlKSkge1xuICAgICAgICAgICAgcmVzb2x2ZWRQcm9taXNlID0gbmVhcmVyVmFsdWU7IC8vIHNob3J0ZW4gY2hhaW5cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmVhcmVyVmFsdWU7XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiB7IHN0YXRlOiBcInBlbmRpbmdcIiB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNvbHZlZFByb21pc2UuaW5zcGVjdCgpO1xuICAgIH07XG5cbiAgICBpZiAoUS5sb25nU3RhY2tTdXBwb3J0ICYmIGhhc1N0YWNrcykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIE5PVEU6IGRvbid0IHRyeSB0byB1c2UgYEVycm9yLmNhcHR1cmVTdGFja1RyYWNlYCBvciB0cmFuc2ZlciB0aGVcbiAgICAgICAgICAgIC8vIGFjY2Vzc29yIGFyb3VuZDsgdGhhdCBjYXVzZXMgbWVtb3J5IGxlYWtzIGFzIHBlciBHSC0xMTEuIEp1c3RcbiAgICAgICAgICAgIC8vIHJlaWZ5IHRoZSBzdGFjayB0cmFjZSBhcyBhIHN0cmluZyBBU0FQLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEF0IHRoZSBzYW1lIHRpbWUsIGN1dCBvZmYgdGhlIGZpcnN0IGxpbmU7IGl0J3MgYWx3YXlzIGp1c3RcbiAgICAgICAgICAgIC8vIFwiW29iamVjdCBQcm9taXNlXVxcblwiLCBhcyBwZXIgdGhlIGB0b1N0cmluZ2AuXG4gICAgICAgICAgICBwcm9taXNlLnN0YWNrID0gZS5zdGFjay5zdWJzdHJpbmcoZS5zdGFjay5pbmRleE9mKFwiXFxuXCIpICsgMSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBOT1RFOiB3ZSBkbyB0aGUgY2hlY2tzIGZvciBgcmVzb2x2ZWRQcm9taXNlYCBpbiBlYWNoIG1ldGhvZCwgaW5zdGVhZCBvZlxuICAgIC8vIGNvbnNvbGlkYXRpbmcgdGhlbSBpbnRvIGBiZWNvbWVgLCBzaW5jZSBvdGhlcndpc2Ugd2UnZCBjcmVhdGUgbmV3XG4gICAgLy8gcHJvbWlzZXMgd2l0aCB0aGUgbGluZXMgYGJlY29tZSh3aGF0ZXZlcih2YWx1ZSkpYC4gU2VlIGUuZy4gR0gtMjUyLlxuXG4gICAgZnVuY3Rpb24gYmVjb21lKG5ld1Byb21pc2UpIHtcbiAgICAgICAgcmVzb2x2ZWRQcm9taXNlID0gbmV3UHJvbWlzZTtcbiAgICAgICAgcHJvbWlzZS5zb3VyY2UgPSBuZXdQcm9taXNlO1xuXG4gICAgICAgIGFycmF5X3JlZHVjZShtZXNzYWdlcywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgbWVzc2FnZSkge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbmV3UHJvbWlzZS5wcm9taXNlRGlzcGF0Y2guYXBwbHkobmV3UHJvbWlzZSwgbWVzc2FnZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcblxuICAgICAgICBtZXNzYWdlcyA9IHZvaWQgMDtcbiAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMgPSB2b2lkIDA7XG4gICAgfVxuXG4gICAgZGVmZXJyZWQucHJvbWlzZSA9IHByb21pc2U7XG4gICAgZGVmZXJyZWQucmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoUSh2YWx1ZSkpO1xuICAgIH07XG5cbiAgICBkZWZlcnJlZC5mdWxmaWxsID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJlY29tZShmdWxmaWxsKHZhbHVlKSk7XG4gICAgfTtcbiAgICBkZWZlcnJlZC5yZWplY3QgPSBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJlY29tZShyZWplY3QocmVhc29uKSk7XG4gICAgfTtcbiAgICBkZWZlcnJlZC5ub3RpZnkgPSBmdW5jdGlvbiAocHJvZ3Jlc3MpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXJyYXlfcmVkdWNlKHByb2dyZXNzTGlzdGVuZXJzLCBmdW5jdGlvbiAodW5kZWZpbmVkLCBwcm9ncmVzc0xpc3RlbmVyKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBwcm9ncmVzc0xpc3RlbmVyKHByb2dyZXNzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgIH07XG5cbiAgICByZXR1cm4gZGVmZXJyZWQ7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIE5vZGUtc3R5bGUgY2FsbGJhY2sgdGhhdCB3aWxsIHJlc29sdmUgb3IgcmVqZWN0IHRoZSBkZWZlcnJlZFxuICogcHJvbWlzZS5cbiAqIEByZXR1cm5zIGEgbm9kZWJhY2tcbiAqL1xuZGVmZXIucHJvdG90eXBlLm1ha2VOb2RlUmVzb2x2ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHZhbHVlKSB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgc2VsZi5yZWplY3QoZXJyb3IpO1xuICAgICAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICBzZWxmLnJlc29sdmUoYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWxmLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHJlc29sdmVyIHtGdW5jdGlvbn0gYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgbm90aGluZyBhbmQgYWNjZXB0c1xuICogdGhlIHJlc29sdmUsIHJlamVjdCwgYW5kIG5vdGlmeSBmdW5jdGlvbnMgZm9yIGEgZGVmZXJyZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgdGhhdCBtYXkgYmUgcmVzb2x2ZWQgd2l0aCB0aGUgZ2l2ZW4gcmVzb2x2ZSBhbmQgcmVqZWN0XG4gKiBmdW5jdGlvbnMsIG9yIHJlamVjdGVkIGJ5IGEgdGhyb3duIGV4Y2VwdGlvbiBpbiByZXNvbHZlclxuICovXG5RLlByb21pc2UgPSBwcm9taXNlOyAvLyBFUzZcblEucHJvbWlzZSA9IHByb21pc2U7XG5mdW5jdGlvbiBwcm9taXNlKHJlc29sdmVyKSB7XG4gICAgaWYgKHR5cGVvZiByZXNvbHZlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJyZXNvbHZlciBtdXN0IGJlIGEgZnVuY3Rpb24uXCIpO1xuICAgIH1cbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIHRyeSB7XG4gICAgICAgIHJlc29sdmVyKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICB9IGNhdGNoIChyZWFzb24pIHtcbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KHJlYXNvbik7XG4gICAgfVxuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG5wcm9taXNlLnJhY2UgPSByYWNlOyAvLyBFUzZcbnByb21pc2UuYWxsID0gYWxsOyAvLyBFUzZcbnByb21pc2UucmVqZWN0ID0gcmVqZWN0OyAvLyBFUzZcbnByb21pc2UucmVzb2x2ZSA9IFE7IC8vIEVTNlxuXG4vLyBYWFggZXhwZXJpbWVudGFsLiAgVGhpcyBtZXRob2QgaXMgYSB3YXkgdG8gZGVub3RlIHRoYXQgYSBsb2NhbCB2YWx1ZSBpc1xuLy8gc2VyaWFsaXphYmxlIGFuZCBzaG91bGQgYmUgaW1tZWRpYXRlbHkgZGlzcGF0Y2hlZCB0byBhIHJlbW90ZSB1cG9uIHJlcXVlc3QsXG4vLyBpbnN0ZWFkIG9mIHBhc3NpbmcgYSByZWZlcmVuY2UuXG5RLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gb2JqZWN0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUucGFzc0J5Q29weSA9IGZ1bmN0aW9uICgpIHtcbiAgICAvL2ZyZWV6ZShvYmplY3QpO1xuICAgIC8vcGFzc0J5Q29waWVzLnNldChvYmplY3QsIHRydWUpO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBJZiB0d28gcHJvbWlzZXMgZXZlbnR1YWxseSBmdWxmaWxsIHRvIHRoZSBzYW1lIHZhbHVlLCBwcm9taXNlcyB0aGF0IHZhbHVlLFxuICogYnV0IG90aGVyd2lzZSByZWplY3RzLlxuICogQHBhcmFtIHgge0FueSp9XG4gKiBAcGFyYW0geSB7QW55Kn1cbiAqIEByZXR1cm5zIHtBbnkqfSBhIHByb21pc2UgZm9yIHggYW5kIHkgaWYgdGhleSBhcmUgdGhlIHNhbWUsIGJ1dCBhIHJlamVjdGlvblxuICogb3RoZXJ3aXNlLlxuICpcbiAqL1xuUS5qb2luID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICByZXR1cm4gUSh4KS5qb2luKHkpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuam9pbiA9IGZ1bmN0aW9uICh0aGF0KSB7XG4gICAgcmV0dXJuIFEoW3RoaXMsIHRoYXRdKS5zcHJlYWQoZnVuY3Rpb24gKHgsIHkpIHtcbiAgICAgICAgaWYgKHggPT09IHkpIHtcbiAgICAgICAgICAgIC8vIFRPRE86IFwiPT09XCIgc2hvdWxkIGJlIE9iamVjdC5pcyBvciBlcXVpdlxuICAgICAgICAgICAgcmV0dXJuIHg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBqb2luOiBub3QgdGhlIHNhbWU6IFwiICsgeCArIFwiIFwiICsgeSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSBmaXJzdCBvZiBhbiBhcnJheSBvZiBwcm9taXNlcyB0byBiZWNvbWUgc2V0dGxlZC5cbiAqIEBwYXJhbSBhbnN3ZXJzIHtBcnJheVtBbnkqXX0gcHJvbWlzZXMgdG8gcmFjZVxuICogQHJldHVybnMge0FueSp9IHRoZSBmaXJzdCBwcm9taXNlIHRvIGJlIHNldHRsZWRcbiAqL1xuUS5yYWNlID0gcmFjZTtcbmZ1bmN0aW9uIHJhY2UoYW5zd2VyUHMpIHtcbiAgICByZXR1cm4gcHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIC8vIFN3aXRjaCB0byB0aGlzIG9uY2Ugd2UgY2FuIGFzc3VtZSBhdCBsZWFzdCBFUzVcbiAgICAgICAgLy8gYW5zd2VyUHMuZm9yRWFjaChmdW5jdGlvbiAoYW5zd2VyUCkge1xuICAgICAgICAvLyAgICAgUShhbnN3ZXJQKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIC8vIH0pO1xuICAgICAgICAvLyBVc2UgdGhpcyBpbiB0aGUgbWVhbnRpbWVcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFuc3dlclBzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBRKGFuc3dlclBzW2ldKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUucmFjZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKFEucmFjZSk7XG59O1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBQcm9taXNlIHdpdGggYSBwcm9taXNlIGRlc2NyaXB0b3Igb2JqZWN0IGFuZCBvcHRpb25hbCBmYWxsYmFja1xuICogZnVuY3Rpb24uICBUaGUgZGVzY3JpcHRvciBjb250YWlucyBtZXRob2RzIGxpa2Ugd2hlbihyZWplY3RlZCksIGdldChuYW1lKSxcbiAqIHNldChuYW1lLCB2YWx1ZSksIHBvc3QobmFtZSwgYXJncyksIGFuZCBkZWxldGUobmFtZSksIHdoaWNoIGFsbFxuICogcmV0dXJuIGVpdGhlciBhIHZhbHVlLCBhIHByb21pc2UgZm9yIGEgdmFsdWUsIG9yIGEgcmVqZWN0aW9uLiAgVGhlIGZhbGxiYWNrXG4gKiBhY2NlcHRzIHRoZSBvcGVyYXRpb24gbmFtZSwgYSByZXNvbHZlciwgYW5kIGFueSBmdXJ0aGVyIGFyZ3VtZW50cyB0aGF0IHdvdWxkXG4gKiBoYXZlIGJlZW4gZm9yd2FyZGVkIHRvIHRoZSBhcHByb3ByaWF0ZSBtZXRob2QgYWJvdmUgaGFkIGEgbWV0aG9kIGJlZW5cbiAqIHByb3ZpZGVkIHdpdGggdGhlIHByb3BlciBuYW1lLiAgVGhlIEFQSSBtYWtlcyBubyBndWFyYW50ZWVzIGFib3V0IHRoZSBuYXR1cmVcbiAqIG9mIHRoZSByZXR1cm5lZCBvYmplY3QsIGFwYXJ0IGZyb20gdGhhdCBpdCBpcyB1c2FibGUgd2hlcmVldmVyIHByb21pc2VzIGFyZVxuICogYm91Z2h0IGFuZCBzb2xkLlxuICovXG5RLm1ha2VQcm9taXNlID0gUHJvbWlzZTtcbmZ1bmN0aW9uIFByb21pc2UoZGVzY3JpcHRvciwgZmFsbGJhY2ssIGluc3BlY3QpIHtcbiAgICBpZiAoZmFsbGJhY2sgPT09IHZvaWQgMCkge1xuICAgICAgICBmYWxsYmFjayA9IGZ1bmN0aW9uIChvcCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJQcm9taXNlIGRvZXMgbm90IHN1cHBvcnQgb3BlcmF0aW9uOiBcIiArIG9wXG4gICAgICAgICAgICApKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKGluc3BlY3QgPT09IHZvaWQgMCkge1xuICAgICAgICBpbnNwZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtzdGF0ZTogXCJ1bmtub3duXCJ9O1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gb2JqZWN0X2NyZWF0ZShQcm9taXNlLnByb3RvdHlwZSk7XG5cbiAgICBwcm9taXNlLnByb21pc2VEaXNwYXRjaCA9IGZ1bmN0aW9uIChyZXNvbHZlLCBvcCwgYXJncykge1xuICAgICAgICB2YXIgcmVzdWx0O1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKGRlc2NyaXB0b3Jbb3BdKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZGVzY3JpcHRvcltvcF0uYXBwbHkocHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZhbGxiYWNrLmNhbGwocHJvbWlzZSwgb3AsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXNvbHZlKSB7XG4gICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHJvbWlzZS5pbnNwZWN0ID0gaW5zcGVjdDtcblxuICAgIC8vIFhYWCBkZXByZWNhdGVkIGB2YWx1ZU9mYCBhbmQgYGV4Y2VwdGlvbmAgc3VwcG9ydFxuICAgIGlmIChpbnNwZWN0KSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwicmVqZWN0ZWRcIikge1xuICAgICAgICAgICAgcHJvbWlzZS5leGNlcHRpb24gPSBpbnNwZWN0ZWQucmVhc29uO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJvbWlzZS52YWx1ZU9mID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGluc3BlY3RlZCA9IGluc3BlY3QoKTtcbiAgICAgICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwicGVuZGluZ1wiIHx8XG4gICAgICAgICAgICAgICAgaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBcIltvYmplY3QgUHJvbWlzZV1cIjtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbiAoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3NlZCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIHZhciBkb25lID0gZmFsc2U7ICAgLy8gZW5zdXJlIHRoZSB1bnRydXN0ZWQgcHJvbWlzZSBtYWtlcyBhdCBtb3N0IGFcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpbmdsZSBjYWxsIHRvIG9uZSBvZiB0aGUgY2FsbGJhY2tzXG5cbiAgICBmdW5jdGlvbiBfZnVsZmlsbGVkKHZhbHVlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGZ1bGZpbGxlZCA9PT0gXCJmdW5jdGlvblwiID8gZnVsZmlsbGVkKHZhbHVlKSA6IHZhbHVlO1xuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9yZWplY3RlZChleGNlcHRpb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZWplY3RlZCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBtYWtlU3RhY2tUcmFjZUxvbmcoZXhjZXB0aW9uLCBzZWxmKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkKGV4Y2VwdGlvbik7XG4gICAgICAgICAgICB9IGNhdGNoIChuZXdFeGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ld0V4Y2VwdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9wcm9ncmVzc2VkKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgcHJvZ3Jlc3NlZCA9PT0gXCJmdW5jdGlvblwiID8gcHJvZ3Jlc3NlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5wcm9taXNlRGlzcGF0Y2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuXG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKF9mdWxmaWxsZWQodmFsdWUpKTtcbiAgICAgICAgfSwgXCJ3aGVuXCIsIFtmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuXG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKF9yZWplY3RlZChleGNlcHRpb24pKTtcbiAgICAgICAgfV0pO1xuICAgIH0pO1xuXG4gICAgLy8gUHJvZ3Jlc3MgcHJvcGFnYXRvciBuZWVkIHRvIGJlIGF0dGFjaGVkIGluIHRoZSBjdXJyZW50IHRpY2suXG4gICAgc2VsZi5wcm9taXNlRGlzcGF0Y2godm9pZCAwLCBcIndoZW5cIiwgW3ZvaWQgMCwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciBuZXdWYWx1ZTtcbiAgICAgICAgdmFyIHRocmV3ID0gZmFsc2U7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IF9wcm9ncmVzc2VkKHZhbHVlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyZXcgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKFEub25lcnJvcikge1xuICAgICAgICAgICAgICAgIFEub25lcnJvcihlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhyZXcpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeShuZXdWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XSk7XG5cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cblEudGFwID0gZnVuY3Rpb24gKHByb21pc2UsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIFEocHJvbWlzZSkudGFwKGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogV29ya3MgYWxtb3N0IGxpa2UgXCJmaW5hbGx5XCIsIGJ1dCBub3QgY2FsbGVkIGZvciByZWplY3Rpb25zLlxuICogT3JpZ2luYWwgcmVzb2x1dGlvbiB2YWx1ZSBpcyBwYXNzZWQgdGhyb3VnaCBjYWxsYmFjayB1bmFmZmVjdGVkLlxuICogQ2FsbGJhY2sgbWF5IHJldHVybiBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGF3YWl0ZWQgZm9yLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtRLlByb21pc2V9XG4gKiBAZXhhbXBsZVxuICogZG9Tb21ldGhpbmcoKVxuICogICAudGhlbiguLi4pXG4gKiAgIC50YXAoY29uc29sZS5sb2cpXG4gKiAgIC50aGVuKC4uLik7XG4gKi9cblByb21pc2UucHJvdG90eXBlLnRhcCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG5cbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwodmFsdWUpLnRoZW5SZXNvbHZlKHZhbHVlKTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIG9ic2VydmVyIG9uIGEgcHJvbWlzZS5cbiAqXG4gKiBHdWFyYW50ZWVzOlxuICpcbiAqIDEuIHRoYXQgZnVsZmlsbGVkIGFuZCByZWplY3RlZCB3aWxsIGJlIGNhbGxlZCBvbmx5IG9uY2UuXG4gKiAyLiB0aGF0IGVpdGhlciB0aGUgZnVsZmlsbGVkIGNhbGxiYWNrIG9yIHRoZSByZWplY3RlZCBjYWxsYmFjayB3aWxsIGJlXG4gKiAgICBjYWxsZWQsIGJ1dCBub3QgYm90aC5cbiAqIDMuIHRoYXQgZnVsZmlsbGVkIGFuZCByZWplY3RlZCB3aWxsIG5vdCBiZSBjYWxsZWQgaW4gdGhpcyB0dXJuLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAgICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSB0byBvYnNlcnZlXG4gKiBAcGFyYW0gZnVsZmlsbGVkICBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2l0aCB0aGUgZnVsZmlsbGVkIHZhbHVlXG4gKiBAcGFyYW0gcmVqZWN0ZWQgICBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2l0aCB0aGUgcmVqZWN0aW9uIGV4Y2VwdGlvblxuICogQHBhcmFtIHByb2dyZXNzZWQgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIG9uIGFueSBwcm9ncmVzcyBub3RpZmljYXRpb25zXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgaW52b2tlZCBjYWxsYmFja1xuICovXG5RLndoZW4gPSB3aGVuO1xuZnVuY3Rpb24gd2hlbih2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3NlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gdmFsdWU7IH0pO1xufTtcblxuUS50aGVuUmVzb2x2ZSA9IGZ1bmN0aW9uIChwcm9taXNlLCB2YWx1ZSkge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZXNvbHZlKHZhbHVlKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRoZW5SZWplY3QgPSBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAoKSB7IHRocm93IHJlYXNvbjsgfSk7XG59O1xuXG5RLnRoZW5SZWplY3QgPSBmdW5jdGlvbiAocHJvbWlzZSwgcmVhc29uKSB7XG4gICAgcmV0dXJuIFEocHJvbWlzZSkudGhlblJlamVjdChyZWFzb24pO1xufTtcblxuLyoqXG4gKiBJZiBhbiBvYmplY3QgaXMgbm90IGEgcHJvbWlzZSwgaXQgaXMgYXMgXCJuZWFyXCIgYXMgcG9zc2libGUuXG4gKiBJZiBhIHByb21pc2UgaXMgcmVqZWN0ZWQsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlIHRvby5cbiAqIElmIGl04oCZcyBhIGZ1bGZpbGxlZCBwcm9taXNlLCB0aGUgZnVsZmlsbG1lbnQgdmFsdWUgaXMgbmVhcmVyLlxuICogSWYgaXTigJlzIGEgZGVmZXJyZWQgcHJvbWlzZSBhbmQgdGhlIGRlZmVycmVkIGhhcyBiZWVuIHJlc29sdmVkLCB0aGVcbiAqIHJlc29sdXRpb24gaXMgXCJuZWFyZXJcIi5cbiAqIEBwYXJhbSBvYmplY3RcbiAqIEByZXR1cm5zIG1vc3QgcmVzb2x2ZWQgKG5lYXJlc3QpIGZvcm0gb2YgdGhlIG9iamVjdFxuICovXG5cbi8vIFhYWCBzaG91bGQgd2UgcmUtZG8gdGhpcz9cblEubmVhcmVyID0gbmVhcmVyO1xuZnVuY3Rpb24gbmVhcmVyKHZhbHVlKSB7XG4gICAgaWYgKGlzUHJvbWlzZSh2YWx1ZSkpIHtcbiAgICAgICAgdmFyIGluc3BlY3RlZCA9IHZhbHVlLmluc3BlY3QoKTtcbiAgICAgICAgaWYgKGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJmdWxmaWxsZWRcIikge1xuICAgICAgICAgICAgcmV0dXJuIGluc3BlY3RlZC52YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgcHJvbWlzZS5cbiAqIE90aGVyd2lzZSBpdCBpcyBhIGZ1bGZpbGxlZCB2YWx1ZS5cbiAqL1xuUS5pc1Byb21pc2UgPSBpc1Byb21pc2U7XG5mdW5jdGlvbiBpc1Byb21pc2Uob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIFByb21pc2U7XG59XG5cblEuaXNQcm9taXNlQWxpa2UgPSBpc1Byb21pc2VBbGlrZTtcbmZ1bmN0aW9uIGlzUHJvbWlzZUFsaWtlKG9iamVjdCkge1xuICAgIHJldHVybiBpc09iamVjdChvYmplY3QpICYmIHR5cGVvZiBvYmplY3QudGhlbiA9PT0gXCJmdW5jdGlvblwiO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHBlbmRpbmcgcHJvbWlzZSwgbWVhbmluZyBub3RcbiAqIGZ1bGZpbGxlZCBvciByZWplY3RlZC5cbiAqL1xuUS5pc1BlbmRpbmcgPSBpc1BlbmRpbmc7XG5mdW5jdGlvbiBpc1BlbmRpbmcob2JqZWN0KSB7XG4gICAgcmV0dXJuIGlzUHJvbWlzZShvYmplY3QpICYmIG9iamVjdC5pbnNwZWN0KCkuc3RhdGUgPT09IFwicGVuZGluZ1wiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc1BlbmRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn07XG5cbi8qKlxuICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgdmFsdWUgb3IgZnVsZmlsbGVkXG4gKiBwcm9taXNlLlxuICovXG5RLmlzRnVsZmlsbGVkID0gaXNGdWxmaWxsZWQ7XG5mdW5jdGlvbiBpc0Z1bGZpbGxlZChvYmplY3QpIHtcbiAgICByZXR1cm4gIWlzUHJvbWlzZShvYmplY3QpIHx8IG9iamVjdC5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzRnVsZmlsbGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJmdWxmaWxsZWRcIjtcbn07XG5cbi8qKlxuICogQHJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgcmVqZWN0ZWQgcHJvbWlzZS5cbiAqL1xuUS5pc1JlamVjdGVkID0gaXNSZWplY3RlZDtcbmZ1bmN0aW9uIGlzUmVqZWN0ZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuIGlzUHJvbWlzZShvYmplY3QpICYmIG9iamVjdC5pbnNwZWN0KCkuc3RhdGUgPT09IFwicmVqZWN0ZWRcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNSZWplY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwicmVqZWN0ZWRcIjtcbn07XG5cbi8vLy8gQkVHSU4gVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vLyBUaGlzIHByb21pc2UgbGlicmFyeSBjb25zdW1lcyBleGNlcHRpb25zIHRocm93biBpbiBoYW5kbGVycyBzbyB0aGV5IGNhbiBiZVxuLy8gaGFuZGxlZCBieSBhIHN1YnNlcXVlbnQgcHJvbWlzZS4gIFRoZSBleGNlcHRpb25zIGdldCBhZGRlZCB0byB0aGlzIGFycmF5IHdoZW5cbi8vIHRoZXkgYXJlIGNyZWF0ZWQsIGFuZCByZW1vdmVkIHdoZW4gdGhleSBhcmUgaGFuZGxlZC4gIE5vdGUgdGhhdCBpbiBFUzYgb3Jcbi8vIHNoaW1tZWQgZW52aXJvbm1lbnRzLCB0aGlzIHdvdWxkIG5hdHVyYWxseSBiZSBhIGBTZXRgLlxudmFyIHVuaGFuZGxlZFJlYXNvbnMgPSBbXTtcbnZhciB1bmhhbmRsZWRSZWplY3Rpb25zID0gW107XG52YXIgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zID0gW107XG52YXIgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcblxuZnVuY3Rpb24gcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCkge1xuICAgIHVuaGFuZGxlZFJlYXNvbnMubGVuZ3RoID0gMDtcbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLmxlbmd0aCA9IDA7XG5cbiAgICBpZiAoIXRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucykge1xuICAgICAgICB0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMgPSB0cnVlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdHJhY2tSZWplY3Rpb24ocHJvbWlzZSwgcmVhc29uKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIFEubmV4dFRpY2sucnVuQWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcHJvY2Vzcy5lbWl0KFwidW5oYW5kbGVkUmVqZWN0aW9uXCIsIHJlYXNvbiwgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVuaGFuZGxlZFJlamVjdGlvbnMucHVzaChwcm9taXNlKTtcbiAgICBpZiAocmVhc29uICYmIHR5cGVvZiByZWFzb24uc3RhY2sgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgdW5oYW5kbGVkUmVhc29ucy5wdXNoKHJlYXNvbi5zdGFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdW5oYW5kbGVkUmVhc29ucy5wdXNoKFwiKG5vIHN0YWNrKSBcIiArIHJlYXNvbik7XG4gICAgfVxufVxuXG5mdW5jdGlvbiB1bnRyYWNrUmVqZWN0aW9uKHByb21pc2UpIHtcbiAgICBpZiAoIXRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGF0ID0gYXJyYXlfaW5kZXhPZih1bmhhbmRsZWRSZWplY3Rpb25zLCBwcm9taXNlKTtcbiAgICBpZiAoYXQgIT09IC0xKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcHJvY2Vzcy5lbWl0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2sucnVuQWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBhdFJlcG9ydCA9IGFycmF5X2luZGV4T2YocmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICBpZiAoYXRSZXBvcnQgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInJlamVjdGlvbkhhbmRsZWRcIiwgdW5oYW5kbGVkUmVhc29uc1thdF0sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgICAgICByZXBvcnRlZFVuaGFuZGxlZFJlamVjdGlvbnMuc3BsaWNlKGF0UmVwb3J0LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdCwgMSk7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMuc3BsaWNlKGF0LCAxKTtcbiAgICB9XG59XG5cblEucmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zID0gcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zO1xuXG5RLmdldFVuaGFuZGxlZFJlYXNvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy8gTWFrZSBhIGNvcHkgc28gdGhhdCBjb25zdW1lcnMgY2FuJ3QgaW50ZXJmZXJlIHdpdGggb3VyIGludGVybmFsIHN0YXRlLlxuICAgIHJldHVybiB1bmhhbmRsZWRSZWFzb25zLnNsaWNlKCk7XG59O1xuXG5RLnN0b3BVbmhhbmRsZWRSZWplY3Rpb25UcmFja2luZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcbiAgICB0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMgPSBmYWxzZTtcbn07XG5cbnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpO1xuXG4vLy8vIEVORCBVTkhBTkRMRUQgUkVKRUNUSU9OIFRSQUNLSU5HXG5cbi8qKlxuICogQ29uc3RydWN0cyBhIHJlamVjdGVkIHByb21pc2UuXG4gKiBAcGFyYW0gcmVhc29uIHZhbHVlIGRlc2NyaWJpbmcgdGhlIGZhaWx1cmVcbiAqL1xuUS5yZWplY3QgPSByZWplY3Q7XG5mdW5jdGlvbiByZWplY3QocmVhc29uKSB7XG4gICAgdmFyIHJlamVjdGlvbiA9IFByb21pc2Uoe1xuICAgICAgICBcIndoZW5cIjogZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgICAgICAgICAvLyBub3RlIHRoYXQgdGhlIGVycm9yIGhhcyBiZWVuIGhhbmRsZWRcbiAgICAgICAgICAgIGlmIChyZWplY3RlZCkge1xuICAgICAgICAgICAgICAgIHVudHJhY2tSZWplY3Rpb24odGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0ZWQgPyByZWplY3RlZChyZWFzb24pIDogdGhpcztcbiAgICAgICAgfVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LCBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJyZWplY3RlZFwiLCByZWFzb246IHJlYXNvbiB9O1xuICAgIH0pO1xuXG4gICAgLy8gTm90ZSB0aGF0IHRoZSByZWFzb24gaGFzIG5vdCBiZWVuIGhhbmRsZWQuXG4gICAgdHJhY2tSZWplY3Rpb24ocmVqZWN0aW9uLCByZWFzb24pO1xuXG4gICAgcmV0dXJuIHJlamVjdGlvbjtcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgZnVsZmlsbGVkIHByb21pc2UgZm9yIGFuIGltbWVkaWF0ZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0gdmFsdWUgaW1tZWRpYXRlIHJlZmVyZW5jZVxuICovXG5RLmZ1bGZpbGwgPSBmdWxmaWxsO1xuZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgXCJnZXRcIjogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXTtcbiAgICAgICAgfSxcbiAgICAgICAgXCJzZXRcIjogZnVuY3Rpb24gKG5hbWUsIHJocykge1xuICAgICAgICAgICAgdmFsdWVbbmFtZV0gPSByaHM7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZGVsZXRlXCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICBkZWxldGUgdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwicG9zdFwiOiBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgICAgICAgICAgLy8gTWFyayBNaWxsZXIgcHJvcG9zZXMgdGhhdCBwb3N0IHdpdGggbm8gbmFtZSBzaG91bGQgYXBwbHkgYVxuICAgICAgICAgICAgLy8gcHJvbWlzZWQgZnVuY3Rpb24uXG4gICAgICAgICAgICBpZiAobmFtZSA9PT0gbnVsbCB8fCBuYW1lID09PSB2b2lkIDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodm9pZCAwLCBhcmdzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlW25hbWVdLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgXCJhcHBseVwiOiBmdW5jdGlvbiAodGhpc3AsIGFyZ3MpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5hcHBseSh0aGlzcCwgYXJncyk7XG4gICAgICAgIH0sXG4gICAgICAgIFwia2V5c1wiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0X2tleXModmFsdWUpO1xuICAgICAgICB9XG4gICAgfSwgdm9pZCAwLCBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJmdWxmaWxsZWRcIiwgdmFsdWU6IHZhbHVlIH07XG4gICAgfSk7XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlbmFibGVzIHRvIFEgcHJvbWlzZXMuXG4gKiBAcGFyYW0gcHJvbWlzZSB0aGVuYWJsZSBwcm9taXNlXG4gKiBAcmV0dXJucyBhIFEgcHJvbWlzZVxuICovXG5mdW5jdGlvbiBjb2VyY2UocHJvbWlzZSkge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwcm9taXNlLnRoZW4oZGVmZXJyZWQucmVzb2x2ZSwgZGVmZXJyZWQucmVqZWN0LCBkZWZlcnJlZC5ub3RpZnkpO1xuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChleGNlcHRpb24pO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cbi8qKlxuICogQW5ub3RhdGVzIGFuIG9iamVjdCBzdWNoIHRoYXQgaXQgd2lsbCBuZXZlciBiZVxuICogdHJhbnNmZXJyZWQgYXdheSBmcm9tIHRoaXMgcHJvY2VzcyBvdmVyIGFueSBwcm9taXNlXG4gKiBjb21tdW5pY2F0aW9uIGNoYW5uZWwuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBwcm9taXNlIGEgd3JhcHBpbmcgb2YgdGhhdCBvYmplY3QgdGhhdFxuICogYWRkaXRpb25hbGx5IHJlc3BvbmRzIHRvIHRoZSBcImlzRGVmXCIgbWVzc2FnZVxuICogd2l0aG91dCBhIHJlamVjdGlvbi5cbiAqL1xuUS5tYXN0ZXIgPSBtYXN0ZXI7XG5mdW5jdGlvbiBtYXN0ZXIob2JqZWN0KSB7XG4gICAgcmV0dXJuIFByb21pc2Uoe1xuICAgICAgICBcImlzRGVmXCI6IGZ1bmN0aW9uICgpIHt9XG4gICAgfSwgZnVuY3Rpb24gZmFsbGJhY2sob3AsIGFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIGRpc3BhdGNoKG9iamVjdCwgb3AsIGFyZ3MpO1xuICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFEob2JqZWN0KS5pbnNwZWN0KCk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogU3ByZWFkcyB0aGUgdmFsdWVzIG9mIGEgcHJvbWlzZWQgYXJyYXkgb2YgYXJndW1lbnRzIGludG8gdGhlXG4gKiBmdWxmaWxsbWVudCBjYWxsYmFjay5cbiAqIEBwYXJhbSBmdWxmaWxsZWQgY2FsbGJhY2sgdGhhdCByZWNlaXZlcyB2YXJpYWRpYyBhcmd1bWVudHMgZnJvbSB0aGVcbiAqIHByb21pc2VkIGFycmF5XG4gKiBAcGFyYW0gcmVqZWN0ZWQgY2FsbGJhY2sgdGhhdCByZWNlaXZlcyB0aGUgZXhjZXB0aW9uIGlmIHRoZSBwcm9taXNlXG4gKiBpcyByZWplY3RlZC5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZSBvciB0aHJvd24gZXhjZXB0aW9uIG9mXG4gKiBlaXRoZXIgY2FsbGJhY2suXG4gKi9cblEuc3ByZWFkID0gc3ByZWFkO1xuZnVuY3Rpb24gc3ByZWFkKHZhbHVlLCBmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIFEodmFsdWUpLnNwcmVhZChmdWxmaWxsZWQsIHJlamVjdGVkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuc3ByZWFkID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpIHtcbiAgICByZXR1cm4gdGhpcy5hbGwoKS50aGVuKGZ1bmN0aW9uIChhcnJheSkge1xuICAgICAgICByZXR1cm4gZnVsZmlsbGVkLmFwcGx5KHZvaWQgMCwgYXJyYXkpO1xuICAgIH0sIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogVGhlIGFzeW5jIGZ1bmN0aW9uIGlzIGEgZGVjb3JhdG9yIGZvciBnZW5lcmF0b3IgZnVuY3Rpb25zLCB0dXJuaW5nXG4gKiB0aGVtIGludG8gYXN5bmNocm9ub3VzIGdlbmVyYXRvcnMuICBBbHRob3VnaCBnZW5lcmF0b3JzIGFyZSBvbmx5IHBhcnRcbiAqIG9mIHRoZSBuZXdlc3QgRUNNQVNjcmlwdCA2IGRyYWZ0cywgdGhpcyBjb2RlIGRvZXMgbm90IGNhdXNlIHN5bnRheFxuICogZXJyb3JzIGluIG9sZGVyIGVuZ2luZXMuICBUaGlzIGNvZGUgc2hvdWxkIGNvbnRpbnVlIHRvIHdvcmsgYW5kIHdpbGxcbiAqIGluIGZhY3QgaW1wcm92ZSBvdmVyIHRpbWUgYXMgdGhlIGxhbmd1YWdlIGltcHJvdmVzLlxuICpcbiAqIEVTNiBnZW5lcmF0b3JzIGFyZSBjdXJyZW50bHkgcGFydCBvZiBWOCB2ZXJzaW9uIDMuMTkgd2l0aCB0aGVcbiAqIC0taGFybW9ueS1nZW5lcmF0b3JzIHJ1bnRpbWUgZmxhZyBlbmFibGVkLiAgU3BpZGVyTW9ua2V5IGhhcyBoYWQgdGhlbVxuICogZm9yIGxvbmdlciwgYnV0IHVuZGVyIGFuIG9sZGVyIFB5dGhvbi1pbnNwaXJlZCBmb3JtLiAgVGhpcyBmdW5jdGlvblxuICogd29ya3Mgb24gYm90aCBraW5kcyBvZiBnZW5lcmF0b3JzLlxuICpcbiAqIERlY29yYXRlcyBhIGdlbmVyYXRvciBmdW5jdGlvbiBzdWNoIHRoYXQ6XG4gKiAgLSBpdCBtYXkgeWllbGQgcHJvbWlzZXNcbiAqICAtIGV4ZWN1dGlvbiB3aWxsIGNvbnRpbnVlIHdoZW4gdGhhdCBwcm9taXNlIGlzIGZ1bGZpbGxlZFxuICogIC0gdGhlIHZhbHVlIG9mIHRoZSB5aWVsZCBleHByZXNzaW9uIHdpbGwgYmUgdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogIC0gaXQgcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgKHdoZW4gdGhlIGdlbmVyYXRvclxuICogICAgc3RvcHMgaXRlcmF0aW5nKVxuICogIC0gdGhlIGRlY29yYXRlZCBmdW5jdGlvbiByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICogICAgb2YgdGhlIGdlbmVyYXRvciBvciB0aGUgZmlyc3QgcmVqZWN0ZWQgcHJvbWlzZSBhbW9uZyB0aG9zZVxuICogICAgeWllbGRlZC5cbiAqICAtIGlmIGFuIGVycm9yIGlzIHRocm93biBpbiB0aGUgZ2VuZXJhdG9yLCBpdCBwcm9wYWdhdGVzIHRocm91Z2hcbiAqICAgIGV2ZXJ5IGZvbGxvd2luZyB5aWVsZCB1bnRpbCBpdCBpcyBjYXVnaHQsIG9yIHVudGlsIGl0IGVzY2FwZXNcbiAqICAgIHRoZSBnZW5lcmF0b3IgZnVuY3Rpb24gYWx0b2dldGhlciwgYW5kIGlzIHRyYW5zbGF0ZWQgaW50byBhXG4gKiAgICByZWplY3Rpb24gZm9yIHRoZSBwcm9taXNlIHJldHVybmVkIGJ5IHRoZSBkZWNvcmF0ZWQgZ2VuZXJhdG9yLlxuICovXG5RLmFzeW5jID0gYXN5bmM7XG5mdW5jdGlvbiBhc3luYyhtYWtlR2VuZXJhdG9yKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwic2VuZFwiLCBhcmcgaXMgYSB2YWx1ZVxuICAgICAgICAvLyB3aGVuIHZlcmIgaXMgXCJ0aHJvd1wiLCBhcmcgaXMgYW4gZXhjZXB0aW9uXG4gICAgICAgIGZ1bmN0aW9uIGNvbnRpbnVlcih2ZXJiLCBhcmcpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQ7XG5cbiAgICAgICAgICAgIC8vIFVudGlsIFY4IDMuMTkgLyBDaHJvbWl1bSAyOSBpcyByZWxlYXNlZCwgU3BpZGVyTW9ua2V5IGlzIHRoZSBvbmx5XG4gICAgICAgICAgICAvLyBlbmdpbmUgdGhhdCBoYXMgYSBkZXBsb3llZCBiYXNlIG9mIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBnZW5lcmF0b3JzLlxuICAgICAgICAgICAgLy8gSG93ZXZlciwgU00ncyBnZW5lcmF0b3JzIHVzZSB0aGUgUHl0aG9uLWluc3BpcmVkIHNlbWFudGljcyBvZlxuICAgICAgICAgICAgLy8gb3V0ZGF0ZWQgRVM2IGRyYWZ0cy4gIFdlIHdvdWxkIGxpa2UgdG8gc3VwcG9ydCBFUzYsIGJ1dCB3ZSdkIGFsc29cbiAgICAgICAgICAgIC8vIGxpa2UgdG8gbWFrZSBpdCBwb3NzaWJsZSB0byB1c2UgZ2VuZXJhdG9ycyBpbiBkZXBsb3llZCBicm93c2Vycywgc29cbiAgICAgICAgICAgIC8vIHdlIGFsc28gc3VwcG9ydCBQeXRob24tc3R5bGUgZ2VuZXJhdG9ycy4gIEF0IHNvbWUgcG9pbnQgd2UgY2FuIHJlbW92ZVxuICAgICAgICAgICAgLy8gdGhpcyBibG9jay5cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBTdG9wSXRlcmF0aW9uID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgLy8gRVM2IEdlbmVyYXRvcnNcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFEocmVzdWx0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gd2hlbihyZXN1bHQudmFsdWUsIGNhbGxiYWNrLCBlcnJiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFNwaWRlck1vbmtleSBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgLy8gRklYTUU6IFJlbW92ZSB0aGlzIGNhc2Ugd2hlbiBTTSBkb2VzIEVTNiBnZW5lcmF0b3JzLlxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGdlbmVyYXRvclt2ZXJiXShhcmcpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBRKGV4Y2VwdGlvbi52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGdlbmVyYXRvciA9IG1ha2VHZW5lcmF0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gY29udGludWVyLmJpbmQoY29udGludWVyLCBcIm5leHRcIik7XG4gICAgICAgIHZhciBlcnJiYWNrID0gY29udGludWVyLmJpbmQoY29udGludWVyLCBcInRocm93XCIpO1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9O1xufVxuXG4vKipcbiAqIFRoZSBzcGF3biBmdW5jdGlvbiBpcyBhIHNtYWxsIHdyYXBwZXIgYXJvdW5kIGFzeW5jIHRoYXQgaW1tZWRpYXRlbHlcbiAqIGNhbGxzIHRoZSBnZW5lcmF0b3IgYW5kIGFsc28gZW5kcyB0aGUgcHJvbWlzZSBjaGFpbiwgc28gdGhhdCBhbnlcbiAqIHVuaGFuZGxlZCBlcnJvcnMgYXJlIHRocm93biBpbnN0ZWFkIG9mIGZvcndhcmRlZCB0byB0aGUgZXJyb3JcbiAqIGhhbmRsZXIuIFRoaXMgaXMgdXNlZnVsIGJlY2F1c2UgaXQncyBleHRyZW1lbHkgY29tbW9uIHRvIHJ1blxuICogZ2VuZXJhdG9ycyBhdCB0aGUgdG9wLWxldmVsIHRvIHdvcmsgd2l0aCBsaWJyYXJpZXMuXG4gKi9cblEuc3Bhd24gPSBzcGF3bjtcbmZ1bmN0aW9uIHNwYXduKG1ha2VHZW5lcmF0b3IpIHtcbiAgICBRLmRvbmUoUS5hc3luYyhtYWtlR2VuZXJhdG9yKSgpKTtcbn1cblxuLy8gRklYTUU6IFJlbW92ZSB0aGlzIGludGVyZmFjZSBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpbiBTcGlkZXJNb25rZXkuXG4vKipcbiAqIFRocm93cyBhIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB0byBzdG9wIGFuIGFzeW5jaHJvbm91cyBnZW5lcmF0b3IuXG4gKlxuICogVGhpcyBpbnRlcmZhY2UgaXMgYSBzdG9wLWdhcCBtZWFzdXJlIHRvIHN1cHBvcnQgZ2VuZXJhdG9yIHJldHVyblxuICogdmFsdWVzIGluIG9sZGVyIEZpcmVmb3gvU3BpZGVyTW9ua2V5LiAgSW4gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IEVTNlxuICogZ2VuZXJhdG9ycyBsaWtlIENocm9taXVtIDI5LCBqdXN0IHVzZSBcInJldHVyblwiIGluIHlvdXIgZ2VuZXJhdG9yXG4gKiBmdW5jdGlvbnMuXG4gKlxuICogQHBhcmFtIHZhbHVlIHRoZSByZXR1cm4gdmFsdWUgZm9yIHRoZSBzdXJyb3VuZGluZyBnZW5lcmF0b3JcbiAqIEB0aHJvd3MgUmV0dXJuVmFsdWUgZXhjZXB0aW9uIHdpdGggdGhlIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqIC8vIEVTNiBzdHlsZVxuICogUS5hc3luYyhmdW5jdGlvbiogKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICByZXR1cm4gZm9vICsgYmFyO1xuICogfSlcbiAqIC8vIE9sZGVyIFNwaWRlck1vbmtleSBzdHlsZVxuICogUS5hc3luYyhmdW5jdGlvbiAoKSB7XG4gKiAgICAgIHZhciBmb28gPSB5aWVsZCBnZXRGb29Qcm9taXNlKCk7XG4gKiAgICAgIHZhciBiYXIgPSB5aWVsZCBnZXRCYXJQcm9taXNlKCk7XG4gKiAgICAgIFEucmV0dXJuKGZvbyArIGJhcik7XG4gKiB9KVxuICovXG5RW1wicmV0dXJuXCJdID0gX3JldHVybjtcbmZ1bmN0aW9uIF9yZXR1cm4odmFsdWUpIHtcbiAgICB0aHJvdyBuZXcgUVJldHVyblZhbHVlKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBUaGUgcHJvbWlzZWQgZnVuY3Rpb24gZGVjb3JhdG9yIGVuc3VyZXMgdGhhdCBhbnkgcHJvbWlzZSBhcmd1bWVudHNcbiAqIGFyZSBzZXR0bGVkIGFuZCBwYXNzZWQgYXMgdmFsdWVzIChgdGhpc2AgaXMgYWxzbyBzZXR0bGVkIGFuZCBwYXNzZWRcbiAqIGFzIGEgdmFsdWUpLiAgSXQgd2lsbCBhbHNvIGVuc3VyZSB0aGF0IHRoZSByZXN1bHQgb2YgYSBmdW5jdGlvbiBpc1xuICogYWx3YXlzIGEgcHJvbWlzZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogdmFyIGFkZCA9IFEucHJvbWlzZWQoZnVuY3Rpb24gKGEsIGIpIHtcbiAqICAgICByZXR1cm4gYSArIGI7XG4gKiB9KTtcbiAqIGFkZChRKGEpLCBRKEIpKTtcbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdG8gZGVjb3JhdGVcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gYSBmdW5jdGlvbiB0aGF0IGhhcyBiZWVuIGRlY29yYXRlZC5cbiAqL1xuUS5wcm9taXNlZCA9IHByb21pc2VkO1xuZnVuY3Rpb24gcHJvbWlzZWQoY2FsbGJhY2spIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gc3ByZWFkKFt0aGlzLCBhbGwoYXJndW1lbnRzKV0sIGZ1bmN0aW9uIChzZWxmLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgICAgIH0pO1xuICAgIH07XG59XG5cbi8qKlxuICogc2VuZHMgYSBtZXNzYWdlIHRvIGEgdmFsdWUgaW4gYSBmdXR1cmUgdHVyblxuICogQHBhcmFtIG9iamVjdCogdGhlIHJlY2lwaWVudFxuICogQHBhcmFtIG9wIHRoZSBuYW1lIG9mIHRoZSBtZXNzYWdlIG9wZXJhdGlvbiwgZS5nLiwgXCJ3aGVuXCIsXG4gKiBAcGFyYW0gYXJncyBmdXJ0aGVyIGFyZ3VtZW50cyB0byBiZSBmb3J3YXJkZWQgdG8gdGhlIG9wZXJhdGlvblxuICogQHJldHVybnMgcmVzdWx0IHtQcm9taXNlfSBhIHByb21pc2UgZm9yIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvblxuICovXG5RLmRpc3BhdGNoID0gZGlzcGF0Y2g7XG5mdW5jdGlvbiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChvcCwgYXJncyk7XG59XG5cblByb21pc2UucHJvdG90eXBlLmRpc3BhdGNoID0gZnVuY3Rpb24gKG9wLCBhcmdzKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGRlZmVycmVkLnJlc29sdmUsIG9wLCBhcmdzKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBnZXRcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHByb3BlcnR5IHZhbHVlXG4gKi9cblEuZ2V0ID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImdldFwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3Igb2JqZWN0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIHByb3BlcnR5IHRvIHNldFxuICogQHBhcmFtIHZhbHVlICAgICBuZXcgdmFsdWUgb2YgcHJvcGVydHlcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwic2V0XCIsIFtrZXksIHZhbHVlXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwic2V0XCIsIFtrZXksIHZhbHVlXSk7XG59O1xuXG4vKipcbiAqIERlbGV0ZXMgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBkZWxldGVcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLmRlbCA9IC8vIFhYWCBsZWdhY3lcblFbXCJkZWxldGVcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBrZXkpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiZGVsZXRlXCIsIFtrZXldKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbCA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZGVsZXRlXCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogSW52b2tlcyBhIG1ldGhvZCBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBtZXRob2QgdG8gaW52b2tlXG4gKiBAcGFyYW0gdmFsdWUgICAgIGEgdmFsdWUgdG8gcG9zdCwgdHlwaWNhbGx5IGFuIGFycmF5IG9mXG4gKiAgICAgICAgICAgICAgICAgIGludm9jYXRpb24gYXJndW1lbnRzIGZvciBwcm9taXNlcyB0aGF0XG4gKiAgICAgICAgICAgICAgICAgIGFyZSB1bHRpbWF0ZWx5IGJhY2tlZCB3aXRoIGByZXNvbHZlYCB2YWx1ZXMsXG4gKiAgICAgICAgICAgICAgICAgIGFzIG9wcG9zZWQgdG8gdGhvc2UgYmFja2VkIHdpdGggVVJMc1xuICogICAgICAgICAgICAgICAgICB3aGVyZWluIHRoZSBwb3N0ZWQgdmFsdWUgY2FuIGJlIGFueVxuICogICAgICAgICAgICAgICAgICBKU09OIHNlcmlhbGl6YWJsZSBvYmplY3QuXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuLy8gYm91bmQgbG9jYWxseSBiZWNhdXNlIGl0IGlzIHVzZWQgYnkgb3RoZXIgbWV0aG9kc1xuUS5tYXBwbHkgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUS5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcmdzXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5tYXBwbHkgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUHJvbWlzZS5wcm90b3R5cGUucG9zdCA9IGZ1bmN0aW9uIChuYW1lLCBhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBpbnZvY2F0aW9uIGFyZ3VtZW50c1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cblEuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5RLm1jYWxsID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEuaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcnJheV9zbGljZShhcmd1bWVudHMsIDIpXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5zZW5kID0gLy8gWFhYIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgcGFybGFuY2VcblByb21pc2UucHJvdG90eXBlLm1jYWxsID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLmludm9rZSA9IGZ1bmN0aW9uIChuYW1lIC8qLi4uYXJncyovKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpXSk7XG59O1xuXG4vKipcbiAqIEFwcGxpZXMgdGhlIHByb21pc2VkIGZ1bmN0aW9uIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gYXJncyAgICAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZhcHBseSA9IGZ1bmN0aW9uIChvYmplY3QsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmFwcGx5ID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cbi8qKlxuICogQ2FsbHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RW1widHJ5XCJdID1cblEuZmNhbGwgPSBmdW5jdGlvbiAob2JqZWN0IC8qIC4uLmFyZ3MqLykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5mY2FsbCA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzKV0pO1xufTtcblxuLyoqXG4gKiBCaW5kcyB0aGUgcHJvbWlzZWQgZnVuY3Rpb24sIHRyYW5zZm9ybWluZyByZXR1cm4gdmFsdWVzIGludG8gYSBmdWxmaWxsZWRcbiAqIHByb21pc2UgYW5kIHRocm93biBlcnJvcnMgaW50byBhIHJlamVjdGVkIG9uZS5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgZnVuY3Rpb25cbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgYXBwbGljYXRpb24gYXJndW1lbnRzXG4gKi9cblEuZmJpbmQgPSBmdW5jdGlvbiAob2JqZWN0IC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSBRKG9iamVjdCk7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBmdW5jdGlvbiBmYm91bmQoKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlLmRpc3BhdGNoKFwiYXBwbHlcIiwgW1xuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIGFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpXG4gICAgICAgIF0pO1xuICAgIH07XG59O1xuUHJvbWlzZS5wcm90b3R5cGUuZmJpbmQgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgIHJldHVybiBmdW5jdGlvbiBmYm91bmQoKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlLmRpc3BhdGNoKFwiYXBwbHlcIiwgW1xuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIGFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpXG4gICAgICAgIF0pO1xuICAgIH07XG59O1xuXG4vKipcbiAqIFJlcXVlc3RzIHRoZSBuYW1lcyBvZiB0aGUgb3duZWQgcHJvcGVydGllcyBvZiBhIHByb21pc2VkXG4gKiBvYmplY3QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBrZXlzIG9mIHRoZSBldmVudHVhbGx5IHNldHRsZWQgb2JqZWN0XG4gKi9cblEua2V5cyA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwia2V5c1wiLCBbXSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5rZXlzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwia2V5c1wiLCBbXSk7XG59O1xuXG4vKipcbiAqIFR1cm5zIGFuIGFycmF5IG9mIHByb21pc2VzIGludG8gYSBwcm9taXNlIGZvciBhbiBhcnJheS4gIElmIGFueSBvZlxuICogdGhlIHByb21pc2VzIGdldHMgcmVqZWN0ZWQsIHRoZSB3aG9sZSBhcnJheSBpcyByZWplY3RlZCBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QXJyYXkqfSBhbiBhcnJheSAob3IgcHJvbWlzZSBmb3IgYW4gYXJyYXkpIG9mIHZhbHVlcyAob3JcbiAqIHByb21pc2VzIGZvciB2YWx1ZXMpXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlc1xuICovXG4vLyBCeSBNYXJrIE1pbGxlclxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9c3RyYXdtYW46Y29uY3VycmVuY3kmcmV2PTEzMDg3NzY1MjEjYWxsZnVsZmlsbGVkXG5RLmFsbCA9IGFsbDtcbmZ1bmN0aW9uIGFsbChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgdmFyIHBlbmRpbmdDb3VudCA9IDA7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9taXNlcywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvbWlzZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBzbmFwc2hvdDtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBpc1Byb21pc2UocHJvbWlzZSkgJiZcbiAgICAgICAgICAgICAgICAoc25hcHNob3QgPSBwcm9taXNlLmluc3BlY3QoKSkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCJcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHByb21pc2VzW2luZGV4XSA9IHNuYXBzaG90LnZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICArK3BlbmRpbmdDb3VudDtcbiAgICAgICAgICAgICAgICB3aGVuKFxuICAgICAgICAgICAgICAgICAgICBwcm9taXNlLFxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VzW2luZGV4XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKC0tcGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShwcm9taXNlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdCxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkoeyBpbmRleDogaW5kZXgsIHZhbHVlOiBwcm9ncmVzcyB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHZvaWQgMCk7XG4gICAgICAgIGlmIChwZW5kaW5nQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH0pO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5hbGwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgcmVzb2x2ZWQgcHJvbWlzZSBvZiBhbiBhcnJheS4gUHJpb3IgcmVqZWN0ZWQgcHJvbWlzZXMgYXJlXG4gKiBpZ25vcmVkLiAgUmVqZWN0cyBvbmx5IGlmIGFsbCBwcm9taXNlcyBhcmUgcmVqZWN0ZWQuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgY29udGFpbmluZyB2YWx1ZXMgb3IgcHJvbWlzZXMgZm9yIHZhbHVlc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZ1bGZpbGxlZCB3aXRoIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgcmVzb2x2ZWQgcHJvbWlzZSxcbiAqIG9yIGEgcmVqZWN0ZWQgcHJvbWlzZSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICovXG5RLmFueSA9IGFueTtcblxuZnVuY3Rpb24gYW55KHByb21pc2VzKSB7XG4gICAgaWYgKHByb21pc2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gUS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgdmFyIGRlZmVycmVkID0gUS5kZWZlcigpO1xuICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgIGFycmF5X3JlZHVjZShwcm9taXNlcywgZnVuY3Rpb24gKHByZXYsIGN1cnJlbnQsIGluZGV4KSB7XG4gICAgICAgIHZhciBwcm9taXNlID0gcHJvbWlzZXNbaW5kZXhdO1xuXG4gICAgICAgIHBlbmRpbmdDb3VudCsrO1xuXG4gICAgICAgIHdoZW4ocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIG9uUHJvZ3Jlc3MpO1xuICAgICAgICBmdW5jdGlvbiBvbkZ1bGZpbGxlZChyZXN1bHQpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBvblJlamVjdGVkKCkge1xuICAgICAgICAgICAgcGVuZGluZ0NvdW50LS07XG4gICAgICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgZGVmZXJyZWQucmVqZWN0KG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgXCJDYW4ndCBnZXQgZnVsZmlsbG1lbnQgdmFsdWUgZnJvbSBhbnkgcHJvbWlzZSwgYWxsIFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJwcm9taXNlcyB3ZXJlIHJlamVjdGVkLlwiXG4gICAgICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25Qcm9ncmVzcyhwcm9ncmVzcykge1xuICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHtcbiAgICAgICAgICAgICAgICBpbmRleDogaW5kZXgsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHByb2dyZXNzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sIHVuZGVmaW5lZCk7XG5cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYW55ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbnkodGhpcyk7XG59O1xuXG4vKipcbiAqIFdhaXRzIGZvciBhbGwgcHJvbWlzZXMgdG8gYmUgc2V0dGxlZCwgZWl0aGVyIGZ1bGZpbGxlZCBvclxuICogcmVqZWN0ZWQuICBUaGlzIGlzIGRpc3RpbmN0IGZyb20gYGFsbGAgc2luY2UgdGhhdCB3b3VsZCBzdG9wXG4gKiB3YWl0aW5nIGF0IHRoZSBmaXJzdCByZWplY3Rpb24uICBUaGUgcHJvbWlzZSByZXR1cm5lZCBieVxuICogYGFsbFJlc29sdmVkYCB3aWxsIG5ldmVyIGJlIHJlamVjdGVkLlxuICogQHBhcmFtIHByb21pc2VzIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgKG9yIGFuIGFycmF5KSBvZiBwcm9taXNlc1xuICogKG9yIHZhbHVlcylcbiAqIEByZXR1cm4gYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiBwcm9taXNlc1xuICovXG5RLmFsbFJlc29sdmVkID0gZGVwcmVjYXRlKGFsbFJlc29sdmVkLCBcImFsbFJlc29sdmVkXCIsIFwiYWxsU2V0dGxlZFwiKTtcbmZ1bmN0aW9uIGFsbFJlc29sdmVkKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIHdoZW4ocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlcykge1xuICAgICAgICBwcm9taXNlcyA9IGFycmF5X21hcChwcm9taXNlcywgUSk7XG4gICAgICAgIHJldHVybiB3aGVuKGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4gd2hlbihwcm9taXNlLCBub29wLCBub29wKTtcbiAgICAgICAgfSkpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZXM7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5hbGxSZXNvbHZlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWxsUmVzb2x2ZWQodGhpcyk7XG59O1xuXG4vKipcbiAqIEBzZWUgUHJvbWlzZSNhbGxTZXR0bGVkXG4gKi9cblEuYWxsU2V0dGxlZCA9IGFsbFNldHRsZWQ7XG5mdW5jdGlvbiBhbGxTZXR0bGVkKHByb21pc2VzKSB7XG4gICAgcmV0dXJuIFEocHJvbWlzZXMpLmFsbFNldHRsZWQoKTtcbn1cblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgdGhlaXIgc3RhdGVzIChhc1xuICogcmV0dXJuZWQgYnkgYGluc3BlY3RgKSB3aGVuIHRoZXkgaGF2ZSBhbGwgc2V0dGxlZC5cbiAqIEBwYXJhbSB7QXJyYXlbQW55Kl19IHZhbHVlcyBhbiBhcnJheSAob3IgcHJvbWlzZSBmb3IgYW4gYXJyYXkpIG9mIHZhbHVlcyAob3JcbiAqIHByb21pc2VzIGZvciB2YWx1ZXMpXG4gKiBAcmV0dXJucyB7QXJyYXlbU3RhdGVdfSBhbiBhcnJheSBvZiBzdGF0ZXMgZm9yIHRoZSByZXNwZWN0aXZlIHZhbHVlcy5cbiAqL1xuUHJvbWlzZS5wcm90b3R5cGUuYWxsU2V0dGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uIChwcm9taXNlcykge1xuICAgICAgICByZXR1cm4gYWxsKGFycmF5X21hcChwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgICAgICAgICAgIHByb21pc2UgPSBRKHByb21pc2UpO1xuICAgICAgICAgICAgZnVuY3Rpb24gcmVnYXJkbGVzcygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZS5pbnNwZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKHJlZ2FyZGxlc3MsIHJlZ2FyZGxlc3MpO1xuICAgICAgICB9KSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIENhcHR1cmVzIHRoZSBmYWlsdXJlIG9mIGEgcHJvbWlzZSwgZ2l2aW5nIGFuIG9wb3J0dW5pdHkgdG8gcmVjb3ZlclxuICogd2l0aCBhIGNhbGxiYWNrLiAgSWYgdGhlIGdpdmVuIHByb21pc2UgaXMgZnVsZmlsbGVkLCB0aGUgcmV0dXJuZWRcbiAqIHByb21pc2UgaXMgZnVsZmlsbGVkLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlIGZvciBzb21ldGhpbmdcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRvIGZ1bGZpbGwgdGhlIHJldHVybmVkIHByb21pc2UgaWYgdGhlXG4gKiBnaXZlbiBwcm9taXNlIGlzIHJlamVjdGVkXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGNhbGxiYWNrXG4gKi9cblEuZmFpbCA9IC8vIFhYWCBsZWdhY3lcblFbXCJjYXRjaFwiXSA9IGZ1bmN0aW9uIChvYmplY3QsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aGVuKHZvaWQgMCwgcmVqZWN0ZWQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmFpbCA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAocmVqZWN0ZWQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKHZvaWQgMCwgcmVqZWN0ZWQpO1xufTtcblxuLyoqXG4gKiBBdHRhY2hlcyBhIGxpc3RlbmVyIHRoYXQgY2FuIHJlc3BvbmQgdG8gcHJvZ3Jlc3Mgbm90aWZpY2F0aW9ucyBmcm9tIGFcbiAqIHByb21pc2UncyBvcmlnaW5hdGluZyBkZWZlcnJlZC4gVGhpcyBsaXN0ZW5lciByZWNlaXZlcyB0aGUgZXhhY3QgYXJndW1lbnRzXG4gKiBwYXNzZWQgdG8gYGBkZWZlcnJlZC5ub3RpZnlgYC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byByZWNlaXZlIGFueSBwcm9ncmVzcyBub3RpZmljYXRpb25zXG4gKiBAcmV0dXJucyB0aGUgZ2l2ZW4gcHJvbWlzZSwgdW5jaGFuZ2VkXG4gKi9cblEucHJvZ3Jlc3MgPSBwcm9ncmVzcztcbmZ1bmN0aW9uIHByb2dyZXNzKG9iamVjdCwgcHJvZ3Jlc3NlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnByb2dyZXNzID0gZnVuY3Rpb24gKHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKHZvaWQgMCwgdm9pZCAwLCBwcm9ncmVzc2VkKTtcbn07XG5cbi8qKlxuICogUHJvdmlkZXMgYW4gb3Bwb3J0dW5pdHkgdG8gb2JzZXJ2ZSB0aGUgc2V0dGxpbmcgb2YgYSBwcm9taXNlLFxuICogcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSBwcm9taXNlIGlzIGZ1bGZpbGxlZCBvciByZWplY3RlZC4gIEZvcndhcmRzXG4gKiB0aGUgcmVzb2x1dGlvbiB0byB0aGUgcmV0dXJuZWQgcHJvbWlzZSB3aGVuIHRoZSBjYWxsYmFjayBpcyBkb25lLlxuICogVGhlIGNhbGxiYWNrIGNhbiByZXR1cm4gYSBwcm9taXNlIHRvIGRlZmVyIGNvbXBsZXRpb24uXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2VcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRvIG9ic2VydmUgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuXG4gKiBwcm9taXNlLCB0YWtlcyBubyBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlbiBwcm9taXNlIHdoZW5cbiAqIGBgZmluYGAgaXMgZG9uZS5cbiAqL1xuUS5maW4gPSAvLyBYWFggbGVnYWN5XG5RW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KVtcImZpbmFsbHlcIl0oY2FsbGJhY2spO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmluID0gLy8gWFhYIGxlZ2FjeVxuUHJvbWlzZS5wcm90b3R5cGVbXCJmaW5hbGx5XCJdID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBRKGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAvLyBUT0RPIGF0dGVtcHQgdG8gcmVjeWNsZSB0aGUgcmVqZWN0aW9uIHdpdGggXCJ0aGlzXCIuXG4gICAgICAgIHJldHVybiBjYWxsYmFjay5mY2FsbCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhyb3cgcmVhc29uO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogVGVybWluYXRlcyBhIGNoYWluIG9mIHByb21pc2VzLCBmb3JjaW5nIHJlamVjdGlvbnMgdG8gYmVcbiAqIHRocm93biBhcyBleGNlcHRpb25zLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlIGF0IHRoZSBlbmQgb2YgYSBjaGFpbiBvZiBwcm9taXNlc1xuICogQHJldHVybnMgbm90aGluZ1xuICovXG5RLmRvbmUgPSBmdW5jdGlvbiAob2JqZWN0LCBmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZG9uZShmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kb25lID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzKSB7XG4gICAgdmFyIG9uVW5oYW5kbGVkRXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgLy8gZm9yd2FyZCB0byBhIGZ1dHVyZSB0dXJuIHNvIHRoYXQgYGB3aGVuYGBcbiAgICAgICAgLy8gZG9lcyBub3QgY2F0Y2ggaXQgYW5kIHR1cm4gaXQgaW50byBhIHJlamVjdGlvbi5cbiAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBtYWtlU3RhY2tUcmFjZUxvbmcoZXJyb3IsIHByb21pc2UpO1xuICAgICAgICAgICAgaWYgKFEub25lcnJvcikge1xuICAgICAgICAgICAgICAgIFEub25lcnJvcihlcnJvcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gQXZvaWQgdW5uZWNlc3NhcnkgYG5leHRUaWNrYGluZyB2aWEgYW4gdW5uZWNlc3NhcnkgYHdoZW5gLlxuICAgIHZhciBwcm9taXNlID0gZnVsZmlsbGVkIHx8IHJlamVjdGVkIHx8IHByb2dyZXNzID9cbiAgICAgICAgdGhpcy50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzKSA6XG4gICAgICAgIHRoaXM7XG5cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgcHJvY2VzcyAmJiBwcm9jZXNzLmRvbWFpbikge1xuICAgICAgICBvblVuaGFuZGxlZEVycm9yID0gcHJvY2Vzcy5kb21haW4uYmluZChvblVuaGFuZGxlZEVycm9yKTtcbiAgICB9XG5cbiAgICBwcm9taXNlLnRoZW4odm9pZCAwLCBvblVuaGFuZGxlZEVycm9yKTtcbn07XG5cbi8qKlxuICogQ2F1c2VzIGEgcHJvbWlzZSB0byBiZSByZWplY3RlZCBpZiBpdCBkb2VzIG5vdCBnZXQgZnVsZmlsbGVkIGJlZm9yZVxuICogc29tZSBtaWxsaXNlY29uZHMgdGltZSBvdXQuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2VcbiAqIEBwYXJhbSB7TnVtYmVyfSBtaWxsaXNlY29uZHMgdGltZW91dFxuICogQHBhcmFtIHtBbnkqfSBjdXN0b20gZXJyb3IgbWVzc2FnZSBvciBFcnJvciBvYmplY3QgKG9wdGlvbmFsKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBpZiBpdCBpc1xuICogZnVsZmlsbGVkIGJlZm9yZSB0aGUgdGltZW91dCwgb3RoZXJ3aXNlIHJlamVjdGVkLlxuICovXG5RLnRpbWVvdXQgPSBmdW5jdGlvbiAob2JqZWN0LCBtcywgZXJyb3IpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRpbWVvdXQobXMsIGVycm9yKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRpbWVvdXQgPSBmdW5jdGlvbiAobXMsIGVycm9yKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghZXJyb3IgfHwgXCJzdHJpbmdcIiA9PT0gdHlwZW9mIGVycm9yKSB7XG4gICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcihlcnJvciB8fCBcIlRpbWVkIG91dCBhZnRlciBcIiArIG1zICsgXCIgbXNcIik7XG4gICAgICAgICAgICBlcnJvci5jb2RlID0gXCJFVElNRURPVVRcIjtcbiAgICAgICAgfVxuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXJyb3IpO1xuICAgIH0sIG1zKTtcblxuICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uIChleGNlcHRpb24pIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChleGNlcHRpb24pO1xuICAgIH0sIGRlZmVycmVkLm5vdGlmeSk7XG5cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSBnaXZlbiB2YWx1ZSAob3IgcHJvbWlzZWQgdmFsdWUpLCBzb21lXG4gKiBtaWxsaXNlY29uZHMgYWZ0ZXIgaXQgcmVzb2x2ZWQuIFBhc3NlcyByZWplY3Rpb25zIGltbWVkaWF0ZWx5LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlbiBwcm9taXNlIGFmdGVyIG1pbGxpc2Vjb25kc1xuICogdGltZSBoYXMgZWxhcHNlZCBzaW5jZSB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZS5cbiAqIElmIHRoZSBnaXZlbiBwcm9taXNlIHJlamVjdHMsIHRoYXQgaXMgcGFzc2VkIGltbWVkaWF0ZWx5LlxuICovXG5RLmRlbGF5ID0gZnVuY3Rpb24gKG9iamVjdCwgdGltZW91dCkge1xuICAgIGlmICh0aW1lb3V0ID09PSB2b2lkIDApIHtcbiAgICAgICAgdGltZW91dCA9IG9iamVjdDtcbiAgICAgICAgb2JqZWN0ID0gdm9pZCAwO1xuICAgIH1cbiAgICByZXR1cm4gUShvYmplY3QpLmRlbGF5KHRpbWVvdXQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZGVsYXkgPSBmdW5jdGlvbiAodGltZW91dCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZSh2YWx1ZSk7XG4gICAgICAgIH0sIHRpbWVvdXQpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgYXMgYW4gYXJyYXksIGFuZCByZXR1cm5zIGEgcHJvbWlzZS5cbiAqXG4gKiAgICAgIFEubmZhcHBseShGUy5yZWFkRmlsZSwgW19fZmlsZW5hbWVdKVxuICogICAgICAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogICAgICB9KVxuICpcbiAqL1xuUS5uZmFwcGx5ID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBhcmdzKSB7XG4gICAgcmV0dXJuIFEoY2FsbGJhY2spLm5mYXBwbHkoYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uZmFwcGx5ID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3MpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBQYXNzZXMgYSBjb250aW51YXRpb24gdG8gYSBOb2RlIGZ1bmN0aW9uLCB3aGljaCBpcyBjYWxsZWQgd2l0aCB0aGUgZ2l2ZW5cbiAqIGFyZ3VtZW50cyBwcm92aWRlZCBpbmRpdmlkdWFsbHksIGFuZCByZXR1cm5zIGEgcHJvbWlzZS5cbiAqIEBleGFtcGxlXG4gKiBRLm5mY2FsbChGUy5yZWFkRmlsZSwgX19maWxlbmFtZSlcbiAqIC50aGVuKGZ1bmN0aW9uIChjb250ZW50KSB7XG4gKiB9KVxuICpcbiAqL1xuUS5uZmNhbGwgPSBmdW5jdGlvbiAoY2FsbGJhY2sgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIFEoY2FsbGJhY2spLm5mYXBwbHkoYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZmFwcGx5KG5vZGVBcmdzKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFdyYXBzIGEgTm9kZUpTIGNvbnRpbnVhdGlvbiBwYXNzaW5nIGZ1bmN0aW9uIGFuZCByZXR1cm5zIGFuIGVxdWl2YWxlbnRcbiAqIHZlcnNpb24gdGhhdCByZXR1cm5zIGEgcHJvbWlzZS5cbiAqIEBleGFtcGxlXG4gKiBRLm5mYmluZChGUy5yZWFkRmlsZSwgX19maWxlbmFtZSkoXCJ1dGYtOFwiKVxuICogLnRoZW4oY29uc29sZS5sb2cpXG4gKiAuZG9uZSgpXG4gKi9cblEubmZiaW5kID1cblEuZGVub2RlaWZ5ID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGJhc2VBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbm9kZUFyZ3MgPSBiYXNlQXJncy5jb25jYXQoYXJyYXlfc2xpY2UoYXJndW1lbnRzKSk7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICAgICAgUShjYWxsYmFjaykuZmFwcGx5KG5vZGVBcmdzKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH07XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uZmJpbmQgPVxuUHJvbWlzZS5wcm90b3R5cGUuZGVub2RlaWZ5ID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5kZW5vZGVpZnkuYXBwbHkodm9pZCAwLCBhcmdzKTtcbn07XG5cblEubmJpbmQgPSBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGJhc2VBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbm9kZUFyZ3MgPSBiYXNlQXJncy5jb25jYXQoYXJyYXlfc2xpY2UoYXJndW1lbnRzKSk7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICAgICAgZnVuY3Rpb24gYm91bmQoKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkodGhpc3AsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgUShib3VuZCkuZmFwcGx5KG5vZGVBcmdzKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH07XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uYmluZCA9IGZ1bmN0aW9uICgvKnRoaXNwLCAuLi5hcmdzKi8pIHtcbiAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMCk7XG4gICAgYXJncy51bnNoaWZ0KHRoaXMpO1xuICAgIHJldHVybiBRLm5iaW5kLmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2sgd2l0aCBhIGdpdmVuIGFycmF5IG9mIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkIGNhbGxiYWNrLlxuICogQHBhcmFtIG9iamVjdCBhbiBvYmplY3QgdGhhdCBoYXMgdGhlIG5hbWVkIG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgbmFtZSBvZiB0aGUgbWV0aG9kIG9mIG9iamVjdFxuICogQHBhcmFtIHtBcnJheX0gYXJncyBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbWV0aG9kOyB0aGUgY2FsbGJhY2tcbiAqIHdpbGwgYmUgcHJvdmlkZWQgYnkgUSBhbmQgYXBwZW5kZWQgdG8gdGhlc2UgYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgdmFsdWUgb3IgZXJyb3JcbiAqL1xuUS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEubnBvc3QgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lLCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5ucG9zdChuYW1lLCBhcmdzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm5tYXBwbHkgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUHJvbWlzZS5wcm90b3R5cGUubnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3MgfHwgW10pO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogQ2FsbHMgYSBtZXRob2Qgb2YgYSBOb2RlLXN0eWxlIG9iamVjdCB0aGF0IGFjY2VwdHMgYSBOb2RlLXN0eWxlXG4gKiBjYWxsYmFjaywgZm9yd2FyZGluZyB0aGUgZ2l2ZW4gdmFyaWFkaWMgYXJndW1lbnRzLCBwbHVzIGEgcHJvdmlkZWRcbiAqIGNhbGxiYWNrIGFyZ3VtZW50LlxuICogQHBhcmFtIG9iamVjdCBhbiBvYmplY3QgdGhhdCBoYXMgdGhlIG5hbWVkIG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgbmFtZSBvZiB0aGUgbWV0aG9kIG9mIG9iamVjdFxuICogQHBhcmFtIC4uLmFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrIHdpbGxcbiAqIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubnNlbmQgPSAvLyBYWFggQmFzZWQgb24gTWFyayBNaWxsZXIncyBwcm9wb3NlZCBcInNlbmRcIlxuUS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5RLm5pbnZva2UgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICBRKG9iamVjdCkuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblByb21pc2UucHJvdG90eXBlLm5tY2FsbCA9IC8vIFhYWCBCYXNlZCBvbiBcIlJlZHNhbmRybydzXCIgcHJvcG9zYWxcblByb21pc2UucHJvdG90eXBlLm5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5kaXNwYXRjaChcInBvc3RcIiwgW25hbWUsIG5vZGVBcmdzXSkuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBJZiBhIGZ1bmN0aW9uIHdvdWxkIGxpa2UgdG8gc3VwcG9ydCBib3RoIE5vZGUgY29udGludWF0aW9uLXBhc3Npbmctc3R5bGUgYW5kXG4gKiBwcm9taXNlLXJldHVybmluZy1zdHlsZSwgaXQgY2FuIGVuZCBpdHMgaW50ZXJuYWwgcHJvbWlzZSBjaGFpbiB3aXRoXG4gKiBgbm9kZWlmeShub2RlYmFjaylgLCBmb3J3YXJkaW5nIHRoZSBvcHRpb25hbCBub2RlYmFjayBhcmd1bWVudC4gIElmIHRoZSB1c2VyXG4gKiBlbGVjdHMgdG8gdXNlIGEgbm9kZWJhY2ssIHRoZSByZXN1bHQgd2lsbCBiZSBzZW50IHRoZXJlLiAgSWYgdGhleSBkbyBub3RcbiAqIHBhc3MgYSBub2RlYmFjaywgdGhleSB3aWxsIHJlY2VpdmUgdGhlIHJlc3VsdCBwcm9taXNlLlxuICogQHBhcmFtIG9iamVjdCBhIHJlc3VsdCAob3IgYSBwcm9taXNlIGZvciBhIHJlc3VsdClcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG5vZGViYWNrIGEgTm9kZS5qcy1zdHlsZSBjYWxsYmFja1xuICogQHJldHVybnMgZWl0aGVyIHRoZSBwcm9taXNlIG9yIG5vdGhpbmdcbiAqL1xuUS5ub2RlaWZ5ID0gbm9kZWlmeTtcbmZ1bmN0aW9uIG5vZGVpZnkob2JqZWN0LCBub2RlYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdCkubm9kZWlmeShub2RlYmFjayk7XG59XG5cblByb21pc2UucHJvdG90eXBlLm5vZGVpZnkgPSBmdW5jdGlvbiAobm9kZWJhY2spIHtcbiAgICBpZiAobm9kZWJhY2spIHtcbiAgICAgICAgdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbm9kZWJhY2sobnVsbCwgdmFsdWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbm9kZWJhY2soZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn07XG5cblEubm9Db25mbGljdCA9IGZ1bmN0aW9uKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlEubm9Db25mbGljdCBvbmx5IHdvcmtzIHdoZW4gUSBpcyB1c2VkIGFzIGEgZ2xvYmFsXCIpO1xufTtcblxuLy8gQWxsIGNvZGUgYmVmb3JlIHRoaXMgcG9pbnQgd2lsbCBiZSBmaWx0ZXJlZCBmcm9tIHN0YWNrIHRyYWNlcy5cbnZhciBxRW5kaW5nTGluZSA9IGNhcHR1cmVMaW5lKCk7XG5cbnJldHVybiBRO1xuXG59KTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoJ19wcm9jZXNzJykpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5eEwzRXVhbk1pWFN3aWJtRnRaWE1pT2x0ZExDSnRZWEJ3YVc1bmN5STZJanRCUVVGQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVNJc0ltWnBiR1VpT2lKblpXNWxjbUYwWldRdWFuTWlMQ0p6YjNWeVkyVlNiMjkwSWpvaUlpd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sc2lMeThnZG1sdE9uUnpQVFE2YzNSelBUUTZjM2M5TkRwY2JpOHFJVnh1SUNwY2JpQXFJRU52Y0hseWFXZG9kQ0F5TURBNUxUSXdNVElnUzNKcGN5QkxiM2RoYkNCMWJtUmxjaUIwYUdVZ2RHVnliWE1nYjJZZ2RHaGxJRTFKVkZ4dUlDb2diR2xqWlc1elpTQm1iM1Z1WkNCaGRDQm9kSFJ3T2k4dloybDBhSFZpTG1OdmJTOXJjbWx6YTI5M1lXd3ZjUzl5WVhjdmJXRnpkR1Z5TDB4SlEwVk9VMFZjYmlBcVhHNGdLaUJYYVhSb0lIQmhjblJ6SUdKNUlGUjViR1Z5SUVOc2IzTmxYRzRnS2lCRGIzQjVjbWxuYUhRZ01qQXdOeTB5TURBNUlGUjViR1Z5SUVOc2IzTmxJSFZ1WkdWeUlIUm9aU0IwWlhKdGN5QnZaaUIwYUdVZ1RVbFVJRmdnYkdsalpXNXpaU0JtYjNWdVpGeHVJQ29nWVhRZ2FIUjBjRG92TDNkM2R5NXZjR1Z1YzI5MWNtTmxMbTl5Wnk5c2FXTmxibk5sY3k5dGFYUXRiR2xqWlc1elpTNW9kRzFzWEc0Z0tpQkdiM0pyWldRZ1lYUWdjbVZtWDNObGJtUXVhbk1nZG1WeWMybHZiam9nTWpBd09TMHdOUzB4TVZ4dUlDcGNiaUFxSUZkcGRHZ2djR0Z5ZEhNZ1lua2dUV0Z5YXlCTmFXeHNaWEpjYmlBcUlFTnZjSGx5YVdkb2RDQW9ReWtnTWpBeE1TQkhiMjluYkdVZ1NXNWpMbHh1SUNwY2JpQXFJRXhwWTJWdWMyVmtJSFZ1WkdWeUlIUm9aU0JCY0dGamFHVWdUR2xqWlc1elpTd2dWbVZ5YzJsdmJpQXlMakFnS0hSb1pTQmNJa3hwWTJWdWMyVmNJaWs3WEc0Z0tpQjViM1VnYldGNUlHNXZkQ0IxYzJVZ2RHaHBjeUJtYVd4bElHVjRZMlZ3ZENCcGJpQmpiMjF3YkdsaGJtTmxJSGRwZEdnZ2RHaGxJRXhwWTJWdWMyVXVYRzRnS2lCWmIzVWdiV0Y1SUc5aWRHRnBiaUJoSUdOdmNIa2diMllnZEdobElFeHBZMlZ1YzJVZ1lYUmNiaUFxWEc0Z0tpQm9kSFJ3T2k4dmQzZDNMbUZ3WVdOb1pTNXZjbWN2YkdsalpXNXpaWE12VEVsRFJVNVRSUzB5TGpCY2JpQXFYRzRnS2lCVmJteGxjM01nY21WeGRXbHlaV1FnWW5rZ1lYQndiR2xqWVdKc1pTQnNZWGNnYjNJZ1lXZHlaV1ZrSUhSdklHbHVJSGR5YVhScGJtY3NJSE52Wm5SM1lYSmxYRzRnS2lCa2FYTjBjbWxpZFhSbFpDQjFibVJsY2lCMGFHVWdUR2xqWlc1elpTQnBjeUJrYVhOMGNtbGlkWFJsWkNCdmJpQmhiaUJjSWtGVElFbFRYQ0lnUWtGVFNWTXNYRzRnS2lCWFNWUklUMVZVSUZkQlVsSkJUbFJKUlZNZ1QxSWdRMDlPUkVsVVNVOU9VeUJQUmlCQlRsa2dTMGxPUkN3Z1pXbDBhR1Z5SUdWNGNISmxjM01nYjNJZ2FXMXdiR2xsWkM1Y2JpQXFJRk5sWlNCMGFHVWdUR2xqWlc1elpTQm1iM0lnZEdobElITndaV05wWm1saklHeGhibWQxWVdkbElHZHZkbVZ5Ym1sdVp5QndaWEp0YVhOemFXOXVjeUJoYm1SY2JpQXFJR3hwYldsMFlYUnBiMjV6SUhWdVpHVnlJSFJvWlNCTWFXTmxibk5sTGx4dUlDcGNiaUFxTDF4dVhHNG9ablZ1WTNScGIyNGdLR1JsWm1sdWFYUnBiMjRwSUh0Y2JpQWdJQ0JjSW5WelpTQnpkSEpwWTNSY0lqdGNibHh1SUNBZ0lDOHZJRlJvYVhNZ1ptbHNaU0IzYVd4c0lHWjFibU4wYVc5dUlIQnliM0JsY214NUlHRnpJR0VnUEhOamNtbHdkRDRnZEdGbkxDQnZjaUJoSUcxdlpIVnNaVnh1SUNBZ0lDOHZJSFZ6YVc1bklFTnZiVzF2YmtwVElHRnVaQ0JPYjJSbFNsTWdiM0lnVW1WeGRXbHlaVXBUSUcxdlpIVnNaU0JtYjNKdFlYUnpMaUFnU1c1Y2JpQWdJQ0F2THlCRGIyMXRiMjR2VG05a1pTOVNaWEYxYVhKbFNsTXNJSFJvWlNCdGIyUjFiR1VnWlhod2IzSjBjeUIwYUdVZ1VTQkJVRWtnWVc1a0lIZG9aVzVjYmlBZ0lDQXZMeUJsZUdWamRYUmxaQ0JoY3lCaElITnBiWEJzWlNBOGMyTnlhWEIwUGl3Z2FYUWdZM0psWVhSbGN5QmhJRkVnWjJ4dlltRnNJR2x1YzNSbFlXUXVYRzVjYmlBZ0lDQXZMeUJOYjI1MFlXZGxJRkpsY1hWcGNtVmNiaUFnSUNCcFppQW9kSGx3Wlc5bUlHSnZiM1J6ZEhKaGNDQTlQVDBnWENKbWRXNWpkR2x2Ymx3aUtTQjdYRzRnSUNBZ0lDQWdJR0p2YjNSemRISmhjQ2hjSW5CeWIyMXBjMlZjSWl3Z1pHVm1hVzVwZEdsdmJpazdYRzVjYmlBZ0lDQXZMeUJEYjIxdGIyNUtVMXh1SUNBZ0lIMGdaV3h6WlNCcFppQW9kSGx3Wlc5bUlHVjRjRzl5ZEhNZ1BUMDlJRndpYjJKcVpXTjBYQ0lnSmlZZ2RIbHdaVzltSUcxdlpIVnNaU0E5UFQwZ1hDSnZZbXBsWTNSY0lpa2dlMXh1SUNBZ0lDQWdJQ0J0YjJSMWJHVXVaWGh3YjNKMGN5QTlJR1JsWm1sdWFYUnBiMjRvS1R0Y2JseHVJQ0FnSUM4dklGSmxjWFZwY21WS1UxeHVJQ0FnSUgwZ1pXeHpaU0JwWmlBb2RIbHdaVzltSUdSbFptbHVaU0E5UFQwZ1hDSm1kVzVqZEdsdmJsd2lJQ1ltSUdSbFptbHVaUzVoYldRcElIdGNiaUFnSUNBZ0lDQWdaR1ZtYVc1bEtHUmxabWx1YVhScGIyNHBPMXh1WEc0Z0lDQWdMeThnVTBWVElDaFRaV04xY21VZ1JXTnRZVk5qY21sd2RDbGNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tIUjVjR1Z2WmlCelpYTWdJVDA5SUZ3aWRXNWtaV1pwYm1Wa1hDSXBJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tDRnpaWE11YjJzb0tTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1TzF4dUlDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlZ6TG0xaGEyVlJJRDBnWkdWbWFXNXBkR2x2Ymp0Y2JpQWdJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ0x5OGdQSE5qY21sd2RENWNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tIUjVjR1Z2WmlCM2FXNWtiM2NnSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lnZkh3Z2RIbHdaVzltSUhObGJHWWdJVDA5SUZ3aWRXNWtaV1pwYm1Wa1hDSXBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z1VISmxabVZ5SUhkcGJtUnZkeUJ2ZG1WeUlITmxiR1lnWm05eUlHRmtaQzF2YmlCelkzSnBjSFJ6TGlCVmMyVWdjMlZzWmlCbWIzSmNiaUFnSUNBZ0lDQWdMeThnYm05dUxYZHBibVJ2ZDJWa0lHTnZiblJsZUhSekxseHVJQ0FnSUNBZ0lDQjJZWElnWjJ4dlltRnNJRDBnZEhsd1pXOW1JSGRwYm1SdmR5QWhQVDBnWENKMWJtUmxabWx1WldSY0lpQS9JSGRwYm1SdmR5QTZJSE5sYkdZN1hHNWNiaUFnSUNBZ0lDQWdMeThnUjJWMElIUm9aU0JnZDJsdVpHOTNZQ0J2WW1wbFkzUXNJSE5oZG1VZ2RHaGxJSEJ5WlhacGIzVnpJRkVnWjJ4dlltRnNYRzRnSUNBZ0lDQWdJQzh2SUdGdVpDQnBibWwwYVdGc2FYcGxJRkVnWVhNZ1lTQm5iRzlpWVd3dVhHNGdJQ0FnSUNBZ0lIWmhjaUJ3Y21WMmFXOTFjMUVnUFNCbmJHOWlZV3d1VVR0Y2JpQWdJQ0FnSUNBZ1oyeHZZbUZzTGxFZ1BTQmtaV1pwYm1sMGFXOXVLQ2s3WEc1Y2JpQWdJQ0FnSUNBZ0x5OGdRV1JrSUdFZ2JtOURiMjVtYkdsamRDQm1kVzVqZEdsdmJpQnpieUJSSUdOaGJpQmlaU0J5WlcxdmRtVmtJR1p5YjIwZ2RHaGxYRzRnSUNBZ0lDQWdJQzh2SUdkc2IySmhiQ0J1WVcxbGMzQmhZMlV1WEc0Z0lDQWdJQ0FnSUdkc2IySmhiQzVSTG01dlEyOXVabXhwWTNRZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQm5iRzlpWVd3dVVTQTlJSEJ5WlhacGIzVnpVVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNBZ0lDQWdJQ0I5TzF4dVhHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnZEdoeWIzY2dibVYzSUVWeWNtOXlLRndpVkdocGN5QmxiblpwY205dWJXVnVkQ0IzWVhNZ2JtOTBJR0Z1ZEdsamFYQmhkR1ZrSUdKNUlGRXVJRkJzWldGelpTQm1hV3hsSUdFZ1luVm5MbHdpS1R0Y2JpQWdJQ0I5WEc1Y2JuMHBLR1oxYm1OMGFXOXVJQ2dwSUh0Y2Jsd2lkWE5sSUhOMGNtbGpkRndpTzF4dVhHNTJZWElnYUdGelUzUmhZMnR6SUQwZ1ptRnNjMlU3WEc1MGNua2dlMXh1SUNBZ0lIUm9jbTkzSUc1bGR5QkZjbkp2Y2lncE8xeHVmU0JqWVhSamFDQW9aU2tnZTF4dUlDQWdJR2hoYzFOMFlXTnJjeUE5SUNFaFpTNXpkR0ZqYXp0Y2JuMWNibHh1THk4Z1FXeHNJR052WkdVZ1lXWjBaWElnZEdocGN5QndiMmx1ZENCM2FXeHNJR0psSUdacGJIUmxjbVZrSUdaeWIyMGdjM1JoWTJzZ2RISmhZMlZ6SUhKbGNHOXlkR1ZrWEc0dkx5QmllU0JSTGx4dWRtRnlJSEZUZEdGeWRHbHVaMHhwYm1VZ1BTQmpZWEIwZFhKbFRHbHVaU2dwTzF4dWRtRnlJSEZHYVd4bFRtRnRaVHRjYmx4dUx5OGdjMmhwYlhOY2JseHVMeThnZFhObFpDQm1iM0lnWm1Gc2JHSmhZMnNnYVc0Z1hDSmhiR3hTWlhOdmJIWmxaRndpWEc1MllYSWdibTl2Y0NBOUlHWjFibU4wYVc5dUlDZ3BJSHQ5TzF4dVhHNHZMeUJWYzJVZ2RHaGxJR1poYzNSbGMzUWdjRzl6YzJsaWJHVWdiV1ZoYm5NZ2RHOGdaWGhsWTNWMFpTQmhJSFJoYzJzZ2FXNGdZU0JtZFhSMWNtVWdkSFZ5Ymx4dUx5OGdiMllnZEdobElHVjJaVzUwSUd4dmIzQXVYRzUyWVhJZ2JtVjRkRlJwWTJzZ1BTaG1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdMeThnYkdsdWEyVmtJR3hwYzNRZ2IyWWdkR0Z6YTNNZ0tITnBibWRzWlN3Z2QybDBhQ0JvWldGa0lHNXZaR1VwWEc0Z0lDQWdkbUZ5SUdobFlXUWdQU0I3ZEdGemF6b2dkbTlwWkNBd0xDQnVaWGgwT2lCdWRXeHNmVHRjYmlBZ0lDQjJZWElnZEdGcGJDQTlJR2hsWVdRN1hHNGdJQ0FnZG1GeUlHWnNkWE5vYVc1bklEMGdabUZzYzJVN1hHNGdJQ0FnZG1GeUlISmxjWFZsYzNSVWFXTnJJRDBnZG05cFpDQXdPMXh1SUNBZ0lIWmhjaUJwYzA1dlpHVktVeUE5SUdaaGJITmxPMXh1SUNBZ0lDOHZJSEYxWlhWbElHWnZjaUJzWVhSbElIUmhjMnR6TENCMWMyVmtJR0o1SUhWdWFHRnVaR3hsWkNCeVpXcGxZM1JwYjI0Z2RISmhZMnRwYm1kY2JpQWdJQ0IyWVhJZ2JHRjBaWEpSZFdWMVpTQTlJRnRkTzF4dVhHNGdJQ0FnWm5WdVkzUnBiMjRnWm14MWMyZ29LU0I3WEc0Z0lDQWdJQ0FnSUM4cUlHcHphR2x1ZENCc2IyOXdablZ1WXpvZ2RISjFaU0FxTDF4dUlDQWdJQ0FnSUNCMllYSWdkR0Z6YXl3Z1pHOXRZV2x1TzF4dVhHNGdJQ0FnSUNBZ0lIZG9hV3hsSUNob1pXRmtMbTVsZUhRcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdobFlXUWdQU0JvWldGa0xtNWxlSFE3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBZWE5ySUQwZ2FHVmhaQzUwWVhOck8xeHVJQ0FnSUNBZ0lDQWdJQ0FnYUdWaFpDNTBZWE5ySUQwZ2RtOXBaQ0F3TzF4dUlDQWdJQ0FnSUNBZ0lDQWdaRzl0WVdsdUlEMGdhR1ZoWkM1a2IyMWhhVzQ3WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoa2IyMWhhVzRwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCb1pXRmtMbVJ2YldGcGJpQTlJSFp2YVdRZ01EdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmtiMjFoYVc0dVpXNTBaWElvS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnSUNBZ0lISjFibE5wYm1kc1pTaDBZWE5yTENCa2IyMWhhVzRwTzF4dVhHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdkMmhwYkdVZ0tHeGhkR1Z5VVhWbGRXVXViR1Z1WjNSb0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMFlYTnJJRDBnYkdGMFpYSlJkV1YxWlM1d2IzQW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISjFibE5wYm1kc1pTaDBZWE5yS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQm1iSFZ6YUdsdVp5QTlJR1poYkhObE8xeHVJQ0FnSUgxY2JpQWdJQ0F2THlCeWRXNXpJR0VnYzJsdVoyeGxJR1oxYm1OMGFXOXVJR2x1SUhSb1pTQmhjM2x1WXlCeGRXVjFaVnh1SUNBZ0lHWjFibU4wYVc5dUlISjFibE5wYm1kc1pTaDBZWE5yTENCa2IyMWhhVzRwSUh0Y2JpQWdJQ0FnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUmhjMnNvS1R0Y2JseHVJQ0FnSUNBZ0lDQjlJR05oZEdOb0lDaGxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnBaaUFvYVhOT2IyUmxTbE1wSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QkpiaUJ1YjJSbExDQjFibU5oZFdkb2RDQmxlR05sY0hScGIyNXpJR0Z5WlNCamIyNXphV1JsY21Wa0lHWmhkR0ZzSUdWeWNtOXljeTVjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCU1pTMTBhSEp2ZHlCMGFHVnRJSE41Ym1Ob2NtOXViM1Z6YkhrZ2RHOGdhVzUwWlhKeWRYQjBJR1pzZFhOb2FXNW5JVnh1WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z1JXNXpkWEpsSUdOdmJuUnBiblZoZEdsdmJpQnBaaUIwYUdVZ2RXNWpZWFZuYUhRZ1pYaGpaWEIwYVc5dUlHbHpJSE4xY0hCeVpYTnpaV1JjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCc2FYTjBaVzVwYm1jZ1hDSjFibU5oZFdkb2RFVjRZMlZ3ZEdsdmJsd2lJR1YyWlc1MGN5QW9ZWE1nWkc5dFlXbHVjeUJrYjJWektTNWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJEYjI1MGFXNTFaU0JwYmlCdVpYaDBJR1YyWlc1MElIUnZJR0YyYjJsa0lIUnBZMnNnY21WamRYSnphVzl1TGx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVMbVY0YVhRb0tUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjMlYwVkdsdFpXOTFkQ2htYkhWemFDd2dNQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHUnZiV0ZwYmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrYjIxaGFXNHVaVzUwWlhJb0tUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IwYUhKdmR5QmxPMXh1WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDOHZJRWx1SUdKeWIzZHpaWEp6TENCMWJtTmhkV2RvZENCbGVHTmxjSFJwYjI1eklHRnlaU0J1YjNRZ1ptRjBZV3d1WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z1VtVXRkR2h5YjNjZ2RHaGxiU0JoYzNsdVkyaHliMjV2ZFhOc2VTQjBieUJoZG05cFpDQnpiRzkzTFdSdmQyNXpMbHh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSE5sZEZScGJXVnZkWFFvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IwYUhKdmR5QmxPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSDBzSURBcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNWNiaUFnSUNBZ0lDQWdhV1lnS0dSdmJXRnBiaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdaRzl0WVdsdUxtVjRhWFFvS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgxY2JseHVJQ0FnSUc1bGVIUlVhV05ySUQwZ1puVnVZM1JwYjI0Z0tIUmhjMnNwSUh0Y2JpQWdJQ0FnSUNBZ2RHRnBiQ0E5SUhSaGFXd3VibVY0ZENBOUlIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhSaGMyczZJSFJoYzJzc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrYjIxaGFXNDZJR2x6VG05a1pVcFRJQ1ltSUhCeWIyTmxjM011Wkc5dFlXbHVMRnh1SUNBZ0lDQWdJQ0FnSUNBZ2JtVjRkRG9nYm5Wc2JGeHVJQ0FnSUNBZ0lDQjlPMXh1WEc0Z0lDQWdJQ0FnSUdsbUlDZ2habXgxYzJocGJtY3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHWnNkWE5vYVc1bklEMGdkSEoxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsY1hWbGMzUlVhV05yS0NrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOU8xeHVYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQndjbTlqWlhOeklEMDlQU0JjSW05aWFtVmpkRndpSUNZbVhHNGdJQ0FnSUNBZ0lIQnliMk5sYzNNdWRHOVRkSEpwYm1jb0tTQTlQVDBnWENKYmIySnFaV04wSUhCeWIyTmxjM05kWENJZ0ppWWdjSEp2WTJWemN5NXVaWGgwVkdsamF5a2dlMXh1SUNBZ0lDQWdJQ0F2THlCRmJuTjFjbVVnVVNCcGN5QnBiaUJoSUhKbFlXd2dUbTlrWlNCbGJuWnBjbTl1YldWdWRDd2dkMmwwYUNCaElHQndjbTlqWlhOekxtNWxlSFJVYVdOcllDNWNiaUFnSUNBZ0lDQWdMeThnVkc4Z2MyVmxJSFJvY205MVoyZ2dabUZyWlNCT2IyUmxJR1Z1ZG1seWIyNXRaVzUwY3pwY2JpQWdJQ0FnSUNBZ0x5OGdLaUJOYjJOb1lTQjBaWE4wSUhKMWJtNWxjaUF0SUdWNGNHOXpaWE1nWVNCZ2NISnZZMlZ6YzJBZ1oyeHZZbUZzSUhkcGRHaHZkWFFnWVNCZ2JtVjRkRlJwWTJ0Z1hHNGdJQ0FnSUNBZ0lDOHZJQ29nUW5KdmQzTmxjbWxtZVNBdElHVjRjRzl6WlhNZ1lTQmdjSEp2WTJWemN5NXVaWGhVYVdOcllDQm1kVzVqZEdsdmJpQjBhR0YwSUhWelpYTmNiaUFnSUNBZ0lDQWdMeThnSUNCZ2MyVjBWR2x0Wlc5MWRHQXVJRWx1SUhSb2FYTWdZMkZ6WlNCZ2MyVjBTVzF0WldScFlYUmxZQ0JwY3lCd2NtVm1aWEp5WldRZ1ltVmpZWFZ6WlZ4dUlDQWdJQ0FnSUNBdkx5QWdJQ0JwZENCcGN5Qm1ZWE4wWlhJdUlFSnliM2R6WlhKcFpua25jeUJnY0hKdlkyVnpjeTUwYjFOMGNtbHVaeWdwWUNCNWFXVnNaSE5jYmlBZ0lDQWdJQ0FnTHk4Z0lDQmNJbHR2WW1wbFkzUWdUMkpxWldOMFhWd2lMQ0IzYUdsc1pTQnBiaUJoSUhKbFlXd2dUbTlrWlNCbGJuWnBjbTl1YldWdWRGeHVJQ0FnSUNBZ0lDQXZMeUFnSUdCd2NtOWpaWE56TG01bGVIUlVhV05yS0NsZ0lIbHBaV3hrY3lCY0lsdHZZbXBsWTNRZ2NISnZZMlZ6YzExY0lpNWNiaUFnSUNBZ0lDQWdhWE5PYjJSbFNsTWdQU0IwY25WbE8xeHVYRzRnSUNBZ0lDQWdJSEpsY1hWbGMzUlVhV05ySUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NISnZZMlZ6Y3k1dVpYaDBWR2xqYXlobWJIVnphQ2s3WEc0Z0lDQWdJQ0FnSUgwN1hHNWNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tIUjVjR1Z2WmlCelpYUkpiVzFsWkdsaGRHVWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0F2THlCSmJpQkpSVEV3TENCT2IyUmxMbXB6SURBdU9Tc3NJRzl5SUdoMGRIQnpPaTh2WjJsMGFIVmlMbU52YlM5T2IySnNaVXBUTDNObGRFbHRiV1ZrYVdGMFpWeHVJQ0FnSUNBZ0lDQnBaaUFvZEhsd1pXOW1JSGRwYm1SdmR5QWhQVDBnWENKMWJtUmxabWx1WldSY0lpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVnhkV1Z6ZEZScFkyc2dQU0J6WlhSSmJXMWxaR2xoZEdVdVltbHVaQ2gzYVc1a2IzY3NJR1pzZFhOb0tUdGNiaUFnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhObGRFbHRiV1ZrYVdGMFpTaG1iSFZ6YUNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5TzF4dUlDQWdJQ0FnSUNCOVhHNWNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tIUjVjR1Z2WmlCTlpYTnpZV2RsUTJoaGJtNWxiQ0FoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaWtnZTF4dUlDQWdJQ0FnSUNBdkx5QnRiMlJsY200Z1luSnZkM05sY25OY2JpQWdJQ0FnSUNBZ0x5OGdhSFIwY0RvdkwzZDNkeTV1YjI1aWJHOWphMmx1Wnk1cGJ5OHlNREV4THpBMkwzZHBibVJ2ZDI1bGVIUjBhV05yTG1oMGJXeGNiaUFnSUNBZ0lDQWdkbUZ5SUdOb1lXNXVaV3dnUFNCdVpYY2dUV1Z6YzJGblpVTm9ZVzV1Wld3b0tUdGNiaUFnSUNBZ0lDQWdMeThnUVhRZ2JHVmhjM1FnVTJGbVlYSnBJRlpsY25OcGIyNGdOaTR3TGpVZ0tEZzFNell1TXpBdU1Ta2dhVzUwWlhKdGFYUjBaVzUwYkhrZ1kyRnVibTkwSUdOeVpXRjBaVnh1SUNBZ0lDQWdJQ0F2THlCM2IzSnJhVzVuSUcxbGMzTmhaMlVnY0c5eWRITWdkR2hsSUdacGNuTjBJSFJwYldVZ1lTQndZV2RsSUd4dllXUnpMbHh1SUNBZ0lDQWdJQ0JqYUdGdWJtVnNMbkJ2Y25ReExtOXViV1Z6YzJGblpTQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsY1hWbGMzUlVhV05ySUQwZ2NtVnhkV1Z6ZEZCdmNuUlVhV05yTzF4dUlDQWdJQ0FnSUNBZ0lDQWdZMmhoYm01bGJDNXdiM0owTVM1dmJtMWxjM05oWjJVZ1BTQm1iSFZ6YUR0Y2JpQWdJQ0FnSUNBZ0lDQWdJR1pzZFhOb0tDazdYRzRnSUNBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0FnSUhaaGNpQnlaWEYxWlhOMFVHOXlkRlJwWTJzZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJQY0dWeVlTQnlaWEYxYVhKbGN5QjFjeUIwYnlCd2NtOTJhV1JsSUdFZ2JXVnpjMkZuWlNCd1lYbHNiMkZrTENCeVpXZGhjbVJzWlhOeklHOW1YRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QjNhR1YwYUdWeUlIZGxJSFZ6WlNCcGRDNWNiaUFnSUNBZ0lDQWdJQ0FnSUdOb1lXNXVaV3d1Y0c5eWRESXVjRzl6ZEUxbGMzTmhaMlVvTUNrN1hHNGdJQ0FnSUNBZ0lIMDdYRzRnSUNBZ0lDQWdJSEpsY1hWbGMzUlVhV05ySUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2MyVjBWR2x0Wlc5MWRDaG1iSFZ6YUN3Z01DazdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYRjFaWE4wVUc5eWRGUnBZMnNvS1R0Y2JpQWdJQ0FnSUNBZ2ZUdGNibHh1SUNBZ0lIMGdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lDOHZJRzlzWkNCaWNtOTNjMlZ5YzF4dUlDQWdJQ0FnSUNCeVpYRjFaWE4wVkdsamF5QTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSE5sZEZScGJXVnZkWFFvWm14MWMyZ3NJREFwTzF4dUlDQWdJQ0FnSUNCOU8xeHVJQ0FnSUgxY2JpQWdJQ0F2THlCeWRXNXpJR0VnZEdGemF5QmhablJsY2lCaGJHd2diM1JvWlhJZ2RHRnphM01nYUdGMlpTQmlaV1Z1SUhKMWJseHVJQ0FnSUM4dklIUm9hWE1nYVhNZ2RYTmxablZzSUdadmNpQjFibWhoYm1Sc1pXUWdjbVZxWldOMGFXOXVJSFJ5WVdOcmFXNW5JSFJvWVhRZ2JtVmxaSE1nZEc4Z2FHRndjR1Z1WEc0Z0lDQWdMeThnWVdaMFpYSWdZV3hzSUdCMGFHVnVZR1FnZEdGemEzTWdhR0YyWlNCaVpXVnVJSEoxYmk1Y2JpQWdJQ0J1WlhoMFZHbGpheTV5ZFc1QlpuUmxjaUE5SUdaMWJtTjBhVzl1SUNoMFlYTnJLU0I3WEc0Z0lDQWdJQ0FnSUd4aGRHVnlVWFZsZFdVdWNIVnphQ2gwWVhOcktUdGNiaUFnSUNBZ0lDQWdhV1lnS0NGbWJIVnphR2x1WnlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWm14MWMyaHBibWNnUFNCMGNuVmxPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVnhkV1Z6ZEZScFkyc29LVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDA3WEc0Z0lDQWdjbVYwZFhKdUlHNWxlSFJVYVdOck8xeHVmU2tvS1R0Y2JseHVMeThnUVhSMFpXMXdkQ0IwYnlCdFlXdGxJR2RsYm1WeWFXTnpJSE5oWm1VZ2FXNGdkR2hsSUdaaFkyVWdiMllnWkc5M2JuTjBjbVZoYlZ4dUx5OGdiVzlrYVdacFkyRjBhVzl1Y3k1Y2JpOHZJRlJvWlhKbElHbHpJRzV2SUhOcGRIVmhkR2x2YmlCM2FHVnlaU0IwYUdseklHbHpJRzVsWTJWemMyRnllUzVjYmk4dklFbG1JSGx2ZFNCdVpXVmtJR0VnYzJWamRYSnBkSGtnWjNWaGNtRnVkR1ZsTENCMGFHVnpaU0J3Y21sdGIzSmthV0ZzY3lCdVpXVmtJSFJ2SUdKbFhHNHZMeUJrWldWd2JIa2dabkp2ZW1WdUlHRnVlWGRoZVN3Z1lXNWtJR2xtSUhsdmRTQmtiMjdpZ0psMElHNWxaV1FnWVNCelpXTjFjbWwwZVNCbmRXRnlZVzUwWldVc1hHNHZMeUIwYUdseklHbHpJR3AxYzNRZ2NHeGhhVzRnY0dGeVlXNXZhV1F1WEc0dkx5QkliM2RsZG1WeUxDQjBhR2x6SUNvcWJXbG5hSFFxS2lCb1lYWmxJSFJvWlNCdWFXTmxJSE5wWkdVdFpXWm1aV04wSUc5bUlISmxaSFZqYVc1bklIUm9aU0J6YVhwbElHOW1YRzR2THlCMGFHVWdiV2x1YVdacFpXUWdZMjlrWlNCaWVTQnlaV1IxWTJsdVp5QjRMbU5oYkd3b0tTQjBieUJ0WlhKbGJIa2dlQ2dwWEc0dkx5QlRaV1VnVFdGeWF5Qk5hV3hzWlhMaWdKbHpJR1Y0Y0d4aGJtRjBhVzl1SUc5bUlIZG9ZWFFnZEdocGN5QmtiMlZ6TGx4dUx5OGdhSFIwY0RvdkwzZHBhMmt1WldOdFlYTmpjbWx3ZEM1dmNtY3ZaRzlyZFM1d2FIQS9hV1E5WTI5dWRtVnVkR2x2Ym5NNmMyRm1aVjl0WlhSaFgzQnliMmR5WVcxdGFXNW5YRzUyWVhJZ1kyRnNiQ0E5SUVaMWJtTjBhVzl1TG1OaGJHdzdYRzVtZFc1amRHbHZiaUIxYm1OMWNuSjVWR2hwY3lobUtTQjdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3d1WVhCd2JIa29aaXdnWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0I5TzF4dWZWeHVMeThnVkdocGN5QnBjeUJsY1hWcGRtRnNaVzUwTENCaWRYUWdjMnh2ZDJWeU9seHVMeThnZFc1amRYSnllVlJvYVhNZ1BTQkdkVzVqZEdsdmJsOWlhVzVrTG1KcGJtUW9SblZ1WTNScGIyNWZZbWx1WkM1allXeHNLVHRjYmk4dklHaDBkSEE2THk5cWMzQmxjbVl1WTI5dEwzVnVZM1Z5Y25sMGFHbHpYRzVjYm5aaGNpQmhjbkpoZVY5emJHbGpaU0E5SUhWdVkzVnljbmxVYUdsektFRnljbUY1TG5CeWIzUnZkSGx3WlM1emJHbGpaU2s3WEc1Y2JuWmhjaUJoY25KaGVWOXlaV1IxWTJVZ1BTQjFibU4xY25KNVZHaHBjeWhjYmlBZ0lDQkJjbkpoZVM1d2NtOTBiM1I1Y0dVdWNtVmtkV05sSUh4OElHWjFibU4wYVc5dUlDaGpZV3hzWW1GamF5d2dZbUZ6YVhNcElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUdsdVpHVjRJRDBnTUN4Y2JpQWdJQ0FnSUNBZ0lDQWdJR3hsYm1kMGFDQTlJSFJvYVhNdWJHVnVaM1JvTzF4dUlDQWdJQ0FnSUNBdkx5QmpiMjVqWlhKdWFXNW5JSFJvWlNCcGJtbDBhV0ZzSUhaaGJIVmxMQ0JwWmlCdmJtVWdhWE1nYm05MElIQnliM1pwWkdWa1hHNGdJQ0FnSUNBZ0lHbG1JQ2hoY21kMWJXVnVkSE11YkdWdVozUm9JRDA5UFNBeEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QnpaV1ZySUhSdklIUm9aU0JtYVhKemRDQjJZV3gxWlNCcGJpQjBhR1VnWVhKeVlYa3NJR0ZqWTI5MWJuUnBibWRjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJR1p2Y2lCMGFHVWdjRzl6YzJsaWFXeHBkSGtnZEdoaGRDQnBjeUJwY3lCaElITndZWEp6WlNCaGNuSmhlVnh1SUNBZ0lDQWdJQ0FnSUNBZ1pHOGdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR2xtSUNocGJtUmxlQ0JwYmlCMGFHbHpLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHSmhjMmx6SUQwZ2RHaHBjMXRwYm1SbGVDc3JYVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1luSmxZV3M3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDZ3JLMmx1WkdWNElENDlJR3hsYm1kMGFDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJ1WlhjZ1ZIbHdaVVZ5Y205eUtDazdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQjNhR2xzWlNBb01TazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnTHk4Z2NtVmtkV05sWEc0Z0lDQWdJQ0FnSUdadmNpQW9PeUJwYm1SbGVDQThJR3hsYm1kMGFEc2dhVzVrWlhnckt5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0x5OGdZV05qYjNWdWRDQm1iM0lnZEdobElIQnZjM05wWW1sc2FYUjVJSFJvWVhRZ2RHaGxJR0Z5Y21GNUlHbHpJSE53WVhKelpWeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHbHVaR1Y0SUdsdUlIUm9hWE1wSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCaVlYTnBjeUE5SUdOaGJHeGlZV05yS0dKaGMybHpMQ0IwYUdselcybHVaR1Y0WFN3Z2FXNWtaWGdwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJpWVhOcGN6dGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdZWEp5WVhsZmFXNWtaWGhQWmlBOUlIVnVZM1Z5Y25sVWFHbHpLRnh1SUNBZ0lFRnljbUY1TG5CeWIzUnZkSGx3WlM1cGJtUmxlRTltSUh4OElHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQXZMeUJ1YjNRZ1lTQjJaWEo1SUdkdmIyUWdjMmhwYlN3Z1luVjBJR2R2YjJRZ1pXNXZkV2RvSUdadmNpQnZkWElnYjI1bElIVnpaU0J2WmlCcGRGeHVJQ0FnSUNBZ0lDQm1iM0lnS0haaGNpQnBJRDBnTURzZ2FTQThJSFJvYVhNdWJHVnVaM1JvT3lCcEt5c3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2gwYUdselcybGRJRDA5UFNCMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUF0TVR0Y2JpQWdJQ0I5WEc0cE8xeHVYRzUyWVhJZ1lYSnlZWGxmYldGd0lEMGdkVzVqZFhKeWVWUm9hWE1vWEc0Z0lDQWdRWEp5WVhrdWNISnZkRzkwZVhCbExtMWhjQ0I4ZkNCbWRXNWpkR2x2YmlBb1kyRnNiR0poWTJzc0lIUm9hWE53S1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0FnSUNBZ2RtRnlJR052Ykd4bFkzUWdQU0JiWFR0Y2JpQWdJQ0FnSUNBZ1lYSnlZWGxmY21Wa2RXTmxLSE5sYkdZc0lHWjFibU4wYVc5dUlDaDFibVJsWm1sdVpXUXNJSFpoYkhWbExDQnBibVJsZUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWTI5c2JHVmpkQzV3ZFhOb0tHTmhiR3hpWVdOckxtTmhiR3dvZEdocGMzQXNJSFpoYkhWbExDQnBibVJsZUN3Z2MyVnNaaWtwTzF4dUlDQWdJQ0FnSUNCOUxDQjJiMmxrSURBcE8xeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1kyOXNiR1ZqZER0Y2JpQWdJQ0I5WEc0cE8xeHVYRzUyWVhJZ2IySnFaV04wWDJOeVpXRjBaU0E5SUU5aWFtVmpkQzVqY21WaGRHVWdmSHdnWm5WdVkzUnBiMjRnS0hCeWIzUnZkSGx3WlNrZ2UxeHVJQ0FnSUdaMWJtTjBhVzl1SUZSNWNHVW9LU0I3SUgxY2JpQWdJQ0JVZVhCbExuQnliM1J2ZEhsd1pTQTlJSEJ5YjNSdmRIbHdaVHRjYmlBZ0lDQnlaWFIxY200Z2JtVjNJRlI1Y0dVb0tUdGNibjA3WEc1Y2JuWmhjaUJ2WW1wbFkzUmZhR0Z6VDNkdVVISnZjR1Z5ZEhrZ1BTQjFibU4xY25KNVZHaHBjeWhQWW1wbFkzUXVjSEp2ZEc5MGVYQmxMbWhoYzA5M2JsQnliM0JsY25SNUtUdGNibHh1ZG1GeUlHOWlhbVZqZEY5clpYbHpJRDBnVDJKcVpXTjBMbXRsZVhNZ2ZId2dablZ1WTNScGIyNGdLRzlpYW1WamRDa2dlMXh1SUNBZ0lIWmhjaUJyWlhseklEMGdXMTA3WEc0Z0lDQWdabTl5SUNoMllYSWdhMlY1SUdsdUlHOWlhbVZqZENrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvYjJKcVpXTjBYMmhoYzA5M2JsQnliM0JsY25SNUtHOWlhbVZqZEN3Z2EyVjVLU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdhMlY1Y3k1d2RYTm9LR3RsZVNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnY21WMGRYSnVJR3RsZVhNN1hHNTlPMXh1WEc1MllYSWdiMkpxWldOMFgzUnZVM1J5YVc1bklEMGdkVzVqZFhKeWVWUm9hWE1vVDJKcVpXTjBMbkJ5YjNSdmRIbHdaUzUwYjFOMGNtbHVaeWs3WEc1Y2JtWjFibU4wYVc5dUlHbHpUMkpxWldOMEtIWmhiSFZsS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFpoYkhWbElEMDlQU0JQWW1wbFkzUW9kbUZzZFdVcE8xeHVmVnh1WEc0dkx5Qm5aVzVsY21GMGIzSWdjbVZzWVhSbFpDQnphR2x0YzF4dVhHNHZMeUJHU1ZoTlJUb2dVbVZ0YjNabElIUm9hWE1nWm5WdVkzUnBiMjRnYjI1alpTQkZVellnWjJWdVpYSmhkRzl5Y3lCaGNtVWdhVzRnVTNCcFpHVnlUVzl1YTJWNUxseHVablZ1WTNScGIyNGdhWE5UZEc5d1NYUmxjbUYwYVc5dUtHVjRZMlZ3ZEdsdmJpa2dlMXh1SUNBZ0lISmxkSFZ5YmlBb1hHNGdJQ0FnSUNBZ0lHOWlhbVZqZEY5MGIxTjBjbWx1WnlobGVHTmxjSFJwYjI0cElEMDlQU0JjSWx0dlltcGxZM1FnVTNSdmNFbDBaWEpoZEdsdmJsMWNJaUI4ZkZ4dUlDQWdJQ0FnSUNCbGVHTmxjSFJwYjI0Z2FXNXpkR0Z1WTJWdlppQlJVbVYwZFhKdVZtRnNkV1ZjYmlBZ0lDQXBPMXh1ZlZ4dVhHNHZMeUJHU1ZoTlJUb2dVbVZ0YjNabElIUm9hWE1nYUdWc2NHVnlJR0Z1WkNCUkxuSmxkSFZ5YmlCdmJtTmxJRVZUTmlCblpXNWxjbUYwYjNKeklHRnlaU0JwYmx4dUx5OGdVM0JwWkdWeVRXOXVhMlY1TGx4dWRtRnlJRkZTWlhSMWNtNVdZV3gxWlR0Y2JtbG1JQ2gwZVhCbGIyWWdVbVYwZFhKdVZtRnNkV1VnSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0JSVW1WMGRYSnVWbUZzZFdVZ1BTQlNaWFIxY201V1lXeDFaVHRjYm4wZ1pXeHpaU0I3WEc0Z0lDQWdVVkpsZEhWeWJsWmhiSFZsSUQwZ1puVnVZM1JwYjI0Z0tIWmhiSFZsS1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZG1Gc2RXVWdQU0IyWVd4MVpUdGNiaUFnSUNCOU8xeHVmVnh1WEc0dkx5QnNiMjVuSUhOMFlXTnJJSFJ5WVdObGMxeHVYRzUyWVhJZ1UxUkJRMHRmU2xWTlVGOVRSVkJCVWtGVVQxSWdQU0JjSWtaeWIyMGdjSEpsZG1sdmRYTWdaWFpsYm5RNlhDSTdYRzVjYm1aMWJtTjBhVzl1SUcxaGEyVlRkR0ZqYTFSeVlXTmxURzl1WnlobGNuSnZjaXdnY0hKdmJXbHpaU2tnZTF4dUlDQWdJQzh2SUVsbUlIQnZjM05wWW14bExDQjBjbUZ1YzJadmNtMGdkR2hsSUdWeWNtOXlJSE4wWVdOcklIUnlZV05sSUdKNUlISmxiVzkyYVc1bklFNXZaR1VnWVc1a0lGRmNiaUFnSUNBdkx5QmpjblZtZEN3Z2RHaGxiaUJqYjI1allYUmxibUYwYVc1bklIZHBkR2dnZEdobElITjBZV05ySUhSeVlXTmxJRzltSUdCd2NtOXRhWE5sWUM0Z1UyVmxJQ00xTnk1Y2JpQWdJQ0JwWmlBb2FHRnpVM1JoWTJ0eklDWW1YRzRnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVjM1JoWTJzZ0ppWmNiaUFnSUNBZ0lDQWdkSGx3Wlc5bUlHVnljbTl5SUQwOVBTQmNJbTlpYW1WamRGd2lJQ1ltWEc0Z0lDQWdJQ0FnSUdWeWNtOXlJQ0U5UFNCdWRXeHNJQ1ltWEc0Z0lDQWdJQ0FnSUdWeWNtOXlMbk4wWVdOcklDWW1YRzRnSUNBZ0lDQWdJR1Z5Y205eUxuTjBZV05yTG1sdVpHVjRUMllvVTFSQlEwdGZTbFZOVUY5VFJWQkJVa0ZVVDFJcElEMDlQU0F0TVZ4dUlDQWdJQ2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdjM1JoWTJ0eklEMGdXMTA3WEc0Z0lDQWdJQ0FnSUdadmNpQW9kbUZ5SUhBZ1BTQndjbTl0YVhObE95QWhJWEE3SUhBZ1BTQndMbk52ZFhKalpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLSEF1YzNSaFkyc3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J6ZEdGamEzTXVkVzV6YUdsbWRDaHdMbk4wWVdOcktUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnpkR0ZqYTNNdWRXNXphR2xtZENobGNuSnZjaTV6ZEdGamF5azdYRzVjYmlBZ0lDQWdJQ0FnZG1GeUlHTnZibU5oZEdWa1UzUmhZMnR6SUQwZ2MzUmhZMnR6TG1wdmFXNG9YQ0pjWEc1Y0lpQXJJRk5VUVVOTFgwcFZUVkJmVTBWUVFWSkJWRTlTSUNzZ1hDSmNYRzVjSWlrN1hHNGdJQ0FnSUNBZ0lHVnljbTl5TG5OMFlXTnJJRDBnWm1sc2RHVnlVM1JoWTJ0VGRISnBibWNvWTI5dVkyRjBaV1JUZEdGamEzTXBPMXh1SUNBZ0lIMWNibjFjYmx4dVpuVnVZM1JwYjI0Z1ptbHNkR1Z5VTNSaFkydFRkSEpwYm1jb2MzUmhZMnRUZEhKcGJtY3BJSHRjYmlBZ0lDQjJZWElnYkdsdVpYTWdQU0J6ZEdGamExTjBjbWx1Wnk1emNHeHBkQ2hjSWx4Y2Jsd2lLVHRjYmlBZ0lDQjJZWElnWkdWemFYSmxaRXhwYm1WeklEMGdXMTA3WEc0Z0lDQWdabTl5SUNoMllYSWdhU0E5SURBN0lHa2dQQ0JzYVc1bGN5NXNaVzVuZEdnN0lDc3JhU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdiR2x1WlNBOUlHeHBibVZ6VzJsZE8xeHVYRzRnSUNBZ0lDQWdJR2xtSUNnaGFYTkpiblJsY201aGJFWnlZVzFsS0d4cGJtVXBJQ1ltSUNGcGMwNXZaR1ZHY21GdFpTaHNhVzVsS1NBbUppQnNhVzVsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWlhOcGNtVmtUR2x1WlhNdWNIVnphQ2hzYVc1bEtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMWNiaUFnSUNCeVpYUjFjbTRnWkdWemFYSmxaRXhwYm1WekxtcHZhVzRvWENKY1hHNWNJaWs3WEc1OVhHNWNibVoxYm1OMGFXOXVJR2x6VG05a1pVWnlZVzFsS0hOMFlXTnJUR2x1WlNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJ6ZEdGamEweHBibVV1YVc1a1pYaFBaaWhjSWlodGIyUjFiR1V1YW5NNlhDSXBJQ0U5UFNBdE1TQjhmRnh1SUNBZ0lDQWdJQ0FnSUNCemRHRmphMHhwYm1VdWFXNWtaWGhQWmloY0lpaHViMlJsTG1wek9sd2lLU0FoUFQwZ0xURTdYRzU5WEc1Y2JtWjFibU4wYVc5dUlHZGxkRVpwYkdWT1lXMWxRVzVrVEdsdVpVNTFiV0psY2loemRHRmphMHhwYm1VcElIdGNiaUFnSUNBdkx5Qk9ZVzFsWkNCbWRXNWpkR2x2Ym5NNklGd2lZWFFnWm5WdVkzUnBiMjVPWVcxbElDaG1hV3hsYm1GdFpUcHNhVzVsVG5WdFltVnlPbU52YkhWdGJrNTFiV0psY2lsY0lseHVJQ0FnSUM4dklFbHVJRWxGTVRBZ1puVnVZM1JwYjI0Z2JtRnRaU0JqWVc0Z2FHRjJaU0J6Y0dGalpYTWdLRndpUVc1dmJubHRiM1Z6SUdaMWJtTjBhVzl1WENJcElFOWZiMXh1SUNBZ0lIWmhjaUJoZEhSbGJYQjBNU0E5SUM5aGRDQXVLeUJjWENnb0xpc3BPaWhjWEdRcktUb29QenBjWEdRcktWeGNLU1F2TG1WNFpXTW9jM1JoWTJ0TWFXNWxLVHRjYmlBZ0lDQnBaaUFvWVhSMFpXMXdkREVwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUZ0aGRIUmxiWEIwTVZzeFhTd2dUblZ0WW1WeUtHRjBkR1Z0Y0hReFd6SmRLVjA3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdMeThnUVc1dmJubHRiM1Z6SUdaMWJtTjBhVzl1Y3pvZ1hDSmhkQ0JtYVd4bGJtRnRaVHBzYVc1bFRuVnRZbVZ5T21OdmJIVnRiazUxYldKbGNsd2lYRzRnSUNBZ2RtRnlJR0YwZEdWdGNIUXlJRDBnTDJGMElDaGJYaUJkS3lrNktGeGNaQ3NwT2lnL09seGNaQ3NwSkM4dVpYaGxZeWh6ZEdGamEweHBibVVwTzF4dUlDQWdJR2xtSUNoaGRIUmxiWEIwTWlrZ2UxeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1cyRjBkR1Z0Y0hReVd6RmRMQ0JPZFcxaVpYSW9ZWFIwWlcxd2RESmJNbDBwWFR0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0F2THlCR2FYSmxabTk0SUhOMGVXeGxPaUJjSW1aMWJtTjBhVzl1UUdacGJHVnVZVzFsT214cGJtVk9kVzFpWlhJZ2IzSWdRR1pwYkdWdVlXMWxPbXhwYm1WT2RXMWlaWEpjSWx4dUlDQWdJSFpoY2lCaGRIUmxiWEIwTXlBOUlDOHVLa0FvTGlzcE9paGNYR1FyS1NRdkxtVjRaV01vYzNSaFkydE1hVzVsS1R0Y2JpQWdJQ0JwWmlBb1lYUjBaVzF3ZERNcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlGdGhkSFJsYlhCME0xc3hYU3dnVG5WdFltVnlLR0YwZEdWdGNIUXpXekpkS1YwN1hHNGdJQ0FnZlZ4dWZWeHVYRzVtZFc1amRHbHZiaUJwYzBsdWRHVnlibUZzUm5KaGJXVW9jM1JoWTJ0TWFXNWxLU0I3WEc0Z0lDQWdkbUZ5SUdacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNpQTlJR2RsZEVacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNpaHpkR0ZqYTB4cGJtVXBPMXh1WEc0Z0lDQWdhV1lnS0NGbWFXeGxUbUZ0WlVGdVpFeHBibVZPZFcxaVpYSXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1poYkhObE8xeHVJQ0FnSUgxY2JseHVJQ0FnSUhaaGNpQm1hV3hsVG1GdFpTQTlJR1pwYkdWT1lXMWxRVzVrVEdsdVpVNTFiV0psY2xzd1hUdGNiaUFnSUNCMllYSWdiR2x1WlU1MWJXSmxjaUE5SUdacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNsc3hYVHRjYmx4dUlDQWdJSEpsZEhWeWJpQm1hV3hsVG1GdFpTQTlQVDBnY1VacGJHVk9ZVzFsSUNZbVhHNGdJQ0FnSUNBZ0lHeHBibVZPZFcxaVpYSWdQajBnY1ZOMFlYSjBhVzVuVEdsdVpTQW1KbHh1SUNBZ0lDQWdJQ0JzYVc1bFRuVnRZbVZ5SUR3OUlIRkZibVJwYm1kTWFXNWxPMXh1ZlZ4dVhHNHZMeUJrYVhOamIzWmxjaUJ2ZDI0Z1ptbHNaU0J1WVcxbElHRnVaQ0JzYVc1bElHNTFiV0psY2lCeVlXNW5aU0JtYjNJZ1ptbHNkR1Z5YVc1bklITjBZV05yWEc0dkx5QjBjbUZqWlhOY2JtWjFibU4wYVc5dUlHTmhjSFIxY21WTWFXNWxLQ2tnZTF4dUlDQWdJR2xtSUNnaGFHRnpVM1JoWTJ0ektTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJqdGNiaUFnSUNCOVhHNWNiaUFnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0IwYUhKdmR5QnVaWGNnUlhKeWIzSW9LVHRjYmlBZ0lDQjlJR05oZEdOb0lDaGxLU0I3WEc0Z0lDQWdJQ0FnSUhaaGNpQnNhVzVsY3lBOUlHVXVjM1JoWTJzdWMzQnNhWFFvWENKY1hHNWNJaWs3WEc0Z0lDQWdJQ0FnSUhaaGNpQm1hWEp6ZEV4cGJtVWdQU0JzYVc1bGMxc3dYUzVwYm1SbGVFOW1LRndpUUZ3aUtTQStJREFnUHlCc2FXNWxjMXN4WFNBNklHeHBibVZ6V3pKZE8xeHVJQ0FnSUNBZ0lDQjJZWElnWm1sc1pVNWhiV1ZCYm1STWFXNWxUblZ0WW1WeUlEMGdaMlYwUm1sc1pVNWhiV1ZCYm1STWFXNWxUblZ0WW1WeUtHWnBjbk4wVEdsdVpTazdYRzRnSUNBZ0lDQWdJR2xtSUNnaFptbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lIMWNibHh1SUNBZ0lDQWdJQ0J4Um1sc1pVNWhiV1VnUFNCbWFXeGxUbUZ0WlVGdVpFeHBibVZPZFcxaVpYSmJNRjA3WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJtYVd4bFRtRnRaVUZ1WkV4cGJtVk9kVzFpWlhKYk1WMDdYRzRnSUNBZ2ZWeHVmVnh1WEc1bWRXNWpkR2x2YmlCa1pYQnlaV05oZEdVb1kyRnNiR0poWTJzc0lHNWhiV1VzSUdGc2RHVnlibUYwYVhabEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdhV1lnS0hSNWNHVnZaaUJqYjI1emIyeGxJQ0U5UFNCY0luVnVaR1ZtYVc1bFpGd2lJQ1ltWEc0Z0lDQWdJQ0FnSUNBZ0lDQjBlWEJsYjJZZ1kyOXVjMjlzWlM1M1lYSnVJRDA5UFNCY0ltWjFibU4wYVc5dVhDSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHTnZibk52YkdVdWQyRnliaWh1WVcxbElDc2dYQ0lnYVhNZ1pHVndjbVZqWVhSbFpDd2dkWE5sSUZ3aUlDc2dZV3gwWlhKdVlYUnBkbVVnSzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aUlHbHVjM1JsWVdRdVhDSXNJRzVsZHlCRmNuSnZjaWhjSWx3aUtTNXpkR0ZqYXlrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtRndjR3g1S0dOaGJHeGlZV05yTENCaGNtZDFiV1Z1ZEhNcE8xeHVJQ0FnSUgwN1hHNTlYRzVjYmk4dklHVnVaQ0J2WmlCemFHbHRjMXh1THk4Z1ltVm5hVzV1YVc1bklHOW1JSEpsWVd3Z2QyOXlhMXh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQndjbTl0YVhObElHWnZjaUJoYmlCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObExDQndZWE56WlhNZ2NISnZiV2x6WlhNZ2RHaHliM1ZuYUN3Z2IzSmNiaUFxSUdOdlpYSmpaWE1nY0hKdmJXbHpaWE1nWm5KdmJTQmthV1ptWlhKbGJuUWdjM2x6ZEdWdGN5NWNiaUFxSUVCd1lYSmhiU0IyWVd4MVpTQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxJRzl5SUhCeWIyMXBjMlZjYmlBcUwxeHVablZ1WTNScGIyNGdVU2gyWVd4MVpTa2dlMXh1SUNBZ0lDOHZJRWxtSUhSb1pTQnZZbXBsWTNRZ2FYTWdZV3h5WldGa2VTQmhJRkJ5YjIxcGMyVXNJSEpsZEhWeWJpQnBkQ0JrYVhKbFkzUnNlUzRnSUZSb2FYTWdaVzVoWW14bGMxeHVJQ0FnSUM4dklIUm9aU0J5WlhOdmJIWmxJR1oxYm1OMGFXOXVJSFJ2SUdKdmRHZ2dZbVVnZFhObFpDQjBieUJqY21WaGRHVmtJSEpsWm1WeVpXNWpaWE1nWm5KdmJTQnZZbXBsWTNSekxGeHVJQ0FnSUM4dklHSjFkQ0IwYnlCMGIyeGxjbUZpYkhrZ1kyOWxjbU5sSUc1dmJpMXdjbTl0YVhObGN5QjBieUJ3Y205dGFYTmxjeTVjYmlBZ0lDQnBaaUFvZG1Gc2RXVWdhVzV6ZEdGdVkyVnZaaUJRY205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUIyWVd4MVpUdGNiaUFnSUNCOVhHNWNiaUFnSUNBdkx5QmhjM05wYldsc1lYUmxJSFJvWlc1aFlteGxjMXh1SUNBZ0lHbG1JQ2hwYzFCeWIyMXBjMlZCYkdsclpTaDJZV3gxWlNrcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTnZaWEpqWlNoMllXeDFaU2s3WEc0Z0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHWjFiR1pwYkd3b2RtRnNkV1VwTzF4dUlDQWdJSDFjYm4xY2JsRXVjbVZ6YjJ4MlpTQTlJRkU3WEc1Y2JpOHFLbHh1SUNvZ1VHVnlabTl5YlhNZ1lTQjBZWE5ySUdsdUlHRWdablYwZFhKbElIUjFjbTRnYjJZZ2RHaGxJR1YyWlc1MElHeHZiM0F1WEc0Z0tpQkFjR0Z5WVcwZ2UwWjFibU4wYVc5dWZTQjBZWE5yWEc0Z0tpOWNibEV1Ym1WNGRGUnBZMnNnUFNCdVpYaDBWR2xqYXp0Y2JseHVMeW9xWEc0Z0tpQkRiMjUwY205c2N5QjNhR1YwYUdWeUlHOXlJRzV2ZENCc2IyNW5JSE4wWVdOcklIUnlZV05sY3lCM2FXeHNJR0psSUc5dVhHNGdLaTljYmxFdWJHOXVaMU4wWVdOclUzVndjRzl5ZENBOUlHWmhiSE5sTzF4dVhHNHZMeUJsYm1GaWJHVWdiRzl1WnlCemRHRmphM01nYVdZZ1VWOUVSVUpWUnlCcGN5QnpaWFJjYm1sbUlDaDBlWEJsYjJZZ2NISnZZMlZ6Y3lBOVBUMGdYQ0p2WW1wbFkzUmNJaUFtSmlCd2NtOWpaWE56SUNZbUlIQnliMk5sYzNNdVpXNTJJQ1ltSUhCeWIyTmxjM011Wlc1MkxsRmZSRVZDVlVjcElIdGNiaUFnSUNCUkxteHZibWRUZEdGamExTjFjSEJ2Y25RZ1BTQjBjblZsTzF4dWZWeHVYRzR2S2lwY2JpQXFJRU52Ym5OMGNuVmpkSE1nWVNCN2NISnZiV2x6WlN3Z2NtVnpiMngyWlN3Z2NtVnFaV04wZlNCdlltcGxZM1F1WEc0Z0tseHVJQ29nWUhKbGMyOXNkbVZnSUdseklHRWdZMkZzYkdKaFkyc2dkRzhnYVc1MmIydGxJSGRwZEdnZ1lTQnRiM0psSUhKbGMyOXNkbVZrSUhaaGJIVmxJR1p2Y2lCMGFHVmNiaUFxSUhCeWIyMXBjMlV1SUZSdklHWjFiR1pwYkd3Z2RHaGxJSEJ5YjIxcGMyVXNJR2x1ZG05clpTQmdjbVZ6YjJ4MlpXQWdkMmwwYUNCaGJua2dkbUZzZFdVZ2RHaGhkQ0JwYzF4dUlDb2dibTkwSUdFZ2RHaGxibUZpYkdVdUlGUnZJSEpsYW1WamRDQjBhR1VnY0hKdmJXbHpaU3dnYVc1MmIydGxJR0J5WlhOdmJIWmxZQ0IzYVhSb0lHRWdjbVZxWldOMFpXUmNiaUFxSUhSb1pXNWhZbXhsTENCdmNpQnBiblp2YTJVZ1lISmxhbVZqZEdBZ2QybDBhQ0IwYUdVZ2NtVmhjMjl1SUdScGNtVmpkR3g1TGlCVWJ5QnlaWE52YkhabElIUm9aVnh1SUNvZ2NISnZiV2x6WlNCMGJ5QmhibTkwYUdWeUlIUm9aVzVoWW14bExDQjBhSFZ6SUhCMWRIUnBibWNnYVhRZ2FXNGdkR2hsSUhOaGJXVWdjM1JoZEdVc0lHbHVkbTlyWlZ4dUlDb2dZSEpsYzI5c2RtVmdJSGRwZEdnZ2RHaGhkQ0J2ZEdobGNpQjBhR1Z1WVdKc1pTNWNiaUFxTDF4dVVTNWtaV1psY2lBOUlHUmxabVZ5TzF4dVpuVnVZM1JwYjI0Z1pHVm1aWElvS1NCN1hHNGdJQ0FnTHk4Z2FXWWdYQ0p0WlhOellXZGxjMXdpSUdseklHRnVJRndpUVhKeVlYbGNJaXdnZEdoaGRDQnBibVJwWTJGMFpYTWdkR2hoZENCMGFHVWdjSEp2YldselpTQm9ZWE1nYm05MElIbGxkRnh1SUNBZ0lDOHZJR0psWlc0Z2NtVnpiMngyWldRdUlDQkpaaUJwZENCcGN5QmNJblZ1WkdWbWFXNWxaRndpTENCcGRDQm9ZWE1nWW1WbGJpQnlaWE52YkhabFpDNGdJRVZoWTJoY2JpQWdJQ0F2THlCbGJHVnRaVzUwSUc5bUlIUm9aU0J0WlhOellXZGxjeUJoY25KaGVTQnBjeUJwZEhObGJHWWdZVzRnWVhKeVlYa2diMllnWTI5dGNHeGxkR1VnWVhKbmRXMWxiblJ6SUhSdlhHNGdJQ0FnTHk4Z1ptOXlkMkZ5WkNCMGJ5QjBhR1VnY21WemIyeDJaV1FnY0hKdmJXbHpaUzRnSUZkbElHTnZaWEpqWlNCMGFHVWdjbVZ6YjJ4MWRHbHZiaUIyWVd4MVpTQjBieUJoWEc0Z0lDQWdMeThnY0hKdmJXbHpaU0IxYzJsdVp5QjBhR1VnWUhKbGMyOXNkbVZnSUdaMWJtTjBhVzl1SUdKbFkyRjFjMlVnYVhRZ2FHRnVaR3hsY3lCaWIzUm9JR1oxYkd4NVhHNGdJQ0FnTHk4Z2JtOXVMWFJvWlc1aFlteGxJSFpoYkhWbGN5QmhibVFnYjNSb1pYSWdkR2hsYm1GaWJHVnpJR2R5WVdObFpuVnNiSGt1WEc0Z0lDQWdkbUZ5SUcxbGMzTmhaMlZ6SUQwZ1cxMHNJSEJ5YjJkeVpYTnpUR2x6ZEdWdVpYSnpJRDBnVzEwc0lISmxjMjlzZG1Wa1VISnZiV2x6WlR0Y2JseHVJQ0FnSUhaaGNpQmtaV1psY25KbFpDQTlJRzlpYW1WamRGOWpjbVZoZEdVb1pHVm1aWEl1Y0hKdmRHOTBlWEJsS1R0Y2JpQWdJQ0IyWVhJZ2NISnZiV2x6WlNBOUlHOWlhbVZqZEY5amNtVmhkR1VvVUhKdmJXbHpaUzV3Y205MGIzUjVjR1VwTzF4dVhHNGdJQ0FnY0hKdmJXbHpaUzV3Y205dGFYTmxSR2x6Y0dGMFkyZ2dQU0JtZFc1amRHbHZiaUFvY21WemIyeDJaU3dnYjNBc0lHOXdaWEpoYm1SektTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCaGNtZHpJRDBnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SektUdGNiaUFnSUNBZ0lDQWdhV1lnS0cxbGMzTmhaMlZ6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J0WlhOellXZGxjeTV3ZFhOb0tHRnlaM01wTzF4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0c5d0lEMDlQU0JjSW5kb1pXNWNJaUFtSmlCdmNHVnlZVzVrYzFzeFhTa2dleUF2THlCd2NtOW5jbVZ6Y3lCdmNHVnlZVzVrWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY0hKdlozSmxjM05NYVhOMFpXNWxjbk11Y0hWemFDaHZjR1Z5WVc1a2Mxc3hYU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCUkxtNWxlSFJVYVdOcktHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J5WlhOdmJIWmxaRkJ5YjIxcGMyVXVjSEp2YldselpVUnBjM0JoZEdOb0xtRndjR3g1S0hKbGMyOXNkbVZrVUhKdmJXbHpaU3dnWVhKbmN5azdYRzRnSUNBZ0lDQWdJQ0FnSUNCOUtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMDdYRzVjYmlBZ0lDQXZMeUJZV0ZnZ1pHVndjbVZqWVhSbFpGeHVJQ0FnSUhCeWIyMXBjMlV1ZG1Gc2RXVlBaaUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdhV1lnS0cxbGMzTmhaMlZ6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdjSEp2YldselpUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0IyWVhJZ2JtVmhjbVZ5Vm1Gc2RXVWdQU0J1WldGeVpYSW9jbVZ6YjJ4MlpXUlFjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdhV1lnS0dselVISnZiV2x6WlNodVpXRnlaWEpXWVd4MVpTa3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxjMjlzZG1Wa1VISnZiV2x6WlNBOUlHNWxZWEpsY2xaaGJIVmxPeUF2THlCemFHOXlkR1Z1SUdOb1lXbHVYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRzVsWVhKbGNsWmhiSFZsTzF4dUlDQWdJSDA3WEc1Y2JpQWdJQ0J3Y205dGFYTmxMbWx1YzNCbFkzUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lHbG1JQ2doY21WemIyeDJaV1JRY205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2V5QnpkR0YwWlRvZ1hDSndaVzVrYVc1blhDSWdmVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY21WemIyeDJaV1JRY205dGFYTmxMbWx1YzNCbFkzUW9LVHRjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdhV1lnS0ZFdWJHOXVaMU4wWVdOclUzVndjRzl5ZENBbUppQm9ZWE5UZEdGamEzTXBJSHRjYmlBZ0lDQWdJQ0FnZEhKNUlIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhSb2NtOTNJRzVsZHlCRmNuSnZjaWdwTzF4dUlDQWdJQ0FnSUNCOUlHTmhkR05vSUNobEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5Qk9UMVJGT2lCa2IyNG5kQ0IwY25rZ2RHOGdkWE5sSUdCRmNuSnZjaTVqWVhCMGRYSmxVM1JoWTJ0VWNtRmpaV0FnYjNJZ2RISmhibk5tWlhJZ2RHaGxYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QmhZMk5sYzNOdmNpQmhjbTkxYm1RN0lIUm9ZWFFnWTJGMWMyVnpJRzFsYlc5eWVTQnNaV0ZyY3lCaGN5QndaWElnUjBndE1URXhMaUJLZFhOMFhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCeVpXbG1lU0IwYUdVZ2MzUmhZMnNnZEhKaFkyVWdZWE1nWVNCemRISnBibWNnUVZOQlVDNWNiaUFnSUNBZ0lDQWdJQ0FnSUM4dlhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCQmRDQjBhR1VnYzJGdFpTQjBhVzFsTENCamRYUWdiMlptSUhSb1pTQm1hWEp6ZENCc2FXNWxPeUJwZENkeklHRnNkMkY1Y3lCcWRYTjBYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QmNJbHR2WW1wbFkzUWdVSEp2YldselpWMWNYRzVjSWl3Z1lYTWdjR1Z5SUhSb1pTQmdkRzlUZEhKcGJtZGdMbHh1SUNBZ0lDQWdJQ0FnSUNBZ2NISnZiV2x6WlM1emRHRmpheUE5SUdVdWMzUmhZMnN1YzNWaWMzUnlhVzVuS0dVdWMzUmhZMnN1YVc1a1pYaFBaaWhjSWx4Y2Jsd2lLU0FySURFcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZWeHVYRzRnSUNBZ0x5OGdUazlVUlRvZ2QyVWdaRzhnZEdobElHTm9aV05yY3lCbWIzSWdZSEpsYzI5c2RtVmtVSEp2YldselpXQWdhVzRnWldGamFDQnRaWFJvYjJRc0lHbHVjM1JsWVdRZ2IyWmNiaUFnSUNBdkx5QmpiMjV6YjJ4cFpHRjBhVzVuSUhSb1pXMGdhVzUwYnlCZ1ltVmpiMjFsWUN3Z2MybHVZMlVnYjNSb1pYSjNhWE5sSUhkbEoyUWdZM0psWVhSbElHNWxkMXh1SUNBZ0lDOHZJSEJ5YjIxcGMyVnpJSGRwZEdnZ2RHaGxJR3hwYm1WeklHQmlaV052YldVb2QyaGhkR1YyWlhJb2RtRnNkV1VwS1dBdUlGTmxaU0JsTG1jdUlFZElMVEkxTWk1Y2JseHVJQ0FnSUdaMWJtTjBhVzl1SUdKbFkyOXRaU2h1WlhkUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lISmxjMjlzZG1Wa1VISnZiV2x6WlNBOUlHNWxkMUJ5YjIxcGMyVTdYRzRnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVjMjkxY21ObElEMGdibVYzVUhKdmJXbHpaVHRjYmx4dUlDQWdJQ0FnSUNCaGNuSmhlVjl5WldSMVkyVW9iV1Z6YzJGblpYTXNJR1oxYm1OMGFXOXVJQ2gxYm1SbFptbHVaV1FzSUcxbGMzTmhaMlVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJRkV1Ym1WNGRGUnBZMnNvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHNWxkMUJ5YjIxcGMyVXVjSEp2YldselpVUnBjM0JoZEdOb0xtRndjR3g1S0c1bGQxQnliMjFwYzJVc0lHMWxjM05oWjJVcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMHNJSFp2YVdRZ01DazdYRzVjYmlBZ0lDQWdJQ0FnYldWemMyRm5aWE1nUFNCMmIybGtJREE3WEc0Z0lDQWdJQ0FnSUhCeWIyZHlaWE56VEdsemRHVnVaWEp6SUQwZ2RtOXBaQ0F3TzF4dUlDQWdJSDFjYmx4dUlDQWdJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVWdQU0J3Y205dGFYTmxPMXh1SUNBZ0lHUmxabVZ5Y21Wa0xuSmxjMjlzZG1VZ1BTQm1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdhV1lnS0hKbGMyOXNkbVZrVUhKdmJXbHpaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdU8xeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnWW1WamIyMWxLRkVvZG1Gc2RXVXBLVHRjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdaR1ZtWlhKeVpXUXVablZzWm1sc2JDQTlJR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2NtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCaVpXTnZiV1VvWm5Wc1ptbHNiQ2gyWVd4MVpTa3BPMXh1SUNBZ0lIMDdYRzRnSUNBZ1pHVm1aWEp5WldRdWNtVnFaV04wSUQwZ1puVnVZM1JwYjI0Z0tISmxZWE52YmlrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvY21WemIyeDJaV1JRY205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lIMWNibHh1SUNBZ0lDQWdJQ0JpWldOdmJXVW9jbVZxWldOMEtISmxZWE52YmlrcE8xeHVJQ0FnSUgwN1hHNGdJQ0FnWkdWbVpYSnlaV1F1Ym05MGFXWjVJRDBnWm5WdVkzUnBiMjRnS0hCeWIyZHlaWE56S1NCN1hHNGdJQ0FnSUNBZ0lHbG1JQ2h5WlhOdmJIWmxaRkJ5YjIxcGMyVXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5Ymp0Y2JpQWdJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ0lDQWdJR0Z5Y21GNVgzSmxaSFZqWlNod2NtOW5jbVZ6YzB4cGMzUmxibVZ5Y3l3Z1puVnVZM1JwYjI0Z0tIVnVaR1ZtYVc1bFpDd2djSEp2WjNKbGMzTk1hWE4wWlc1bGNpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1VTNXVaWGgwVkdsamF5aG1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY0hKdlozSmxjM05NYVhOMFpXNWxjaWh3Y205bmNtVnpjeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQWdJQ0FnZlN3Z2RtOXBaQ0F3S1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlFTnlaV0YwWlhNZ1lTQk9iMlJsTFhOMGVXeGxJR05oYkd4aVlXTnJJSFJvWVhRZ2QybHNiQ0J5WlhOdmJIWmxJRzl5SUhKbGFtVmpkQ0IwYUdVZ1pHVm1aWEp5WldSY2JpQXFJSEJ5YjIxcGMyVXVYRzRnS2lCQWNtVjBkWEp1Y3lCaElHNXZaR1ZpWVdOclhHNGdLaTljYm1SbFptVnlMbkJ5YjNSdmRIbHdaUzV0WVd0bFRtOWtaVkpsYzI5c2RtVnlJRDBnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUhaaGNpQnpaV3htSUQwZ2RHaHBjenRjYmlBZ0lDQnlaWFIxY200Z1puVnVZM1JwYjI0Z0tHVnljbTl5TENCMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9aWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhObGJHWXVjbVZxWldOMEtHVnljbTl5S1R0Y2JpQWdJQ0FnSUNBZ2ZTQmxiSE5sSUdsbUlDaGhjbWQxYldWdWRITXViR1Z1WjNSb0lENGdNaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlZzWmk1eVpYTnZiSFpsS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5d2dNU2twTzF4dUlDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlZzWmk1eVpYTnZiSFpsS0haaGJIVmxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDA3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRUJ3WVhKaGJTQnlaWE52YkhabGNpQjdSblZ1WTNScGIyNTlJR0VnWm5WdVkzUnBiMjRnZEdoaGRDQnlaWFIxY201eklHNXZkR2hwYm1jZ1lXNWtJR0ZqWTJWd2RITmNiaUFxSUhSb1pTQnlaWE52YkhabExDQnlaV3BsWTNRc0lHRnVaQ0J1YjNScFpua2dablZ1WTNScGIyNXpJR1p2Y2lCaElHUmxabVZ5Y21Wa0xseHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUhSb1lYUWdiV0Y1SUdKbElISmxjMjlzZG1Wa0lIZHBkR2dnZEdobElHZHBkbVZ1SUhKbGMyOXNkbVVnWVc1a0lISmxhbVZqZEZ4dUlDb2dablZ1WTNScGIyNXpMQ0J2Y2lCeVpXcGxZM1JsWkNCaWVTQmhJSFJvY205M2JpQmxlR05sY0hScGIyNGdhVzRnY21WemIyeDJaWEpjYmlBcUwxeHVVUzVRY205dGFYTmxJRDBnY0hKdmJXbHpaVHNnTHk4Z1JWTTJYRzVSTG5CeWIyMXBjMlVnUFNCd2NtOXRhWE5sTzF4dVpuVnVZM1JwYjI0Z2NISnZiV2x6WlNoeVpYTnZiSFpsY2lrZ2UxeHVJQ0FnSUdsbUlDaDBlWEJsYjJZZ2NtVnpiMngyWlhJZ0lUMDlJRndpWm5WdVkzUnBiMjVjSWlrZ2UxeHVJQ0FnSUNBZ0lDQjBhSEp2ZHlCdVpYY2dWSGx3WlVWeWNtOXlLRndpY21WemIyeDJaWElnYlhWemRDQmlaU0JoSUdaMWJtTjBhVzl1TGx3aUtUdGNiaUFnSUNCOVhHNGdJQ0FnZG1GeUlHUmxabVZ5Y21Wa0lEMGdaR1ZtWlhJb0tUdGNiaUFnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0J5WlhOdmJIWmxjaWhrWldabGNuSmxaQzV5WlhOdmJIWmxMQ0JrWldabGNuSmxaQzV5WldwbFkzUXNJR1JsWm1WeWNtVmtMbTV2ZEdsbWVTazdYRzRnSUNBZ2ZTQmpZWFJqYUNBb2NtVmhjMjl1S1NCN1hHNGdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xuSmxhbVZqZENoeVpXRnpiMjRwTzF4dUlDQWdJSDFjYmlBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JuMWNibHh1Y0hKdmJXbHpaUzV5WVdObElEMGdjbUZqWlRzZ0x5OGdSVk0yWEc1d2NtOXRhWE5sTG1Gc2JDQTlJR0ZzYkRzZ0x5OGdSVk0yWEc1d2NtOXRhWE5sTG5KbGFtVmpkQ0E5SUhKbGFtVmpkRHNnTHk4Z1JWTTJYRzV3Y205dGFYTmxMbkpsYzI5c2RtVWdQU0JST3lBdkx5QkZVelpjYmx4dUx5OGdXRmhZSUdWNGNHVnlhVzFsYm5SaGJDNGdJRlJvYVhNZ2JXVjBhRzlrSUdseklHRWdkMkY1SUhSdklHUmxibTkwWlNCMGFHRjBJR0VnYkc5allXd2dkbUZzZFdVZ2FYTmNiaTh2SUhObGNtbGhiR2w2WVdKc1pTQmhibVFnYzJodmRXeGtJR0psSUdsdGJXVmthV0YwWld4NUlHUnBjM0JoZEdOb1pXUWdkRzhnWVNCeVpXMXZkR1VnZFhCdmJpQnlaWEYxWlhOMExGeHVMeThnYVc1emRHVmhaQ0J2WmlCd1lYTnphVzVuSUdFZ2NtVm1aWEpsYm1ObExseHVVUzV3WVhOelFubERiM0I1SUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZENrZ2UxeHVJQ0FnSUM4dlpuSmxaWHBsS0c5aWFtVmpkQ2s3WEc0Z0lDQWdMeTl3WVhOelFubERiM0JwWlhNdWMyVjBLRzlpYW1WamRDd2dkSEoxWlNrN1hHNGdJQ0FnY21WMGRYSnVJRzlpYW1WamREdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExuQmhjM05DZVVOdmNIa2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnTHk5bWNtVmxlbVVvYjJKcVpXTjBLVHRjYmlBZ0lDQXZMM0JoYzNOQ2VVTnZjR2xsY3k1elpYUW9iMkpxWldOMExDQjBjblZsS1R0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3p0Y2JuMDdYRzVjYmk4cUtseHVJQ29nU1dZZ2RIZHZJSEJ5YjIxcGMyVnpJR1YyWlc1MGRXRnNiSGtnWm5Wc1ptbHNiQ0IwYnlCMGFHVWdjMkZ0WlNCMllXeDFaU3dnY0hKdmJXbHpaWE1nZEdoaGRDQjJZV3gxWlN4Y2JpQXFJR0oxZENCdmRHaGxjbmRwYzJVZ2NtVnFaV04wY3k1Y2JpQXFJRUJ3WVhKaGJTQjRJSHRCYm5rcWZWeHVJQ29nUUhCaGNtRnRJSGtnZTBGdWVTcDlYRzRnS2lCQWNtVjBkWEp1Y3lCN1FXNTVLbjBnWVNCd2NtOXRhWE5sSUdadmNpQjRJR0Z1WkNCNUlHbG1JSFJvWlhrZ1lYSmxJSFJvWlNCellXMWxMQ0JpZFhRZ1lTQnlaV3BsWTNScGIyNWNiaUFxSUc5MGFHVnlkMmx6WlM1Y2JpQXFYRzRnS2k5Y2JsRXVhbTlwYmlBOUlHWjFibU4wYVc5dUlDaDRMQ0I1S1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvZUNrdWFtOXBiaWg1S1R0Y2JuMDdYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1wdmFXNGdQU0JtZFc1amRHbHZiaUFvZEdoaGRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktGdDBhR2x6TENCMGFHRjBYU2t1YzNCeVpXRmtLR1oxYm1OMGFXOXVJQ2g0TENCNUtTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoNElEMDlQU0I1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCVVQwUlBPaUJjSWowOVBWd2lJSE5vYjNWc1pDQmlaU0JQWW1wbFkzUXVhWE1nYjNJZ1pYRjFhWFpjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCNE8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnZEdoeWIzY2dibVYzSUVWeWNtOXlLRndpUTJGdUozUWdhbTlwYmpvZ2JtOTBJSFJvWlNCellXMWxPaUJjSWlBcklIZ2dLeUJjSWlCY0lpQXJJSGtwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnWm1seWMzUWdiMllnWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhNZ2RHOGdZbVZqYjIxbElITmxkSFJzWldRdVhHNGdLaUJBY0dGeVlXMGdZVzV6ZDJWeWN5QjdRWEp5WVhsYlFXNTVLbDE5SUhCeWIyMXBjMlZ6SUhSdklISmhZMlZjYmlBcUlFQnlaWFIxY201eklIdEJibmtxZlNCMGFHVWdabWx5YzNRZ2NISnZiV2x6WlNCMGJ5QmlaU0J6WlhSMGJHVmtYRzRnS2k5Y2JsRXVjbUZqWlNBOUlISmhZMlU3WEc1bWRXNWpkR2x2YmlCeVlXTmxLR0Z1YzNkbGNsQnpLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIQnliMjFwYzJVb1puVnVZM1JwYjI0Z0tISmxjMjlzZG1Vc0lISmxhbVZqZENrZ2UxeHVJQ0FnSUNBZ0lDQXZMeUJUZDJsMFkyZ2dkRzhnZEdocGN5QnZibU5sSUhkbElHTmhiaUJoYzNOMWJXVWdZWFFnYkdWaGMzUWdSVk0xWEc0Z0lDQWdJQ0FnSUM4dklHRnVjM2RsY2xCekxtWnZja1ZoWTJnb1puVnVZM1JwYjI0Z0tHRnVjM2RsY2xBcElIdGNiaUFnSUNBZ0lDQWdMeThnSUNBZ0lGRW9ZVzV6ZDJWeVVDa3VkR2hsYmloeVpYTnZiSFpsTENCeVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNBdkx5QjlLVHRjYmlBZ0lDQWdJQ0FnTHk4Z1ZYTmxJSFJvYVhNZ2FXNGdkR2hsSUcxbFlXNTBhVzFsWEc0Z0lDQWdJQ0FnSUdadmNpQW9kbUZ5SUdrZ1BTQXdMQ0JzWlc0Z1BTQmhibk4zWlhKUWN5NXNaVzVuZEdnN0lHa2dQQ0JzWlc0N0lHa3JLeWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdVU2hoYm5OM1pYSlFjMXRwWFNrdWRHaGxiaWh5WlhOdmJIWmxMQ0J5WldwbFkzUXBPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdmU2s3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkpoWTJVZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaFJMbkpoWTJVcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCRGIyNXpkSEoxWTNSeklHRWdVSEp2YldselpTQjNhWFJvSUdFZ2NISnZiV2x6WlNCa1pYTmpjbWx3ZEc5eUlHOWlhbVZqZENCaGJtUWdiM0IwYVc5dVlXd2dabUZzYkdKaFkydGNiaUFxSUdaMWJtTjBhVzl1TGlBZ1ZHaGxJR1JsYzJOeWFYQjBiM0lnWTI5dWRHRnBibk1nYldWMGFHOWtjeUJzYVd0bElIZG9aVzRvY21WcVpXTjBaV1FwTENCblpYUW9ibUZ0WlNrc1hHNGdLaUJ6WlhRb2JtRnRaU3dnZG1Gc2RXVXBMQ0J3YjNOMEtHNWhiV1VzSUdGeVozTXBMQ0JoYm1RZ1pHVnNaWFJsS0c1aGJXVXBMQ0IzYUdsamFDQmhiR3hjYmlBcUlISmxkSFZ5YmlCbGFYUm9aWElnWVNCMllXeDFaU3dnWVNCd2NtOXRhWE5sSUdadmNpQmhJSFpoYkhWbExDQnZjaUJoSUhKbGFtVmpkR2x2Ymk0Z0lGUm9aU0JtWVd4c1ltRmphMXh1SUNvZ1lXTmpaWEIwY3lCMGFHVWdiM0JsY21GMGFXOXVJRzVoYldVc0lHRWdjbVZ6YjJ4MlpYSXNJR0Z1WkNCaGJua2dablZ5ZEdobGNpQmhjbWQxYldWdWRITWdkR2hoZENCM2IzVnNaRnh1SUNvZ2FHRjJaU0JpWldWdUlHWnZjbmRoY21SbFpDQjBieUIwYUdVZ1lYQndjbTl3Y21saGRHVWdiV1YwYUc5a0lHRmliM1psSUdoaFpDQmhJRzFsZEdodlpDQmlaV1Z1WEc0Z0tpQndjbTkyYVdSbFpDQjNhWFJvSUhSb1pTQndjbTl3WlhJZ2JtRnRaUzRnSUZSb1pTQkJVRWtnYldGclpYTWdibThnWjNWaGNtRnVkR1ZsY3lCaFltOTFkQ0IwYUdVZ2JtRjBkWEpsWEc0Z0tpQnZaaUIwYUdVZ2NtVjBkWEp1WldRZ2IySnFaV04wTENCaGNHRnlkQ0JtY205dElIUm9ZWFFnYVhRZ2FYTWdkWE5oWW14bElIZG9aWEpsWlhabGNpQndjbTl0YVhObGN5QmhjbVZjYmlBcUlHSnZkV2RvZENCaGJtUWdjMjlzWkM1Y2JpQXFMMXh1VVM1dFlXdGxVSEp2YldselpTQTlJRkJ5YjIxcGMyVTdYRzVtZFc1amRHbHZiaUJRY205dGFYTmxLR1JsYzJOeWFYQjBiM0lzSUdaaGJHeGlZV05yTENCcGJuTndaV04wS1NCN1hHNGdJQ0FnYVdZZ0tHWmhiR3hpWVdOcklEMDlQU0IyYjJsa0lEQXBJSHRjYmlBZ0lDQWdJQ0FnWm1Gc2JHSmhZMnNnUFNCbWRXNWpkR2x2YmlBb2IzQXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1FvYm1WM0lFVnljbTl5S0Z4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aVVISnZiV2x6WlNCa2IyVnpJRzV2ZENCemRYQndiM0owSUc5d1pYSmhkR2x2YmpvZ1hDSWdLeUJ2Y0Z4dUlDQWdJQ0FnSUNBZ0lDQWdLU2s3WEc0Z0lDQWdJQ0FnSUgwN1hHNGdJQ0FnZlZ4dUlDQWdJR2xtSUNocGJuTndaV04wSUQwOVBTQjJiMmxrSURBcElIdGNiaUFnSUNBZ0lDQWdhVzV6Y0dWamRDQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjdjM1JoZEdVNklGd2lkVzVyYm05M2Jsd2lmVHRjYmlBZ0lDQWdJQ0FnZlR0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0IyWVhJZ2NISnZiV2x6WlNBOUlHOWlhbVZqZEY5amNtVmhkR1VvVUhKdmJXbHpaUzV3Y205MGIzUjVjR1VwTzF4dVhHNGdJQ0FnY0hKdmJXbHpaUzV3Y205dGFYTmxSR2x6Y0dGMFkyZ2dQU0JtZFc1amRHbHZiaUFvY21WemIyeDJaU3dnYjNBc0lHRnlaM01wSUh0Y2JpQWdJQ0FnSUNBZ2RtRnlJSEpsYzNWc2REdGNiaUFnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoa1pYTmpjbWx3ZEc5eVcyOXdYU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGMzVnNkQ0E5SUdSbGMyTnlhWEIwYjNKYmIzQmRMbUZ3Y0d4NUtIQnliMjFwYzJVc0lHRnlaM01wTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWE4xYkhRZ1BTQm1ZV3hzWW1GamF5NWpZV3hzS0hCeWIyMXBjMlVzSUc5d0xDQmhjbWR6S1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhOMWJIUWdQU0J5WldwbFkzUW9aWGhqWlhCMGFXOXVLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCcFppQW9jbVZ6YjJ4MlpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVnpiMngyWlNoeVpYTjFiSFFwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlR0Y2JseHVJQ0FnSUhCeWIyMXBjMlV1YVc1emNHVmpkQ0E5SUdsdWMzQmxZM1E3WEc1Y2JpQWdJQ0F2THlCWVdGZ2daR1Z3Y21WallYUmxaQ0JnZG1Gc2RXVlBabUFnWVc1a0lHQmxlR05sY0hScGIyNWdJSE4xY0hCdmNuUmNiaUFnSUNCcFppQW9hVzV6Y0dWamRDa2dlMXh1SUNBZ0lDQWdJQ0IyWVhJZ2FXNXpjR1ZqZEdWa0lEMGdhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lDQWdJQ0JwWmlBb2FXNXpjR1ZqZEdWa0xuTjBZWFJsSUQwOVBTQmNJbkpsYW1WamRHVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVaWGhqWlhCMGFXOXVJRDBnYVc1emNHVmpkR1ZrTG5KbFlYTnZianRjYmlBZ0lDQWdJQ0FnZlZ4dVhHNGdJQ0FnSUNBZ0lIQnliMjFwYzJVdWRtRnNkV1ZQWmlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIWmhjaUJwYm5Od1pXTjBaV1FnUFNCcGJuTndaV04wS0NrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2FXNXpjR1ZqZEdWa0xuTjBZWFJsSUQwOVBTQmNJbkJsYm1ScGJtZGNJaUI4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsdWMzQmxZM1JsWkM1emRHRjBaU0E5UFQwZ1hDSnlaV3BsWTNSbFpGd2lLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVTdYRzRnSUNBZ0lDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdhVzV6Y0dWamRHVmtMblpoYkhWbE8xeHVJQ0FnSUNBZ0lDQjlPMXh1SUNBZ0lIMWNibHh1SUNBZ0lISmxkSFZ5YmlCd2NtOXRhWE5sTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzUwYjFOMGNtbHVaeUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNCeVpYUjFjbTRnWENKYmIySnFaV04wSUZCeWIyMXBjMlZkWENJN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGFHVnVJRDBnWm5WdVkzUnBiMjRnS0daMWJHWnBiR3hsWkN3Z2NtVnFaV04wWldRc0lIQnliMmR5WlhOelpXUXBJSHRjYmlBZ0lDQjJZWElnYzJWc1ppQTlJSFJvYVhNN1hHNGdJQ0FnZG1GeUlHUmxabVZ5Y21Wa0lEMGdaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdaRzl1WlNBOUlHWmhiSE5sT3lBZ0lDOHZJR1Z1YzNWeVpTQjBhR1VnZFc1MGNuVnpkR1ZrSUhCeWIyMXBjMlVnYldGclpYTWdZWFFnYlc5emRDQmhYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJ6YVc1bmJHVWdZMkZzYkNCMGJ5QnZibVVnYjJZZ2RHaGxJR05oYkd4aVlXTnJjMXh1WEc0Z0lDQWdablZ1WTNScGIyNGdYMloxYkdacGJHeGxaQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSFI1Y0dWdlppQm1kV3htYVd4c1pXUWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpQS9JR1oxYkdacGJHeGxaQ2gyWVd4MVpTa2dPaUIyWVd4MVpUdGNiaUFnSUNBZ0lDQWdmU0JqWVhSamFDQW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2NtVnFaV04wS0dWNFkyVndkR2x2YmlrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOVhHNWNiaUFnSUNCbWRXNWpkR2x2YmlCZmNtVnFaV04wWldRb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoMGVYQmxiMllnY21WcVpXTjBaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdiV0ZyWlZOMFlXTnJWSEpoWTJWTWIyNW5LR1Y0WTJWd2RHbHZiaXdnYzJWc1ppazdYRzRnSUNBZ0lDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNSbFpDaGxlR05sY0hScGIyNHBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb2JtVjNSWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYW1WamRDaHVaWGRGZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJ5WldwbFkzUW9aWGhqWlhCMGFXOXVLVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQm1kVzVqZEdsdmJpQmZjSEp2WjNKbGMzTmxaQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdkSGx3Wlc5bUlIQnliMmR5WlhOelpXUWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpQS9JSEJ5YjJkeVpYTnpaV1FvZG1Gc2RXVXBJRG9nZG1Gc2RXVTdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ1VTNXVaWGgwVkdsamF5aG1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUhObGJHWXVjSEp2YldselpVUnBjM0JoZEdOb0tHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHUnZibVVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTQ3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNCa2IyNWxJRDBnZEhKMVpUdGNibHh1SUNBZ0lDQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWNtVnpiMngyWlNoZlpuVnNabWxzYkdWa0tIWmhiSFZsS1NrN1hHNGdJQ0FnSUNBZ0lIMHNJRndpZDJobGJsd2lMQ0JiWm5WdVkzUnBiMjRnS0dWNFkyVndkR2x2YmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHUnZibVVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTQ3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNCa2IyNWxJRDBnZEhKMVpUdGNibHh1SUNBZ0lDQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWNtVnpiMngyWlNoZmNtVnFaV04wWldRb1pYaGpaWEIwYVc5dUtTazdYRzRnSUNBZ0lDQWdJSDFkS1R0Y2JpQWdJQ0I5S1R0Y2JseHVJQ0FnSUM4dklGQnliMmR5WlhOeklIQnliM0JoWjJGMGIzSWdibVZsWkNCMGJ5QmlaU0JoZEhSaFkyaGxaQ0JwYmlCMGFHVWdZM1Z5Y21WdWRDQjBhV05yTGx4dUlDQWdJSE5sYkdZdWNISnZiV2x6WlVScGMzQmhkR05vS0hadmFXUWdNQ3dnWENKM2FHVnVYQ0lzSUZ0MmIybGtJREFzSUdaMWJtTjBhVzl1SUNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdibVYzVm1Gc2RXVTdYRzRnSUNBZ0lDQWdJSFpoY2lCMGFISmxkeUE5SUdaaGJITmxPMXh1SUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYm1WM1ZtRnNkV1VnUFNCZmNISnZaM0psYzNObFpDaDJZV3gxWlNrN1hHNGdJQ0FnSUNBZ0lIMGdZMkYwWTJnZ0tHVXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbVYzSUQwZ2RISjFaVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2hSTG05dVpYSnliM0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCUkxtOXVaWEp5YjNJb1pTazdYRzRnSUNBZ0lDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhSb2NtOTNJR1U3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCcFppQW9JWFJvY21WM0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1dWIzUnBabmtvYm1WM1ZtRnNkV1VwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlYwcE8xeHVYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OU8xeHVYRzVSTG5SaGNDQTlJR1oxYm1OMGFXOXVJQ2h3Y205dGFYTmxMQ0JqWVd4c1ltRmpheWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLSEJ5YjIxcGMyVXBMblJoY0NoallXeHNZbUZqYXlrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZkdmNtdHpJR0ZzYlc5emRDQnNhV3RsSUZ3aVptbHVZV3hzZVZ3aUxDQmlkWFFnYm05MElHTmhiR3hsWkNCbWIzSWdjbVZxWldOMGFXOXVjeTVjYmlBcUlFOXlhV2RwYm1Gc0lISmxjMjlzZFhScGIyNGdkbUZzZFdVZ2FYTWdjR0Z6YzJWa0lIUm9jbTkxWjJnZ1kyRnNiR0poWTJzZ2RXNWhabVpsWTNSbFpDNWNiaUFxSUVOaGJHeGlZV05ySUcxaGVTQnlaWFIxY200Z1lTQndjbTl0YVhObElIUm9ZWFFnZDJsc2JDQmlaU0JoZDJGcGRHVmtJR1p2Y2k1Y2JpQXFJRUJ3WVhKaGJTQjdSblZ1WTNScGIyNTlJR05oYkd4aVlXTnJYRzRnS2lCQWNtVjBkWEp1Y3lCN1VTNVFjbTl0YVhObGZWeHVJQ29nUUdWNFlXMXdiR1ZjYmlBcUlHUnZVMjl0WlhSb2FXNW5LQ2xjYmlBcUlDQWdMblJvWlc0b0xpNHVLVnh1SUNvZ0lDQXVkR0Z3S0dOdmJuTnZiR1V1Ykc5bktWeHVJQ29nSUNBdWRHaGxiaWd1TGk0cE8xeHVJQ292WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MFlYQWdQU0JtZFc1amRHbHZiaUFvWTJGc2JHSmhZMnNwSUh0Y2JpQWdJQ0JqWVd4c1ltRmpheUE5SUZFb1kyRnNiR0poWTJzcE8xeHVYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVkR2hsYmlobWRXNWpkR2x2YmlBb2RtRnNkV1VwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yTG1aallXeHNLSFpoYkhWbEtTNTBhR1Z1VW1WemIyeDJaU2gyWVd4MVpTazdYRzRnSUNBZ2ZTazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxaMmx6ZEdWeWN5QmhiaUJ2WW5ObGNuWmxjaUJ2YmlCaElIQnliMjFwYzJVdVhHNGdLbHh1SUNvZ1IzVmhjbUZ1ZEdWbGN6cGNiaUFxWEc0Z0tpQXhMaUIwYUdGMElHWjFiR1pwYkd4bFpDQmhibVFnY21WcVpXTjBaV1FnZDJsc2JDQmlaU0JqWVd4c1pXUWdiMjVzZVNCdmJtTmxMbHh1SUNvZ01pNGdkR2hoZENCbGFYUm9aWElnZEdobElHWjFiR1pwYkd4bFpDQmpZV3hzWW1GamF5QnZjaUIwYUdVZ2NtVnFaV04wWldRZ1kyRnNiR0poWTJzZ2QybHNiQ0JpWlZ4dUlDb2dJQ0FnWTJGc2JHVmtMQ0JpZFhRZ2JtOTBJR0p2ZEdndVhHNGdLaUF6TGlCMGFHRjBJR1oxYkdacGJHeGxaQ0JoYm1RZ2NtVnFaV04wWldRZ2QybHNiQ0J1YjNRZ1ltVWdZMkZzYkdWa0lHbHVJSFJvYVhNZ2RIVnliaTVjYmlBcVhHNGdLaUJBY0dGeVlXMGdkbUZzZFdVZ0lDQWdJQ0J3Y205dGFYTmxJRzl5SUdsdGJXVmthV0YwWlNCeVpXWmxjbVZ1WTJVZ2RHOGdiMkp6WlhKMlpWeHVJQ29nUUhCaGNtRnRJR1oxYkdacGJHeGxaQ0FnWm5WdVkzUnBiMjRnZEc4Z1ltVWdZMkZzYkdWa0lIZHBkR2dnZEdobElHWjFiR1pwYkd4bFpDQjJZV3gxWlZ4dUlDb2dRSEJoY21GdElISmxhbVZqZEdWa0lDQWdablZ1WTNScGIyNGdkRzhnWW1VZ1kyRnNiR1ZrSUhkcGRHZ2dkR2hsSUhKbGFtVmpkR2x2YmlCbGVHTmxjSFJwYjI1Y2JpQXFJRUJ3WVhKaGJTQndjbTluY21WemMyVmtJR1oxYm1OMGFXOXVJSFJ2SUdKbElHTmhiR3hsWkNCdmJpQmhibmtnY0hKdlozSmxjM01nYm05MGFXWnBZMkYwYVc5dWMxeHVJQ29nUUhKbGRIVnliaUJ3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsSUdaeWIyMGdkR2hsSUdsdWRtOXJaV1FnWTJGc2JHSmhZMnRjYmlBcUwxeHVVUzUzYUdWdUlEMGdkMmhsYmp0Y2JtWjFibU4wYVc5dUlIZG9aVzRvZG1Gc2RXVXNJR1oxYkdacGJHeGxaQ3dnY21WcVpXTjBaV1FzSUhCeWIyZHlaWE56WldRcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNoMllXeDFaU2t1ZEdobGJpaG1kV3htYVd4c1pXUXNJSEpsYW1WamRHVmtMQ0J3Y205bmNtVnpjMlZrS1R0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1ZEdobGJsSmxjMjlzZG1VZ1BTQm1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NTBhR1Z1S0daMWJtTjBhVzl1SUNncElIc2djbVYwZFhKdUlIWmhiSFZsT3lCOUtUdGNibjA3WEc1Y2JsRXVkR2hsYmxKbGMyOXNkbVVnUFNCbWRXNWpkR2x2YmlBb2NISnZiV2x6WlN3Z2RtRnNkV1VwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h3Y205dGFYTmxLUzUwYUdWdVVtVnpiMngyWlNoMllXeDFaU2s3WEc1OU8xeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzUwYUdWdVVtVnFaV04wSUQwZ1puVnVZM1JwYjI0Z0tISmxZWE52YmlrZ2UxeHVJQ0FnSUhKbGRIVnliaUIwYUdsekxuUm9aVzRvWm5WdVkzUnBiMjRnS0NrZ2V5QjBhSEp2ZHlCeVpXRnpiMjQ3SUgwcE8xeHVmVHRjYmx4dVVTNTBhR1Z1VW1WcVpXTjBJRDBnWm5WdVkzUnBiMjRnS0hCeWIyMXBjMlVzSUhKbFlYTnZiaWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLSEJ5YjIxcGMyVXBMblJvWlc1U1pXcGxZM1FvY21WaGMyOXVLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dTV1lnWVc0Z2IySnFaV04wSUdseklHNXZkQ0JoSUhCeWIyMXBjMlVzSUdsMElHbHpJR0Z6SUZ3aWJtVmhjbHdpSUdGeklIQnZjM05wWW14bExseHVJQ29nU1dZZ1lTQndjbTl0YVhObElHbHpJSEpsYW1WamRHVmtMQ0JwZENCcGN5QmhjeUJjSW01bFlYSmNJaUJoY3lCd2IzTnphV0pzWlNCMGIyOHVYRzRnS2lCSlppQnBkT0tBbVhNZ1lTQm1kV3htYVd4c1pXUWdjSEp2YldselpTd2dkR2hsSUdaMWJHWnBiR3h0Wlc1MElIWmhiSFZsSUdseklHNWxZWEpsY2k1Y2JpQXFJRWxtSUdsMDRvQ1pjeUJoSUdSbFptVnljbVZrSUhCeWIyMXBjMlVnWVc1a0lIUm9aU0JrWldabGNuSmxaQ0JvWVhNZ1ltVmxiaUJ5WlhOdmJIWmxaQ3dnZEdobFhHNGdLaUJ5WlhOdmJIVjBhVzl1SUdseklGd2libVZoY21WeVhDSXVYRzRnS2lCQWNHRnlZVzBnYjJKcVpXTjBYRzRnS2lCQWNtVjBkWEp1Y3lCdGIzTjBJSEpsYzI5c2RtVmtJQ2h1WldGeVpYTjBLU0JtYjNKdElHOW1JSFJvWlNCdlltcGxZM1JjYmlBcUwxeHVYRzR2THlCWVdGZ2djMmh2ZFd4a0lIZGxJSEpsTFdSdklIUm9hWE0vWEc1UkxtNWxZWEpsY2lBOUlHNWxZWEpsY2p0Y2JtWjFibU4wYVc5dUlHNWxZWEpsY2loMllXeDFaU2tnZTF4dUlDQWdJR2xtSUNocGMxQnliMjFwYzJVb2RtRnNkV1VwS1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJwYm5Od1pXTjBaV1FnUFNCMllXeDFaUzVwYm5Od1pXTjBLQ2s3WEc0Z0lDQWdJQ0FnSUdsbUlDaHBibk53WldOMFpXUXVjM1JoZEdVZ1BUMDlJRndpWm5Wc1ptbHNiR1ZrWENJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJwYm5Od1pXTjBaV1F1ZG1Gc2RXVTdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUhaaGJIVmxPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSEJ5YjIxcGMyVXVYRzRnS2lCUGRHaGxjbmRwYzJVZ2FYUWdhWE1nWVNCbWRXeG1hV3hzWldRZ2RtRnNkV1V1WEc0Z0tpOWNibEV1YVhOUWNtOXRhWE5sSUQwZ2FYTlFjbTl0YVhObE8xeHVablZ1WTNScGIyNGdhWE5RY205dGFYTmxLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCdlltcGxZM1FnYVc1emRHRnVZMlZ2WmlCUWNtOXRhWE5sTzF4dWZWeHVYRzVSTG1selVISnZiV2x6WlVGc2FXdGxJRDBnYVhOUWNtOXRhWE5sUVd4cGEyVTdYRzVtZFc1amRHbHZiaUJwYzFCeWIyMXBjMlZCYkdsclpTaHZZbXBsWTNRcElIdGNiaUFnSUNCeVpYUjFjbTRnYVhOUFltcGxZM1FvYjJKcVpXTjBLU0FtSmlCMGVYQmxiMllnYjJKcVpXTjBMblJvWlc0Z1BUMDlJRndpWm5WdVkzUnBiMjVjSWp0Y2JuMWNibHh1THlvcVhHNGdLaUJBY21WMGRYSnVjeUIzYUdWMGFHVnlJSFJvWlNCbmFYWmxiaUJ2WW1wbFkzUWdhWE1nWVNCd1pXNWthVzVuSUhCeWIyMXBjMlVzSUcxbFlXNXBibWNnYm05MFhHNGdLaUJtZFd4bWFXeHNaV1FnYjNJZ2NtVnFaV04wWldRdVhHNGdLaTljYmxFdWFYTlFaVzVrYVc1bklEMGdhWE5RWlc1a2FXNW5PMXh1Wm5WdVkzUnBiMjRnYVhOUVpXNWthVzVuS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQnBjMUJ5YjIxcGMyVW9iMkpxWldOMEtTQW1KaUJ2WW1wbFkzUXVhVzV6Y0dWamRDZ3BMbk4wWVhSbElEMDlQU0JjSW5CbGJtUnBibWRjSWp0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1YVhOUVpXNWthVzVuSUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbWx1YzNCbFkzUW9LUzV6ZEdGMFpTQTlQVDBnWENKd1pXNWthVzVuWENJN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVCeVpYUjFjbTV6SUhkb1pYUm9aWElnZEdobElHZHBkbVZ1SUc5aWFtVmpkQ0JwY3lCaElIWmhiSFZsSUc5eUlHWjFiR1pwYkd4bFpGeHVJQ29nY0hKdmJXbHpaUzVjYmlBcUwxeHVVUzVwYzBaMWJHWnBiR3hsWkNBOUlHbHpSblZzWm1sc2JHVmtPMXh1Wm5WdVkzUnBiMjRnYVhOR2RXeG1hV3hzWldRb2IySnFaV04wS1NCN1hHNGdJQ0FnY21WMGRYSnVJQ0ZwYzFCeWIyMXBjMlVvYjJKcVpXTjBLU0I4ZkNCdlltcGxZM1F1YVc1emNHVmpkQ2dwTG5OMFlYUmxJRDA5UFNCY0ltWjFiR1pwYkd4bFpGd2lPMXh1ZlZ4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXBjMFoxYkdacGJHeGxaQ0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NXBibk53WldOMEtDa3VjM1JoZEdVZ1BUMDlJRndpWm5Wc1ptbHNiR1ZrWENJN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVCeVpYUjFjbTV6SUhkb1pYUm9aWElnZEdobElHZHBkbVZ1SUc5aWFtVmpkQ0JwY3lCaElISmxhbVZqZEdWa0lIQnliMjFwYzJVdVhHNGdLaTljYmxFdWFYTlNaV3BsWTNSbFpDQTlJR2x6VW1WcVpXTjBaV1E3WEc1bWRXNWpkR2x2YmlCcGMxSmxhbVZqZEdWa0tHOWlhbVZqZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUJwYzFCeWIyMXBjMlVvYjJKcVpXTjBLU0FtSmlCdlltcGxZM1F1YVc1emNHVmpkQ2dwTG5OMFlYUmxJRDA5UFNCY0luSmxhbVZqZEdWa1hDSTdYRzU5WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtbHpVbVZxWldOMFpXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbkpsYW1WamRHVmtYQ0k3WEc1OU8xeHVYRzR2THk4dklFSkZSMGxPSUZWT1NFRk9SRXhGUkNCU1JVcEZRMVJKVDA0Z1ZGSkJRMHRKVGtkY2JseHVMeThnVkdocGN5QndjbTl0YVhObElHeHBZbkpoY25rZ1kyOXVjM1Z0WlhNZ1pYaGpaWEIwYVc5dWN5QjBhSEp2ZDI0Z2FXNGdhR0Z1Wkd4bGNuTWdjMjhnZEdobGVTQmpZVzRnWW1WY2JpOHZJR2hoYm1Sc1pXUWdZbmtnWVNCemRXSnpaWEYxWlc1MElIQnliMjFwYzJVdUlDQlVhR1VnWlhoalpYQjBhVzl1Y3lCblpYUWdZV1JrWldRZ2RHOGdkR2hwY3lCaGNuSmhlU0IzYUdWdVhHNHZMeUIwYUdWNUlHRnlaU0JqY21WaGRHVmtMQ0JoYm1RZ2NtVnRiM1psWkNCM2FHVnVJSFJvWlhrZ1lYSmxJR2hoYm1Sc1pXUXVJQ0JPYjNSbElIUm9ZWFFnYVc0Z1JWTTJJRzl5WEc0dkx5QnphR2x0YldWa0lHVnVkbWx5YjI1dFpXNTBjeXdnZEdocGN5QjNiM1ZzWkNCdVlYUjFjbUZzYkhrZ1ltVWdZU0JnVTJWMFlDNWNiblpoY2lCMWJtaGhibVJzWldSU1pXRnpiMjV6SUQwZ1cxMDdYRzUyWVhJZ2RXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5QTlJRnRkTzF4dWRtRnlJSEpsY0c5eWRHVmtWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeUE5SUZ0ZE8xeHVkbUZ5SUhSeVlXTnJWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeUE5SUhSeWRXVTdYRzVjYm1aMWJtTjBhVzl1SUhKbGMyVjBWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeWdwSUh0Y2JpQWdJQ0IxYm1oaGJtUnNaV1JTWldGemIyNXpMbXhsYm1kMGFDQTlJREE3WEc0Z0lDQWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeTVzWlc1bmRHZ2dQU0F3TzF4dVhHNGdJQ0FnYVdZZ0tDRjBjbUZqYTFWdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ym5NcElIdGNiaUFnSUNBZ0lDQWdkSEpoWTJ0VmJtaGhibVJzWldSU1pXcGxZM1JwYjI1eklEMGdkSEoxWlR0Y2JpQWdJQ0I5WEc1OVhHNWNibVoxYm1OMGFXOXVJSFJ5WVdOclVtVnFaV04wYVc5dUtIQnliMjFwYzJVc0lISmxZWE52YmlrZ2UxeHVJQ0FnSUdsbUlDZ2hkSEpoWTJ0VmJtaGhibVJzWldSU1pXcGxZM1JwYjI1ektTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJqdGNiaUFnSUNCOVhHNGdJQ0FnYVdZZ0tIUjVjR1Z2WmlCd2NtOWpaWE56SUQwOVBTQmNJbTlpYW1WamRGd2lJQ1ltSUhSNWNHVnZaaUJ3Y205alpYTnpMbVZ0YVhRZ1BUMDlJRndpWm5WdVkzUnBiMjVjSWlrZ2UxeHVJQ0FnSUNBZ0lDQlJMbTVsZUhSVWFXTnJMbkoxYmtGbWRHVnlLR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoaGNuSmhlVjlwYm1SbGVFOW1LSFZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1zSUhCeWIyMXBjMlVwSUNFOVBTQXRNU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhCeWIyTmxjM011WlcxcGRDaGNJblZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibHdpTENCeVpXRnpiMjRzSUhCeWIyMXBjMlVwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3k1d2RYTm9LSEJ5YjIxcGMyVXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQjFibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpMbkIxYzJnb2NISnZiV2x6WlNrN1hHNGdJQ0FnYVdZZ0tISmxZWE52YmlBbUppQjBlWEJsYjJZZ2NtVmhjMjl1TG5OMFlXTnJJQ0U5UFNCY0luVnVaR1ZtYVc1bFpGd2lLU0I3WEc0Z0lDQWdJQ0FnSUhWdWFHRnVaR3hsWkZKbFlYTnZibk11Y0hWemFDaHlaV0Z6YjI0dWMzUmhZMnNwTzF4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJSFZ1YUdGdVpHeGxaRkpsWVhOdmJuTXVjSFZ6YUNoY0lpaHVieUJ6ZEdGamF5a2dYQ0lnS3lCeVpXRnpiMjRwTzF4dUlDQWdJSDFjYm4xY2JseHVablZ1WTNScGIyNGdkVzUwY21GamExSmxhbVZqZEdsdmJpaHdjbTl0YVhObEtTQjdYRzRnSUNBZ2FXWWdLQ0YwY21GamExVnVhR0Z1Wkd4bFpGSmxhbVZqZEdsdmJuTXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIWmhjaUJoZENBOUlHRnljbUY1WDJsdVpHVjRUMllvZFc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3l3Z2NISnZiV2x6WlNrN1hHNGdJQ0FnYVdZZ0tHRjBJQ0U5UFNBdE1Ta2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2RIbHdaVzltSUhCeWIyTmxjM01nUFQwOUlGd2liMkpxWldOMFhDSWdKaVlnZEhsd1pXOW1JSEJ5YjJObGMzTXVaVzFwZENBOVBUMGdYQ0ptZFc1amRHbHZibHdpS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JSTG01bGVIUlVhV05yTG5KMWJrRm1kR1Z5S0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjJZWElnWVhSU1pYQnZjblFnUFNCaGNuSmhlVjlwYm1SbGVFOW1LSEpsY0c5eWRHVmtWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeXdnY0hKdmJXbHpaU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHRjBVbVZ3YjNKMElDRTlQU0F0TVNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205alpYTnpMbVZ0YVhRb1hDSnlaV3BsWTNScGIyNUlZVzVrYkdWa1hDSXNJSFZ1YUdGdVpHeGxaRkpsWVhOdmJuTmJZWFJkTENCd2NtOXRhWE5sS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVZ3YjNKMFpXUlZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpMbk53YkdsalpTaGhkRkpsY0c5eWRDd2dNU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2RXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5NXpjR3hwWTJVb1lYUXNJREVwTzF4dUlDQWdJQ0FnSUNCMWJtaGhibVJzWldSU1pXRnpiMjV6TG5Od2JHbGpaU2hoZEN3Z01TazdYRzRnSUNBZ2ZWeHVmVnh1WEc1UkxuSmxjMlYwVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlISmxjMlYwVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3p0Y2JseHVVUzVuWlhSVmJtaGhibVJzWldSU1pXRnpiMjV6SUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDOHZJRTFoYTJVZ1lTQmpiM0I1SUhOdklIUm9ZWFFnWTI5dWMzVnRaWEp6SUdOaGJpZDBJR2x1ZEdWeVptVnlaU0IzYVhSb0lHOTFjaUJwYm5SbGNtNWhiQ0J6ZEdGMFpTNWNiaUFnSUNCeVpYUjFjbTRnZFc1b1lXNWtiR1ZrVW1WaGMyOXVjeTV6YkdsalpTZ3BPMXh1ZlR0Y2JseHVVUzV6ZEc5d1ZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dVZISmhZMnRwYm1jZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdjbVZ6WlhSVmJtaGhibVJzWldSU1pXcGxZM1JwYjI1ektDazdYRzRnSUNBZ2RISmhZMnRWYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6SUQwZ1ptRnNjMlU3WEc1OU8xeHVYRzV5WlhObGRGVnVhR0Z1Wkd4bFpGSmxhbVZqZEdsdmJuTW9LVHRjYmx4dUx5OHZMeUJGVGtRZ1ZVNUlRVTVFVEVWRUlGSkZTa1ZEVkVsUFRpQlVVa0ZEUzBsT1IxeHVYRzR2S2lwY2JpQXFJRU52Ym5OMGNuVmpkSE1nWVNCeVpXcGxZM1JsWkNCd2NtOXRhWE5sTGx4dUlDb2dRSEJoY21GdElISmxZWE52YmlCMllXeDFaU0JrWlhOamNtbGlhVzVuSUhSb1pTQm1ZV2xzZFhKbFhHNGdLaTljYmxFdWNtVnFaV04wSUQwZ2NtVnFaV04wTzF4dVpuVnVZM1JwYjI0Z2NtVnFaV04wS0hKbFlYTnZiaWtnZTF4dUlDQWdJSFpoY2lCeVpXcGxZM1JwYjI0Z1BTQlFjbTl0YVhObEtIdGNiaUFnSUNBZ0lDQWdYQ0ozYUdWdVhDSTZJR1oxYm1OMGFXOXVJQ2h5WldwbFkzUmxaQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdMeThnYm05MFpTQjBhR0YwSUhSb1pTQmxjbkp2Y2lCb1lYTWdZbVZsYmlCb1lXNWtiR1ZrWEc0Z0lDQWdJQ0FnSUNBZ0lDQnBaaUFvY21WcVpXTjBaV1FwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMWJuUnlZV05yVW1WcVpXTjBhVzl1S0hSb2FYTXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYW1WamRHVmtJRDhnY21WcVpXTjBaV1FvY21WaGMyOXVLU0E2SUhSb2FYTTdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlMQ0JtZFc1amRHbHZiaUJtWVd4c1ltRmpheWdwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhSb2FYTTdYRzRnSUNBZ2ZTd2dablZ1WTNScGIyNGdhVzV6Y0dWamRDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSHNnYzNSaGRHVTZJRndpY21WcVpXTjBaV1JjSWl3Z2NtVmhjMjl1T2lCeVpXRnpiMjRnZlR0Y2JpQWdJQ0I5S1R0Y2JseHVJQ0FnSUM4dklFNXZkR1VnZEdoaGRDQjBhR1VnY21WaGMyOXVJR2hoY3lCdWIzUWdZbVZsYmlCb1lXNWtiR1ZrTGx4dUlDQWdJSFJ5WVdOclVtVnFaV04wYVc5dUtISmxhbVZqZEdsdmJpd2djbVZoYzI5dUtUdGNibHh1SUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1JwYjI0N1hHNTlYRzVjYmk4cUtseHVJQ29nUTI5dWMzUnlkV04wY3lCaElHWjFiR1pwYkd4bFpDQndjbTl0YVhObElHWnZjaUJoYmlCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObExseHVJQ29nUUhCaGNtRnRJSFpoYkhWbElHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVmNiaUFxTDF4dVVTNW1kV3htYVd4c0lEMGdablZzWm1sc2JEdGNibVoxYm1OMGFXOXVJR1oxYkdacGJHd29kbUZzZFdVcElIdGNiaUFnSUNCeVpYUjFjbTRnVUhKdmJXbHpaU2g3WEc0Z0lDQWdJQ0FnSUZ3aWQyaGxibHdpT2lCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnZG1Gc2RXVTdYRzRnSUNBZ0lDQWdJSDBzWEc0Z0lDQWdJQ0FnSUZ3aVoyVjBYQ0k2SUdaMWJtTjBhVzl1SUNodVlXMWxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1ZiYm1GdFpWMDdYRzRnSUNBZ0lDQWdJSDBzWEc0Z0lDQWdJQ0FnSUZ3aWMyVjBYQ0k2SUdaMWJtTjBhVzl1SUNodVlXMWxMQ0J5YUhNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhaaGJIVmxXMjVoYldWZElEMGdjbWh6TzF4dUlDQWdJQ0FnSUNCOUxGeHVJQ0FnSUNBZ0lDQmNJbVJsYkdWMFpWd2lPaUJtZFc1amRHbHZiaUFvYm1GdFpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pHVnNaWFJsSUhaaGJIVmxXMjVoYldWZE8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW5CdmMzUmNJam9nWm5WdVkzUnBiMjRnS0c1aGJXVXNJR0Z5WjNNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUM4dklFMWhjbXNnVFdsc2JHVnlJSEJ5YjNCdmMyVnpJSFJvWVhRZ2NHOXpkQ0IzYVhSb0lHNXZJRzVoYldVZ2MyaHZkV3hrSUdGd2NHeDVJR0ZjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJSEJ5YjIxcGMyVmtJR1oxYm1OMGFXOXVMbHh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLRzVoYldVZ1BUMDlJRzUxYkd3Z2ZId2dibUZ0WlNBOVBUMGdkbTlwWkNBd0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIWmhiSFZsTG1Gd2NHeDVLSFp2YVdRZ01Dd2dZWEpuY3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjJZV3gxWlZ0dVlXMWxYUzVoY0hCc2VTaDJZV3gxWlN3Z1lYSm5jeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSDBzWEc0Z0lDQWdJQ0FnSUZ3aVlYQndiSGxjSWpvZ1puVnVZM1JwYjI0Z0tIUm9hWE53TENCaGNtZHpLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1V1WVhCd2JIa29kR2hwYzNBc0lHRnlaM01wTzF4dUlDQWdJQ0FnSUNCOUxGeHVJQ0FnSUNBZ0lDQmNJbXRsZVhOY0lqb2dablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlHOWlhbVZqZEY5clpYbHpLSFpoYkhWbEtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMHNJSFp2YVdRZ01Dd2dablZ1WTNScGIyNGdhVzV6Y0dWamRDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSHNnYzNSaGRHVTZJRndpWm5Wc1ptbHNiR1ZrWENJc0lIWmhiSFZsT2lCMllXeDFaU0I5TzF4dUlDQWdJSDBwTzF4dWZWeHVYRzR2S2lwY2JpQXFJRU52Ym5abGNuUnpJSFJvWlc1aFlteGxjeUIwYnlCUklIQnliMjFwYzJWekxseHVJQ29nUUhCaGNtRnRJSEJ5YjIxcGMyVWdkR2hsYm1GaWJHVWdjSEp2YldselpWeHVJQ29nUUhKbGRIVnlibk1nWVNCUklIQnliMjFwYzJWY2JpQXFMMXh1Wm5WdVkzUnBiMjRnWTI5bGNtTmxLSEJ5YjIxcGMyVXBJSHRjYmlBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJRkV1Ym1WNGRGUnBZMnNvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTNTBhR1Z1S0dSbFptVnljbVZrTG5KbGMyOXNkbVVzSUdSbFptVnljbVZrTG5KbGFtVmpkQ3dnWkdWbVpYSnlaV1F1Ym05MGFXWjVLVHRjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WldwbFkzUW9aWGhqWlhCMGFXOXVLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDBwTzF4dUlDQWdJSEpsZEhWeWJpQmtaV1psY25KbFpDNXdjbTl0YVhObE8xeHVmVnh1WEc0dktpcGNiaUFxSUVGdWJtOTBZWFJsY3lCaGJpQnZZbXBsWTNRZ2MzVmphQ0IwYUdGMElHbDBJSGRwYkd3Z2JtVjJaWElnWW1WY2JpQXFJSFJ5WVc1elptVnljbVZrSUdGM1lYa2dabkp2YlNCMGFHbHpJSEJ5YjJObGMzTWdiM1psY2lCaGJua2djSEp2YldselpWeHVJQ29nWTI5dGJYVnVhV05oZEdsdmJpQmphR0Z1Ym1Wc0xseHVJQ29nUUhCaGNtRnRJRzlpYW1WamRGeHVJQ29nUUhKbGRIVnlibk1nY0hKdmJXbHpaU0JoSUhkeVlYQndhVzVuSUc5bUlIUm9ZWFFnYjJKcVpXTjBJSFJvWVhSY2JpQXFJR0ZrWkdsMGFXOXVZV3hzZVNCeVpYTndiMjVrY3lCMGJ5QjBhR1VnWENKcGMwUmxabHdpSUcxbGMzTmhaMlZjYmlBcUlIZHBkR2h2ZFhRZ1lTQnlaV3BsWTNScGIyNHVYRzRnS2k5Y2JsRXViV0Z6ZEdWeUlEMGdiV0Z6ZEdWeU8xeHVablZ1WTNScGIyNGdiV0Z6ZEdWeUtHOWlhbVZqZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUJRY205dGFYTmxLSHRjYmlBZ0lDQWdJQ0FnWENKcGMwUmxabHdpT2lCbWRXNWpkR2x2YmlBb0tTQjdmVnh1SUNBZ0lIMHNJR1oxYm1OMGFXOXVJR1poYkd4aVlXTnJLRzl3TENCaGNtZHpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJrYVhOd1lYUmphQ2h2WW1wbFkzUXNJRzl3TENCaGNtZHpLVHRjYmlBZ0lDQjlMQ0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdWFXNXpjR1ZqZENncE8xeHVJQ0FnSUgwcE8xeHVmVnh1WEc0dktpcGNiaUFxSUZOd2NtVmhaSE1nZEdobElIWmhiSFZsY3lCdlppQmhJSEJ5YjIxcGMyVmtJR0Z5Y21GNUlHOW1JR0Z5WjNWdFpXNTBjeUJwYm5SdklIUm9aVnh1SUNvZ1puVnNabWxzYkcxbGJuUWdZMkZzYkdKaFkyc3VYRzRnS2lCQWNHRnlZVzBnWm5Wc1ptbHNiR1ZrSUdOaGJHeGlZV05ySUhSb1lYUWdjbVZqWldsMlpYTWdkbUZ5YVdGa2FXTWdZWEpuZFcxbGJuUnpJR1p5YjIwZ2RHaGxYRzRnS2lCd2NtOXRhWE5sWkNCaGNuSmhlVnh1SUNvZ1FIQmhjbUZ0SUhKbGFtVmpkR1ZrSUdOaGJHeGlZV05ySUhSb1lYUWdjbVZqWldsMlpYTWdkR2hsSUdWNFkyVndkR2x2YmlCcFppQjBhR1VnY0hKdmJXbHpaVnh1SUNvZ2FYTWdjbVZxWldOMFpXUXVYRzRnS2lCQWNtVjBkWEp1Y3lCaElIQnliMjFwYzJVZ1ptOXlJSFJvWlNCeVpYUjFjbTRnZG1Gc2RXVWdiM0lnZEdoeWIzZHVJR1Y0WTJWd2RHbHZiaUJ2Wmx4dUlDb2daV2wwYUdWeUlHTmhiR3hpWVdOckxseHVJQ292WEc1UkxuTndjbVZoWkNBOUlITndjbVZoWkR0Y2JtWjFibU4wYVc5dUlITndjbVZoWkNoMllXeDFaU3dnWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0haaGJIVmxLUzV6Y0hKbFlXUW9ablZzWm1sc2JHVmtMQ0J5WldwbFkzUmxaQ2s3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbk53Y21WaFpDQTlJR1oxYm1OMGFXOXVJQ2htZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdVlXeHNLQ2t1ZEdobGJpaG1kVzVqZEdsdmJpQW9ZWEp5WVhrcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHWjFiR1pwYkd4bFpDNWhjSEJzZVNoMmIybGtJREFzSUdGeWNtRjVLVHRjYmlBZ0lDQjlMQ0J5WldwbFkzUmxaQ2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRlJvWlNCaGMzbHVZeUJtZFc1amRHbHZiaUJwY3lCaElHUmxZMjl5WVhSdmNpQm1iM0lnWjJWdVpYSmhkRzl5SUdaMWJtTjBhVzl1Y3l3Z2RIVnlibWx1WjF4dUlDb2dkR2hsYlNCcGJuUnZJR0Z6ZVc1amFISnZibTkxY3lCblpXNWxjbUYwYjNKekxpQWdRV3gwYUc5MVoyZ2daMlZ1WlhKaGRHOXljeUJoY21VZ2IyNXNlU0J3WVhKMFhHNGdLaUJ2WmlCMGFHVWdibVYzWlhOMElFVkRUVUZUWTNKcGNIUWdOaUJrY21GbWRITXNJSFJvYVhNZ1kyOWtaU0JrYjJWeklHNXZkQ0JqWVhWelpTQnplVzUwWVhoY2JpQXFJR1Z5Y205eWN5QnBiaUJ2YkdSbGNpQmxibWRwYm1WekxpQWdWR2hwY3lCamIyUmxJSE5vYjNWc1pDQmpiMjUwYVc1MVpTQjBieUIzYjNKcklHRnVaQ0IzYVd4c1hHNGdLaUJwYmlCbVlXTjBJR2x0Y0hKdmRtVWdiM1psY2lCMGFXMWxJR0Z6SUhSb1pTQnNZVzVuZFdGblpTQnBiWEJ5YjNabGN5NWNiaUFxWEc0Z0tpQkZVellnWjJWdVpYSmhkRzl5Y3lCaGNtVWdZM1Z5Y21WdWRHeDVJSEJoY25RZ2IyWWdWamdnZG1WeWMybHZiaUF6TGpFNUlIZHBkR2dnZEdobFhHNGdLaUF0TFdoaGNtMXZibmt0WjJWdVpYSmhkRzl5Y3lCeWRXNTBhVzFsSUdac1lXY2daVzVoWW14bFpDNGdJRk53YVdSbGNrMXZibXRsZVNCb1lYTWdhR0ZrSUhSb1pXMWNiaUFxSUdadmNpQnNiMjVuWlhJc0lHSjFkQ0IxYm1SbGNpQmhiaUJ2YkdSbGNpQlFlWFJvYjI0dGFXNXpjR2x5WldRZ1ptOXliUzRnSUZSb2FYTWdablZ1WTNScGIyNWNiaUFxSUhkdmNtdHpJRzl1SUdKdmRHZ2dhMmx1WkhNZ2IyWWdaMlZ1WlhKaGRHOXljeTVjYmlBcVhHNGdLaUJFWldOdmNtRjBaWE1nWVNCblpXNWxjbUYwYjNJZ1puVnVZM1JwYjI0Z2MzVmphQ0IwYUdGME9seHVJQ29nSUMwZ2FYUWdiV0Y1SUhscFpXeGtJSEJ5YjIxcGMyVnpYRzRnS2lBZ0xTQmxlR1ZqZFhScGIyNGdkMmxzYkNCamIyNTBhVzUxWlNCM2FHVnVJSFJvWVhRZ2NISnZiV2x6WlNCcGN5Qm1kV3htYVd4c1pXUmNiaUFxSUNBdElIUm9aU0IyWVd4MVpTQnZaaUIwYUdVZ2VXbGxiR1FnWlhod2NtVnpjMmx2YmlCM2FXeHNJR0psSUhSb1pTQm1kV3htYVd4c1pXUWdkbUZzZFdWY2JpQXFJQ0F0SUdsMElISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJQ2gzYUdWdUlIUm9aU0JuWlc1bGNtRjBiM0pjYmlBcUlDQWdJSE4wYjNCeklHbDBaWEpoZEdsdVp5bGNiaUFxSUNBdElIUm9aU0JrWldOdmNtRjBaV1FnWm5WdVkzUnBiMjRnY21WMGRYSnVjeUJoSUhCeWIyMXBjMlVnWm05eUlIUm9aU0J5WlhSMWNtNGdkbUZzZFdWY2JpQXFJQ0FnSUc5bUlIUm9aU0JuWlc1bGNtRjBiM0lnYjNJZ2RHaGxJR1pwY25OMElISmxhbVZqZEdWa0lIQnliMjFwYzJVZ1lXMXZibWNnZEdodmMyVmNiaUFxSUNBZ0lIbHBaV3hrWldRdVhHNGdLaUFnTFNCcFppQmhiaUJsY25KdmNpQnBjeUIwYUhKdmQyNGdhVzRnZEdobElHZGxibVZ5WVhSdmNpd2dhWFFnY0hKdmNHRm5ZWFJsY3lCMGFISnZkV2RvWEc0Z0tpQWdJQ0JsZG1WeWVTQm1iMnhzYjNkcGJtY2dlV2xsYkdRZ2RXNTBhV3dnYVhRZ2FYTWdZMkYxWjJoMExDQnZjaUIxYm5ScGJDQnBkQ0JsYzJOaGNHVnpYRzRnS2lBZ0lDQjBhR1VnWjJWdVpYSmhkRzl5SUdaMWJtTjBhVzl1SUdGc2RHOW5aWFJvWlhJc0lHRnVaQ0JwY3lCMGNtRnVjMnhoZEdWa0lHbHVkRzhnWVZ4dUlDb2dJQ0FnY21WcVpXTjBhVzl1SUdadmNpQjBhR1VnY0hKdmJXbHpaU0J5WlhSMWNtNWxaQ0JpZVNCMGFHVWdaR1ZqYjNKaGRHVmtJR2RsYm1WeVlYUnZjaTVjYmlBcUwxeHVVUzVoYzNsdVl5QTlJR0Z6ZVc1ak8xeHVablZ1WTNScGIyNGdZWE41Ym1Nb2JXRnJaVWRsYm1WeVlYUnZjaWtnZTF4dUlDQWdJSEpsZEhWeWJpQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUM4dklIZG9aVzRnZG1WeVlpQnBjeUJjSW5ObGJtUmNJaXdnWVhKbklHbHpJR0VnZG1Gc2RXVmNiaUFnSUNBZ0lDQWdMeThnZDJobGJpQjJaWEppSUdseklGd2lkR2h5YjNkY0lpd2dZWEpuSUdseklHRnVJR1Y0WTJWd2RHbHZibHh1SUNBZ0lDQWdJQ0JtZFc1amRHbHZiaUJqYjI1MGFXNTFaWElvZG1WeVlpd2dZWEpuS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IyWVhJZ2NtVnpkV3gwTzF4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCVmJuUnBiQ0JXT0NBekxqRTVJQzhnUTJoeWIyMXBkVzBnTWprZ2FYTWdjbVZzWldGelpXUXNJRk53YVdSbGNrMXZibXRsZVNCcGN5QjBhR1VnYjI1c2VWeHVJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z1pXNW5hVzVsSUhSb1lYUWdhR0Z6SUdFZ1pHVndiRzk1WldRZ1ltRnpaU0J2WmlCaWNtOTNjMlZ5Y3lCMGFHRjBJSE4xY0hCdmNuUWdaMlZ1WlhKaGRHOXljeTVjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRWh2ZDJWMlpYSXNJRk5OSjNNZ1oyVnVaWEpoZEc5eWN5QjFjMlVnZEdobElGQjVkR2h2YmkxcGJuTndhWEpsWkNCelpXMWhiblJwWTNNZ2IyWmNiaUFnSUNBZ0lDQWdJQ0FnSUM4dklHOTFkR1JoZEdWa0lFVlROaUJrY21GbWRITXVJQ0JYWlNCM2IzVnNaQ0JzYVd0bElIUnZJSE4xY0hCdmNuUWdSVk0yTENCaWRYUWdkMlVuWkNCaGJITnZYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QnNhV3RsSUhSdklHMWhhMlVnYVhRZ2NHOXpjMmxpYkdVZ2RHOGdkWE5sSUdkbGJtVnlZWFJ2Y25NZ2FXNGdaR1Z3Ykc5NVpXUWdZbkp2ZDNObGNuTXNJSE52WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUIzWlNCaGJITnZJSE4xY0hCdmNuUWdVSGwwYUc5dUxYTjBlV3hsSUdkbGJtVnlZWFJ2Y25NdUlDQkJkQ0J6YjIxbElIQnZhVzUwSUhkbElHTmhiaUJ5WlcxdmRtVmNiaUFnSUNBZ0lDQWdJQ0FnSUM4dklIUm9hWE1nWW14dlkyc3VYRzVjYmlBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2gwZVhCbGIyWWdVM1J2Y0VsMFpYSmhkR2x2YmlBOVBUMGdYQ0oxYm1SbFptbHVaV1JjSWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDOHZJRVZUTmlCSFpXNWxjbUYwYjNKelhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVnpkV3gwSUQwZ1oyVnVaWEpoZEc5eVczWmxjbUpkS0dGeVp5azdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmU0JqWVhSamFDQW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLSEpsYzNWc2RDNWtiMjVsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQlJLSEpsYzNWc2RDNTJZV3gxWlNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIZG9aVzRvY21WemRXeDBMblpoYkhWbExDQmpZV3hzWW1GamF5d2daWEp5WW1GamF5azdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QlRjR2xrWlhKTmIyNXJaWGtnUjJWdVpYSmhkRzl5YzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUM4dklFWkpXRTFGT2lCU1pXMXZkbVVnZEdocGN5QmpZWE5sSUhkb1pXNGdVMDBnWkc5bGN5QkZVellnWjJWdVpYSmhkRzl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYTjFiSFFnUFNCblpXNWxjbUYwYjNKYmRtVnlZbDBvWVhKbktUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlJR05oZEdOb0lDaGxlR05sY0hScGIyNHBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR2x6VTNSdmNFbDBaWEpoZEdsdmJpaGxlR05sY0hScGIyNHBLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdVU2hsZUdObGNIUnBiMjR1ZG1Gc2RXVXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYW1WamRDaGxlR05sY0hScGIyNHBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCM2FHVnVLSEpsYzNWc2RDd2dZMkZzYkdKaFkyc3NJR1Z5Y21KaFkyc3BPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSFpoY2lCblpXNWxjbUYwYjNJZ1BTQnRZV3RsUjJWdVpYSmhkRzl5TG1Gd2NHeDVLSFJvYVhNc0lHRnlaM1Z0Wlc1MGN5azdYRzRnSUNBZ0lDQWdJSFpoY2lCallXeHNZbUZqYXlBOUlHTnZiblJwYm5WbGNpNWlhVzVrS0dOdmJuUnBiblZsY2l3Z1hDSnVaWGgwWENJcE8xeHVJQ0FnSUNBZ0lDQjJZWElnWlhKeVltRmpheUE5SUdOdmJuUnBiblZsY2k1aWFXNWtLR052Ym5ScGJuVmxjaXdnWENKMGFISnZkMXdpS1R0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yS0NrN1hHNGdJQ0FnZlR0Y2JuMWNibHh1THlvcVhHNGdLaUJVYUdVZ2MzQmhkMjRnWm5WdVkzUnBiMjRnYVhNZ1lTQnpiV0ZzYkNCM2NtRndjR1Z5SUdGeWIzVnVaQ0JoYzNsdVl5QjBhR0YwSUdsdGJXVmthV0YwWld4NVhHNGdLaUJqWVd4c2N5QjBhR1VnWjJWdVpYSmhkRzl5SUdGdVpDQmhiSE52SUdWdVpITWdkR2hsSUhCeWIyMXBjMlVnWTJoaGFXNHNJSE52SUhSb1lYUWdZVzU1WEc0Z0tpQjFibWhoYm1Sc1pXUWdaWEp5YjNKeklHRnlaU0IwYUhKdmQyNGdhVzV6ZEdWaFpDQnZaaUJtYjNKM1lYSmtaV1FnZEc4Z2RHaGxJR1Z5Y205eVhHNGdLaUJvWVc1a2JHVnlMaUJVYUdseklHbHpJSFZ6WldaMWJDQmlaV05oZFhObElHbDBKM01nWlhoMGNtVnRaV3g1SUdOdmJXMXZiaUIwYnlCeWRXNWNiaUFxSUdkbGJtVnlZWFJ2Y25NZ1lYUWdkR2hsSUhSdmNDMXNaWFpsYkNCMGJ5QjNiM0pySUhkcGRHZ2diR2xpY21GeWFXVnpMbHh1SUNvdlhHNVJMbk53WVhkdUlEMGdjM0JoZDI0N1hHNW1kVzVqZEdsdmJpQnpjR0YzYmlodFlXdGxSMlZ1WlhKaGRHOXlLU0I3WEc0Z0lDQWdVUzVrYjI1bEtGRXVZWE41Ym1Nb2JXRnJaVWRsYm1WeVlYUnZjaWtvS1NrN1hHNTlYRzVjYmk4dklFWkpXRTFGT2lCU1pXMXZkbVVnZEdocGN5QnBiblJsY21aaFkyVWdiMjVqWlNCRlV6WWdaMlZ1WlhKaGRHOXljeUJoY21VZ2FXNGdVM0JwWkdWeVRXOXVhMlY1TGx4dUx5b3FYRzRnS2lCVWFISnZkM01nWVNCU1pYUjFjbTVXWVd4MVpTQmxlR05sY0hScGIyNGdkRzhnYzNSdmNDQmhiaUJoYzNsdVkyaHliMjV2ZFhNZ1oyVnVaWEpoZEc5eUxseHVJQ3BjYmlBcUlGUm9hWE1nYVc1MFpYSm1ZV05sSUdseklHRWdjM1J2Y0MxbllYQWdiV1ZoYzNWeVpTQjBieUJ6ZFhCd2IzSjBJR2RsYm1WeVlYUnZjaUJ5WlhSMWNtNWNiaUFxSUhaaGJIVmxjeUJwYmlCdmJHUmxjaUJHYVhKbFptOTRMMU53YVdSbGNrMXZibXRsZVM0Z0lFbHVJR0p5YjNkelpYSnpJSFJvWVhRZ2MzVndjRzl5ZENCRlV6WmNiaUFxSUdkbGJtVnlZWFJ2Y25NZ2JHbHJaU0JEYUhKdmJXbDFiU0F5T1N3Z2FuVnpkQ0IxYzJVZ1hDSnlaWFIxY201Y0lpQnBiaUI1YjNWeUlHZGxibVZ5WVhSdmNseHVJQ29nWm5WdVkzUnBiMjV6TGx4dUlDcGNiaUFxSUVCd1lYSmhiU0IyWVd4MVpTQjBhR1VnY21WMGRYSnVJSFpoYkhWbElHWnZjaUIwYUdVZ2MzVnljbTkxYm1ScGJtY2daMlZ1WlhKaGRHOXlYRzRnS2lCQWRHaHliM2R6SUZKbGRIVnlibFpoYkhWbElHVjRZMlZ3ZEdsdmJpQjNhWFJvSUhSb1pTQjJZV3gxWlM1Y2JpQXFJRUJsZUdGdGNHeGxYRzRnS2lBdkx5QkZVellnYzNSNWJHVmNiaUFxSUZFdVlYTjVibU1vWm5WdVkzUnBiMjRxSUNncElIdGNiaUFxSUNBZ0lDQWdkbUZ5SUdadmJ5QTlJSGxwWld4a0lHZGxkRVp2YjFCeWIyMXBjMlVvS1R0Y2JpQXFJQ0FnSUNBZ2RtRnlJR0poY2lBOUlIbHBaV3hrSUdkbGRFSmhjbEJ5YjIxcGMyVW9LVHRjYmlBcUlDQWdJQ0FnY21WMGRYSnVJR1p2YnlBcklHSmhjanRjYmlBcUlIMHBYRzRnS2lBdkx5QlBiR1JsY2lCVGNHbGtaWEpOYjI1clpYa2djM1I1YkdWY2JpQXFJRkV1WVhONWJtTW9ablZ1WTNScGIyNGdLQ2tnZTF4dUlDb2dJQ0FnSUNCMllYSWdabTl2SUQwZ2VXbGxiR1FnWjJWMFJtOXZVSEp2YldselpTZ3BPMXh1SUNvZ0lDQWdJQ0IyWVhJZ1ltRnlJRDBnZVdsbGJHUWdaMlYwUW1GeVVISnZiV2x6WlNncE8xeHVJQ29nSUNBZ0lDQlJMbkpsZEhWeWJpaG1iMjhnS3lCaVlYSXBPMXh1SUNvZ2ZTbGNiaUFxTDF4dVVWdGNJbkpsZEhWeWJsd2lYU0E5SUY5eVpYUjFjbTQ3WEc1bWRXNWpkR2x2YmlCZmNtVjBkWEp1S0haaGJIVmxLU0I3WEc0Z0lDQWdkR2h5YjNjZ2JtVjNJRkZTWlhSMWNtNVdZV3gxWlNoMllXeDFaU2s3WEc1OVhHNWNiaThxS2x4dUlDb2dWR2hsSUhCeWIyMXBjMlZrSUdaMWJtTjBhVzl1SUdSbFkyOXlZWFJ2Y2lCbGJuTjFjbVZ6SUhSb1lYUWdZVzU1SUhCeWIyMXBjMlVnWVhKbmRXMWxiblJ6WEc0Z0tpQmhjbVVnYzJWMGRHeGxaQ0JoYm1RZ2NHRnpjMlZrSUdGeklIWmhiSFZsY3lBb1lIUm9hWE5nSUdseklHRnNjMjhnYzJWMGRHeGxaQ0JoYm1RZ2NHRnpjMlZrWEc0Z0tpQmhjeUJoSUhaaGJIVmxLUzRnSUVsMElIZHBiR3dnWVd4emJ5Qmxibk4xY21VZ2RHaGhkQ0IwYUdVZ2NtVnpkV3gwSUc5bUlHRWdablZ1WTNScGIyNGdhWE5jYmlBcUlHRnNkMkY1Y3lCaElIQnliMjFwYzJVdVhHNGdLbHh1SUNvZ1FHVjRZVzF3YkdWY2JpQXFJSFpoY2lCaFpHUWdQU0JSTG5CeWIyMXBjMlZrS0daMWJtTjBhVzl1SUNoaExDQmlLU0I3WEc0Z0tpQWdJQ0FnY21WMGRYSnVJR0VnS3lCaU8xeHVJQ29nZlNrN1hHNGdLaUJoWkdRb1VTaGhLU3dnVVNoQ0tTazdYRzRnS2x4dUlDb2dRSEJoY21GdElIdG1kVzVqZEdsdmJuMGdZMkZzYkdKaFkyc2dWR2hsSUdaMWJtTjBhVzl1SUhSdklHUmxZMjl5WVhSbFhHNGdLaUJBY21WMGRYSnVjeUI3Wm5WdVkzUnBiMjU5SUdFZ1puVnVZM1JwYjI0Z2RHaGhkQ0JvWVhNZ1ltVmxiaUJrWldOdmNtRjBaV1F1WEc0Z0tpOWNibEV1Y0hKdmJXbHpaV1FnUFNCd2NtOXRhWE5sWkR0Y2JtWjFibU4wYVc5dUlIQnliMjFwYzJWa0tHTmhiR3hpWVdOcktTQjdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlITndjbVZoWkNoYmRHaHBjeXdnWVd4c0tHRnlaM1Z0Wlc1MGN5bGRMQ0JtZFc1amRHbHZiaUFvYzJWc1ppd2dZWEpuY3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtITmxiR1lzSUdGeVozTXBPMXh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0I5TzF4dWZWeHVYRzR2S2lwY2JpQXFJSE5sYm1SeklHRWdiV1Z6YzJGblpTQjBieUJoSUhaaGJIVmxJR2x1SUdFZ1puVjBkWEpsSUhSMWNtNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUXFJSFJvWlNCeVpXTnBjR2xsYm5SY2JpQXFJRUJ3WVhKaGJTQnZjQ0IwYUdVZ2JtRnRaU0J2WmlCMGFHVWdiV1Z6YzJGblpTQnZjR1Z5WVhScGIyNHNJR1V1Wnk0c0lGd2lkMmhsYmx3aUxGeHVJQ29nUUhCaGNtRnRJR0Z5WjNNZ1puVnlkR2hsY2lCaGNtZDFiV1Z1ZEhNZ2RHOGdZbVVnWm05eWQyRnlaR1ZrSUhSdklIUm9aU0J2Y0dWeVlYUnBiMjVjYmlBcUlFQnlaWFIxY201eklISmxjM1ZzZENCN1VISnZiV2x6WlgwZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVnpkV3gwSUc5bUlIUm9aU0J2Y0dWeVlYUnBiMjVjYmlBcUwxeHVVUzVrYVhOd1lYUmphQ0E5SUdScGMzQmhkR05vTzF4dVpuVnVZM1JwYjI0Z1pHbHpjR0YwWTJnb2IySnFaV04wTENCdmNDd2dZWEpuY3lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2t1WkdsemNHRjBZMmdvYjNBc0lHRnlaM01wTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVrYVhOd1lYUmphQ0E5SUdaMWJtTjBhVzl1SUNodmNDd2dZWEpuY3lrZ2UxeHVJQ0FnSUhaaGNpQnpaV3htSUQwZ2RHaHBjenRjYmlBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJRkV1Ym1WNGRGUnBZMnNvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQnpaV3htTG5CeWIyMXBjMlZFYVhOd1lYUmphQ2hrWldabGNuSmxaQzV5WlhOdmJIWmxMQ0J2Y0N3Z1lYSm5jeWs3WEc0Z0lDQWdmU2s3WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVkbGRITWdkR2hsSUhaaGJIVmxJRzltSUdFZ2NISnZjR1Z5ZEhrZ2FXNGdZU0JtZFhSMWNtVWdkSFZ5Ymk1Y2JpQXFJRUJ3WVhKaGJTQnZZbXBsWTNRZ0lDQWdjSEp2YldselpTQnZjaUJwYlcxbFpHbGhkR1VnY21WbVpYSmxibU5sSUdadmNpQjBZWEpuWlhRZ2IySnFaV04wWEc0Z0tpQkFjR0Z5WVcwZ2JtRnRaU0FnSUNBZ0lHNWhiV1VnYjJZZ2NISnZjR1Z5ZEhrZ2RHOGdaMlYwWEc0Z0tpQkFjbVYwZFhKdUlIQnliMjFwYzJVZ1ptOXlJSFJvWlNCd2NtOXdaWEowZVNCMllXeDFaVnh1SUNvdlhHNVJMbWRsZENBOUlHWjFibU4wYVc5dUlDaHZZbXBsWTNRc0lHdGxlU2tnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VaR2x6Y0dGMFkyZ29YQ0puWlhSY0lpd2dXMnRsZVYwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVoyVjBJRDBnWm5WdVkzUnBiMjRnS0d0bGVTa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbVJwYzNCaGRHTm9LRndpWjJWMFhDSXNJRnRyWlhsZEtUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1UyVjBjeUIwYUdVZ2RtRnNkV1VnYjJZZ1lTQndjbTl3WlhKMGVTQnBiaUJoSUdaMWRIVnlaU0IwZFhKdUxseHVJQ29nUUhCaGNtRnRJRzlpYW1WamRDQWdJQ0J3Y205dGFYTmxJRzl5SUdsdGJXVmthV0YwWlNCeVpXWmxjbVZ1WTJVZ1ptOXlJRzlpYW1WamRDQnZZbXBsWTNSY2JpQXFJRUJ3WVhKaGJTQnVZVzFsSUNBZ0lDQWdibUZ0WlNCdlppQndjbTl3WlhKMGVTQjBieUJ6WlhSY2JpQXFJRUJ3WVhKaGJTQjJZV3gxWlNBZ0lDQWdibVYzSUhaaGJIVmxJRzltSUhCeWIzQmxjblI1WEc0Z0tpQkFjbVYwZFhKdUlIQnliMjFwYzJVZ1ptOXlJSFJvWlNCeVpYUjFjbTRnZG1Gc2RXVmNiaUFxTDF4dVVTNXpaWFFnUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wTENCclpYa3NJSFpoYkhWbEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a2FYTndZWFJqYUNoY0luTmxkRndpTENCYmEyVjVMQ0IyWVd4MVpWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVjMlYwSUQwZ1puVnVZM1JwYjI0Z0tHdGxlU3dnZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVrYVhOd1lYUmphQ2hjSW5ObGRGd2lMQ0JiYTJWNUxDQjJZV3gxWlYwcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCRVpXeGxkR1Z6SUdFZ2NISnZjR1Z5ZEhrZ2FXNGdZU0JtZFhSMWNtVWdkSFZ5Ymk1Y2JpQXFJRUJ3WVhKaGJTQnZZbXBsWTNRZ0lDQWdjSEp2YldselpTQnZjaUJwYlcxbFpHbGhkR1VnY21WbVpYSmxibU5sSUdadmNpQjBZWEpuWlhRZ2IySnFaV04wWEc0Z0tpQkFjR0Z5WVcwZ2JtRnRaU0FnSUNBZ0lHNWhiV1VnYjJZZ2NISnZjR1Z5ZEhrZ2RHOGdaR1ZzWlhSbFhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1ZjYmlBcUwxeHVVUzVrWld3Z1BTQXZMeUJZV0ZnZ2JHVm5ZV041WEc1Ulcxd2laR1ZzWlhSbFhDSmRJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnYTJWNUtTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a2FYTndZWFJqYUNoY0ltUmxiR1YwWlZ3aUxDQmJhMlY1WFNrN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1a1pXd2dQU0F2THlCWVdGZ2diR1ZuWVdONVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pWdGNJbVJsYkdWMFpWd2lYU0E5SUdaMWJtTjBhVzl1SUNoclpYa3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVrYVhOd1lYUmphQ2hjSW1SbGJHVjBaVndpTENCYmEyVjVYU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRWx1ZG05clpYTWdZU0J0WlhSb2IyUWdhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdiV1YwYUc5a0lIUnZJR2x1ZG05clpWeHVJQ29nUUhCaGNtRnRJSFpoYkhWbElDQWdJQ0JoSUhaaGJIVmxJSFJ2SUhCdmMzUXNJSFI1Y0dsallXeHNlU0JoYmlCaGNuSmhlU0J2Wmx4dUlDb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnBiblp2WTJGMGFXOXVJR0Z5WjNWdFpXNTBjeUJtYjNJZ2NISnZiV2x6WlhNZ2RHaGhkRnh1SUNvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCaGNtVWdkV3gwYVcxaGRHVnNlU0JpWVdOclpXUWdkMmwwYUNCZ2NtVnpiMngyWldBZ2RtRnNkV1Z6TEZ4dUlDb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmhjeUJ2Y0hCdmMyVmtJSFJ2SUhSb2IzTmxJR0poWTJ0bFpDQjNhWFJvSUZWU1RITmNiaUFxSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZDJobGNtVnBiaUIwYUdVZ2NHOXpkR1ZrSUhaaGJIVmxJR05oYmlCaVpTQmhibmxjYmlBcUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1NsTlBUaUJ6WlhKcFlXeHBlbUZpYkdVZ2IySnFaV04wTGx4dUlDb2dRSEpsZEhWeWJpQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVjBkWEp1SUhaaGJIVmxYRzRnS2k5Y2JpOHZJR0p2ZFc1a0lHeHZZMkZzYkhrZ1ltVmpZWFZ6WlNCcGRDQnBjeUIxYzJWa0lHSjVJRzkwYUdWeUlHMWxkR2h2WkhOY2JsRXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEV1Y0c5emRDQTlJR1oxYm1OMGFXOXVJQ2h2WW1wbFkzUXNJRzVoYldVc0lHRnlaM01wSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEpuYzEwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJXRndjR3g1SUQwZ0x5OGdXRmhZSUVGeklIQnliM0J2YzJWa0lHSjVJRndpVW1Wa2MyRnVaSEp2WENKY2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExuQnZjM1FnUFNCbWRXNWpkR2x2YmlBb2JtRnRaU3dnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEpuYzEwcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCSmJuWnZhMlZ6SUdFZ2JXVjBhRzlrSUdsdUlHRWdablYwZFhKbElIUjFjbTR1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wSUNBZ0lIQnliMjFwYzJVZ2IzSWdhVzF0WldScFlYUmxJSEpsWm1WeVpXNWpaU0JtYjNJZ2RHRnlaMlYwSUc5aWFtVmpkRnh1SUNvZ1FIQmhjbUZ0SUc1aGJXVWdJQ0FnSUNCdVlXMWxJRzltSUcxbGRHaHZaQ0IwYnlCcGJuWnZhMlZjYmlBcUlFQndZWEpoYlNBdUxpNWhjbWR6SUNBZ1lYSnlZWGtnYjJZZ2FXNTJiMk5oZEdsdmJpQmhjbWQxYldWdWRITmNiaUFxSUVCeVpYUjFjbTRnY0hKdmJXbHpaU0JtYjNJZ2RHaGxJSEpsZEhWeWJpQjJZV3gxWlZ4dUlDb3ZYRzVSTG5ObGJtUWdQU0F2THlCWVdGZ2dUV0Z5YXlCTmFXeHNaWEluY3lCd2NtOXdiM05sWkNCd1lYSnNZVzVqWlZ4dVVTNXRZMkZzYkNBOUlDOHZJRmhZV0NCQmN5QndjbTl3YjNObFpDQmllU0JjSWxKbFpITmhibVJ5YjF3aVhHNVJMbWx1ZG05clpTQTlJR1oxYm1OMGFXOXVJQ2h2WW1wbFkzUXNJRzVoYldVZ0x5b3VMaTVoY21kektpOHBJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaHZZbXBsWTNRcExtUnBjM0JoZEdOb0tGd2ljRzl6ZEZ3aUxDQmJibUZ0WlN3Z1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpMQ0F5S1YwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWMyVnVaQ0E5SUM4dklGaFlXQ0JOWVhKcklFMXBiR3hsY2lkeklIQnliM0J2YzJWa0lIQmhjbXhoYm1ObFhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXRZMkZzYkNBOUlDOHZJRmhZV0NCQmN5QndjbTl3YjNObFpDQmllU0JjSWxKbFpITmhibVJ5YjF3aVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXBiblp2YTJVZ1BTQm1kVzVqZEdsdmJpQW9ibUZ0WlNBdktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeEtWMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkJjSEJzYVdWeklIUm9aU0J3Y205dGFYTmxaQ0JtZFc1amRHbHZiaUJwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUhSaGNtZGxkQ0JtZFc1amRHbHZibHh1SUNvZ1FIQmhjbUZ0SUdGeVozTWdJQ0FnSUNCaGNuSmhlU0J2WmlCaGNIQnNhV05oZEdsdmJpQmhjbWQxYldWdWRITmNiaUFxTDF4dVVTNW1ZWEJ3YkhrZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQmhjbWR6S1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0MmIybGtJREFzSUdGeVozTmRLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVpoY0hCc2VTQTlJR1oxYm1OMGFXOXVJQ2hoY21kektTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVaR2x6Y0dGMFkyZ29YQ0poY0hCc2VWd2lMQ0JiZG05cFpDQXdMQ0JoY21kelhTazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFTmhiR3h6SUhSb1pTQndjbTl0YVhObFpDQm1kVzVqZEdsdmJpQnBiaUJoSUdaMWRIVnlaU0IwZFhKdUxseHVJQ29nUUhCaGNtRnRJRzlpYW1WamRDQWdJQ0J3Y205dGFYTmxJRzl5SUdsdGJXVmthV0YwWlNCeVpXWmxjbVZ1WTJVZ1ptOXlJSFJoY21kbGRDQm1kVzVqZEdsdmJseHVJQ29nUUhCaGNtRnRJQzR1TG1GeVozTWdJQ0JoY25KaGVTQnZaaUJoY0hCc2FXTmhkR2x2YmlCaGNtZDFiV1Z1ZEhOY2JpQXFMMXh1VVZ0Y0luUnllVndpWFNBOVhHNVJMbVpqWVd4c0lEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDQXZLaUF1TGk1aGNtZHpLaThwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJwYzNCaGRHTm9LRndpWVhCd2JIbGNJaXdnVzNadmFXUWdNQ3dnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SekxDQXhLVjBwTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1Wm1OaGJHd2dQU0JtZFc1amRHbHZiaUFvTHlvdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWthWE53WVhSamFDaGNJbUZ3Y0d4NVhDSXNJRnQyYjJsa0lEQXNJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3lsZEtUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1FtbHVaSE1nZEdobElIQnliMjFwYzJWa0lHWjFibU4wYVc5dUxDQjBjbUZ1YzJadmNtMXBibWNnY21WMGRYSnVJSFpoYkhWbGN5QnBiblJ2SUdFZ1puVnNabWxzYkdWa1hHNGdLaUJ3Y205dGFYTmxJR0Z1WkNCMGFISnZkMjRnWlhKeWIzSnpJR2x1ZEc4Z1lTQnlaV3BsWTNSbFpDQnZibVV1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wSUNBZ0lIQnliMjFwYzJVZ2IzSWdhVzF0WldScFlYUmxJSEpsWm1WeVpXNWpaU0JtYjNJZ2RHRnlaMlYwSUdaMWJtTjBhVzl1WEc0Z0tpQkFjR0Z5WVcwZ0xpNHVZWEpuY3lBZ0lHRnljbUY1SUc5bUlHRndjR3hwWTJGMGFXOXVJR0Z5WjNWdFpXNTBjMXh1SUNvdlhHNVJMbVppYVc1a0lEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDQXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSFpoY2lCd2NtOXRhWE5sSUQwZ1VTaHZZbXBsWTNRcE8xeHVJQ0FnSUhaaGNpQmhjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpMQ0F4S1R0Y2JpQWdJQ0J5WlhSMWNtNGdablZ1WTNScGIyNGdabUp2ZFc1a0tDa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdjSEp2YldselpTNWthWE53WVhSamFDaGNJbUZ3Y0d4NVhDSXNJRnRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE1zWEc0Z0lDQWdJQ0FnSUNBZ0lDQmhjbWR6TG1OdmJtTmhkQ2hoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNcEtWeHVJQ0FnSUNBZ0lDQmRLVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtWmlhVzVrSUQwZ1puVnVZM1JwYjI0Z0tDOHFMaTR1WVhKbmN5b3ZLU0I3WEc0Z0lDQWdkbUZ5SUhCeWIyMXBjMlVnUFNCMGFHbHpPMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0J5WlhSMWNtNGdablZ1WTNScGIyNGdabUp2ZFc1a0tDa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdjSEp2YldselpTNWthWE53WVhSamFDaGNJbUZ3Y0d4NVhDSXNJRnRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE1zWEc0Z0lDQWdJQ0FnSUNBZ0lDQmhjbWR6TG1OdmJtTmhkQ2hoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNcEtWeHVJQ0FnSUNBZ0lDQmRLVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlNaWEYxWlhOMGN5QjBhR1VnYm1GdFpYTWdiMllnZEdobElHOTNibVZrSUhCeWIzQmxjblJwWlhNZ2IyWWdZU0J3Y205dGFYTmxaRnh1SUNvZ2IySnFaV04wSUdsdUlHRWdablYwZFhKbElIUjFjbTR1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wSUNBZ0lIQnliMjFwYzJVZ2IzSWdhVzF0WldScFlYUmxJSEpsWm1WeVpXNWpaU0JtYjNJZ2RHRnlaMlYwSUc5aWFtVmpkRnh1SUNvZ1FISmxkSFZ5YmlCd2NtOXRhWE5sSUdadmNpQjBhR1VnYTJWNWN5QnZaaUIwYUdVZ1pYWmxiblIxWVd4c2VTQnpaWFIwYkdWa0lHOWlhbVZqZEZ4dUlDb3ZYRzVSTG10bGVYTWdQU0JtZFc1amRHbHZiaUFvYjJKcVpXTjBLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbXRsZVhOY0lpd2dXMTBwTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1YTJWNWN5QTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0ltdGxlWE5jSWl3Z1cxMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlVkWEp1Y3lCaGJpQmhjbkpoZVNCdlppQndjbTl0YVhObGN5QnBiblJ2SUdFZ2NISnZiV2x6WlNCbWIzSWdZVzRnWVhKeVlYa3VJQ0JKWmlCaGJua2diMlpjYmlBcUlIUm9aU0J3Y205dGFYTmxjeUJuWlhSeklISmxhbVZqZEdWa0xDQjBhR1VnZDJodmJHVWdZWEp5WVhrZ2FYTWdjbVZxWldOMFpXUWdhVzF0WldScFlYUmxiSGt1WEc0Z0tpQkFjR0Z5WVcwZ2UwRnljbUY1S24wZ1lXNGdZWEp5WVhrZ0tHOXlJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1S1NCdlppQjJZV3gxWlhNZ0tHOXlYRzRnS2lCd2NtOXRhWE5sY3lCbWIzSWdkbUZzZFdWektWeHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQmhiaUJoY25KaGVTQnZaaUIwYUdVZ1kyOXljbVZ6Y0c5dVpHbHVaeUIyWVd4MVpYTmNiaUFxTDF4dUx5OGdRbmtnVFdGeWF5Qk5hV3hzWlhKY2JpOHZJR2gwZEhBNkx5OTNhV3RwTG1WamJXRnpZM0pwY0hRdWIzSm5MMlJ2YTNVdWNHaHdQMmxrUFhOMGNtRjNiV0Z1T21OdmJtTjFjbkpsYm1ONUpuSmxkajB4TXpBNE56YzJOVEl4STJGc2JHWjFiR1pwYkd4bFpGeHVVUzVoYkd3Z1BTQmhiR3c3WEc1bWRXNWpkR2x2YmlCaGJHd29jSEp2YldselpYTXBJSHRjYmlBZ0lDQnlaWFIxY200Z2QyaGxiaWh3Y205dGFYTmxjeXdnWm5WdVkzUnBiMjRnS0hCeWIyMXBjMlZ6S1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJ3Wlc1a2FXNW5RMjkxYm5RZ1BTQXdPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQmhjbkpoZVY5eVpXUjFZMlVvY0hKdmJXbHpaWE1zSUdaMWJtTjBhVzl1SUNoMWJtUmxabWx1WldRc0lIQnliMjFwYzJVc0lHbHVaR1Y0S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IyWVhJZ2MyNWhjSE5vYjNRN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FYTlFjbTl0YVhObEtIQnliMjFwYzJVcElDWW1YRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdLSE51WVhCemFHOTBJRDBnY0hKdmJXbHpaUzVwYm5Od1pXTjBLQ2twTG5OMFlYUmxJRDA5UFNCY0ltWjFiR1pwYkd4bFpGd2lYRzRnSUNBZ0lDQWdJQ0FnSUNBcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQndjbTl0YVhObGMxdHBibVJsZUYwZ1BTQnpibUZ3YzJodmRDNTJZV3gxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdLeXR3Wlc1a2FXNW5RMjkxYm5RN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2QyaGxiaWhjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZiV2x6WlN4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdablZ1WTNScGIyNGdLSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQndjbTl0YVhObGMxdHBibVJsZUYwZ1BTQjJZV3gxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDZ3RMWEJsYm1ScGJtZERiM1Z1ZENBOVBUMGdNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vb2NISnZiV2x6WlhNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5TEZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmtaV1psY25KbFpDNXlaV3BsWTNRc1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR1oxYm1OMGFXOXVJQ2h3Y205bmNtVnpjeWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWkdWbVpYSnlaV1F1Ym05MGFXWjVLSHNnYVc1a1pYZzZJR2x1WkdWNExDQjJZV3gxWlRvZ2NISnZaM0psYzNNZ2ZTazdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOUxDQjJiMmxrSURBcE8xeHVJQ0FnSUNBZ0lDQnBaaUFvY0dWdVpHbHVaME52ZFc1MElEMDlQU0F3S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WlhOdmJIWmxLSEJ5YjIxcGMyVnpLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlLVHRjYm4xY2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVZV3hzSUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCaGJHd29kR2hwY3lrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZKbGRIVnlibk1nZEdobElHWnBjbk4wSUhKbGMyOXNkbVZrSUhCeWIyMXBjMlVnYjJZZ1lXNGdZWEp5WVhrdUlGQnlhVzl5SUhKbGFtVmpkR1ZrSUhCeWIyMXBjMlZ6SUdGeVpWeHVJQ29nYVdkdWIzSmxaQzRnSUZKbGFtVmpkSE1nYjI1c2VTQnBaaUJoYkd3Z2NISnZiV2x6WlhNZ1lYSmxJSEpsYW1WamRHVmtMbHh1SUNvZ1FIQmhjbUZ0SUh0QmNuSmhlU3A5SUdGdUlHRnljbUY1SUdOdmJuUmhhVzVwYm1jZ2RtRnNkV1Z6SUc5eUlIQnliMjFwYzJWeklHWnZjaUIyWVd4MVpYTmNiaUFxSUVCeVpYUjFjbTV6SUdFZ2NISnZiV2x6WlNCbWRXeG1hV3hzWldRZ2QybDBhQ0IwYUdVZ2RtRnNkV1VnYjJZZ2RHaGxJR1pwY25OMElISmxjMjlzZG1Wa0lIQnliMjFwYzJVc1hHNGdLaUJ2Y2lCaElISmxhbVZqZEdWa0lIQnliMjFwYzJVZ2FXWWdZV3hzSUhCeWIyMXBjMlZ6SUdGeVpTQnlaV3BsWTNSbFpDNWNiaUFxTDF4dVVTNWhibmtnUFNCaGJuazdYRzVjYm1aMWJtTjBhVzl1SUdGdWVTaHdjbTl0YVhObGN5a2dlMXh1SUNBZ0lHbG1JQ2h3Y205dGFYTmxjeTVzWlc1bmRHZ2dQVDA5SURBcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlGRXVjbVZ6YjJ4MlpTZ3BPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUZFdVpHVm1aWElvS1R0Y2JpQWdJQ0IyWVhJZ2NHVnVaR2x1WjBOdmRXNTBJRDBnTUR0Y2JpQWdJQ0JoY25KaGVWOXlaV1IxWTJVb2NISnZiV2x6WlhNc0lHWjFibU4wYVc5dUlDaHdjbVYyTENCamRYSnlaVzUwTENCcGJtUmxlQ2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdjSEp2YldselpTQTlJSEJ5YjIxcGMyVnpXMmx1WkdWNFhUdGNibHh1SUNBZ0lDQWdJQ0J3Wlc1a2FXNW5RMjkxYm5Rckt6dGNibHh1SUNBZ0lDQWdJQ0IzYUdWdUtIQnliMjFwYzJVc0lHOXVSblZzWm1sc2JHVmtMQ0J2YmxKbGFtVmpkR1ZrTENCdmJsQnliMmR5WlhOektUdGNiaUFnSUNBZ0lDQWdablZ1WTNScGIyNGdiMjVHZFd4bWFXeHNaV1FvY21WemRXeDBLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtaV1psY25KbFpDNXlaWE52YkhabEtISmxjM1ZzZENrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdablZ1WTNScGIyNGdiMjVTWldwbFkzUmxaQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEJsYm1ScGJtZERiM1Z1ZEMwdE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tIQmxibVJwYm1kRGIzVnVkQ0E5UFQwZ01Da2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYW1WamRDaHVaWGNnUlhKeWIzSW9YRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aVEyRnVKM1FnWjJWMElHWjFiR1pwYkd4dFpXNTBJSFpoYkhWbElHWnliMjBnWVc1NUlIQnliMjFwYzJVc0lHRnNiQ0JjSWlBclhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRndpY0hKdmJXbHpaWE1nZDJWeVpTQnlaV3BsWTNSbFpDNWNJbHh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ2twTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUc5dVVISnZaM0psYzNNb2NISnZaM0psYzNNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdSbFptVnljbVZrTG01dmRHbG1lU2g3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYVc1a1pYZzZJR2x1WkdWNExGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIWmhiSFZsT2lCd2NtOW5jbVZ6YzF4dUlDQWdJQ0FnSUNBZ0lDQWdmU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5TENCMWJtUmxabWx1WldRcE8xeHVYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbUZ1ZVNBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z1lXNTVLSFJvYVhNcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCWFlXbDBjeUJtYjNJZ1lXeHNJSEJ5YjIxcGMyVnpJSFJ2SUdKbElITmxkSFJzWldRc0lHVnBkR2hsY2lCbWRXeG1hV3hzWldRZ2IzSmNiaUFxSUhKbGFtVmpkR1ZrTGlBZ1ZHaHBjeUJwY3lCa2FYTjBhVzVqZENCbWNtOXRJR0JoYkd4Z0lITnBibU5sSUhSb1lYUWdkMjkxYkdRZ2MzUnZjRnh1SUNvZ2QyRnBkR2x1WnlCaGRDQjBhR1VnWm1seWMzUWdjbVZxWldOMGFXOXVMaUFnVkdobElIQnliMjFwYzJVZ2NtVjBkWEp1WldRZ1lubGNiaUFxSUdCaGJHeFNaWE52YkhabFpHQWdkMmxzYkNCdVpYWmxjaUJpWlNCeVpXcGxZM1JsWkM1Y2JpQXFJRUJ3WVhKaGJTQndjbTl0YVhObGN5QmhJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1SUNodmNpQmhiaUJoY25KaGVTa2diMllnY0hKdmJXbHpaWE5jYmlBcUlDaHZjaUIyWVd4MVpYTXBYRzRnS2lCQWNtVjBkWEp1SUdFZ2NISnZiV2x6WlNCbWIzSWdZVzRnWVhKeVlYa2diMllnY0hKdmJXbHpaWE5jYmlBcUwxeHVVUzVoYkd4U1pYTnZiSFpsWkNBOUlHUmxjSEpsWTJGMFpTaGhiR3hTWlhOdmJIWmxaQ3dnWENKaGJHeFNaWE52YkhabFpGd2lMQ0JjSW1Gc2JGTmxkSFJzWldSY0lpazdYRzVtZFc1amRHbHZiaUJoYkd4U1pYTnZiSFpsWkNod2NtOXRhWE5sY3lrZ2UxeHVJQ0FnSUhKbGRIVnliaUIzYUdWdUtIQnliMjFwYzJWekxDQm1kVzVqZEdsdmJpQW9jSEp2YldselpYTXBJSHRjYmlBZ0lDQWdJQ0FnY0hKdmJXbHpaWE1nUFNCaGNuSmhlVjl0WVhBb2NISnZiV2x6WlhNc0lGRXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdkMmhsYmloaGJHd29ZWEp5WVhsZmJXRndLSEJ5YjIxcGMyVnpMQ0JtZFc1amRHbHZiaUFvY0hKdmJXbHpaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIZG9aVzRvY0hKdmJXbHpaU3dnYm05dmNDd2dibTl2Y0NrN1hHNGdJQ0FnSUNBZ0lIMHBLU3dnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVnpPMXh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0I5S1R0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1WVd4c1VtVnpiMngyWldRZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlHRnNiRkpsYzI5c2RtVmtLSFJvYVhNcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCQWMyVmxJRkJ5YjIxcGMyVWpZV3hzVTJWMGRHeGxaRnh1SUNvdlhHNVJMbUZzYkZObGRIUnNaV1FnUFNCaGJHeFRaWFIwYkdWa08xeHVablZ1WTNScGIyNGdZV3hzVTJWMGRHeGxaQ2h3Y205dGFYTmxjeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLSEJ5YjIxcGMyVnpLUzVoYkd4VFpYUjBiR1ZrS0NrN1hHNTlYRzVjYmk4cUtseHVJQ29nVkhWeWJuTWdZVzRnWVhKeVlYa2diMllnY0hKdmJXbHpaWE1nYVc1MGJ5QmhJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1SUc5bUlIUm9aV2x5SUhOMFlYUmxjeUFvWVhOY2JpQXFJSEpsZEhWeWJtVmtJR0o1SUdCcGJuTndaV04wWUNrZ2QyaGxiaUIwYUdWNUlHaGhkbVVnWVd4c0lITmxkSFJzWldRdVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNVcwRnVlU3BkZlNCMllXeDFaWE1nWVc0Z1lYSnlZWGtnS0c5eUlIQnliMjFwYzJVZ1ptOXlJR0Z1SUdGeWNtRjVLU0J2WmlCMllXeDFaWE1nS0c5eVhHNGdLaUJ3Y205dGFYTmxjeUJtYjNJZ2RtRnNkV1Z6S1Z4dUlDb2dRSEpsZEhWeWJuTWdlMEZ5Y21GNVcxTjBZWFJsWFgwZ1lXNGdZWEp5WVhrZ2IyWWdjM1JoZEdWeklHWnZjaUIwYUdVZ2NtVnpjR1ZqZEdsMlpTQjJZV3gxWlhNdVhHNGdLaTljYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1Gc2JGTmxkSFJzWldRZ1BTQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9jSEp2YldselpYTXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR0ZzYkNoaGNuSmhlVjl0WVhBb2NISnZiV2x6WlhNc0lHWjFibU4wYVc5dUlDaHdjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCd2NtOXRhWE5sSUQwZ1VTaHdjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUhKbFoyRnlaR3hsYzNNb0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIQnliMjFwYzJVdWFXNXpjR1ZqZENncE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIQnliMjFwYzJVdWRHaGxiaWh5WldkaGNtUnNaWE56TENCeVpXZGhjbVJzWlhOektUdGNiaUFnSUNBZ0lDQWdmU2twTzF4dUlDQWdJSDBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJEWVhCMGRYSmxjeUIwYUdVZ1ptRnBiSFZ5WlNCdlppQmhJSEJ5YjIxcGMyVXNJR2RwZG1sdVp5QmhiaUJ2Y0c5eWRIVnVhWFI1SUhSdklISmxZMjkyWlhKY2JpQXFJSGRwZEdnZ1lTQmpZV3hzWW1GamF5NGdJRWxtSUhSb1pTQm5hWFpsYmlCd2NtOXRhWE5sSUdseklHWjFiR1pwYkd4bFpDd2dkR2hsSUhKbGRIVnlibVZrWEc0Z0tpQndjbTl0YVhObElHbHpJR1oxYkdacGJHeGxaQzVjYmlBcUlFQndZWEpoYlNCN1FXNTVLbjBnY0hKdmJXbHpaU0JtYjNJZ2MyOXRaWFJvYVc1blhHNGdLaUJBY0dGeVlXMGdlMFoxYm1OMGFXOXVmU0JqWVd4c1ltRmpheUIwYnlCbWRXeG1hV3hzSUhSb1pTQnlaWFIxY201bFpDQndjbTl0YVhObElHbG1JSFJvWlZ4dUlDb2daMmwyWlc0Z2NISnZiV2x6WlNCcGN5QnlaV3BsWTNSbFpGeHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WMGRYSnVJSFpoYkhWbElHOW1JSFJvWlNCallXeHNZbUZqYTF4dUlDb3ZYRzVSTG1aaGFXd2dQU0F2THlCWVdGZ2diR1ZuWVdONVhHNVJXMXdpWTJGMFkyaGNJbDBnUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wTENCeVpXcGxZM1JsWkNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2t1ZEdobGJpaDJiMmxrSURBc0lISmxhbVZqZEdWa0tUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtWmhhV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaVnRjSW1OaGRHTm9YQ0pkSUQwZ1puVnVZM1JwYjI0Z0tISmxhbVZqZEdWa0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVkR2hsYmloMmIybGtJREFzSUhKbGFtVmpkR1ZrS1R0Y2JuMDdYRzVjYmk4cUtseHVJQ29nUVhSMFlXTm9aWE1nWVNCc2FYTjBaVzVsY2lCMGFHRjBJR05oYmlCeVpYTndiMjVrSUhSdklIQnliMmR5WlhOeklHNXZkR2xtYVdOaGRHbHZibk1nWm5KdmJTQmhYRzRnS2lCd2NtOXRhWE5sSjNNZ2IzSnBaMmx1WVhScGJtY2daR1ZtWlhKeVpXUXVJRlJvYVhNZ2JHbHpkR1Z1WlhJZ2NtVmpaV2wyWlhNZ2RHaGxJR1Y0WVdOMElHRnlaM1Z0Wlc1MGMxeHVJQ29nY0dGemMyVmtJSFJ2SUdCZ1pHVm1aWEp5WldRdWJtOTBhV1o1WUdBdVhHNGdLaUJBY0dGeVlXMGdlMEZ1ZVNwOUlIQnliMjFwYzJVZ1ptOXlJSE52YldWMGFHbHVaMXh1SUNvZ1FIQmhjbUZ0SUh0R2RXNWpkR2x2Ym4wZ1kyRnNiR0poWTJzZ2RHOGdjbVZqWldsMlpTQmhibmtnY0hKdlozSmxjM01nYm05MGFXWnBZMkYwYVc5dWMxeHVJQ29nUUhKbGRIVnlibk1nZEdobElHZHBkbVZ1SUhCeWIyMXBjMlVzSUhWdVkyaGhibWRsWkZ4dUlDb3ZYRzVSTG5CeWIyZHlaWE56SUQwZ2NISnZaM0psYzNNN1hHNW1kVzVqZEdsdmJpQndjbTluY21WemN5aHZZbXBsWTNRc0lIQnliMmR5WlhOelpXUXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaHZZbXBsWTNRcExuUm9aVzRvZG05cFpDQXdMQ0IyYjJsa0lEQXNJSEJ5YjJkeVpYTnpaV1FwTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV3Y205bmNtVnpjeUE5SUdaMWJtTjBhVzl1SUNod2NtOW5jbVZ6YzJWa0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVkR2hsYmloMmIybGtJREFzSUhadmFXUWdNQ3dnY0hKdlozSmxjM05sWkNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZCeWIzWnBaR1Z6SUdGdUlHOXdjRzl5ZEhWdWFYUjVJSFJ2SUc5aWMyVnlkbVVnZEdobElITmxkSFJzYVc1bklHOW1JR0VnY0hKdmJXbHpaU3hjYmlBcUlISmxaMkZ5Wkd4bGMzTWdiMllnZDJobGRHaGxjaUIwYUdVZ2NISnZiV2x6WlNCcGN5Qm1kV3htYVd4c1pXUWdiM0lnY21WcVpXTjBaV1F1SUNCR2IzSjNZWEprYzF4dUlDb2dkR2hsSUhKbGMyOXNkWFJwYjI0Z2RHOGdkR2hsSUhKbGRIVnlibVZrSUhCeWIyMXBjMlVnZDJobGJpQjBhR1VnWTJGc2JHSmhZMnNnYVhNZ1pHOXVaUzVjYmlBcUlGUm9aU0JqWVd4c1ltRmpheUJqWVc0Z2NtVjBkWEp1SUdFZ2NISnZiV2x6WlNCMGJ5QmtaV1psY2lCamIyMXdiR1YwYVc5dUxseHVJQ29nUUhCaGNtRnRJSHRCYm5rcWZTQndjbTl0YVhObFhHNGdLaUJBY0dGeVlXMGdlMFoxYm1OMGFXOXVmU0JqWVd4c1ltRmpheUIwYnlCdlluTmxjblpsSUhSb1pTQnlaWE52YkhWMGFXOXVJRzltSUhSb1pTQm5hWFpsYmx4dUlDb2djSEp2YldselpTd2dkR0ZyWlhNZ2JtOGdZWEpuZFcxbGJuUnpMbHh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVnpiMngxZEdsdmJpQnZaaUIwYUdVZ1oybDJaVzRnY0hKdmJXbHpaU0IzYUdWdVhHNGdLaUJnWUdacGJtQmdJR2x6SUdSdmJtVXVYRzRnS2k5Y2JsRXVabWx1SUQwZ0x5OGdXRmhZSUd4bFoyRmplVnh1VVZ0Y0ltWnBibUZzYkhsY0lsMGdQU0JtZFc1amRHbHZiaUFvYjJKcVpXTjBMQ0JqWVd4c1ltRmpheWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDbGJYQ0ptYVc1aGJHeDVYQ0pkS0dOaGJHeGlZV05yS1R0Y2JuMDdYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1acGJpQTlJQzh2SUZoWVdDQnNaV2RoWTNsY2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbFcxd2labWx1WVd4c2VWd2lYU0E5SUdaMWJtTjBhVzl1SUNoallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUdOaGJHeGlZV05ySUQwZ1VTaGpZV3hzWW1GamF5azdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVkR2hsYmlobWRXNWpkR2x2YmlBb2RtRnNkV1VwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yTG1aallXeHNLQ2t1ZEdobGJpaG1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgwcE8xeHVJQ0FnSUgwc0lHWjFibU4wYVc5dUlDaHlaV0Z6YjI0cElIdGNiaUFnSUNBZ0lDQWdMeThnVkU5RVR5QmhkSFJsYlhCMElIUnZJSEpsWTNsamJHVWdkR2hsSUhKbGFtVmpkR2x2YmlCM2FYUm9JRndpZEdocGMxd2lMbHh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdZMkZzYkdKaFkyc3VabU5oYkd3b0tTNTBhR1Z1S0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhSb2NtOTNJSEpsWVhOdmJqdGNiaUFnSUNBZ0lDQWdmU2s3WEc0Z0lDQWdmU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRlJsY20xcGJtRjBaWE1nWVNCamFHRnBiaUJ2WmlCd2NtOXRhWE5sY3l3Z1ptOXlZMmx1WnlCeVpXcGxZM1JwYjI1eklIUnZJR0psWEc0Z0tpQjBhSEp2ZDI0Z1lYTWdaWGhqWlhCMGFXOXVjeTVjYmlBcUlFQndZWEpoYlNCN1FXNTVLbjBnY0hKdmJXbHpaU0JoZENCMGFHVWdaVzVrSUc5bUlHRWdZMmhoYVc0Z2IyWWdjSEp2YldselpYTmNiaUFxSUVCeVpYUjFjbTV6SUc1dmRHaHBibWRjYmlBcUwxeHVVUzVrYjI1bElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dablZzWm1sc2JHVmtMQ0J5WldwbFkzUmxaQ3dnY0hKdlozSmxjM01wSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJ2Ym1Vb1puVnNabWxzYkdWa0xDQnlaV3BsWTNSbFpDd2djSEp2WjNKbGMzTXBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVaRzl1WlNBOUlHWjFibU4wYVc5dUlDaG1kV3htYVd4c1pXUXNJSEpsYW1WamRHVmtMQ0J3Y205bmNtVnpjeWtnZTF4dUlDQWdJSFpoY2lCdmJsVnVhR0Z1Wkd4bFpFVnljbTl5SUQwZ1puVnVZM1JwYjI0Z0tHVnljbTl5S1NCN1hHNGdJQ0FnSUNBZ0lDOHZJR1p2Y25kaGNtUWdkRzhnWVNCbWRYUjFjbVVnZEhWeWJpQnpieUIwYUdGMElHQmdkMmhsYm1CZ1hHNGdJQ0FnSUNBZ0lDOHZJR1J2WlhNZ2JtOTBJR05oZEdOb0lHbDBJR0Z1WkNCMGRYSnVJR2wwSUdsdWRHOGdZU0J5WldwbFkzUnBiMjR1WEc0Z0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2JXRnJaVk4wWVdOclZISmhZMlZNYjI1bktHVnljbTl5TENCd2NtOXRhWE5sS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoUkxtOXVaWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQlJMbTl1WlhKeWIzSW9aWEp5YjNJcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IwYUhKdmR5Qmxjbkp2Y2p0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnZlR0Y2JseHVJQ0FnSUM4dklFRjJiMmxrSUhWdWJtVmpaWE56WVhKNUlHQnVaWGgwVkdsamEyQnBibWNnZG1saElHRnVJSFZ1Ym1WalpYTnpZWEo1SUdCM2FHVnVZQzVjYmlBZ0lDQjJZWElnY0hKdmJXbHpaU0E5SUdaMWJHWnBiR3hsWkNCOGZDQnlaV3BsWTNSbFpDQjhmQ0J3Y205bmNtVnpjeUEvWEc0Z0lDQWdJQ0FnSUhSb2FYTXVkR2hsYmlobWRXeG1hV3hzWldRc0lISmxhbVZqZEdWa0xDQndjbTluY21WemN5a2dPbHh1SUNBZ0lDQWdJQ0IwYUdsek8xeHVYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQndjbTlqWlhOeklEMDlQU0JjSW05aWFtVmpkRndpSUNZbUlIQnliMk5sYzNNZ0ppWWdjSEp2WTJWemN5NWtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdiMjVWYm1oaGJtUnNaV1JGY25KdmNpQTlJSEJ5YjJObGMzTXVaRzl0WVdsdUxtSnBibVFvYjI1VmJtaGhibVJzWldSRmNuSnZjaWs3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdjSEp2YldselpTNTBhR1Z1S0hadmFXUWdNQ3dnYjI1VmJtaGhibVJzWldSRmNuSnZjaWs3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oZFhObGN5QmhJSEJ5YjIxcGMyVWdkRzhnWW1VZ2NtVnFaV04wWldRZ2FXWWdhWFFnWkc5bGN5QnViM1FnWjJWMElHWjFiR1pwYkd4bFpDQmlaV1p2Y21WY2JpQXFJSE52YldVZ2JXbHNiR2x6WldOdmJtUnpJSFJwYldVZ2IzVjBMbHh1SUNvZ1FIQmhjbUZ0SUh0QmJua3FmU0J3Y205dGFYTmxYRzRnS2lCQWNHRnlZVzBnZTA1MWJXSmxjbjBnYldsc2JHbHpaV052Ym1SeklIUnBiV1Z2ZFhSY2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ1kzVnpkRzl0SUdWeWNtOXlJRzFsYzNOaFoyVWdiM0lnUlhKeWIzSWdiMkpxWldOMElDaHZjSFJwYjI1aGJDbGNiaUFxSUVCeVpYUjFjbTV6SUdFZ2NISnZiV2x6WlNCbWIzSWdkR2hsSUhKbGMyOXNkWFJwYjI0Z2IyWWdkR2hsSUdkcGRtVnVJSEJ5YjIxcGMyVWdhV1lnYVhRZ2FYTmNiaUFxSUdaMWJHWnBiR3hsWkNCaVpXWnZjbVVnZEdobElIUnBiV1Z2ZFhRc0lHOTBhR1Z5ZDJselpTQnlaV3BsWTNSbFpDNWNiaUFxTDF4dVVTNTBhVzFsYjNWMElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2diWE1zSUdWeWNtOXlLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNTBhVzFsYjNWMEtHMXpMQ0JsY25KdmNpazdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBhVzFsYjNWMElEMGdablZ1WTNScGIyNGdLRzF6TENCbGNuSnZjaWtnZTF4dUlDQWdJSFpoY2lCa1pXWmxjbkpsWkNBOUlHUmxabVZ5S0NrN1hHNGdJQ0FnZG1GeUlIUnBiV1Z2ZFhSSlpDQTlJSE5sZEZScGJXVnZkWFFvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvSVdWeWNtOXlJSHg4SUZ3aWMzUnlhVzVuWENJZ1BUMDlJSFI1Y0dWdlppQmxjbkp2Y2lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWlhKeWIzSWdQU0J1WlhjZ1JYSnliM0lvWlhKeWIzSWdmSHdnWENKVWFXMWxaQ0J2ZFhRZ1lXWjBaWElnWENJZ0t5QnRjeUFySUZ3aUlHMXpYQ0lwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdaWEp5YjNJdVkyOWtaU0E5SUZ3aVJWUkpUVVZFVDFWVVhDSTdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnWkdWbVpYSnlaV1F1Y21WcVpXTjBLR1Z5Y205eUtUdGNiaUFnSUNCOUxDQnRjeWs3WEc1Y2JpQWdJQ0IwYUdsekxuUm9aVzRvWm5WdVkzUnBiMjRnS0haaGJIVmxLU0I3WEc0Z0lDQWdJQ0FnSUdOc1pXRnlWR2x0Wlc5MWRDaDBhVzFsYjNWMFNXUXBPMXh1SUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WlhOdmJIWmxLSFpoYkhWbEtUdGNiaUFnSUNCOUxDQm1kVzVqZEdsdmJpQW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUdOc1pXRnlWR2x0Wlc5MWRDaDBhVzFsYjNWMFNXUXBPMXh1SUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WldwbFkzUW9aWGhqWlhCMGFXOXVLVHRjYmlBZ0lDQjlMQ0JrWldabGNuSmxaQzV1YjNScFpua3BPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnWjJsMlpXNGdkbUZzZFdVZ0tHOXlJSEJ5YjIxcGMyVmtJSFpoYkhWbEtTd2djMjl0WlZ4dUlDb2diV2xzYkdselpXTnZibVJ6SUdGbWRHVnlJR2wwSUhKbGMyOXNkbVZrTGlCUVlYTnpaWE1nY21WcVpXTjBhVzl1Y3lCcGJXMWxaR2xoZEdWc2VTNWNiaUFxSUVCd1lYSmhiU0I3UVc1NUtuMGdjSEp2YldselpWeHVJQ29nUUhCaGNtRnRJSHRPZFcxaVpYSjlJRzFwYkd4cGMyVmpiMjVrYzF4dUlDb2dRSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6YjJ4MWRHbHZiaUJ2WmlCMGFHVWdaMmwyWlc0Z2NISnZiV2x6WlNCaFpuUmxjaUJ0YVd4c2FYTmxZMjl1WkhOY2JpQXFJSFJwYldVZ2FHRnpJR1ZzWVhCelpXUWdjMmx1WTJVZ2RHaGxJSEpsYzI5c2RYUnBiMjRnYjJZZ2RHaGxJR2RwZG1WdUlIQnliMjFwYzJVdVhHNGdLaUJKWmlCMGFHVWdaMmwyWlc0Z2NISnZiV2x6WlNCeVpXcGxZM1J6TENCMGFHRjBJR2x6SUhCaGMzTmxaQ0JwYlcxbFpHbGhkR1ZzZVM1Y2JpQXFMMXh1VVM1a1pXeGhlU0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUhScGJXVnZkWFFwSUh0Y2JpQWdJQ0JwWmlBb2RHbHRaVzkxZENBOVBUMGdkbTlwWkNBd0tTQjdYRzRnSUNBZ0lDQWdJSFJwYldWdmRYUWdQU0J2WW1wbFkzUTdYRzRnSUNBZ0lDQWdJRzlpYW1WamRDQTlJSFp2YVdRZ01EdGNiaUFnSUNCOVhHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzVrWld4aGVTaDBhVzFsYjNWMEtUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtUmxiR0Y1SUQwZ1puVnVZM1JwYjI0Z0tIUnBiV1Z2ZFhRcElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NTBhR1Z1S0daMWJtTjBhVzl1SUNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdaR1ZtWlhKeVpXUWdQU0JrWldabGNpZ3BPMXh1SUNBZ0lDQWdJQ0J6WlhSVWFXMWxiM1YwS0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdSbFptVnljbVZrTG5KbGMyOXNkbVVvZG1Gc2RXVXBPMXh1SUNBZ0lDQWdJQ0I5TENCMGFXMWxiM1YwS1R0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc0Z0lDQWdmU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRkJoYzNObGN5QmhJR052Ym5ScGJuVmhkR2x2YmlCMGJ5QmhJRTV2WkdVZ1puVnVZM1JwYjI0c0lIZG9hV05vSUdseklHTmhiR3hsWkNCM2FYUm9JSFJvWlNCbmFYWmxibHh1SUNvZ1lYSm5kVzFsYm5SeklIQnliM1pwWkdWa0lHRnpJR0Z1SUdGeWNtRjVMQ0JoYm1RZ2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVdVhHNGdLbHh1SUNvZ0lDQWdJQ0JSTG01bVlYQndiSGtvUmxNdWNtVmhaRVpwYkdVc0lGdGZYMlpwYkdWdVlXMWxYU2xjYmlBcUlDQWdJQ0FnTG5Sb1pXNG9ablZ1WTNScGIyNGdLR052Ym5SbGJuUXBJSHRjYmlBcUlDQWdJQ0FnZlNsY2JpQXFYRzRnS2k5Y2JsRXVibVpoY0hCc2VTQTlJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheXdnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHTmhiR3hpWVdOcktTNXVabUZ3Y0d4NUtHRnlaM01wTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1Ym1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoaGNtZHpLU0I3WEc0Z0lDQWdkbUZ5SUdSbFptVnljbVZrSUQwZ1pHVm1aWElvS1R0Y2JpQWdJQ0IyWVhJZ2JtOWtaVUZ5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kektUdGNiaUFnSUNCdWIyUmxRWEpuY3k1d2RYTm9LR1JsWm1WeWNtVmtMbTFoYTJWT2IyUmxVbVZ6YjJ4MlpYSW9LU2s3WEc0Z0lDQWdkR2hwY3k1bVlYQndiSGtvYm05a1pVRnlaM01wTG1aaGFXd29aR1ZtWlhKeVpXUXVjbVZxWldOMEtUdGNiaUFnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dVR0Z6YzJWeklHRWdZMjl1ZEdsdWRXRjBhVzl1SUhSdklHRWdUbTlrWlNCbWRXNWpkR2x2Yml3Z2QyaHBZMmdnYVhNZ1kyRnNiR1ZrSUhkcGRHZ2dkR2hsSUdkcGRtVnVYRzRnS2lCaGNtZDFiV1Z1ZEhNZ2NISnZkbWxrWldRZ2FXNWthWFpwWkhWaGJHeDVMQ0JoYm1RZ2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVdVhHNGdLaUJBWlhoaGJYQnNaVnh1SUNvZ1VTNXVabU5oYkd3b1JsTXVjbVZoWkVacGJHVXNJRjlmWm1sc1pXNWhiV1VwWEc0Z0tpQXVkR2hsYmlobWRXNWpkR2x2YmlBb1kyOXVkR1Z1ZENrZ2UxeHVJQ29nZlNsY2JpQXFYRzRnS2k5Y2JsRXVibVpqWVd4c0lEMGdablZ1WTNScGIyNGdLR05oYkd4aVlXTnJJQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlHRnlaM01nUFNCaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXNJREVwTzF4dUlDQWdJSEpsZEhWeWJpQlJLR05oYkd4aVlXTnJLUzV1Wm1Gd2NHeDVLR0Z5WjNNcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtWmpZV3hzSUQwZ1puVnVZM1JwYjI0Z0tDOHFMaTR1WVhKbmN5b3ZLU0I3WEc0Z0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpLVHRjYmlBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJRzV2WkdWQmNtZHpMbkIxYzJnb1pHVm1aWEp5WldRdWJXRnJaVTV2WkdWU1pYTnZiSFpsY2lncEtUdGNiaUFnSUNCMGFHbHpMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJSEpsZEhWeWJpQmtaV1psY25KbFpDNXdjbTl0YVhObE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCWGNtRndjeUJoSUU1dlpHVktVeUJqYjI1MGFXNTFZWFJwYjI0Z2NHRnpjMmx1WnlCbWRXNWpkR2x2YmlCaGJtUWdjbVYwZFhKdWN5QmhiaUJsY1hWcGRtRnNaVzUwWEc0Z0tpQjJaWEp6YVc5dUlIUm9ZWFFnY21WMGRYSnVjeUJoSUhCeWIyMXBjMlV1WEc0Z0tpQkFaWGhoYlhCc1pWeHVJQ29nVVM1dVptSnBibVFvUmxNdWNtVmhaRVpwYkdVc0lGOWZabWxzWlc1aGJXVXBLRndpZFhSbUxUaGNJaWxjYmlBcUlDNTBhR1Z1S0dOdmJuTnZiR1V1Ykc5bktWeHVJQ29nTG1SdmJtVW9LVnh1SUNvdlhHNVJMbTVtWW1sdVpDQTlYRzVSTG1SbGJtOWtaV2xtZVNBOUlHWjFibU4wYVc5dUlDaGpZV3hzWW1GamF5QXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSFpoY2lCaVlYTmxRWEpuY3lBOUlHRnljbUY1WDNOc2FXTmxLR0Z5WjNWdFpXNTBjeXdnTVNrN1hHNGdJQ0FnY21WMGRYSnVJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2RtRnlJRzV2WkdWQmNtZHpJRDBnWW1GelpVRnlaM011WTI5dVkyRjBLR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3lrcE8xeHVJQ0FnSUNBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJQ0FnSUNCdWIyUmxRWEpuY3k1d2RYTm9LR1JsWm1WeWNtVmtMbTFoYTJWT2IyUmxVbVZ6YjJ4MlpYSW9LU2s3WEc0Z0lDQWdJQ0FnSUZFb1kyRnNiR0poWTJzcExtWmhjSEJzZVNodWIyUmxRWEpuY3lrdVptRnBiQ2hrWldabGNuSmxaQzV5WldwbFkzUXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNiaUFnSUNCOU8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtWmlhVzVrSUQxY2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtUmxibTlrWldsbWVTQTlJR1oxYm1OMGFXOXVJQ2d2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmhjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpLVHRjYmlBZ0lDQmhjbWR6TG5WdWMyaHBablFvZEdocGN5azdYRzRnSUNBZ2NtVjBkWEp1SUZFdVpHVnViMlJsYVdaNUxtRndjR3g1S0hadmFXUWdNQ3dnWVhKbmN5azdYRzU5TzF4dVhHNVJMbTVpYVc1a0lEMGdablZ1WTNScGIyNGdLR05oYkd4aVlXTnJMQ0IwYUdsemNDQXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSFpoY2lCaVlYTmxRWEpuY3lBOUlHRnljbUY1WDNOc2FXTmxLR0Z5WjNWdFpXNTBjeXdnTWlrN1hHNGdJQ0FnY21WMGRYSnVJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2RtRnlJRzV2WkdWQmNtZHpJRDBnWW1GelpVRnlaM011WTI5dVkyRjBLR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3lrcE8xeHVJQ0FnSUNBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJQ0FnSUNCdWIyUmxRWEpuY3k1d2RYTm9LR1JsWm1WeWNtVmtMbTFoYTJWT2IyUmxVbVZ6YjJ4MlpYSW9LU2s3WEc0Z0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUdKdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtRndjR3g1S0hSb2FYTndMQ0JoY21kMWJXVnVkSE1wTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lGRW9ZbTkxYm1RcExtWmhjSEJzZVNodWIyUmxRWEpuY3lrdVptRnBiQ2hrWldabGNuSmxaQzV5WldwbFkzUXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNiaUFnSUNCOU8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtSnBibVFnUFNCbWRXNWpkR2x2YmlBb0x5cDBhR2x6Y0N3Z0xpNHVZWEpuY3lvdktTQjdYRzRnSUNBZ2RtRnlJR0Z5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kMWJXVnVkSE1zSURBcE8xeHVJQ0FnSUdGeVozTXVkVzV6YUdsbWRDaDBhR2x6S1R0Y2JpQWdJQ0J5WlhSMWNtNGdVUzV1WW1sdVpDNWhjSEJzZVNoMmIybGtJREFzSUdGeVozTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkRZV3hzY3lCaElHMWxkR2h2WkNCdlppQmhJRTV2WkdVdGMzUjViR1VnYjJKcVpXTjBJSFJvWVhRZ1lXTmpaWEIwY3lCaElFNXZaR1V0YzNSNWJHVmNiaUFxSUdOaGJHeGlZV05ySUhkcGRHZ2dZU0JuYVhabGJpQmhjbkpoZVNCdlppQmhjbWQxYldWdWRITXNJSEJzZFhNZ1lTQndjbTkyYVdSbFpDQmpZV3hzWW1GamF5NWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdZVzRnYjJKcVpXTjBJSFJvWVhRZ2FHRnpJSFJvWlNCdVlXMWxaQ0J0WlhSb2IyUmNiaUFxSUVCd1lYSmhiU0I3VTNSeWFXNW5mU0J1WVcxbElHNWhiV1VnYjJZZ2RHaGxJRzFsZEdodlpDQnZaaUJ2WW1wbFkzUmNiaUFxSUVCd1lYSmhiU0I3UVhKeVlYbDlJR0Z5WjNNZ1lYSm5kVzFsYm5SeklIUnZJSEJoYzNNZ2RHOGdkR2hsSUcxbGRHaHZaRHNnZEdobElHTmhiR3hpWVdOclhHNGdLaUIzYVd4c0lHSmxJSEJ5YjNacFpHVmtJR0o1SUZFZ1lXNWtJR0Z3Y0dWdVpHVmtJSFJ2SUhSb1pYTmxJR0Z5WjNWdFpXNTBjeTVjYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1iM0lnZEdobElIWmhiSFZsSUc5eUlHVnljbTl5WEc0Z0tpOWNibEV1Ym0xaGNIQnNlU0E5SUM4dklGaFlXQ0JCY3lCd2NtOXdiM05sWkNCaWVTQmNJbEpsWkhOaGJtUnliMXdpWEc1UkxtNXdiM04wSUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZEN3Z2JtRnRaU3dnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdWJuQnZjM1FvYm1GdFpTd2dZWEpuY3lrN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWJXRndjR3g1SUQwZ0x5OGdXRmhZSUVGeklIQnliM0J2YzJWa0lHSjVJRndpVW1Wa2MyRnVaSEp2WENKY2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtNXdiM04wSUQwZ1puVnVZM1JwYjI0Z0tHNWhiV1VzSUdGeVozTXBJSHRjYmlBZ0lDQjJZWElnYm05a1pVRnlaM01nUFNCaGNuSmhlVjl6YkdsalpTaGhjbWR6SUh4OElGdGRLVHRjYmlBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJRzV2WkdWQmNtZHpMbkIxYzJnb1pHVm1aWEp5WldRdWJXRnJaVTV2WkdWU1pYTnZiSFpsY2lncEtUdGNiaUFnSUNCMGFHbHpMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dibTlrWlVGeVozTmRLUzVtWVdsc0tHUmxabVZ5Y21Wa0xuSmxhbVZqZENrN1hHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFTmhiR3h6SUdFZ2JXVjBhRzlrSUc5bUlHRWdUbTlrWlMxemRIbHNaU0J2WW1wbFkzUWdkR2hoZENCaFkyTmxjSFJ6SUdFZ1RtOWtaUzF6ZEhsc1pWeHVJQ29nWTJGc2JHSmhZMnNzSUdadmNuZGhjbVJwYm1jZ2RHaGxJR2RwZG1WdUlIWmhjbWxoWkdsaklHRnlaM1Z0Wlc1MGN5d2djR3gxY3lCaElIQnliM1pwWkdWa1hHNGdLaUJqWVd4c1ltRmpheUJoY21kMWJXVnVkQzVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVc0Z2IySnFaV04wSUhSb1lYUWdhR0Z6SUhSb1pTQnVZVzFsWkNCdFpYUm9iMlJjYmlBcUlFQndZWEpoYlNCN1UzUnlhVzVuZlNCdVlXMWxJRzVoYldVZ2IyWWdkR2hsSUcxbGRHaHZaQ0J2WmlCdlltcGxZM1JjYmlBcUlFQndZWEpoYlNBdUxpNWhjbWR6SUdGeVozVnRaVzUwY3lCMGJ5QndZWE56SUhSdklIUm9aU0J0WlhSb2IyUTdJSFJvWlNCallXeHNZbUZqYXlCM2FXeHNYRzRnS2lCaVpTQndjbTkyYVdSbFpDQmllU0JSSUdGdVpDQmhjSEJsYm1SbFpDQjBieUIwYUdWelpTQmhjbWQxYldWdWRITXVYRzRnS2lCQWNtVjBkWEp1Y3lCaElIQnliMjFwYzJVZ1ptOXlJSFJvWlNCMllXeDFaU0J2Y2lCbGNuSnZjbHh1SUNvdlhHNVJMbTV6Wlc1a0lEMGdMeThnV0ZoWUlFSmhjMlZrSUc5dUlFMWhjbXNnVFdsc2JHVnlKM01nY0hKdmNHOXpaV1FnWENKelpXNWtYQ0pjYmxFdWJtMWpZV3hzSUQwZ0x5OGdXRmhZSUVKaGMyVmtJRzl1SUZ3aVVtVmtjMkZ1WkhKdkozTmNJaUJ3Y205d2IzTmhiRnh1VVM1dWFXNTJiMnRsSUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZEN3Z2JtRnRaU0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQnViMlJsUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01pazdYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnYm05a1pVRnlaM05kS1M1bVlXbHNLR1JsWm1WeWNtVmtMbkpsYW1WamRDazdYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OU8xeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV1YzJWdVpDQTlJQzh2SUZoWVdDQkNZWE5sWkNCdmJpQk5ZWEpySUUxcGJHeGxjaWR6SUhCeWIzQnZjMlZrSUZ3aWMyVnVaRndpWEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWJXTmhiR3dnUFNBdkx5QllXRmdnUW1GelpXUWdiMjRnWENKU1pXUnpZVzVrY204bmMxd2lJSEJ5YjNCdmMyRnNYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV1YVc1MmIydGxJRDBnWm5WdVkzUnBiMjRnS0c1aGJXVWdMeW91TGk1aGNtZHpLaThwSUh0Y2JpQWdJQ0IyWVhJZ2JtOWtaVUZ5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kMWJXVnVkSE1zSURFcE8xeHVJQ0FnSUhaaGNpQmtaV1psY25KbFpDQTlJR1JsWm1WeUtDazdYRzRnSUNBZ2JtOWtaVUZ5WjNNdWNIVnphQ2hrWldabGNuSmxaQzV0WVd0bFRtOWtaVkpsYzI5c2RtVnlLQ2twTzF4dUlDQWdJSFJvYVhNdVpHbHpjR0YwWTJnb1hDSndiM04wWENJc0lGdHVZVzFsTENCdWIyUmxRWEpuYzEwcExtWmhhV3dvWkdWbVpYSnlaV1F1Y21WcVpXTjBLVHRjYmlBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JuMDdYRzVjYmk4cUtseHVJQ29nU1dZZ1lTQm1kVzVqZEdsdmJpQjNiM1ZzWkNCc2FXdGxJSFJ2SUhOMWNIQnZjblFnWW05MGFDQk9iMlJsSUdOdmJuUnBiblZoZEdsdmJpMXdZWE56YVc1bkxYTjBlV3hsSUdGdVpGeHVJQ29nY0hKdmJXbHpaUzF5WlhSMWNtNXBibWN0YzNSNWJHVXNJR2wwSUdOaGJpQmxibVFnYVhSeklHbHVkR1Z5Ym1Gc0lIQnliMjFwYzJVZ1kyaGhhVzRnZDJsMGFGeHVJQ29nWUc1dlpHVnBabmtvYm05a1pXSmhZMnNwWUN3Z1ptOXlkMkZ5WkdsdVp5QjBhR1VnYjNCMGFXOXVZV3dnYm05a1pXSmhZMnNnWVhKbmRXMWxiblF1SUNCSlppQjBhR1VnZFhObGNseHVJQ29nWld4bFkzUnpJSFJ2SUhWelpTQmhJRzV2WkdWaVlXTnJMQ0IwYUdVZ2NtVnpkV3gwSUhkcGJHd2dZbVVnYzJWdWRDQjBhR1Z5WlM0Z0lFbG1JSFJvWlhrZ1pHOGdibTkwWEc0Z0tpQndZWE56SUdFZ2JtOWtaV0poWTJzc0lIUm9aWGtnZDJsc2JDQnlaV05sYVhabElIUm9aU0J5WlhOMWJIUWdjSEp2YldselpTNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdZU0J5WlhOMWJIUWdLRzl5SUdFZ2NISnZiV2x6WlNCbWIzSWdZU0J5WlhOMWJIUXBYRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCdWIyUmxZbUZqYXlCaElFNXZaR1V1YW5NdGMzUjViR1VnWTJGc2JHSmhZMnRjYmlBcUlFQnlaWFIxY201eklHVnBkR2hsY2lCMGFHVWdjSEp2YldselpTQnZjaUJ1YjNSb2FXNW5YRzRnS2k5Y2JsRXVibTlrWldsbWVTQTlJRzV2WkdWcFpuazdYRzVtZFc1amRHbHZiaUJ1YjJSbGFXWjVLRzlpYW1WamRDd2dibTlrWldKaFkyc3BJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaHZZbXBsWTNRcExtNXZaR1ZwWm5rb2JtOWtaV0poWTJzcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWIyUmxhV1o1SUQwZ1puVnVZM1JwYjI0Z0tHNXZaR1ZpWVdOcktTQjdYRzRnSUNBZ2FXWWdLRzV2WkdWaVlXTnJLU0I3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVkR2hsYmlobWRXNWpkR2x2YmlBb2RtRnNkV1VwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJRkV1Ym1WNGRGUnBZMnNvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHNXZaR1ZpWVdOcktHNTFiR3dzSUhaaGJIVmxLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIMHBPMXh1SUNBZ0lDQWdJQ0I5TENCbWRXNWpkR2x2YmlBb1pYSnliM0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJRkV1Ym1WNGRGUnBZMnNvWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHNXZaR1ZpWVdOcktHVnljbTl5S1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDBwTzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZEdocGN6dGNiaUFnSUNCOVhHNTlPMXh1WEc1UkxtNXZRMjl1Wm14cFkzUWdQU0JtZFc1amRHbHZiaWdwSUh0Y2JpQWdJQ0IwYUhKdmR5QnVaWGNnUlhKeWIzSW9YQ0pSTG01dlEyOXVabXhwWTNRZ2IyNXNlU0IzYjNKcmN5QjNhR1Z1SUZFZ2FYTWdkWE5sWkNCaGN5QmhJR2RzYjJKaGJGd2lLVHRjYm4wN1hHNWNiaTh2SUVGc2JDQmpiMlJsSUdKbFptOXlaU0IwYUdseklIQnZhVzUwSUhkcGJHd2dZbVVnWm1sc2RHVnlaV1FnWm5KdmJTQnpkR0ZqYXlCMGNtRmpaWE11WEc1MllYSWdjVVZ1WkdsdVoweHBibVVnUFNCallYQjBkWEpsVEdsdVpTZ3BPMXh1WEc1eVpYUjFjbTRnVVR0Y2JseHVmU2s3WEc0aVhYMD0iLCIvKipcbiAqIFJvb3QgcmVmZXJlbmNlIGZvciBpZnJhbWVzLlxuICovXG5cbnZhciByb290O1xuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7IC8vIEJyb3dzZXIgd2luZG93XG4gIHJvb3QgPSB3aW5kb3c7XG59IGVsc2UgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJykgeyAvLyBXZWIgV29ya2VyXG4gIHJvb3QgPSBzZWxmO1xufSBlbHNlIHsgLy8gT3RoZXIgZW52aXJvbm1lbnRzXG4gIGNvbnNvbGUud2FybihcIlVzaW5nIGJyb3dzZXItb25seSB2ZXJzaW9uIG9mIHN1cGVyYWdlbnQgaW4gbm9uLWJyb3dzZXIgZW52aXJvbm1lbnRcIik7XG4gIHJvb3QgPSB0aGlzO1xufVxuXG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2VtaXR0ZXInKTtcbnZhciByZXF1ZXN0QmFzZSA9IHJlcXVpcmUoJy4vcmVxdWVzdC1iYXNlJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzLW9iamVjdCcpO1xuXG4vKipcbiAqIE5vb3AuXG4gKi9cblxuZnVuY3Rpb24gbm9vcCgpe307XG5cbi8qKlxuICogRXhwb3NlIGByZXF1ZXN0YC5cbiAqL1xuXG52YXIgcmVxdWVzdCA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9yZXF1ZXN0JykuYmluZChudWxsLCBSZXF1ZXN0KTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgWEhSLlxuICovXG5cbnJlcXVlc3QuZ2V0WEhSID0gZnVuY3Rpb24gKCkge1xuICBpZiAocm9vdC5YTUxIdHRwUmVxdWVzdFxuICAgICAgJiYgKCFyb290LmxvY2F0aW9uIHx8ICdmaWxlOicgIT0gcm9vdC5sb2NhdGlvbi5wcm90b2NvbFxuICAgICAgICAgIHx8ICFyb290LkFjdGl2ZVhPYmplY3QpKSB7XG4gICAgcmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdDtcbiAgfSBlbHNlIHtcbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01pY3Jvc29mdC5YTUxIVFRQJyk7IH0gY2F0Y2goZSkge31cbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQLjYuMCcpOyB9IGNhdGNoKGUpIHt9XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUC4zLjAnKTsgfSBjYXRjaChlKSB7fVxuICAgIHRyeSB7IHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTXN4bWwyLlhNTEhUVFAnKTsgfSBjYXRjaChlKSB7fVxuICB9XG4gIHRocm93IEVycm9yKFwiQnJvd3Nlci1vbmx5IHZlcmlzb24gb2Ygc3VwZXJhZ2VudCBjb3VsZCBub3QgZmluZCBYSFJcIik7XG59O1xuXG4vKipcbiAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSwgYWRkZWQgdG8gc3VwcG9ydCBJRS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxudmFyIHRyaW0gPSAnJy50cmltXG4gID8gZnVuY3Rpb24ocykgeyByZXR1cm4gcy50cmltKCk7IH1cbiAgOiBmdW5jdGlvbihzKSB7IHJldHVybiBzLnJlcGxhY2UoLyheXFxzKnxcXHMqJCkvZywgJycpOyB9O1xuXG4vKipcbiAqIFNlcmlhbGl6ZSB0aGUgZ2l2ZW4gYG9iamAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VyaWFsaXplKG9iaikge1xuICBpZiAoIWlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gIHZhciBwYWlycyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSwgb2JqW2tleV0pO1xuICB9XG4gIHJldHVybiBwYWlycy5qb2luKCcmJyk7XG59XG5cbi8qKlxuICogSGVscHMgJ3NlcmlhbGl6ZScgd2l0aCBzZXJpYWxpemluZyBhcnJheXMuXG4gKiBNdXRhdGVzIHRoZSBwYWlycyBhcnJheS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwYWlyc1xuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHtNaXhlZH0gdmFsXG4gKi9cblxuZnVuY3Rpb24gcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSwgdmFsKSB7XG4gIGlmICh2YWwgIT0gbnVsbCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICAgIHZhbC5mb3JFYWNoKGZ1bmN0aW9uKHYpIHtcbiAgICAgICAgcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSwgdik7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHZhbCkpIHtcbiAgICAgIGZvcih2YXIgc3Via2V5IGluIHZhbCkge1xuICAgICAgICBwdXNoRW5jb2RlZEtleVZhbHVlUGFpcihwYWlycywga2V5ICsgJ1snICsgc3Via2V5ICsgJ10nLCB2YWxbc3Via2V5XSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSlcbiAgICAgICAgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQodmFsKSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHZhbCA9PT0gbnVsbCkge1xuICAgIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSkpO1xuICB9XG59XG5cbi8qKlxuICogRXhwb3NlIHNlcmlhbGl6YXRpb24gbWV0aG9kLlxuICovXG5cbiByZXF1ZXN0LnNlcmlhbGl6ZU9iamVjdCA9IHNlcmlhbGl6ZTtcblxuIC8qKlxuICAqIFBhcnNlIHRoZSBnaXZlbiB4LXd3dy1mb3JtLXVybGVuY29kZWQgYHN0cmAuXG4gICpcbiAgKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gICogQHJldHVybiB7T2JqZWN0fVxuICAqIEBhcGkgcHJpdmF0ZVxuICAqL1xuXG5mdW5jdGlvbiBwYXJzZVN0cmluZyhzdHIpIHtcbiAgdmFyIG9iaiA9IHt9O1xuICB2YXIgcGFpcnMgPSBzdHIuc3BsaXQoJyYnKTtcbiAgdmFyIHBhaXI7XG4gIHZhciBwb3M7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHBhaXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgcGFpciA9IHBhaXJzW2ldO1xuICAgIHBvcyA9IHBhaXIuaW5kZXhPZignPScpO1xuICAgIGlmIChwb3MgPT0gLTEpIHtcbiAgICAgIG9ialtkZWNvZGVVUklDb21wb25lbnQocGFpcildID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9ialtkZWNvZGVVUklDb21wb25lbnQocGFpci5zbGljZSgwLCBwb3MpKV0gPVxuICAgICAgICBkZWNvZGVVUklDb21wb25lbnQocGFpci5zbGljZShwb3MgKyAxKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBFeHBvc2UgcGFyc2VyLlxuICovXG5cbnJlcXVlc3QucGFyc2VTdHJpbmcgPSBwYXJzZVN0cmluZztcblxuLyoqXG4gKiBEZWZhdWx0IE1JTUUgdHlwZSBtYXAuXG4gKlxuICogICAgIHN1cGVyYWdlbnQudHlwZXMueG1sID0gJ2FwcGxpY2F0aW9uL3htbCc7XG4gKlxuICovXG5cbnJlcXVlc3QudHlwZXMgPSB7XG4gIGh0bWw6ICd0ZXh0L2h0bWwnLFxuICBqc29uOiAnYXBwbGljYXRpb24vanNvbicsXG4gIHhtbDogJ2FwcGxpY2F0aW9uL3htbCcsXG4gIHVybGVuY29kZWQ6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybS1kYXRhJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcbn07XG5cbi8qKlxuICogRGVmYXVsdCBzZXJpYWxpemF0aW9uIG1hcC5cbiAqXG4gKiAgICAgc3VwZXJhZ2VudC5zZXJpYWxpemVbJ2FwcGxpY2F0aW9uL3htbCddID0gZnVuY3Rpb24ob2JqKXtcbiAqICAgICAgIHJldHVybiAnZ2VuZXJhdGVkIHhtbCBoZXJlJztcbiAqICAgICB9O1xuICpcbiAqL1xuXG4gcmVxdWVzdC5zZXJpYWxpemUgPSB7XG4gICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogc2VyaWFsaXplLFxuICAgJ2FwcGxpY2F0aW9uL2pzb24nOiBKU09OLnN0cmluZ2lmeVxuIH07XG5cbiAvKipcbiAgKiBEZWZhdWx0IHBhcnNlcnMuXG4gICpcbiAgKiAgICAgc3VwZXJhZ2VudC5wYXJzZVsnYXBwbGljYXRpb24veG1sJ10gPSBmdW5jdGlvbihzdHIpe1xuICAqICAgICAgIHJldHVybiB7IG9iamVjdCBwYXJzZWQgZnJvbSBzdHIgfTtcbiAgKiAgICAgfTtcbiAgKlxuICAqL1xuXG5yZXF1ZXN0LnBhcnNlID0ge1xuICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogcGFyc2VTdHJpbmcsXG4gICdhcHBsaWNhdGlvbi9qc29uJzogSlNPTi5wYXJzZVxufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gaGVhZGVyIGBzdHJgIGludG9cbiAqIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBtYXBwZWQgZmllbGRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlSGVhZGVyKHN0cikge1xuICB2YXIgbGluZXMgPSBzdHIuc3BsaXQoL1xccj9cXG4vKTtcbiAgdmFyIGZpZWxkcyA9IHt9O1xuICB2YXIgaW5kZXg7XG4gIHZhciBsaW5lO1xuICB2YXIgZmllbGQ7XG4gIHZhciB2YWw7XG5cbiAgbGluZXMucG9wKCk7IC8vIHRyYWlsaW5nIENSTEZcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGluZXMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBsaW5lID0gbGluZXNbaV07XG4gICAgaW5kZXggPSBsaW5lLmluZGV4T2YoJzonKTtcbiAgICBmaWVsZCA9IGxpbmUuc2xpY2UoMCwgaW5kZXgpLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFsID0gdHJpbShsaW5lLnNsaWNlKGluZGV4ICsgMSkpO1xuICAgIGZpZWxkc1tmaWVsZF0gPSB2YWw7XG4gIH1cblxuICByZXR1cm4gZmllbGRzO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGBtaW1lYCBpcyBqc29uIG9yIGhhcyAranNvbiBzdHJ1Y3R1cmVkIHN5bnRheCBzdWZmaXguXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0pTT04obWltZSkge1xuICByZXR1cm4gL1tcXC8rXWpzb25cXGIvLnRlc3QobWltZSk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBtaW1lIHR5cGUgZm9yIHRoZSBnaXZlbiBgc3RyYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiB0eXBlKHN0cil7XG4gIHJldHVybiBzdHIuc3BsaXQoLyAqOyAqLykuc2hpZnQoKTtcbn07XG5cbi8qKlxuICogUmV0dXJuIGhlYWRlciBmaWVsZCBwYXJhbWV0ZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcmFtcyhzdHIpe1xuICByZXR1cm4gc3RyLnNwbGl0KC8gKjsgKi8pLnJlZHVjZShmdW5jdGlvbihvYmosIHN0cil7XG4gICAgdmFyIHBhcnRzID0gc3RyLnNwbGl0KC8gKj0gKi8pLFxuICAgICAgICBrZXkgPSBwYXJ0cy5zaGlmdCgpLFxuICAgICAgICB2YWwgPSBwYXJ0cy5zaGlmdCgpO1xuXG4gICAgaWYgKGtleSAmJiB2YWwpIG9ialtrZXldID0gdmFsO1xuICAgIHJldHVybiBvYmo7XG4gIH0sIHt9KTtcbn07XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgUmVzcG9uc2VgIHdpdGggdGhlIGdpdmVuIGB4aHJgLlxuICpcbiAqICAtIHNldCBmbGFncyAoLm9rLCAuZXJyb3IsIGV0YylcbiAqICAtIHBhcnNlIGhlYWRlclxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICBBbGlhc2luZyBgc3VwZXJhZ2VudGAgYXMgYHJlcXVlc3RgIGlzIG5pY2U6XG4gKlxuICogICAgICByZXF1ZXN0ID0gc3VwZXJhZ2VudDtcbiAqXG4gKiAgV2UgY2FuIHVzZSB0aGUgcHJvbWlzZS1saWtlIEFQSSwgb3IgcGFzcyBjYWxsYmFja3M6XG4gKlxuICogICAgICByZXF1ZXN0LmdldCgnLycpLmVuZChmdW5jdGlvbihyZXMpe30pO1xuICogICAgICByZXF1ZXN0LmdldCgnLycsIGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogIFNlbmRpbmcgZGF0YSBjYW4gYmUgY2hhaW5lZDpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInKVxuICogICAgICAgIC5zZW5kKHsgbmFtZTogJ3RqJyB9KVxuICogICAgICAgIC5lbmQoZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiAgT3IgcGFzc2VkIHRvIGAuc2VuZCgpYDpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInKVxuICogICAgICAgIC5zZW5kKHsgbmFtZTogJ3RqJyB9LCBmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqICBPciBwYXNzZWQgdG8gYC5wb3N0KClgOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicsIHsgbmFtZTogJ3RqJyB9KVxuICogICAgICAgIC5lbmQoZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiBPciBmdXJ0aGVyIHJlZHVjZWQgdG8gYSBzaW5nbGUgY2FsbCBmb3Igc2ltcGxlIGNhc2VzOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicsIHsgbmFtZTogJ3RqJyB9LCBmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqIEBwYXJhbSB7WE1MSFRUUFJlcXVlc3R9IHhoclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIFJlc3BvbnNlKHJlcSwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgdGhpcy5yZXEgPSByZXE7XG4gIHRoaXMueGhyID0gdGhpcy5yZXEueGhyO1xuICAvLyByZXNwb25zZVRleHQgaXMgYWNjZXNzaWJsZSBvbmx5IGlmIHJlc3BvbnNlVHlwZSBpcyAnJyBvciAndGV4dCcgYW5kIG9uIG9sZGVyIGJyb3dzZXJzXG4gIHRoaXMudGV4dCA9ICgodGhpcy5yZXEubWV0aG9kICE9J0hFQUQnICYmICh0aGlzLnhoci5yZXNwb25zZVR5cGUgPT09ICcnIHx8IHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9PT0gJ3RleHQnKSkgfHwgdHlwZW9mIHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9PT0gJ3VuZGVmaW5lZCcpXG4gICAgID8gdGhpcy54aHIucmVzcG9uc2VUZXh0XG4gICAgIDogbnVsbDtcbiAgdGhpcy5zdGF0dXNUZXh0ID0gdGhpcy5yZXEueGhyLnN0YXR1c1RleHQ7XG4gIHRoaXMuX3NldFN0YXR1c1Byb3BlcnRpZXModGhpcy54aHIuc3RhdHVzKTtcbiAgdGhpcy5oZWFkZXIgPSB0aGlzLmhlYWRlcnMgPSBwYXJzZUhlYWRlcih0aGlzLnhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSk7XG4gIC8vIGdldEFsbFJlc3BvbnNlSGVhZGVycyBzb21ldGltZXMgZmFsc2VseSByZXR1cm5zIFwiXCIgZm9yIENPUlMgcmVxdWVzdHMsIGJ1dFxuICAvLyBnZXRSZXNwb25zZUhlYWRlciBzdGlsbCB3b3Jrcy4gc28gd2UgZ2V0IGNvbnRlbnQtdHlwZSBldmVuIGlmIGdldHRpbmdcbiAgLy8gb3RoZXIgaGVhZGVycyBmYWlscy5cbiAgdGhpcy5oZWFkZXJbJ2NvbnRlbnQtdHlwZSddID0gdGhpcy54aHIuZ2V0UmVzcG9uc2VIZWFkZXIoJ2NvbnRlbnQtdHlwZScpO1xuICB0aGlzLl9zZXRIZWFkZXJQcm9wZXJ0aWVzKHRoaXMuaGVhZGVyKTtcbiAgdGhpcy5ib2R5ID0gdGhpcy5yZXEubWV0aG9kICE9ICdIRUFEJ1xuICAgID8gdGhpcy5fcGFyc2VCb2R5KHRoaXMudGV4dCA/IHRoaXMudGV4dCA6IHRoaXMueGhyLnJlc3BvbnNlKVxuICAgIDogbnVsbDtcbn1cblxuLyoqXG4gKiBHZXQgY2FzZS1pbnNlbnNpdGl2ZSBgZmllbGRgIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oZmllbGQpe1xuICByZXR1cm4gdGhpcy5oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV07XG59O1xuXG4vKipcbiAqIFNldCBoZWFkZXIgcmVsYXRlZCBwcm9wZXJ0aWVzOlxuICpcbiAqICAgLSBgLnR5cGVgIHRoZSBjb250ZW50IHR5cGUgd2l0aG91dCBwYXJhbXNcbiAqXG4gKiBBIHJlc3BvbnNlIG9mIFwiQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04XCJcbiAqIHdpbGwgcHJvdmlkZSB5b3Ugd2l0aCBhIGAudHlwZWAgb2YgXCJ0ZXh0L3BsYWluXCIuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGhlYWRlclxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLl9zZXRIZWFkZXJQcm9wZXJ0aWVzID0gZnVuY3Rpb24oaGVhZGVyKXtcbiAgLy8gY29udGVudC10eXBlXG4gIHZhciBjdCA9IHRoaXMuaGVhZGVyWydjb250ZW50LXR5cGUnXSB8fCAnJztcbiAgdGhpcy50eXBlID0gdHlwZShjdCk7XG5cbiAgLy8gcGFyYW1zXG4gIHZhciBvYmogPSBwYXJhbXMoY3QpO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB0aGlzW2tleV0gPSBvYmpba2V5XTtcbn07XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGJvZHkgYHN0cmAuXG4gKlxuICogVXNlZCBmb3IgYXV0by1wYXJzaW5nIG9mIGJvZGllcy4gUGFyc2Vyc1xuICogYXJlIGRlZmluZWQgb24gdGhlIGBzdXBlcmFnZW50LnBhcnNlYCBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuX3BhcnNlQm9keSA9IGZ1bmN0aW9uKHN0cil7XG4gIHZhciBwYXJzZSA9IHJlcXVlc3QucGFyc2VbdGhpcy50eXBlXTtcbiAgaWYgKCFwYXJzZSAmJiBpc0pTT04odGhpcy50eXBlKSkge1xuICAgIHBhcnNlID0gcmVxdWVzdC5wYXJzZVsnYXBwbGljYXRpb24vanNvbiddO1xuICB9XG4gIHJldHVybiBwYXJzZSAmJiBzdHIgJiYgKHN0ci5sZW5ndGggfHwgc3RyIGluc3RhbmNlb2YgT2JqZWN0KVxuICAgID8gcGFyc2Uoc3RyKVxuICAgIDogbnVsbDtcbn07XG5cbi8qKlxuICogU2V0IGZsYWdzIHN1Y2ggYXMgYC5va2AgYmFzZWQgb24gYHN0YXR1c2AuXG4gKlxuICogRm9yIGV4YW1wbGUgYSAyeHggcmVzcG9uc2Ugd2lsbCBnaXZlIHlvdSBhIGAub2tgIG9mIF9fdHJ1ZV9fXG4gKiB3aGVyZWFzIDV4eCB3aWxsIGJlIF9fZmFsc2VfXyBhbmQgYC5lcnJvcmAgd2lsbCBiZSBfX3RydWVfXy4gVGhlXG4gKiBgLmNsaWVudEVycm9yYCBhbmQgYC5zZXJ2ZXJFcnJvcmAgYXJlIGFsc28gYXZhaWxhYmxlIHRvIGJlIG1vcmVcbiAqIHNwZWNpZmljLCBhbmQgYC5zdGF0dXNUeXBlYCBpcyB0aGUgY2xhc3Mgb2YgZXJyb3IgcmFuZ2luZyBmcm9tIDEuLjVcbiAqIHNvbWV0aW1lcyB1c2VmdWwgZm9yIG1hcHBpbmcgcmVzcG9uZCBjb2xvcnMgZXRjLlxuICpcbiAqIFwic3VnYXJcIiBwcm9wZXJ0aWVzIGFyZSBhbHNvIGRlZmluZWQgZm9yIGNvbW1vbiBjYXNlcy4gQ3VycmVudGx5IHByb3ZpZGluZzpcbiAqXG4gKiAgIC0gLm5vQ29udGVudFxuICogICAtIC5iYWRSZXF1ZXN0XG4gKiAgIC0gLnVuYXV0aG9yaXplZFxuICogICAtIC5ub3RBY2NlcHRhYmxlXG4gKiAgIC0gLm5vdEZvdW5kXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHN0YXR1c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLl9zZXRTdGF0dXNQcm9wZXJ0aWVzID0gZnVuY3Rpb24oc3RhdHVzKXtcbiAgLy8gaGFuZGxlIElFOSBidWc6IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTAwNDY5NzIvbXNpZS1yZXR1cm5zLXN0YXR1cy1jb2RlLW9mLTEyMjMtZm9yLWFqYXgtcmVxdWVzdFxuICBpZiAoc3RhdHVzID09PSAxMjIzKSB7XG4gICAgc3RhdHVzID0gMjA0O1xuICB9XG5cbiAgdmFyIHR5cGUgPSBzdGF0dXMgLyAxMDAgfCAwO1xuXG4gIC8vIHN0YXR1cyAvIGNsYXNzXG4gIHRoaXMuc3RhdHVzID0gdGhpcy5zdGF0dXNDb2RlID0gc3RhdHVzO1xuICB0aGlzLnN0YXR1c1R5cGUgPSB0eXBlO1xuXG4gIC8vIGJhc2ljc1xuICB0aGlzLmluZm8gPSAxID09IHR5cGU7XG4gIHRoaXMub2sgPSAyID09IHR5cGU7XG4gIHRoaXMuY2xpZW50RXJyb3IgPSA0ID09IHR5cGU7XG4gIHRoaXMuc2VydmVyRXJyb3IgPSA1ID09IHR5cGU7XG4gIHRoaXMuZXJyb3IgPSAoNCA9PSB0eXBlIHx8IDUgPT0gdHlwZSlcbiAgICA/IHRoaXMudG9FcnJvcigpXG4gICAgOiBmYWxzZTtcblxuICAvLyBzdWdhclxuICB0aGlzLmFjY2VwdGVkID0gMjAyID09IHN0YXR1cztcbiAgdGhpcy5ub0NvbnRlbnQgPSAyMDQgPT0gc3RhdHVzO1xuICB0aGlzLmJhZFJlcXVlc3QgPSA0MDAgPT0gc3RhdHVzO1xuICB0aGlzLnVuYXV0aG9yaXplZCA9IDQwMSA9PSBzdGF0dXM7XG4gIHRoaXMubm90QWNjZXB0YWJsZSA9IDQwNiA9PSBzdGF0dXM7XG4gIHRoaXMubm90Rm91bmQgPSA0MDQgPT0gc3RhdHVzO1xuICB0aGlzLmZvcmJpZGRlbiA9IDQwMyA9PSBzdGF0dXM7XG59O1xuXG4vKipcbiAqIFJldHVybiBhbiBgRXJyb3JgIHJlcHJlc2VudGF0aXZlIG9mIHRoaXMgcmVzcG9uc2UuXG4gKlxuICogQHJldHVybiB7RXJyb3J9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS50b0Vycm9yID0gZnVuY3Rpb24oKXtcbiAgdmFyIHJlcSA9IHRoaXMucmVxO1xuICB2YXIgbWV0aG9kID0gcmVxLm1ldGhvZDtcbiAgdmFyIHVybCA9IHJlcS51cmw7XG5cbiAgdmFyIG1zZyA9ICdjYW5ub3QgJyArIG1ldGhvZCArICcgJyArIHVybCArICcgKCcgKyB0aGlzLnN0YXR1cyArICcpJztcbiAgdmFyIGVyciA9IG5ldyBFcnJvcihtc2cpO1xuICBlcnIuc3RhdHVzID0gdGhpcy5zdGF0dXM7XG4gIGVyci5tZXRob2QgPSBtZXRob2Q7XG4gIGVyci51cmwgPSB1cmw7XG5cbiAgcmV0dXJuIGVycjtcbn07XG5cbi8qKlxuICogRXhwb3NlIGBSZXNwb25zZWAuXG4gKi9cblxucmVxdWVzdC5SZXNwb25zZSA9IFJlc3BvbnNlO1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYFJlcXVlc3RgIHdpdGggdGhlIGdpdmVuIGBtZXRob2RgIGFuZCBgdXJsYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFJlcXVlc3QobWV0aG9kLCB1cmwpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLl9xdWVyeSA9IHRoaXMuX3F1ZXJ5IHx8IFtdO1xuICB0aGlzLm1ldGhvZCA9IG1ldGhvZDtcbiAgdGhpcy51cmwgPSB1cmw7XG4gIHRoaXMuaGVhZGVyID0ge307IC8vIHByZXNlcnZlcyBoZWFkZXIgbmFtZSBjYXNlXG4gIHRoaXMuX2hlYWRlciA9IHt9OyAvLyBjb2VyY2VzIGhlYWRlciBuYW1lcyB0byBsb3dlcmNhc2VcbiAgdGhpcy5vbignZW5kJywgZnVuY3Rpb24oKXtcbiAgICB2YXIgZXJyID0gbnVsbDtcbiAgICB2YXIgcmVzID0gbnVsbDtcblxuICAgIHRyeSB7XG4gICAgICByZXMgPSBuZXcgUmVzcG9uc2Uoc2VsZik7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICBlcnIgPSBuZXcgRXJyb3IoJ1BhcnNlciBpcyB1bmFibGUgdG8gcGFyc2UgdGhlIHJlc3BvbnNlJyk7XG4gICAgICBlcnIucGFyc2UgPSB0cnVlO1xuICAgICAgZXJyLm9yaWdpbmFsID0gZTtcbiAgICAgIC8vIGlzc3VlICM2NzU6IHJldHVybiB0aGUgcmF3IHJlc3BvbnNlIGlmIHRoZSByZXNwb25zZSBwYXJzaW5nIGZhaWxzXG4gICAgICBlcnIucmF3UmVzcG9uc2UgPSBzZWxmLnhociAmJiBzZWxmLnhoci5yZXNwb25zZVRleHQgPyBzZWxmLnhoci5yZXNwb25zZVRleHQgOiBudWxsO1xuICAgICAgLy8gaXNzdWUgIzg3NjogcmV0dXJuIHRoZSBodHRwIHN0YXR1cyBjb2RlIGlmIHRoZSByZXNwb25zZSBwYXJzaW5nIGZhaWxzXG4gICAgICBlcnIuc3RhdHVzQ29kZSA9IHNlbGYueGhyICYmIHNlbGYueGhyLnN0YXR1cyA/IHNlbGYueGhyLnN0YXR1cyA6IG51bGw7XG4gICAgICByZXR1cm4gc2VsZi5jYWxsYmFjayhlcnIpO1xuICAgIH1cblxuICAgIHNlbGYuZW1pdCgncmVzcG9uc2UnLCByZXMpO1xuXG4gICAgdmFyIG5ld19lcnI7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChyZXMuc3RhdHVzIDwgMjAwIHx8IHJlcy5zdGF0dXMgPj0gMzAwKSB7XG4gICAgICAgIG5ld19lcnIgPSBuZXcgRXJyb3IocmVzLnN0YXR1c1RleHQgfHwgJ1Vuc3VjY2Vzc2Z1bCBIVFRQIHJlc3BvbnNlJyk7XG4gICAgICAgIG5ld19lcnIub3JpZ2luYWwgPSBlcnI7XG4gICAgICAgIG5ld19lcnIucmVzcG9uc2UgPSByZXM7XG4gICAgICAgIG5ld19lcnIuc3RhdHVzID0gcmVzLnN0YXR1cztcbiAgICAgIH1cbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgIG5ld19lcnIgPSBlOyAvLyAjOTg1IHRvdWNoaW5nIHJlcyBtYXkgY2F1c2UgSU5WQUxJRF9TVEFURV9FUlIgb24gb2xkIEFuZHJvaWRcbiAgICB9XG5cbiAgICAvLyAjMTAwMCBkb24ndCBjYXRjaCBlcnJvcnMgZnJvbSB0aGUgY2FsbGJhY2sgdG8gYXZvaWQgZG91YmxlIGNhbGxpbmcgaXRcbiAgICBpZiAobmV3X2Vycikge1xuICAgICAgc2VsZi5jYWxsYmFjayhuZXdfZXJyLCByZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZWxmLmNhbGxiYWNrKG51bGwsIHJlcyk7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBNaXhpbiBgRW1pdHRlcmAgYW5kIGByZXF1ZXN0QmFzZWAuXG4gKi9cblxuRW1pdHRlcihSZXF1ZXN0LnByb3RvdHlwZSk7XG5mb3IgKHZhciBrZXkgaW4gcmVxdWVzdEJhc2UpIHtcbiAgUmVxdWVzdC5wcm90b3R5cGVba2V5XSA9IHJlcXVlc3RCYXNlW2tleV07XG59XG5cbi8qKlxuICogU2V0IENvbnRlbnQtVHlwZSB0byBgdHlwZWAsIG1hcHBpbmcgdmFsdWVzIGZyb20gYHJlcXVlc3QudHlwZXNgLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgc3VwZXJhZ2VudC50eXBlcy54bWwgPSAnYXBwbGljYXRpb24veG1sJztcbiAqXG4gKiAgICAgIHJlcXVlc3QucG9zdCgnLycpXG4gKiAgICAgICAgLnR5cGUoJ3htbCcpXG4gKiAgICAgICAgLnNlbmQoeG1sc3RyaW5nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxdWVzdC5wb3N0KCcvJylcbiAqICAgICAgICAudHlwZSgnYXBwbGljYXRpb24veG1sJylcbiAqICAgICAgICAuc2VuZCh4bWxzdHJpbmcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS50eXBlID0gZnVuY3Rpb24odHlwZSl7XG4gIHRoaXMuc2V0KCdDb250ZW50LVR5cGUnLCByZXF1ZXN0LnR5cGVzW3R5cGVdIHx8IHR5cGUpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHJlc3BvbnNlVHlwZSB0byBgdmFsYC4gUHJlc2VudGx5IHZhbGlkIHJlc3BvbnNlVHlwZXMgYXJlICdibG9iJyBhbmRcbiAqICdhcnJheWJ1ZmZlcicuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAucmVzcG9uc2VUeXBlKCdibG9iJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUucmVzcG9uc2VUeXBlID0gZnVuY3Rpb24odmFsKXtcbiAgdGhpcy5fcmVzcG9uc2VUeXBlID0gdmFsO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IEFjY2VwdCB0byBgdHlwZWAsIG1hcHBpbmcgdmFsdWVzIGZyb20gYHJlcXVlc3QudHlwZXNgLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgc3VwZXJhZ2VudC50eXBlcy5qc29uID0gJ2FwcGxpY2F0aW9uL2pzb24nO1xuICpcbiAqICAgICAgcmVxdWVzdC5nZXQoJy9hZ2VudCcpXG4gKiAgICAgICAgLmFjY2VwdCgnanNvbicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogICAgICByZXF1ZXN0LmdldCgnL2FnZW50JylcbiAqICAgICAgICAuYWNjZXB0KCdhcHBsaWNhdGlvbi9qc29uJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYWNjZXB0XG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24odHlwZSl7XG4gIHRoaXMuc2V0KCdBY2NlcHQnLCByZXF1ZXN0LnR5cGVzW3R5cGVdIHx8IHR5cGUpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IEF1dGhvcml6YXRpb24gZmllbGQgdmFsdWUgd2l0aCBgdXNlcmAgYW5kIGBwYXNzYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXNlclxuICogQHBhcmFtIHtTdHJpbmd9IHBhc3NcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIHdpdGggJ3R5cGUnIHByb3BlcnR5ICdhdXRvJyBvciAnYmFzaWMnIChkZWZhdWx0ICdiYXNpYycpXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYXV0aCA9IGZ1bmN0aW9uKHVzZXIsIHBhc3MsIG9wdGlvbnMpe1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgdHlwZTogJ2Jhc2ljJ1xuICAgIH1cbiAgfVxuXG4gIHN3aXRjaCAob3B0aW9ucy50eXBlKSB7XG4gICAgY2FzZSAnYmFzaWMnOlxuICAgICAgdmFyIHN0ciA9IGJ0b2EodXNlciArICc6JyArIHBhc3MpO1xuICAgICAgdGhpcy5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmFzaWMgJyArIHN0cik7XG4gICAgYnJlYWs7XG5cbiAgICBjYXNlICdhdXRvJzpcbiAgICAgIHRoaXMudXNlcm5hbWUgPSB1c2VyO1xuICAgICAgdGhpcy5wYXNzd29yZCA9IHBhc3M7XG4gICAgYnJlYWs7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiogQWRkIHF1ZXJ5LXN0cmluZyBgdmFsYC5cbipcbiogRXhhbXBsZXM6XG4qXG4qICAgcmVxdWVzdC5nZXQoJy9zaG9lcycpXG4qICAgICAucXVlcnkoJ3NpemU9MTAnKVxuKiAgICAgLnF1ZXJ5KHsgY29sb3I6ICdibHVlJyB9KVxuKlxuKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IHZhbFxuKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiogQGFwaSBwdWJsaWNcbiovXG5cblJlcXVlc3QucHJvdG90eXBlLnF1ZXJ5ID0gZnVuY3Rpb24odmFsKXtcbiAgaWYgKCdzdHJpbmcnICE9IHR5cGVvZiB2YWwpIHZhbCA9IHNlcmlhbGl6ZSh2YWwpO1xuICBpZiAodmFsKSB0aGlzLl9xdWVyeS5wdXNoKHZhbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBRdWV1ZSB0aGUgZ2l2ZW4gYGZpbGVgIGFzIGFuIGF0dGFjaG1lbnQgdG8gdGhlIHNwZWNpZmllZCBgZmllbGRgLFxuICogd2l0aCBvcHRpb25hbCBgZmlsZW5hbWVgLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmF0dGFjaCgnY29udGVudCcsIG5ldyBCbG9iKFsnPGEgaWQ9XCJhXCI+PGIgaWQ9XCJiXCI+aGV5ITwvYj48L2E+J10sIHsgdHlwZTogXCJ0ZXh0L2h0bWxcIn0pKVxuICogICAuZW5kKGNhbGxiYWNrKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHBhcmFtIHtCbG9ifEZpbGV9IGZpbGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWxlbmFtZVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmF0dGFjaCA9IGZ1bmN0aW9uKGZpZWxkLCBmaWxlLCBmaWxlbmFtZSl7XG4gIHRoaXMuX2dldEZvcm1EYXRhKCkuYXBwZW5kKGZpZWxkLCBmaWxlLCBmaWxlbmFtZSB8fCBmaWxlLm5hbWUpO1xuICByZXR1cm4gdGhpcztcbn07XG5cblJlcXVlc3QucHJvdG90eXBlLl9nZXRGb3JtRGF0YSA9IGZ1bmN0aW9uKCl7XG4gIGlmICghdGhpcy5fZm9ybURhdGEpIHtcbiAgICB0aGlzLl9mb3JtRGF0YSA9IG5ldyByb290LkZvcm1EYXRhKCk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuX2Zvcm1EYXRhO1xufTtcblxuLyoqXG4gKiBJbnZva2UgdGhlIGNhbGxiYWNrIHdpdGggYGVycmAgYW5kIGByZXNgXG4gKiBhbmQgaGFuZGxlIGFyaXR5IGNoZWNrLlxuICpcbiAqIEBwYXJhbSB7RXJyb3J9IGVyclxuICogQHBhcmFtIHtSZXNwb25zZX0gcmVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jYWxsYmFjayA9IGZ1bmN0aW9uKGVyciwgcmVzKXtcbiAgdmFyIGZuID0gdGhpcy5fY2FsbGJhY2s7XG4gIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gIGZuKGVyciwgcmVzKTtcbn07XG5cbi8qKlxuICogSW52b2tlIGNhbGxiYWNrIHdpdGggeC1kb21haW4gZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY3Jvc3NEb21haW5FcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIGJlZW4gdGVybWluYXRlZFxcblBvc3NpYmxlIGNhdXNlczogdGhlIG5ldHdvcmsgaXMgb2ZmbGluZSwgT3JpZ2luIGlzIG5vdCBhbGxvd2VkIGJ5IEFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbiwgdGhlIHBhZ2UgaXMgYmVpbmcgdW5sb2FkZWQsIGV0Yy4nKTtcbiAgZXJyLmNyb3NzRG9tYWluID0gdHJ1ZTtcblxuICBlcnIuc3RhdHVzID0gdGhpcy5zdGF0dXM7XG4gIGVyci5tZXRob2QgPSB0aGlzLm1ldGhvZDtcbiAgZXJyLnVybCA9IHRoaXMudXJsO1xuXG4gIHRoaXMuY2FsbGJhY2soZXJyKTtcbn07XG5cbi8qKlxuICogSW52b2tlIGNhbGxiYWNrIHdpdGggdGltZW91dCBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5fdGltZW91dEVycm9yID0gZnVuY3Rpb24oKXtcbiAgdmFyIHRpbWVvdXQgPSB0aGlzLl90aW1lb3V0O1xuICB2YXIgZXJyID0gbmV3IEVycm9yKCd0aW1lb3V0IG9mICcgKyB0aW1lb3V0ICsgJ21zIGV4Y2VlZGVkJyk7XG4gIGVyci50aW1lb3V0ID0gdGltZW91dDtcbiAgdGhpcy5jYWxsYmFjayhlcnIpO1xufTtcblxuLyoqXG4gKiBDb21wb3NlIHF1ZXJ5c3RyaW5nIHRvIGFwcGVuZCB0byByZXEudXJsXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuX2FwcGVuZFF1ZXJ5U3RyaW5nID0gZnVuY3Rpb24oKXtcbiAgdmFyIHF1ZXJ5ID0gdGhpcy5fcXVlcnkuam9pbignJicpO1xuICBpZiAocXVlcnkpIHtcbiAgICB0aGlzLnVybCArPSB+dGhpcy51cmwuaW5kZXhPZignPycpXG4gICAgICA/ICcmJyArIHF1ZXJ5XG4gICAgICA6ICc/JyArIHF1ZXJ5O1xuICB9XG59O1xuXG4vKipcbiAqIEluaXRpYXRlIHJlcXVlc3QsIGludm9raW5nIGNhbGxiYWNrIGBmbihyZXMpYFxuICogd2l0aCBhbiBpbnN0YW5jZW9mIGBSZXNwb25zZWAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihmbil7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHhociA9IHRoaXMueGhyID0gcmVxdWVzdC5nZXRYSFIoKTtcbiAgdmFyIHRpbWVvdXQgPSB0aGlzLl90aW1lb3V0O1xuICB2YXIgZGF0YSA9IHRoaXMuX2Zvcm1EYXRhIHx8IHRoaXMuX2RhdGE7XG5cbiAgLy8gc3RvcmUgY2FsbGJhY2tcbiAgdGhpcy5fY2FsbGJhY2sgPSBmbiB8fCBub29wO1xuXG4gIC8vIHN0YXRlIGNoYW5nZVxuICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKXtcbiAgICBpZiAoNCAhPSB4aHIucmVhZHlTdGF0ZSkgcmV0dXJuO1xuXG4gICAgLy8gSW4gSUU5LCByZWFkcyB0byBhbnkgcHJvcGVydHkgKGUuZy4gc3RhdHVzKSBvZmYgb2YgYW4gYWJvcnRlZCBYSFIgd2lsbFxuICAgIC8vIHJlc3VsdCBpbiB0aGUgZXJyb3IgXCJDb3VsZCBub3QgY29tcGxldGUgdGhlIG9wZXJhdGlvbiBkdWUgdG8gZXJyb3IgYzAwYzAyM2ZcIlxuICAgIHZhciBzdGF0dXM7XG4gICAgdHJ5IHsgc3RhdHVzID0geGhyLnN0YXR1cyB9IGNhdGNoKGUpIHsgc3RhdHVzID0gMDsgfVxuXG4gICAgaWYgKDAgPT0gc3RhdHVzKSB7XG4gICAgICBpZiAoc2VsZi50aW1lZG91dCkgcmV0dXJuIHNlbGYuX3RpbWVvdXRFcnJvcigpO1xuICAgICAgaWYgKHNlbGYuX2Fib3J0ZWQpIHJldHVybjtcbiAgICAgIHJldHVybiBzZWxmLmNyb3NzRG9tYWluRXJyb3IoKTtcbiAgICB9XG4gICAgc2VsZi5lbWl0KCdlbmQnKTtcbiAgfTtcblxuICAvLyBwcm9ncmVzc1xuICB2YXIgaGFuZGxlUHJvZ3Jlc3MgPSBmdW5jdGlvbihlKXtcbiAgICBpZiAoZS50b3RhbCA+IDApIHtcbiAgICAgIGUucGVyY2VudCA9IGUubG9hZGVkIC8gZS50b3RhbCAqIDEwMDtcbiAgICB9XG4gICAgZS5kaXJlY3Rpb24gPSAnZG93bmxvYWQnO1xuICAgIHNlbGYuZW1pdCgncHJvZ3Jlc3MnLCBlKTtcbiAgfTtcbiAgaWYgKHRoaXMuaGFzTGlzdGVuZXJzKCdwcm9ncmVzcycpKSB7XG4gICAgeGhyLm9ucHJvZ3Jlc3MgPSBoYW5kbGVQcm9ncmVzcztcbiAgfVxuICB0cnkge1xuICAgIGlmICh4aHIudXBsb2FkICYmIHRoaXMuaGFzTGlzdGVuZXJzKCdwcm9ncmVzcycpKSB7XG4gICAgICB4aHIudXBsb2FkLm9ucHJvZ3Jlc3MgPSBoYW5kbGVQcm9ncmVzcztcbiAgICB9XG4gIH0gY2F0Y2goZSkge1xuICAgIC8vIEFjY2Vzc2luZyB4aHIudXBsb2FkIGZhaWxzIGluIElFIGZyb20gYSB3ZWIgd29ya2VyLCBzbyBqdXN0IHByZXRlbmQgaXQgZG9lc24ndCBleGlzdC5cbiAgICAvLyBSZXBvcnRlZCBoZXJlOlxuICAgIC8vIGh0dHBzOi8vY29ubmVjdC5taWNyb3NvZnQuY29tL0lFL2ZlZWRiYWNrL2RldGFpbHMvODM3MjQ1L3htbGh0dHByZXF1ZXN0LXVwbG9hZC10aHJvd3MtaW52YWxpZC1hcmd1bWVudC13aGVuLXVzZWQtZnJvbS13ZWItd29ya2VyLWNvbnRleHRcbiAgfVxuXG4gIC8vIHRpbWVvdXRcbiAgaWYgKHRpbWVvdXQgJiYgIXRoaXMuX3RpbWVyKSB7XG4gICAgdGhpcy5fdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICBzZWxmLnRpbWVkb3V0ID0gdHJ1ZTtcbiAgICAgIHNlbGYuYWJvcnQoKTtcbiAgICB9LCB0aW1lb3V0KTtcbiAgfVxuXG4gIC8vIHF1ZXJ5c3RyaW5nXG4gIHRoaXMuX2FwcGVuZFF1ZXJ5U3RyaW5nKCk7XG5cbiAgLy8gaW5pdGlhdGUgcmVxdWVzdFxuICBpZiAodGhpcy51c2VybmFtZSAmJiB0aGlzLnBhc3N3b3JkKSB7XG4gICAgeGhyLm9wZW4odGhpcy5tZXRob2QsIHRoaXMudXJsLCB0cnVlLCB0aGlzLnVzZXJuYW1lLCB0aGlzLnBhc3N3b3JkKTtcbiAgfSBlbHNlIHtcbiAgICB4aHIub3Blbih0aGlzLm1ldGhvZCwgdGhpcy51cmwsIHRydWUpO1xuICB9XG5cbiAgLy8gQ09SU1xuICBpZiAodGhpcy5fd2l0aENyZWRlbnRpYWxzKSB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcblxuICAvLyBib2R5XG4gIGlmICgnR0VUJyAhPSB0aGlzLm1ldGhvZCAmJiAnSEVBRCcgIT0gdGhpcy5tZXRob2QgJiYgJ3N0cmluZycgIT0gdHlwZW9mIGRhdGEgJiYgIXRoaXMuX2lzSG9zdChkYXRhKSkge1xuICAgIC8vIHNlcmlhbGl6ZSBzdHVmZlxuICAgIHZhciBjb250ZW50VHlwZSA9IHRoaXMuX2hlYWRlclsnY29udGVudC10eXBlJ107XG4gICAgdmFyIHNlcmlhbGl6ZSA9IHRoaXMuX3NlcmlhbGl6ZXIgfHwgcmVxdWVzdC5zZXJpYWxpemVbY29udGVudFR5cGUgPyBjb250ZW50VHlwZS5zcGxpdCgnOycpWzBdIDogJyddO1xuICAgIGlmICghc2VyaWFsaXplICYmIGlzSlNPTihjb250ZW50VHlwZSkpIHNlcmlhbGl6ZSA9IHJlcXVlc3Quc2VyaWFsaXplWydhcHBsaWNhdGlvbi9qc29uJ107XG4gICAgaWYgKHNlcmlhbGl6ZSkgZGF0YSA9IHNlcmlhbGl6ZShkYXRhKTtcbiAgfVxuXG4gIC8vIHNldCBoZWFkZXIgZmllbGRzXG4gIGZvciAodmFyIGZpZWxkIGluIHRoaXMuaGVhZGVyKSB7XG4gICAgaWYgKG51bGwgPT0gdGhpcy5oZWFkZXJbZmllbGRdKSBjb250aW51ZTtcbiAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihmaWVsZCwgdGhpcy5oZWFkZXJbZmllbGRdKTtcbiAgfVxuXG4gIGlmICh0aGlzLl9yZXNwb25zZVR5cGUpIHtcbiAgICB4aHIucmVzcG9uc2VUeXBlID0gdGhpcy5fcmVzcG9uc2VUeXBlO1xuICB9XG5cbiAgLy8gc2VuZCBzdHVmZlxuICB0aGlzLmVtaXQoJ3JlcXVlc3QnLCB0aGlzKTtcblxuICAvLyBJRTExIHhoci5zZW5kKHVuZGVmaW5lZCkgc2VuZHMgJ3VuZGVmaW5lZCcgc3RyaW5nIGFzIFBPU1QgcGF5bG9hZCAoaW5zdGVhZCBvZiBub3RoaW5nKVxuICAvLyBXZSBuZWVkIG51bGwgaGVyZSBpZiBkYXRhIGlzIHVuZGVmaW5lZFxuICB4aHIuc2VuZCh0eXBlb2YgZGF0YSAhPT0gJ3VuZGVmaW5lZCcgPyBkYXRhIDogbnVsbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuXG4vKipcbiAqIEV4cG9zZSBgUmVxdWVzdGAuXG4gKi9cblxucmVxdWVzdC5SZXF1ZXN0ID0gUmVxdWVzdDtcblxuLyoqXG4gKiBHRVQgYHVybGAgd2l0aCBvcHRpb25hbCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZHxGdW5jdGlvbn0gW2RhdGFdIG9yIGZuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LmdldCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnR0VUJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEucXVlcnkoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIEhFQUQgYHVybGAgd2l0aCBvcHRpb25hbCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZHxGdW5jdGlvbn0gW2RhdGFdIG9yIGZuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LmhlYWQgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ0hFQUQnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBPUFRJT05TIHF1ZXJ5IHRvIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IFtkYXRhXSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2ZuXVxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5vcHRpb25zID0gZnVuY3Rpb24odXJsLCBkYXRhLCBmbil7XG4gIHZhciByZXEgPSByZXF1ZXN0KCdPUFRJT05TJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEuc2VuZChkYXRhKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbi8qKlxuICogREVMRVRFIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl1cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlbCh1cmwsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ0RFTEVURScsIHVybCk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG5yZXF1ZXN0WydkZWwnXSA9IGRlbDtcbnJlcXVlc3RbJ2RlbGV0ZSddID0gZGVsO1xuXG4vKipcbiAqIFBBVENIIGB1cmxgIHdpdGggb3B0aW9uYWwgYGRhdGFgIGFuZCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZH0gW2RhdGFdXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LnBhdGNoID0gZnVuY3Rpb24odXJsLCBkYXRhLCBmbil7XG4gIHZhciByZXEgPSByZXF1ZXN0KCdQQVRDSCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIFBPU1QgYHVybGAgd2l0aCBvcHRpb25hbCBgZGF0YWAgYW5kIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfSBbZGF0YV1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl1cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QucG9zdCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUE9TVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIFBVVCBgdXJsYCB3aXRoIG9wdGlvbmFsIGBkYXRhYCBhbmQgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IFtkYXRhXSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2ZuXVxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5wdXQgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ1BVVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuIiwiLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhbiBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGlzT2JqZWN0KG9iaikge1xuICByZXR1cm4gbnVsbCAhPT0gb2JqICYmICdvYmplY3QnID09PSB0eXBlb2Ygb2JqO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0O1xuIiwiLyoqXG4gKiBNb2R1bGUgb2YgbWl4ZWQtaW4gZnVuY3Rpb25zIHNoYXJlZCBiZXR3ZWVuIG5vZGUgYW5kIGNsaWVudCBjb2RlXG4gKi9cbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXMtb2JqZWN0Jyk7XG5cbi8qKlxuICogQ2xlYXIgcHJldmlvdXMgdGltZW91dC5cbiAqXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5jbGVhclRpbWVvdXQgPSBmdW5jdGlvbiBfY2xlYXJUaW1lb3V0KCl7XG4gIHRoaXMuX3RpbWVvdXQgPSAwO1xuICBjbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgZGVmYXVsdCByZXNwb25zZSBib2R5IHBhcnNlclxuICpcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgdG8gY29udmVydCBpbmNvbWluZyBkYXRhIGludG8gcmVxdWVzdC5ib2R5XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5wYXJzZSA9IGZ1bmN0aW9uIHBhcnNlKGZuKXtcbiAgdGhpcy5fcGFyc2VyID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBPdmVycmlkZSBkZWZhdWx0IHJlcXVlc3QgYm9keSBzZXJpYWxpemVyXG4gKlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCB0byBjb252ZXJ0IGRhdGEgc2V0IHZpYSAuc2VuZCBvciAuYXR0YWNoIGludG8gcGF5bG9hZCB0byBzZW5kXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5zZXJpYWxpemUgPSBmdW5jdGlvbiBzZXJpYWxpemUoZm4pe1xuICB0aGlzLl9zZXJpYWxpemVyID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgdGltZW91dCB0byBgbXNgLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtc1xuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMudGltZW91dCA9IGZ1bmN0aW9uIHRpbWVvdXQobXMpe1xuICB0aGlzLl90aW1lb3V0ID0gbXM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBQcm9taXNlIHN1cHBvcnRcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZXNvbHZlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3RcbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKi9cblxuZXhwb3J0cy50aGVuID0gZnVuY3Rpb24gdGhlbihyZXNvbHZlLCByZWplY3QpIHtcbiAgaWYgKCF0aGlzLl9mdWxsZmlsbGVkUHJvbWlzZSkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLl9mdWxsZmlsbGVkUHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKGlubmVyUmVzb2x2ZSwgaW5uZXJSZWplY3Qpe1xuICAgICAgc2VsZi5lbmQoZnVuY3Rpb24oZXJyLCByZXMpe1xuICAgICAgICBpZiAoZXJyKSBpbm5lclJlamVjdChlcnIpOyBlbHNlIGlubmVyUmVzb2x2ZShyZXMpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuX2Z1bGxmaWxsZWRQcm9taXNlLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbn1cblxuLyoqXG4gKiBBbGxvdyBmb3IgZXh0ZW5zaW9uXG4gKi9cblxuZXhwb3J0cy51c2UgPSBmdW5jdGlvbiB1c2UoZm4pIHtcbiAgZm4odGhpcyk7XG4gIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogR2V0IHJlcXVlc3QgaGVhZGVyIGBmaWVsZGAuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmdldCA9IGZ1bmN0aW9uKGZpZWxkKXtcbiAgcmV0dXJuIHRoaXMuX2hlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbn07XG5cbi8qKlxuICogR2V0IGNhc2UtaW5zZW5zaXRpdmUgaGVhZGVyIGBmaWVsZGAgdmFsdWUuXG4gKiBUaGlzIGlzIGEgZGVwcmVjYXRlZCBpbnRlcm5hbCBBUEkuIFVzZSBgLmdldChmaWVsZClgIGluc3RlYWQuXG4gKlxuICogKGdldEhlYWRlciBpcyBubyBsb25nZXIgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSBzdXBlcmFnZW50IGNvZGUgYmFzZSlcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICogQGRlcHJlY2F0ZWRcbiAqL1xuXG5leHBvcnRzLmdldEhlYWRlciA9IGV4cG9ydHMuZ2V0O1xuXG4vKipcbiAqIFNldCBoZWFkZXIgYGZpZWxkYCB0byBgdmFsYCwgb3IgbXVsdGlwbGUgZmllbGRzIHdpdGggb25lIG9iamVjdC5cbiAqIENhc2UtaW5zZW5zaXRpdmUuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpXG4gKiAgICAgICAgLnNldCgnWC1BUEktS2V5JywgJ2Zvb2JhcicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAuc2V0KHsgQWNjZXB0OiAnYXBwbGljYXRpb24vanNvbicsICdYLUFQSS1LZXknOiAnZm9vYmFyJyB9KVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gZmllbGRcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWxcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnNldCA9IGZ1bmN0aW9uKGZpZWxkLCB2YWwpe1xuICBpZiAoaXNPYmplY3QoZmllbGQpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIGZpZWxkKSB7XG4gICAgICB0aGlzLnNldChrZXksIGZpZWxkW2tleV0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV0gPSB2YWw7XG4gIHRoaXMuaGVhZGVyW2ZpZWxkXSA9IHZhbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBoZWFkZXIgYGZpZWxkYC5cbiAqIENhc2UtaW5zZW5zaXRpdmUuXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC51bnNldCgnVXNlci1BZ2VudCcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKi9cbmV4cG9ydHMudW5zZXQgPSBmdW5jdGlvbihmaWVsZCl7XG4gIGRlbGV0ZSB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV07XG4gIGRlbGV0ZSB0aGlzLmhlYWRlcltmaWVsZF07XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBXcml0ZSB0aGUgZmllbGQgYG5hbWVgIGFuZCBgdmFsYCBmb3IgXCJtdWx0aXBhcnQvZm9ybS1kYXRhXCJcbiAqIHJlcXVlc3QgYm9kaWVzLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmZpZWxkKCdmb28nLCAnYmFyJylcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtTdHJpbmd8QmxvYnxGaWxlfEJ1ZmZlcnxmcy5SZWFkU3RyZWFtfSB2YWxcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuZXhwb3J0cy5maWVsZCA9IGZ1bmN0aW9uKG5hbWUsIHZhbCkge1xuICB0aGlzLl9nZXRGb3JtRGF0YSgpLmFwcGVuZChuYW1lLCB2YWwpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWJvcnQgdGhlIHJlcXVlc3QsIGFuZCBjbGVhciBwb3RlbnRpYWwgdGltZW91dC5cbiAqXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuZXhwb3J0cy5hYm9ydCA9IGZ1bmN0aW9uKCl7XG4gIGlmICh0aGlzLl9hYm9ydGVkKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgdGhpcy5fYWJvcnRlZCA9IHRydWU7XG4gIHRoaXMueGhyICYmIHRoaXMueGhyLmFib3J0KCk7IC8vIGJyb3dzZXJcbiAgdGhpcy5yZXEgJiYgdGhpcy5yZXEuYWJvcnQoKTsgLy8gbm9kZVxuICB0aGlzLmNsZWFyVGltZW91dCgpO1xuICB0aGlzLmVtaXQoJ2Fib3J0Jyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFbmFibGUgdHJhbnNtaXNzaW9uIG9mIGNvb2tpZXMgd2l0aCB4LWRvbWFpbiByZXF1ZXN0cy5cbiAqXG4gKiBOb3RlIHRoYXQgZm9yIHRoaXMgdG8gd29yayB0aGUgb3JpZ2luIG11c3Qgbm90IGJlXG4gKiB1c2luZyBcIkFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpblwiIHdpdGggYSB3aWxkY2FyZCxcbiAqIGFuZCBhbHNvIG11c3Qgc2V0IFwiQWNjZXNzLUNvbnRyb2wtQWxsb3ctQ3JlZGVudGlhbHNcIlxuICogdG8gXCJ0cnVlXCIuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLndpdGhDcmVkZW50aWFscyA9IGZ1bmN0aW9uKCl7XG4gIC8vIFRoaXMgaXMgYnJvd3Nlci1vbmx5IGZ1bmN0aW9uYWxpdHkuIE5vZGUgc2lkZSBpcyBuby1vcC5cbiAgdGhpcy5fd2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgbWF4IHJlZGlyZWN0cyB0byBgbmAuIERvZXMgbm90aW5nIGluIGJyb3dzZXIgWEhSIGltcGxlbWVudGF0aW9uLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5yZWRpcmVjdHMgPSBmdW5jdGlvbihuKXtcbiAgdGhpcy5fbWF4UmVkaXJlY3RzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENvbnZlcnQgdG8gYSBwbGFpbiBqYXZhc2NyaXB0IG9iamVjdCAobm90IEpTT04gc3RyaW5nKSBvZiBzY2FsYXIgcHJvcGVydGllcy5cbiAqIE5vdGUgYXMgdGhpcyBtZXRob2QgaXMgZGVzaWduZWQgdG8gcmV0dXJuIGEgdXNlZnVsIG5vbi10aGlzIHZhbHVlLFxuICogaXQgY2Fubm90IGJlIGNoYWluZWQuXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBkZXNjcmliaW5nIG1ldGhvZCwgdXJsLCBhbmQgZGF0YSBvZiB0aGlzIHJlcXVlc3RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy50b0pTT04gPSBmdW5jdGlvbigpe1xuICByZXR1cm4ge1xuICAgIG1ldGhvZDogdGhpcy5tZXRob2QsXG4gICAgdXJsOiB0aGlzLnVybCxcbiAgICBkYXRhOiB0aGlzLl9kYXRhLFxuICAgIGhlYWRlcnM6IHRoaXMuX2hlYWRlclxuICB9O1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIGhvc3Qgb2JqZWN0LFxuICogd2UgZG9uJ3Qgd2FudCB0byBzZXJpYWxpemUgdGhlc2UgOilcbiAqXG4gKiBUT0RPOiBmdXR1cmUgcHJvb2YsIG1vdmUgdG8gY29tcG9lbnQgbGFuZFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLl9pc0hvc3QgPSBmdW5jdGlvbiBfaXNIb3N0KG9iaikge1xuICB2YXIgc3RyID0ge30udG9TdHJpbmcuY2FsbChvYmopO1xuXG4gIHN3aXRjaCAoc3RyKSB7XG4gICAgY2FzZSAnW29iamVjdCBGaWxlXSc6XG4gICAgY2FzZSAnW29iamVjdCBCbG9iXSc6XG4gICAgY2FzZSAnW29iamVjdCBGb3JtRGF0YV0nOlxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIFNlbmQgYGRhdGFgIGFzIHRoZSByZXF1ZXN0IGJvZHksIGRlZmF1bHRpbmcgdGhlIGAudHlwZSgpYCB0byBcImpzb25cIiB3aGVuXG4gKiBhbiBvYmplY3QgaXMgZ2l2ZW4uXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICAgLy8gbWFudWFsIGpzb25cbiAqICAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgICAudHlwZSgnanNvbicpXG4gKiAgICAgICAgIC5zZW5kKCd7XCJuYW1lXCI6XCJ0alwifScpXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gYXV0byBqc29uXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gbWFudWFsIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC50eXBlKCdmb3JtJylcbiAqICAgICAgICAgLnNlbmQoJ25hbWU9dGonKVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIGF1dG8geC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2Zvcm0nKVxuICogICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBkZWZhdWx0cyB0byB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAqICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgLnNlbmQoJ25hbWU9dG9iaScpXG4gKiAgICAgICAgLnNlbmQoJ3NwZWNpZXM9ZmVycmV0JylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gZGF0YVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuc2VuZCA9IGZ1bmN0aW9uKGRhdGEpe1xuICB2YXIgb2JqID0gaXNPYmplY3QoZGF0YSk7XG4gIHZhciB0eXBlID0gdGhpcy5faGVhZGVyWydjb250ZW50LXR5cGUnXTtcblxuICAvLyBtZXJnZVxuICBpZiAob2JqICYmIGlzT2JqZWN0KHRoaXMuX2RhdGEpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHtcbiAgICAgIHRoaXMuX2RhdGFba2V5XSA9IGRhdGFba2V5XTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIGRhdGEpIHtcbiAgICAvLyBkZWZhdWx0IHRvIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICAgIGlmICghdHlwZSkgdGhpcy50eXBlKCdmb3JtJyk7XG4gICAgdHlwZSA9IHRoaXMuX2hlYWRlclsnY29udGVudC10eXBlJ107XG4gICAgaWYgKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnID09IHR5cGUpIHtcbiAgICAgIHRoaXMuX2RhdGEgPSB0aGlzLl9kYXRhXG4gICAgICAgID8gdGhpcy5fZGF0YSArICcmJyArIGRhdGFcbiAgICAgICAgOiBkYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9kYXRhID0gKHRoaXMuX2RhdGEgfHwgJycpICsgZGF0YTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gIH1cblxuICBpZiAoIW9iaiB8fCB0aGlzLl9pc0hvc3QoZGF0YSkpIHJldHVybiB0aGlzO1xuXG4gIC8vIGRlZmF1bHQgdG8ganNvblxuICBpZiAoIXR5cGUpIHRoaXMudHlwZSgnanNvbicpO1xuICByZXR1cm4gdGhpcztcbn07XG4iLCIvLyBUaGUgbm9kZSBhbmQgYnJvd3NlciBtb2R1bGVzIGV4cG9zZSB2ZXJzaW9ucyBvZiB0aGlzIHdpdGggdGhlXG4vLyBhcHByb3ByaWF0ZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBib3VuZCBhcyBmaXJzdCBhcmd1bWVudFxuLyoqXG4gKiBJc3N1ZSBhIHJlcXVlc3Q6XG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgcmVxdWVzdCgnR0VUJywgJy91c2VycycpLmVuZChjYWxsYmFjaylcbiAqICAgIHJlcXVlc3QoJy91c2VycycpLmVuZChjYWxsYmFjaylcbiAqICAgIHJlcXVlc3QoJy91c2VycycsIGNhbGxiYWNrKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSB1cmwgb3IgY2FsbGJhY2tcbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIHJlcXVlc3QoUmVxdWVzdENvbnN0cnVjdG9yLCBtZXRob2QsIHVybCkge1xuICAvLyBjYWxsYmFja1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgdXJsKSB7XG4gICAgcmV0dXJuIG5ldyBSZXF1ZXN0Q29uc3RydWN0b3IoJ0dFVCcsIG1ldGhvZCkuZW5kKHVybCk7XG4gIH1cblxuICAvLyB1cmwgZmlyc3RcbiAgaWYgKDIgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdENvbnN0cnVjdG9yKCdHRVQnLCBtZXRob2QpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBSZXF1ZXN0Q29uc3RydWN0b3IobWV0aG9kLCB1cmwpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVlc3Q7XG4iLCJcclxuLyoqXHJcbiAqIEV4cG9zZSBgRW1pdHRlcmAuXHJcbiAqL1xyXG5cclxuaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgbW9kdWxlLmV4cG9ydHMgPSBFbWl0dGVyO1xyXG59XHJcblxyXG4vKipcclxuICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXHJcbiAqXHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuZnVuY3Rpb24gRW1pdHRlcihvYmopIHtcclxuICBpZiAob2JqKSByZXR1cm4gbWl4aW4ob2JqKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBNaXhpbiB0aGUgZW1pdHRlciBwcm9wZXJ0aWVzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXHJcbiAqIEByZXR1cm4ge09iamVjdH1cclxuICogQGFwaSBwcml2YXRlXHJcbiAqL1xyXG5cclxuZnVuY3Rpb24gbWl4aW4ob2JqKSB7XHJcbiAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XHJcbiAgICBvYmpba2V5XSA9IEVtaXR0ZXIucHJvdG90eXBlW2tleV07XHJcbiAgfVxyXG4gIHJldHVybiBvYmo7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cclxuICogQHJldHVybiB7RW1pdHRlcn1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9XHJcbkVtaXR0ZXIucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbihldmVudCwgZm4pe1xyXG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcclxuICAodGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XSA9IHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gfHwgW10pXHJcbiAgICAucHVzaChmbik7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXHJcbiAqIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxyXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pe1xyXG4gIGZ1bmN0aW9uIG9uKCkge1xyXG4gICAgdGhpcy5vZmYoZXZlbnQsIG9uKTtcclxuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbiAgfVxyXG5cclxuICBvbi5mbiA9IGZuO1xyXG4gIHRoaXMub24oZXZlbnQsIG9uKTtcclxuICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxyXG4gKiByZWdpc3RlcmVkIGNhbGxiYWNrcy5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXHJcbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUub2ZmID1cclxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPVxyXG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxyXG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcclxuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XHJcblxyXG4gIC8vIGFsbFxyXG4gIGlmICgwID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcclxuICAgIHRoaXMuX2NhbGxiYWNrcyA9IHt9O1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvLyBzcGVjaWZpYyBldmVudFxyXG4gIHZhciBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xyXG4gIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcclxuXHJcbiAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xyXG4gIGlmICgxID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcclxuICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxyXG4gIHZhciBjYjtcclxuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xyXG4gICAgY2IgPSBjYWxsYmFja3NbaV07XHJcbiAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xyXG4gICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xyXG4gICAgICBicmVhaztcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcGFyYW0ge01peGVkfSAuLi5cclxuICogQHJldHVybiB7RW1pdHRlcn1cclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXZlbnQpe1xyXG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcclxuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxyXG4gICAgLCBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xyXG5cclxuICBpZiAoY2FsbGJhY2tzKSB7XHJcbiAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XHJcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gY2FsbGJhY2tzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcbiAgICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybiBhcnJheSBvZiBjYWxsYmFja3MgZm9yIGBldmVudGAuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcmV0dXJuIHtBcnJheX1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCl7XHJcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xyXG4gIHJldHVybiB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XHJcbiAqIEByZXR1cm4ge0Jvb2xlYW59XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xyXG4gIHJldHVybiAhISB0aGlzLmxpc3RlbmVycyhldmVudCkubGVuZ3RoO1xyXG59O1xyXG4iLCIgLypnbG9iYWwgSlNPTkVkaXRvciovXG4ndXNlIHN0cmljdCc7XG5cbndpbmRvdy5Td2FnZ2VyVWkgPSBCYWNrYm9uZS5Sb3V0ZXIuZXh0ZW5kKHtcblxuICBkb21faWQ6ICdzd2FnZ2VyX3VpJyxcblxuICAvLyBBdHRyaWJ1dGVzXG4gIG9wdGlvbnM6IG51bGwsXG4gIGFwaTogbnVsbCxcbiAgaGVhZGVyVmlldzogbnVsbCxcbiAgbWFpblZpZXc6IG51bGwsXG5cbiAgLy8gU3dhZ2dlclVpIGFjY2VwdHMgYWxsIHRoZSBzYW1lIG9wdGlvbnMgYXMgU3dhZ2dlckFwaVxuICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAob3B0aW9ucy5kZWZhdWx0TW9kZWxSZW5kZXJpbmcgIT09ICdtb2RlbCcpIHtcbiAgICAgIG9wdGlvbnMuZGVmYXVsdE1vZGVsUmVuZGVyaW5nID0gJ3NjaGVtYSc7XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLmhpZ2hsaWdodFNpemVUaHJlc2hvbGQpIHtcbiAgICAgIG9wdGlvbnMuaGlnaGxpZ2h0U2l6ZVRocmVzaG9sZCA9IDEwMDAwMDtcbiAgICB9XG5cbiAgICAvLyBBbGxvdyBkb21faWQgdG8gYmUgb3ZlcnJpZGRlblxuICAgIGlmIChvcHRpb25zLmRvbV9pZCkge1xuICAgICAgdGhpcy5kb21faWQgPSBvcHRpb25zLmRvbV9pZDtcbiAgICAgIGRlbGV0ZSBvcHRpb25zLmRvbV9pZDtcbiAgICB9XG5cbiAgICBpZiAoIW9wdGlvbnMuc3VwcG9ydGVkU3VibWl0TWV0aG9kcyl7XG4gICAgICBvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBbXG4gICAgICAgICdnZXQnLFxuICAgICAgICAncHV0JyxcbiAgICAgICAgJ3Bvc3QnLFxuICAgICAgICAnZGVsZXRlJyxcbiAgICAgICAgJ2hlYWQnLFxuICAgICAgICAnb3B0aW9ucycsXG4gICAgICAgICdwYXRjaCdcbiAgICAgIF07XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLm9hdXRoMlJlZGlyZWN0VXJsID09PSAnc3RyaW5nJykge1xuICAgICAgd2luZG93Lm9BdXRoUmVkaXJlY3RVcmwgPSBvcHRpb25zLm9hdXRoMlJlZGlyZWN0VXJsO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBhbiBlbXB0eSBkaXYgd2hpY2ggY29udGFpbnMgdGhlIGRvbV9pZFxuICAgIGlmICghICQoJyMnICsgdGhpcy5kb21faWQpLmxlbmd0aCl7XG4gICAgICAkKCdib2R5JykuYXBwZW5kKCc8ZGl2IGlkPVwiJyArIHRoaXMuZG9tX2lkICsgJ1wiPjwvZGl2PicpIDtcbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgLy8gc2V0IG1hcmtlZCBvcHRpb25zXG4gICAgbWFya2VkLnNldE9wdGlvbnMoe2dmbTogdHJ1ZX0pO1xuXG4gICAgLy8gU2V0IHRoZSBjYWxsYmFja3NcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgdGhpcy5vcHRpb25zLnN1Y2Nlc3MgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoYXQucmVuZGVyKCk7IH07XG4gICAgdGhpcy5vcHRpb25zLnByb2dyZXNzID0gZnVuY3Rpb24oZCkgeyByZXR1cm4gdGhhdC5zaG93TWVzc2FnZShkKTsgfTtcbiAgICB0aGlzLm9wdGlvbnMuZmFpbHVyZSA9IGZ1bmN0aW9uKGQpIHsgcmV0dXJuIHRoYXQub25Mb2FkRmFpbHVyZShkKTsgfTtcblxuICAgIC8vIENyZWF0ZSB2aWV3IHRvIGhhbmRsZSB0aGUgaGVhZGVyIGlucHV0c1xuICAgIHRoaXMuaGVhZGVyVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuSGVhZGVyVmlldyh7ZWw6ICQoJyNoZWFkZXInKX0pO1xuXG4gICAgLy8gRXZlbnQgaGFuZGxlciBmb3Igd2hlbiB0aGUgYmFzZVVybC9hcGlLZXkgaXMgZW50ZXJlZCBieSB1c2VyXG4gICAgdGhpcy5oZWFkZXJWaWV3Lm9uKCd1cGRhdGUtc3dhZ2dlci11aScsIGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHJldHVybiB0aGF0LnVwZGF0ZVN3YWdnZXJVaShkYXRhKTtcbiAgICB9KTtcblxuICAgIC8vIEpTb24gRWRpdG9yIGN1c3RvbSB0aGVtaW5nXG4gICAgIEpTT05FZGl0b3IuZGVmYXVsdHMuaWNvbmxpYnMuc3dhZ2dlciA9IEpTT05FZGl0b3IuQWJzdHJhY3RJY29uTGliLmV4dGVuZCh7XG4gICAgICBtYXBwaW5nOiB7XG4gICAgICAgIGNvbGxhcHNlOiAnY29sbGFwc2UnLFxuICAgICAgICBleHBhbmQ6ICdleHBhbmQnXG4gICAgICAgIH0sXG4gICAgICBpY29uX3ByZWZpeDogJ3N3YWdnZXItJ1xuICAgICAgfSk7XG5cbiAgfSxcblxuICAvLyBTZXQgYW4gb3B0aW9uIGFmdGVyIGluaXRpYWxpemluZ1xuICBzZXRPcHRpb246IGZ1bmN0aW9uKG9wdGlvbiwgdmFsdWUpIHtcbiAgICB0aGlzLm9wdGlvbnNbb3B0aW9uXSA9IHZhbHVlO1xuICB9LFxuXG4gIC8vIEdldCB0aGUgdmFsdWUgb2YgYSBwcmV2aW91c2x5IHNldCBvcHRpb25cbiAgZ2V0T3B0aW9uOiBmdW5jdGlvbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zW29wdGlvbl07XG4gIH0sXG5cbiAgLy8gRXZlbnQgaGFuZGxlciBmb3Igd2hlbiB1cmwva2V5IGlzIHJlY2VpdmVkIGZyb20gdXNlclxuICB1cGRhdGVTd2FnZ2VyVWk6IGZ1bmN0aW9uKGRhdGEpe1xuICAgIHRoaXMub3B0aW9ucy51cmwgPSBkYXRhLnVybDtcbiAgICB0aGlzLmxvYWQoKTtcbiAgfSxcblxuICAvLyBDcmVhdGUgYW4gYXBpIGFuZCByZW5kZXJcbiAgbG9hZDogZnVuY3Rpb24oKXtcbiAgICAvLyBJbml0aWFsaXplIHRoZSBBUEkgb2JqZWN0XG4gICAgaWYgKHRoaXMubWFpblZpZXcpIHtcbiAgICAgIHRoaXMubWFpblZpZXcuY2xlYXIoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hdXRoVmlldykge1xuICAgICAgdGhpcy5hdXRoVmlldy5yZW1vdmUoKTtcbiAgICB9XG4gICAgdmFyIHVybCA9IHRoaXMub3B0aW9ucy51cmw7XG4gICAgaWYgKHVybCAmJiB1cmwuaW5kZXhPZignaHR0cCcpICE9PSAwKSB7XG4gICAgICB1cmwgPSB0aGlzLmJ1aWxkVXJsKHdpbmRvdy5sb2NhdGlvbi5ocmVmLnRvU3RyaW5nKCksIHVybCk7XG4gICAgfVxuICAgIGlmKHRoaXMuYXBpKSB7XG4gICAgICB0aGlzLm9wdGlvbnMuYXV0aG9yaXphdGlvbnMgPSB0aGlzLmFwaS5jbGllbnRBdXRob3JpemF0aW9ucy5hdXRoejtcbiAgICB9XG4gICAgdGhpcy5vcHRpb25zLnVybCA9IHVybDtcbiAgICB0aGlzLmhlYWRlclZpZXcudXBkYXRlKHVybCk7XG5cbiAgICB0aGlzLmFwaSA9IG5ldyBTd2FnZ2VyQ2xpZW50KHRoaXMub3B0aW9ucyk7XG4gIH0sXG5cbiAgLy8gY29sbGFwc2UgYWxsIHNlY3Rpb25zXG4gIGNvbGxhcHNlQWxsOiBmdW5jdGlvbigpe1xuICAgIERvY3MuY29sbGFwc2VFbmRwb2ludExpc3RGb3JSZXNvdXJjZSgnJyk7XG4gIH0sXG5cbiAgLy8gbGlzdCBvcGVyYXRpb25zIGZvciBhbGwgc2VjdGlvbnNcbiAgbGlzdEFsbDogZnVuY3Rpb24oKXtcbiAgICBEb2NzLmNvbGxhcHNlT3BlcmF0aW9uc0ZvclJlc291cmNlKCcnKTtcbiAgfSxcblxuICAvLyBleHBhbmQgb3BlcmF0aW9ucyBmb3IgYWxsIHNlY3Rpb25zXG4gIGV4cGFuZEFsbDogZnVuY3Rpb24oKXtcbiAgICBEb2NzLmV4cGFuZE9wZXJhdGlvbnNGb3JSZXNvdXJjZSgnJyk7XG4gIH0sXG5cbiAgLy8gVGhpcyBpcyBib3VuZCB0byBzdWNjZXNzIGhhbmRsZXIgZm9yIFN3YWdnZXJBcGlcbiAgLy8gIHNvIGl0IGdldHMgY2FsbGVkIHdoZW4gU3dhZ2dlckFwaSBjb21wbGV0ZXMgbG9hZGluZ1xuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgdmFyIGF1dGhzTW9kZWw7XG4gICAgdGhpcy5zaG93TWVzc2FnZSgnRmluaXNoZWQgTG9hZGluZyBSZXNvdXJjZSBJbmZvcm1hdGlvbi4gUmVuZGVyaW5nIFN3YWdnZXIgVUkuLi4nKTtcbiAgICB0aGlzLm1haW5WaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5NYWluVmlldyh7XG4gICAgICBtb2RlbDogdGhpcy5hcGksXG4gICAgICBlbDogJCgnIycgKyB0aGlzLmRvbV9pZCksXG4gICAgICBzd2FnZ2VyT3B0aW9uczogdGhpcy5vcHRpb25zLFxuICAgICAgcm91dGVyOiB0aGlzXG4gICAgfSkucmVuZGVyKCk7XG4gICAgaWYgKCFfLmlzRW1wdHkodGhpcy5hcGkuc2VjdXJpdHlEZWZpbml0aW9ucykpe1xuICAgICAgYXV0aHNNb2RlbCA9IF8ubWFwKHRoaXMuYXBpLnNlY3VyaXR5RGVmaW5pdGlvbnMsIGZ1bmN0aW9uIChhdXRoLCBuYW1lKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgICAgcmVzdWx0W25hbWVdID0gYXV0aDtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hdXRoVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuQXV0aEJ1dHRvblZpZXcoe1xuICAgICAgICBkYXRhOiBTd2FnZ2VyVWkudXRpbHMucGFyc2VTZWN1cml0eURlZmluaXRpb25zKGF1dGhzTW9kZWwpLFxuICAgICAgICByb3V0ZXI6IHRoaXNcbiAgICAgIH0pO1xuICAgICAgJCgnI2F1dGhfY29udGFpbmVyJykuYXBwZW5kKHRoaXMuYXV0aFZpZXcucmVuZGVyKCkuZWwpO1xuICAgIH1cbiAgICB0aGlzLnNob3dNZXNzYWdlKCk7XG4gICAgc3dpdGNoICh0aGlzLm9wdGlvbnMuZG9jRXhwYW5zaW9uKSB7XG4gICAgICBjYXNlICdmdWxsJzpcbiAgICAgICAgdGhpcy5leHBhbmRBbGwoKTsgYnJlYWs7XG4gICAgICBjYXNlICdsaXN0JzpcbiAgICAgICAgdGhpcy5saXN0QWxsKCk7IGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHRoaXMucmVuZGVyR0ZNKCk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLm9uQ29tcGxldGUpe1xuICAgICAgdGhpcy5vcHRpb25zLm9uQ29tcGxldGUodGhpcy5hcGksIHRoaXMpO1xuICAgIH1cblxuICAgIHNldFRpbWVvdXQoRG9jcy5zaGViYW5nLmJpbmQodGhpcyksIDEwMCk7XG4gIH0sXG5cbiAgYnVpbGRVcmw6IGZ1bmN0aW9uKGJhc2UsIHVybCl7XG4gICAgaWYgKHVybC5pbmRleE9mKCcvJykgPT09IDApIHtcbiAgICAgIHZhciBwYXJ0cyA9IGJhc2Uuc3BsaXQoJy8nKTtcbiAgICAgIGJhc2UgPSBwYXJ0c1swXSArICcvLycgKyBwYXJ0c1syXTtcbiAgICAgIHJldHVybiBiYXNlICsgdXJsO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZW5kT2ZQYXRoID0gYmFzZS5sZW5ndGg7XG5cbiAgICAgIGlmIChiYXNlLmluZGV4T2YoJz8nKSA+IC0xKXtcbiAgICAgICAgZW5kT2ZQYXRoID0gTWF0aC5taW4oZW5kT2ZQYXRoLCBiYXNlLmluZGV4T2YoJz8nKSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChiYXNlLmluZGV4T2YoJyMnKSA+IC0xKXtcbiAgICAgICAgZW5kT2ZQYXRoID0gTWF0aC5taW4oZW5kT2ZQYXRoLCBiYXNlLmluZGV4T2YoJyMnKSk7XG4gICAgICB9XG5cbiAgICAgIGJhc2UgPSBiYXNlLnN1YnN0cmluZygwLCBlbmRPZlBhdGgpO1xuXG4gICAgICBpZiAoYmFzZS5pbmRleE9mKCcvJywgYmFzZS5sZW5ndGggLSAxICkgIT09IC0xKXtcbiAgICAgICAgcmV0dXJuIGJhc2UgKyB1cmw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBiYXNlICsgJy8nICsgdXJsO1xuICAgIH1cbiAgfSxcblxuICAvLyBTaG93cyBtZXNzYWdlIG9uIHRvcGJhciBvZiB0aGUgdWlcbiAgc2hvd01lc3NhZ2U6IGZ1bmN0aW9uKGRhdGEpe1xuICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGRhdGEgPSAnJztcbiAgICB9XG4gICAgdmFyICRtc2diYXIgPSAkKCcjbWVzc2FnZS1iYXInKTtcbiAgICAkbXNnYmFyLnJlbW92ZUNsYXNzKCdtZXNzYWdlLWZhaWwnKTtcbiAgICAkbXNnYmFyLmFkZENsYXNzKCdtZXNzYWdlLXN1Y2Nlc3MnKTtcbiAgICAkbXNnYmFyLnRleHQoZGF0YSk7XG4gICAgaWYod2luZG93LlN3YWdnZXJUcmFuc2xhdG9yKSB7XG4gICAgICB3aW5kb3cuU3dhZ2dlclRyYW5zbGF0b3IudHJhbnNsYXRlKCRtc2diYXIpO1xuICAgIH1cbiAgfSxcblxuICAvLyBzaG93cyBtZXNzYWdlIGluIHJlZFxuICBvbkxvYWRGYWlsdXJlOiBmdW5jdGlvbihkYXRhKXtcbiAgICBpZiAoZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBkYXRhID0gJyc7XG4gICAgfVxuICAgICQoJyNtZXNzYWdlLWJhcicpLnJlbW92ZUNsYXNzKCdtZXNzYWdlLXN1Y2Nlc3MnKTtcbiAgICAkKCcjbWVzc2FnZS1iYXInKS5hZGRDbGFzcygnbWVzc2FnZS1mYWlsJyk7XG5cbiAgICB2YXIgdmFsID0gJCgnI21lc3NhZ2UtYmFyJykudGV4dChkYXRhKTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMub25GYWlsdXJlKSB7XG4gICAgICB0aGlzLm9wdGlvbnMub25GYWlsdXJlKGRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWw7XG4gIH0sXG5cbiAgLy8gUmVuZGVycyBHRk0gZm9yIGVsZW1lbnRzIHdpdGggJ21hcmtkb3duJyBjbGFzc1xuICByZW5kZXJHRk06IGZ1bmN0aW9uKCl7XG4gICAgJCgnLm1hcmtkb3duJykuZWFjaChmdW5jdGlvbigpe1xuICAgICAgJCh0aGlzKS5odG1sKG1hcmtlZCgkKHRoaXMpLmh0bWwoKSkpO1xuICAgIH0pO1xuXG4gICAgJCgnLnByb3BEZXNjJywgJy5tb2RlbC1zaWduYXR1cmUgLmRlc2NyaXB0aW9uJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAkKHRoaXMpLmh0bWwobWFya2VkKCQodGhpcykuaHRtbCgpKSkuYWRkQ2xhc3MoJ21hcmtkb3duJyk7XG4gICAgfSk7XG4gIH1cblxufSk7XG5cbndpbmRvdy5Td2FnZ2VyVWkuVmlld3MgPSB7fTtcbndpbmRvdy5Td2FnZ2VyVWkuTW9kZWxzID0ge307XG53aW5kb3cuU3dhZ2dlclVpLkNvbGxlY3Rpb25zID0ge307XG53aW5kb3cuU3dhZ2dlclVpLnBhcnRpYWxzID0ge307XG53aW5kb3cuU3dhZ2dlclVpLnV0aWxzID0ge307XG5cbi8vIGRvbid0IGJyZWFrIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCBwcmV2aW91cyB2ZXJzaW9ucyBhbmQgd2FybiB1c2VycyB0byB1cGdyYWRlIHRoZWlyIGNvZGVcbihmdW5jdGlvbigpe1xuICB3aW5kb3cuYXV0aG9yaXphdGlvbnMgPSB7XG4gICAgYWRkOiBmdW5jdGlvbigpIHtcbiAgICAgIHdhcm4oJ1VzaW5nIHdpbmRvdy5hdXRob3JpemF0aW9ucyBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIFN3YWdnZXJVaS5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKCkuJyk7XG5cbiAgICAgIGlmICh0eXBlb2Ygd2luZG93LnN3YWdnZXJVaSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignd2luZG93LnN3YWdnZXJVaSBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgfVxuXG4gICAgICBpZiAod2luZG93LnN3YWdnZXJVaSBpbnN0YW5jZW9mIFN3YWdnZXJVaSkge1xuICAgICAgICB3aW5kb3cuc3dhZ2dlclVpLmFwaS5jbGllbnRBdXRob3JpemF0aW9ucy5hZGQuYXBwbHkod2luZG93LnN3YWdnZXJVaS5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHdpbmRvdy5BcGlLZXlBdXRob3JpemF0aW9uID0gZnVuY3Rpb24oKSB7XG4gICAgd2Fybignd2luZG93LkFwaUtleUF1dGhvcml6YXRpb24gaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBTd2FnZ2VyQ2xpZW50LkFwaUtleUF1dGhvcml6YXRpb24uJyk7XG4gICAgU3dhZ2dlckNsaWVudC5BcGlLZXlBdXRob3JpemF0aW9uLmFwcGx5KHdpbmRvdywgYXJndW1lbnRzKTtcbiAgfTtcblxuICB3aW5kb3cuUGFzc3dvcmRBdXRob3JpemF0aW9uID0gZnVuY3Rpb24oKSB7XG4gICAgd2Fybignd2luZG93LlBhc3N3b3JkQXV0aG9yaXphdGlvbiBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIFN3YWdnZXJDbGllbnQuUGFzc3dvcmRBdXRob3JpemF0aW9uLicpO1xuICAgIFN3YWdnZXJDbGllbnQuUGFzc3dvcmRBdXRob3JpemF0aW9uLmFwcGx5KHdpbmRvdywgYXJndW1lbnRzKTtcbiAgfTtcblxuICBmdW5jdGlvbiB3YXJuKG1lc3NhZ2UpIHtcbiAgICBpZiAoJ2NvbnNvbGUnIGluIHdpbmRvdyAmJiB0eXBlb2Ygd2luZG93LmNvbnNvbGUud2FybiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc29sZS53YXJuKG1lc3NhZ2UpO1xuICAgIH1cbiAgfVxufSkoKTtcblxuXG4vLyBVTURcbihmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgLy8gQU1ELiBSZWdpc3RlciBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlLlxuICAgICAgICBkZWZpbmUoWydiJ10sIGZ1bmN0aW9uIChiKSB7XG4gICAgICAgICAgICByZXR1cm4gKHJvb3QuU3dhZ2dlclVpID0gZmFjdG9yeShiKSk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIC8vIE5vZGUuIERvZXMgbm90IHdvcmsgd2l0aCBzdHJpY3QgQ29tbW9uSlMsIGJ1dFxuICAgICAgICAvLyBvbmx5IENvbW1vbkpTLWxpa2UgZW52aXJvbm1lbnRzIHRoYXQgc3VwcG9ydCBtb2R1bGUuZXhwb3J0cyxcbiAgICAgICAgLy8gbGlrZSBOb2RlLlxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSgnYicpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBCcm93c2VyIGdsb2JhbHNcbiAgICAgICAgcm9vdC5Td2FnZ2VyVWkgPSBmYWN0b3J5KHJvb3QuYik7XG4gICAgfVxufSh0aGlzLCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFN3YWdnZXJVaTtcbn0pKTtcbiIsIid1c2Ugc3RyaWN0Jztcblxud2luZG93LlN3YWdnZXJVaS51dGlscyA9IHtcbiAgICBwYXJzZVNlY3VyaXR5RGVmaW5pdGlvbnM6IGZ1bmN0aW9uIChzZWN1cml0eSwgc2VjdXJpdHlEZWZpbml0aW9ucykge1xuICAgICAgICB2YXIgYXV0aHMgPSBPYmplY3QuYXNzaWduKHt9LCBzZWN1cml0eURlZmluaXRpb25zKTtcbiAgICAgICAgdmFyIG9hdXRoMkFyciA9IFtdO1xuICAgICAgICB2YXIgYXV0aHNBcnIgPSBbXTtcbiAgICAgICAgdmFyIHNjb3BlcyA9IFtdO1xuICAgICAgICB2YXIgdXRpbHMgPSB3aW5kb3cuU3dhZ2dlclVpLnV0aWxzO1xuXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWN1cml0eSkpIHsgcmV0dXJuIG51bGw7IH1cblxuICAgICAgICBzZWN1cml0eS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICB2YXIgc2luZ2xlU2VjdXJpdHkgPSB7fTtcbiAgICAgICAgICAgIHZhciBzaW5nbGVPYXV0aDJTZWN1cml0eSA9IHt9O1xuXG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gaXRlbSkge1xuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGl0ZW1ba2V5XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFhdXRoc1trZXldKSB7IGNvbnRpbnVlOyB9XG4gICAgICAgICAgICAgICAgICAgIGF1dGhzW2tleV0gPSBhdXRoc1trZXldIHx8IHt9O1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXV0aHNba2V5XS50eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XSA9IE9iamVjdC5hc3NpZ24oe30sIGF1dGhzW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMgPSBPYmplY3QuYXNzaWduKHt9LCBhdXRoc1trZXldLnNjb3Blcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1ba2V5XS5pbmRleE9mKGkpIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXNbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMgPSB1dGlscy5wYXJzZU9hdXRoMlNjb3BlcyhzaW5nbGVPYXV0aDJTZWN1cml0eVtrZXldLnNjb3Blcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzY29wZXMgPSBfLm1lcmdlKHNjb3Blcywgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlU2VjdXJpdHlba2V5XSA9IE9iamVjdC5hc3NpZ24oe30sIGF1dGhzW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1ba2V5XS50eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XSA9IE9iamVjdC5hc3NpZ24oe30sIGl0ZW1ba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGVPYXV0aDJTZWN1cml0eVtrZXldLnNjb3BlcyA9IHV0aWxzLnBhcnNlT2F1dGgyU2NvcGVzKHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlcyA9IF8ubWVyZ2Uoc2NvcGVzLCBzaW5nbGVPYXV0aDJTZWN1cml0eVtrZXldLnNjb3Blcyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGVTZWN1cml0eVtrZXldID0gaXRlbVtrZXldO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIV8uaXNFbXB0eShzaW5nbGVTZWN1cml0eSkpIHtcbiAgICAgICAgICAgICAgICBhdXRoc0Fyci5wdXNoKHNpbmdsZVNlY3VyaXR5KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoc2luZ2xlT2F1dGgyU2VjdXJpdHkpKXtcbiAgICAgICAgICAgICAgICBvYXV0aDJBcnIucHVzaChzaW5nbGVPYXV0aDJTZWN1cml0eSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhdXRocyA6IGF1dGhzQXJyLFxuICAgICAgICAgICAgb2F1dGgyOiBvYXV0aDJBcnIsXG4gICAgICAgICAgICBzY29wZXM6IHNjb3Blc1xuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBwYXJzZU9hdXRoMlNjb3BlczogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIHNjb3BlcyA9IE9iamVjdC5hc3NpZ24oe30sIGRhdGEpO1xuICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gc2NvcGVzKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaCh7c2NvcGU6IGtleSwgZGVzY3JpcHRpb246IHNjb3Blc1trZXldfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG5cbiAgICBzYW5pdGl6ZTogZnVuY3Rpb24oaHRtbCkge1xuICAgICAgICAvLyBTdHJpcCB0aGUgc2NyaXB0IHRhZ3MgZnJvbSB0aGUgaHRtbCBhbmQgaW5saW5lIGV2ZW5oYW5kbGVyc1xuICAgICAgICBodG1sID0gaHRtbC5yZXBsYWNlKC88c2NyaXB0XFxiW148XSooPzooPyE8XFwvc2NyaXB0Pik8W148XSopKjxcXC9zY3JpcHQ+L2dpLCAnJyk7XG4gICAgICAgIGh0bWwgPSBodG1sLnJlcGxhY2UoLyhvblxcdys9XCJbXlwiXSpcIikqKG9uXFx3Kz0nW14nXSonKSoob25cXHcrPVxcdypcXChcXHcqXFwpKSovZ2ksICcnKTtcblxuICAgICAgICByZXR1cm4gaHRtbDtcbiAgICB9XG59OyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLk1vZGVscy5BcGlLZXlBdXRoTW9kZWwgPSBCYWNrYm9uZS5Nb2RlbC5leHRlbmQoe1xuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgICdpbic6ICcnLFxuICAgICAgICBuYW1lOiAnJyxcbiAgICAgICAgdGl0bGU6ICcnLFxuICAgICAgICB2YWx1ZTogJydcbiAgICB9LFxuXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm9uKCdjaGFuZ2UnLCB0aGlzLnZhbGlkYXRlKTtcbiAgICB9LFxuXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZhbGlkID0gISF0aGlzLmdldCgndmFsdWUnKTtcblxuICAgICAgICB0aGlzLnNldCgndmFsaWQnLCB2YWxpZCk7XG5cbiAgICAgICAgcmV0dXJuIHZhbGlkO1xuICAgIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLkFwaUtleUF1dGhWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoeyAvLyBUT0RPOiBhcHBlbmQgdGhpcyB0byBnbG9iYWwgU3dhZ2dlclVpXG5cbiAgICBldmVudHM6IHtcbiAgICAgICAgJ2NoYW5nZSAuaW5wdXRfYXBpS2V5X2VudHJ5JzogJ2FwaUtleUNoYW5nZSdcbiAgICB9LFxuXG4gICAgc2VsZWN0b3JzOiB7XG4gICAgICAgIGFwaWtleUlucHV0OiAnLmlucHV0X2FwaUtleV9lbnRyeSdcbiAgICB9LFxuXG4gICAgdGVtcGxhdGU6IEhhbmRsZWJhcnMudGVtcGxhdGVzLmFwaWtleV9hdXRoLFxuXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ob3B0cykge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRzIHx8IHt9O1xuICAgICAgICB0aGlzLnJvdXRlciA9IHRoaXMub3B0aW9ucy5yb3V0ZXI7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCl7XG4gICAgICAgIHRoaXMuJGVsLmh0bWwodGhpcy50ZW1wbGF0ZSh0aGlzLm1vZGVsLnRvSlNPTigpKSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGFwaUtleUNoYW5nZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIHZhbCA9ICQoZS50YXJnZXQpLnZhbCgpO1xuICAgICAgICBpZiAodmFsKSB7XG4gICAgICAgICAgICB0aGlzLiQodGhpcy5zZWxlY3RvcnMuYXBpa2V5SW5wdXQpLnJlbW92ZUNsYXNzKCdlcnJvcicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tb2RlbC5zZXQoJ3ZhbHVlJywgdmFsKTtcbiAgICB9LFxuXG4gICAgaXNWYWxpZDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC52YWxpZGF0ZSgpO1xuICAgIH0sXG5cbiAgICBoaWdobGlnaHRJbnZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuJCh0aGlzLnNlbGVjdG9ycy5hcGlrZXlJbnB1dCkuYWRkQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLkF1dGhCdXR0b25WaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICAgIGV2ZW50czoge1xuICAgICAgICAnY2xpY2sgLmF1dGhvcml6ZV9fYnRuJzogJ2F1dGhvcml6ZUJ0bkNsaWNrJ1xuICAgIH0sXG5cbiAgICB0cGxzOiB7XG4gICAgICAgIHBvcHVwOiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wb3B1cCxcbiAgICAgICAgYXV0aEJ0bjogSGFuZGxlYmFycy50ZW1wbGF0ZXMuYXV0aF9idXR0b24sXG4gICAgICAgIGF1dGhCdG5PcGVyYXRpb246IEhhbmRsZWJhcnMudGVtcGxhdGVzLmF1dGhfYnV0dG9uX29wZXJhdGlvblxuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdHMgfHwge307XG4gICAgICAgIHRoaXMub3B0aW9ucy5kYXRhID0gdGhpcy5vcHRpb25zLmRhdGEgfHwge307XG4gICAgICAgIHRoaXMuaXNPcGVyYXRpb24gPSB0aGlzLm9wdGlvbnMuaXNPcGVyYXRpb247XG4gICAgICAgIHRoaXMubW9kZWwgPSB0aGlzLm1vZGVsIHx8IHt9O1xuICAgICAgICB0aGlzLnJvdXRlciA9IHRoaXMub3B0aW9ucy5yb3V0ZXI7XG4gICAgICAgIHRoaXMuYXV0aHMgPSB0aGlzLm9wdGlvbnMuZGF0YS5vYXV0aDIuY29uY2F0KHRoaXMub3B0aW9ucy5kYXRhLmF1dGhzKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0cGxOYW1lID0gdGhpcy5pc09wZXJhdGlvbiA/ICdhdXRoQnRuT3BlcmF0aW9uJyA6ICdhdXRoQnRuJztcblxuICAgICAgICB0aGlzLiRhdXRoRWwgPSB0aGlzLnJlbmRlckF1dGhzKHRoaXMuYXV0aHMpO1xuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudHBsc1t0cGxOYW1lXSh0aGlzLm1vZGVsKSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGF1dGhvcml6ZUJ0bkNsaWNrOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgYXV0aHNNb2RlbDtcblxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgYXV0aHNNb2RlbCA9IHtcbiAgICAgICAgICAgIHRpdGxlOiAnQXZhaWxhYmxlIGF1dGhvcml6YXRpb25zJyxcbiAgICAgICAgICAgIGNvbnRlbnQ6IHRoaXMuJGF1dGhFbFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFRoZSBjb250ZW50IG9mIHRoZSBwb3B1cCBpcyByZW1vdmVkIGFuZCBhbGwgZXZlbnRzIHVuYm91bmQgYWZ0ZXIgY2xpY2tpbmcgdGhlICdDYW5jZWwnIGJ1dHRvbiBvZiB0aGUgcG9wdXAuXG4gICAgICAgIC8vIFdlJ2xsIGhhdmUgdG8gcmUtcmVuZGVyIHRoZSBjb250ZW50cyBiZWZvcmUgY3JlYXRpbmcgYSBuZXcgcG9wdXAgdmlldy5cbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgICAgICB0aGlzLnBvcHVwID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5Qb3B1cFZpZXcoe21vZGVsOiBhdXRoc01vZGVsfSk7XG4gICAgICAgIHRoaXMucG9wdXAucmVuZGVyKCk7XG4gICAgfSxcblxuICAgIHJlbmRlckF1dGhzOiBmdW5jdGlvbiAoYXV0aHMpIHtcbiAgICAgICAgdmFyICRlbCA9ICQoJzxkaXY+Jyk7XG4gICAgICAgIHZhciBpc0xvZ291dCA9IGZhbHNlO1xuXG4gICAgICAgIGF1dGhzLmZvckVhY2goZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgICAgIHZhciBhdXRoVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuQXV0aFZpZXcoe2RhdGE6IGF1dGgsIHJvdXRlcjogdGhpcy5yb3V0ZXJ9KTtcbiAgICAgICAgICAgIHZhciBhdXRoRWwgPSBhdXRoVmlldy5yZW5kZXIoKS5lbDtcbiAgICAgICAgICAgICRlbC5hcHBlbmQoYXV0aEVsKTtcbiAgICAgICAgICAgIGlmIChhdXRoVmlldy5pc0xvZ291dCkge1xuICAgICAgICAgICAgICAgIGlzTG9nb3V0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5tb2RlbC5pc0xvZ291dCA9IGlzTG9nb3V0O1xuXG4gICAgICAgIHJldHVybiAkZWw7XG4gICAgfVxuXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLkNvbGxlY3Rpb25zLkF1dGhzQ29sbGVjdGlvbiA9IEJhY2tib25lLkNvbGxlY3Rpb24uZXh0ZW5kKHtcbiAgICBjb25zdHJ1Y3RvcjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgICAgICBhcmdzWzBdID0gdGhpcy5wYXJzZShhcmdzWzBdKTtcblxuICAgICAgICBCYWNrYm9uZS5Db2xsZWN0aW9uLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH0sXG5cbiAgICBhZGQ6IGZ1bmN0aW9uIChtb2RlbCkge1xuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobW9kZWwpKSB7XG4gICAgICAgICAgICBhcmdzWzBdID0gXy5tYXAobW9kZWwsIGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZU9uZSh2YWwpO1xuICAgICAgICAgICAgfSwgdGhpcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhcmdzWzBdID0gdGhpcy5oYW5kbGVPbmUobW9kZWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgQmFja2JvbmUuQ29sbGVjdGlvbi5wcm90b3R5cGUuYWRkLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH0sXG5cbiAgICBoYW5kbGVPbmU6IGZ1bmN0aW9uIChtb2RlbCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gbW9kZWw7XG5cbiAgICAgICAgaWYgKCEgKG1vZGVsIGluc3RhbmNlb2YgQmFja2JvbmUuTW9kZWwpICkge1xuICAgICAgICAgICAgc3dpdGNoIChtb2RlbC50eXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnb2F1dGgyJzpcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFN3YWdnZXJVaS5Nb2RlbHMuT2F1dGgyTW9kZWwobW9kZWwpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdiYXNpYyc6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTd2FnZ2VyVWkuTW9kZWxzLkJhc2ljQXV0aE1vZGVsKG1vZGVsKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnYXBpS2V5JzpcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFN3YWdnZXJVaS5Nb2RlbHMuQXBpS2V5QXV0aE1vZGVsKG1vZGVsKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEJhY2tib25lLk1vZGVsKG1vZGVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIGlzVmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHZhbGlkID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLm1vZGVscy5mb3JFYWNoKGZ1bmN0aW9uKG1vZGVsKSB7XG4gICAgICAgICAgICBpZiAoIW1vZGVsLnZhbGlkYXRlKCkpIHtcbiAgICAgICAgICAgICAgICB2YWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdmFsaWQ7XG4gICAgfSxcblxuICAgIGlzQXV0aG9yaXplZDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sZW5ndGggPT09IHRoaXMud2hlcmUoeyBpc0xvZ291dDogdHJ1ZSB9KS5sZW5ndGg7XG4gICAgfSxcblxuICAgIGlzUGFydGlhbGx5QXV0aG9yaXplZDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aGVyZSh7IGlzTG9nb3V0OiB0cnVlIH0pLmxlbmd0aCA+IDA7XG4gICAgfSxcblxuICAgIHBhcnNlOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgYXV0aHogPSB7fTtcblxuICAgICAgICBpZih0eXBlb2Ygd2luZG93LnN3YWdnZXJVaSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGF1dGh6ID0gT2JqZWN0LmFzc2lnbih7fSwgd2luZG93LnN3YWdnZXJVaS5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYXV0aHopO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIF8ubWFwKGRhdGEsIGZ1bmN0aW9uIChhdXRoLCBuYW1lKSB7XG4gICAgICAgICAgICB2YXIgaXNCYXNpYyA9IGF1dGh6W25hbWVdICYmIGF1dGgudHlwZSA9PT0gJ2Jhc2ljJyAmJiBhdXRoeltuYW1lXS51c2VybmFtZSAmJiBhdXRoeltuYW1lXS5wYXNzd29yZDtcblxuICAgICAgICAgICAgXy5leHRlbmQoYXV0aCwge1xuICAgICAgICAgICAgICAgIHRpdGxlOiBuYW1lXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKGF1dGh6W25hbWVdIHx8IGlzQmFzaWMpIHtcbiAgICAgICAgICAgICAgICBfLmV4dGVuZChhdXRoLCB7XG4gICAgICAgICAgICAgICAgICAgIGlzTG9nb3V0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaXNCYXNpYyA/IHVuZGVmaW5lZCA6IGF1dGh6W25hbWVdLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB1c2VybmFtZTogaXNCYXNpYyA/IGF1dGh6W25hbWVdLnVzZXJuYW1lIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICBwYXNzd29yZDogaXNCYXNpYyA/IGF1dGh6W25hbWVdLnBhc3N3b3JkIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICB2YWxpZDogdHJ1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gYXV0aDtcbiAgICAgICAgfSk7XG4gICAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuQXV0aHNDb2xsZWN0aW9uVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cyB8fCB7fTtcbiAgICAgICAgdGhpcy5vcHRpb25zLmRhdGEgPSB0aGlzLm9wdGlvbnMuZGF0YSB8fCB7fTtcbiAgICAgICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuXG4gICAgICAgIHRoaXMuY29sbGVjdGlvbiA9IG5ldyBTd2FnZ2VyVWkuQ29sbGVjdGlvbnMuQXV0aHNDb2xsZWN0aW9uKG9wdHMuZGF0YSk7XG5cbiAgICAgICAgdGhpcy4kaW5uZXJFbCA9ICQoJzxkaXY+Jyk7XG4gICAgICAgIHRoaXMuYXV0aFZpZXdzID0gW107XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmNvbGxlY3Rpb24uZWFjaChmdW5jdGlvbiAoYXV0aCkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJPbmVBdXRoKGF1dGgpO1xuICAgICAgICB9LCB0aGlzKTtcblxuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMuJGlubmVyRWwuaHRtbCgpID8gdGhpcy4kaW5uZXJFbCA6ICcnKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgcmVuZGVyT25lQXV0aDogZnVuY3Rpb24gKGF1dGhNb2RlbCkge1xuICAgICAgICB2YXIgYXV0aFZpZXdFbCwgYXV0aFZpZXcsIGF1dGhWaWV3TmFtZTtcbiAgICAgICAgdmFyIHR5cGUgPSBhdXRoTW9kZWwuZ2V0KCd0eXBlJyk7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhcGlLZXknKSB7XG4gICAgICAgICAgICBhdXRoVmlld05hbWUgPSAnQXBpS2V5QXV0aFZpZXcnO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdiYXNpYycgJiYgdGhpcy4kaW5uZXJFbC5maW5kKCcuYmFzaWNfYXV0aF9jb250YWluZXInKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGF1dGhWaWV3TmFtZSA9ICdCYXNpY0F1dGhWaWV3JztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgYXV0aFZpZXdOYW1lID0gJ09hdXRoMlZpZXcnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGF1dGhWaWV3TmFtZSkge1xuICAgICAgICAgICAgYXV0aFZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzW2F1dGhWaWV3TmFtZV0oe21vZGVsOiBhdXRoTW9kZWwsIHJvdXRlcjogdGhpcy5yb3V0ZXJ9KTtcbiAgICAgICAgICAgIGF1dGhWaWV3RWwgPSBhdXRoVmlldy5yZW5kZXIoKS5lbDtcbiAgICAgICAgICAgIHRoaXMuYXV0aFZpZXdzLnB1c2goYXV0aFZpZXcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy4kaW5uZXJFbC5hcHBlbmQoYXV0aFZpZXdFbCk7XG4gICAgfSxcblxuICAgIGhpZ2hsaWdodEludmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hdXRoVmlld3MuZm9yRWFjaChmdW5jdGlvbiAodmlldykge1xuICAgICAgICAgICAgdmlldy5oaWdobGlnaHRJbnZhbGlkKCk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIH1cblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qIGdsb2JhbCByZWRpcmVjdF91cmk6dHJ1ZSAqL1xuLyogZ2xvYmFsIGNsaWVudElkICovXG4vKiBnbG9iYWwgc2NvcGVTZXBhcmF0b3IgKi9cbi8qIGdsb2JhbCBhZGRpdGlvbmFsUXVlcnlTdHJpbmdQYXJhbXMgKi9cbi8qIGdsb2JhbCBjbGllbnRTZWNyZXQgKi9cbi8qIGdsb2JhbCBvbk9BdXRoQ29tcGxldGUgKi9cbi8qIGdsb2JhbCByZWFsbSAqL1xuLypqc2hpbnQgdW51c2VkOmZhbHNlKi9cblxuU3dhZ2dlclVpLlZpZXdzLkF1dGhWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICAgIGV2ZW50czoge1xuICAgICAgICAnY2xpY2sgLmF1dGhfc3VibWl0X19idXR0b24nOiAnYXV0aG9yaXplQ2xpY2snLFxuICAgICAgICAnY2xpY2sgLmF1dGhfbG9nb3V0X19idXR0b24nOiAnbG9nb3V0Q2xpY2snXG4gICAgfSxcblxuICAgIHRwbHM6IHtcbiAgICAgICAgbWFpbjogSGFuZGxlYmFycy50ZW1wbGF0ZXMuYXV0aF92aWV3XG4gICAgfSxcblxuICAgIHNlbGVjdG9yczoge1xuICAgICAgICBpbm5lckVsOiAnLmF1dGhfaW5uZXInLFxuICAgICAgICBhdXRoQnRuOiAnLmF1dGhfc3VibWl0X19idXR0b24nXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cyB8fCB7fTtcbiAgICAgICAgb3B0cy5kYXRhID0gb3B0cy5kYXRhIHx8IHt9O1xuICAgICAgICB0aGlzLnJvdXRlciA9IHRoaXMub3B0aW9ucy5yb3V0ZXI7XG5cbiAgICAgICAgdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5BdXRoc0NvbGxlY3Rpb25WaWV3KHtkYXRhOiBvcHRzLmRhdGF9KTtcblxuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudHBscy5tYWluKHtcbiAgICAgICAgICAgIGlzTG9nb3V0OiB0aGlzLmF1dGhzQ29sbGVjdGlvblZpZXcuY29sbGVjdGlvbi5pc0F1dGhvcml6ZWQoKSxcbiAgICAgICAgICAgIGlzQXV0aG9yaXplZDogdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNQYXJ0aWFsbHlBdXRob3JpemVkKClcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLiRpbm5lckVsID0gdGhpcy4kKHRoaXMuc2VsZWN0b3JzLmlubmVyRWwpO1xuICAgICAgICB0aGlzLmlzTG9nb3V0ID0gdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNQYXJ0aWFsbHlBdXRob3JpemVkKCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLiRpbm5lckVsLmh0bWwodGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LnJlbmRlcigpLmVsKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgYXV0aG9yaXplQ2xpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBpZiAodGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICB0aGlzLmF1dGhvcml6ZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmhpZ2hsaWdodEludmFsaWQoKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBhdXRob3JpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uZm9yRWFjaChmdW5jdGlvbiAoYXV0aCkge1xuICAgICAgICAgICAgdmFyIGtleUF1dGgsIGJhc2ljQXV0aDtcbiAgICAgICAgICAgIHZhciB0eXBlID0gYXV0aC5nZXQoJ3R5cGUnKTtcblxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdhcGlLZXknKSB7XG4gICAgICAgICAgICAgICAga2V5QXV0aCA9IG5ldyBTd2FnZ2VyQ2xpZW50LkFwaUtleUF1dGhvcml6YXRpb24oXG4gICAgICAgICAgICAgICAgICAgIGF1dGguZ2V0KCduYW1lJyksXG4gICAgICAgICAgICAgICAgICAgIGF1dGguZ2V0KCd2YWx1ZScpLFxuICAgICAgICAgICAgICAgICAgICBhdXRoLmdldCgnaW4nKVxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKGF1dGguZ2V0KCd0aXRsZScpLCBrZXlBdXRoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jhc2ljJykge1xuICAgICAgICAgICAgICAgIGJhc2ljQXV0aCA9IG5ldyBTd2FnZ2VyQ2xpZW50LlBhc3N3b3JkQXV0aG9yaXphdGlvbihhdXRoLmdldCgndXNlcm5hbWUnKSwgYXV0aC5nZXQoJ3Bhc3N3b3JkJykpO1xuICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLmFwaS5jbGllbnRBdXRob3JpemF0aW9ucy5hZGQoYXV0aC5nZXQoJ3RpdGxlJyksIGJhc2ljQXV0aCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYXV0aDInKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVPYXV0aDJMb2dpbihhdXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5yb3V0ZXIubG9hZCgpO1xuICAgIH0sXG5cbiAgICBsb2dvdXRDbGljazogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmZvckVhY2goZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgICAgIHdpbmRvdy5zd2FnZ2VyVWkuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLnJlbW92ZShhdXRoLmdldCgndGl0bGUnKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucm91dGVyLmxvYWQoKTtcbiAgICB9LFxuXG4gICAgLy8gdGFrZW4gZnJvbSBsaWIvc3dhZ2dlci1vYXV0aC5qc1xuICAgIGhhbmRsZU9hdXRoMkxvZ2luOiBmdW5jdGlvbiAoYXV0aCkge1xuICAgICAgICB2YXIgaG9zdCA9IHdpbmRvdy5sb2NhdGlvbjtcbiAgICAgICAgdmFyIHBhdGhuYW1lID0gbG9jYXRpb24ucGF0aG5hbWUuc3Vic3RyaW5nKDAsIGxvY2F0aW9uLnBhdGhuYW1lLmxhc3RJbmRleE9mKCcvJykpO1xuICAgICAgICB2YXIgZGVmYXVsdFJlZGlyZWN0VXJsID0gaG9zdC5wcm90b2NvbCArICcvLycgKyBob3N0Lmhvc3QgKyBwYXRobmFtZSArICcvbzJjLmh0bWwnO1xuICAgICAgICB2YXIgcmVkaXJlY3RVcmwgPSB3aW5kb3cub0F1dGhSZWRpcmVjdFVybCB8fCBkZWZhdWx0UmVkaXJlY3RVcmw7XG4gICAgICAgIHZhciB1cmwgPSBudWxsO1xuICAgICAgICB2YXIgc2NvcGVzID0gXy5tYXAoYXV0aC5nZXQoJ3Njb3BlcycpLCBmdW5jdGlvbiAoc2NvcGUpIHtcbiAgICAgICAgICAgIGlmKHNjb3BlLmNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NvcGUuc2NvcGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgY29udGFpbmVyID0gd2luZG93LnN3YWdnZXJVaUF1dGggfHwgKHdpbmRvdy5zd2FnZ2VyVWlBdXRoID0ge30pO1xuICAgICAgICB2YXIgc3RhdGUsIGRldHMsIGVwO1xuICAgICAgICBjb250YWluZXIuT0F1dGhTY2hlbWVLZXkgPSBhdXRoLmdldCgndGl0bGUnKTtcblxuICAgICAgICB3aW5kb3cuZW5hYmxlZFNjb3BlcyA9IHNjb3BlcztcbiAgICAgICAgdmFyIGZsb3cgPSBhdXRoLmdldCgnZmxvdycpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBhY2Nlc3MgdG9rZW4gcGFyYW1ldGVyIHJldHVybmVkIGJ5IHRoZSBzZXJ2ZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSBkZXRzXG4gICAgICAgICAqICAgICBUaGUgYXV0aG9yaXNhdGlvbiBzY2hlbWUgY29uZmlndXJhdGlvbi5cbiAgICAgICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgYWNjZXNzIHRva2VuIHBhcmFtZXRlclxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZ2V0VG9rZW5OYW1lKGRldHMpIHtcbiAgICAgICAgICAgIHJldHVybiBkZXRzLnZlbmRvckV4dGVuc2lvbnNbJ3gtdG9rZW5OYW1lJ10gfHwgZGV0cy50b2tlbk5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZihhdXRoLmdldCgndHlwZScpID09PSAnb2F1dGgyJyAmJiBmbG93ICYmIChmbG93ID09PSAnaW1wbGljaXQnIHx8IGZsb3cgPT09ICdhY2Nlc3NDb2RlJykpIHtcbiAgICAgICAgICAgIGRldHMgPSBhdXRoLmF0dHJpYnV0ZXM7XG4gICAgICAgICAgICB1cmwgPSBkZXRzLmF1dGhvcml6YXRpb25VcmwgKyAnP3Jlc3BvbnNlX3R5cGU9JyArIChmbG93ID09PSAnaW1wbGljaXQnID8gJ3Rva2VuJyA6ICdjb2RlJyk7XG4gICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZ2V0VG9rZW5OYW1lKGRldHMpIHx8ICdhY2Nlc3NfdG9rZW4nO1xuICAgICAgICAgICAgY29udGFpbmVyLnRva2VuVXJsID0gKGZsb3cgPT09ICdhY2Nlc3NDb2RlJyA/IGRldHMudG9rZW5VcmwgOiBudWxsKTtcbiAgICAgICAgICAgIHN0YXRlID0gY29udGFpbmVyLk9BdXRoU2NoZW1lS2V5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYoYXV0aC5nZXQoJ3R5cGUnKSA9PT0gJ29hdXRoMicgJiYgZmxvdyAmJiAoZmxvdyA9PT0gJ2FwcGxpY2F0aW9uJykpIHtcbiAgICAgICAgICAgIGRldHMgPSBhdXRoLmF0dHJpYnV0ZXM7XG4gICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZ2V0VG9rZW5OYW1lKGRldHMpIHx8ICdhY2Nlc3NfdG9rZW4nO1xuICAgICAgICAgICAgdGhpcy5jbGllbnRDcmVkZW50aWFsc0Zsb3coc2NvcGVzLCBkZXRzLCBjb250YWluZXIuT0F1dGhTY2hlbWVLZXkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYoYXV0aC5nZXQoJ3R5cGUnKSA9PT0gJ29hdXRoMicgJiYgZmxvdyAmJiAoZmxvdyA9PT0gJ3Bhc3N3b3JkJykpIHtcbiAgICAgICAgICAgIGRldHMgPSBhdXRoLmF0dHJpYnV0ZXM7XG4gICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZ2V0VG9rZW5OYW1lKGRldHMpIHx8ICdhY2Nlc3NfdG9rZW4nO1xuICAgICAgICAgICAgdGhpcy5wYXNzd29yZEZsb3coc2NvcGVzLCBkZXRzLCBjb250YWluZXIuT0F1dGhTY2hlbWVLZXkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYoYXV0aC5nZXQoJ2dyYW50VHlwZXMnKSkge1xuICAgICAgICAgICAgLy8gMS4yIHN1cHBvcnRcbiAgICAgICAgICAgIHZhciBvID0gYXV0aC5nZXQoJ2dyYW50VHlwZXMnKTtcbiAgICAgICAgICAgIGZvcih2YXIgdCBpbiBvKSB7XG4gICAgICAgICAgICAgICAgaWYoby5oYXNPd25Qcm9wZXJ0eSh0KSAmJiB0ID09PSAnaW1wbGljaXQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGRldHMgPSBvW3RdO1xuICAgICAgICAgICAgICAgICAgICBlcCA9IGRldHMubG9naW5FbmRwb2ludC51cmw7XG4gICAgICAgICAgICAgICAgICAgIHVybCA9IGRldHMubG9naW5FbmRwb2ludC51cmwgKyAnP3Jlc3BvbnNlX3R5cGU9dG9rZW4nO1xuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZ2V0VG9rZW5OYW1lKGRldHMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChvLmhhc093blByb3BlcnR5KHQpICYmIHQgPT09ICdhY2Nlc3NDb2RlJykge1xuICAgICAgICAgICAgICAgICAgICBkZXRzID0gb1t0XTtcbiAgICAgICAgICAgICAgICAgICAgZXAgPSBkZXRzLnRva2VuUmVxdWVzdEVuZHBvaW50LnVybDtcbiAgICAgICAgICAgICAgICAgICAgdXJsID0gZGV0cy50b2tlblJlcXVlc3RFbmRwb2ludC51cmwgKyAnP3Jlc3BvbnNlX3R5cGU9Y29kZSc7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lci50b2tlbk5hbWUgPSBnZXRUb2tlbk5hbWUoZGV0cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RVcmw7XG5cbiAgICAgICAgdXJsICs9ICcmcmVkaXJlY3RfdXJpPScgKyBlbmNvZGVVUklDb21wb25lbnQocmVkaXJlY3RVcmwpO1xuICAgICAgICB1cmwgKz0gJyZyZWFsbT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHJlYWxtKTtcbiAgICAgICAgdXJsICs9ICcmY2xpZW50X2lkPScgKyBlbmNvZGVVUklDb21wb25lbnQoY2xpZW50SWQpO1xuICAgICAgICB1cmwgKz0gJyZzY29wZT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHNjb3Blcy5qb2luKHNjb3BlU2VwYXJhdG9yKSk7XG4gICAgICAgIHVybCArPSAnJnN0YXRlPScgKyBlbmNvZGVVUklDb21wb25lbnQoc3RhdGUpO1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gYWRkaXRpb25hbFF1ZXJ5U3RyaW5nUGFyYW1zKSB7XG4gICAgICAgICAgICB1cmwgKz0gJyYnICsga2V5ICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KGFkZGl0aW9uYWxRdWVyeVN0cmluZ1BhcmFtc1trZXldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdpbmRvdy5vcGVuKHVybCk7XG4gICAgfSxcblxuICAgIC8vIHRha2VuIGZyb20gbGliL3N3YWdnZXItb2F1dGguanNcbiAgICBjbGllbnRDcmVkZW50aWFsc0Zsb3c6IGZ1bmN0aW9uIChzY29wZXMsIG9hdXRoLCBPQXV0aFNjaGVtZUtleSkge1xuICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuUmVxdWVzdChzY29wZXMsIG9hdXRoLCBPQXV0aFNjaGVtZUtleSwgJ2NsaWVudF9jcmVkZW50aWFscycpO1xuICAgIH0sXG5cbiAgICBwYXNzd29yZEZsb3c6IGZ1bmN0aW9uIChzY29wZXMsIG9hdXRoLCBPQXV0aFNjaGVtZUtleSkge1xuICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuUmVxdWVzdChzY29wZXMsIG9hdXRoLCBPQXV0aFNjaGVtZUtleSwgJ3Bhc3N3b3JkJywge1xuICAgICAgICAgICAgJ3VzZXJuYW1lJzogb2F1dGgudXNlcm5hbWUsXG4gICAgICAgICAgICAncGFzc3dvcmQnOiBvYXV0aC5wYXNzd29yZFxuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgYWNjZXNzVG9rZW5SZXF1ZXN0OiBmdW5jdGlvbiAoc2NvcGVzLCBvYXV0aCwgT0F1dGhTY2hlbWVLZXksIGdyYW50VHlwZSwgcGFyYW1zKSB7XG4gICAgICAgIHBhcmFtcyA9ICQuZXh0ZW5kKHt9LCB7XG4gICAgICAgICAgICAnc2NvcGUnOiBzY29wZXMuam9pbignICcpLFxuICAgICAgICAgICAgJ2dyYW50X3R5cGUnOiBncmFudFR5cGVcbiAgICAgICAgfSwgcGFyYW1zKTtcblxuICAgICAgICB2YXIgaGVhZGVycz0ge307XG5cbiAgICAgICAgc3dpdGNoIChvYXV0aC5jbGllbnRBdXRoZW50aWNhdGlvblR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2Jhc2ljJzpcbiAgICAgICAgICAgICAgICBoZWFkZXJzLkF1dGhvcml6YXRpb24gPSAnQmFzaWMgJyArIGJ0b2Eob2F1dGguY2xpZW50SWQgKyAnOicgKyBvYXV0aC5jbGllbnRTZWNyZXQpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncmVxdWVzdC1ib2R5JzpcbiAgICAgICAgICAgICAgICBwYXJhbXMuY2xpZW50X2lkID0gb2F1dGguY2xpZW50SWQ7XG4gICAgICAgICAgICAgICAgcGFyYW1zLmNsaWVudF9zZWNyZXQgPSBvYXV0aC5jbGllbnRTZWNyZXQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsIDogb2F1dGgudG9rZW5VcmwsXG4gICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiBwYXJhbXMsXG4gICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKGRhdGEpXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgb25PQXV0aENvbXBsZXRlKGRhdGEsIE9BdXRoU2NoZW1lS2V5KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKClcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBvbk9BdXRoQ29tcGxldGUoJycpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLk1vZGVscy5CYXNpY0F1dGhNb2RlbCA9IEJhY2tib25lLk1vZGVsLmV4dGVuZCh7XG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgdXNlcm5hbWU6ICcnLFxuICAgICAgICBwYXNzd29yZDogJycsXG4gICAgICAgIHRpdGxlOiAnYmFzaWMnXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vbignY2hhbmdlJywgdGhpcy52YWxpZGF0ZSk7XG4gICAgfSxcblxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2YWxpZCA9ICEhdGhpcy5nZXQoJ3Bhc3N3b3JkJykgJiYgISF0aGlzLmdldCgndXNlcm5hbWUnKTtcblxuICAgICAgICB0aGlzLnNldCgndmFsaWQnLCB2YWxpZCk7XG5cbiAgICAgICAgcmV0dXJuIHZhbGlkO1xuICAgIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLkJhc2ljQXV0aFZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAob3B0cykge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRzIHx8IHt9O1xuICAgICAgICB0aGlzLnJvdXRlciA9IHRoaXMub3B0aW9ucy5yb3V0ZXI7XG4gICAgfSxcblxuICAgIGV2ZW50czoge1xuICAgICAgICAnY2hhbmdlIC5hdXRoX2lucHV0JzogJ2lucHV0Q2hhbmdlJ1xuICAgIH0sXG5cbiAgICBzZWxlY3RvcnM6IHtcbiAgICAgICAgdXNlcm5hbWVJbnB1dDogJy5iYXNpY19hdXRoX191c2VybmFtZScsXG4gICAgICAgIHBhc3N3b3JkSW5wdXQ6ICcuYmFzaWNfYXV0aF9fcGFzc3dvcmQnXG4gICAgfSxcblxuICAgIGNsczoge1xuICAgICAgICBlcnJvcjogJ2Vycm9yJ1xuICAgIH0sXG5cbiAgICB0ZW1wbGF0ZTogSGFuZGxlYmFycy50ZW1wbGF0ZXMuYmFzaWNfYXV0aCxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24oKXtcbiAgICAgICAgJCh0aGlzLmVsKS5odG1sKHRoaXMudGVtcGxhdGUodGhpcy5tb2RlbC50b0pTT04oKSkpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBpbnB1dENoYW5nZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyICRlbCA9ICQoZS50YXJnZXQpO1xuICAgICAgICB2YXIgdmFsID0gJGVsLnZhbCgpO1xuICAgICAgICB2YXIgYXR0ciA9ICRlbC5wcm9wKCduYW1lJyk7XG5cbiAgICAgICAgaWYgKHZhbCkge1xuICAgICAgICAgICAgJGVsLnJlbW92ZUNsYXNzKHRoaXMuY2xzLmVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubW9kZWwuc2V0KGF0dHIsIHZhbCk7XG4gICAgfSxcblxuICAgIGlzVmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwudmFsaWRhdGUoKTtcbiAgICB9LFxuXG4gICAgaGlnaGxpZ2h0SW52YWxpZDogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXRoaXMubW9kZWwuZ2V0KCd1c2VybmFtZScpKSB7XG4gICAgICAgICAgICB0aGlzLiQodGhpcy5zZWxlY3RvcnMudXNlcm5hbWVJbnB1dCkuYWRkQ2xhc3ModGhpcy5jbHMuZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5Db250ZW50VHlwZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkge30sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICBcdHRoaXMubW9kZWwuY29udGVudFR5cGVJZCA9ICdjdCcgKyBNYXRoLnJhbmRvbSgpO1xuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5jb250ZW50X3R5cGUodGhpcy5tb2RlbCkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5IZWFkZXJWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBldmVudHM6IHtcbiAgICAnY2xpY2sgI3Nob3ctcGV0LXN0b3JlLWljb24nICAgIDogJ3Nob3dQZXRTdG9yZScsXG4gICAgJ2NsaWNrICNleHBsb3JlJyAgICAgICAgICAgICAgICA6ICdzaG93Q3VzdG9tJyxcbiAgICAnc3VibWl0ICNhcGlfc2VsZWN0b3InICAgICAgICAgIDogJ3Nob3dDdXN0b20nLFxuICAgICdrZXl1cCAjaW5wdXRfYmFzZVVybCcgICAgICAgICAgOiAnc2hvd0N1c3RvbU9uS2V5dXAnLFxuICAgICdrZXl1cCAjaW5wdXRfYXBpS2V5JyAgICAgICAgICAgOiAnc2hvd0N1c3RvbU9uS2V5dXAnXG4gIH0sXG5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXt9LFxuXG4gIHNob3dQZXRTdG9yZTogZnVuY3Rpb24oKXtcbiAgICB0aGlzLnRyaWdnZXIoJ3VwZGF0ZS1zd2FnZ2VyLXVpJywge1xuICAgICAgdXJsOidodHRwOi8vcGV0c3RvcmUuc3dhZ2dlci5pby92Mi9zd2FnZ2VyLmpzb24nXG4gICAgfSk7XG4gIH0sXG5cbiAgc2hvd0N1c3RvbU9uS2V5dXA6IGZ1bmN0aW9uKGUpe1xuICAgIGlmIChlLmtleUNvZGUgPT09IDEzKSB7XG4gICAgICB0aGlzLnNob3dDdXN0b20oKTtcbiAgICB9XG4gIH0sXG5cbiAgc2hvd0N1c3RvbTogZnVuY3Rpb24oZSl7XG4gICAgaWYgKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICB0aGlzLnRyaWdnZXIoJ3VwZGF0ZS1zd2FnZ2VyLXVpJywge1xuICAgICAgdXJsOiAkKCcjaW5wdXRfYmFzZVVybCcpLnZhbCgpXG4gICAgfSk7XG4gIH0sXG5cbiAgdXBkYXRlOiBmdW5jdGlvbih1cmwsIGFwaUtleSwgdHJpZ2dlcil7XG4gICAgaWYgKHRyaWdnZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdHJpZ2dlciA9IGZhbHNlO1xuICAgIH1cblxuICAgICQoJyNpbnB1dF9iYXNlVXJsJykudmFsKHVybCk7XG5cbiAgICBpZiAodHJpZ2dlcikge1xuICAgICAgdGhpcy50cmlnZ2VyKCd1cGRhdGUtc3dhZ2dlci11aScsIHt1cmw6dXJsfSk7XG4gICAgfVxuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLk1haW5WaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBhcGlzU29ydGVyIDoge1xuICAgIGFscGhhICAgOiBmdW5jdGlvbihhLGIpeyByZXR1cm4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKTsgfVxuICB9LFxuICBvcGVyYXRpb25zU29ydGVycyA6IHtcbiAgICBhbHBoYSAgIDogZnVuY3Rpb24oYSxiKXsgcmV0dXJuIGEucGF0aC5sb2NhbGVDb21wYXJlKGIucGF0aCk7IH0sXG4gICAgbWV0aG9kICA6IGZ1bmN0aW9uKGEsYil7IHJldHVybiBhLm1ldGhvZC5sb2NhbGVDb21wYXJlKGIubWV0aG9kKTsgfVxuICB9LFxuICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKXtcbiAgICB2YXIgc29ydGVyT3B0aW9uLCBzb3J0ZXJGbiwga2V5LCB2YWx1ZTtcbiAgICBvcHRzID0gb3B0cyB8fCB7fTtcblxuICAgIHRoaXMucm91dGVyID0gb3B0cy5yb3V0ZXI7XG5cbiAgICAvLyBTb3J0IEFQSXNcbiAgICBpZiAob3B0cy5zd2FnZ2VyT3B0aW9ucy5hcGlzU29ydGVyKSB7XG4gICAgICBzb3J0ZXJPcHRpb24gPSBvcHRzLnN3YWdnZXJPcHRpb25zLmFwaXNTb3J0ZXI7XG4gICAgICBpZiAoXy5pc0Z1bmN0aW9uKHNvcnRlck9wdGlvbikpIHtcbiAgICAgICAgc29ydGVyRm4gPSBzb3J0ZXJPcHRpb247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzb3J0ZXJGbiA9IHRoaXMuYXBpc1NvcnRlcltzb3J0ZXJPcHRpb25dO1xuICAgICAgfVxuICAgICAgaWYgKF8uaXNGdW5jdGlvbihzb3J0ZXJGbikpIHtcbiAgICAgICAgdGhpcy5tb2RlbC5hcGlzQXJyYXkuc29ydChzb3J0ZXJGbik7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFNvcnQgb3BlcmF0aW9ucyBvZiBlYWNoIEFQSVxuICAgIGlmIChvcHRzLnN3YWdnZXJPcHRpb25zLm9wZXJhdGlvbnNTb3J0ZXIpIHtcbiAgICAgIHNvcnRlck9wdGlvbiA9IG9wdHMuc3dhZ2dlck9wdGlvbnMub3BlcmF0aW9uc1NvcnRlcjtcbiAgICAgIGlmIChfLmlzRnVuY3Rpb24oc29ydGVyT3B0aW9uKSkge1xuICAgICAgICBzb3J0ZXJGbiA9IHNvcnRlck9wdGlvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNvcnRlckZuID0gdGhpcy5vcGVyYXRpb25zU29ydGVyc1tzb3J0ZXJPcHRpb25dO1xuICAgICAgfVxuICAgICAgaWYgKF8uaXNGdW5jdGlvbihzb3J0ZXJGbikpIHtcbiAgICAgICAgZm9yIChrZXkgaW4gdGhpcy5tb2RlbC5hcGlzQXJyYXkpIHtcbiAgICAgICAgICB0aGlzLm1vZGVsLmFwaXNBcnJheVtrZXldLm9wZXJhdGlvbnNBcnJheS5zb3J0KHNvcnRlckZuKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNldCB1cCB0aGUgVUkgZm9yIGlucHV0XG4gICAgdGhpcy5tb2RlbC5hdXRocyA9IFtdO1xuXG4gICAgZm9yIChrZXkgaW4gdGhpcy5tb2RlbC5zZWN1cml0eURlZmluaXRpb25zKSB7XG4gICAgICB2YWx1ZSA9IHRoaXMubW9kZWwuc2VjdXJpdHlEZWZpbml0aW9uc1trZXldO1xuXG4gICAgICB0aGlzLm1vZGVsLmF1dGhzLnB1c2goe1xuICAgICAgICBuYW1lOiBrZXksXG4gICAgICAgIHR5cGU6IHZhbHVlLnR5cGUsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCd2YWxpZGF0b3JVcmwnIGluIG9wdHMuc3dhZ2dlck9wdGlvbnMpIHtcbiAgICAgIC8vIFZhbGlkYXRvciBVUkwgc3BlY2lmaWVkIGV4cGxpY2l0bHlcbiAgICAgIHRoaXMubW9kZWwudmFsaWRhdG9yVXJsID0gb3B0cy5zd2FnZ2VyT3B0aW9ucy52YWxpZGF0b3JVcmw7XG4gICAgfSBlbHNlIGlmICh0aGlzLm1vZGVsLnVybC5pbmRleE9mKCdsb2NhbGhvc3QnKSA+IDAgfHwgdGhpcy5tb2RlbC51cmwuaW5kZXhPZignMTI3LjAuMC4xJykgPiAwKSB7XG4gICAgICAvLyBMb2NhbGhvc3Qgb3ZlcnJpZGVcbiAgICAgIHRoaXMubW9kZWwudmFsaWRhdG9yVXJsID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tb2RlbC52YWxpZGF0b3JVcmwgPSAnLy9vbmxpbmUuc3dhZ2dlci5pby92YWxpZGF0b3InO1xuICAgIH1cblxuICAgIC8vIEpTb25FZGl0b3IgcmVxdWlyZXMgdHlwZT0nb2JqZWN0JyB0byBiZSBwcmVzZW50IG9uIGRlZmluZWQgdHlwZXMsIHdlIGFkZCBpdCBpZiBpdCdzIG1pc3NpbmdcbiAgICAvLyBpcyB0aGVyZSBhbnkgdmFsaWQgY2FzZSB3ZXJlIGl0IHNob3VsZCBub3QgYmUgYWRkZWQgP1xuICAgIHZhciBkZWY7XG4gICAgZm9yKGRlZiBpbiB0aGlzLm1vZGVsLmRlZmluaXRpb25zKXtcbiAgICAgIGlmICghdGhpcy5tb2RlbC5kZWZpbml0aW9uc1tkZWZdLnR5cGUpe1xuICAgICAgICB0aGlzLm1vZGVsLmRlZmluaXRpb25zW2RlZl0udHlwZSA9ICdvYmplY3QnO1xuICAgICAgfVxuICAgIH1cblxuICB9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5tYWluKHRoaXMubW9kZWwpKTtcbiAgICB0aGlzLmluZm8gPSB0aGlzLiQoJy5pbmZvJylbMF07XG5cbiAgICBpZiAodGhpcy5pbmZvKSB7XG4gICAgICB0aGlzLmluZm8uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLm9uTGlua0NsaWNrLCB0cnVlKTtcbiAgICB9XG5cbiAgICB0aGlzLm1vZGVsLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSB0aGlzLm1vZGVsLnNlY3VyaXR5RGVmaW5pdGlvbnMgfHwge307XG5cbiAgICAvLyBSZW5kZXIgZWFjaCByZXNvdXJjZVxuXG4gICAgdmFyIHJlc291cmNlcyA9IHt9O1xuICAgIHZhciBjb3VudGVyID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubW9kZWwuYXBpc0FycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcmVzb3VyY2UgPSB0aGlzLm1vZGVsLmFwaXNBcnJheVtpXTtcbiAgICAgIHZhciBpZCA9IHJlc291cmNlLm5hbWU7XG4gICAgICB3aGlsZSAodHlwZW9mIHJlc291cmNlc1tpZF0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlkID0gaWQgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICBjb3VudGVyICs9IDE7XG4gICAgICB9XG4gICAgICByZXNvdXJjZS5pZCA9IHNhbml0aXplSHRtbChpZCk7XG4gICAgICByZXNvdXJjZXNbaWRdID0gcmVzb3VyY2U7XG4gICAgICB0aGlzLmFkZFJlc291cmNlKHJlc291cmNlLCB0aGlzLm1vZGVsLmF1dGhzKTtcbiAgICB9XG5cbiAgICAkKCcucHJvcFdyYXAnKS5ob3ZlcihmdW5jdGlvbiBvbkhvdmVyKCl7XG4gICAgICAkKCcub3B0aW9uc1dyYXBwZXInLCAkKHRoaXMpKS5zaG93KCk7XG4gICAgfSwgZnVuY3Rpb24gb2ZmaG92ZXIoKXtcbiAgICAgICQoJy5vcHRpb25zV3JhcHBlcicsICQodGhpcykpLmhpZGUoKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBhZGRSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UsIGF1dGhzKXtcbiAgICAvLyBSZW5kZXIgYSByZXNvdXJjZSBhbmQgYWRkIGl0IHRvIHJlc291cmNlcyBsaVxuICAgIHJlc291cmNlLmlkID0gcmVzb3VyY2UuaWQucmVwbGFjZSgvW15hLXpBLVpcXGRdL2csIGZ1bmN0aW9uKHN0cikgeyByZXR1cm4gc3RyLmNoYXJDb2RlQXQoMCk7IH0pO1xuXG4gICAgLy8gTWFrZSBhbGwgZGVmaW5pdGlvbnMgYXZhaWxhYmxlIGF0IHRoZSByb290IG9mIHRoZSByZXNvdXJjZSBzbyB0aGF0IHRoZXkgY2FuXG4gICAgLy8gYmUgbG9hZGVkIGJ5IHRoZSBKU29uRWRpdG9yXG4gICAgcmVzb3VyY2UuZGVmaW5pdGlvbnMgPSB0aGlzLm1vZGVsLmRlZmluaXRpb25zO1xuXG4gICAgdmFyIHJlc291cmNlVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuUmVzb3VyY2VWaWV3KHtcbiAgICAgIG1vZGVsOiByZXNvdXJjZSxcbiAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXIsXG4gICAgICB0YWdOYW1lOiAnbGknLFxuICAgICAgaWQ6ICdyZXNvdXJjZV8nICsgcmVzb3VyY2UuaWQsXG4gICAgICBjbGFzc05hbWU6ICdyZXNvdXJjZScsXG4gICAgICBhdXRoczogYXV0aHMsXG4gICAgICBzd2FnZ2VyT3B0aW9uczogdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zXG4gICAgfSk7XG4gICAgJCgnI3Jlc291cmNlcycsIHRoaXMuZWwpLmFwcGVuZChyZXNvdXJjZVZpZXcucmVuZGVyKCkuZWwpO1xuICB9LFxuXG4gIGNsZWFyOiBmdW5jdGlvbigpe1xuICAgICQodGhpcy5lbCkuaHRtbCgnJyk7XG4gIH0sXG5cbiAgb25MaW5rQ2xpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIGVsID0gZS50YXJnZXQ7XG5cbiAgICBpZiAoZWwudGFnTmFtZSA9PT0gJ0EnICYmIGVsLmhyZWYgJiYgIWVsLnRhcmdldCkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHdpbmRvdy5vcGVuKGVsLmhyZWYsICdfYmxhbmsnKTtcbiAgICB9XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuTW9kZWxzLk9hdXRoMk1vZGVsID0gQmFja2JvbmUuTW9kZWwuZXh0ZW5kKHtcbiAgICBkZWZhdWx0czoge1xuICAgICAgICBzY29wZXM6IHt9LFxuICAgICAgICBpc1Bhc3N3b3JkRmxvdzogZmFsc2UsXG4gICAgICAgIGNsaWVudEF1dGhlbnRpY2F0aW9uVHlwZTogJ25vbmUnXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYodGhpcy5hdHRyaWJ1dGVzICYmIHRoaXMuYXR0cmlidXRlcy5zY29wZXMpIHtcbiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0gXy5jbG9uZURlZXAodGhpcy5hdHRyaWJ1dGVzKTtcbiAgICAgICAgICAgIHZhciBpLCBzY29wZXMgPSBbXTtcbiAgICAgICAgICAgIGZvcihpIGluIGF0dHJpYnV0ZXMuc2NvcGVzKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNjb3BlID0gYXR0cmlidXRlcy5zY29wZXNbaV07XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIHNjb3BlLmRlc2NyaXB0aW9uID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBzY29wZXNbc2NvcGVdID0gYXR0cmlidXRlcy5zY29wZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIHNjb3Blcy5wdXNoKGF0dHJpYnV0ZXMuc2NvcGVzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhdHRyaWJ1dGVzLnNjb3BlcyA9IHNjb3BlcztcbiAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hdHRyaWJ1dGVzICYmIHRoaXMuYXR0cmlidXRlcy5mbG93KSB7XG4gICAgICAgICAgICB2YXIgZmxvdyA9IHRoaXMuYXR0cmlidXRlcy5mbG93O1xuICAgICAgICAgICAgdGhpcy5zZXQoJ2lzUGFzc3dvcmRGbG93JywgZmxvdyA9PT0gJ3Bhc3N3b3JkJyk7XG4gICAgICAgICAgICB0aGlzLnNldCgncmVxdWlyZUNsaWVudEF1dGhlbnRpY2F0aW9uJywgZmxvdyA9PT0gJ2FwcGxpY2F0aW9uJyk7XG4gICAgICAgICAgICB0aGlzLnNldCgnY2xpZW50QXV0aGVudGljYXRpb24nLCBmbG93ID09PSAncGFzc3dvcmQnIHx8IGZsb3cgPT09ICdhcHBsaWNhdGlvbicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub24oJ2NoYW5nZScsIHRoaXMudmFsaWRhdGUpO1xuICAgIH0sXG5cbiAgICBzZXRTY29wZXM6IGZ1bmN0aW9uIChuYW1lLCB2YWwpIHtcbiAgICAgICAgdmFyIGF1dGggPSBfLmV4dGVuZCh7fSwgdGhpcy5hdHRyaWJ1dGVzKTtcbiAgICAgICAgdmFyIGluZGV4ID0gXy5maW5kSW5kZXgoYXV0aC5zY29wZXMsIGZ1bmN0aW9uKG8pIHtcbiAgICAgICAgICAgIHJldHVybiBvLnNjb3BlID09PSBuYW1lO1xuICAgICAgICB9KTtcbiAgICAgICAgYXV0aC5zY29wZXNbaW5kZXhdLmNoZWNrZWQgPSB2YWw7XG5cbiAgICAgICAgdGhpcy5zZXQoYXV0aCk7XG4gICAgICAgIHRoaXMudmFsaWRhdGUoKTtcbiAgICB9LFxuXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB2YWxpZCA9IGZhbHNlO1xuICAgICAgaWYgKHRoaXMuZ2V0KCdpc1Bhc3N3b3JkRmxvdycpICYmXG4gICAgICAgICAgKCF0aGlzLmdldCgndXNlcm5hbWUnKSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmdldCgnY2xpZW50QXV0aGVudGljYXRpb25UeXBlJykgaW4gWydiYXNpYycsICdyZXF1ZXN0LWJvZHknXSAmJlxuICAgICAgICAgICghdGhpcy5nZXQoJ2NsaWVudElkJykpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2NwID0gdGhpcy5nZXQoJ3Njb3BlcycpO1xuICAgICAgdmFyIGlkeCA9ICBfLmZpbmRJbmRleChzY3AsIGZ1bmN0aW9uIChvKSB7XG4gICAgICAgICByZXR1cm4gby5jaGVja2VkID09PSB0cnVlO1xuICAgICAgfSk7XG5cbiAgICAgIGlmKHNjcC5sZW5ndGggPiAwICYmIGlkeCA+PSAwKSB7XG4gICAgICAgICAgdmFsaWQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZihzY3AubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdmFsaWQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNldCgndmFsaWQnLCB2YWxpZCk7XG5cbiAgICAgIHJldHVybiB2YWxpZDtcbiAgICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLk9hdXRoMlZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gICAgZXZlbnRzOiB7XG4gICAgICAgICdjaGFuZ2UgLm9hdXRoLXNjb3BlJzogJ3Njb3BlQ2hhbmdlJyxcbiAgICAgICAgJ2NoYW5nZSAub2F1dGgtdXNlcm5hbWUnOiAnc2V0VXNlcm5hbWUnLFxuICAgICAgICAnY2hhbmdlIC5vYXV0aC1wYXNzd29yZCc6ICdzZXRQYXNzd29yZCcsXG4gICAgICAgICdjaGFuZ2UgLm9hdXRoLWNsaWVudC1hdXRoZW50aWNhdGlvbi10eXBlJzogJ3NldENsaWVudEF1dGhlbnRpY2F0aW9uVHlwZScsXG4gICAgICAgICdjaGFuZ2UgLm9hdXRoLWNsaWVudC1pZCc6ICdzZXRDbGllbnRJZCcsXG4gICAgICAgICdjaGFuZ2UgLm9hdXRoLWNsaWVudC1zZWNyZXQnOiAnc2V0Q2xpZW50U2VjcmV0J1xuICAgIH0sXG5cbiAgICB0ZW1wbGF0ZTogSGFuZGxlYmFycy50ZW1wbGF0ZXMub2F1dGgyLFxuXG4gICAgY2xzOiB7XG4gICAgICAgIGVycm9yOiAnZXJyb3InXG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudGVtcGxhdGUodGhpcy5tb2RlbC50b0pTT04oKSkpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBzY29wZUNoYW5nZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIHZhbCA9ICQoZS50YXJnZXQpLnByb3AoJ2NoZWNrZWQnKTtcbiAgICAgICAgdmFyIHNjb3BlID0gJChlLnRhcmdldCkuZGF0YSgnc2NvcGUnKTtcblxuICAgICAgICB0aGlzLm1vZGVsLnNldFNjb3BlcyhzY29wZSwgdmFsKTtcbiAgICB9LFxuXG4gICAgc2V0VXNlcm5hbWU6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciB2YWw9ICQoZS50YXJnZXQpLnZhbCgpO1xuICAgICAgICB0aGlzLm1vZGVsLnNldCgndXNlcm5hbWUnLCB2YWwpO1xuICAgICAgICBpZiAodmFsKSB7XG4gICAgICAgICAgICAkKGUudGFyZ2V0KS5yZW1vdmVDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc2V0UGFzc3dvcmQ6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHRoaXMubW9kZWwuc2V0KCdwYXNzd29yZCcsICQoZS50YXJnZXQpLnZhbCgpKTtcbiAgICB9LFxuXG4gICAgc2V0Q2xpZW50QXV0aGVudGljYXRpb25UeXBlOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgdHlwZSA9ICQoZS50YXJnZXQpLnZhbCgpO1xuICAgICAgICB2YXIgJGVsID0gdGhpcy4kZWw7XG4gICAgICAgIHRoaXMubW9kZWwuc2V0KCdjbGllbnRBdXRoZW50aWNhdGlvblR5cGUnLCB0eXBlKTtcblxuICAgICAgICBzd2l0Y2godHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnbm9uZSc6XG4gICAgICAgICAgICAgICAgJGVsLmZpbmQoJy5vYXV0aC1jbGllbnQtYXV0aGVudGljYXRpb24nKS5oaWRlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdiYXNpYyc6XG4gICAgICAgICAgICBjYXNlICdyZXF1ZXN0LWJvZHknOlxuICAgICAgICAgICAgICAgICRlbC5maW5kKCcub2F1dGgtY2xpZW50LWlkJykucmVtb3ZlQ2xhc3ModGhpcy5jbHMuZXJyb3IpO1xuICAgICAgICAgICAgICAgICRlbC5maW5kKCcub2F1dGgtY2xpZW50LWF1dGhlbnRpY2F0aW9uJykuc2hvdygpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHNldENsaWVudElkOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgdmFsID0gJChlLnRhcmdldCkudmFsKCk7XG4gICAgICAgIHRoaXMubW9kZWwuc2V0KCdjbGllbnRJZCcsIHZhbCk7XG4gICAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgICAgICQoZS50YXJnZXQpLnJlbW92ZUNsYXNzKHRoaXMuY2xzLmVycm9yKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBzZXRDbGllbnRTZWNyZXQ6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHRoaXMubW9kZWwuc2V0KCdjbGllbnRTZWNyZXQnLCAkKGUudGFyZ2V0KS52YWwoKSk7XG4gICAgICAgICQoZS50YXJnZXQpLnJlbW92ZUNsYXNzKCdlcnJvcicpO1xuICAgIH0sXG5cbiAgICBoaWdobGlnaHRJbnZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5tb2RlbC5nZXQoJ3VzZXJuYW1lJykpIHtcbiAgICAgICAgICAgIHRoaXMuJGVsLmZpbmQoJy5vYXV0aC11c2VybmFtZScpLmFkZENsYXNzKHRoaXMuY2xzLmVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5tb2RlbC5nZXQoJ2NsaWVudElkJykpIHtcbiAgICAgICAgICAgIHRoaXMuJGVsLmZpbmQoJy5vYXV0aC1jbGllbnQtaWQnKS5hZGRDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5PcGVyYXRpb25WaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbnZvY2F0aW9uVXJsOiBudWxsLFxuXG4gIGV2ZW50czoge1xuICAgICdzdWJtaXQgLnNhbmRib3gnICAgICAgICAgOiAnc3VibWl0T3BlcmF0aW9uJyxcbiAgICAnY2xpY2sgLnN1Ym1pdCcgICAgICAgICAgIDogJ3N1Ym1pdE9wZXJhdGlvbicsXG4gICAgJ2NsaWNrIC5yZXNwb25zZV9oaWRlcicgICA6ICdoaWRlUmVzcG9uc2UnLFxuICAgICdjbGljayAudG9nZ2xlT3BlcmF0aW9uJyAgOiAndG9nZ2xlT3BlcmF0aW9uQ29udGVudCcsXG4gICAgJ21vdXNlZW50ZXIgLmFwaS1pYycgICAgICA6ICdtb3VzZUVudGVyJyxcbiAgICAnZGJsY2xpY2sgLmN1cmwnICAgICAgICAgIDogJ3NlbGVjdFRleHQnLFxuICAgICdjaGFuZ2UgW25hbWU9cmVzcG9uc2VDb250ZW50VHlwZV0nIDogJ3Nob3dTbmlwcGV0J1xuICB9LFxuXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgICB0aGlzLnJvdXRlciA9IG9wdHMucm91dGVyO1xuICAgIHRoaXMuYXV0aHMgPSBvcHRzLmF1dGhzO1xuICAgIHRoaXMucGFyZW50SWQgPSB0aGlzLm1vZGVsLnBhcmVudElkO1xuICAgIHRoaXMubmlja25hbWUgPSB0aGlzLm1vZGVsLm5pY2tuYW1lO1xuICAgIHRoaXMubW9kZWwuZW5jb2RlZFBhcmVudElkID0gZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMucGFyZW50SWQpO1xuXG4gICAgaWYgKG9wdHMuc3dhZ2dlck9wdGlvbnMpIHtcbiAgICAgIHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZyA9IG9wdHMuc3dhZ2dlck9wdGlvbnMuZGVmYXVsdE1vZGVsUmVuZGVyaW5nO1xuXG4gICAgICBpZiAob3B0cy5zd2FnZ2VyT3B0aW9ucy5zaG93UmVxdWVzdEhlYWRlcnMpIHtcbiAgICAgICAgdGhpcy5tb2RlbC5zaG93UmVxdWVzdEhlYWRlcnMgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0cy5zd2FnZ2VyT3B0aW9ucy5zaG93T3BlcmF0aW9uSWRzKSB7XG4gICAgICAgIHRoaXMubW9kZWwuc2hvd09wZXJhdGlvbklkcyA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIHNlbGVjdFRleHQ6IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGRvYyA9IGRvY3VtZW50LFxuICAgICAgICB0ZXh0ID0gZXZlbnQudGFyZ2V0LmZpcnN0Q2hpbGQsXG4gICAgICAgIHJhbmdlLFxuICAgICAgICBzZWxlY3Rpb247XG4gICAgaWYgKGRvYy5ib2R5LmNyZWF0ZVRleHRSYW5nZSkge1xuICAgICAgcmFuZ2UgPSBkb2N1bWVudC5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpO1xuICAgICAgcmFuZ2UubW92ZVRvRWxlbWVudFRleHQodGV4dCk7XG4gICAgICByYW5nZS5zZWxlY3QoKTtcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5nZXRTZWxlY3Rpb24pIHtcbiAgICAgIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICAgIHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgIHJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyh0ZXh0KTtcbiAgICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgIHNlbGVjdGlvbi5hZGRSYW5nZShyYW5nZSk7XG4gICAgfVxuICB9LFxuXG4gIG1vdXNlRW50ZXI6IGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZWxlbSA9ICQodGhpcy5lbCkuZmluZCgnLmNvbnRlbnQnKTtcbiAgICB2YXIgeCA9IGUucGFnZVg7XG4gICAgdmFyIHkgPSBlLnBhZ2VZO1xuICAgIHZhciBzY1ggPSAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpO1xuICAgIHZhciBzY1kgPSAkKHdpbmRvdykuc2Nyb2xsVG9wKCk7XG4gICAgdmFyIHNjTWF4WCA9IHNjWCArICQod2luZG93KS53aWR0aCgpO1xuICAgIHZhciBzY01heFkgPSBzY1kgKyAkKHdpbmRvdykuaGVpZ2h0KCk7XG4gICAgdmFyIHdkID0gZWxlbS53aWR0aCgpO1xuICAgIHZhciBoZ2ggPSBlbGVtLmhlaWdodCgpO1xuXG4gICAgaWYgKHggKyB3ZCA+IHNjTWF4WCkge1xuICAgICAgeCA9IHNjTWF4WCAtIHdkO1xuICAgIH1cblxuICAgIGlmICh4IDwgc2NYKSB7XG4gICAgICB4ID0gc2NYO1xuICAgIH1cblxuICAgIGlmICh5ICsgaGdoID4gc2NNYXhZKSB7XG4gICAgICB5ID0gc2NNYXhZIC0gaGdoO1xuICAgIH1cblxuICAgIGlmICh5IDwgc2NZKSB7XG4gICAgICB5ID0gc2NZO1xuICAgIH1cblxuICAgIHZhciBwb3MgPSB7fTtcbiAgICBwb3MudG9wID0geTtcbiAgICBwb3MubGVmdCA9IHg7XG4gICAgZWxlbS5jc3MocG9zKTtcbiAgfSxcblxuICAvLyBOb3RlOiBjb3BpZWQgZnJvbSBDb2ZmZWVTY3JpcHQgY29tcGlsZWQgZmlsZVxuICAvLyBUT0RPOiByZWZhY3RvclxuICByZW5kZXI6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhLCBhdXRoLCBhdXRocywgY29kZSwgY29udGVudFR5cGVNb2RlbCwgaXNNZXRob2RTdWJtaXNzaW9uU3VwcG9ydGVkLCBrLCBrZXksIGwsIGxlbiwgbGVuMSwgbGVuMiwgbGVuMywgbGVuNCwgbSwgbW9kZWxBdXRocywgbiwgbywgcCwgcGFyYW0sIHEsIHJlZiwgcmVmMSwgcmVmMiwgcmVmMywgcmVmNCwgcmVmNSwgcmVzcG9uc2VDb250ZW50VHlwZVZpZXcsIHJlc3BvbnNlU2lnbmF0dXJlVmlldywgc2NoZW1hLCBzY2hlbWFPYmosIHNjb3BlSW5kZXgsIHNpZ25hdHVyZU1vZGVsLCBzdGF0dXNDb2RlLCBzdWNjZXNzUmVzcG9uc2UsIHR5cGUsIHYsIHZhbHVlLCBwcm9kdWNlcywgaXNYTUwsIGlzSlNPTjtcbiAgICBpc01ldGhvZFN1Ym1pc3Npb25TdXBwb3J0ZWQgPSBqUXVlcnkuaW5BcnJheSh0aGlzLm1vZGVsLm1ldGhvZCwgdGhpcy5tb2RlbC5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzKCkpID49IDA7XG4gICAgaWYgKCFpc01ldGhvZFN1Ym1pc3Npb25TdXBwb3J0ZWQpIHtcbiAgICAgIHRoaXMubW9kZWwuaXNSZWFkT25seSA9IHRydWU7XG4gICAgfVxuICAgIHRoaXMubW9kZWwuZGVzY3JpcHRpb24gPSB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uIHx8IHRoaXMubW9kZWwubm90ZXM7XG4gICAgdGhpcy5tb2RlbC5vYXV0aCA9IG51bGw7XG4gICAgbW9kZWxBdXRocyA9IHRoaXMubW9kZWwuYXV0aG9yaXphdGlvbnMgfHwgdGhpcy5tb2RlbC5zZWN1cml0eTtcbiAgICBpZiAobW9kZWxBdXRocykge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkobW9kZWxBdXRocykpIHtcbiAgICAgICAgZm9yIChsID0gMCwgbGVuID0gbW9kZWxBdXRocy5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgICAgIGF1dGhzID0gbW9kZWxBdXRoc1tsXTtcbiAgICAgICAgICBmb3IgKGtleSBpbiBhdXRocykge1xuICAgICAgICAgICAgZm9yIChhIGluIHRoaXMuYXV0aHMpIHtcbiAgICAgICAgICAgICAgYXV0aCA9IHRoaXMuYXV0aHNbYV07XG4gICAgICAgICAgICAgIGlmIChrZXkgPT09IGF1dGgubmFtZSkge1xuICAgICAgICAgICAgICAgIGlmIChhdXRoLnR5cGUgPT09ICdvYXV0aDInKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoID0ge307XG4gICAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoLnNjb3BlcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgcmVmMSA9IGF1dGgudmFsdWUuc2NvcGVzO1xuICAgICAgICAgICAgICAgICAgZm9yIChrIGluIHJlZjEpIHtcbiAgICAgICAgICAgICAgICAgICAgdiA9IHJlZjFba107XG4gICAgICAgICAgICAgICAgICAgIHNjb3BlSW5kZXggPSBhdXRoc1trZXldLmluZGV4T2Yoayk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzY29wZUluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICBvID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NvcGU6IGssXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogdlxuICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vYXV0aC5zY29wZXMucHVzaChvKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChrIGluIG1vZGVsQXV0aHMpIHtcbiAgICAgICAgICB2ID0gbW9kZWxBdXRoc1trXTtcbiAgICAgICAgICBpZiAoayA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsLm9hdXRoID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIHRoaXMubW9kZWwub2F1dGggPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsLm9hdXRoLnNjb3BlcyA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgIHRoaXMubW9kZWwub2F1dGguc2NvcGVzID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKG0gPSAwLCBsZW4xID0gdi5sZW5ndGg7IG0gPCBsZW4xOyBtKyspIHtcbiAgICAgICAgICAgICAgbyA9IHZbbV07XG4gICAgICAgICAgICAgIHRoaXMubW9kZWwub2F1dGguc2NvcGVzLnB1c2gobyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcy5tb2RlbC5yZXNwb25zZXMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLm1vZGVsLnJlc3BvbnNlTWVzc2FnZXMgPSBbXTtcbiAgICAgIHJlZjIgPSB0aGlzLm1vZGVsLnJlc3BvbnNlcztcbiAgICAgIGZvciAoY29kZSBpbiByZWYyKSB7XG4gICAgICAgIHZhbHVlID0gcmVmMltjb2RlXTtcbiAgICAgICAgc2NoZW1hID0gbnVsbDtcbiAgICAgICAgc2NoZW1hT2JqID0gdGhpcy5tb2RlbC5yZXNwb25zZXNbY29kZV0uc2NoZW1hO1xuICAgICAgICBpZiAoc2NoZW1hT2JqICYmIHNjaGVtYU9iai4kcmVmKSB7XG4gICAgICAgICAgc2NoZW1hID0gc2NoZW1hT2JqLiRyZWY7XG4gICAgICAgICAgaWYgKHNjaGVtYS5pbmRleE9mKCcjL2RlZmluaXRpb25zLycpICE9PSAtMSkge1xuICAgICAgICAgICAgc2NoZW1hID0gc2NoZW1hLnJlcGxhY2UoL14uKiNcXC9kZWZpbml0aW9uc1xcLy8sICcnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzLnB1c2goe1xuICAgICAgICAgIGNvZGU6IGNvZGUsXG4gICAgICAgICAgbWVzc2FnZTogdmFsdWUuZGVzY3JpcHRpb24sXG4gICAgICAgICAgcmVzcG9uc2VNb2RlbDogc2NoZW1hLFxuICAgICAgICAgIGhlYWRlcnM6IHZhbHVlLmhlYWRlcnMsXG4gICAgICAgICAgc2NoZW1hOiBzY2hlbWFPYmpcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzID0gW107XG4gICAgfVxuICAgIHNpZ25hdHVyZU1vZGVsID0gbnVsbDtcbiAgICBwcm9kdWNlcyA9IHRoaXMubW9kZWwucHJvZHVjZXM7XG4gICAgaXNYTUwgPSB0aGlzLmNvbnRhaW5zKHByb2R1Y2VzLCAneG1sJyk7XG4gICAgaXNKU09OID0gaXNYTUwgPyB0aGlzLmNvbnRhaW5zKHByb2R1Y2VzLCAnanNvbicpIDogdHJ1ZTtcblxuICAgIGlmICh0aGlzLm1vZGVsLnN1Y2Nlc3NSZXNwb25zZSkge1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5tb2RlbC5zdWNjZXNzUmVzcG9uc2U7XG4gICAgICBmb3IgKGtleSBpbiBzdWNjZXNzUmVzcG9uc2UpIHtcbiAgICAgICAgdmFsdWUgPSBzdWNjZXNzUmVzcG9uc2Vba2V5XTtcbiAgICAgICAgdGhpcy5tb2RlbC5zdWNjZXNzQ29kZSA9IGtleTtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbHVlLmNyZWF0ZUpTT05TYW1wbGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB0aGlzLm1vZGVsLnN1Y2Nlc3NEZXNjcmlwdGlvbiA9IHZhbHVlLmRlc2NyaXB0aW9uO1xuICAgICAgICAgIHRoaXMubW9kZWwuaGVhZGVycyA9IHRoaXMucGFyc2VSZXNwb25zZUhlYWRlcnModmFsdWUuaGVhZGVycyk7XG4gICAgICAgICAgc2lnbmF0dXJlTW9kZWwgPSB7XG4gICAgICAgICAgICBzYW1wbGVKU09OOiBpc0pTT04gPyBKU09OLnN0cmluZ2lmeShTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmNyZWF0ZUpTT05TYW1wbGUodmFsdWUpLCB2b2lkIDAsIDIpIDogZmFsc2UsXG4gICAgICAgICAgICBpc1BhcmFtOiBmYWxzZSxcbiAgICAgICAgICAgIHNhbXBsZVhNTDogaXNYTUwgPyBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmNyZWF0ZVhNTFNhbXBsZSh2YWx1ZS5uYW1lLCB2YWx1ZS5kZWZpbml0aW9uLCB2YWx1ZS5tb2RlbHMpIDogZmFsc2UsXG4gICAgICAgICAgICBzaWduYXR1cmU6IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuZ2V0TW9kZWxTaWduYXR1cmUodmFsdWUubmFtZSwgdmFsdWUuZGVmaW5pdGlvbiwgdmFsdWUubW9kZWxzLCB2YWx1ZS5tb2RlbFByb3BlcnR5TWFjcm8pXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzaWduYXR1cmVNb2RlbCA9IHtcbiAgICAgICAgICAgIHNpZ25hdHVyZTogU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5nZXRQcmltaXRpdmVTaWduYXR1cmUodmFsdWUpXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlbC5yZXNwb25zZUNsYXNzU2lnbmF0dXJlICYmIHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHNpZ25hdHVyZU1vZGVsID0ge1xuICAgICAgICBzYW1wbGVKU09OOiB0aGlzLm1vZGVsLnJlc3BvbnNlU2FtcGxlSlNPTixcbiAgICAgICAgaXNQYXJhbTogZmFsc2UsXG4gICAgICAgIHNpZ25hdHVyZTogdGhpcy5tb2RlbC5yZXNwb25zZUNsYXNzU2lnbmF0dXJlXG4gICAgICB9O1xuICAgIH1cbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMub3BlcmF0aW9uKHRoaXMubW9kZWwpKTtcbiAgICBpZiAoc2lnbmF0dXJlTW9kZWwpIHtcbiAgICAgIHNpZ25hdHVyZU1vZGVsLmRlZmF1bHRSZW5kZXJpbmcgPSB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmc7XG4gICAgICByZXNwb25zZVNpZ25hdHVyZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlNpZ25hdHVyZVZpZXcoe1xuICAgICAgICBtb2RlbDogc2lnbmF0dXJlTW9kZWwsXG4gICAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXIsXG4gICAgICAgIHRhZ05hbWU6ICdkaXYnXG4gICAgICB9KTtcbiAgICAgICQoJy5tb2RlbC1zaWduYXR1cmUnLCAkKHRoaXMuZWwpKS5hcHBlbmQocmVzcG9uc2VTaWduYXR1cmVWaWV3LnJlbmRlcigpLmVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tb2RlbC5yZXNwb25zZUNsYXNzU2lnbmF0dXJlID0gJ3N0cmluZyc7XG4gICAgICAkKCcubW9kZWwtc2lnbmF0dXJlJywgJCh0aGlzLmVsKSkuaHRtbCh0aGlzLm1vZGVsLnR5cGUpO1xuICAgIH1cbiAgICBjb250ZW50VHlwZU1vZGVsID0ge1xuICAgICAgaXNQYXJhbTogZmFsc2VcbiAgICB9O1xuICAgIGNvbnRlbnRUeXBlTW9kZWwuY29uc3VtZXMgPSB0aGlzLm1vZGVsLmNvbnN1bWVzO1xuICAgIGNvbnRlbnRUeXBlTW9kZWwucHJvZHVjZXMgPSB0aGlzLm1vZGVsLnByb2R1Y2VzO1xuICAgIHJlZjMgPSB0aGlzLm1vZGVsLnBhcmFtZXRlcnM7XG4gICAgZm9yIChuID0gMCwgbGVuMiA9IHJlZjMubGVuZ3RoOyBuIDwgbGVuMjsgbisrKSB7XG4gICAgICBwYXJhbSA9IHJlZjNbbl07XG4gICAgICB0eXBlID0gcGFyYW0udHlwZSB8fCBwYXJhbS5kYXRhVHlwZSB8fCAnJztcbiAgICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2NoZW1hID0gcGFyYW0uc2NoZW1hO1xuICAgICAgICBpZiAoc2NoZW1hICYmIHNjaGVtYS4kcmVmKSB7XG4gICAgICAgICAgcmVmID0gc2NoZW1hLiRyZWY7XG4gICAgICAgICAgaWYgKHJlZi5pbmRleE9mKCcjL2RlZmluaXRpb25zLycpID09PSAwKSB7XG4gICAgICAgICAgICB0eXBlID0gcmVmLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHR5cGUgPSByZWY7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodHlwZSAmJiB0eXBlLnRvTG93ZXJDYXNlKCkgPT09ICdmaWxlJykge1xuICAgICAgICBpZiAoIWNvbnRlbnRUeXBlTW9kZWwuY29uc3VtZXMpIHtcbiAgICAgICAgICBjb250ZW50VHlwZU1vZGVsLmNvbnN1bWVzID0gJ211bHRpcGFydC9mb3JtLWRhdGEnO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBwYXJhbS50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgcmVzcG9uc2VDb250ZW50VHlwZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlJlc3BvbnNlQ29udGVudFR5cGVWaWV3KHtcbiAgICAgIG1vZGVsOiBjb250ZW50VHlwZU1vZGVsLFxuICAgICAgcm91dGVyOiB0aGlzLnJvdXRlclxuICAgIH0pO1xuICAgICQoJy5yZXNwb25zZS1jb250ZW50LXR5cGUnLCAkKHRoaXMuZWwpKS5hcHBlbmQocmVzcG9uc2VDb250ZW50VHlwZVZpZXcucmVuZGVyKCkuZWwpO1xuICAgIHJlZjQgPSB0aGlzLm1vZGVsLnBhcmFtZXRlcnM7XG4gICAgZm9yIChwID0gMCwgbGVuMyA9IHJlZjQubGVuZ3RoOyBwIDwgbGVuMzsgcCsrKSB7XG4gICAgICBwYXJhbSA9IHJlZjRbcF07XG4gICAgICB0aGlzLmFkZFBhcmFtZXRlcihwYXJhbSwgY29udGVudFR5cGVNb2RlbC5jb25zdW1lcyk7XG4gICAgfVxuICAgIHJlZjUgPSB0aGlzLm1vZGVsLnJlc3BvbnNlTWVzc2FnZXM7XG4gICAgZm9yIChxID0gMCwgbGVuNCA9IHJlZjUubGVuZ3RoOyBxIDwgbGVuNDsgcSsrKSB7XG4gICAgICBzdGF0dXNDb2RlID0gcmVmNVtxXTtcbiAgICAgIHN0YXR1c0NvZGUuaXNYTUwgPSBpc1hNTDtcbiAgICAgIHN0YXR1c0NvZGUuaXNKU09OID0gaXNKU09OO1xuICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHN0YXR1c0NvZGUuaGVhZGVycykpIHtcbiAgICAgICAgc3RhdHVzQ29kZS5oZWFkZXJzID0gdGhpcy5wYXJzZUhlYWRlcnNUeXBlKHN0YXR1c0NvZGUuaGVhZGVycyk7XG4gICAgICB9XG4gICAgICB0aGlzLmFkZFN0YXR1c0NvZGUoc3RhdHVzQ29kZSk7XG4gICAgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5tb2RlbC5zZWN1cml0eSkpIHtcbiAgICAgIHZhciBhdXRoc01vZGVsID0gU3dhZ2dlclVpLnV0aWxzLnBhcnNlU2VjdXJpdHlEZWZpbml0aW9ucyh0aGlzLm1vZGVsLnNlY3VyaXR5LCB0aGlzLm1vZGVsLnBhcmVudC5zZWN1cml0eURlZmluaXRpb25zKTtcblxuICAgICAgYXV0aHNNb2RlbC5pc0xvZ291dCA9ICFfLmlzRW1wdHkodGhpcy5tb2RlbC5jbGllbnRBdXRob3JpemF0aW9ucy5hdXRoeik7XG4gICAgICB0aGlzLmF1dGhWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5BdXRoQnV0dG9uVmlldyh7XG4gICAgICAgIGRhdGE6IGF1dGhzTW9kZWwsXG4gICAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXIsXG4gICAgICAgIGlzT3BlcmF0aW9uOiB0cnVlLFxuICAgICAgICBtb2RlbDoge1xuICAgICAgICAgIHNjb3BlczogYXV0aHNNb2RlbC5zY29wZXNcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLiQoJy5hdXRob3JpemUtd3JhcHBlcicpLmFwcGVuZCh0aGlzLmF1dGhWaWV3LnJlbmRlcigpLmVsKTtcbiAgICB9XG5cbiAgICB0aGlzLnNob3dTbmlwcGV0KCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgcGFyc2VIZWFkZXJzVHlwZTogZnVuY3Rpb24gKGhlYWRlcnMpIHtcbiAgICB2YXIgbWFwID0ge1xuICAgICAgJ3N0cmluZyc6IHtcbiAgICAgICAgJ2RhdGUtdGltZSc6ICdkYXRlVGltZScsXG4gICAgICAgICdkYXRlJyAgICAgOiAnZGF0ZSdcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgXy5mb3JFYWNoKGhlYWRlcnMsIGZ1bmN0aW9uIChoZWFkZXIpIHtcbiAgICAgIHZhciB2YWx1ZTtcbiAgICAgIGhlYWRlciA9IGhlYWRlciB8fCB7fTtcbiAgICAgIHZhbHVlID0gbWFwW2hlYWRlci50eXBlXSAmJiBtYXBbaGVhZGVyLnR5cGVdW2hlYWRlci5mb3JtYXRdO1xuICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgICAgICBoZWFkZXIudHlwZSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGhlYWRlcnM7XG4gIH0sXG5cbiAgY29udGFpbnM6IGZ1bmN0aW9uIChwcm9kdWNlcywgdHlwZSkge1xuICAgIHJldHVybiBwcm9kdWNlcy5maWx0ZXIoZnVuY3Rpb24gKHZhbCkge1xuICAgICAgaWYgKHZhbC5pbmRleE9mKHR5cGUpID4gLTEpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSkubGVuZ3RoO1xuICB9LFxuXG4gIHBhcnNlUmVzcG9uc2VIZWFkZXJzOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgIHZhciBIRUFERVJTX1NFUEFSQVRPUiA9ICc7ICc7XG4gICAgdmFyIGhlYWRlcnMgPSBfLmNsb25lKGRhdGEpO1xuXG4gICAgXy5mb3JFYWNoKGhlYWRlcnMsIGZ1bmN0aW9uIChoZWFkZXIpIHtcbiAgICAgIHZhciBvdGhlciA9IFtdO1xuICAgICAgXy5mb3JFYWNoKGhlYWRlciwgZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgdmFyIHByb3BlcnRpZXMgPSBbJ3R5cGUnLCAnZGVzY3JpcHRpb24nXTtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuaW5kZXhPZihrZXkudG9Mb3dlckNhc2UoKSkgPT09IC0xKSB7XG4gICAgICAgICAgb3RoZXIucHVzaChrZXkgKyAnOiAnICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgb3RoZXIuam9pbihIRUFERVJTX1NFUEFSQVRPUik7XG4gICAgICBoZWFkZXIub3RoZXIgPSBvdGhlcjtcbiAgICB9KTtcblxuICAgIHJldHVybiBoZWFkZXJzO1xuICB9LFxuXG4gIGFkZFBhcmFtZXRlcjogZnVuY3Rpb24ocGFyYW0sIGNvbnN1bWVzKSB7XG4gICAgLy8gUmVuZGVyIGEgcGFyYW1ldGVyXG4gICAgcGFyYW0uY29uc3VtZXMgPSBjb25zdW1lcztcbiAgICBwYXJhbS5kZWZhdWx0UmVuZGVyaW5nID0gdGhpcy5tb2RlbC5kZWZhdWx0UmVuZGVyaW5nO1xuXG4gICAgLy8gQ29weSB0aGlzIHBhcmFtIEpTT04gc3BlYyBzbyB0aGF0IGl0IHdpbGwgYmUgYXZhaWxhYmxlIGZvciBKc29uRWRpdG9yXG4gICAgaWYocGFyYW0uc2NoZW1hKXtcbiAgICAgICQuZXh0ZW5kKHRydWUsIHBhcmFtLnNjaGVtYSwgdGhpcy5tb2RlbC5kZWZpbml0aW9uc1twYXJhbS50eXBlXSk7XG4gICAgICBwYXJhbS5zY2hlbWEuZGVmaW5pdGlvbnMgPSB0aGlzLm1vZGVsLmRlZmluaXRpb25zO1xuICAgICAgLy8gVGhpcyBpcyByZXF1aXJlZCBmb3IgSnNvbkVkaXRvciB0byBkaXNwbGF5IHRoZSByb290IHByb3Blcmx5XG4gICAgICBpZighcGFyYW0uc2NoZW1hLnR5cGUpe1xuICAgICAgICBwYXJhbS5zY2hlbWEudHlwZSA9ICdvYmplY3QnO1xuICAgICAgfVxuICAgICAgLy8gVGhpcyBpcyB0aGUgdGl0bGUgdGhhdCB3aWxsIGJlIHVzZWQgYnkgSnNvbkVkaXRvciBmb3IgdGhlIHJvb3RcbiAgICAgIC8vIFNpbmNlIHdlIGFscmVhZHkgZGlzcGxheSB0aGUgcGFyYW1ldGVyJ3MgbmFtZSBpbiB0aGUgUGFyYW1ldGVyIGNvbHVtblxuICAgICAgLy8gV2Ugc2V0IHRoaXMgdG8gc3BhY2UsIHdlIGNhbid0IHNldCBpdCB0byBudWxsIG9yIHNwYWNlIG90aGVyd2lzZSBKc29uRWRpdG9yXG4gICAgICAvLyB3aWxsIHJlcGxhY2UgaXQgd2l0aCB0aGUgdGV4dCBcInJvb3RcIiB3aGljaCB3b24ndCBsb29rIGdvb2Qgb24gc2NyZWVuXG4gICAgICBpZighcGFyYW0uc2NoZW1hLnRpdGxlKXtcbiAgICAgICAgcGFyYW0uc2NoZW1hLnRpdGxlID0gJyAnO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBwYXJhbVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlBhcmFtZXRlclZpZXcoe1xuICAgICAgbW9kZWw6IHBhcmFtLFxuICAgICAgdGFnTmFtZTogJ3RyJyxcbiAgICAgIHJlYWRPbmx5OiB0aGlzLm1vZGVsLmlzUmVhZE9ubHksXG4gICAgICBzd2FnZ2VyT3B0aW9uczogdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zXG4gICAgfSk7XG4gICAgJCgnLm9wZXJhdGlvbi1wYXJhbXMnLCAkKHRoaXMuZWwpKS5hcHBlbmQocGFyYW1WaWV3LnJlbmRlcigpLmVsKTtcbiAgfSxcblxuICBhZGRTdGF0dXNDb2RlOiBmdW5jdGlvbihzdGF0dXNDb2RlKSB7XG4gICAgLy8gUmVuZGVyIHN0YXR1cyBjb2Rlc1xuICAgIHN0YXR1c0NvZGUuZGVmYXVsdFJlbmRlcmluZyA9IHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZztcbiAgICB2YXIgc3RhdHVzQ29kZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlN0YXR1c0NvZGVWaWV3KHtcbiAgICAgIG1vZGVsOiBzdGF0dXNDb2RlLFxuICAgICAgdGFnTmFtZTogJ3RyJyxcbiAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXJcbiAgICB9KTtcbiAgICAkKCcub3BlcmF0aW9uLXN0YXR1cycsICQodGhpcy5lbCkpLmFwcGVuZChzdGF0dXNDb2RlVmlldy5yZW5kZXIoKS5lbCk7XG4gIH0sXG5cbiAgLy8gTm90ZTogY29waWVkIGZyb20gQ29mZmVlU2NyaXB0IGNvbXBpbGVkIGZpbGVcbiAgLy8gVE9ETzogcmVkYWN0b3JcbiAgc3VibWl0T3BlcmF0aW9uOiBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVycm9yX2ZyZWUsIGZvcm0sIGlzRmlsZVVwbG9hZCwgbWFwLCBvcHRzO1xuICAgIGlmIChlICE9PSBudWxsKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIGZvcm0gPSAkKCcuc2FuZGJveCcsICQodGhpcy5lbCkpO1xuICAgIGVycm9yX2ZyZWUgPSB0cnVlO1xuICAgIGZvcm0uZmluZCgnaW5wdXQucmVxdWlyZWQnKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgJCh0aGlzKS5yZW1vdmVDbGFzcygnZXJyb3InKTtcbiAgICAgIGlmIChqUXVlcnkudHJpbSgkKHRoaXMpLnZhbCgpKSA9PT0gJycpIHtcbiAgICAgICAgJCh0aGlzKS5hZGRDbGFzcygnZXJyb3InKTtcbiAgICAgICAgJCh0aGlzKS53aWdnbGUoe1xuICAgICAgICAgIGNhbGxiYWNrOiAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgJChfdGhpcykuZm9jdXMoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSkodGhpcylcbiAgICAgICAgfSk7XG4gICAgICAgIGVycm9yX2ZyZWUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBmb3JtLmZpbmQoJ3RleHRhcmVhLnJlcXVpcmVkOnZpc2libGUnKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgJCh0aGlzKS5yZW1vdmVDbGFzcygnZXJyb3InKTtcbiAgICAgIGlmIChqUXVlcnkudHJpbSgkKHRoaXMpLnZhbCgpKSA9PT0gJycpIHtcbiAgICAgICAgJCh0aGlzKS5hZGRDbGFzcygnZXJyb3InKTtcbiAgICAgICAgJCh0aGlzKS53aWdnbGUoe1xuICAgICAgICAgIGNhbGxiYWNrOiAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgcmV0dXJuICQoX3RoaXMpLmZvY3VzKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKHRoaXMpXG4gICAgICAgIH0pO1xuICAgICAgICBlcnJvcl9mcmVlID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZm9ybS5maW5kKCdzZWxlY3QucmVxdWlyZWQnKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgJCh0aGlzKS5yZW1vdmVDbGFzcygnZXJyb3InKTtcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkSW5kZXggPT09IC0xKSB7XG4gICAgICAgICQodGhpcykuYWRkQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICAgICQodGhpcykud2lnZ2xlKHtcbiAgICAgICAgICBjYWxsYmFjazogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICQoX3RoaXMpLmZvY3VzKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKHRoaXMpXG4gICAgICAgIH0pO1xuICAgICAgICBlcnJvcl9mcmVlID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGVycm9yX2ZyZWUpIHtcbiAgICAgIG1hcCA9IHRoaXMuZ2V0SW5wdXRNYXAoZm9ybSk7XG4gICAgICBpc0ZpbGVVcGxvYWQgPSB0aGlzLmlzRmlsZVVwbG9hZChmb3JtKTtcbiAgICAgIG9wdHMgPSB7XG4gICAgICAgIHBhcmVudDogdGhpc1xuICAgICAgfTtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuc3dhZ2dlck9wdGlvbnMpIHtcbiAgICAgICAgZm9yKHZhciBrZXkgaW4gdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zKSB7XG4gICAgICAgICAgb3B0c1trZXldID0gdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zW2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIHBpO1xuICAgICAgZm9yKHBpID0gMDsgcGkgPCB0aGlzLm1vZGVsLnBhcmFtZXRlcnMubGVuZ3RoOyBwaSsrKXtcbiAgICAgICAgdmFyIHAgPSB0aGlzLm1vZGVsLnBhcmFtZXRlcnNbcGldO1xuICAgICAgICBpZiggcC5qc29uRWRpdG9yICYmIHAuanNvbkVkaXRvci5pc0VuYWJsZWQoKSl7XG4gICAgICAgICAgdmFyIGpzb24gPSBwLmpzb25FZGl0b3IuZ2V0VmFsdWUoKTtcbiAgICAgICAgICBtYXBbcC5uYW1lXSA9IEpTT04uc3RyaW5naWZ5KGpzb24pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG9wdHMucmVzcG9uc2VDb250ZW50VHlwZSA9ICQoJ2RpdiBzZWxlY3RbbmFtZT1yZXNwb25zZUNvbnRlbnRUeXBlXScsICQodGhpcy5lbCkpLnZhbCgpO1xuICAgICAgb3B0cy5yZXF1ZXN0Q29udGVudFR5cGUgPSAkKCdkaXYgc2VsZWN0W25hbWU9cGFyYW1ldGVyQ29udGVudFR5cGVdJywgJCh0aGlzLmVsKSkudmFsKCk7XG4gICAgICAkKCcucmVzcG9uc2VfdGhyb2JiZXInLCAkKHRoaXMuZWwpKS5zaG93KCk7XG4gICAgICBpZiAoaXNGaWxlVXBsb2FkKSB7XG4gICAgICAgICQoJy5yZXF1ZXN0X3VybCcsICQodGhpcy5lbCkpLmh0bWwoJzxwcmU+PC9wcmU+Jyk7XG4gICAgICAgICQoJy5yZXF1ZXN0X3VybCBwcmUnLCAkKHRoaXMuZWwpKS50ZXh0KHRoaXMuaW52b2NhdGlvblVybCk7XG5cbiAgICAgICAgb3B0cy51c2VKUXVlcnkgPSB0cnVlO1xuICAgICAgICBtYXAucGFyYW1ldGVyQ29udGVudFR5cGUgPSAnbXVsdGlwYXJ0L2Zvcm0tZGF0YSc7XG4gICAgICAgIHRoaXMubWFwID0gbWFwO1xuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC5leGVjdXRlKG1hcCwgb3B0cywgdGhpcy5zaG93Q29tcGxldGVTdGF0dXMsIHRoaXMuc2hvd0Vycm9yU3RhdHVzLCB0aGlzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubWFwID0gbWFwO1xuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC5leGVjdXRlKG1hcCwgb3B0cywgdGhpcy5zaG93Q29tcGxldGVTdGF0dXMsIHRoaXMuc2hvd0Vycm9yU3RhdHVzLCB0aGlzKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgZ2V0SW5wdXRNYXA6IGZ1bmN0aW9uIChmb3JtKSB7XG4gICAgdmFyIG1hcCwgcmVmMSwgbCwgbGVuLCBvLCByZWYyLCBtLCBsZW4xLCB2YWwsIHJlZjMsIG4sIGxlbjI7XG4gICAgbWFwID0ge307XG4gICAgcmVmMSA9IGZvcm0uZmluZCgnaW5wdXQnKTtcbiAgICBmb3IgKGwgPSAwLCBsZW4gPSByZWYxLmxlbmd0aDsgbCA8IGxlbjsgbCsrKSB7XG4gICAgICBvID0gcmVmMVtsXTtcbiAgICAgIGlmICgoby52YWx1ZSAhPT0gbnVsbCkgJiYgalF1ZXJ5LnRyaW0oby52YWx1ZSkubGVuZ3RoID4gMCkge1xuICAgICAgICBtYXBbby5uYW1lXSA9IG8udmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoby50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgbWFwW28ubmFtZV0gPSBvLmZpbGVzWzBdO1xuICAgICAgfVxuICAgIH1cbiAgICByZWYyID0gZm9ybS5maW5kKCd0ZXh0YXJlYScpO1xuICAgIGZvciAobSA9IDAsIGxlbjEgPSByZWYyLmxlbmd0aDsgbSA8IGxlbjE7IG0rKykge1xuICAgICAgbyA9IHJlZjJbbV07XG4gICAgICB2YWwgPSB0aGlzLmdldFRleHRBcmVhVmFsdWUobyk7XG4gICAgICBpZiAoKHZhbCAhPT0gbnVsbCkgJiYgalF1ZXJ5LnRyaW0odmFsKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIG1hcFtvLm5hbWVdID0gdmFsO1xuICAgICAgfVxuICAgIH1cbiAgICByZWYzID0gZm9ybS5maW5kKCdzZWxlY3QnKTtcbiAgICBmb3IgKG4gPSAwLCBsZW4yID0gcmVmMy5sZW5ndGg7IG4gPCBsZW4yOyBuKyspIHtcbiAgICAgIG8gPSByZWYzW25dO1xuICAgICAgdmFsID0gdGhpcy5nZXRTZWxlY3RlZFZhbHVlKG8pO1xuICAgICAgaWYgKCh2YWwgIT09IG51bGwpICYmIGpRdWVyeS50cmltKHZhbCkubGVuZ3RoID4gMCkge1xuICAgICAgICBtYXBbby5uYW1lXSA9IHZhbDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hcDtcbiAgfSxcblxuICBpc0ZpbGVVcGxvYWQ6IGZ1bmN0aW9uIChmb3JtKSB7XG4gICAgdmFyIHJlZjEsIGwsIGxlbiwgbztcbiAgICB2YXIgaXNGaWxlVXBsb2FkID0gZmFsc2U7XG4gICAgcmVmMSA9IGZvcm0uZmluZCgnaW5wdXQnKTtcbiAgICBmb3IgKGwgPSAwLCBsZW4gPSByZWYxLmxlbmd0aDsgbCA8IGxlbjsgbCsrKSB7XG4gICAgICBvID0gcmVmMVtsXTtcbiAgICAgIGlmIChvLnR5cGUgPT09ICdmaWxlJykge1xuICAgICAgICBpc0ZpbGVVcGxvYWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXNGaWxlVXBsb2FkO1xuICB9LFxuXG4gIHN1Y2Nlc3M6IGZ1bmN0aW9uKHJlc3BvbnNlLCBwYXJlbnQpIHtcbiAgICBwYXJlbnQuc2hvd0NvbXBsZXRlU3RhdHVzKHJlc3BvbnNlKTtcbiAgfSxcblxuICAvLyB3cmFwcyBhIGpxdWVyeSByZXNwb25zZSBhcyBhIHNocmVkIHJlc3BvbnNlXG4gIHdyYXA6IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICB2YXIgaCwgaGVhZGVyQXJyYXksIGhlYWRlcnMsIGksIGwsIGxlbiwgbztcbiAgICBoZWFkZXJzID0ge307XG4gICAgaGVhZGVyQXJyYXkgPSBkYXRhLmdldEFsbFJlc3BvbnNlSGVhZGVycygpLnNwbGl0KCdcXHInKTtcbiAgICBmb3IgKGwgPSAwLCBsZW4gPSBoZWFkZXJBcnJheS5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgaSA9IGhlYWRlckFycmF5W2xdO1xuICAgICAgaCA9IGkubWF0Y2goL14oW146XSo/KTooLiopJC8pO1xuICAgICAgaWYgKCFoKSB7XG4gICAgICAgIGggPSBbXTtcbiAgICAgIH1cbiAgICAgIGguc2hpZnQoKTtcbiAgICAgIGlmIChoWzBdICE9PSB2b2lkIDAgJiYgaFsxXSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGhlYWRlcnNbaFswXS50cmltKCldID0gaFsxXS50cmltKCk7XG4gICAgICB9XG4gICAgfVxuICAgIG8gPSB7fTtcbiAgICBvLmNvbnRlbnQgPSB7fTtcbiAgICBvLmNvbnRlbnQuZGF0YSA9IGRhdGEucmVzcG9uc2VUZXh0O1xuICAgIG8uaGVhZGVycyA9IGhlYWRlcnM7XG4gICAgby5yZXF1ZXN0ID0ge307XG4gICAgby5yZXF1ZXN0LnVybCA9IHRoaXMuaW52b2NhdGlvblVybDtcbiAgICBvLnN0YXR1cyA9IGRhdGEuc3RhdHVzO1xuICAgIHJldHVybiBvO1xuICB9LFxuXG4gIGdldFNlbGVjdGVkVmFsdWU6IGZ1bmN0aW9uKHNlbGVjdCkge1xuICAgIGlmICghc2VsZWN0Lm11bHRpcGxlKSB7XG4gICAgICByZXR1cm4gc2VsZWN0LnZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IFtdO1xuICAgICAgZm9yICh2YXIgbCA9IDAsIGxlbiA9IHNlbGVjdC5vcHRpb25zLmxlbmd0aDsgbCA8IGxlbjsgbCsrKSB7XG4gICAgICAgIHZhciBvcHQgPSBzZWxlY3Qub3B0aW9uc1tsXTtcbiAgICAgICAgaWYgKG9wdC5zZWxlY3RlZCkge1xuICAgICAgICAgIG9wdGlvbnMucHVzaChvcHQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBvcHRpb25zO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8vIGhhbmRsZXIgZm9yIGhpZGUgcmVzcG9uc2UgbGlua1xuICBoaWRlUmVzcG9uc2U6IGZ1bmN0aW9uKGUpIHtcbiAgICBpZiAoZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH1cbiAgICAkKCcucmVzcG9uc2UnLCAkKHRoaXMuZWwpKS5zbGlkZVVwKCk7XG4gICAgJCgnLnJlc3BvbnNlX2hpZGVyJywgJCh0aGlzLmVsKSkuZmFkZU91dCgpO1xuICB9LFxuXG4gIC8vIFNob3cgcmVzcG9uc2UgZnJvbSBzZXJ2ZXJcbiAgc2hvd1Jlc3BvbnNlOiBmdW5jdGlvbihyZXNwb25zZSkge1xuICAgIHZhciBwcmV0dHlKc29uID0gSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UsIG51bGwsICdcXHQnKS5yZXBsYWNlKC9cXG4vZywgJzxicj4nKTtcbiAgICAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpLmh0bWwoXy5lc2NhcGUocHJldHR5SnNvbikpO1xuICB9LFxuXG4gIC8vIFNob3cgZXJyb3IgZnJvbSBzZXJ2ZXJcbiAgc2hvd0Vycm9yU3RhdHVzOiBmdW5jdGlvbihkYXRhLCBwYXJlbnQpIHtcbiAgICBwYXJlbnQuc2hvd1N0YXR1cyhkYXRhKTtcbiAgfSxcblxuICAvLyBzaG93IHRoZSBzdGF0dXMgY29kZXNcbiAgc2hvd0NvbXBsZXRlU3RhdHVzOiBmdW5jdGlvbihkYXRhLCBwYXJlbnQpe1xuICAgIHBhcmVudC5zaG93U3RhdHVzKGRhdGEpO1xuICB9LFxuXG4gIC8vIEFkYXB0ZWQgZnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yODkzMjU5LzQ1NDAwNFxuICAvLyBOb3RlOiBkaXJlY3RseSBwb3J0ZWQgZnJvbSBDb2ZmZWVTY3JpcHRcbiAgLy8gVE9ETzogQ2xlYW51cCBDb2ZmZWVTY3JpcHQgYXJ0aWZhY3RzXG4gIGZvcm1hdFhtbDogZnVuY3Rpb24oeG1sKSB7XG4gICAgdmFyIGNvbnRleHAsIGZuLCBmb3JtYXR0ZWQsIGluZGVudCwgbCwgbGFzdFR5cGUsIGxlbiwgbGluZXMsIGxuLCBwYWQsIHJlZywgdHJhbnNpdGlvbnMsIHdzZXhwO1xuICAgIHJlZyA9IC8oPikoPCkoXFwvKikvZztcbiAgICB3c2V4cCA9IC9bIF0qKC4qKVsgXStcXG4vZztcbiAgICBjb250ZXhwID0gLyg8Lis+KSguK1xcbikvZztcbiAgICB4bWwgPSB4bWwucmVwbGFjZSgvXFxyXFxuL2csICdcXG4nKS5yZXBsYWNlKHJlZywgJyQxXFxuJDIkMycpLnJlcGxhY2Uod3NleHAsICckMVxcbicpLnJlcGxhY2UoY29udGV4cCwgJyQxXFxuJDInKTtcbiAgICBwYWQgPSAwO1xuICAgIGZvcm1hdHRlZCA9ICcnO1xuICAgIGxpbmVzID0geG1sLnNwbGl0KCdcXG4nKTtcbiAgICBpbmRlbnQgPSAwO1xuICAgIGxhc3RUeXBlID0gJ290aGVyJztcbiAgICB0cmFuc2l0aW9ucyA9IHtcbiAgICAgICdzaW5nbGUtPnNpbmdsZSc6IDAsXG4gICAgICAnc2luZ2xlLT5jbG9zaW5nJzogLTEsXG4gICAgICAnc2luZ2xlLT5vcGVuaW5nJzogMCxcbiAgICAgICdzaW5nbGUtPm90aGVyJzogMCxcbiAgICAgICdjbG9zaW5nLT5zaW5nbGUnOiAwLFxuICAgICAgJ2Nsb3NpbmctPmNsb3NpbmcnOiAtMSxcbiAgICAgICdjbG9zaW5nLT5vcGVuaW5nJzogMCxcbiAgICAgICdjbG9zaW5nLT5vdGhlcic6IDAsXG4gICAgICAnb3BlbmluZy0+c2luZ2xlJzogMSxcbiAgICAgICdvcGVuaW5nLT5jbG9zaW5nJzogMCxcbiAgICAgICdvcGVuaW5nLT5vcGVuaW5nJzogMSxcbiAgICAgICdvcGVuaW5nLT5vdGhlcic6IDEsXG4gICAgICAnb3RoZXItPnNpbmdsZSc6IDAsXG4gICAgICAnb3RoZXItPmNsb3NpbmcnOiAtMSxcbiAgICAgICdvdGhlci0+b3BlbmluZyc6IDAsXG4gICAgICAnb3RoZXItPm90aGVyJzogMFxuICAgIH07XG4gICAgZm4gPSBmdW5jdGlvbihsbikge1xuICAgICAgdmFyIGZyb21Ubywgaiwga2V5LCBwYWRkaW5nLCB0eXBlLCB0eXBlcywgdmFsdWU7XG4gICAgICB0eXBlcyA9IHtcbiAgICAgICAgc2luZ2xlOiBCb29sZWFuKGxuLm1hdGNoKC88LitcXC8+LykpLFxuICAgICAgICBjbG9zaW5nOiBCb29sZWFuKGxuLm1hdGNoKC88XFwvLis+LykpLFxuICAgICAgICBvcGVuaW5nOiBCb29sZWFuKGxuLm1hdGNoKC88W14hP10uKj4vKSlcbiAgICAgIH07XG4gICAgICB0eXBlID0gKChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHJlc3VsdHM7XG4gICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChrZXkgaW4gdHlwZXMpIHtcbiAgICAgICAgICB2YWx1ZSA9IHR5cGVzW2tleV07XG4gICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goa2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICB9KSgpKVswXTtcbiAgICAgIHR5cGUgPSB0eXBlID09PSB2b2lkIDAgPyAnb3RoZXInIDogdHlwZTtcbiAgICAgIGZyb21UbyA9IGxhc3RUeXBlICsgJy0+JyArIHR5cGU7XG4gICAgICBsYXN0VHlwZSA9IHR5cGU7XG4gICAgICBwYWRkaW5nID0gJyc7XG4gICAgICBpbmRlbnQgKz0gdHJhbnNpdGlvbnNbZnJvbVRvXTtcbiAgICAgIHBhZGRpbmcgPSAoKGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbSwgcmVmMSwgcmVzdWx0cztcbiAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICBmb3IgKGogPSBtID0gMCwgcmVmMSA9IGluZGVudDsgMCA8PSByZWYxID8gbSA8IHJlZjEgOiBtID4gcmVmMTsgaiA9IDAgPD0gcmVmMSA/ICsrbSA6IC0tbSkge1xuICAgICAgICAgIHJlc3VsdHMucHVzaCgnICAnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgIH0pKCkpLmpvaW4oJycpO1xuICAgICAgaWYgKGZyb21UbyA9PT0gJ29wZW5pbmctPmNsb3NpbmcnKSB7XG4gICAgICAgIGZvcm1hdHRlZCA9IGZvcm1hdHRlZC5zdWJzdHIoMCwgZm9ybWF0dGVkLmxlbmd0aCAtIDEpICsgbG4gKyAnXFxuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvcm1hdHRlZCArPSBwYWRkaW5nICsgbG4gKyAnXFxuJztcbiAgICAgIH1cbiAgICB9O1xuICAgIGZvciAobCA9IDAsIGxlbiA9IGxpbmVzLmxlbmd0aDsgbCA8IGxlbjsgbCsrKSB7XG4gICAgICBsbiA9IGxpbmVzW2xdO1xuICAgICAgZm4obG4pO1xuICAgIH1cbiAgICByZXR1cm4gZm9ybWF0dGVkO1xuICB9LFxuXG4gIC8vIHB1dHMgdGhlIHJlc3BvbnNlIGRhdGEgaW4gVUlcbiAgc2hvd1N0YXR1czogZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICB2YXIgdXJsLCBjb250ZW50O1xuICAgIGlmIChyZXNwb25zZS5jb250ZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnRlbnQgPSByZXNwb25zZS5kYXRhO1xuICAgICAgdXJsID0gcmVzcG9uc2UudXJsO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50ID0gcmVzcG9uc2UuY29udGVudC5kYXRhO1xuICAgICAgdXJsID0gcmVzcG9uc2UucmVxdWVzdC51cmw7XG4gICAgfVxuICAgIHZhciBoZWFkZXJzID0gcmVzcG9uc2UuaGVhZGVycztcbiAgICBpZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnRlbnQgPSBqUXVlcnkudHJpbShjb250ZW50KTtcbiAgICB9XG5cbiAgICAvLyBpZiBzZXJ2ZXIgaXMgbmljZSwgYW5kIHNlbmRzIGNvbnRlbnQtdHlwZSBiYWNrLCB3ZSBjYW4gdXNlIGl0XG4gICAgdmFyIGNvbnRlbnRUeXBlID0gbnVsbDtcbiAgICBpZiAoaGVhZGVycykge1xuICAgICAgY29udGVudFR5cGUgPSBoZWFkZXJzWydDb250ZW50LVR5cGUnXSB8fCBoZWFkZXJzWydjb250ZW50LXR5cGUnXTtcbiAgICAgIGlmIChjb250ZW50VHlwZSkge1xuICAgICAgICBjb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlLnNwbGl0KCc7JylbMF0udHJpbSgpO1xuICAgICAgfVxuICAgIH1cblxuICAgICQoJy5yZXNwb25zZV9ib2R5JywgJCh0aGlzLmVsKSkucmVtb3ZlQ2xhc3MoJ2pzb24nKTtcbiAgICAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpLnJlbW92ZUNsYXNzKCd4bWwnKTtcblxuICAgIHZhciBzdXBwb3J0c0F1ZGlvUGxheWJhY2sgPSBmdW5jdGlvbihjb250ZW50VHlwZSl7XG4gICAgICB2YXIgYXVkaW9FbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYXVkaW8nKTtcbiAgICAgIHJldHVybiAhIShhdWRpb0VsZW1lbnQuY2FuUGxheVR5cGUgJiYgYXVkaW9FbGVtZW50LmNhblBsYXlUeXBlKGNvbnRlbnRUeXBlKS5yZXBsYWNlKC9uby8sICcnKSk7XG4gICAgfTtcblxuICAgIHZhciBwcmU7XG4gICAgdmFyIGNvZGU7XG4gICAgdmFyIHNraXBIaWdobGlnaHQgPSBmYWxzZTtcbiAgICBpZiAoIWNvbnRlbnQpIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQoJ25vIGNvbnRlbnQnKTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJqc29uXCIgLz4nKS5hcHBlbmQoY29kZSk7XG5cbiAgICAgIC8vIEpTT05cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgICBjb250ZW50VHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScgfHxcbiAgICAgICAgaGVhZGVyc1snQ29udGVudC1EaXNwb3NpdGlvbiddICYmICgvYXR0YWNobWVudC8pLnRlc3QoaGVhZGVyc1snQ29udGVudC1EaXNwb3NpdGlvbiddKSB8fFxuICAgICAgICBoZWFkZXJzWydjb250ZW50LWRpc3Bvc2l0aW9uJ10gJiYgKC9hdHRhY2htZW50LykudGVzdChoZWFkZXJzWydjb250ZW50LWRpc3Bvc2l0aW9uJ10pIHx8XG4gICAgICAgIGhlYWRlcnNbJ0NvbnRlbnQtRGVzY3JpcHRpb24nXSAmJiAoL0ZpbGUgVHJhbnNmZXIvKS50ZXN0KGhlYWRlcnNbJ0NvbnRlbnQtRGVzY3JpcHRpb24nXSkgfHxcbiAgICAgICAgaGVhZGVyc1snY29udGVudC1kZXNjcmlwdGlvbiddICYmICgvRmlsZSBUcmFuc2Zlci8pLnRlc3QoaGVhZGVyc1snY29udGVudC1kZXNjcmlwdGlvbiddKSkge1xuXG4gICAgICBpZiAoJ0Jsb2InIGluIHdpbmRvdykge1xuICAgICAgICB2YXIgdHlwZSA9IGNvbnRlbnRUeXBlIHx8ICd0ZXh0L2h0bWwnO1xuICAgICAgICB2YXIgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgdmFyIGhyZWY7XG5cbiAgICAgICAgaWYoe30udG9TdHJpbmcuYXBwbHkoY29udGVudCkgPT09ICdbb2JqZWN0IEJsb2JdJykge1xuICAgICAgICAgIGhyZWYgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChjb250ZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB2YXIgYmluYXJ5RGF0YSA9IFtdO1xuICAgICAgICAgIGJpbmFyeURhdGEucHVzaChjb250ZW50KTtcbiAgICAgICAgICBocmVmID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoYmluYXJ5RGF0YSwge3R5cGU6IHR5cGV9KSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZpbGVOYW1lID0gcmVzcG9uc2UudXJsLnN1YnN0cihyZXNwb25zZS51cmwubGFzdEluZGV4T2YoJy8nKSArIDEpO1xuICAgICAgICB2YXIgZG93bmxvYWQgPSBbdHlwZSwgZmlsZU5hbWUsIGhyZWZdLmpvaW4oJzonKTtcblxuICAgICAgICAvLyBVc2UgZmlsZW5hbWUgZnJvbSByZXNwb25zZSBoZWFkZXJcbiAgICAgICAgdmFyIGRpc3Bvc2l0aW9uID0gaGVhZGVyc1snY29udGVudC1kaXNwb3NpdGlvbiddIHx8IGhlYWRlcnNbJ0NvbnRlbnQtRGlzcG9zaXRpb24nXTtcbiAgICAgICAgaWYodHlwZW9mIGRpc3Bvc2l0aW9uICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHZhciByZXNwb25zZUZpbGVuYW1lID0gL2ZpbGVuYW1lPShbXjtdKik7Py8uZXhlYyhkaXNwb3NpdGlvbik7XG4gICAgICAgICAgaWYocmVzcG9uc2VGaWxlbmFtZSAhPT0gbnVsbCAmJiByZXNwb25zZUZpbGVuYW1lLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIGRvd25sb2FkID0gcmVzcG9uc2VGaWxlbmFtZVsxXTtcbiAgICAgICAgICAgIGZpbGVOYW1lID0gZG93bmxvYWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYS5zZXRBdHRyaWJ1dGUoJ2hyZWYnLCBocmVmKTtcbiAgICAgICAgYS5zZXRBdHRyaWJ1dGUoJ2Rvd25sb2FkJywgZG93bmxvYWQpO1xuICAgICAgICBhLmlubmVyVGV4dCA9ICdEb3dubG9hZCAnICsgZmlsZU5hbWU7XG5cbiAgICAgICAgcHJlID0gJCgnPGRpdi8+JykuYXBwZW5kKGEpO1xuICAgICAgICBza2lwSGlnaGxpZ2h0ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJqc29uXCIgLz4nKS5hcHBlbmQoJ0Rvd25sb2FkIGhlYWRlcnMgZGV0ZWN0ZWQgYnV0IHlvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IGRvd25sb2FkaW5nIGJpbmFyeSB2aWEgWEhSIChCbG9iKS4nKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGNvbnRlbnRUeXBlID09PSAnYXBwbGljYXRpb24vanNvbicgfHwgL1xcK2pzb24kLy50ZXN0KGNvbnRlbnRUeXBlKSkge1xuICAgICAgdmFyIGpzb24gPSBudWxsO1xuICAgICAgdHJ5IHtcbiAgICAgICAganNvbiA9IEpTT04uc3RyaW5naWZ5KEpTT04ucGFyc2UoY29udGVudCksIG51bGwsICcgICcpO1xuICAgICAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgICAgIGpzb24gPSAnY2FuXFwndCBwYXJzZSBKU09OLiAgUmF3IHJlc3VsdDpcXG5cXG4nICsgY29udGVudDtcbiAgICAgIH1cbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQoanNvbik7XG4gICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwianNvblwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBYTUxcbiAgICB9IGVsc2UgaWYgKGNvbnRlbnRUeXBlID09PSAnYXBwbGljYXRpb24veG1sJyB8fCAvXFwreG1sJC8udGVzdChjb250ZW50VHlwZSkpIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQodGhpcy5mb3JtYXRYbWwoY29udGVudCkpO1xuICAgICAgcHJlID0gJCgnPHByZSBjbGFzcz1cInhtbFwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBIVE1MXG4gICAgfSBlbHNlIGlmIChjb250ZW50VHlwZSA9PT0gJ3RleHQvaHRtbCcpIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLmh0bWwoXy5lc2NhcGUoY29udGVudCkpO1xuICAgICAgcHJlID0gJCgnPHByZSBjbGFzcz1cInhtbFwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBQbGFpbiBUZXh0XG4gICAgfSBlbHNlIGlmICgvdGV4dFxcL3BsYWluLy50ZXN0KGNvbnRlbnRUeXBlKSkge1xuICAgICAgY29kZSA9ICQoJzxjb2RlIC8+JykudGV4dChjb250ZW50KTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJwbGFpblwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBJbWFnZVxuICAgIH0gZWxzZSBpZiAoL15pbWFnZVxcLy8udGVzdChjb250ZW50VHlwZSkpIHtcbiAgICAgIHZhciB1cmxDcmVhdG9yID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMO1xuICAgICAgdmFyIGltYWdlVXJsID0gdXJsQ3JlYXRvci5jcmVhdGVPYmplY3RVUkwoY29udGVudCk7XG5cbiAgICAgIHByZSA9ICQoJzxpbWc+JykuYXR0ciggJ3NyYycsIGltYWdlVXJsKTtcbiAgICAgIC8vIEF1ZGlvXG4gICAgfSBlbHNlIGlmICgvXmF1ZGlvXFwvLy50ZXN0KGNvbnRlbnRUeXBlKSAmJiBzdXBwb3J0c0F1ZGlvUGxheWJhY2soY29udGVudFR5cGUpKSB7XG4gICAgICBwcmUgPSAkKCc8YXVkaW8gY29udHJvbHM+JykuYXBwZW5kKCQoJzxzb3VyY2U+JykuYXR0cignc3JjJywgdXJsKS5hdHRyKCd0eXBlJywgY29udGVudFR5cGUpKTtcbiAgICB9IGVsc2UgaWYoaGVhZGVycy5sb2NhdGlvbiB8fCBoZWFkZXJzLkxvY2F0aW9uKSB7XG4gICAgICAvLyBMb2NhdGlvbiBoZWFkZXIgYmFzZWQgcmVkaXJlY3QgZG93bmxvYWRcbiAgICAgIHdpbmRvdy5sb2NhdGlvbiA9IHJlc3BvbnNlLnVybDtcblxuICAgICAgLy8gQW55dGhpbmcgZWxzZSAoQ09SUylcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZSA9ICQoJzxjb2RlIC8+JykudGV4dChjb250ZW50KTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJqc29uXCIgLz4nKS5hcHBlbmQoY29kZSk7XG4gICAgfVxuICAgIHZhciByZXNwb25zZV9ib2R5ID0gcHJlO1xuICAgICQoJy5yZXF1ZXN0X3VybCcsICQodGhpcy5lbCkpLmh0bWwoJzxwcmU+PC9wcmU+Jyk7XG4gICAgJCgnLnJlcXVlc3RfdXJsIHByZScsICQodGhpcy5lbCkpLnRleHQodXJsKTtcbiAgICAkKCcucmVzcG9uc2VfY29kZScsICQodGhpcy5lbCkpLmh0bWwoJzxwcmU+JyArIHJlc3BvbnNlLnN0YXR1cyArICc8L3ByZT4nKTtcbiAgICAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpLmh0bWwocmVzcG9uc2VfYm9keSk7XG4gICAgJCgnLnJlc3BvbnNlX2hlYWRlcnMnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyBfLmVzY2FwZShKU09OLnN0cmluZ2lmeShyZXNwb25zZS5oZWFkZXJzLCBudWxsLCAnICAnKSkucmVwbGFjZSgvXFxuL2csICc8YnI+JykgKyAnPC9wcmU+Jyk7XG4gICAgJCgnLnJlc3BvbnNlJywgJCh0aGlzLmVsKSkuc2xpZGVEb3duKCk7XG4gICAgJCgnLnJlc3BvbnNlX2hpZGVyJywgJCh0aGlzLmVsKSkuc2hvdygpO1xuICAgICQoJy5yZXNwb25zZV90aHJvYmJlcicsICQodGhpcy5lbCkpLmhpZGUoKTtcblxuXG4gICAgLy8gYWRkcyBjdXJsIG91dHB1dFxuICAgIHZhciBjdXJsQ29tbWFuZCA9IHRoaXMubW9kZWwuYXNDdXJsKHRoaXMubWFwLCB7cmVzcG9uc2VDb250ZW50VHlwZTogY29udGVudFR5cGV9KTtcbiAgICBjdXJsQ29tbWFuZCA9IGN1cmxDb21tYW5kLnJlcGxhY2UoJyEnLCAnJiMzMzsnKTtcbiAgICAkKCAnZGl2LmN1cmwnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyBfLmVzY2FwZShjdXJsQ29tbWFuZCkgKyAnPC9wcmU+Jyk7XG5cbiAgICAvLyBvbmx5IGhpZ2hsaWdodCB0aGUgcmVzcG9uc2UgaWYgcmVzcG9uc2UgaXMgbGVzcyB0aGFuIHRocmVzaG9sZCwgZGVmYXVsdCBzdGF0ZSBpcyBoaWdobGlnaHQgcmVzcG9uc2VcbiAgICB2YXIgb3B0cyA9IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9ucztcblxuICAgIGlmIChvcHRzLnNob3dSZXF1ZXN0SGVhZGVycykge1xuICAgICAgdmFyIGZvcm0gPSAkKCcuc2FuZGJveCcsICQodGhpcy5lbCkpLFxuICAgICAgICAgIG1hcCA9IHRoaXMuZ2V0SW5wdXRNYXAoZm9ybSksXG4gICAgICAgICAgcmVxdWVzdEhlYWRlcnMgPSB0aGlzLm1vZGVsLmdldEhlYWRlclBhcmFtcyhtYXApO1xuICAgICAgZGVsZXRlIHJlcXVlc3RIZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgICAgICQoJy5yZXF1ZXN0X2hlYWRlcnMnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyBfLmVzY2FwZShKU09OLnN0cmluZ2lmeShyZXF1ZXN0SGVhZGVycywgbnVsbCwgJyAgJykpLnJlcGxhY2UoL1xcbi9nLCAnPGJyPicpICsgJzwvcHJlPicpO1xuICAgIH1cblxuICAgIC8vIENhbGwgdXNlci1kZWZpbmVkIGhvb2tcbiAgICBpZiAob3B0cy5yZXNwb25zZUhvb2tzICYmIG9wdHMucmVzcG9uc2VIb29rc1t0aGlzLm5pY2tuYW1lXSkge1xuICAgICAgb3B0cy5yZXNwb25zZUhvb2tzW3RoaXMubmlja25hbWVdKHJlc3BvbnNlLCB0aGlzKTtcbiAgICB9XG5cbiAgICB2YXIgcmVzcG9uc2VfYm9keV9lbCA9ICQoJy5yZXNwb25zZV9ib2R5JywgJCh0aGlzLmVsKSlbMF07XG4gICAgLy8gb25seSBoaWdobGlnaHQgdGhlIHJlc3BvbnNlIGlmIHJlc3BvbnNlIGlzIGxlc3MgdGhhbiB0aHJlc2hvbGQsIGRlZmF1bHQgc3RhdGUgaXMgaGlnaGxpZ2h0IHJlc3BvbnNlXG4gICAgaWYgKG9wdHMuaGlnaGxpZ2h0U2l6ZVRocmVzaG9sZCAmJiB0eXBlb2YgcmVzcG9uc2UuZGF0YSAhPT0gJ3VuZGVmaW5lZCcgJiYgcmVzcG9uc2UuZGF0YS5sZW5ndGggPiBvcHRzLmhpZ2hsaWdodFNpemVUaHJlc2hvbGQgfHwgc2tpcEhpZ2hsaWdodCkge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlX2JvZHlfZWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBobGpzLmhpZ2hsaWdodEJsb2NrKHJlc3BvbnNlX2JvZHlfZWwpO1xuICAgIH1cbiAgfSxcblxuICB0b2dnbGVPcGVyYXRpb25Db250ZW50OiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgZWxlbSA9ICQoJyMnICsgRG9jcy5lc2NhcGVSZXNvdXJjZU5hbWUodGhpcy5wYXJlbnRJZCArICdfJyArIHRoaXMubmlja25hbWUgKyAnX2NvbnRlbnQnKSk7XG4gICAgaWYgKGVsZW0uaXMoJzp2aXNpYmxlJykpe1xuICAgICAgJC5iYnEucHVzaFN0YXRlKCcjLycsIDIpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIERvY3MuY29sbGFwc2VPcGVyYXRpb24oZWxlbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIERvY3MuZXhwYW5kT3BlcmF0aW9uKGVsZW0pO1xuICAgIH1cbiAgfSxcblxuICBnZXRUZXh0QXJlYVZhbHVlOiBmdW5jdGlvbih0ZXh0QXJlYSkge1xuICAgIHZhciBwYXJhbSwgcGFyc2VkLCByZXN1bHQsIGk7XG4gICAgaWYgKHRleHRBcmVhLnZhbHVlID09PSBudWxsIHx8IGpRdWVyeS50cmltKHRleHRBcmVhLnZhbHVlKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBwYXJhbSA9IHRoaXMuZ2V0UGFyYW1CeU5hbWUodGV4dEFyZWEubmFtZSk7XG4gICAgaWYgKHBhcmFtICYmIHBhcmFtLnR5cGUgJiYgcGFyYW0udHlwZS50b0xvd2VyQ2FzZSgpID09PSAnYXJyYXknKSB7XG4gICAgICBwYXJzZWQgPSB0ZXh0QXJlYS52YWx1ZS5zcGxpdCgnXFxuJyk7XG4gICAgICByZXN1bHQgPSBbXTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXJzZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHBhcnNlZFtpXSAhPT0gbnVsbCAmJiBqUXVlcnkudHJpbShwYXJzZWRbaV0pLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICByZXN1bHQucHVzaChwYXJzZWRbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0Lmxlbmd0aCA+IDAgPyByZXN1bHQgOiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGV4dEFyZWEudmFsdWU7XG4gICAgfVxuICB9LFxuXG4gIHNob3dTbmlwcGV0OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNvbnRlbnRUeXBlRWwgPSB0aGlzLiQoJ1tuYW1lPXJlc3BvbnNlQ29udGVudFR5cGVdJyk7XG4gICAgdmFyIHhtbFNuaXBwZXRFbCA9IHRoaXMuJCgnLm9wZXJhdGlvbi1zdGF0dXMgLnNuaXBwZXRfeG1sLCAucmVzcG9uc2UtY2xhc3MgLnNuaXBwZXRfeG1sJyk7XG4gICAgdmFyIGpzb25TbmlwcGV0RWwgPSB0aGlzLiQoJy5vcGVyYXRpb24tc3RhdHVzIC5zbmlwcGV0X2pzb24sIC5yZXNwb25zZS1jbGFzcyAuc25pcHBldF9qc29uJyk7XG4gICAgdmFyIGNvbnRlbnRUeXBlO1xuXG4gICAgaWYgKCFjb250ZW50VHlwZUVsLmxlbmd0aCkgeyByZXR1cm47IH1cbiAgICBjb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlRWwudmFsKCk7XG5cbiAgICBpZiAoY29udGVudFR5cGUuaW5kZXhPZigneG1sJykgPiAtMSkge1xuICAgICAgeG1sU25pcHBldEVsLnNob3coKTtcbiAgICAgIGpzb25TbmlwcGV0RWwuaGlkZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBqc29uU25pcHBldEVsLnNob3coKTtcbiAgICAgIHhtbFNuaXBwZXRFbC5oaWRlKCk7XG4gICAgfVxuICB9LFxuXG4gIGdldFBhcmFtQnlOYW1lOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgdmFyIGk7XG4gICAgaWYgKHRoaXMubW9kZWwucGFyYW1ldGVycykge1xuICAgICAgZm9yKGkgPSAwOyBpIDwgdGhpcy5tb2RlbC5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsLnBhcmFtZXRlcnNbaV0ubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLm1vZGVsLnBhcmFtZXRlcnNbaV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5QYXJhbWV0ZXJDb250ZW50VHlwZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICAoKSB7fSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgdGhpcy5tb2RlbC5wYXJhbWV0ZXJDb250ZW50VHlwZUlkID0gJ3BjdCcgKyBNYXRoLnJhbmRvbSgpO1xuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5wYXJhbWV0ZXJfY29udGVudF90eXBlKHRoaXMubW9kZWwpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5QYXJhbWV0ZXJWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBldmVudHM6IHtcbiAgICAnY2hhbmdlIFtuYW1lPXBhcmFtZXRlckNvbnRlbnRUeXBlXScgOiAndG9nZ2xlUGFyYW1ldGVyU25pcHBldCdcbiAgfSxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbigpe1xuICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2lzQXJyYXknLCBmdW5jdGlvbihwYXJhbSwgb3B0cykge1xuICAgICAgdmFyIHBhcmFtVHlwZSA9IHBhcmFtLnR5cGUgJiYgcGFyYW0udHlwZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKHBhcmFtVHlwZSA9PT0gJ2FycmF5JyB8fCBwYXJhbS5hbGxvd011bHRpcGxlKSB7XG4gICAgICAgIHJldHVybiBvcHRzLmZuKHRoaXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG9wdHMuaW52ZXJzZSh0aGlzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0eXBlID0gdGhpcy5tb2RlbC50eXBlIHx8IHRoaXMubW9kZWwuZGF0YVR5cGU7XG4gICAgdmFyIG1vZGVsVHlwZSA9IHRoaXMubW9kZWwubW9kZWxTaWduYXR1cmUudHlwZTtcbiAgICB2YXIgbW9kZWxEZWZpbml0aW9ucyA9IHRoaXMubW9kZWwubW9kZWxTaWduYXR1cmUuZGVmaW5pdGlvbnM7XG4gICAgdmFyIHNjaGVtYSA9IHRoaXMubW9kZWwuc2NoZW1hIHx8IHt9O1xuICAgIHZhciBjb25zdW1lcyA9IHRoaXMubW9kZWwuY29uc3VtZXMgfHwgW107XG4gICAgdmFyIHNhbXBsZUpTT04sIHNpZ25hdHVyZVZpZXc7XG5cbiAgICBpZiAodHlwZW9mIHR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgICAgdmFyIHJlZiA9IHNjaGVtYS4kcmVmO1xuICAgICAgICBpZiAocmVmLmluZGV4T2YoJyMvZGVmaW5pdGlvbnMvJykgPT09IDApIHtcbiAgICAgICAgICB0eXBlID0gcmVmLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHlwZSA9IHJlZjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubW9kZWwudHlwZSA9IHR5cGU7XG4gICAgdGhpcy5tb2RlbC5wYXJhbVR5cGUgPSB0aGlzLm1vZGVsLmluIHx8IHRoaXMubW9kZWwucGFyYW1UeXBlO1xuICAgIHRoaXMubW9kZWwuaXNCb2R5ID0gdGhpcy5tb2RlbC5wYXJhbVR5cGUgPT09ICdib2R5JyB8fCB0aGlzLm1vZGVsLmluID09PSAnYm9keSc7XG4gICAgdGhpcy5tb2RlbC5pc0ZpbGUgPSB0eXBlICYmIHR5cGUudG9Mb3dlckNhc2UoKSA9PT0gJ2ZpbGUnO1xuXG4gICAgLy8gQWxsb3cgZm9yIGRlZmF1bHQgPT09IGZhbHNlXG4gICAgaWYodHlwZW9mIHRoaXMubW9kZWwuZGVmYXVsdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMubW9kZWwuZGVmYXVsdCA9IHRoaXMubW9kZWwuZGVmYXVsdFZhbHVlO1xuICAgIH1cblxuICAgIHRoaXMubW9kZWwuaGFzRGVmYXVsdCA9ICh0eXBlb2YgdGhpcy5tb2RlbC5kZWZhdWx0ICE9PSAndW5kZWZpbmVkJyk7XG4gICAgdGhpcy5tb2RlbC52YWx1ZUlkID0gJ20nICsgdGhpcy5tb2RlbC5uYW1lICsgTWF0aC5yYW5kb20oKTtcblxuICAgIGlmICh0aGlzLm1vZGVsLmFsbG93YWJsZVZhbHVlcykge1xuICAgICAgdGhpcy5tb2RlbC5pc0xpc3QgPSB0cnVlO1xuICAgIH1cblxuICAgIHZhciBpc1hNTCA9IHRoaXMuY29udGFpbnMoY29uc3VtZXMsICd4bWwnKTtcbiAgICB2YXIgaXNKU09OID0gaXNYTUwgPyB0aGlzLmNvbnRhaW5zKGNvbnN1bWVzLCAnanNvbicpIDogdHJ1ZTtcbiAgICBzYW1wbGVKU09OID0gU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVQYXJhbWV0ZXJKU09OU2FtcGxlKG1vZGVsVHlwZSwgbW9kZWxEZWZpbml0aW9ucyk7XG5cbiAgICB2YXIgdGVtcGxhdGUgPSB0aGlzLnRlbXBsYXRlKCk7XG4gICAgJCh0aGlzLmVsKS5odG1sKHRlbXBsYXRlKHRoaXMubW9kZWwpKTtcblxuICAgIHZhciBzaWduYXR1cmVNb2RlbCA9IHtcbiAgICAgIHNhbXBsZUpTT046IGlzSlNPTiA/IHNhbXBsZUpTT04gOiBmYWxzZSxcbiAgICAgIHNhbXBsZVhNTDogc2FtcGxlSlNPTiAmJiBpc1hNTCA/IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuY3JlYXRlWE1MU2FtcGxlKCcnLCBzY2hlbWEsIG1vZGVsRGVmaW5pdGlvbnMsIHRydWUpIDogZmFsc2UsXG4gICAgICBpc1BhcmFtOiB0cnVlLFxuICAgICAgc2lnbmF0dXJlOiBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmdldFBhcmFtZXRlck1vZGVsU2lnbmF0dXJlKG1vZGVsVHlwZSwgbW9kZWxEZWZpbml0aW9ucyksXG4gICAgICBkZWZhdWx0UmVuZGVyaW5nOiB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmdcbiAgICB9O1xuXG4gICAgaWYgKHNhbXBsZUpTT04pIHtcbiAgICAgIHNpZ25hdHVyZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlNpZ25hdHVyZVZpZXcoe21vZGVsOiBzaWduYXR1cmVNb2RlbCwgdGFnTmFtZTogJ2Rpdid9KTtcbiAgICAgICQoJy5tb2RlbC1zaWduYXR1cmUnLCAkKHRoaXMuZWwpKS5hcHBlbmQoc2lnbmF0dXJlVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgJCgnLm1vZGVsLXNpZ25hdHVyZScsICQodGhpcy5lbCkpLmh0bWwodGhpcy5tb2RlbC5zaWduYXR1cmUpO1xuICAgIH1cblxuICAgIHZhciBpc1BhcmFtID0gZmFsc2U7XG5cbiAgICBpZiggdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zLmpzb25FZGl0b3IgJiYgdGhpcy5tb2RlbC5pc0JvZHkgJiYgdGhpcy5tb2RlbC5zY2hlbWEpe1xuICAgICAgdmFyICRzZWxmID0gJCh0aGlzLmVsKTtcbiAgICAgIHRoaXMubW9kZWwuanNvbkVkaXRvciA9XG4gICAgICAgIC8qIGdsb2JhbCBKU09ORWRpdG9yICovXG4gICAgICAgIG5ldyBKU09ORWRpdG9yKCQoJy5lZGl0b3JfaG9sZGVyJywgJHNlbGYpWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICB7c2NoZW1hOiB0aGlzLm1vZGVsLnNjaGVtYSwgc3RhcnR2YWwgOiB0aGlzLm1vZGVsLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgICAgICBhamF4OnRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlX3Byb3BlcnRpZXM6dHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVfZWRpdF9qc29uOnRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29ubGliOiAnc3dhZ2dlcicgfSk7XG4gICAgICAvLyBUaGlzIGlzIHNvIHRoYXQgdGhlIHNpZ25hdHVyZSBjYW4gc2VuZCBiYWNrIHRoZSBzYW1wbGUgdG8gdGhlIGpzb24gZWRpdG9yXG4gICAgICAvLyBUT0RPOiBTaWduYXR1cmVWaWV3IHNob3VsZCBleHBvc2UgYW4gZXZlbnQgXCJvblNhbXBsZUNsaWNrZWRcIiBpbnN0ZWFkXG4gICAgICBzaWduYXR1cmVNb2RlbC5qc29uRWRpdG9yID0gdGhpcy5tb2RlbC5qc29uRWRpdG9yO1xuICAgICAgJCgnLmJvZHktdGV4dGFyZWEnLCAkc2VsZikuaGlkZSgpO1xuICAgICAgJCgnLmVkaXRvcl9ob2xkZXInLCAkc2VsZikuc2hvdygpO1xuICAgICAgJCgnLnBhcmFtZXRlci1jb250ZW50LXR5cGUnLCAkc2VsZilcbiAgICAgICAgLmNoYW5nZShmdW5jdGlvbihlKXtcbiAgICAgICAgICAgIGlmKGUudGFyZ2V0LnZhbHVlID09PSAnYXBwbGljYXRpb24veG1sJyl7XG4gICAgICAgICAgICAgICQoJy5ib2R5LXRleHRhcmVhJywgJHNlbGYpLnNob3coKTtcbiAgICAgICAgICAgICAgJCgnLmVkaXRvcl9ob2xkZXInLCAkc2VsZikuaGlkZSgpO1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLmpzb25FZGl0b3IuZGlzYWJsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICQoJy5ib2R5LXRleHRhcmVhJywgJHNlbGYpLmhpZGUoKTtcbiAgICAgICAgICAgICAgJCgnLmVkaXRvcl9ob2xkZXInLCAkc2VsZikuc2hvdygpO1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLmpzb25FZGl0b3IuZW5hYmxlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG5cbiAgICBpZiAodGhpcy5tb2RlbC5pc0JvZHkpIHtcbiAgICAgIGlzUGFyYW0gPSB0cnVlO1xuICAgIH1cblxuICAgIHZhciBjb250ZW50VHlwZU1vZGVsID0ge1xuICAgICAgaXNQYXJhbTogaXNQYXJhbVxuICAgIH07XG5cbiAgICBjb250ZW50VHlwZU1vZGVsLmNvbnN1bWVzID0gdGhpcy5tb2RlbC5jb25zdW1lcztcblxuICAgIGlmIChpc1BhcmFtKSB7XG4gICAgICB2YXIgcGFyYW1ldGVyQ29udGVudFR5cGVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5QYXJhbWV0ZXJDb250ZW50VHlwZVZpZXcoe21vZGVsOiBjb250ZW50VHlwZU1vZGVsfSk7XG4gICAgICAkKCcucGFyYW1ldGVyLWNvbnRlbnQtdHlwZScsICQodGhpcy5lbCkpLmFwcGVuZChwYXJhbWV0ZXJDb250ZW50VHlwZVZpZXcucmVuZGVyKCkuZWwpO1xuICAgICAgdGhpcy50b2dnbGVQYXJhbWV0ZXJTbmlwcGV0KCk7XG4gICAgfVxuXG4gICAgZWxzZSB7XG4gICAgICB2YXIgcmVzcG9uc2VDb250ZW50VHlwZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlJlc3BvbnNlQ29udGVudFR5cGVWaWV3KHttb2RlbDogY29udGVudFR5cGVNb2RlbH0pO1xuICAgICAgJCgnLnJlc3BvbnNlLWNvbnRlbnQtdHlwZScsICQodGhpcy5lbCkpLmFwcGVuZChyZXNwb25zZUNvbnRlbnRUeXBlVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgICB0aGlzLnRvZ2dsZVJlc3BvbnNlU25pcHBldCgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIGNvbnRhaW5zOiBmdW5jdGlvbiAoY29uc3VtZXMsIHR5cGUpIHtcbiAgICByZXR1cm4gY29uc3VtZXMuZmlsdGVyKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIGlmICh2YWwuaW5kZXhPZih0eXBlKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pLmxlbmd0aDtcbiAgfSxcblxuICB0b2dnbGVQYXJhbWV0ZXJTbmlwcGV0OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNvbnRlbnRUeXBlID0gdGhpcy4kKCdbbmFtZT1wYXJhbWV0ZXJDb250ZW50VHlwZV0nKS52YWwoKTtcblxuICAgIHRoaXMudG9nZ2xlU25pcHBldChjb250ZW50VHlwZSk7XG4gIH0sXG5cbiAgdG9nZ2xlUmVzcG9uc2VTbmlwcGV0OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNvbnRlbnRFbCA9IHRoaXMuJCgnW25hbWU9cmVzcG9uc2VDb250ZW50VHlwZV0nKTtcblxuICAgIGlmICghY29udGVudEVsLmxlbmd0aCkgeyByZXR1cm47IH1cblxuICAgIHRoaXMudG9nZ2xlU25pcHBldChjb250ZW50RWwudmFsKCkpO1xuICB9LFxuXG4gIHRvZ2dsZVNuaXBwZXQ6IGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgdHlwZSA9IHR5cGUgfHwgJyc7XG4gICAgaWYgKHR5cGUuaW5kZXhPZigneG1sJykgPiAtMSkge1xuICAgICAgdGhpcy4kKCcuc25pcHBldF94bWwnKS5zaG93KCk7XG4gICAgICB0aGlzLiQoJy5zbmlwcGV0X2pzb24nKS5oaWRlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuJCgnLnNuaXBwZXRfanNvbicpLnNob3coKTtcbiAgICAgIHRoaXMuJCgnLnNuaXBwZXRfeG1sJykuaGlkZSgpO1xuICAgIH1cbiAgfSxcblxuICAvLyBSZXR1cm4gYW4gYXBwcm9wcmlhdGUgdGVtcGxhdGUgYmFzZWQgb24gaWYgdGhlIHBhcmFtZXRlciBpcyBhIGxpc3QsIHJlYWRvbmx5LCByZXF1aXJlZFxuICB0ZW1wbGF0ZTogZnVuY3Rpb24oKXtcbiAgICBpZiAodGhpcy5tb2RlbC5pc0xpc3QpIHtcbiAgICAgIHJldHVybiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wYXJhbV9saXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnJlYWRPbmx5KSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsLnJlcXVpcmVkKSB7XG4gICAgICAgICAgcmV0dXJuIEhhbmRsZWJhcnMudGVtcGxhdGVzLnBhcmFtX3JlYWRvbmx5X3JlcXVpcmVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wYXJhbV9yZWFkb25seTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMubW9kZWwucmVxdWlyZWQpIHtcbiAgICAgICAgICByZXR1cm4gSGFuZGxlYmFycy50ZW1wbGF0ZXMucGFyYW1fcmVxdWlyZWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIEhhbmRsZWJhcnMudGVtcGxhdGVzLnBhcmFtO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoganNoaW50IC1XMTIyICovXG5Td2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlID0gKGZ1bmN0aW9uICgpIHtcbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciByZXNvbHZlU2NoZW1hID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICAgIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLnNjaGVtYSkpIHtcbiAgICAgIHNjaGVtYSA9IHJlc29sdmVTY2hlbWEoc2NoZW1hLnNjaGVtYSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNjaGVtYTtcbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIHNpbXBsZVJlZiA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKG5hbWUuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIG5hbWUuc3Vic3RyaW5nKCcjL2RlZmluaXRpb25zLycubGVuZ3RoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5hbWU7XG4gICAgfVxuICB9O1xuXG4gIC8vIGNvcHktcGFzdGVkIGZyb20gc3dhZ2dlci1qc1xuICB2YXIgZ2V0SW5saW5lTW9kZWwgPSBmdW5jdGlvbihpbmxpbmVTdHIpIHtcbiAgICBpZigvXklubGluZSBNb2RlbCBcXGQrJC8udGVzdChpbmxpbmVTdHIpICYmIHRoaXMuaW5saW5lTW9kZWxzKSB7XG4gICAgICB2YXIgaWQgPSBwYXJzZUludChpbmxpbmVTdHIuc3Vic3RyKCdJbmxpbmUgTW9kZWwnLmxlbmd0aCkudHJpbSgpLDEwKTsgLy9cbiAgICAgIHZhciBtb2RlbCA9IHRoaXMuaW5saW5lTW9kZWxzW2lkXTtcbiAgICAgIHJldHVybiBtb2RlbDtcbiAgICB9XG4gICAgLy8gSSdtIHJldHVybmluZyBudWxsIGhlcmUsIHNob3VsZCBJIHJhdGhlciB0aHJvdyBhbiBlcnJvcj9cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIGZvcm1hdFhtbCA9IGZ1bmN0aW9uKHhtbCkge1xuICAgIHZhciBjb250ZXhwLCBmbiwgZm9ybWF0dGVkLCBpbmRlbnQsIGwsIGxhc3RUeXBlLCBsZW4sIGxpbmVzLCBsbiwgcGFkLCByZWcsIHRyYW5zaXRpb25zLCB3c2V4cDtcbiAgICByZWcgPSAvKD4pKDwpKFxcLyopL2c7XG4gICAgd3NleHAgPSAvWyBdKiguKilbIF0rXFxuL2c7XG4gICAgY29udGV4cCA9IC8oPC4rPikoLitcXG4pL2c7XG4gICAgeG1sID0geG1sLnJlcGxhY2UocmVnLCAnJDFcXG4kMiQzJykucmVwbGFjZSh3c2V4cCwgJyQxXFxuJykucmVwbGFjZShjb250ZXhwLCAnJDFcXG4kMicpO1xuICAgIHBhZCA9IDA7XG4gICAgZm9ybWF0dGVkID0gJyc7XG4gICAgbGluZXMgPSB4bWwuc3BsaXQoJ1xcbicpO1xuICAgIGluZGVudCA9IDA7XG4gICAgbGFzdFR5cGUgPSAnb3RoZXInO1xuICAgIHRyYW5zaXRpb25zID0ge1xuICAgICAgJ3NpbmdsZS0+c2luZ2xlJzogMCxcbiAgICAgICdzaW5nbGUtPmNsb3NpbmcnOiAtMSxcbiAgICAgICdzaW5nbGUtPm9wZW5pbmcnOiAwLFxuICAgICAgJ3NpbmdsZS0+b3RoZXInOiAwLFxuICAgICAgJ2Nsb3NpbmctPnNpbmdsZSc6IDAsXG4gICAgICAnY2xvc2luZy0+Y2xvc2luZyc6IC0xLFxuICAgICAgJ2Nsb3NpbmctPm9wZW5pbmcnOiAwLFxuICAgICAgJ2Nsb3NpbmctPm90aGVyJzogMCxcbiAgICAgICdvcGVuaW5nLT5zaW5nbGUnOiAxLFxuICAgICAgJ29wZW5pbmctPmNsb3NpbmcnOiAwLFxuICAgICAgJ29wZW5pbmctPm9wZW5pbmcnOiAxLFxuICAgICAgJ29wZW5pbmctPm90aGVyJzogMSxcbiAgICAgICdvdGhlci0+c2luZ2xlJzogMCxcbiAgICAgICdvdGhlci0+Y2xvc2luZyc6IC0xLFxuICAgICAgJ290aGVyLT5vcGVuaW5nJzogMCxcbiAgICAgICdvdGhlci0+b3RoZXInOiAwXG4gICAgfTtcbiAgICBmbiA9IGZ1bmN0aW9uKGxuKSB7XG4gICAgICB2YXIgZnJvbVRvLCBqLCBrZXksIHBhZGRpbmcsIHR5cGUsIHR5cGVzLCB2YWx1ZTtcbiAgICAgIHR5cGVzID0ge1xuICAgICAgICBzaW5nbGU6IEJvb2xlYW4obG4ubWF0Y2goLzwuK1xcLz4vKSksXG4gICAgICAgIGNsb3Npbmc6IEJvb2xlYW4obG4ubWF0Y2goLzxcXC8uKz4vKSksXG4gICAgICAgIG9wZW5pbmc6IEJvb2xlYW4obG4ubWF0Y2goLzxbXiE/XS4qPi8pKVxuICAgICAgfTtcbiAgICAgIHR5cGUgPSAoKGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgcmVzdWx0cztcbiAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICBmb3IgKGtleSBpbiB0eXBlcykge1xuICAgICAgICAgIHZhbHVlID0gdHlwZXNba2V5XTtcbiAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChrZXkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgIH0pKCkpWzBdO1xuICAgICAgdHlwZSA9IHR5cGUgPT09IHZvaWQgMCA/ICdvdGhlcicgOiB0eXBlO1xuICAgICAgZnJvbVRvID0gbGFzdFR5cGUgKyAnLT4nICsgdHlwZTtcbiAgICAgIGxhc3RUeXBlID0gdHlwZTtcbiAgICAgIHBhZGRpbmcgPSAnJztcbiAgICAgIGluZGVudCArPSB0cmFuc2l0aW9uc1tmcm9tVG9dO1xuICAgICAgcGFkZGluZyA9ICgoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBtLCByZWYxLCByZXN1bHRzO1xuICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgIGZvciAoaiA9IG0gPSAwLCByZWYxID0gaW5kZW50OyAwIDw9IHJlZjEgPyBtIDwgcmVmMSA6IG0gPiByZWYxOyBqID0gMCA8PSByZWYxID8gKyttIDogLS1tKSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKCcgICcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgfSkoKSkuam9pbignJyk7XG4gICAgICBpZiAoZnJvbVRvID09PSAnb3BlbmluZy0+Y2xvc2luZycpIHtcbiAgICAgICAgZm9ybWF0dGVkID0gZm9ybWF0dGVkLnN1YnN0cigwLCBmb3JtYXR0ZWQubGVuZ3RoIC0gMSkgKyBsbiArICdcXG4nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9ybWF0dGVkICs9IHBhZGRpbmcgKyBsbiArICdcXG4nO1xuICAgICAgfVxuICAgIH07XG4gICAgZm9yIChsID0gMCwgbGVuID0gbGluZXMubGVuZ3RoOyBsIDwgbGVuOyBsKyspIHtcbiAgICAgIGxuID0gbGluZXNbbF07XG4gICAgICBmbihsbik7XG4gICAgfVxuICAgIHJldHVybiBmb3JtYXR0ZWQ7XG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBnZXRNb2RlbFNpZ25hdHVyZSA9IGZ1bmN0aW9uIChuYW1lLCBzY2hlbWEsIG1vZGVscywgbW9kZWxQcm9wZXJ0eU1hY3JvKSB7XG4gICAgdmFyIHN0cm9uZ09wZW4gPSAnPHNwYW4gY2xhc3M9XCJzdHJvbmdcIj4nO1xuICAgIHZhciBzdHJvbmdDbG9zZSA9ICc8L3NwYW4+JztcblxuICAgIHZhciBvcHRpb25IdG1sID0gZnVuY3Rpb24gKGxhYmVsLCB2YWx1ZSkge1xuICAgICAgcmV0dXJuICc8dHI+PHRkIGNsYXNzPVwib3B0aW9uTmFtZVwiPicgKyBsYWJlbCArICc6PC90ZD48dGQ+JyArIHZhbHVlICsgJzwvdGQ+PC90cj4nO1xuICAgIH07XG5cblxuICAgIC8vIEFsbG93IGZvciBpZ25vcmluZyB0aGUgJ25hbWUnIGFyZ3VtZW50Li4uLiBzaGlmdGluZyB0aGUgcmVzdFxuICAgIGlmKF8uaXNPYmplY3QoYXJndW1lbnRzWzBdKSkge1xuICAgICAgbmFtZSA9IHZvaWQgMDtcbiAgICAgIHNjaGVtYSA9IGFyZ3VtZW50c1swXTtcbiAgICAgIG1vZGVscyA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGFyZ3VtZW50c1syXTtcbiAgICB9XG5cbiAgICBtb2RlbHMgPSBtb2RlbHMgfHwge307XG5cbiAgICAvLyBSZXNvbHZlIHRoZSBzY2hlbWEgKEhhbmRsZSBuZXN0ZWQgc2NoZW1hcylcbiAgICBzY2hlbWEgPSByZXNvbHZlU2NoZW1hKHNjaGVtYSk7XG5cbiAgICAvLyBSZXR1cm4gZm9yIGVtcHR5IG9iamVjdFxuICAgIGlmKF8uaXNFbXB0eShzY2hlbWEpKSB7XG4gICAgICByZXR1cm4gc3Ryb25nT3BlbiArICdFbXB0eScgKyBzdHJvbmdDbG9zZTtcbiAgICB9XG5cbiAgICAvLyBEZXJlZmVyZW5jZSAkcmVmIGZyb20gJ21vZGVscydcbiAgICBpZih0eXBlb2Ygc2NoZW1hLiRyZWYgPT09ICdzdHJpbmcnKSB7XG4gICAgICBuYW1lID0gc2ltcGxlUmVmKHNjaGVtYS4kcmVmKTtcbiAgICAgIHNjaGVtYSA9IG1vZGVsc1tuYW1lXTtcbiAgICAgIGlmKHR5cGVvZiBzY2hlbWEgPT09ICd1bmRlZmluZWQnKVxuICAgICAge1xuICAgICAgICByZXR1cm4gc3Ryb25nT3BlbiArIG5hbWUgKyAnIGlzIG5vdCBkZWZpbmVkIScgKyBzdHJvbmdDbG9zZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZih0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIG5hbWUgPSBzY2hlbWEudGl0bGUgfHwgJ0lubGluZSBNb2RlbCc7XG4gICAgfVxuXG4gICAgLy8gSWYgd2UgYXJlIGEgTW9kZWwgb2JqZWN0Li4uIGFkanVzdCBhY2NvcmRpbmdseVxuICAgIGlmKHNjaGVtYS5kZWZpbml0aW9uKSB7XG4gICAgICBzY2hlbWEgPSBzY2hlbWEuZGVmaW5pdGlvbjtcbiAgICB9XG5cbiAgICBpZih0eXBlb2YgbW9kZWxQcm9wZXJ0eU1hY3JvICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBmdW5jdGlvbihwcm9wKXtcbiAgICAgICAgcmV0dXJuIChwcm9wIHx8IHt9KS5kZWZhdWx0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcmVmZXJlbmNlcyA9IHt9O1xuICAgIHZhciBzZWVuTW9kZWxzID0gW107XG4gICAgdmFyIGlubGluZU1vZGVscyA9IDA7XG5cbiAgICAvLyBHZW5lcmF0ZSBjdXJyZW50IEhUTUxcbiAgICB2YXIgaHRtbCA9IHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpO1xuXG4gICAgLy8gR2VuZXJhdGUgcmVmZXJlbmNlcyBIVE1MXG4gICAgd2hpbGUgKF8ua2V5cyhyZWZlcmVuY2VzKS5sZW5ndGggPiAwKSB7XG4gICAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgICBfLmZvckVhY2gocmVmZXJlbmNlcywgZnVuY3Rpb24gKHNjaGVtYSwgbmFtZSkge1xuICAgICAgICB2YXIgc2Vlbk1vZGVsID0gXy5pbmRleE9mKHNlZW5Nb2RlbHMsIG5hbWUpID4gLTE7XG5cbiAgICAgICAgZGVsZXRlIHJlZmVyZW5jZXNbbmFtZV07XG5cbiAgICAgICAgaWYgKCFzZWVuTW9kZWwpIHtcbiAgICAgICAgICBzZWVuTW9kZWxzLnB1c2gobmFtZSk7XG5cbiAgICAgICAgICBodG1sICs9ICc8YnIgLz4nICsgcHJvY2Vzc01vZGVsKHNjaGVtYSwgbmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgICB9XG5cbiAgICByZXR1cm4gaHRtbDtcblxuXG4gICAgZnVuY3Rpb24gYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSwgc2tpcFJlZikge1xuICAgICAgdmFyIG1vZGVsTmFtZSA9IG5hbWU7XG4gICAgICB2YXIgbW9kZWw7XG5cbiAgICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgICBtb2RlbE5hbWUgPSBzY2hlbWEudGl0bGUgfHwgc2ltcGxlUmVmKHNjaGVtYS4kcmVmKTtcbiAgICAgICAgbW9kZWwgPSBtb2RlbHNbc2ltcGxlUmVmKHNjaGVtYS4kcmVmKV07XG4gICAgICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwgJyArICgrK2lubGluZU1vZGVscyk7XG4gICAgICAgIG1vZGVsID0ge2RlZmluaXRpb246IHNjaGVtYX07XG4gICAgICB9XG5cbiAgICAgIGlmIChza2lwUmVmICE9PSB0cnVlKSB7XG4gICAgICAgIHJlZmVyZW5jZXNbbW9kZWxOYW1lXSA9IF8uaXNVbmRlZmluZWQobW9kZWwpID8ge30gOiBtb2RlbC5kZWZpbml0aW9uO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbW9kZWxOYW1lO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByaW1pdGl2ZVRvSFRNTChzY2hlbWEpIHtcbiAgICAgIHZhciBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcFR5cGVcIj4nO1xuICAgICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcblxuICAgICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYSwgc2ltcGxlUmVmKHNjaGVtYS4kcmVmKSk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEucHJvcGVydGllcykpIHtcbiAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICBodG1sICs9ICdBcnJheVsnO1xuXG4gICAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICAgIGh0bWwgKz0gXy5tYXAoc2NoZW1hLml0ZW1zLCBhZGRSZWZlcmVuY2UpLmpvaW4oJywnKTtcbiAgICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy4kcmVmKSkge1xuICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSAmJiBfLmluZGV4T2YoWydhcnJheScsICdvYmplY3QnXSwgc2NoZW1hLml0ZW1zLnR5cGUpID09PSAtMSkge1xuICAgICAgICAgICAgICBodG1sICs9IHNjaGVtYS5pdGVtcy50eXBlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zLCBzaW1wbGVSZWYoc2NoZW1hLml0ZW1zLiRyZWYpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ0FycmF5IHR5cGVcXCdzIFxcJ2l0ZW1zXFwnIHNjaGVtYSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICAgIH1cblxuICAgICAgICBodG1sICs9ICddJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGh0bWwgKz0gc2NoZW1hLnR5cGU7XG4gICAgICB9XG5cbiAgICAgIGh0bWwgKz0gJzwvc3Bhbj4nO1xuXG4gICAgICByZXR1cm4gaHRtbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmltaXRpdmVUb09wdGlvbnNIVE1MKHNjaGVtYSwgaHRtbCkge1xuICAgICAgdmFyIG9wdGlvbnMgPSAnJztcbiAgICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgICB2YXIgaXNBcnJheSA9IHR5cGUgPT09ICdhcnJheSc7XG5cbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuZGVzY3JpcHRpb24pKSB7XG4gICAgICAgIGh0bWwgKz0gJzogJyArICc8c3BhbiBjbGFzcz1cInByb3BEZXNjXCI+JyArIHNjaGVtYS5kZXNjcmlwdGlvbiArICc8L3NwYW4+JztcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5lbnVtKSB7XG4gICAgICAgIGh0bWwgKz0gJyA9IDxzcGFuIGNsYXNzPVwicHJvcFZhbHNcIj5bXFwnJyArIHNjaGVtYS5lbnVtLmpvaW4oJ1xcJywgXFwnJykgKyAnXFwnXTwvc3Bhbj4nO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykgJiYgIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpKSB7XG4gICAgICAgICAgdHlwZSA9IHNjaGVtYS5pdGVtcy50eXBlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHR5cGUgPSAnb2JqZWN0JztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRGVmYXVsdCcsIHNjaGVtYS5kZWZhdWx0KTtcbiAgICAgIH1cblxuICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICBpZiAoc2NoZW1hLm1pbkxlbmd0aCkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBMZW5ndGgnLCBzY2hlbWEubWluTGVuZ3RoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEubWF4TGVuZ3RoKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIExlbmd0aCcsIHNjaGVtYS5tYXhMZW5ndGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5wYXR0ZXJuKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdSZWcuIEV4cC4nLCBzY2hlbWEucGF0dGVybik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbnRlZ2VyJzpcbiAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICAgIGlmIChzY2hlbWEubWluaW11bSkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBWYWx1ZScsIHNjaGVtYS5taW5pbXVtKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEuZXhjbHVzaXZlTWluaW11bSkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1pbi4nLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5tYXhpbXVtKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIFZhbHVlJywgc2NoZW1hLm1heGltdW0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5leGNsdXNpdmVNYXhpbXVtKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFeGNsdXNpdmUgTWF4LicsICd0cnVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NoZW1hLm11bHRpcGxlT2YpIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ011bHRpcGxlIE9mJywgc2NoZW1hLm11bHRpcGxlT2YpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0FycmF5KSB7XG4gICAgICAgIGlmIChzY2hlbWEubWluSXRlbXMpIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gSXRlbXMnLCBzY2hlbWEubWluSXRlbXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5tYXhJdGVtcykge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBJdGVtcycsIHNjaGVtYS5tYXhJdGVtcyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NoZW1hLnVuaXF1ZUl0ZW1zKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdVbmlxdWUgSXRlbXMnLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5jb2xsZWN0aW9uRm9ybWF0KSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdDb2xsLiBGb3JtYXQnLCBzY2hlbWEuY29sbGVjdGlvbkZvcm1hdCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5lbnVtKSkge1xuICAgICAgICAgIHZhciBlbnVtU3RyaW5nO1xuXG4gICAgICAgICAgaWYgKHR5cGUgPT09ICdudW1iZXInIHx8IHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgICAgICAgZW51bVN0cmluZyA9IHNjaGVtYS5lbnVtLmpvaW4oJywgJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVudW1TdHJpbmcgPSAnXCInICsgc2NoZW1hLmVudW0uam9pbignXCIsIFwiJykgKyAnXCInO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRW51bScsIGVudW1TdHJpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BXcmFwXCI+JyArIGh0bWwgKyAnPHRhYmxlIGNsYXNzPVwib3B0aW9uc1dyYXBwZXJcIj48dHI+PHRoIGNvbHNwYW49XCIyXCI+JyArIHR5cGUgKyAnPC90aD48L3RyPicgKyBvcHRpb25zICsgJzwvdGFibGU+PC9zcGFuPic7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBodG1sO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpIHtcbiAgICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgICB2YXIgaXNBcnJheSA9IHNjaGVtYS50eXBlID09PSAnYXJyYXknO1xuICAgICAgdmFyIGh0bWwgPSBzdHJvbmdPcGVuICsgbmFtZSArICcgJyArIChpc0FycmF5ID8gJ1snIDogJ3snKSArIHN0cm9uZ0Nsb3NlO1xuICAgICAgdmFyIGNvbnRlbnRzO1xuXG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBzZWVuTW9kZWxzLnB1c2gobmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0FycmF5KSB7XG4gICAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIF8ubWFwKHNjaGVtYS5pdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIHZhciB0eXBlID0gaXRlbS50eXBlIHx8ICdvYmplY3QnO1xuXG4gICAgICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChpdGVtLiRyZWYpKSB7XG4gICAgICAgICAgICAgIGlmIChfLmluZGV4T2YoWydhcnJheScsICdvYmplY3QnXSwgdHlwZSkgPiAtMSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlID09PSAnb2JqZWN0JyAmJiBfLmlzVW5kZWZpbmVkKGl0ZW0ucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiAnb2JqZWN0JztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZFJlZmVyZW5jZShpdGVtKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoaXRlbSwgdHlwZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBhZGRSZWZlcmVuY2UoaXRlbSwgc2ltcGxlUmVmKGl0ZW0uJHJlZikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLmpvaW4oJyw8L2Rpdj48ZGl2PicpO1xuICAgICAgICB9IGVsc2UgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLiRyZWYpKSB7XG4gICAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHNjaGVtYS5pdGVtcy50eXBlIHx8ICdvYmplY3QnKSA+IC0xKSB7XG4gICAgICAgICAgICAgIGlmICgoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMudHlwZSkgfHwgc2NoZW1hLml0ZW1zLnR5cGUgPT09ICdvYmplY3QnKSAmJiBfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+b2JqZWN0PC9kaXY+JztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zKSArICc8L2Rpdj4nO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBwcmltaXRpdmVUb09wdGlvbnNIVE1MKHNjaGVtYS5pdGVtcywgc2NoZW1hLml0ZW1zLnR5cGUpICsgJzwvZGl2Pic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMsIHNpbXBsZVJlZihzY2hlbWEuaXRlbXMuJHJlZikpICsgJzwvZGl2Pic7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICAgIGh0bWwgKz0gJzxkaXY+b2JqZWN0PC9kaXY+JztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSkgKyAnPC9kaXY+JztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgICBjb250ZW50cyA9IF8ubWFwKHNjaGVtYS5wcm9wZXJ0aWVzLCBmdW5jdGlvbiAocHJvcGVydHksIG5hbWUpIHtcbiAgICAgICAgICAgICAgdmFyIHByb3BlcnR5SXNSZXF1aXJlZCA9IChfLmluZGV4T2Yoc2NoZW1hLnJlcXVpcmVkLCBuYW1lKSA+PSAwKTtcbiAgICAgICAgICAgICAgdmFyIGNQcm9wZXJ0eSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcblxuICAgICAgICAgICAgICB2YXIgcmVxdWlyZWRDbGFzcyA9IHByb3BlcnR5SXNSZXF1aXJlZCA/ICdyZXF1aXJlZCcgOiAnJztcbiAgICAgICAgICAgICAgdmFyIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wTmFtZSAnICsgcmVxdWlyZWRDbGFzcyArICdcIj4nICsgbmFtZSArICc8L3NwYW4+ICgnO1xuICAgICAgICAgICAgICB2YXIgbW9kZWw7XG5cbiAgICAgICAgICAgICAgLy8gQWxsb3cgbWFjcm8gdG8gc2V0IHRoZSBkZWZhdWx0IHZhbHVlXG4gICAgICAgICAgICAgIGNQcm9wZXJ0eS5kZWZhdWx0ID0gbW9kZWxQcm9wZXJ0eU1hY3JvKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gICAgICAgICAgICAgIGNQcm9wZXJ0eSA9IHJlc29sdmVTY2hlbWEoY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgICAvLyBXZSBuZWVkIHRvIGhhbmRsZSBwcm9wZXJ0eSByZWZlcmVuY2VzIHRvIHByaW1pdGl2ZXMgKElzc3VlIDMzOSlcbiAgICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKGNQcm9wZXJ0eS4kcmVmKSkge1xuICAgICAgICAgICAgICAgIG1vZGVsID0gbW9kZWxzW3NpbXBsZVJlZihjUHJvcGVydHkuJHJlZildO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKG1vZGVsKSAmJiBfLmluZGV4T2YoW3VuZGVmaW5lZCwgJ2FycmF5JywgJ29iamVjdCddLCBtb2RlbC5kZWZpbml0aW9uLnR5cGUpID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgLy8gVXNlIHJlZmVyZW5jZWQgc2NoZW1hXG4gICAgICAgICAgICAgICAgICBjUHJvcGVydHkgPSByZXNvbHZlU2NoZW1hKG1vZGVsLmRlZmluaXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGh0bWwgKz0gcHJpbWl0aXZlVG9IVE1MKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgICAgaWYoIXByb3BlcnR5SXNSZXF1aXJlZCkge1xuICAgICAgICAgICAgICAgIGh0bWwgKz0gJywgPHNwYW4gY2xhc3M9XCJwcm9wT3B0S2V5XCI+b3B0aW9uYWw8L3NwYW4+JztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmKHByb3BlcnR5LnJlYWRPbmx5KSB7XG4gICAgICAgICAgICAgICAgICBodG1sICs9ICcsIDxzcGFuIGNsYXNzPVwicHJvcFJlYWRPbmx5XCI+cmVhZCBvbmx5PC9zcGFuPic7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBodG1sICs9ICcpJztcblxuICAgICAgICAgICAgICByZXR1cm4gJzxkaXYnICsgKHByb3BlcnR5LnJlYWRPbmx5ID8gJyBjbGFzcz1cInJlYWRPbmx5XCInIDogJycpICsgJz4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChjUHJvcGVydHksIGh0bWwpO1xuICAgICAgICAgICAgfSkuam9pbignLDwvZGl2PicpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChjb250ZW50cykge1xuICAgICAgICAgICAgaHRtbCArPSBjb250ZW50cyArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBwcmltaXRpdmVUb09wdGlvbnNIVE1MKHNjaGVtYSwgdHlwZSkgKyAnPC9kaXY+JztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gaHRtbCArIHN0cm9uZ09wZW4gKyAoaXNBcnJheSA/ICddJyA6ICd9JykgKyBzdHJvbmdDbG9zZTtcbiAgICB9XG5cbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIHNjaGVtYVRvSlNPTiA9IGZ1bmN0aW9uIChzY2hlbWEsIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykge1xuICAgIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICAgIHNjaGVtYSA9IHJlc29sdmVTY2hlbWEoc2NoZW1hKTtcblxuICAgIGlmKHR5cGVvZiBtb2RlbFByb3BlcnR5TWFjcm8gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGZ1bmN0aW9uKHByb3Ape1xuICAgICAgICByZXR1cm4gKHByb3AgfHwge30pLmRlZmF1bHQ7XG4gICAgICB9O1xuICAgIH1cblxuICAgIG1vZGVsc1RvSWdub3JlPSBtb2RlbHNUb0lnbm9yZSB8fCB7fTtcblxuICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgdmFyIGZvcm1hdCA9IHNjaGVtYS5mb3JtYXQ7XG4gICAgdmFyIG1vZGVsO1xuICAgIHZhciBvdXRwdXQ7XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmV4YW1wbGUpKSB7XG4gICAgICBvdXRwdXQgPSBzY2hlbWEuZXhhbXBsZTtcbiAgICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSAmJiBfLmlzQXJyYXkoc2NoZW1hLmVudW0pKSB7XG4gICAgICBvdXRwdXQgPSBzY2hlbWEuZW51bVswXTtcbiAgICB9XG5cbiAgICBpZiAoXy5pc1VuZGVmaW5lZChvdXRwdXQpKSB7XG4gICAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgICAgbW9kZWwgPSBtb2RlbHNbc2ltcGxlUmVmKHNjaGVtYS4kcmVmKV07XG5cbiAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKG1vZGVsKSkge1xuICAgICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdKSkge1xuICAgICAgICAgICAgbW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV0gPSBtb2RlbDtcbiAgICAgICAgICAgIG91dHB1dCA9IHNjaGVtYVRvSlNPTihtb2RlbC5kZWZpbml0aW9uLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgICAgICAgZGVsZXRlIG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAobW9kZWwudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICAgICAgICBvdXRwdXQgPSBbXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG91dHB1dCA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuZGVmYXVsdCkpIHtcbiAgICAgICAgb3V0cHV0ID0gc2NoZW1hLmRlZmF1bHQ7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmIChmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgICAgICAgb3V0cHV0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2RhdGUnKSB7XG4gICAgICAgICAgb3V0cHV0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3V0cHV0ID0gJ3N0cmluZyc7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAgICAgIG91dHB1dCA9IDA7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgIG91dHB1dCA9IDAuMDtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIG91dHB1dCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIG91dHB1dCA9IHt9O1xuXG4gICAgICAgIF8uZm9yRWFjaChzY2hlbWEucHJvcGVydGllcywgZnVuY3Rpb24gKHByb3BlcnR5LCBuYW1lKSB7XG4gICAgICAgICAgdmFyIGNQcm9wZXJ0eSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcblxuICAgICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICAgIGNQcm9wZXJ0eS5kZWZhdWx0ID0gbW9kZWxQcm9wZXJ0eU1hY3JvKHByb3BlcnR5KTtcblxuICAgICAgICAgIG91dHB1dFtuYW1lXSA9IHNjaGVtYVRvSlNPTihjUHJvcGVydHksIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgICAgIG91dHB1dCA9IFtdO1xuXG4gICAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICAgIF8uZm9yRWFjaChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICBvdXRwdXQucHVzaChzY2hlbWFUb0pTT04oaXRlbSwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBvdXRwdXQucHVzaChzY2hlbWFUb0pTT04oc2NoZW1hLml0ZW1zLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pKTtcbiAgICAgICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBvdXRwdXQucHVzaCh7fSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ0FycmF5IHR5cGVcXCdzIFxcJ2l0ZW1zXFwnIHByb3BlcnR5IGlzIG5vdCBhbiBhcnJheSBvciBhbiBvYmplY3QsIGNhbm5vdCBwcm9jZXNzJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9O1xuXG4gIC8vIGNvcHktcGFzdGVkIGZyb20gc3dhZ2dlci1qc1xuICB2YXIgY3JlYXRlSlNPTlNhbXBsZSA9IGZ1bmN0aW9uICh2YWx1ZSwgbW9kZWxzVG9JZ25vcmUpIHtcbiAgICBtb2RlbHNUb0lnbm9yZSA9IG1vZGVsc1RvSWdub3JlIHx8IHt9O1xuXG4gICAgbW9kZWxzVG9JZ25vcmVbdmFsdWUubmFtZV0gPSB2YWx1ZTtcblxuICAgIC8vIFJlc3BvbnNlIHN1cHBvcnRcbiAgICBpZiAodmFsdWUuZXhhbXBsZXMgJiYgXy5pc1BsYWluT2JqZWN0KHZhbHVlLmV4YW1wbGVzKSkge1xuICAgICAgdmFsdWUgPSBfLmNsb25lRGVlcCh2YWx1ZSk7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlLmV4YW1wbGVzKTtcblxuICAgICAgXy5mb3JFYWNoKGtleXMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZihrZXkuaW5kZXhPZignYXBwbGljYXRpb24vanNvbicpID09PSAwKSB7XG4gICAgICAgICAgdmFyIGV4YW1wbGUgPSB2YWx1ZS5leGFtcGxlc1trZXldO1xuICAgICAgICAgIGlmIChfLmlzU3RyaW5nKGV4YW1wbGUpKSB7XG4gICAgICAgICAgICBleGFtcGxlID0ganN5YW1sLnNhZmVMb2FkKGV4YW1wbGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YWx1ZS5kZWZpbml0aW9uLmV4YW1wbGUgPSBleGFtcGxlO1xuICAgICAgICAgIHJldHVybiBzY2hlbWFUb0pTT04odmFsdWUuZGVmaW5pdGlvbiwgZXhhbXBsZSwgbW9kZWxzVG9JZ25vcmUsIHZhbHVlLm1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZS5leGFtcGxlcykge1xuICAgICAgdmFsdWUgPSBfLmNsb25lRGVlcCh2YWx1ZSk7XG4gICAgICB2YXIgZXhhbXBsZSA9IHZhbHVlLmV4YW1wbGVzO1xuICAgICAgaWYgKF8uaXNTdHJpbmcoZXhhbXBsZSkpIHtcbiAgICAgICAgZXhhbXBsZSA9IGpzeWFtbC5zYWZlTG9hZChleGFtcGxlKTtcbiAgICAgIH1cbiAgICAgIHZhbHVlLmRlZmluaXRpb24uZXhhbXBsZSA9IGV4YW1wbGU7XG4gICAgICByZXR1cm4gc2NoZW1hVG9KU09OKHZhbHVlLmRlZmluaXRpb24sIGV4YW1wbGUsIG1vZGVsc1RvSWdub3JlLCB2YWx1ZS5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgIH1cblxuICAgIHJldHVybiBzY2hlbWFUb0pTT04odmFsdWUuZGVmaW5pdGlvbiwgdmFsdWUubW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgdmFsdWUubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIGdldFBhcmFtZXRlck1vZGVsU2lnbmF0dXJlID0gZnVuY3Rpb24gKHR5cGUsIGRlZmluaXRpb25zKSB7XG4gICAgICB2YXIgaXNQcmltaXRpdmUsIGxpc3RUeXBlO1xuXG4gICAgICBpZiAodHlwZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIGxpc3RUeXBlID0gdHJ1ZTtcbiAgICAgICAgdHlwZSA9IHR5cGVbMF07XG4gICAgICB9XG5cbiAgICAgIC8vIENvbnZlcnQgdW5kZWZpbmVkIHRvIHN0cmluZyBvZiAndW5kZWZpbmVkJ1xuICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0eXBlID0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlzUHJpbWl0aXZlID0gdHJ1ZTtcblxuICAgICAgfSBlbHNlIGlmIChkZWZpbml0aW9uc1t0eXBlXSl7XG4gICAgICAgIC8vIGEgbW9kZWwgZGVmIGV4aXN0cz9cbiAgICAgICAgdHlwZSA9IGRlZmluaXRpb25zW3R5cGVdOyAvKiBNb2RlbCAqL1xuICAgICAgICBpc1ByaW1pdGl2ZSA9IGZhbHNlO1xuXG4gICAgICB9IGVsc2UgaWYgKGdldElubGluZU1vZGVsKHR5cGUpKSB7XG4gICAgICAgIHR5cGUgPSBnZXRJbmxpbmVNb2RlbCh0eXBlKTsgLyogTW9kZWwgKi9cbiAgICAgICAgaXNQcmltaXRpdmUgPSBmYWxzZTtcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gV2UgZGVmYXVsdCB0byBwcmltaXRpdmVcbiAgICAgICAgaXNQcmltaXRpdmUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNQcmltaXRpdmUpIHtcbiAgICAgICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuICdBcnJheVsnICsgdHlwZSArICddJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdHlwZS50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAobGlzdFR5cGUpIHtcbiAgICAgICAgICByZXR1cm4gJ0FycmF5WycgKyBnZXRNb2RlbFNpZ25hdHVyZSh0eXBlLm5hbWUsIHR5cGUuZGVmaW5pdGlvbiwgdHlwZS5tb2RlbHMsIHR5cGUubW9kZWxQcm9wZXJ0eU1hY3JvKSArICddJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZ2V0TW9kZWxTaWduYXR1cmUodHlwZS5uYW1lLCB0eXBlLmRlZmluaXRpb24sIHR5cGUubW9kZWxzLCB0eXBlLm1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIGNyZWF0ZVBhcmFtZXRlckpTT05TYW1wbGUgPSBmdW5jdGlvbiAodHlwZSwgbW9kZWxzKSB7XG4gICAgdmFyIGxpc3RUeXBlLCBzYW1wbGVKc29uLCBpbm5lclR5cGU7XG4gICAgbW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuXG4gICAgbGlzdFR5cGUgPSAodHlwZSBpbnN0YW5jZW9mIEFycmF5KTtcbiAgICBpbm5lclR5cGUgPSBsaXN0VHlwZSA/IHR5cGVbMF0gOiB0eXBlO1xuXG4gICAgaWYobW9kZWxzW2lubmVyVHlwZV0pIHtcbiAgICAgIHNhbXBsZUpzb24gPSBjcmVhdGVKU09OU2FtcGxlKG1vZGVsc1tpbm5lclR5cGVdKTtcbiAgICB9IGVsc2UgaWYgKGdldElubGluZU1vZGVsKGlubmVyVHlwZSkpe1xuICAgICAgc2FtcGxlSnNvbiA9IGNyZWF0ZUpTT05TYW1wbGUoZ2V0SW5saW5lTW9kZWwoaW5uZXJUeXBlKSk7IC8vIG1heSByZXR1cm4gbnVsbCwgaWYgdHlwZSBpc24ndCBjb3JyZWN0XG4gICAgfVxuXG5cbiAgICBpZiAoc2FtcGxlSnNvbikge1xuICAgICAgc2FtcGxlSnNvbiA9IGxpc3RUeXBlID8gW3NhbXBsZUpzb25dIDogc2FtcGxlSnNvbjtcblxuICAgICAgaWYgKHR5cGVvZiBzYW1wbGVKc29uID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc09iamVjdChzYW1wbGVKc29uKSkge1xuICAgICAgICB2YXIgdCA9IHNhbXBsZUpzb247XG5cbiAgICAgICAgaWYgKHNhbXBsZUpzb24gaW5zdGFuY2VvZiBBcnJheSAmJiBzYW1wbGVKc29uLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0ID0gc2FtcGxlSnNvblswXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0Lm5vZGVOYW1lICYmIHR5cGVvZiB0ID09PSAnTm9kZScpIHtcbiAgICAgICAgICB2YXIgeG1sU3RyaW5nID0gbmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyh0KTtcblxuICAgICAgICAgIHJldHVybiBmb3JtYXRYbWwoeG1sU3RyaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc2FtcGxlSnNvbiwgbnVsbCwgMik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzYW1wbGVKc29uO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB2YXIgd3JhcFRhZyA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgYXR0cnMpIHtcbiAgICB2YXIgc3RyLCBhdHRyaWJ1dGVzO1xuXG4gICAgYXR0cnMgPSBhdHRycyB8fCBbXTtcblxuICAgIGF0dHJpYnV0ZXMgPSBhdHRycy5tYXAoZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgIHJldHVybiAnICcgKyBhdHRyLm5hbWUgKyAnPVwiJyArIGF0dHIudmFsdWUgKyAnXCInO1xuICAgIH0pLmpvaW4oJycpO1xuXG4gICAgaWYgKCFuYW1lKSB7XG4gICAgICByZXR1cm4gZ2V0RXJyb3JNZXNzYWdlKCdOb2RlIG5hbWUgaXMgbm90IHByb3ZpZGVkJyk7XG4gICAgfVxuXG4gICAgc3RyID0gW1xuICAgICAgJzwnLCBuYW1lLFxuICAgICAgYXR0cmlidXRlcyxcbiAgICAgICc+JyxcbiAgICAgIHZhbHVlLFxuICAgICAgJzwvJywgbmFtZSwgJz4nXG4gICAgXTtcblxuICAgIHJldHVybiBzdHIuam9pbignJyk7XG4gIH07XG5cbiAgLy8gQ29tbWVudGluZyB0aGlzIGZ1bnRpb24gYXMgdGhlIG5hbWVzIGFyZSBub3cgZGV0ZXJtaW5lZCBiZWZvcmVoYW5kIGFuZCB0aGUgcHJlZml4IHBhcnQgaXMgZXhwb3NlZCBhcyBhIHNlcGFyYXRlIGZ1bmN0aW9uIHwgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItdWkvaXNzdWVzLzI1NzdcbiAvKiogdmFyIGdldE5hbWUgPSBmdW5jdGlvbiAobmFtZSwgeG1sKSB7XG4gICAgdmFyIHJlc3VsdCA9IG5hbWUgfHwgJyc7XG5cbiAgICB4bWwgPSB4bWwgfHwge307XG5cbiAgICBpZiAoeG1sLm5hbWUpIHtcbiAgICAgIHJlc3VsdCA9IHhtbC5uYW1lO1xuICAgIH1cblxuICAgIGlmICh4bWwucHJlZml4KSB7XG4gICAgICByZXN1bHQgPSB4bWwucHJlZml4ICsgJzonICsgcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gICovXG4gIFxuICB2YXIgZ2V0UHJlZml4ID0gZnVuY3Rpb24gKG5hbWUsIHhtbCkge1xuICAgIHZhciByZXN1bHQgPSBuYW1lIHx8ICcnO1xuXG4gICAgeG1sID0geG1sIHx8IHt9O1xuXG4gICAgaWYgKHhtbC5wcmVmaXgpIHtcbiAgICAgIHJlc3VsdCA9IHhtbC5wcmVmaXggKyAnOicgKyByZXN1bHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICB2YXIgZ2V0TmFtZXNwYWNlID0gZnVuY3Rpb24gKHhtbCkge1xuICAgIHZhciBuYW1lc3BhY2UgPSAnJztcbiAgICB2YXIgbmFtZSA9ICd4bWxucyc7XG5cbiAgICB4bWwgPSB4bWwgfHwge307XG5cbiAgICBpZiAoeG1sLm5hbWVzcGFjZSkge1xuICAgICAgbmFtZXNwYWNlID0geG1sLm5hbWVzcGFjZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5hbWVzcGFjZTtcbiAgICB9XG5cbiAgICBpZiAoeG1sLnByZWZpeCkge1xuICAgICAgbmFtZSArPSAnOicgKyB4bWwucHJlZml4O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgdmFsdWU6IG5hbWVzcGFjZVxuICAgIH07XG4gIH07XG5cbiAgdmFyIGNyZWF0ZUFycmF5WE1MID0gZnVuY3Rpb24gKGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgbmFtZSA9IGRlc2NyaXB0b3IubmFtZTtcbiAgICB2YXIgY29uZmlnID0gZGVzY3JpcHRvci5jb25maWc7XG4gICAgdmFyIGRlZmluaXRpb24gPSBkZXNjcmlwdG9yLmRlZmluaXRpb247XG4gICAgdmFyIG1vZGVscyA9IGRlc2NyaXB0b3IubW9kZWxzO1xuICAgIHZhciB2YWx1ZTtcbiAgICB2YXIgaXRlbXMgPSBkZWZpbml0aW9uLml0ZW1zO1xuICAgIHZhciB4bWwgPSBkZWZpbml0aW9uLnhtbCB8fCB7fTtcbiAgICB2YXIgbmFtZXNwYWNlID0gZ2V0TmFtZXNwYWNlKHhtbCk7XG4gICAgdmFyIGF0dHJpYnV0ZXMgPSBbXTtcblxuICAgIGlmICghaXRlbXMpIHsgcmV0dXJuIGdldEVycm9yTWVzc2FnZSgpOyB9XG4gICAgdmFyIGtleSA9IG5hbWU7XG4gICAgLy8gSWYgdGhlcmUgaXMgYSBuYW1lIHNwZWNpZmllZCBmb3IgdGhlIGFycmF5IGVsZW1lbnRzLCB1c2UgdGhhdCBmb3IgdGhlIGFycmF5IGVsZW1lbnRzIG5hbWUgfCBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci11aS9pc3N1ZXMvMjU3N1xuICAgIGlmKGl0ZW1zLnhtbCAmJiBpdGVtcy54bWwubmFtZSkge1xuICAgICAgICBrZXkgPSBpdGVtcy54bWwubmFtZTtcbiAgICB9XG4gICAgdmFsdWUgPSBjcmVhdGVTY2hlbWFYTUwoa2V5LCBpdGVtcywgbW9kZWxzLCBjb25maWcpO1xuICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgIGF0dHJpYnV0ZXMucHVzaChuYW1lc3BhY2UpO1xuICAgIH1cblxuICAgIGlmICh4bWwud3JhcHBlZCkge1xuICAgICAgdmFsdWUgPSB3cmFwVGFnKG5hbWUsIHZhbHVlLCBhdHRyaWJ1dGVzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH07XG5cbiAgdmFyIGdldFByaW1pdGl2ZVNpZ25hdHVyZSA9IGZ1bmN0aW9uIChzY2hlbWEpIHtcbiAgICB2YXIgdHlwZSwgaXRlbXM7XG5cbiAgICBzY2hlbWEgPSBzY2hlbWEgfHwge307XG4gICAgaXRlbXMgPSBzY2hlbWEuaXRlbXMgfHwge307XG4gICAgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICcnO1xuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdvYmplY3QnOiByZXR1cm4gJ09iamVjdCBpcyBub3QgYSBwcmltaXRpdmUnO1xuICAgICAgY2FzZSAnYXJyYXknIDogcmV0dXJuICdBcnJheVsnICsgKGl0ZW1zLmZvcm1hdCB8fCBpdGVtcy50eXBlKSArICddJztcbiAgICAgIGRlZmF1bHQ6IHJldHVybiBzY2hlbWEuZm9ybWF0IHx8IHR5cGU7XG4gICAgfVxuICB9O1xuXG4gIHZhciBjcmVhdGVQcmltaXRpdmVYTUwgPSBmdW5jdGlvbiAoZGVzY3JpcHRvcikge1xuICAgIHZhciBuYW1lID0gZGVzY3JpcHRvci5uYW1lO1xuICAgIHZhciBkZWZpbml0aW9uID0gZGVzY3JpcHRvci5kZWZpbml0aW9uO1xuICAgIHZhciBwcmltaXRpdmVzTWFwID0ge1xuICAgICAgJ3N0cmluZyc6IHtcbiAgICAgICAgJ2RhdGUnOiBuZXcgRGF0ZSgxKS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF0sXG4gICAgICAgICdkYXRlLXRpbWUnIDogbmV3IERhdGUoMSkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgJ2RlZmF1bHQnOiAnc3RyaW5nJ1xuICAgICAgfSxcbiAgICAgICdpbnRlZ2VyJzoge1xuICAgICAgICAnZGVmYXVsdCc6IDFcbiAgICAgIH0sXG4gICAgICAnbnVtYmVyJzoge1xuICAgICAgICAnZGVmYXVsdCc6IDEuMVxuICAgICAgfSxcbiAgICAgICdib29sZWFuJzoge1xuICAgICAgICAnZGVmYXVsdCc6IHRydWVcbiAgICAgIH1cbiAgICB9O1xuICAgIHZhciB0eXBlID0gZGVmaW5pdGlvbi50eXBlO1xuICAgIHZhciBmb3JtYXQgPSBkZWZpbml0aW9uLmZvcm1hdDtcbiAgICB2YXIgeG1sID0gZGVmaW5pdGlvbi54bWwgfHwge307XG4gICAgdmFyIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZSh4bWwpO1xuICAgIHZhciBhdHRyaWJ1dGVzID0gW107XG4gICAgdmFyIHZhbHVlO1xuXG4gICAgaWYgKF8ua2V5cyhwcmltaXRpdmVzTWFwKS5pbmRleE9mKHR5cGUpIDwgMCkgeyByZXR1cm4gZ2V0RXJyb3JNZXNzYWdlKCk7IH1cblxuICAgIGlmIChfLmlzQXJyYXkoZGVmaW5pdGlvbi5lbnVtKSl7XG4gICAgICB2YWx1ZSA9IGRlZmluaXRpb24uZW51bVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgPSBkZWZpbml0aW9uLmV4YW1wbGUgfHwgcHJpbWl0aXZlc01hcFt0eXBlXVtmb3JtYXRdIHx8IHByaW1pdGl2ZXNNYXBbdHlwZV0uZGVmYXVsdDtcbiAgICB9XG5cbiAgICBpZiAoeG1sLmF0dHJpYnV0ZSkge1xuICAgICAgcmV0dXJuIHtuYW1lOiBuYW1lLCB2YWx1ZTogdmFsdWV9O1xuICAgIH1cblxuICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgIGF0dHJpYnV0ZXMucHVzaChuYW1lc3BhY2UpO1xuICAgIH1cblxuICAgIHJldHVybiB3cmFwVGFnKG5hbWUsIHZhbHVlLCBhdHRyaWJ1dGVzKTtcbiAgfTtcblxuICBmdW5jdGlvbiBjcmVhdGVPYmplY3RYTUwgKGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgbmFtZSA9IGRlc2NyaXB0b3IubmFtZTtcbiAgICB2YXIgZGVmaW5pdGlvbiA9IGRlc2NyaXB0b3IuZGVmaW5pdGlvbjtcbiAgICB2YXIgY29uZmlnID0gZGVzY3JpcHRvci5jb25maWc7XG4gICAgdmFyIG1vZGVscyA9IGRlc2NyaXB0b3IubW9kZWxzO1xuICAgIHZhciBpc1BhcmFtID0gZGVzY3JpcHRvci5jb25maWcuaXNQYXJhbTtcbiAgICB2YXIgc2VyaWFsaXplZFByb3BlcnRpZXM7XG4gICAgdmFyIGF0dHJzID0gW107XG4gICAgdmFyIHByb3BlcnRpZXMgPSBkZWZpbml0aW9uLnByb3BlcnRpZXM7XG4gICAgdmFyIGFkZGl0aW9uYWxQcm9wZXJ0aWVzID0gZGVmaW5pdGlvbi5hZGRpdGlvbmFsUHJvcGVydGllcztcbiAgICB2YXIgeG1sID0gZGVmaW5pdGlvbi54bWw7XG4gICAgdmFyIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZSh4bWwpO1xuXG4gICAgaWYgKG5hbWVzcGFjZSkge1xuICAgICAgYXR0cnMucHVzaChuYW1lc3BhY2UpO1xuICAgIH0gICBcblxuICAgIGlmICghcHJvcGVydGllcyAmJiAhYWRkaXRpb25hbFByb3BlcnRpZXMpIHsgcmV0dXJuIGdldEVycm9yTWVzc2FnZSgpOyB9XG5cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyB8fCB7fTtcblxuICAgIHNlcmlhbGl6ZWRQcm9wZXJ0aWVzID0gXy5tYXAocHJvcGVydGllcywgZnVuY3Rpb24gKHByb3AsIGtleSkge1xuICAgICAgdmFyIHhtbCwgcmVzdWx0O1xuXG4gICAgICBpZiAoaXNQYXJhbSAmJiBwcm9wLnJlYWRPbmx5KSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cblxuICAgICAgeG1sID0gcHJvcC54bWwgfHwge307XG4gICAgICByZXN1bHQgPSBjcmVhdGVTY2hlbWFYTUwoa2V5LCBwcm9wLCBtb2RlbHMsIGNvbmZpZyk7XG5cbiAgICAgIGlmICh4bWwuYXR0cmlidXRlKSB7XG4gICAgICAgIGF0dHJzLnB1c2gocmVzdWx0KTtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pLmpvaW4oJycpO1xuXG4gICAgaWYgKGFkZGl0aW9uYWxQcm9wZXJ0aWVzKSB7XG4gICAgICBzZXJpYWxpemVkUHJvcGVydGllcyArPSAnPCEtLSBhZGRpdGlvbmFsIGVsZW1lbnRzIGFsbG93ZWQgLS0+JztcbiAgICB9XG5cbiAgICByZXR1cm4gd3JhcFRhZyhuYW1lLCBzZXJpYWxpemVkUHJvcGVydGllcywgYXR0cnMpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0SW5maW5pdGVMb29wTWVzc2FnZSAobmFtZSwgbG9vcFRvKSB7XG4gICAgcmV0dXJuIHdyYXBUYWcobmFtZSwgJzwhLS0gSW5maW5pdGUgbG9vcCAkcmVmOicgKyBsb29wVG8gKyAnIC0tPicpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0RXJyb3JNZXNzYWdlIChkZXRhaWxzKSB7XG4gICAgZGV0YWlscyA9IGRldGFpbHMgPyAnOiAnICsgZGV0YWlscyA6ICcnO1xuICAgIHJldHVybiAnPCEtLSBpbnZhbGlkIFhNTCcgKyBkZXRhaWxzICsgJyAtLT4nO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlU2NoZW1hWE1MIChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZykge1xuICAgIHZhciAkcmVmID0gXy5pc09iamVjdChkZWZpbml0aW9uKSA/IGRlZmluaXRpb24uJHJlZiA6IG51bGw7XG4gICAgdmFyIG91dHB1dCwgaW5kZXg7XG4gICAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xuICAgIGNvbmZpZy5tb2RlbHNUb0lnbm9yZSA9IGNvbmZpZy5tb2RlbHNUb0lnbm9yZSB8fCBbXTtcbiAgIFxuICAgIHZhciBkZXNjcmlwdG9yID0gXy5pc1N0cmluZygkcmVmKSA/IGdldERlc2NyaXB0b3JCeVJlZigkcmVmLCBuYW1lLCBtb2RlbHMsIGNvbmZpZylcbiAgICAgICAgOiBnZXREZXNjcmlwdG9yKG5hbWUsIGRlZmluaXRpb24sIG1vZGVscywgY29uZmlnKTtcbiAgICBcbiAgICBpZiAoIWRlc2NyaXB0b3IpIHtcbiAgICAgIHJldHVybiBnZXRFcnJvck1lc3NhZ2UoKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGRlc2NyaXB0b3IudHlwZSkge1xuICAgICAgY2FzZSAnYXJyYXknOlxuICAgICAgICBvdXRwdXQgPSBjcmVhdGVBcnJheVhNTChkZXNjcmlwdG9yKTsgYnJlYWs7XG4gICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICBvdXRwdXQgPSBjcmVhdGVPYmplY3RYTUwoZGVzY3JpcHRvcik7IGJyZWFrO1xuICAgICAgY2FzZSAnbG9vcCc6XG4gICAgICAgIG91dHB1dCA9IGdldEluZmluaXRlTG9vcE1lc3NhZ2UoZGVzY3JpcHRvci5uYW1lLCBkZXNjcmlwdG9yLmNvbmZpZy5sb29wVG8pOyBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIG91dHB1dCA9IGNyZWF0ZVByaW1pdGl2ZVhNTChkZXNjcmlwdG9yKTtcbiAgICB9XG5cbiAgICBpZiAoJHJlZiAmJiBkZXNjcmlwdG9yLnR5cGUgIT09ICdsb29wJykge1xuICAgICAgaW5kZXggPSBjb25maWcubW9kZWxzVG9JZ25vcmUuaW5kZXhPZigkcmVmKTtcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgIGNvbmZpZy5tb2RlbHNUb0lnbm9yZS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxuICBmdW5jdGlvbiBEZXNjcmlwdG9yIChuYW1lLCB0eXBlLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgfVxuICAgIHRoaXMuY29uZmlnID0gY29uZmlnIHx8IHt9O1xuICAgIHRoaXMuY29uZmlnLm1vZGVsc1RvSWdub3JlID0gdGhpcy5jb25maWcubW9kZWxzVG9JZ25vcmUgfHwgW107XG4gICAgLy8gbmFtZSBpcyBhbHJlYWR5IHNldCBieSBnZXREZXNjcmlwdG9yQnlSZWYgb3IgZ2V0RGVzY3JpcHRvciBmdW5jdGlvbiBkZXBlbmRpbmcgb24gdGhlIHR5cGUuIE9ubHkgcHJlZml4LCBpZiBwcmVzZW50IGlzIG5lZWRlZCB0byBiZSBzZXQgaGVyZSB8IGh0dHBzOi8vZ2l0aHViLmNvbS9zd2FnZ2VyLWFwaS9zd2FnZ2VyLXVpL2lzc3Vlcy8yNTc3XG4gICAgdGhpcy5uYW1lID0gZ2V0UHJlZml4KG5hbWUsIGRlZmluaXRpb24ueG1sKTtcbiAgICB0aGlzLmRlZmluaXRpb24gPSBkZWZpbml0aW9uO1xuICAgIHRoaXMubW9kZWxzID0gbW9kZWxzO1xuICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gIH1cblxuICBmdW5jdGlvbiBnZXREZXNjcmlwdG9yQnlSZWYoJHJlZiwgbmFtZSwgbW9kZWxzLCBjb25maWcpIHtcbiAgICB2YXIgbW9kZWxUeXBlID0gc2ltcGxlUmVmKCRyZWYpO1xuICAgIHZhciBtb2RlbCA9IG1vZGVsc1ttb2RlbFR5cGVdIHx8IHt9O1xuICAgIHZhciB0eXBlID0gbW9kZWwuZGVmaW5pdGlvbiAmJiBtb2RlbC5kZWZpbml0aW9uLnR5cGUgPyBtb2RlbC5kZWZpbml0aW9uLnR5cGUgOiAnb2JqZWN0JztcbiAgICAvLyBJZiBtb2RlbCBkZWZpbml0aW9uIHhtbCBuYW1lIGlzIHByZXNlbnQsIHRoZW4gdGhhdCB3aWxsIGJlIHByZWZlcnJlZCBvdmVyIG1vZGVsIG5hbWUuIFRoaXMgaXMgdGhlIGNhc2Ugb2YgcHJlZmVycmluZyBYbWxFbGVtZW50IG5hbWUgb3ZlciBYbWxSb290RWxlbWVudCBuYW1lIGlmIFhtbEVsZW1lbnQgbmFtZSBpcyBwcm92aWRlZCB8IGh0dHBzOi8vZ2l0aHViLmNvbS9zd2FnZ2VyLWFwaS9zd2FnZ2VyLXVpL2lzc3Vlcy8yNTc3XG4gICAgaWYobW9kZWwuZGVmaW5pdGlvbiAmJiBtb2RlbC5kZWZpbml0aW9uLnhtbCAmJiBtb2RlbC5kZWZpbml0aW9uLnhtbC5uYW1lKSB7XG4gICAgICAgIG5hbWUgPSBuYW1lIHx8IG1vZGVsLmRlZmluaXRpb24ueG1sLm5hbWUgfHwgbW9kZWwubmFtZTtcbiAgICB9XG4gICAgLy8gZWxzZSBvbmx5IG1vZGVsIG5hbWUgd2lsbCBiZSBjb25zaWRlcmVkIGZvciBkZXRlcm1pbmF0aW9uIHwgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItdWkvaXNzdWVzLzI1NzdcbiAgICBlbHNlIHtcbiAgICAgICAgbmFtZSA9IG5hbWUgfHwgbW9kZWwubmFtZTtcbiAgICB9XG4gICAgXG4gICAgaWYgKGNvbmZpZy5tb2RlbHNUb0lnbm9yZS5pbmRleE9mKCRyZWYpID4gLTEpIHtcbiAgICAgIHR5cGUgPSAnbG9vcCc7XG4gICAgICBjb25maWcubG9vcFRvID0gbW9kZWxUeXBlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25maWcubW9kZWxzVG9JZ25vcmUucHVzaCgkcmVmKTtcbiAgICB9XG5cbiAgICBpZiAoIW1vZGVsLmRlZmluaXRpb24pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERlc2NyaXB0b3IobmFtZSwgdHlwZSwgbW9kZWwuZGVmaW5pdGlvbiwgbW9kZWxzLCBjb25maWcpOyAgICBcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldERlc2NyaXB0b3IgKG5hbWUsIGRlZmluaXRpb24sIG1vZGVscywgY29uZmlnKXtcbiAgICB2YXIgdHlwZSA9IGRlZmluaXRpb24udHlwZSB8fCAnb2JqZWN0JztcbiAgICAvLyBJZiBkZWZpbml0aW9uIHhtbCBuYW1lIGlzIHByZXNlbnQsIHRoZW4gdGhhdCB3aWxsIGJlIHByZWZlcnJlZCBvdmVyIG5hbWUgfCBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci11aS9pc3N1ZXMvMjU3N1xuICAgIGlmKGRlZmluaXRpb24ueG1sICYmIGRlZmluaXRpb24ueG1sLm5hbWUpIHtcbiAgICAgICAgbmFtZSA9IGRlZmluaXRpb24ueG1sLm5hbWUgfHwgbmFtZTtcbiAgICB9XG4gICAgaWYgKCFkZWZpbml0aW9uKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IERlc2NyaXB0b3IobmFtZSwgdHlwZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBjb25maWcpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlWE1MU2FtcGxlIChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGlzUGFyYW0pIHtcbiAgICB2YXIgcHJvbG9nID0gJzw/eG1sIHZlcnNpb249XCIxLjBcIj8+JztcblxuICAgIHJldHVybiBmb3JtYXRYbWwocHJvbG9nICsgY3JlYXRlU2NoZW1hWE1MKG5hbWUsIGRlZmluaXRpb24sIG1vZGVscywgeyBpc1BhcmFtOiBpc1BhcmFtIH0gKSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgICAgZ2V0TW9kZWxTaWduYXR1cmU6IGdldE1vZGVsU2lnbmF0dXJlLFxuICAgICAgY3JlYXRlSlNPTlNhbXBsZTogY3JlYXRlSlNPTlNhbXBsZSxcbiAgICAgIGdldFBhcmFtZXRlck1vZGVsU2lnbmF0dXJlOiBnZXRQYXJhbWV0ZXJNb2RlbFNpZ25hdHVyZSxcbiAgICAgIGNyZWF0ZVBhcmFtZXRlckpTT05TYW1wbGU6IGNyZWF0ZVBhcmFtZXRlckpTT05TYW1wbGUsXG4gICAgICBjcmVhdGVTY2hlbWFYTUw6IGNyZWF0ZVNjaGVtYVhNTCxcbiAgICAgIGNyZWF0ZVhNTFNhbXBsZTogY3JlYXRlWE1MU2FtcGxlLFxuICAgICAgZ2V0UHJpbWl0aXZlU2lnbmF0dXJlOiBnZXRQcmltaXRpdmVTaWduYXR1cmVcbiAgfTtcblxufSkoKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLlBvcHVwVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgICBldmVudHM6IHtcbiAgICAgICAgJ2NsaWNrIC5hcGktcG9wdXAtY2FuY2VsJzogJ2NhbmNlbENsaWNrJ1xuICAgIH0sXG5cbiAgICB0ZW1wbGF0ZTogSGFuZGxlYmFycy50ZW1wbGF0ZXMucG9wdXAsXG4gICAgY2xhc3NOYW1lOiAnYXBpLXBvcHVwLWRpYWxvZycsXG5cbiAgICBzZWxlY3RvcnM6IHtcbiAgICAgICAgY29udGVudDogJy5hcGktcG9wdXAtY29udGVudCcsXG4gICAgICAgIG1haW4gICA6ICcjc3dhZ2dlci11aS1jb250YWluZXInXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCl7XG4gICAgICAgIHRoaXMuJGVsLmh0bWwodGhpcy50ZW1wbGF0ZSh0aGlzLm1vZGVsKSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLiQodGhpcy5zZWxlY3RvcnMuY29udGVudCkuYXBwZW5kKHRoaXMubW9kZWwuY29udGVudCk7XG4gICAgICAgICQodGhpcy5zZWxlY3RvcnMubWFpbikuZmlyc3QoKS5hcHBlbmQodGhpcy5lbCk7XG4gICAgICAgIHRoaXMuc2hvd1BvcHVwKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIHNob3dQb3B1cDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLiRlbC5zaG93KCk7XG4gICAgfSxcblxuICAgIGNhbmNlbENsaWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlKCk7XG4gICAgfVxuXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLlJlc291cmNlVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ob3B0cykge1xuICAgIG9wdHMgPSBvcHRzIHx8IHt9O1xuICAgIHRoaXMucm91dGVyID0gb3B0cy5yb3V0ZXI7XG4gICAgdGhpcy5hdXRocyA9IG9wdHMuYXV0aHM7XG4gICAgaWYgKCcnID09PSB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKHRoaXMubW9kZWwuZGVzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMubW9kZWwuc3VtbWFyeSA9IHRoaXMubW9kZWwuZGVzY3JpcHRpb247XG4gICAgfVxuICAgIHRoaXMubnVtYmVyID0gMDtcbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgdmFyIG1ldGhvZHMgPSB7fTtcblxuXG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLnJlc291cmNlKHRoaXMubW9kZWwpKTtcblxuICAgIC8vIFJlbmRlciBlYWNoIG9wZXJhdGlvblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb2RlbC5vcGVyYXRpb25zQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBvcGVyYXRpb24gPSB0aGlzLm1vZGVsLm9wZXJhdGlvbnNBcnJheVtpXTtcbiAgICAgIHZhciBjb3VudGVyID0gMDtcbiAgICAgIHZhciBpZCA9IG9wZXJhdGlvbi5uaWNrbmFtZTtcblxuICAgICAgd2hpbGUgKHR5cGVvZiBtZXRob2RzW2lkXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWQgPSBpZCArICdfJyArIGNvdW50ZXI7XG4gICAgICAgIGNvdW50ZXIgKz0gMTtcbiAgICAgIH1cblxuICAgICAgbWV0aG9kc1tpZF0gPSBvcGVyYXRpb247XG5cbiAgICAgIG9wZXJhdGlvbi5uaWNrbmFtZSA9IGlkO1xuICAgICAgb3BlcmF0aW9uLnBhcmVudElkID0gdGhpcy5tb2RlbC5pZDtcbiAgICAgIG9wZXJhdGlvbi5kZWZpbml0aW9ucyA9IHRoaXMubW9kZWwuZGVmaW5pdGlvbnM7IC8vIG1ha2UgSnNvbiBTY2hlbWEgYXZhaWxhYmxlIGZvciBKU29uRWRpdG9yIGluIHRoaXMgb3BlcmF0aW9uXG4gICAgICB0aGlzLmFkZE9wZXJhdGlvbihvcGVyYXRpb24pO1xuICAgIH1cblxuICAgICQoJy50b2dnbGVFbmRwb2ludExpc3QnLCB0aGlzLmVsKS5jbGljayh0aGlzLmNhbGxEb2NzLmJpbmQodGhpcywgJ3RvZ2dsZUVuZHBvaW50TGlzdEZvclJlc291cmNlJykpO1xuICAgICQoJy5jb2xsYXBzZVJlc291cmNlJywgdGhpcy5lbCkuY2xpY2sodGhpcy5jYWxsRG9jcy5iaW5kKHRoaXMsICdjb2xsYXBzZU9wZXJhdGlvbnNGb3JSZXNvdXJjZScpKTtcbiAgICAkKCcuZXhwYW5kUmVzb3VyY2UnLCB0aGlzLmVsKS5jbGljayh0aGlzLmNhbGxEb2NzLmJpbmQodGhpcywgJ2V4cGFuZE9wZXJhdGlvbnNGb3JSZXNvdXJjZScpKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIGFkZE9wZXJhdGlvbjogZnVuY3Rpb24ob3BlcmF0aW9uKSB7XG5cbiAgICBvcGVyYXRpb24ubnVtYmVyID0gdGhpcy5udW1iZXI7XG5cbiAgICAvLyBSZW5kZXIgYW4gb3BlcmF0aW9uIGFuZCBhZGQgaXQgdG8gb3BlcmF0aW9ucyBsaVxuICAgIHZhciBvcGVyYXRpb25WaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5PcGVyYXRpb25WaWV3KHtcbiAgICAgIG1vZGVsOiBvcGVyYXRpb24sXG4gICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgdGFnTmFtZTogJ2xpJyxcbiAgICAgIGNsYXNzTmFtZTogJ2VuZHBvaW50JyxcbiAgICAgIHN3YWdnZXJPcHRpb25zOiB0aGlzLm9wdGlvbnMuc3dhZ2dlck9wdGlvbnMsXG4gICAgICBhdXRoczogdGhpcy5hdXRoc1xuICAgIH0pO1xuXG4gICAgJCgnLmVuZHBvaW50cycsICQodGhpcy5lbCkpLmFwcGVuZChvcGVyYXRpb25WaWV3LnJlbmRlcigpLmVsKTtcblxuICAgIHRoaXMubnVtYmVyKys7XG5cbiAgfSxcbiAgLy8gR2VuZXJpYyBFdmVudCBoYW5kbGVyIChgRG9jc2AgaXMgZ2xvYmFsKVxuXG5cbiAgY2FsbERvY3M6IGZ1bmN0aW9uKGZuTmFtZSwgZSkge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBEb2NzW2ZuTmFtZV0oZS5jdXJyZW50VGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5SZXNwb25zZUNvbnRlbnRUeXBlVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXt9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24oKXtcbiAgICB0aGlzLm1vZGVsLnJlc3BvbnNlQ29udGVudFR5cGVJZCA9ICdyY3QnICsgTWF0aC5yYW5kb20oKTtcbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMucmVzcG9uc2VfY29udGVudF90eXBlKHRoaXMubW9kZWwpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuU2lnbmF0dXJlVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgZXZlbnRzOiB7XG4gICAgJ2NsaWNrIGEuZGVzY3JpcHRpb24tbGluaycgICAgICAgOiAnc3dpdGNoVG9EZXNjcmlwdGlvbicsXG4gICAgJ2NsaWNrIGEuc25pcHBldC1saW5rJyAgICAgICAgICAgOiAnc3dpdGNoVG9TbmlwcGV0JyxcbiAgICAnbW91c2Vkb3duIC5zbmlwcGV0X2pzb24nICAgICAgICAgIDogJ2pzb25TbmlwcGV0TW91c2VEb3duJyxcbiAgICAnbW91c2Vkb3duIC5zbmlwcGV0X3htbCcgICAgICAgICAgOiAneG1sU25pcHBldE1vdXNlRG93bidcbiAgfSxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gIH0sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuXG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLnNpZ25hdHVyZSh0aGlzLm1vZGVsKSk7XG5cbiAgICBpZiAodGhpcy5tb2RlbC5kZWZhdWx0UmVuZGVyaW5nID09PSAnbW9kZWwnKSB7XG4gICAgICB0aGlzLnN3aXRjaFRvRGVzY3JpcHRpb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zd2l0Y2hUb1NuaXBwZXQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICAvLyBoYW5kbGVyIGZvciBzaG93IHNpZ25hdHVyZVxuICBzd2l0Y2hUb0Rlc2NyaXB0aW9uOiBmdW5jdGlvbihlKXtcbiAgICBpZiAoZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH1cblxuICAgICQoJy5zbmlwcGV0JywgJCh0aGlzLmVsKSkuaGlkZSgpO1xuICAgICQoJy5kZXNjcmlwdGlvbicsICQodGhpcy5lbCkpLnNob3coKTtcbiAgICAkKCcuZGVzY3JpcHRpb24tbGluaycsICQodGhpcy5lbCkpLmFkZENsYXNzKCdzZWxlY3RlZCcpO1xuICAgICQoJy5zbmlwcGV0LWxpbmsnLCAkKHRoaXMuZWwpKS5yZW1vdmVDbGFzcygnc2VsZWN0ZWQnKTtcbiAgfSxcblxuICAvLyBoYW5kbGVyIGZvciBzaG93IHNhbXBsZVxuICBzd2l0Y2hUb1NuaXBwZXQ6IGZ1bmN0aW9uKGUpe1xuICAgIGlmIChlKSB7IGUucHJldmVudERlZmF1bHQoKTsgfVxuXG4gICAgJCgnLnNuaXBwZXQnLCAkKHRoaXMuZWwpKS5zaG93KCk7XG4gICAgJCgnLmRlc2NyaXB0aW9uJywgJCh0aGlzLmVsKSkuaGlkZSgpO1xuICAgICQoJy5zbmlwcGV0LWxpbmsnLCAkKHRoaXMuZWwpKS5hZGRDbGFzcygnc2VsZWN0ZWQnKTtcbiAgICAkKCcuZGVzY3JpcHRpb24tbGluaycsICQodGhpcy5lbCkpLnJlbW92ZUNsYXNzKCdzZWxlY3RlZCcpO1xuICB9LFxuXG4gIC8vIGhhbmRsZXIgZm9yIHNuaXBwZXQgdG8gdGV4dCBhcmVhXG4gIHNuaXBwZXRUb1RleHRBcmVhOiBmdW5jdGlvbih2YWwpIHtcbiAgICB2YXIgdGV4dEFyZWEgPSAkKCd0ZXh0YXJlYScsICQodGhpcy5lbC5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZSkpO1xuXG4gICAgLy8gRml4IGZvciBidWcgaW4gSUUgMTAvMTEgd2hpY2ggY2F1c2VzIHBsYWNlaG9sZGVyIHRleHQgdG8gYmUgY29waWVkIHRvIFwidmFsdWVcIlxuICAgIGlmICgkLnRyaW0odGV4dEFyZWEudmFsKCkpID09PSAnJyB8fCB0ZXh0QXJlYS5wcm9wKCdwbGFjZWhvbGRlcicpID09PSB0ZXh0QXJlYS52YWwoKSkge1xuICAgICAgdGV4dEFyZWEudmFsKHZhbCk7XG4gICAgICAvLyBUT0RPIG1vdmUgdGhpcyBjb2RlIG91dHNpZGUgb2YgdGhlIHZpZXcgYW5kIGV4cG9zZSBhbiBldmVudCBpbnN0ZWFkXG4gICAgICBpZiggdGhpcy5tb2RlbC5qc29uRWRpdG9yICYmIHRoaXMubW9kZWwuanNvbkVkaXRvci5pc0VuYWJsZWQoKSl7XG4gICAgICAgIHRoaXMubW9kZWwuanNvbkVkaXRvci5zZXRWYWx1ZShKU09OLnBhcnNlKHRoaXMubW9kZWwuc2FtcGxlSlNPTikpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBqc29uU25pcHBldE1vdXNlRG93bjogZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAodGhpcy5tb2RlbC5pc1BhcmFtKSB7XG4gICAgICBpZiAoZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH1cblxuICAgICAgdGhpcy5zbmlwcGV0VG9UZXh0QXJlYSh0aGlzLm1vZGVsLnNhbXBsZUpTT04pO1xuICAgIH1cbiAgfSxcblxuICB4bWxTbmlwcGV0TW91c2VEb3duOiBmdW5jdGlvbiAoZSkge1xuICAgIGlmICh0aGlzLm1vZGVsLmlzUGFyYW0pIHtcbiAgICAgIGlmIChlKSB7IGUucHJldmVudERlZmF1bHQoKTsgfVxuXG4gICAgICB0aGlzLnNuaXBwZXRUb1RleHRBcmVhKHRoaXMubW9kZWwuc2FtcGxlWE1MKTtcbiAgICB9XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLlN0YXR1c0NvZGVWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbiAob3B0cykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdHMgfHwge307XG4gICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuICB9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24oKXtcbiAgICB2YXIgcmVzcG9uc2VNb2RlbCwgcmVzcG9uc2VNb2RlbFZpZXc7XG4gICAgdmFyIHZhbHVlID0gdGhpcy5yb3V0ZXIuYXBpLm1vZGVsc1t0aGlzLm1vZGVsLnJlc3BvbnNlTW9kZWxdO1xuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5zdGF0dXNfY29kZSh0aGlzLm1vZGVsKSk7XG5cbiAgICBpZiAodGhpcy5yb3V0ZXIuYXBpLm1vZGVscy5oYXNPd25Qcm9wZXJ0eSh0aGlzLm1vZGVsLnJlc3BvbnNlTW9kZWwpKSB7XG4gICAgICByZXNwb25zZU1vZGVsID0ge1xuICAgICAgICBzYW1wbGVKU09OOiBKU09OLnN0cmluZ2lmeShTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmNyZWF0ZUpTT05TYW1wbGUodmFsdWUpLCB2b2lkIDAsIDIpLFxuICAgICAgICBzYW1wbGVYTUw6IHRoaXMubW9kZWwuaXNYTUwgPyBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmNyZWF0ZVhNTFNhbXBsZSgnJywgdGhpcy5tb2RlbC5zY2hlbWEsIHRoaXMucm91dGVyLmFwaS5tb2RlbHMpIDogZmFsc2UsXG4gICAgICAgIGlzUGFyYW06IGZhbHNlLFxuICAgICAgICBzaWduYXR1cmU6IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuZ2V0TW9kZWxTaWduYXR1cmUodGhpcy5tb2RlbC5yZXNwb25zZU1vZGVsLCB2YWx1ZSwgdGhpcy5yb3V0ZXIuYXBpLm1vZGVscyksXG4gICAgICAgIGRlZmF1bHRSZW5kZXJpbmc6IHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZ1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzcG9uc2VNb2RlbCA9IHtcbiAgICAgICAgc2lnbmF0dXJlOiBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmdldFByaW1pdGl2ZVNpZ25hdHVyZSh0aGlzLm1vZGVsLnNjaGVtYSlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmVzcG9uc2VNb2RlbFZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlNpZ25hdHVyZVZpZXcoe21vZGVsOiByZXNwb25zZU1vZGVsLCB0YWdOYW1lOiAnZGl2J30pO1xuICAgICQoJy5tb2RlbC1zaWduYXR1cmUnLCB0aGlzLiRlbCkuYXBwZW5kKHJlc3BvbnNlTW9kZWxWaWV3LnJlbmRlcigpLmVsKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufSk7Il19 |