Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 1 | /** |
| 2 | * 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 |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3 | * @version v2.1.5 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4 | * @link http://swagger.io |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5 | * @license Apache-2.0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6 | */ |
| 7 | (function(){this["Handlebars"] = this["Handlebars"] || {}; |
| 8 | this["Handlebars"]["templates"] = this["Handlebars"]["templates"] || {}; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9 | this["Handlebars"]["templates"]["apikey_auth"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11 | return " <span class=\"key_auth__value\">" |
| 12 | + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper))) |
| 13 | + "</span>\n"; |
| 14 | },"3":function(depth0,helpers,partials,data) { |
| 15 | return " <input placeholder=\"api_key\" class=\"auth_input input_apiKey_entry\" name=\"apiKey\" type=\"text\"/>\n"; |
| 16 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 17 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class=\"key_input_container\">\n <h3 class=\"auth__title\">Api key authorization</h3>\n <div class=\"auth__description\">" |
| 18 | + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper))) |
| 19 | + "</div>\n <div>\n <div class=\"key_auth__field\">\n <span class=\"key_auth__label\">name:</span>\n <span class=\"key_auth__value\">" |
| 20 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 21 | + "</span>\n </div>\n <div class=\"key_auth__field\">\n <span class=\"key_auth__label\">in:</span>\n <span class=\"key_auth__value\">" |
| 22 | + escapeExpression(((helper = (helper = helpers['in'] || (depth0 != null ? depth0['in'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"in","hash":{},"data":data}) : helper))) |
| 23 | + "</span>\n </div>\n <div class=\"key_auth__field\">\n <span class=\"key_auth__label\">value:</span>\n"; |
| 24 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data}); |
| 25 | if (stack1 != null) { buffer += stack1; } |
| 26 | return buffer + " </div>\n </div>\n</div>\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 27 | },"useData":true}); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 28 | this["Handlebars"]["templates"]["auth_button_operation"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 29 | return " authorize__btn_operation_login\n"; |
| 30 | },"3":function(depth0,helpers,partials,data) { |
| 31 | return " authorize__btn_operation_logout\n"; |
| 32 | },"5":function(depth0,helpers,partials,data) { |
| 33 | var stack1, buffer = " <ul class=\"authorize-scopes\">\n"; |
| 34 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.scopes : depth0), {"name":"each","hash":{},"fn":this.program(6, data),"inverse":this.noop,"data":data}); |
| 35 | if (stack1 != null) { buffer += stack1; } |
| 36 | return buffer + " </ul>\n"; |
| 37 | },"6":function(depth0,helpers,partials,data) { |
| 38 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 39 | return " <li class=\"authorize__scope\" title=\"" |
| 40 | + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper))) |
| 41 | + "\">" |
| 42 | + escapeExpression(((helper = (helper = helpers.scope || (depth0 != null ? depth0.scope : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"scope","hash":{},"data":data}) : helper))) |
| 43 | + "</li>\n"; |
| 44 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 45 | var stack1, buffer = "<div class=\"authorize__btn authorize__btn_operation\n"; |
| 46 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data}); |
| 47 | if (stack1 != null) { buffer += stack1; } |
| 48 | buffer += "\">\n"; |
| 49 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.scopes : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data}); |
| 50 | if (stack1 != null) { buffer += stack1; } |
| 51 | return buffer + "</div>\n"; |
| 52 | },"useData":true}); |
| 53 | this["Handlebars"]["templates"]["auth_button"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 54 | return "<a class='authorize__btn' href=\"#\">Authorize</a>\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 55 | },"useData":true}); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 56 | this["Handlebars"]["templates"]["auth_view"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 57 | return " <button type=\"button\" class=\"auth__button auth_submit__button\" data-sw-translate>Authorize</button>\n"; |
| 58 | },"3":function(depth0,helpers,partials,data) { |
| 59 | return " <button type=\"button\" class=\"auth__button auth_logout__button\" data-sw-translate>Logout</button>\n"; |
| 60 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 61 | var stack1, buffer = "<div class=\"auth_container\">\n\n <div class=\"auth_inner\"></div>\n <div class=\"auth_submit\">\n"; |
| 62 | stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"unless","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 63 | if (stack1 != null) { buffer += stack1; } |
| 64 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isAuthorized : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data}); |
| 65 | if (stack1 != null) { buffer += stack1; } |
| 66 | return buffer + " </div>\n\n</div>\n"; |
| 67 | },"useData":true}); |
| 68 | this["Handlebars"]["templates"]["basic_auth"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 69 | return " - authorized"; |
| 70 | },"3":function(depth0,helpers,partials,data) { |
| 71 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 72 | return " <span class=\"basic_auth__value\">" |
| 73 | + escapeExpression(((helper = (helper = helpers.username || (depth0 != null ? depth0.username : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"username","hash":{},"data":data}) : helper))) |
| 74 | + "</span>\n"; |
| 75 | },"5":function(depth0,helpers,partials,data) { |
| 76 | return " <input required placeholder=\"username\" class=\"basic_auth__username auth_input\" name=\"username\" type=\"text\"/>\n"; |
| 77 | },"7":function(depth0,helpers,partials,data) { |
| 78 | 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"; |
| 79 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 80 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class='basic_auth_container'>\n <h3 class=\"auth__title\">Basic authentication"; |
| 81 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 82 | if (stack1 != null) { buffer += stack1; } |
| 83 | buffer += "</h3>\n <form class=\"basic_input_container\">\n <div class=\"auth__description\">" |
| 84 | + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper))) |
| 85 | + "</div>\n <div class=\"auth_label\">\n <span class=\"basic_auth__label\" data-sw-translate>username:</span>\n"; |
| 86 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.program(5, data),"data":data}); |
| 87 | if (stack1 != null) { buffer += stack1; } |
| 88 | buffer += " </div>\n"; |
| 89 | stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"unless","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data}); |
| 90 | if (stack1 != null) { buffer += stack1; } |
| 91 | return buffer + " </form>\n</div>\n"; |
| 92 | },"useData":true}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 93 | this["Handlebars"]["templates"]["content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 94 | var stack1, buffer = ""; |
| 95 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); |
| 96 | if (stack1 != null) { buffer += stack1; } |
| 97 | return buffer; |
| 98 | },"2":function(depth0,helpers,partials,data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 99 | var lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 100 | return " <option value=\"" |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 101 | + escapeExpression(lambda(depth0, depth0)) |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 102 | + "\">" |
| 103 | + escapeExpression(lambda(depth0, depth0)) |
| 104 | + "</option>\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 105 | },"4":function(depth0,helpers,partials,data) { |
| 106 | return " <option value=\"application/json\">application/json</option>\n"; |
| 107 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 108 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label data-sw-translate for=\"" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 109 | + escapeExpression(((helper = (helper = helpers.contentTypeId || (depth0 != null ? depth0.contentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"contentTypeId","hash":{},"data":data}) : helper))) |
| 110 | + "\">Response Content Type</label>\n<select name=\"contentType\" id=\"" |
| 111 | + escapeExpression(((helper = (helper = helpers.contentTypeId || (depth0 != null ? depth0.contentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"contentTypeId","hash":{},"data":data}) : helper))) |
| 112 | + "\">\n"; |
| 113 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(4, data),"data":data}); |
| 114 | if (stack1 != null) { buffer += stack1; } |
| 115 | return buffer + "</select>\n"; |
| 116 | },"useData":true}); |
| 117 | 'use strict'; |
| 118 | |
| 119 | |
| 120 | $(function() { |
| 121 | |
| 122 | // Helper function for vertically aligning DOM elements |
| 123 | // http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/ |
| 124 | $.fn.vAlign = function() { |
| 125 | return this.each(function(){ |
| 126 | var ah = $(this).height(); |
| 127 | var ph = $(this).parent().height(); |
| 128 | var mh = (ph - ah) / 2; |
| 129 | $(this).css('margin-top', mh); |
| 130 | }); |
| 131 | }; |
| 132 | |
| 133 | $.fn.stretchFormtasticInputWidthToParent = function() { |
| 134 | return this.each(function(){ |
| 135 | var p_width = $(this).closest("form").innerWidth(); |
| 136 | var p_padding = parseInt($(this).closest("form").css('padding-left') ,10) + parseInt($(this).closest('form').css('padding-right'), 10); |
| 137 | var this_padding = parseInt($(this).css('padding-left'), 10) + parseInt($(this).css('padding-right'), 10); |
| 138 | $(this).css('width', p_width - p_padding - this_padding); |
| 139 | }); |
| 140 | }; |
| 141 | |
| 142 | $('form.formtastic li.string input, form.formtastic textarea').stretchFormtasticInputWidthToParent(); |
| 143 | |
| 144 | // Vertically center these paragraphs |
| 145 | // Parent may need a min-height for this to work.. |
| 146 | $('ul.downplayed li div.content p').vAlign(); |
| 147 | |
| 148 | // When a sandbox form is submitted.. |
| 149 | $("form.sandbox").submit(function(){ |
| 150 | |
| 151 | var error_free = true; |
| 152 | |
| 153 | // Cycle through the forms required inputs |
| 154 | $(this).find("input.required").each(function() { |
| 155 | |
| 156 | // Remove any existing error styles from the input |
| 157 | $(this).removeClass('error'); |
| 158 | |
| 159 | // Tack the error style on if the input is empty.. |
| 160 | if ($(this).val() === '') { |
| 161 | $(this).addClass('error'); |
| 162 | $(this).wiggle(); |
| 163 | error_free = false; |
| 164 | } |
| 165 | |
| 166 | }); |
| 167 | |
| 168 | return error_free; |
| 169 | }); |
| 170 | |
| 171 | }); |
| 172 | |
| 173 | function clippyCopiedCallback() { |
| 174 | $('#api_key_copied').fadeIn().delay(1000).fadeOut(); |
| 175 | |
| 176 | // var b = $("#clippy_tooltip_" + a); |
| 177 | // b.length != 0 && (b.attr("title", "copied!").trigger("tipsy.reload"), setTimeout(function() { |
| 178 | // b.attr("title", "copy to clipboard") |
| 179 | // }, |
| 180 | // 500)) |
| 181 | } |
| 182 | |
| 183 | // Logging function that accounts for browsers that don't have window.console |
| 184 | function log(){ |
| 185 | log.history = log.history || []; |
| 186 | log.history.push(arguments); |
| 187 | if(this.console){ |
| 188 | console.log( Array.prototype.slice.call(arguments)[0] ); |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | // Handle browsers that do console incorrectly (IE9 and below, see http://stackoverflow.com/a/5539378/7913) |
| 193 | if (Function.prototype.bind && console && typeof console.log === "object") { |
| 194 | [ |
| 195 | "log","info","warn","error","assert","dir","clear","profile","profileEnd" |
| 196 | ].forEach(function (method) { |
| 197 | console[method] = this.bind(console[method], console); |
| 198 | }, Function.prototype.call); |
| 199 | } |
| 200 | |
| 201 | window.Docs = { |
| 202 | |
| 203 | shebang: function() { |
| 204 | |
| 205 | // If shebang has an operation nickname in it.. |
| 206 | // e.g. /docs/#!/words/get_search |
| 207 | var fragments = $.param.fragment().split('/'); |
| 208 | fragments.shift(); // get rid of the bang |
| 209 | |
| 210 | switch (fragments.length) { |
| 211 | case 1: |
| 212 | if (fragments[0].length > 0) { // prevent matching "#/" |
| 213 | // Expand all operations for the resource and scroll to it |
| 214 | var dom_id = 'resource_' + fragments[0]; |
| 215 | |
| 216 | Docs.expandEndpointListForResource(fragments[0]); |
| 217 | $("#"+dom_id).slideto({highlight: false}); |
| 218 | } |
| 219 | break; |
| 220 | case 2: |
| 221 | // Refer to the endpoint DOM element, e.g. #words_get_search |
| 222 | |
| 223 | // Expand Resource |
| 224 | Docs.expandEndpointListForResource(fragments[0]); |
| 225 | $("#"+dom_id).slideto({highlight: false}); |
| 226 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 227 | // Expand operation |
| 228 | var li_dom_id = fragments.join('_'); |
| 229 | var li_content_dom_id = li_dom_id + "_content"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 230 | |
| 231 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 232 | Docs.expandOperation($('#'+li_content_dom_id)); |
| 233 | $('#'+li_dom_id).slideto({highlight: false}); |
| 234 | break; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 235 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 236 | }, |
| 237 | |
| 238 | toggleEndpointListForResource: function(resource) { |
| 239 | var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints'); |
| 240 | if (elem.is(':visible')) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 241 | $.bbq.pushState('#/', 2); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 242 | Docs.collapseEndpointListForResource(resource); |
| 243 | } else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 244 | $.bbq.pushState('#/' + resource, 2); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 245 | Docs.expandEndpointListForResource(resource); |
| 246 | } |
| 247 | }, |
| 248 | |
| 249 | // Expand resource |
| 250 | expandEndpointListForResource: function(resource) { |
| 251 | var resource = Docs.escapeResourceName(resource); |
| 252 | if (resource == '') { |
| 253 | $('.resource ul.endpoints').slideDown(); |
| 254 | return; |
| 255 | } |
| 256 | |
| 257 | $('li#resource_' + resource).addClass('active'); |
| 258 | |
| 259 | var elem = $('li#resource_' + resource + ' ul.endpoints'); |
| 260 | elem.slideDown(); |
| 261 | }, |
| 262 | |
| 263 | // Collapse resource and mark as explicitly closed |
| 264 | collapseEndpointListForResource: function(resource) { |
| 265 | var resource = Docs.escapeResourceName(resource); |
| 266 | if (resource == '') { |
| 267 | $('.resource ul.endpoints').slideUp(); |
| 268 | return; |
| 269 | } |
| 270 | |
| 271 | $('li#resource_' + resource).removeClass('active'); |
| 272 | |
| 273 | var elem = $('li#resource_' + resource + ' ul.endpoints'); |
| 274 | elem.slideUp(); |
| 275 | }, |
| 276 | |
| 277 | expandOperationsForResource: function(resource) { |
| 278 | // Make sure the resource container is open.. |
| 279 | Docs.expandEndpointListForResource(resource); |
| 280 | |
| 281 | if (resource == '') { |
| 282 | $('.resource ul.endpoints li.operation div.content').slideDown(); |
| 283 | return; |
| 284 | } |
| 285 | |
| 286 | $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() { |
| 287 | Docs.expandOperation($(this)); |
| 288 | }); |
| 289 | }, |
| 290 | |
| 291 | collapseOperationsForResource: function(resource) { |
| 292 | // Make sure the resource container is open.. |
| 293 | Docs.expandEndpointListForResource(resource); |
| 294 | |
| 295 | if (resource == '') { |
| 296 | $('.resource ul.endpoints li.operation div.content').slideUp(); |
| 297 | return; |
| 298 | } |
| 299 | |
| 300 | $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() { |
| 301 | Docs.collapseOperation($(this)); |
| 302 | }); |
| 303 | }, |
| 304 | |
| 305 | escapeResourceName: function(resource) { |
| 306 | return resource.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g, "\\$&"); |
| 307 | }, |
| 308 | |
| 309 | expandOperation: function(elem) { |
| 310 | elem.slideDown(); |
| 311 | }, |
| 312 | |
| 313 | collapseOperation: function(elem) { |
| 314 | elem.slideUp(); |
| 315 | } |
| 316 | }; |
| 317 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 318 | /*! |
| 319 | * https://github.com/es-shims/es5-shim |
| 320 | * @license es5-shim Copyright 2009-2015 by contributors, MIT License |
| 321 | * see https://github.com/es-shims/es5-shim/blob/master/LICENSE |
| 322 | */ |
| 323 | |
| 324 | // vim: ts=4 sts=4 sw=4 expandtab |
| 325 | |
| 326 | // Add semicolon to prevent IIFE from being passed as argument to concatenated code. |
| 327 | ; |
| 328 | |
| 329 | // UMD (Universal Module Definition) |
| 330 | // see https://github.com/umdjs/umd/blob/master/templates/returnExports.js |
| 331 | (function (root, factory) { |
| 332 | 'use strict'; |
| 333 | |
| 334 | /* global define, exports, module */ |
| 335 | if (typeof define === 'function' && define.amd) { |
| 336 | // AMD. Register as an anonymous module. |
| 337 | define(factory); |
| 338 | } else if (typeof exports === 'object') { |
| 339 | // Node. Does not work with strict CommonJS, but |
| 340 | // only CommonJS-like enviroments that support module.exports, |
| 341 | // like Node. |
| 342 | module.exports = factory(); |
| 343 | } else { |
| 344 | // Browser globals (root is window) |
| 345 | root.returnExports = factory(); |
| 346 | } |
| 347 | }(this, function () { |
| 348 | /** |
| 349 | * Brings an environment as close to ECMAScript 5 compliance |
| 350 | * as is possible with the facilities of erstwhile engines. |
| 351 | * |
| 352 | * Annotated ES5: http://es5.github.com/ (specific links below) |
| 353 | * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf |
| 354 | * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/ |
| 355 | */ |
| 356 | |
| 357 | // Shortcut to an often accessed properties, in order to avoid multiple |
| 358 | // dereference that costs universally. This also holds a reference to known-good |
| 359 | // functions. |
| 360 | var $Array = Array; |
| 361 | var ArrayPrototype = $Array.prototype; |
| 362 | var $Object = Object; |
| 363 | var ObjectPrototype = $Object.prototype; |
| 364 | var $Function = Function; |
| 365 | var FunctionPrototype = $Function.prototype; |
| 366 | var $String = String; |
| 367 | var StringPrototype = $String.prototype; |
| 368 | var $Number = Number; |
| 369 | var NumberPrototype = $Number.prototype; |
| 370 | var array_slice = ArrayPrototype.slice; |
| 371 | var array_splice = ArrayPrototype.splice; |
| 372 | var array_push = ArrayPrototype.push; |
| 373 | var array_unshift = ArrayPrototype.unshift; |
| 374 | var array_concat = ArrayPrototype.concat; |
| 375 | var array_join = ArrayPrototype.join; |
| 376 | var call = FunctionPrototype.call; |
| 377 | var apply = FunctionPrototype.apply; |
| 378 | var max = Math.max; |
| 379 | var min = Math.min; |
| 380 | |
| 381 | // Having a toString local variable name breaks in Opera so use to_string. |
| 382 | var to_string = ObjectPrototype.toString; |
| 383 | |
| 384 | /* global Symbol */ |
| 385 | /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */ |
| 386 | var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; |
| 387 | 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; }; |
| 388 | |
| 389 | 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; }; |
| 390 | 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; }; |
| 391 | /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */ |
| 392 | |
| 393 | /* inlined from http://npmjs.com/define-properties */ |
| 394 | var supportsDescriptors = $Object.defineProperty && (function () { |
| 395 | try { |
| 396 | var obj = {}; |
| 397 | $Object.defineProperty(obj, 'x', { enumerable: false, value: obj }); |
| 398 | for (var _ in obj) { // jscs:ignore disallowUnusedVariables |
| 399 | return false; |
| 400 | } |
| 401 | return obj.x === obj; |
| 402 | } catch (e) { /* this is ES3 */ |
| 403 | return false; |
| 404 | } |
| 405 | }()); |
| 406 | var defineProperties = (function (has) { |
| 407 | // Define configurable, writable, and non-enumerable props |
| 408 | // if they don't exist. |
| 409 | var defineProperty; |
| 410 | if (supportsDescriptors) { |
| 411 | defineProperty = function (object, name, method, forceAssign) { |
| 412 | if (!forceAssign && (name in object)) { |
| 413 | return; |
| 414 | } |
| 415 | $Object.defineProperty(object, name, { |
| 416 | configurable: true, |
| 417 | enumerable: false, |
| 418 | writable: true, |
| 419 | value: method |
| 420 | }); |
| 421 | }; |
| 422 | } else { |
| 423 | defineProperty = function (object, name, method, forceAssign) { |
| 424 | if (!forceAssign && (name in object)) { |
| 425 | return; |
| 426 | } |
| 427 | object[name] = method; |
| 428 | }; |
| 429 | } |
| 430 | return function defineProperties(object, map, forceAssign) { |
| 431 | for (var name in map) { |
| 432 | if (has.call(map, name)) { |
| 433 | defineProperty(object, name, map[name], forceAssign); |
| 434 | } |
| 435 | } |
| 436 | }; |
| 437 | }(ObjectPrototype.hasOwnProperty)); |
| 438 | |
| 439 | // |
| 440 | // Util |
| 441 | // ====== |
| 442 | // |
| 443 | |
| 444 | /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */ |
| 445 | var isPrimitive = function isPrimitive(input) { |
| 446 | var type = typeof input; |
| 447 | return input === null || (type !== 'object' && type !== 'function'); |
| 448 | }; |
| 449 | |
| 450 | var isActualNaN = $Number.isNaN || function isActualNaN(x) { |
| 451 | return x !== x; |
| 452 | }; |
| 453 | |
| 454 | var ES = { |
| 455 | // ES5 9.4 |
| 456 | // http://es5.github.com/#x9.4 |
| 457 | // http://jsperf.com/to-integer |
| 458 | /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */ |
| 459 | ToInteger: function ToInteger(num) { |
| 460 | var n = +num; |
| 461 | if (isActualNaN(n)) { |
| 462 | n = 0; |
| 463 | } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { |
| 464 | n = (n > 0 || -1) * Math.floor(Math.abs(n)); |
| 465 | } |
| 466 | return n; |
| 467 | }, |
| 468 | |
| 469 | /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */ |
| 470 | ToPrimitive: function ToPrimitive(input) { |
| 471 | var val, valueOf, toStr; |
| 472 | if (isPrimitive(input)) { |
| 473 | return input; |
| 474 | } |
| 475 | valueOf = input.valueOf; |
| 476 | if (isCallable(valueOf)) { |
| 477 | val = valueOf.call(input); |
| 478 | if (isPrimitive(val)) { |
| 479 | return val; |
| 480 | } |
| 481 | } |
| 482 | toStr = input.toString; |
| 483 | if (isCallable(toStr)) { |
| 484 | val = toStr.call(input); |
| 485 | if (isPrimitive(val)) { |
| 486 | return val; |
| 487 | } |
| 488 | } |
| 489 | throw new TypeError(); |
| 490 | }, |
| 491 | |
| 492 | // ES5 9.9 |
| 493 | // http://es5.github.com/#x9.9 |
| 494 | /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */ |
| 495 | ToObject: function (o) { |
| 496 | if (o == null) { // this matches both null and undefined |
| 497 | throw new TypeError("can't convert " + o + ' to object'); |
| 498 | } |
| 499 | return $Object(o); |
| 500 | }, |
| 501 | |
| 502 | /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */ |
| 503 | ToUint32: function ToUint32(x) { |
| 504 | return x >>> 0; |
| 505 | } |
| 506 | }; |
| 507 | |
| 508 | // |
| 509 | // Function |
| 510 | // ======== |
| 511 | // |
| 512 | |
| 513 | // ES-5 15.3.4.5 |
| 514 | // http://es5.github.com/#x15.3.4.5 |
| 515 | |
| 516 | var Empty = function Empty() {}; |
| 517 | |
| 518 | defineProperties(FunctionPrototype, { |
| 519 | bind: function bind(that) { // .length is 1 |
| 520 | // 1. Let Target be the this value. |
| 521 | var target = this; |
| 522 | // 2. If IsCallable(Target) is false, throw a TypeError exception. |
| 523 | if (!isCallable(target)) { |
| 524 | throw new TypeError('Function.prototype.bind called on incompatible ' + target); |
| 525 | } |
| 526 | // 3. Let A be a new (possibly empty) internal list of all of the |
| 527 | // argument values provided after thisArg (arg1, arg2 etc), in order. |
| 528 | // XXX slicedArgs will stand in for "A" if used |
| 529 | var args = array_slice.call(arguments, 1); // for normal call |
| 530 | // 4. Let F be a new native ECMAScript object. |
| 531 | // 11. Set the [[Prototype]] internal property of F to the standard |
| 532 | // built-in Function prototype object as specified in 15.3.3.1. |
| 533 | // 12. Set the [[Call]] internal property of F as described in |
| 534 | // 15.3.4.5.1. |
| 535 | // 13. Set the [[Construct]] internal property of F as described in |
| 536 | // 15.3.4.5.2. |
| 537 | // 14. Set the [[HasInstance]] internal property of F as described in |
| 538 | // 15.3.4.5.3. |
| 539 | var bound; |
| 540 | var binder = function () { |
| 541 | |
| 542 | if (this instanceof bound) { |
| 543 | // 15.3.4.5.2 [[Construct]] |
| 544 | // When the [[Construct]] internal method of a function object, |
| 545 | // F that was created using the bind function is called with a |
| 546 | // list of arguments ExtraArgs, the following steps are taken: |
| 547 | // 1. Let target be the value of F's [[TargetFunction]] |
| 548 | // internal property. |
| 549 | // 2. If target has no [[Construct]] internal method, a |
| 550 | // TypeError exception is thrown. |
| 551 | // 3. Let boundArgs be the value of F's [[BoundArgs]] internal |
| 552 | // property. |
| 553 | // 4. Let args be a new list containing the same values as the |
| 554 | // list boundArgs in the same order followed by the same |
| 555 | // values as the list ExtraArgs in the same order. |
| 556 | // 5. Return the result of calling the [[Construct]] internal |
| 557 | // method of target providing args as the arguments. |
| 558 | |
| 559 | var result = apply.call( |
| 560 | target, |
| 561 | this, |
| 562 | array_concat.call(args, array_slice.call(arguments)) |
| 563 | ); |
| 564 | if ($Object(result) === result) { |
| 565 | return result; |
| 566 | } |
| 567 | return this; |
| 568 | |
| 569 | } else { |
| 570 | // 15.3.4.5.1 [[Call]] |
| 571 | // When the [[Call]] internal method of a function object, F, |
| 572 | // which was created using the bind function is called with a |
| 573 | // this value and a list of arguments ExtraArgs, the following |
| 574 | // steps are taken: |
| 575 | // 1. Let boundArgs be the value of F's [[BoundArgs]] internal |
| 576 | // property. |
| 577 | // 2. Let boundThis be the value of F's [[BoundThis]] internal |
| 578 | // property. |
| 579 | // 3. Let target be the value of F's [[TargetFunction]] internal |
| 580 | // property. |
| 581 | // 4. Let args be a new list containing the same values as the |
| 582 | // list boundArgs in the same order followed by the same |
| 583 | // values as the list ExtraArgs in the same order. |
| 584 | // 5. Return the result of calling the [[Call]] internal method |
| 585 | // of target providing boundThis as the this value and |
| 586 | // providing args as the arguments. |
| 587 | |
| 588 | // equiv: target.call(this, ...boundArgs, ...args) |
| 589 | return apply.call( |
| 590 | target, |
| 591 | that, |
| 592 | array_concat.call(args, array_slice.call(arguments)) |
| 593 | ); |
| 594 | |
| 595 | } |
| 596 | |
| 597 | }; |
| 598 | |
| 599 | // 15. If the [[Class]] internal property of Target is "Function", then |
| 600 | // a. Let L be the length property of Target minus the length of A. |
| 601 | // b. Set the length own property of F to either 0 or L, whichever is |
| 602 | // larger. |
| 603 | // 16. Else set the length own property of F to 0. |
| 604 | |
| 605 | var boundLength = max(0, target.length - args.length); |
| 606 | |
| 607 | // 17. Set the attributes of the length own property of F to the values |
| 608 | // specified in 15.3.5.1. |
| 609 | var boundArgs = []; |
| 610 | for (var i = 0; i < boundLength; i++) { |
| 611 | array_push.call(boundArgs, '$' + i); |
| 612 | } |
| 613 | |
| 614 | // XXX Build a dynamic function with desired amount of arguments is the only |
| 615 | // way to set the length property of a function. |
| 616 | // In environments where Content Security Policies enabled (Chrome extensions, |
| 617 | // for ex.) all use of eval or Function costructor throws an exception. |
| 618 | // However in all of these environments Function.prototype.bind exists |
| 619 | // and so this code will never be executed. |
| 620 | bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder); |
| 621 | |
| 622 | if (target.prototype) { |
| 623 | Empty.prototype = target.prototype; |
| 624 | bound.prototype = new Empty(); |
| 625 | // Clean up dangling references. |
| 626 | Empty.prototype = null; |
| 627 | } |
| 628 | |
| 629 | // TODO |
| 630 | // 18. Set the [[Extensible]] internal property of F to true. |
| 631 | |
| 632 | // TODO |
| 633 | // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). |
| 634 | // 20. Call the [[DefineOwnProperty]] internal method of F with |
| 635 | // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: |
| 636 | // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and |
| 637 | // false. |
| 638 | // 21. Call the [[DefineOwnProperty]] internal method of F with |
| 639 | // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, |
| 640 | // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, |
| 641 | // and false. |
| 642 | |
| 643 | // TODO |
| 644 | // NOTE Function objects created using Function.prototype.bind do not |
| 645 | // have a prototype property or the [[Code]], [[FormalParameters]], and |
| 646 | // [[Scope]] internal properties. |
| 647 | // XXX can't delete prototype in pure-js. |
| 648 | |
| 649 | // 22. Return F. |
| 650 | return bound; |
| 651 | } |
| 652 | }); |
| 653 | |
| 654 | // _Please note: Shortcuts are defined after `Function.prototype.bind` as we |
| 655 | // use it in defining shortcuts. |
| 656 | var owns = call.bind(ObjectPrototype.hasOwnProperty); |
| 657 | var toStr = call.bind(ObjectPrototype.toString); |
| 658 | var arraySlice = call.bind(array_slice); |
| 659 | var arraySliceApply = apply.bind(array_slice); |
| 660 | var strSlice = call.bind(StringPrototype.slice); |
| 661 | var strSplit = call.bind(StringPrototype.split); |
| 662 | var strIndexOf = call.bind(StringPrototype.indexOf); |
| 663 | var pushCall = call.bind(array_push); |
| 664 | var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable); |
| 665 | var arraySort = call.bind(ArrayPrototype.sort); |
| 666 | |
| 667 | // |
| 668 | // Array |
| 669 | // ===== |
| 670 | // |
| 671 | |
| 672 | var isArray = $Array.isArray || function isArray(obj) { |
| 673 | return toStr(obj) === '[object Array]'; |
| 674 | }; |
| 675 | |
| 676 | // ES5 15.4.4.12 |
| 677 | // http://es5.github.com/#x15.4.4.13 |
| 678 | // Return len+argCount. |
| 679 | // [bugfix, ielt8] |
| 680 | // IE < 8 bug: [].unshift(0) === undefined but should be "1" |
| 681 | var hasUnshiftReturnValueBug = [].unshift(0) !== 1; |
| 682 | defineProperties(ArrayPrototype, { |
| 683 | unshift: function () { |
| 684 | array_unshift.apply(this, arguments); |
| 685 | return this.length; |
| 686 | } |
| 687 | }, hasUnshiftReturnValueBug); |
| 688 | |
| 689 | // ES5 15.4.3.2 |
| 690 | // http://es5.github.com/#x15.4.3.2 |
| 691 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray |
| 692 | defineProperties($Array, { isArray: isArray }); |
| 693 | |
| 694 | // The IsCallable() check in the Array functions |
| 695 | // has been replaced with a strict check on the |
| 696 | // internal class of the object to trap cases where |
| 697 | // the provided function was actually a regular |
| 698 | // expression literal, which in V8 and |
| 699 | // JavaScriptCore is a typeof "function". Only in |
| 700 | // V8 are regular expression literals permitted as |
| 701 | // reduce parameters, so it is desirable in the |
| 702 | // general case for the shim to match the more |
| 703 | // strict and common behavior of rejecting regular |
| 704 | // expressions. |
| 705 | |
| 706 | // ES5 15.4.4.18 |
| 707 | // http://es5.github.com/#x15.4.4.18 |
| 708 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach |
| 709 | |
| 710 | // Check failure of by-index access of string characters (IE < 9) |
| 711 | // and failure of `0 in boxedString` (Rhino) |
| 712 | var boxedString = $Object('a'); |
| 713 | var splitString = boxedString[0] !== 'a' || !(0 in boxedString); |
| 714 | |
| 715 | var properlyBoxesContext = function properlyBoxed(method) { |
| 716 | // Check node 0.6.21 bug where third parameter is not boxed |
| 717 | var properlyBoxesNonStrict = true; |
| 718 | var properlyBoxesStrict = true; |
| 719 | var threwException = false; |
| 720 | if (method) { |
| 721 | try { |
| 722 | method.call('foo', function (_, __, context) { |
| 723 | if (typeof context !== 'object') { |
| 724 | properlyBoxesNonStrict = false; |
| 725 | } |
| 726 | }); |
| 727 | |
| 728 | method.call([1], function () { |
| 729 | 'use strict'; |
| 730 | |
| 731 | properlyBoxesStrict = typeof this === 'string'; |
| 732 | }, 'x'); |
| 733 | } catch (e) { |
| 734 | threwException = true; |
| 735 | } |
| 736 | } |
| 737 | return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict; |
| 738 | }; |
| 739 | |
| 740 | defineProperties(ArrayPrototype, { |
| 741 | forEach: function forEach(callbackfn/*, thisArg*/) { |
| 742 | var object = ES.ToObject(this); |
| 743 | var self = splitString && isString(this) ? strSplit(this, '') : object; |
| 744 | var i = -1; |
| 745 | var length = ES.ToUint32(self.length); |
| 746 | var T; |
| 747 | if (arguments.length > 1) { |
| 748 | T = arguments[1]; |
| 749 | } |
| 750 | |
| 751 | // If no callback function or if callback is not a callable function |
| 752 | if (!isCallable(callbackfn)) { |
| 753 | throw new TypeError('Array.prototype.forEach callback must be a function'); |
| 754 | } |
| 755 | |
| 756 | while (++i < length) { |
| 757 | if (i in self) { |
| 758 | // Invoke the callback function with call, passing arguments: |
| 759 | // context, property value, property key, thisArg object |
| 760 | if (typeof T === 'undefined') { |
| 761 | callbackfn(self[i], i, object); |
| 762 | } else { |
| 763 | callbackfn.call(T, self[i], i, object); |
| 764 | } |
| 765 | } |
| 766 | } |
| 767 | } |
| 768 | }, !properlyBoxesContext(ArrayPrototype.forEach)); |
| 769 | |
| 770 | // ES5 15.4.4.19 |
| 771 | // http://es5.github.com/#x15.4.4.19 |
| 772 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map |
| 773 | defineProperties(ArrayPrototype, { |
| 774 | map: function map(callbackfn/*, thisArg*/) { |
| 775 | var object = ES.ToObject(this); |
| 776 | var self = splitString && isString(this) ? strSplit(this, '') : object; |
| 777 | var length = ES.ToUint32(self.length); |
| 778 | var result = $Array(length); |
| 779 | var T; |
| 780 | if (arguments.length > 1) { |
| 781 | T = arguments[1]; |
| 782 | } |
| 783 | |
| 784 | // If no callback function or if callback is not a callable function |
| 785 | if (!isCallable(callbackfn)) { |
| 786 | throw new TypeError('Array.prototype.map callback must be a function'); |
| 787 | } |
| 788 | |
| 789 | for (var i = 0; i < length; i++) { |
| 790 | if (i in self) { |
| 791 | if (typeof T === 'undefined') { |
| 792 | result[i] = callbackfn(self[i], i, object); |
| 793 | } else { |
| 794 | result[i] = callbackfn.call(T, self[i], i, object); |
| 795 | } |
| 796 | } |
| 797 | } |
| 798 | return result; |
| 799 | } |
| 800 | }, !properlyBoxesContext(ArrayPrototype.map)); |
| 801 | |
| 802 | // ES5 15.4.4.20 |
| 803 | // http://es5.github.com/#x15.4.4.20 |
| 804 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter |
| 805 | defineProperties(ArrayPrototype, { |
| 806 | filter: function filter(callbackfn/*, thisArg*/) { |
| 807 | var object = ES.ToObject(this); |
| 808 | var self = splitString && isString(this) ? strSplit(this, '') : object; |
| 809 | var length = ES.ToUint32(self.length); |
| 810 | var result = []; |
| 811 | var value; |
| 812 | var T; |
| 813 | if (arguments.length > 1) { |
| 814 | T = arguments[1]; |
| 815 | } |
| 816 | |
| 817 | // If no callback function or if callback is not a callable function |
| 818 | if (!isCallable(callbackfn)) { |
| 819 | throw new TypeError('Array.prototype.filter callback must be a function'); |
| 820 | } |
| 821 | |
| 822 | for (var i = 0; i < length; i++) { |
| 823 | if (i in self) { |
| 824 | value = self[i]; |
| 825 | if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) { |
| 826 | pushCall(result, value); |
| 827 | } |
| 828 | } |
| 829 | } |
| 830 | return result; |
| 831 | } |
| 832 | }, !properlyBoxesContext(ArrayPrototype.filter)); |
| 833 | |
| 834 | // ES5 15.4.4.16 |
| 835 | // http://es5.github.com/#x15.4.4.16 |
| 836 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every |
| 837 | defineProperties(ArrayPrototype, { |
| 838 | every: function every(callbackfn/*, thisArg*/) { |
| 839 | var object = ES.ToObject(this); |
| 840 | var self = splitString && isString(this) ? strSplit(this, '') : object; |
| 841 | var length = ES.ToUint32(self.length); |
| 842 | var T; |
| 843 | if (arguments.length > 1) { |
| 844 | T = arguments[1]; |
| 845 | } |
| 846 | |
| 847 | // If no callback function or if callback is not a callable function |
| 848 | if (!isCallable(callbackfn)) { |
| 849 | throw new TypeError('Array.prototype.every callback must be a function'); |
| 850 | } |
| 851 | |
| 852 | for (var i = 0; i < length; i++) { |
| 853 | if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) { |
| 854 | return false; |
| 855 | } |
| 856 | } |
| 857 | return true; |
| 858 | } |
| 859 | }, !properlyBoxesContext(ArrayPrototype.every)); |
| 860 | |
| 861 | // ES5 15.4.4.17 |
| 862 | // http://es5.github.com/#x15.4.4.17 |
| 863 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some |
| 864 | defineProperties(ArrayPrototype, { |
| 865 | some: function some(callbackfn/*, thisArg */) { |
| 866 | var object = ES.ToObject(this); |
| 867 | var self = splitString && isString(this) ? strSplit(this, '') : object; |
| 868 | var length = ES.ToUint32(self.length); |
| 869 | var T; |
| 870 | if (arguments.length > 1) { |
| 871 | T = arguments[1]; |
| 872 | } |
| 873 | |
| 874 | // If no callback function or if callback is not a callable function |
| 875 | if (!isCallable(callbackfn)) { |
| 876 | throw new TypeError('Array.prototype.some callback must be a function'); |
| 877 | } |
| 878 | |
| 879 | for (var i = 0; i < length; i++) { |
| 880 | if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) { |
| 881 | return true; |
| 882 | } |
| 883 | } |
| 884 | return false; |
| 885 | } |
| 886 | }, !properlyBoxesContext(ArrayPrototype.some)); |
| 887 | |
| 888 | // ES5 15.4.4.21 |
| 889 | // http://es5.github.com/#x15.4.4.21 |
| 890 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce |
| 891 | var reduceCoercesToObject = false; |
| 892 | if (ArrayPrototype.reduce) { |
| 893 | reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { |
| 894 | return list; |
| 895 | }) === 'object'; |
| 896 | } |
| 897 | defineProperties(ArrayPrototype, { |
| 898 | reduce: function reduce(callbackfn/*, initialValue*/) { |
| 899 | var object = ES.ToObject(this); |
| 900 | var self = splitString && isString(this) ? strSplit(this, '') : object; |
| 901 | var length = ES.ToUint32(self.length); |
| 902 | |
| 903 | // If no callback function or if callback is not a callable function |
| 904 | if (!isCallable(callbackfn)) { |
| 905 | throw new TypeError('Array.prototype.reduce callback must be a function'); |
| 906 | } |
| 907 | |
| 908 | // no value to return if no initial value and an empty array |
| 909 | if (length === 0 && arguments.length === 1) { |
| 910 | throw new TypeError('reduce of empty array with no initial value'); |
| 911 | } |
| 912 | |
| 913 | var i = 0; |
| 914 | var result; |
| 915 | if (arguments.length >= 2) { |
| 916 | result = arguments[1]; |
| 917 | } else { |
| 918 | do { |
| 919 | if (i in self) { |
| 920 | result = self[i++]; |
| 921 | break; |
| 922 | } |
| 923 | |
| 924 | // if array contains no values, no initial value to return |
| 925 | if (++i >= length) { |
| 926 | throw new TypeError('reduce of empty array with no initial value'); |
| 927 | } |
| 928 | } while (true); |
| 929 | } |
| 930 | |
| 931 | for (; i < length; i++) { |
| 932 | if (i in self) { |
| 933 | result = callbackfn(result, self[i], i, object); |
| 934 | } |
| 935 | } |
| 936 | |
| 937 | return result; |
| 938 | } |
| 939 | }, !reduceCoercesToObject); |
| 940 | |
| 941 | // ES5 15.4.4.22 |
| 942 | // http://es5.github.com/#x15.4.4.22 |
| 943 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight |
| 944 | var reduceRightCoercesToObject = false; |
| 945 | if (ArrayPrototype.reduceRight) { |
| 946 | reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { |
| 947 | return list; |
| 948 | }) === 'object'; |
| 949 | } |
| 950 | defineProperties(ArrayPrototype, { |
| 951 | reduceRight: function reduceRight(callbackfn/*, initial*/) { |
| 952 | var object = ES.ToObject(this); |
| 953 | var self = splitString && isString(this) ? strSplit(this, '') : object; |
| 954 | var length = ES.ToUint32(self.length); |
| 955 | |
| 956 | // If no callback function or if callback is not a callable function |
| 957 | if (!isCallable(callbackfn)) { |
| 958 | throw new TypeError('Array.prototype.reduceRight callback must be a function'); |
| 959 | } |
| 960 | |
| 961 | // no value to return if no initial value, empty array |
| 962 | if (length === 0 && arguments.length === 1) { |
| 963 | throw new TypeError('reduceRight of empty array with no initial value'); |
| 964 | } |
| 965 | |
| 966 | var result; |
| 967 | var i = length - 1; |
| 968 | if (arguments.length >= 2) { |
| 969 | result = arguments[1]; |
| 970 | } else { |
| 971 | do { |
| 972 | if (i in self) { |
| 973 | result = self[i--]; |
| 974 | break; |
| 975 | } |
| 976 | |
| 977 | // if array contains no values, no initial value to return |
| 978 | if (--i < 0) { |
| 979 | throw new TypeError('reduceRight of empty array with no initial value'); |
| 980 | } |
| 981 | } while (true); |
| 982 | } |
| 983 | |
| 984 | if (i < 0) { |
| 985 | return result; |
| 986 | } |
| 987 | |
| 988 | do { |
| 989 | if (i in self) { |
| 990 | result = callbackfn(result, self[i], i, object); |
| 991 | } |
| 992 | } while (i--); |
| 993 | |
| 994 | return result; |
| 995 | } |
| 996 | }, !reduceRightCoercesToObject); |
| 997 | |
| 998 | // ES5 15.4.4.14 |
| 999 | // http://es5.github.com/#x15.4.4.14 |
| 1000 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf |
| 1001 | var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1; |
| 1002 | defineProperties(ArrayPrototype, { |
| 1003 | indexOf: function indexOf(searchElement/*, fromIndex */) { |
| 1004 | var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this); |
| 1005 | var length = ES.ToUint32(self.length); |
| 1006 | |
| 1007 | if (length === 0) { |
| 1008 | return -1; |
| 1009 | } |
| 1010 | |
| 1011 | var i = 0; |
| 1012 | if (arguments.length > 1) { |
| 1013 | i = ES.ToInteger(arguments[1]); |
| 1014 | } |
| 1015 | |
| 1016 | // handle negative indices |
| 1017 | i = i >= 0 ? i : max(0, length + i); |
| 1018 | for (; i < length; i++) { |
| 1019 | if (i in self && self[i] === searchElement) { |
| 1020 | return i; |
| 1021 | } |
| 1022 | } |
| 1023 | return -1; |
| 1024 | } |
| 1025 | }, hasFirefox2IndexOfBug); |
| 1026 | |
| 1027 | // ES5 15.4.4.15 |
| 1028 | // http://es5.github.com/#x15.4.4.15 |
| 1029 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf |
| 1030 | var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1; |
| 1031 | defineProperties(ArrayPrototype, { |
| 1032 | lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) { |
| 1033 | var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this); |
| 1034 | var length = ES.ToUint32(self.length); |
| 1035 | |
| 1036 | if (length === 0) { |
| 1037 | return -1; |
| 1038 | } |
| 1039 | var i = length - 1; |
| 1040 | if (arguments.length > 1) { |
| 1041 | i = min(i, ES.ToInteger(arguments[1])); |
| 1042 | } |
| 1043 | // handle negative indices |
| 1044 | i = i >= 0 ? i : length - Math.abs(i); |
| 1045 | for (; i >= 0; i--) { |
| 1046 | if (i in self && searchElement === self[i]) { |
| 1047 | return i; |
| 1048 | } |
| 1049 | } |
| 1050 | return -1; |
| 1051 | } |
| 1052 | }, hasFirefox2LastIndexOfBug); |
| 1053 | |
| 1054 | // ES5 15.4.4.12 |
| 1055 | // http://es5.github.com/#x15.4.4.12 |
| 1056 | var spliceNoopReturnsEmptyArray = (function () { |
| 1057 | var a = [1, 2]; |
| 1058 | var result = a.splice(); |
| 1059 | return a.length === 2 && isArray(result) && result.length === 0; |
| 1060 | }()); |
| 1061 | defineProperties(ArrayPrototype, { |
| 1062 | // Safari 5.0 bug where .splice() returns undefined |
| 1063 | splice: function splice(start, deleteCount) { |
| 1064 | if (arguments.length === 0) { |
| 1065 | return []; |
| 1066 | } else { |
| 1067 | return array_splice.apply(this, arguments); |
| 1068 | } |
| 1069 | } |
| 1070 | }, !spliceNoopReturnsEmptyArray); |
| 1071 | |
| 1072 | var spliceWorksWithEmptyObject = (function () { |
| 1073 | var obj = {}; |
| 1074 | ArrayPrototype.splice.call(obj, 0, 0, 1); |
| 1075 | return obj.length === 1; |
| 1076 | }()); |
| 1077 | defineProperties(ArrayPrototype, { |
| 1078 | splice: function splice(start, deleteCount) { |
| 1079 | if (arguments.length === 0) { |
| 1080 | return []; |
| 1081 | } |
| 1082 | var args = arguments; |
| 1083 | this.length = max(ES.ToInteger(this.length), 0); |
| 1084 | if (arguments.length > 0 && typeof deleteCount !== 'number') { |
| 1085 | args = arraySlice(arguments); |
| 1086 | if (args.length < 2) { |
| 1087 | pushCall(args, this.length - start); |
| 1088 | } else { |
| 1089 | args[1] = ES.ToInteger(deleteCount); |
| 1090 | } |
| 1091 | } |
| 1092 | return array_splice.apply(this, args); |
| 1093 | } |
| 1094 | }, !spliceWorksWithEmptyObject); |
| 1095 | var spliceWorksWithLargeSparseArrays = (function () { |
| 1096 | // Per https://github.com/es-shims/es5-shim/issues/295 |
| 1097 | // Safari 7/8 breaks with sparse arrays of size 1e5 or greater |
| 1098 | var arr = new $Array(1e5); |
| 1099 | // note: the index MUST be 8 or larger or the test will false pass |
| 1100 | arr[8] = 'x'; |
| 1101 | arr.splice(1, 1); |
| 1102 | // note: this test must be defined *after* the indexOf shim |
| 1103 | // per https://github.com/es-shims/es5-shim/issues/313 |
| 1104 | return arr.indexOf('x') === 7; |
| 1105 | }()); |
| 1106 | var spliceWorksWithSmallSparseArrays = (function () { |
| 1107 | // Per https://github.com/es-shims/es5-shim/issues/295 |
| 1108 | // Opera 12.15 breaks on this, no idea why. |
| 1109 | var n = 256; |
| 1110 | var arr = []; |
| 1111 | arr[n] = 'a'; |
| 1112 | arr.splice(n + 1, 0, 'b'); |
| 1113 | return arr[n] === 'a'; |
| 1114 | }()); |
| 1115 | defineProperties(ArrayPrototype, { |
| 1116 | splice: function splice(start, deleteCount) { |
| 1117 | var O = ES.ToObject(this); |
| 1118 | var A = []; |
| 1119 | var len = ES.ToUint32(O.length); |
| 1120 | var relativeStart = ES.ToInteger(start); |
| 1121 | var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len); |
| 1122 | var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart); |
| 1123 | |
| 1124 | var k = 0; |
| 1125 | var from; |
| 1126 | while (k < actualDeleteCount) { |
| 1127 | from = $String(actualStart + k); |
| 1128 | if (owns(O, from)) { |
| 1129 | A[k] = O[from]; |
| 1130 | } |
| 1131 | k += 1; |
| 1132 | } |
| 1133 | |
| 1134 | var items = arraySlice(arguments, 2); |
| 1135 | var itemCount = items.length; |
| 1136 | var to; |
| 1137 | if (itemCount < actualDeleteCount) { |
| 1138 | k = actualStart; |
| 1139 | var maxK = len - actualDeleteCount; |
| 1140 | while (k < maxK) { |
| 1141 | from = $String(k + actualDeleteCount); |
| 1142 | to = $String(k + itemCount); |
| 1143 | if (owns(O, from)) { |
| 1144 | O[to] = O[from]; |
| 1145 | } else { |
| 1146 | delete O[to]; |
| 1147 | } |
| 1148 | k += 1; |
| 1149 | } |
| 1150 | k = len; |
| 1151 | var minK = len - actualDeleteCount + itemCount; |
| 1152 | while (k > minK) { |
| 1153 | delete O[k - 1]; |
| 1154 | k -= 1; |
| 1155 | } |
| 1156 | } else if (itemCount > actualDeleteCount) { |
| 1157 | k = len - actualDeleteCount; |
| 1158 | while (k > actualStart) { |
| 1159 | from = $String(k + actualDeleteCount - 1); |
| 1160 | to = $String(k + itemCount - 1); |
| 1161 | if (owns(O, from)) { |
| 1162 | O[to] = O[from]; |
| 1163 | } else { |
| 1164 | delete O[to]; |
| 1165 | } |
| 1166 | k -= 1; |
| 1167 | } |
| 1168 | } |
| 1169 | k = actualStart; |
| 1170 | for (var i = 0; i < items.length; ++i) { |
| 1171 | O[k] = items[i]; |
| 1172 | k += 1; |
| 1173 | } |
| 1174 | O.length = len - actualDeleteCount + itemCount; |
| 1175 | |
| 1176 | return A; |
| 1177 | } |
| 1178 | }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays); |
| 1179 | |
| 1180 | var originalJoin = ArrayPrototype.join; |
| 1181 | var hasStringJoinBug; |
| 1182 | try { |
| 1183 | hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3'; |
| 1184 | } catch (e) { |
| 1185 | hasStringJoinBug = true; |
| 1186 | } |
| 1187 | if (hasStringJoinBug) { |
| 1188 | defineProperties(ArrayPrototype, { |
| 1189 | join: function join(separator) { |
| 1190 | var sep = typeof separator === 'undefined' ? ',' : separator; |
| 1191 | return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep); |
| 1192 | } |
| 1193 | }, hasStringJoinBug); |
| 1194 | } |
| 1195 | |
| 1196 | var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2'; |
| 1197 | if (hasJoinUndefinedBug) { |
| 1198 | defineProperties(ArrayPrototype, { |
| 1199 | join: function join(separator) { |
| 1200 | var sep = typeof separator === 'undefined' ? ',' : separator; |
| 1201 | return originalJoin.call(this, sep); |
| 1202 | } |
| 1203 | }, hasJoinUndefinedBug); |
| 1204 | } |
| 1205 | |
| 1206 | var pushShim = function push(item) { |
| 1207 | var O = ES.ToObject(this); |
| 1208 | var n = ES.ToUint32(O.length); |
| 1209 | var i = 0; |
| 1210 | while (i < arguments.length) { |
| 1211 | O[n + i] = arguments[i]; |
| 1212 | i += 1; |
| 1213 | } |
| 1214 | O.length = n + i; |
| 1215 | return n + i; |
| 1216 | }; |
| 1217 | |
| 1218 | var pushIsNotGeneric = (function () { |
| 1219 | var obj = {}; |
| 1220 | var result = Array.prototype.push.call(obj, undefined); |
| 1221 | return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0); |
| 1222 | }()); |
| 1223 | defineProperties(ArrayPrototype, { |
| 1224 | push: function push(item) { |
| 1225 | if (isArray(this)) { |
| 1226 | return array_push.apply(this, arguments); |
| 1227 | } |
| 1228 | return pushShim.apply(this, arguments); |
| 1229 | } |
| 1230 | }, pushIsNotGeneric); |
| 1231 | |
| 1232 | // This fixes a very weird bug in Opera 10.6 when pushing `undefined |
| 1233 | var pushUndefinedIsWeird = (function () { |
| 1234 | var arr = []; |
| 1235 | var result = arr.push(undefined); |
| 1236 | return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0); |
| 1237 | }()); |
| 1238 | defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird); |
| 1239 | |
| 1240 | // ES5 15.2.3.14 |
| 1241 | // http://es5.github.io/#x15.4.4.10 |
| 1242 | // Fix boxed string bug |
| 1243 | defineProperties(ArrayPrototype, { |
| 1244 | slice: function (start, end) { |
| 1245 | var arr = isString(this) ? strSplit(this, '') : this; |
| 1246 | return arraySliceApply(arr, arguments); |
| 1247 | } |
| 1248 | }, splitString); |
| 1249 | |
| 1250 | var sortIgnoresNonFunctions = (function () { |
| 1251 | try { |
| 1252 | [1, 2].sort(null); |
| 1253 | [1, 2].sort({}); |
| 1254 | return true; |
| 1255 | } catch (e) {} |
| 1256 | return false; |
| 1257 | }()); |
| 1258 | var sortThrowsOnRegex = (function () { |
| 1259 | // this is a problem in Firefox 4, in which `typeof /a/ === 'function'` |
| 1260 | try { |
| 1261 | [1, 2].sort(/a/); |
| 1262 | return false; |
| 1263 | } catch (e) {} |
| 1264 | return true; |
| 1265 | }()); |
| 1266 | var sortIgnoresUndefined = (function () { |
| 1267 | // applies in IE 8, for one. |
| 1268 | try { |
| 1269 | [1, 2].sort(undefined); |
| 1270 | return true; |
| 1271 | } catch (e) {} |
| 1272 | return false; |
| 1273 | }()); |
| 1274 | defineProperties(ArrayPrototype, { |
| 1275 | sort: function sort(compareFn) { |
| 1276 | if (typeof compareFn === 'undefined') { |
| 1277 | return arraySort(this); |
| 1278 | } |
| 1279 | if (!isCallable(compareFn)) { |
| 1280 | throw new TypeError('Array.prototype.sort callback must be a function'); |
| 1281 | } |
| 1282 | return arraySort(this, compareFn); |
| 1283 | } |
| 1284 | }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex); |
| 1285 | |
| 1286 | // |
| 1287 | // Object |
| 1288 | // ====== |
| 1289 | // |
| 1290 | |
| 1291 | // ES5 15.2.3.14 |
| 1292 | // http://es5.github.com/#x15.2.3.14 |
| 1293 | |
| 1294 | // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation |
| 1295 | var hasDontEnumBug = !isEnum({ 'toString': null }, 'toString'); |
| 1296 | var hasProtoEnumBug = isEnum(function () {}, 'prototype'); |
| 1297 | var hasStringEnumBug = !owns('x', '0'); |
| 1298 | var equalsConstructorPrototype = function (o) { |
| 1299 | var ctor = o.constructor; |
| 1300 | return ctor && ctor.prototype === o; |
| 1301 | }; |
| 1302 | var blacklistedKeys = { |
| 1303 | $window: true, |
| 1304 | $console: true, |
| 1305 | $parent: true, |
| 1306 | $self: true, |
| 1307 | $frame: true, |
| 1308 | $frames: true, |
| 1309 | $frameElement: true, |
| 1310 | $webkitIndexedDB: true, |
| 1311 | $webkitStorageInfo: true, |
| 1312 | $external: true |
| 1313 | }; |
| 1314 | var hasAutomationEqualityBug = (function () { |
| 1315 | /* globals window */ |
| 1316 | if (typeof window === 'undefined') { |
| 1317 | return false; |
| 1318 | } |
| 1319 | for (var k in window) { |
| 1320 | try { |
| 1321 | if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') { |
| 1322 | equalsConstructorPrototype(window[k]); |
| 1323 | } |
| 1324 | } catch (e) { |
| 1325 | return true; |
| 1326 | } |
| 1327 | } |
| 1328 | return false; |
| 1329 | }()); |
| 1330 | var equalsConstructorPrototypeIfNotBuggy = function (object) { |
| 1331 | if (typeof window === 'undefined' || !hasAutomationEqualityBug) { |
| 1332 | return equalsConstructorPrototype(object); |
| 1333 | } |
| 1334 | try { |
| 1335 | return equalsConstructorPrototype(object); |
| 1336 | } catch (e) { |
| 1337 | return false; |
| 1338 | } |
| 1339 | }; |
| 1340 | var dontEnums = [ |
| 1341 | 'toString', |
| 1342 | 'toLocaleString', |
| 1343 | 'valueOf', |
| 1344 | 'hasOwnProperty', |
| 1345 | 'isPrototypeOf', |
| 1346 | 'propertyIsEnumerable', |
| 1347 | 'constructor' |
| 1348 | ]; |
| 1349 | var dontEnumsLength = dontEnums.length; |
| 1350 | |
| 1351 | // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js |
| 1352 | // can be replaced with require('is-arguments') if we ever use a build process instead |
| 1353 | var isStandardArguments = function isArguments(value) { |
| 1354 | return toStr(value) === '[object Arguments]'; |
| 1355 | }; |
| 1356 | var isLegacyArguments = function isArguments(value) { |
| 1357 | return value !== null && |
| 1358 | typeof value === 'object' && |
| 1359 | typeof value.length === 'number' && |
| 1360 | value.length >= 0 && |
| 1361 | !isArray(value) && |
| 1362 | isCallable(value.callee); |
| 1363 | }; |
| 1364 | var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments; |
| 1365 | |
| 1366 | defineProperties($Object, { |
| 1367 | keys: function keys(object) { |
| 1368 | var isFn = isCallable(object); |
| 1369 | var isArgs = isArguments(object); |
| 1370 | var isObject = object !== null && typeof object === 'object'; |
| 1371 | var isStr = isObject && isString(object); |
| 1372 | |
| 1373 | if (!isObject && !isFn && !isArgs) { |
| 1374 | throw new TypeError('Object.keys called on a non-object'); |
| 1375 | } |
| 1376 | |
| 1377 | var theKeys = []; |
| 1378 | var skipProto = hasProtoEnumBug && isFn; |
| 1379 | if ((isStr && hasStringEnumBug) || isArgs) { |
| 1380 | for (var i = 0; i < object.length; ++i) { |
| 1381 | pushCall(theKeys, $String(i)); |
| 1382 | } |
| 1383 | } |
| 1384 | |
| 1385 | if (!isArgs) { |
| 1386 | for (var name in object) { |
| 1387 | if (!(skipProto && name === 'prototype') && owns(object, name)) { |
| 1388 | pushCall(theKeys, $String(name)); |
| 1389 | } |
| 1390 | } |
| 1391 | } |
| 1392 | |
| 1393 | if (hasDontEnumBug) { |
| 1394 | var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object); |
| 1395 | for (var j = 0; j < dontEnumsLength; j++) { |
| 1396 | var dontEnum = dontEnums[j]; |
| 1397 | if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) { |
| 1398 | pushCall(theKeys, dontEnum); |
| 1399 | } |
| 1400 | } |
| 1401 | } |
| 1402 | return theKeys; |
| 1403 | } |
| 1404 | }); |
| 1405 | |
| 1406 | var keysWorksWithArguments = $Object.keys && (function () { |
| 1407 | // Safari 5.0 bug |
| 1408 | return $Object.keys(arguments).length === 2; |
| 1409 | }(1, 2)); |
| 1410 | var keysHasArgumentsLengthBug = $Object.keys && (function () { |
| 1411 | var argKeys = $Object.keys(arguments); |
| 1412 | return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1; |
| 1413 | }(1)); |
| 1414 | var originalKeys = $Object.keys; |
| 1415 | defineProperties($Object, { |
| 1416 | keys: function keys(object) { |
| 1417 | if (isArguments(object)) { |
| 1418 | return originalKeys(arraySlice(object)); |
| 1419 | } else { |
| 1420 | return originalKeys(object); |
| 1421 | } |
| 1422 | } |
| 1423 | }, !keysWorksWithArguments || keysHasArgumentsLengthBug); |
| 1424 | |
| 1425 | // |
| 1426 | // Date |
| 1427 | // ==== |
| 1428 | // |
| 1429 | |
| 1430 | var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0; |
| 1431 | var aNegativeTestDate = new Date(-1509842289600292); |
| 1432 | var aPositiveTestDate = new Date(1449662400000); |
| 1433 | var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT'; |
| 1434 | var hasToDateStringFormatBug; |
| 1435 | var hasToStringFormatBug; |
| 1436 | var timeZoneOffset = aNegativeTestDate.getTimezoneOffset(); |
| 1437 | if (timeZoneOffset < -720) { |
| 1438 | hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875'; |
| 1439 | hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString()); |
| 1440 | } else { |
| 1441 | hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875'; |
| 1442 | hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString()); |
| 1443 | } |
| 1444 | |
| 1445 | var originalGetFullYear = call.bind(Date.prototype.getFullYear); |
| 1446 | var originalGetMonth = call.bind(Date.prototype.getMonth); |
| 1447 | var originalGetDate = call.bind(Date.prototype.getDate); |
| 1448 | var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear); |
| 1449 | var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth); |
| 1450 | var originalGetUTCDate = call.bind(Date.prototype.getUTCDate); |
| 1451 | var originalGetUTCDay = call.bind(Date.prototype.getUTCDay); |
| 1452 | var originalGetUTCHours = call.bind(Date.prototype.getUTCHours); |
| 1453 | var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes); |
| 1454 | var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds); |
| 1455 | var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds); |
| 1456 | var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; |
| 1457 | var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; |
| 1458 | var daysInMonth = function daysInMonth(month, year) { |
| 1459 | return originalGetDate(new Date(year, month, 0)); |
| 1460 | }; |
| 1461 | |
| 1462 | defineProperties(Date.prototype, { |
| 1463 | getFullYear: function getFullYear() { |
| 1464 | if (!this || !(this instanceof Date)) { |
| 1465 | throw new TypeError('this is not a Date object.'); |
| 1466 | } |
| 1467 | var year = originalGetFullYear(this); |
| 1468 | if (year < 0 && originalGetMonth(this) > 11) { |
| 1469 | return year + 1; |
| 1470 | } |
| 1471 | return year; |
| 1472 | }, |
| 1473 | getMonth: function getMonth() { |
| 1474 | if (!this || !(this instanceof Date)) { |
| 1475 | throw new TypeError('this is not a Date object.'); |
| 1476 | } |
| 1477 | var year = originalGetFullYear(this); |
| 1478 | var month = originalGetMonth(this); |
| 1479 | if (year < 0 && month > 11) { |
| 1480 | return 0; |
| 1481 | } |
| 1482 | return month; |
| 1483 | }, |
| 1484 | getDate: function getDate() { |
| 1485 | if (!this || !(this instanceof Date)) { |
| 1486 | throw new TypeError('this is not a Date object.'); |
| 1487 | } |
| 1488 | var year = originalGetFullYear(this); |
| 1489 | var month = originalGetMonth(this); |
| 1490 | var date = originalGetDate(this); |
| 1491 | if (year < 0 && month > 11) { |
| 1492 | if (month === 12) { |
| 1493 | return date; |
| 1494 | } |
| 1495 | var days = daysInMonth(0, year + 1); |
| 1496 | return (days - date) + 1; |
| 1497 | } |
| 1498 | return date; |
| 1499 | }, |
| 1500 | getUTCFullYear: function getUTCFullYear() { |
| 1501 | if (!this || !(this instanceof Date)) { |
| 1502 | throw new TypeError('this is not a Date object.'); |
| 1503 | } |
| 1504 | var year = originalGetUTCFullYear(this); |
| 1505 | if (year < 0 && originalGetUTCMonth(this) > 11) { |
| 1506 | return year + 1; |
| 1507 | } |
| 1508 | return year; |
| 1509 | }, |
| 1510 | getUTCMonth: function getUTCMonth() { |
| 1511 | if (!this || !(this instanceof Date)) { |
| 1512 | throw new TypeError('this is not a Date object.'); |
| 1513 | } |
| 1514 | var year = originalGetUTCFullYear(this); |
| 1515 | var month = originalGetUTCMonth(this); |
| 1516 | if (year < 0 && month > 11) { |
| 1517 | return 0; |
| 1518 | } |
| 1519 | return month; |
| 1520 | }, |
| 1521 | getUTCDate: function getUTCDate() { |
| 1522 | if (!this || !(this instanceof Date)) { |
| 1523 | throw new TypeError('this is not a Date object.'); |
| 1524 | } |
| 1525 | var year = originalGetUTCFullYear(this); |
| 1526 | var month = originalGetUTCMonth(this); |
| 1527 | var date = originalGetUTCDate(this); |
| 1528 | if (year < 0 && month > 11) { |
| 1529 | if (month === 12) { |
| 1530 | return date; |
| 1531 | } |
| 1532 | var days = daysInMonth(0, year + 1); |
| 1533 | return (days - date) + 1; |
| 1534 | } |
| 1535 | return date; |
| 1536 | } |
| 1537 | }, hasNegativeMonthYearBug); |
| 1538 | |
| 1539 | defineProperties(Date.prototype, { |
| 1540 | toUTCString: function toUTCString() { |
| 1541 | if (!this || !(this instanceof Date)) { |
| 1542 | throw new TypeError('this is not a Date object.'); |
| 1543 | } |
| 1544 | var day = originalGetUTCDay(this); |
| 1545 | var date = originalGetUTCDate(this); |
| 1546 | var month = originalGetUTCMonth(this); |
| 1547 | var year = originalGetUTCFullYear(this); |
| 1548 | var hour = originalGetUTCHours(this); |
| 1549 | var minute = originalGetUTCMinutes(this); |
| 1550 | var second = originalGetUTCSeconds(this); |
| 1551 | return dayName[day] + ', ' + |
| 1552 | (date < 10 ? '0' + date : date) + ' ' + |
| 1553 | monthName[month] + ' ' + |
| 1554 | year + ' ' + |
| 1555 | (hour < 10 ? '0' + hour : hour) + ':' + |
| 1556 | (minute < 10 ? '0' + minute : minute) + ':' + |
| 1557 | (second < 10 ? '0' + second : second) + ' GMT'; |
| 1558 | } |
| 1559 | }, hasNegativeMonthYearBug || hasToUTCStringFormatBug); |
| 1560 | |
| 1561 | // Opera 12 has `,` |
| 1562 | defineProperties(Date.prototype, { |
| 1563 | toDateString: function toDateString() { |
| 1564 | if (!this || !(this instanceof Date)) { |
| 1565 | throw new TypeError('this is not a Date object.'); |
| 1566 | } |
| 1567 | var day = this.getDay(); |
| 1568 | var date = this.getDate(); |
| 1569 | var month = this.getMonth(); |
| 1570 | var year = this.getFullYear(); |
| 1571 | return dayName[day] + ' ' + |
| 1572 | monthName[month] + ' ' + |
| 1573 | (date < 10 ? '0' + date : date) + ' ' + |
| 1574 | year; |
| 1575 | } |
| 1576 | }, hasNegativeMonthYearBug || hasToDateStringFormatBug); |
| 1577 | |
| 1578 | // can't use defineProperties here because of toString enumeration issue in IE <= 8 |
| 1579 | if (hasNegativeMonthYearBug || hasToStringFormatBug) { |
| 1580 | Date.prototype.toString = function toString() { |
| 1581 | if (!this || !(this instanceof Date)) { |
| 1582 | throw new TypeError('this is not a Date object.'); |
| 1583 | } |
| 1584 | var day = this.getDay(); |
| 1585 | var date = this.getDate(); |
| 1586 | var month = this.getMonth(); |
| 1587 | var year = this.getFullYear(); |
| 1588 | var hour = this.getHours(); |
| 1589 | var minute = this.getMinutes(); |
| 1590 | var second = this.getSeconds(); |
| 1591 | var timezoneOffset = this.getTimezoneOffset(); |
| 1592 | var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60); |
| 1593 | var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60); |
| 1594 | return dayName[day] + ' ' + |
| 1595 | monthName[month] + ' ' + |
| 1596 | (date < 10 ? '0' + date : date) + ' ' + |
| 1597 | year + ' ' + |
| 1598 | (hour < 10 ? '0' + hour : hour) + ':' + |
| 1599 | (minute < 10 ? '0' + minute : minute) + ':' + |
| 1600 | (second < 10 ? '0' + second : second) + ' GMT' + |
| 1601 | (timezoneOffset > 0 ? '-' : '+') + |
| 1602 | (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) + |
| 1603 | (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset); |
| 1604 | }; |
| 1605 | if (supportsDescriptors) { |
| 1606 | $Object.defineProperty(Date.prototype, 'toString', { |
| 1607 | configurable: true, |
| 1608 | enumerable: false, |
| 1609 | writable: true |
| 1610 | }); |
| 1611 | } |
| 1612 | } |
| 1613 | |
| 1614 | // ES5 15.9.5.43 |
| 1615 | // http://es5.github.com/#x15.9.5.43 |
| 1616 | // This function returns a String value represent the instance in time |
| 1617 | // represented by this Date object. The format of the String is the Date Time |
| 1618 | // string format defined in 15.9.1.15. All fields are present in the String. |
| 1619 | // The time zone is always UTC, denoted by the suffix Z. If the time value of |
| 1620 | // this object is not a finite Number a RangeError exception is thrown. |
| 1621 | var negativeDate = -62198755200000; |
| 1622 | var negativeYearString = '-000001'; |
| 1623 | var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1; |
| 1624 | var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z'; |
| 1625 | |
| 1626 | var getTime = call.bind(Date.prototype.getTime); |
| 1627 | |
| 1628 | defineProperties(Date.prototype, { |
| 1629 | toISOString: function toISOString() { |
| 1630 | if (!isFinite(this) || !isFinite(getTime(this))) { |
| 1631 | // Adope Photoshop requires the second check. |
| 1632 | throw new RangeError('Date.prototype.toISOString called on non-finite value.'); |
| 1633 | } |
| 1634 | |
| 1635 | var year = originalGetUTCFullYear(this); |
| 1636 | |
| 1637 | var month = originalGetUTCMonth(this); |
| 1638 | // see https://github.com/es-shims/es5-shim/issues/111 |
| 1639 | year += Math.floor(month / 12); |
| 1640 | month = (month % 12 + 12) % 12; |
| 1641 | |
| 1642 | // the date time string format is specified in 15.9.1.15. |
| 1643 | var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)]; |
| 1644 | year = ( |
| 1645 | (year < 0 ? '-' : (year > 9999 ? '+' : '')) + |
| 1646 | strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6) |
| 1647 | ); |
| 1648 | |
| 1649 | for (var i = 0; i < result.length; ++i) { |
| 1650 | // pad months, days, hours, minutes, and seconds to have two digits. |
| 1651 | result[i] = strSlice('00' + result[i], -2); |
| 1652 | } |
| 1653 | // pad milliseconds to have three digits. |
| 1654 | return ( |
| 1655 | year + '-' + arraySlice(result, 0, 2).join('-') + |
| 1656 | 'T' + arraySlice(result, 2).join(':') + '.' + |
| 1657 | strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z' |
| 1658 | ); |
| 1659 | } |
| 1660 | }, hasNegativeDateBug || hasSafari51DateBug); |
| 1661 | |
| 1662 | // ES5 15.9.5.44 |
| 1663 | // http://es5.github.com/#x15.9.5.44 |
| 1664 | // This function provides a String representation of a Date object for use by |
| 1665 | // JSON.stringify (15.12.3). |
| 1666 | var dateToJSONIsSupported = (function () { |
| 1667 | try { |
| 1668 | return Date.prototype.toJSON && |
| 1669 | new Date(NaN).toJSON() === null && |
| 1670 | new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 && |
| 1671 | Date.prototype.toJSON.call({ // generic |
| 1672 | toISOString: function () { return true; } |
| 1673 | }); |
| 1674 | } catch (e) { |
| 1675 | return false; |
| 1676 | } |
| 1677 | }()); |
| 1678 | if (!dateToJSONIsSupported) { |
| 1679 | Date.prototype.toJSON = function toJSON(key) { |
| 1680 | // When the toJSON method is called with argument key, the following |
| 1681 | // steps are taken: |
| 1682 | |
| 1683 | // 1. Let O be the result of calling ToObject, giving it the this |
| 1684 | // value as its argument. |
| 1685 | // 2. Let tv be ES.ToPrimitive(O, hint Number). |
| 1686 | var O = $Object(this); |
| 1687 | var tv = ES.ToPrimitive(O); |
| 1688 | // 3. If tv is a Number and is not finite, return null. |
| 1689 | if (typeof tv === 'number' && !isFinite(tv)) { |
| 1690 | return null; |
| 1691 | } |
| 1692 | // 4. Let toISO be the result of calling the [[Get]] internal method of |
| 1693 | // O with argument "toISOString". |
| 1694 | var toISO = O.toISOString; |
| 1695 | // 5. If IsCallable(toISO) is false, throw a TypeError exception. |
| 1696 | if (!isCallable(toISO)) { |
| 1697 | throw new TypeError('toISOString property is not callable'); |
| 1698 | } |
| 1699 | // 6. Return the result of calling the [[Call]] internal method of |
| 1700 | // toISO with O as the this value and an empty argument list. |
| 1701 | return toISO.call(O); |
| 1702 | |
| 1703 | // NOTE 1 The argument is ignored. |
| 1704 | |
| 1705 | // NOTE 2 The toJSON function is intentionally generic; it does not |
| 1706 | // require that its this value be a Date object. Therefore, it can be |
| 1707 | // transferred to other kinds of objects for use as a method. However, |
| 1708 | // it does require that any such object have a toISOString method. An |
| 1709 | // object is free to use the argument key to filter its |
| 1710 | // stringification. |
| 1711 | }; |
| 1712 | } |
| 1713 | |
| 1714 | // ES5 15.9.4.2 |
| 1715 | // http://es5.github.com/#x15.9.4.2 |
| 1716 | // based on work shared by Daniel Friesen (dantman) |
| 1717 | // http://gist.github.com/303249 |
| 1718 | var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15; |
| 1719 | 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')); |
| 1720 | var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z')); |
| 1721 | if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) { |
| 1722 | // XXX global assignment won't work in embeddings that use |
| 1723 | // an alternate object for the context. |
| 1724 | /* global Date: true */ |
| 1725 | /* eslint-disable no-undef */ |
| 1726 | var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1; |
| 1727 | var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime()); |
| 1728 | /* eslint-disable no-implicit-globals */ |
| 1729 | Date = (function (NativeDate) { |
| 1730 | /* eslint-enable no-implicit-globals */ |
| 1731 | /* eslint-enable no-undef */ |
| 1732 | // Date.length === 7 |
| 1733 | var DateShim = function Date(Y, M, D, h, m, s, ms) { |
| 1734 | var length = arguments.length; |
| 1735 | var date; |
| 1736 | if (this instanceof NativeDate) { |
| 1737 | var seconds = s; |
| 1738 | var millis = ms; |
| 1739 | if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) { |
| 1740 | // work around a Safari 8/9 bug where it treats the seconds as signed |
| 1741 | var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit; |
| 1742 | var sToShift = Math.floor(msToShift / 1e3); |
| 1743 | seconds += sToShift; |
| 1744 | millis -= sToShift * 1e3; |
| 1745 | } |
| 1746 | date = length === 1 && $String(Y) === Y ? // isString(Y) |
| 1747 | // We explicitly pass it through parse: |
| 1748 | new NativeDate(DateShim.parse(Y)) : |
| 1749 | // We have to manually make calls depending on argument |
| 1750 | // length here |
| 1751 | length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) : |
| 1752 | length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) : |
| 1753 | length >= 5 ? new NativeDate(Y, M, D, h, m) : |
| 1754 | length >= 4 ? new NativeDate(Y, M, D, h) : |
| 1755 | length >= 3 ? new NativeDate(Y, M, D) : |
| 1756 | length >= 2 ? new NativeDate(Y, M) : |
| 1757 | length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y) : |
| 1758 | new NativeDate(); |
| 1759 | } else { |
| 1760 | date = NativeDate.apply(this, arguments); |
| 1761 | } |
| 1762 | if (!isPrimitive(date)) { |
| 1763 | // Prevent mixups with unfixed Date object |
| 1764 | defineProperties(date, { constructor: DateShim }, true); |
| 1765 | } |
| 1766 | return date; |
| 1767 | }; |
| 1768 | |
| 1769 | // 15.9.1.15 Date Time String Format. |
| 1770 | var isoDateExpression = new RegExp('^' + |
| 1771 | '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign + |
| 1772 | // 6-digit extended year |
| 1773 | '(?:-(\\d{2})' + // optional month capture |
| 1774 | '(?:-(\\d{2})' + // optional day capture |
| 1775 | '(?:' + // capture hours:minutes:seconds.milliseconds |
| 1776 | 'T(\\d{2})' + // hours capture |
| 1777 | ':(\\d{2})' + // minutes capture |
| 1778 | '(?:' + // optional :seconds.milliseconds |
| 1779 | ':(\\d{2})' + // seconds capture |
| 1780 | '(?:(\\.\\d{1,}))?' + // milliseconds capture |
| 1781 | ')?' + |
| 1782 | '(' + // capture UTC offset component |
| 1783 | 'Z|' + // UTC capture |
| 1784 | '(?:' + // offset specifier +/-hours:minutes |
| 1785 | '([-+])' + // sign capture |
| 1786 | '(\\d{2})' + // hours offset capture |
| 1787 | ':(\\d{2})' + // minutes offset capture |
| 1788 | ')' + |
| 1789 | ')?)?)?)?' + |
| 1790 | '$'); |
| 1791 | |
| 1792 | var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; |
| 1793 | |
| 1794 | var dayFromMonth = function dayFromMonth(year, month) { |
| 1795 | var t = month > 1 ? 1 : 0; |
| 1796 | return ( |
| 1797 | months[month] + |
| 1798 | Math.floor((year - 1969 + t) / 4) - |
| 1799 | Math.floor((year - 1901 + t) / 100) + |
| 1800 | Math.floor((year - 1601 + t) / 400) + |
| 1801 | 365 * (year - 1970) |
| 1802 | ); |
| 1803 | }; |
| 1804 | |
| 1805 | var toUTC = function toUTC(t) { |
| 1806 | var s = 0; |
| 1807 | var ms = t; |
| 1808 | if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) { |
| 1809 | // work around a Safari 8/9 bug where it treats the seconds as signed |
| 1810 | var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit; |
| 1811 | var sToShift = Math.floor(msToShift / 1e3); |
| 1812 | s += sToShift; |
| 1813 | ms -= sToShift * 1e3; |
| 1814 | } |
| 1815 | return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms)); |
| 1816 | }; |
| 1817 | |
| 1818 | // Copy any custom methods a 3rd party library may have added |
| 1819 | for (var key in NativeDate) { |
| 1820 | if (owns(NativeDate, key)) { |
| 1821 | DateShim[key] = NativeDate[key]; |
| 1822 | } |
| 1823 | } |
| 1824 | |
| 1825 | // Copy "native" methods explicitly; they may be non-enumerable |
| 1826 | defineProperties(DateShim, { |
| 1827 | now: NativeDate.now, |
| 1828 | UTC: NativeDate.UTC |
| 1829 | }, true); |
| 1830 | DateShim.prototype = NativeDate.prototype; |
| 1831 | defineProperties(DateShim.prototype, { |
| 1832 | constructor: DateShim |
| 1833 | }, true); |
| 1834 | |
| 1835 | // Upgrade Date.parse to handle simplified ISO 8601 strings |
| 1836 | var parseShim = function parse(string) { |
| 1837 | var match = isoDateExpression.exec(string); |
| 1838 | if (match) { |
| 1839 | // parse months, days, hours, minutes, seconds, and milliseconds |
| 1840 | // provide default values if necessary |
| 1841 | // parse the UTC offset component |
| 1842 | var year = $Number(match[1]), |
| 1843 | month = $Number(match[2] || 1) - 1, |
| 1844 | day = $Number(match[3] || 1) - 1, |
| 1845 | hour = $Number(match[4] || 0), |
| 1846 | minute = $Number(match[5] || 0), |
| 1847 | second = $Number(match[6] || 0), |
| 1848 | millisecond = Math.floor($Number(match[7] || 0) * 1000), |
| 1849 | // When time zone is missed, local offset should be used |
| 1850 | // (ES 5.1 bug) |
| 1851 | // see https://bugs.ecmascript.org/show_bug.cgi?id=112 |
| 1852 | isLocalTime = Boolean(match[4] && !match[8]), |
| 1853 | signOffset = match[9] === '-' ? 1 : -1, |
| 1854 | hourOffset = $Number(match[10] || 0), |
| 1855 | minuteOffset = $Number(match[11] || 0), |
| 1856 | result; |
| 1857 | var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0; |
| 1858 | if ( |
| 1859 | hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) && |
| 1860 | minute < 60 && second < 60 && millisecond < 1000 && |
| 1861 | month > -1 && month < 12 && hourOffset < 24 && |
| 1862 | minuteOffset < 60 && // detect invalid offsets |
| 1863 | day > -1 && |
| 1864 | day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month)) |
| 1865 | ) { |
| 1866 | result = ( |
| 1867 | (dayFromMonth(year, month) + day) * 24 + |
| 1868 | hour + |
| 1869 | hourOffset * signOffset |
| 1870 | ) * 60; |
| 1871 | result = ( |
| 1872 | (result + minute + minuteOffset * signOffset) * 60 + |
| 1873 | second |
| 1874 | ) * 1000 + millisecond; |
| 1875 | if (isLocalTime) { |
| 1876 | result = toUTC(result); |
| 1877 | } |
| 1878 | if (-8.64e15 <= result && result <= 8.64e15) { |
| 1879 | return result; |
| 1880 | } |
| 1881 | } |
| 1882 | return NaN; |
| 1883 | } |
| 1884 | return NativeDate.parse.apply(this, arguments); |
| 1885 | }; |
| 1886 | defineProperties(DateShim, { parse: parseShim }); |
| 1887 | |
| 1888 | return DateShim; |
| 1889 | }(Date)); |
| 1890 | /* global Date: false */ |
| 1891 | } |
| 1892 | |
| 1893 | // ES5 15.9.4.4 |
| 1894 | // http://es5.github.com/#x15.9.4.4 |
| 1895 | if (!Date.now) { |
| 1896 | Date.now = function now() { |
| 1897 | return new Date().getTime(); |
| 1898 | }; |
| 1899 | } |
| 1900 | |
| 1901 | // |
| 1902 | // Number |
| 1903 | // ====== |
| 1904 | // |
| 1905 | |
| 1906 | // ES5.1 15.7.4.5 |
| 1907 | // http://es5.github.com/#x15.7.4.5 |
| 1908 | var hasToFixedBugs = NumberPrototype.toFixed && ( |
| 1909 | (0.00008).toFixed(3) !== '0.000' || |
| 1910 | (0.9).toFixed(0) !== '1' || |
| 1911 | (1.255).toFixed(2) !== '1.25' || |
| 1912 | (1000000000000000128).toFixed(0) !== '1000000000000000128' |
| 1913 | ); |
| 1914 | |
| 1915 | var toFixedHelpers = { |
| 1916 | base: 1e7, |
| 1917 | size: 6, |
| 1918 | data: [0, 0, 0, 0, 0, 0], |
| 1919 | multiply: function multiply(n, c) { |
| 1920 | var i = -1; |
| 1921 | var c2 = c; |
| 1922 | while (++i < toFixedHelpers.size) { |
| 1923 | c2 += n * toFixedHelpers.data[i]; |
| 1924 | toFixedHelpers.data[i] = c2 % toFixedHelpers.base; |
| 1925 | c2 = Math.floor(c2 / toFixedHelpers.base); |
| 1926 | } |
| 1927 | }, |
| 1928 | divide: function divide(n) { |
| 1929 | var i = toFixedHelpers.size; |
| 1930 | var c = 0; |
| 1931 | while (--i >= 0) { |
| 1932 | c += toFixedHelpers.data[i]; |
| 1933 | toFixedHelpers.data[i] = Math.floor(c / n); |
| 1934 | c = (c % n) * toFixedHelpers.base; |
| 1935 | } |
| 1936 | }, |
| 1937 | numToString: function numToString() { |
| 1938 | var i = toFixedHelpers.size; |
| 1939 | var s = ''; |
| 1940 | while (--i >= 0) { |
| 1941 | if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) { |
| 1942 | var t = $String(toFixedHelpers.data[i]); |
| 1943 | if (s === '') { |
| 1944 | s = t; |
| 1945 | } else { |
| 1946 | s += strSlice('0000000', 0, 7 - t.length) + t; |
| 1947 | } |
| 1948 | } |
| 1949 | } |
| 1950 | return s; |
| 1951 | }, |
| 1952 | pow: function pow(x, n, acc) { |
| 1953 | return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc))); |
| 1954 | }, |
| 1955 | log: function log(x) { |
| 1956 | var n = 0; |
| 1957 | var x2 = x; |
| 1958 | while (x2 >= 4096) { |
| 1959 | n += 12; |
| 1960 | x2 /= 4096; |
| 1961 | } |
| 1962 | while (x2 >= 2) { |
| 1963 | n += 1; |
| 1964 | x2 /= 2; |
| 1965 | } |
| 1966 | return n; |
| 1967 | } |
| 1968 | }; |
| 1969 | |
| 1970 | var toFixedShim = function toFixed(fractionDigits) { |
| 1971 | var f, x, s, m, e, z, j, k; |
| 1972 | |
| 1973 | // Test for NaN and round fractionDigits down |
| 1974 | f = $Number(fractionDigits); |
| 1975 | f = isActualNaN(f) ? 0 : Math.floor(f); |
| 1976 | |
| 1977 | if (f < 0 || f > 20) { |
| 1978 | throw new RangeError('Number.toFixed called with invalid number of decimals'); |
| 1979 | } |
| 1980 | |
| 1981 | x = $Number(this); |
| 1982 | |
| 1983 | if (isActualNaN(x)) { |
| 1984 | return 'NaN'; |
| 1985 | } |
| 1986 | |
| 1987 | // If it is too big or small, return the string value of the number |
| 1988 | if (x <= -1e21 || x >= 1e21) { |
| 1989 | return $String(x); |
| 1990 | } |
| 1991 | |
| 1992 | s = ''; |
| 1993 | |
| 1994 | if (x < 0) { |
| 1995 | s = '-'; |
| 1996 | x = -x; |
| 1997 | } |
| 1998 | |
| 1999 | m = '0'; |
| 2000 | |
| 2001 | if (x > 1e-21) { |
| 2002 | // 1e-21 < x < 1e21 |
| 2003 | // -70 < log2(x) < 70 |
| 2004 | e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69; |
| 2005 | z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1)); |
| 2006 | z *= 0x10000000000000; // Math.pow(2, 52); |
| 2007 | e = 52 - e; |
| 2008 | |
| 2009 | // -18 < e < 122 |
| 2010 | // x = z / 2 ^ e |
| 2011 | if (e > 0) { |
| 2012 | toFixedHelpers.multiply(0, z); |
| 2013 | j = f; |
| 2014 | |
| 2015 | while (j >= 7) { |
| 2016 | toFixedHelpers.multiply(1e7, 0); |
| 2017 | j -= 7; |
| 2018 | } |
| 2019 | |
| 2020 | toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0); |
| 2021 | j = e - 1; |
| 2022 | |
| 2023 | while (j >= 23) { |
| 2024 | toFixedHelpers.divide(1 << 23); |
| 2025 | j -= 23; |
| 2026 | } |
| 2027 | |
| 2028 | toFixedHelpers.divide(1 << j); |
| 2029 | toFixedHelpers.multiply(1, 1); |
| 2030 | toFixedHelpers.divide(2); |
| 2031 | m = toFixedHelpers.numToString(); |
| 2032 | } else { |
| 2033 | toFixedHelpers.multiply(0, z); |
| 2034 | toFixedHelpers.multiply(1 << (-e), 0); |
| 2035 | m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f); |
| 2036 | } |
| 2037 | } |
| 2038 | |
| 2039 | if (f > 0) { |
| 2040 | k = m.length; |
| 2041 | |
| 2042 | if (k <= f) { |
| 2043 | m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m; |
| 2044 | } else { |
| 2045 | m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f); |
| 2046 | } |
| 2047 | } else { |
| 2048 | m = s + m; |
| 2049 | } |
| 2050 | |
| 2051 | return m; |
| 2052 | }; |
| 2053 | defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs); |
| 2054 | |
| 2055 | var hasToPrecisionUndefinedBug = (function () { |
| 2056 | try { |
| 2057 | return 1.0.toPrecision(undefined) === '1'; |
| 2058 | } catch (e) { |
| 2059 | return true; |
| 2060 | } |
| 2061 | }()); |
| 2062 | var originalToPrecision = NumberPrototype.toPrecision; |
| 2063 | defineProperties(NumberPrototype, { |
| 2064 | toPrecision: function toPrecision(precision) { |
| 2065 | return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision); |
| 2066 | } |
| 2067 | }, hasToPrecisionUndefinedBug); |
| 2068 | |
| 2069 | // |
| 2070 | // String |
| 2071 | // ====== |
| 2072 | // |
| 2073 | |
| 2074 | // ES5 15.5.4.14 |
| 2075 | // http://es5.github.com/#x15.5.4.14 |
| 2076 | |
| 2077 | // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers] |
| 2078 | // Many browsers do not split properly with regular expressions or they |
| 2079 | // do not perform the split correctly under obscure conditions. |
| 2080 | // See http://blog.stevenlevithan.com/archives/cross-browser-split |
| 2081 | // I've tested in many browsers and this seems to cover the deviant ones: |
| 2082 | // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""] |
| 2083 | // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""] |
| 2084 | // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not |
| 2085 | // [undefined, "t", undefined, "e", ...] |
| 2086 | // ''.split(/.?/) should be [], not [""] |
| 2087 | // '.'.split(/()()/) should be ["."], not ["", "", "."] |
| 2088 | |
| 2089 | if ( |
| 2090 | 'ab'.split(/(?:ab)*/).length !== 2 || |
| 2091 | '.'.split(/(.?)(.?)/).length !== 4 || |
| 2092 | 'tesst'.split(/(s)*/)[1] === 't' || |
| 2093 | 'test'.split(/(?:)/, -1).length !== 4 || |
| 2094 | ''.split(/.?/).length || |
| 2095 | '.'.split(/()()/).length > 1 |
| 2096 | ) { |
| 2097 | (function () { |
| 2098 | var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group |
| 2099 | var maxSafe32BitInt = Math.pow(2, 32) - 1; |
| 2100 | |
| 2101 | StringPrototype.split = function (separator, limit) { |
| 2102 | var string = String(this); |
| 2103 | if (typeof separator === 'undefined' && limit === 0) { |
| 2104 | return []; |
| 2105 | } |
| 2106 | |
| 2107 | // If `separator` is not a regex, use native split |
| 2108 | if (!isRegex(separator)) { |
| 2109 | return strSplit(this, separator, limit); |
| 2110 | } |
| 2111 | |
| 2112 | var output = []; |
| 2113 | var flags = (separator.ignoreCase ? 'i' : '') + |
| 2114 | (separator.multiline ? 'm' : '') + |
| 2115 | (separator.unicode ? 'u' : '') + // in ES6 |
| 2116 | (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6 |
| 2117 | lastLastIndex = 0, |
| 2118 | // Make `global` and avoid `lastIndex` issues by working with a copy |
| 2119 | separator2, match, lastIndex, lastLength; |
| 2120 | var separatorCopy = new RegExp(separator.source, flags + 'g'); |
| 2121 | if (!compliantExecNpcg) { |
| 2122 | // Doesn't need flags gy, but they don't hurt |
| 2123 | separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags); |
| 2124 | } |
| 2125 | /* Values for `limit`, per the spec: |
| 2126 | * If undefined: 4294967295 // maxSafe32BitInt |
| 2127 | * If 0, Infinity, or NaN: 0 |
| 2128 | * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; |
| 2129 | * If negative number: 4294967296 - Math.floor(Math.abs(limit)) |
| 2130 | * If other: Type-convert, then use the above rules |
| 2131 | */ |
| 2132 | var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit); |
| 2133 | match = separatorCopy.exec(string); |
| 2134 | while (match) { |
| 2135 | // `separatorCopy.lastIndex` is not reliable cross-browser |
| 2136 | lastIndex = match.index + match[0].length; |
| 2137 | if (lastIndex > lastLastIndex) { |
| 2138 | pushCall(output, strSlice(string, lastLastIndex, match.index)); |
| 2139 | // Fix browsers whose `exec` methods don't consistently return `undefined` for |
| 2140 | // nonparticipating capturing groups |
| 2141 | if (!compliantExecNpcg && match.length > 1) { |
| 2142 | /* eslint-disable no-loop-func */ |
| 2143 | match[0].replace(separator2, function () { |
| 2144 | for (var i = 1; i < arguments.length - 2; i++) { |
| 2145 | if (typeof arguments[i] === 'undefined') { |
| 2146 | match[i] = void 0; |
| 2147 | } |
| 2148 | } |
| 2149 | }); |
| 2150 | /* eslint-enable no-loop-func */ |
| 2151 | } |
| 2152 | if (match.length > 1 && match.index < string.length) { |
| 2153 | array_push.apply(output, arraySlice(match, 1)); |
| 2154 | } |
| 2155 | lastLength = match[0].length; |
| 2156 | lastLastIndex = lastIndex; |
| 2157 | if (output.length >= splitLimit) { |
| 2158 | break; |
| 2159 | } |
| 2160 | } |
| 2161 | if (separatorCopy.lastIndex === match.index) { |
| 2162 | separatorCopy.lastIndex++; // Avoid an infinite loop |
| 2163 | } |
| 2164 | match = separatorCopy.exec(string); |
| 2165 | } |
| 2166 | if (lastLastIndex === string.length) { |
| 2167 | if (lastLength || !separatorCopy.test('')) { |
| 2168 | pushCall(output, ''); |
| 2169 | } |
| 2170 | } else { |
| 2171 | pushCall(output, strSlice(string, lastLastIndex)); |
| 2172 | } |
| 2173 | return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output; |
| 2174 | }; |
| 2175 | }()); |
| 2176 | |
| 2177 | // [bugfix, chrome] |
| 2178 | // If separator is undefined, then the result array contains just one String, |
| 2179 | // which is the this value (converted to a String). If limit is not undefined, |
| 2180 | // then the output array is truncated so that it contains no more than limit |
| 2181 | // elements. |
| 2182 | // "0".split(undefined, 0) -> [] |
| 2183 | } else if ('0'.split(void 0, 0).length) { |
| 2184 | StringPrototype.split = function split(separator, limit) { |
| 2185 | if (typeof separator === 'undefined' && limit === 0) { |
| 2186 | return []; |
| 2187 | } |
| 2188 | return strSplit(this, separator, limit); |
| 2189 | }; |
| 2190 | } |
| 2191 | |
| 2192 | var str_replace = StringPrototype.replace; |
| 2193 | var replaceReportsGroupsCorrectly = (function () { |
| 2194 | var groups = []; |
| 2195 | 'x'.replace(/x(.)?/g, function (match, group) { |
| 2196 | pushCall(groups, group); |
| 2197 | }); |
| 2198 | return groups.length === 1 && typeof groups[0] === 'undefined'; |
| 2199 | }()); |
| 2200 | |
| 2201 | if (!replaceReportsGroupsCorrectly) { |
| 2202 | StringPrototype.replace = function replace(searchValue, replaceValue) { |
| 2203 | var isFn = isCallable(replaceValue); |
| 2204 | var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source); |
| 2205 | if (!isFn || !hasCapturingGroups) { |
| 2206 | return str_replace.call(this, searchValue, replaceValue); |
| 2207 | } else { |
| 2208 | var wrappedReplaceValue = function (match) { |
| 2209 | var length = arguments.length; |
| 2210 | var originalLastIndex = searchValue.lastIndex; |
| 2211 | searchValue.lastIndex = 0; |
| 2212 | var args = searchValue.exec(match) || []; |
| 2213 | searchValue.lastIndex = originalLastIndex; |
| 2214 | pushCall(args, arguments[length - 2], arguments[length - 1]); |
| 2215 | return replaceValue.apply(this, args); |
| 2216 | }; |
| 2217 | return str_replace.call(this, searchValue, wrappedReplaceValue); |
| 2218 | } |
| 2219 | }; |
| 2220 | } |
| 2221 | |
| 2222 | // ECMA-262, 3rd B.2.3 |
| 2223 | // Not an ECMAScript standard, although ECMAScript 3rd Edition has a |
| 2224 | // non-normative section suggesting uniform semantics and it should be |
| 2225 | // normalized across all browsers |
| 2226 | // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE |
| 2227 | var string_substr = StringPrototype.substr; |
| 2228 | var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b'; |
| 2229 | defineProperties(StringPrototype, { |
| 2230 | substr: function substr(start, length) { |
| 2231 | var normalizedStart = start; |
| 2232 | if (start < 0) { |
| 2233 | normalizedStart = max(this.length + start, 0); |
| 2234 | } |
| 2235 | return string_substr.call(this, normalizedStart, length); |
| 2236 | } |
| 2237 | }, hasNegativeSubstrBug); |
| 2238 | |
| 2239 | // ES5 15.5.4.20 |
| 2240 | // whitespace from: http://es5.github.io/#x15.5.4.20 |
| 2241 | var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + |
| 2242 | '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + |
| 2243 | '\u2029\uFEFF'; |
| 2244 | var zeroWidth = '\u200b'; |
| 2245 | var wsRegexChars = '[' + ws + ']'; |
| 2246 | var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*'); |
| 2247 | var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$'); |
| 2248 | var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim()); |
| 2249 | defineProperties(StringPrototype, { |
| 2250 | // http://blog.stevenlevithan.com/archives/faster-trim-javascript |
| 2251 | // http://perfectionkills.com/whitespace-deviations/ |
| 2252 | trim: function trim() { |
| 2253 | if (typeof this === 'undefined' || this === null) { |
| 2254 | throw new TypeError("can't convert " + this + ' to object'); |
| 2255 | } |
| 2256 | return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, ''); |
| 2257 | } |
| 2258 | }, hasTrimWhitespaceBug); |
| 2259 | var trim = call.bind(String.prototype.trim); |
| 2260 | |
| 2261 | var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1; |
| 2262 | defineProperties(StringPrototype, { |
| 2263 | lastIndexOf: function lastIndexOf(searchString) { |
| 2264 | if (typeof this === 'undefined' || this === null) { |
| 2265 | throw new TypeError("can't convert " + this + ' to object'); |
| 2266 | } |
| 2267 | var S = $String(this); |
| 2268 | var searchStr = $String(searchString); |
| 2269 | var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN; |
| 2270 | var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos); |
| 2271 | var start = min(max(pos, 0), S.length); |
| 2272 | var searchLen = searchStr.length; |
| 2273 | var k = start + searchLen; |
| 2274 | while (k > 0) { |
| 2275 | k = max(0, k - searchLen); |
| 2276 | var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr); |
| 2277 | if (index !== -1) { |
| 2278 | return k + index; |
| 2279 | } |
| 2280 | } |
| 2281 | return -1; |
| 2282 | } |
| 2283 | }, hasLastIndexBug); |
| 2284 | |
| 2285 | var originalLastIndexOf = StringPrototype.lastIndexOf; |
| 2286 | defineProperties(StringPrototype, { |
| 2287 | lastIndexOf: function lastIndexOf(searchString) { |
| 2288 | return originalLastIndexOf.apply(this, arguments); |
| 2289 | } |
| 2290 | }, StringPrototype.lastIndexOf.length !== 1); |
| 2291 | |
| 2292 | // ES-5 15.1.2.2 |
| 2293 | /* eslint-disable radix */ |
| 2294 | if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) { |
| 2295 | /* eslint-enable radix */ |
| 2296 | /* global parseInt: true */ |
| 2297 | parseInt = (function (origParseInt) { |
| 2298 | var hexRegex = /^[\-+]?0[xX]/; |
| 2299 | return function parseInt(str, radix) { |
| 2300 | var string = trim(String(str)); |
| 2301 | var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10); |
| 2302 | return origParseInt(string, defaultedRadix); |
| 2303 | }; |
| 2304 | }(parseInt)); |
| 2305 | } |
| 2306 | |
| 2307 | // https://es5.github.io/#x15.1.2.3 |
| 2308 | if (1 / parseFloat('-0') !== -Infinity) { |
| 2309 | /* global parseFloat: true */ |
| 2310 | parseFloat = (function (origParseFloat) { |
| 2311 | return function parseFloat(string) { |
| 2312 | var inputString = trim(String(string)); |
| 2313 | var result = origParseFloat(inputString); |
| 2314 | return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result; |
| 2315 | }; |
| 2316 | }(parseFloat)); |
| 2317 | } |
| 2318 | |
| 2319 | if (String(new RangeError('test')) !== 'RangeError: test') { |
| 2320 | var errorToStringShim = function toString() { |
| 2321 | if (typeof this === 'undefined' || this === null) { |
| 2322 | throw new TypeError("can't convert " + this + ' to object'); |
| 2323 | } |
| 2324 | var name = this.name; |
| 2325 | if (typeof name === 'undefined') { |
| 2326 | name = 'Error'; |
| 2327 | } else if (typeof name !== 'string') { |
| 2328 | name = $String(name); |
| 2329 | } |
| 2330 | var msg = this.message; |
| 2331 | if (typeof msg === 'undefined') { |
| 2332 | msg = ''; |
| 2333 | } else if (typeof msg !== 'string') { |
| 2334 | msg = $String(msg); |
| 2335 | } |
| 2336 | if (!name) { |
| 2337 | return msg; |
| 2338 | } |
| 2339 | if (!msg) { |
| 2340 | return name; |
| 2341 | } |
| 2342 | return name + ': ' + msg; |
| 2343 | }; |
| 2344 | // can't use defineProperties here because of toString enumeration issue in IE <= 8 |
| 2345 | Error.prototype.toString = errorToStringShim; |
| 2346 | } |
| 2347 | |
| 2348 | if (supportsDescriptors) { |
| 2349 | var ensureNonEnumerable = function (obj, prop) { |
| 2350 | if (isEnum(obj, prop)) { |
| 2351 | var desc = Object.getOwnPropertyDescriptor(obj, prop); |
| 2352 | if (desc.configurable) { |
| 2353 | desc.enumerable = false; |
| 2354 | Object.defineProperty(obj, prop, desc); |
| 2355 | } |
| 2356 | } |
| 2357 | }; |
| 2358 | ensureNonEnumerable(Error.prototype, 'message'); |
| 2359 | if (Error.prototype.message !== '') { |
| 2360 | Error.prototype.message = ''; |
| 2361 | } |
| 2362 | ensureNonEnumerable(Error.prototype, 'name'); |
| 2363 | } |
| 2364 | |
| 2365 | if (String(/a/mig) !== '/a/gim') { |
| 2366 | var regexToString = function toString() { |
| 2367 | var str = '/' + this.source + '/'; |
| 2368 | if (this.global) { |
| 2369 | str += 'g'; |
| 2370 | } |
| 2371 | if (this.ignoreCase) { |
| 2372 | str += 'i'; |
| 2373 | } |
| 2374 | if (this.multiline) { |
| 2375 | str += 'm'; |
| 2376 | } |
| 2377 | return str; |
| 2378 | }; |
| 2379 | // can't use defineProperties here because of toString enumeration issue in IE <= 8 |
| 2380 | RegExp.prototype.toString = regexToString; |
| 2381 | } |
| 2382 | })); |
| 2383 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2384 | 'use strict'; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2385 | /*jslint eqeq: true*/ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2386 | |
| 2387 | Handlebars.registerHelper('sanitize', function(html) { |
| 2388 | // Strip the script tags from the html, and return it as a Handlebars.SafeString |
| 2389 | html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, ''); |
| 2390 | return new Handlebars.SafeString(html); |
| 2391 | }); |
| 2392 | |
| 2393 | Handlebars.registerHelper('renderTextParam', function(param) { |
| 2394 | var result, type = 'text', idAtt = ''; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2395 | var paramType = param.type || param.schema.type || ''; |
| 2396 | var isArray = paramType.toLowerCase() === 'array' || param.allowMultiple; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2397 | var defaultValue = isArray && Array.isArray(param.default) ? param.default.join('\n') : param.default; |
| 2398 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2399 | var dataVendorExtensions = Object.keys(param).filter(function(property) { |
| 2400 | // filter X-data- properties |
| 2401 | return property.match(/^X-data-/i) !== null; |
| 2402 | }).reduce(function(result, property) { |
| 2403 | // remove X- from property name, so it results in html attributes like data-foo='bar' |
| 2404 | return result += ' ' + property.substring(2, property.length) + '=\'' + param[property] + '\''; |
| 2405 | }, ''); |
| 2406 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2407 | if (typeof defaultValue === 'undefined') { |
| 2408 | defaultValue = ''; |
| 2409 | } |
| 2410 | |
| 2411 | if(param.format && param.format === 'password') { |
| 2412 | type = 'password'; |
| 2413 | } |
| 2414 | |
| 2415 | if(param.valueId) { |
| 2416 | idAtt = ' id=\'' + param.valueId + '\''; |
| 2417 | } |
| 2418 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2419 | if (typeof defaultValue === 'string' || defaultValue instanceof String) { |
| 2420 | defaultValue = defaultValue.replace(/'/g,'''); |
| 2421 | } |
| 2422 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2423 | if(isArray) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2424 | result = '<textarea class=\'body-textarea' + (param.required ? ' required' : '') + '\' name=\'' + param.name + '\'' + idAtt + dataVendorExtensions; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2425 | result += ' placeholder=\'Provide multiple values in new lines' + (param.required ? ' (at least one required).' : '.') + '\'>'; |
| 2426 | result += defaultValue + '</textarea>'; |
| 2427 | } else { |
| 2428 | var parameterClass = 'parameter'; |
| 2429 | if(param.required) { |
| 2430 | parameterClass += ' required'; |
| 2431 | } |
| 2432 | result = '<input class=\'' + parameterClass + '\' minlength=\'' + (param.required ? 1 : 0) + '\''; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2433 | result += ' name=\'' + param.name +'\' placeholder=\'' + (param.required ? '(required)' : '') + '\'' + idAtt + dataVendorExtensions; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2434 | result += ' type=\'' + type + '\' value=\'' + defaultValue + '\'/>'; |
| 2435 | } |
| 2436 | return new Handlebars.SafeString(result); |
| 2437 | }); |
| 2438 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2439 | Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) { |
| 2440 | |
| 2441 | switch (operator) { |
| 2442 | case '==': |
| 2443 | return (v1 == v2) ? options.fn(this) : options.inverse(this); |
| 2444 | case '===': |
| 2445 | return (v1 === v2) ? options.fn(this) : options.inverse(this); |
| 2446 | case '<': |
| 2447 | return (v1 < v2) ? options.fn(this) : options.inverse(this); |
| 2448 | case '<=': |
| 2449 | return (v1 <= v2) ? options.fn(this) : options.inverse(this); |
| 2450 | case '>': |
| 2451 | return (v1 > v2) ? options.fn(this) : options.inverse(this); |
| 2452 | case '>=': |
| 2453 | return (v1 >= v2) ? options.fn(this) : options.inverse(this); |
| 2454 | case '&&': |
| 2455 | return (v1 && v2) ? options.fn(this) : options.inverse(this); |
| 2456 | case '||': |
| 2457 | return (v1 || v2) ? options.fn(this) : options.inverse(this); |
| 2458 | default: |
| 2459 | return options.inverse(this); |
| 2460 | } |
| 2461 | }); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2462 | this["Handlebars"]["templates"]["main"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 2463 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression, buffer = " <div class=\"info_title\">" |
| 2464 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1), depth0)) |
| 2465 | + "</div>\n <div class=\"info_description markdown\">"; |
| 2466 | stack1 = lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.description : stack1), depth0); |
| 2467 | if (stack1 != null) { buffer += stack1; } |
| 2468 | buffer += "</div>\n"; |
| 2469 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.externalDocs : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); |
| 2470 | if (stack1 != null) { buffer += stack1; } |
| 2471 | buffer += " "; |
| 2472 | stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1), {"name":"if","hash":{},"fn":this.program(4, data),"inverse":this.noop,"data":data}); |
| 2473 | if (stack1 != null) { buffer += stack1; } |
| 2474 | buffer += "\n "; |
| 2475 | stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1), {"name":"if","hash":{},"fn":this.program(6, data),"inverse":this.noop,"data":data}); |
| 2476 | if (stack1 != null) { buffer += stack1; } |
| 2477 | buffer += "\n "; |
| 2478 | stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), {"name":"if","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data}); |
| 2479 | if (stack1 != null) { buffer += stack1; } |
| 2480 | buffer += "\n "; |
| 2481 | stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data}); |
| 2482 | if (stack1 != null) { buffer += stack1; } |
| 2483 | buffer += "\n "; |
| 2484 | stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1), {"name":"if","hash":{},"fn":this.program(12, data),"inverse":this.noop,"data":data}); |
| 2485 | if (stack1 != null) { buffer += stack1; } |
| 2486 | return buffer + "\n"; |
| 2487 | },"2":function(depth0,helpers,partials,data) { |
| 2488 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 2489 | return " <p>" |
| 2490 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.description : stack1), depth0)) |
| 2491 | + "</p>\n <a href=\"" |
| 2492 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1), depth0)) |
| 2493 | + "\" target=\"_blank\">" |
| 2494 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1), depth0)) |
| 2495 | + "</a>\n"; |
| 2496 | },"4":function(depth0,helpers,partials,data) { |
| 2497 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2498 | return "<div class=\"info_tos\"><a target=\"_blank\" href=\"" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2499 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1), depth0)) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2500 | + "\" data-sw-translate>Terms of service</a></div>"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2501 | },"6":function(depth0,helpers,partials,data) { |
| 2502 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2503 | return "<div><div class='info_name' style=\"display: inline\" data-sw-translate>Created by </div> " |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2504 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1), depth0)) |
| 2505 | + "</div>"; |
| 2506 | },"8":function(depth0,helpers,partials,data) { |
| 2507 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2508 | return "<div class='info_url' data-sw-translate>See more at <a href=\"" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2509 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), depth0)) |
| 2510 | + "\">" |
| 2511 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), depth0)) |
| 2512 | + "</a></div>"; |
| 2513 | },"10":function(depth0,helpers,partials,data) { |
| 2514 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2515 | return "<div class='info_email'><a target=\"_parent\" href=\"mailto:" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2516 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1), depth0)) |
| 2517 | + "?subject=" |
| 2518 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1), depth0)) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2519 | + "\" data-sw-translate>Contact the developer</a></div>"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2520 | },"12":function(depth0,helpers,partials,data) { |
| 2521 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2522 | return "<div class='info_license'><a target=\"_blank\" href='" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2523 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.url : stack1), depth0)) |
| 2524 | + "'>" |
| 2525 | + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.name : stack1), depth0)) |
| 2526 | + "</a></div>"; |
| 2527 | },"14":function(depth0,helpers,partials,data) { |
| 2528 | var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2529 | return " , <span style=\"font-variant: small-caps\" data-sw-translate>api version</span>: " |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2530 | + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1), depth0)) |
| 2531 | + "\n "; |
| 2532 | },"16":function(depth0,helpers,partials,data) { |
| 2533 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2534 | return " <span style=\"float:right\"><a target=\"_blank\" href=\"" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2535 | + escapeExpression(((helper = (helper = helpers.validatorUrl || (depth0 != null ? depth0.validatorUrl : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"validatorUrl","hash":{},"data":data}) : helper))) |
| 2536 | + "/debug?url=" |
| 2537 | + escapeExpression(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper))) |
| 2538 | + "\"><img id=\"validator\" src=\"" |
| 2539 | + escapeExpression(((helper = (helper = helpers.validatorUrl || (depth0 != null ? depth0.validatorUrl : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"validatorUrl","hash":{},"data":data}) : helper))) |
| 2540 | + "?url=" |
| 2541 | + escapeExpression(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper))) |
| 2542 | + "\"></a>\n </span>\n"; |
| 2543 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 2544 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class='info' id='api_info'>\n"; |
| 2545 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.info : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 2546 | if (stack1 != null) { buffer += stack1; } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2547 | buffer += "</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>: " |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2548 | + escapeExpression(((helper = (helper = helpers.basePath || (depth0 != null ? depth0.basePath : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"basePath","hash":{},"data":data}) : helper))) |
| 2549 | + "\n"; |
| 2550 | stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1), {"name":"if","hash":{},"fn":this.program(14, data),"inverse":this.noop,"data":data}); |
| 2551 | if (stack1 != null) { buffer += stack1; } |
| 2552 | buffer += "]\n"; |
| 2553 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.validatorUrl : depth0), {"name":"if","hash":{},"fn":this.program(16, data),"inverse":this.noop,"data":data}); |
| 2554 | if (stack1 != null) { buffer += stack1; } |
| 2555 | return buffer + " </h4>\n </div>\n</div>\n"; |
| 2556 | },"useData":true}); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2557 | this["Handlebars"]["templates"]["oauth2"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 2558 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <li>\n <input class=\"oauth-scope\" type=\"checkbox\" data-scope=\"" |
| 2559 | + escapeExpression(((helper = (helper = helpers.scope || (depth0 != null ? depth0.scope : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"scope","hash":{},"data":data}) : helper))) |
| 2560 | + "\" oauthtype=\"" |
| 2561 | + escapeExpression(((helper = (helper = helpers.OAuthSchemeKey || (depth0 != null ? depth0.OAuthSchemeKey : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"OAuthSchemeKey","hash":{},"data":data}) : helper))) |
| 2562 | + "\"/>\n <label>" |
| 2563 | + escapeExpression(((helper = (helper = helpers.scope || (depth0 != null ? depth0.scope : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"scope","hash":{},"data":data}) : helper))) |
| 2564 | + "</label><br/>\n <span class=\"api-scope-desc\">" |
| 2565 | + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper))) |
| 2566 | + "\n"; |
| 2567 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.OAuthSchemeKey : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); |
| 2568 | if (stack1 != null) { buffer += stack1; } |
| 2569 | return buffer + " </span>\n </li>\n"; |
| 2570 | },"2":function(depth0,helpers,partials,data) { |
| 2571 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2572 | return " (" |
| 2573 | + escapeExpression(((helper = (helper = helpers.OAuthSchemeKey || (depth0 != null ? depth0.OAuthSchemeKey : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"OAuthSchemeKey","hash":{},"data":data}) : helper))) |
| 2574 | + ")\n"; |
| 2575 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 2576 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div>\n <h3 class=\"auth__title\">Select OAuth2.0 Scopes</h3>\n <p>" |
| 2577 | + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper))) |
| 2578 | + "</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 <p><strong> " |
| 2579 | + escapeExpression(((helper = (helper = helpers.appName || (depth0 != null ? depth0.appName : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"appName","hash":{},"data":data}) : helper))) |
| 2580 | + " </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n <p>Authorization URL: " |
| 2581 | + escapeExpression(((helper = (helper = helpers.authorizationUrl || (depth0 != null ? depth0.authorizationUrl : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"authorizationUrl","hash":{},"data":data}) : helper))) |
| 2582 | + "</p>\n <p>flow: " |
| 2583 | + escapeExpression(((helper = (helper = helpers.flow || (depth0 != null ? depth0.flow : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"flow","hash":{},"data":data}) : helper))) |
| 2584 | + "</p>\n <ul class=\"api-popup-scopes\">\n"; |
| 2585 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.scopes : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 2586 | if (stack1 != null) { buffer += stack1; } |
| 2587 | return buffer + " </ul>\n</div>"; |
| 2588 | },"useData":true}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2589 | this["Handlebars"]["templates"]["operation"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 2590 | return "deprecated"; |
| 2591 | },"3":function(depth0,helpers,partials,data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2592 | return " <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2593 | },"5":function(depth0,helpers,partials,data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2594 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = " <h4><span data-sw-translate>Implementation Notes</span></h4>\n <div class=\"markdown\">"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2595 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 2596 | if (stack1 != null) { buffer += stack1; } |
| 2597 | return buffer + "</div>\n"; |
| 2598 | },"7":function(depth0,helpers,partials,data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2599 | return " <div class='authorize-wrapper authorize-wrapper_operation'></div>\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2600 | },"9":function(depth0,helpers,partials,data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2601 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <div class=\"response-class\">\n <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> " |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2602 | + escapeExpression(((helper = (helper = helpers.successCode || (depth0 != null ? depth0.successCode : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"successCode","hash":{},"data":data}) : helper))) |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2603 | + ")</h4>\n "; |
| 2604 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.successDescription : depth0), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data}); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2605 | if (stack1 != null) { buffer += stack1; } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2606 | return buffer + "\n <p><span class=\"model-signature\" /></p>\n <br/>\n <div class=\"response-content-type\" />\n </div>\n"; |
| 2607 | },"10":function(depth0,helpers,partials,data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2608 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "<div class=\"markdown\">"; |
| 2609 | stack1 = ((helper = (helper = helpers.successDescription || (depth0 != null ? depth0.successDescription : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"successDescription","hash":{},"data":data}) : helper)); |
| 2610 | if (stack1 != null) { buffer += stack1; } |
| 2611 | return buffer + "</div>"; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2612 | },"12":function(depth0,helpers,partials,data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2613 | var stack1, buffer = " <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"; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2614 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"each","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data}); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2615 | if (stack1 != null) { buffer += stack1; } |
| 2616 | return buffer + " </tbody>\n </table>\n"; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2617 | },"13":function(depth0,helpers,partials,data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2618 | var lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 2619 | return " <tr>\n <td>" |
| 2620 | + escapeExpression(lambda((data && data.key), depth0)) |
| 2621 | + "</td>\n <td>" |
| 2622 | + escapeExpression(lambda((depth0 != null ? depth0.description : depth0), depth0)) |
| 2623 | + "</td>\n <td>" |
| 2624 | + escapeExpression(lambda((depth0 != null ? depth0.type : depth0), depth0)) |
| 2625 | + "</td>\n <td>" |
| 2626 | + escapeExpression(lambda((depth0 != null ? depth0.other : depth0), depth0)) |
| 2627 | + "</td>\n </tr>\n"; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2628 | },"15":function(depth0,helpers,partials,data) { |
| 2629 | 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"; |
| 2630 | },"17":function(depth0,helpers,partials,data) { |
| 2631 | 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"; |
| 2632 | },"19":function(depth0,helpers,partials,data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2633 | return ""; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2634 | },"21":function(depth0,helpers,partials,data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2635 | 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"; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2636 | },"23":function(depth0,helpers,partials,data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2637 | return " <h4 data-sw-translate>Request Headers</h4>\n <div class='block request_headers'></div>\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2638 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2639 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <ul class='operations' >\n <li class='" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2640 | + escapeExpression(((helper = (helper = helpers.method || (depth0 != null ? depth0.method : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"method","hash":{},"data":data}) : helper))) |
| 2641 | + " operation' id='" |
| 2642 | + escapeExpression(((helper = (helper = helpers.parentId || (depth0 != null ? depth0.parentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parentId","hash":{},"data":data}) : helper))) |
| 2643 | + "_" |
| 2644 | + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper))) |
| 2645 | + "'>\n <div class='heading'>\n <h3>\n <span class='http_method'>\n <a href='#!/" |
| 2646 | + escapeExpression(((helper = (helper = helpers.encodedParentId || (depth0 != null ? depth0.encodedParentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"encodedParentId","hash":{},"data":data}) : helper))) |
| 2647 | + "/" |
| 2648 | + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper))) |
| 2649 | + "' class=\"toggleOperation\">" |
| 2650 | + escapeExpression(((helper = (helper = helpers.method || (depth0 != null ? depth0.method : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"method","hash":{},"data":data}) : helper))) |
| 2651 | + "</a>\n </span>\n <span class='path'>\n <a href='#!/" |
| 2652 | + escapeExpression(((helper = (helper = helpers.encodedParentId || (depth0 != null ? depth0.encodedParentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"encodedParentId","hash":{},"data":data}) : helper))) |
| 2653 | + "/" |
| 2654 | + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper))) |
| 2655 | + "' class=\"toggleOperation "; |
| 2656 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.deprecated : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 2657 | if (stack1 != null) { buffer += stack1; } |
| 2658 | buffer += "\">" |
| 2659 | + escapeExpression(((helper = (helper = helpers.path || (depth0 != null ? depth0.path : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"path","hash":{},"data":data}) : helper))) |
| 2660 | + "</a>\n </span>\n </h3>\n <ul class='options'>\n <li>\n <a href='#!/" |
| 2661 | + escapeExpression(((helper = (helper = helpers.encodedParentId || (depth0 != null ? depth0.encodedParentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"encodedParentId","hash":{},"data":data}) : helper))) |
| 2662 | + "/" |
| 2663 | + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper))) |
| 2664 | + "' class=\"toggleOperation\">"; |
| 2665 | stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"summary","hash":{},"data":data}) : helper)); |
| 2666 | if (stack1 != null) { buffer += stack1; } |
| 2667 | buffer += "</a>\n </li>\n </ul>\n </div>\n <div class='content' id='" |
| 2668 | + escapeExpression(((helper = (helper = helpers.parentId || (depth0 != null ? depth0.parentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parentId","hash":{},"data":data}) : helper))) |
| 2669 | + "_" |
| 2670 | + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper))) |
| 2671 | + "_content' style='display:none'>\n"; |
| 2672 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.deprecated : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data}); |
| 2673 | if (stack1 != null) { buffer += stack1; } |
| 2674 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.description : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data}); |
| 2675 | if (stack1 != null) { buffer += stack1; } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2676 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.security : depth0), {"name":"if","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data}); |
| 2677 | if (stack1 != null) { buffer += stack1; } |
| 2678 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.type : depth0), {"name":"if","hash":{},"fn":this.program(9, data),"inverse":this.noop,"data":data}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2679 | if (stack1 != null) { buffer += stack1; } |
| 2680 | buffer += "\n"; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2681 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"if","hash":{},"fn":this.program(12, data),"inverse":this.noop,"data":data}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2682 | if (stack1 != null) { buffer += stack1; } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2683 | buffer += "\n <form accept-charset='UTF-8' class='sandbox'>\n <div style='margin:0;padding:0;display:inline'></div>\n"; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2684 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.parameters : depth0), {"name":"if","hash":{},"fn":this.program(15, data),"inverse":this.noop,"data":data}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2685 | if (stack1 != null) { buffer += stack1; } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2686 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.responseMessages : depth0), {"name":"if","hash":{},"fn":this.program(17, data),"inverse":this.noop,"data":data}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2687 | if (stack1 != null) { buffer += stack1; } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2688 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isReadOnly : depth0), {"name":"if","hash":{},"fn":this.program(19, data),"inverse":this.program(21, data),"data":data}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2689 | if (stack1 != null) { buffer += stack1; } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2690 | buffer += " </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"; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2691 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showRequestHeaders : depth0), {"name":"if","hash":{},"fn":this.program(23, data),"inverse":this.noop,"data":data}); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2692 | if (stack1 != null) { buffer += stack1; } |
| 2693 | return buffer + " <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"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2694 | },"useData":true}); |
| 2695 | this["Handlebars"]["templates"]["param_list"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 2696 | return " required"; |
| 2697 | },"3":function(depth0,helpers,partials,data) { |
| 2698 | return " multiple=\"multiple\""; |
| 2699 | },"5":function(depth0,helpers,partials,data) { |
| 2700 | return " required "; |
| 2701 | },"7":function(depth0,helpers,partials,data) { |
| 2702 | var stack1, buffer = " <option "; |
| 2703 | stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.hasDefault : depth0), {"name":"unless","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data}); |
| 2704 | if (stack1 != null) { buffer += stack1; } |
| 2705 | return buffer + " value=''></option>\n"; |
| 2706 | },"8":function(depth0,helpers,partials,data) { |
| 2707 | return " selected=\"\" "; |
| 2708 | },"10":function(depth0,helpers,partials,data) { |
| 2709 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "\n <option "; |
| 2710 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isDefault : depth0), {"name":"if","hash":{},"fn":this.program(11, data),"inverse":this.noop,"data":data}); |
| 2711 | if (stack1 != null) { buffer += stack1; } |
| 2712 | buffer += " value='" |
| 2713 | + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper))) |
| 2714 | + "'> " |
| 2715 | + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper))) |
| 2716 | + " "; |
| 2717 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isDefault : depth0), {"name":"if","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data}); |
| 2718 | if (stack1 != null) { buffer += stack1; } |
| 2719 | return buffer + " </option>\n\n"; |
| 2720 | },"11":function(depth0,helpers,partials,data) { |
| 2721 | return " selected=\"\" "; |
| 2722 | },"13":function(depth0,helpers,partials,data) { |
| 2723 | return " (default) "; |
| 2724 | },"15":function(depth0,helpers,partials,data) { |
| 2725 | return "<strong>"; |
| 2726 | },"17":function(depth0,helpers,partials,data) { |
| 2727 | return "</strong>"; |
| 2728 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 2729 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code"; |
| 2730 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 2731 | if (stack1 != null) { buffer += stack1; } |
| 2732 | buffer += "'><label for='" |
| 2733 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2734 | + "'>" |
| 2735 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2736 | + "</label></td>\n<td>\n <select "; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2737 | stack1 = ((helpers.isArray || (depth0 && depth0.isArray) || helperMissing).call(depth0, depth0, {"name":"isArray","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data})); |
| 2738 | if (stack1 != null) { buffer += stack1; } |
| 2739 | buffer += " class=\"parameter "; |
| 2740 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data}); |
| 2741 | if (stack1 != null) { buffer += stack1; } |
| 2742 | buffer += "\" name=\"" |
| 2743 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2744 | + "\" id=\"" |
| 2745 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2746 | + "\">\n\n"; |
| 2747 | stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"unless","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data}); |
| 2748 | if (stack1 != null) { buffer += stack1; } |
| 2749 | buffer += "\n"; |
| 2750 | stack1 = helpers.each.call(depth0, ((stack1 = (depth0 != null ? depth0.allowableValues : depth0)) != null ? stack1.descriptiveValues : stack1), {"name":"each","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data}); |
| 2751 | if (stack1 != null) { buffer += stack1; } |
| 2752 | buffer += "\n </select>\n</td>\n<td class=\"markdown\">"; |
| 2753 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(15, data),"inverse":this.noop,"data":data}); |
| 2754 | if (stack1 != null) { buffer += stack1; } |
| 2755 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 2756 | if (stack1 != null) { buffer += stack1; } |
| 2757 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(17, data),"inverse":this.noop,"data":data}); |
| 2758 | if (stack1 != null) { buffer += stack1; } |
| 2759 | buffer += "</td>\n<td>"; |
| 2760 | stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper)); |
| 2761 | if (stack1 != null) { buffer += stack1; } |
| 2762 | return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| 2763 | },"useData":true}); |
| 2764 | this["Handlebars"]["templates"]["param_readonly_required"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 2765 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2766 | return " <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='" |
| 2767 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2768 | + "' id='" |
| 2769 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2770 | + "'>" |
| 2771 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 2772 | + "</textarea>\n"; |
| 2773 | },"3":function(depth0,helpers,partials,data) { |
| 2774 | var stack1, buffer = ""; |
| 2775 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(4, data),"inverse":this.program(6, data),"data":data}); |
| 2776 | if (stack1 != null) { buffer += stack1; } |
| 2777 | return buffer; |
| 2778 | },"4":function(depth0,helpers,partials,data) { |
| 2779 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2780 | return " " |
| 2781 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 2782 | + "\n"; |
| 2783 | },"6":function(depth0,helpers,partials,data) { |
| 2784 | return " (empty)\n"; |
| 2785 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 2786 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code required'><label for='" |
| 2787 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2788 | + "'>" |
| 2789 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2790 | + "</label></td>\n<td>\n"; |
| 2791 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data}); |
| 2792 | if (stack1 != null) { buffer += stack1; } |
| 2793 | buffer += "</td>\n<td class=\"markdown\">"; |
| 2794 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 2795 | if (stack1 != null) { buffer += stack1; } |
| 2796 | buffer += "</td>\n<td>"; |
| 2797 | stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper)); |
| 2798 | if (stack1 != null) { buffer += stack1; } |
| 2799 | return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| 2800 | },"useData":true}); |
| 2801 | this["Handlebars"]["templates"]["param_readonly"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 2802 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2803 | return " <textarea class='body-textarea' readonly='readonly' name='" |
| 2804 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2805 | + "' id='" |
| 2806 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2807 | + "'>" |
| 2808 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2809 | + "</textarea>\n <div class=\"parameter-content-type\" />\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2810 | },"3":function(depth0,helpers,partials,data) { |
| 2811 | var stack1, buffer = ""; |
| 2812 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(4, data),"inverse":this.program(6, data),"data":data}); |
| 2813 | if (stack1 != null) { buffer += stack1; } |
| 2814 | return buffer; |
| 2815 | },"4":function(depth0,helpers,partials,data) { |
| 2816 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2817 | return " " |
| 2818 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 2819 | + "\n"; |
| 2820 | },"6":function(depth0,helpers,partials,data) { |
| 2821 | return " (empty)\n"; |
| 2822 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 2823 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code'><label for='" |
| 2824 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2825 | + "'>" |
| 2826 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2827 | + "</label></td>\n<td>\n"; |
| 2828 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data}); |
| 2829 | if (stack1 != null) { buffer += stack1; } |
| 2830 | buffer += "</td>\n<td class=\"markdown\">"; |
| 2831 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 2832 | if (stack1 != null) { buffer += stack1; } |
| 2833 | buffer += "</td>\n<td>"; |
| 2834 | stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper)); |
| 2835 | if (stack1 != null) { buffer += stack1; } |
| 2836 | return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| 2837 | },"useData":true}); |
| 2838 | this["Handlebars"]["templates"]["param_required"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 2839 | var stack1, buffer = ""; |
| 2840 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(4, data),"data":data}); |
| 2841 | if (stack1 != null) { buffer += stack1; } |
| 2842 | return buffer; |
| 2843 | },"2":function(depth0,helpers,partials,data) { |
| 2844 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2845 | return " <input type=\"file\" name='" |
| 2846 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2847 | + "' id='" |
| 2848 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2849 | + "'/>\n"; |
| 2850 | },"4":function(depth0,helpers,partials,data) { |
| 2851 | var stack1, buffer = ""; |
| 2852 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.program(7, data),"data":data}); |
| 2853 | if (stack1 != null) { buffer += stack1; } |
| 2854 | return buffer; |
| 2855 | },"5":function(depth0,helpers,partials,data) { |
| 2856 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2857 | return " <div class=\"editor_holder\"></div>\n <textarea class='body-textarea required' placeholder='(required)' name='" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2858 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2859 | + "' id=\"" |
| 2860 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2861 | + "\">" |
| 2862 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 2863 | + "</textarea>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
| 2864 | },"7":function(depth0,helpers,partials,data) { |
| 2865 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2866 | return " <textarea class='body-textarea required' placeholder='(required)' name='" |
| 2867 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2868 | + "' id='" |
| 2869 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2870 | + "'></textarea>\n <div class=\"editor_holder\"></div>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2871 | },"9":function(depth0,helpers,partials,data) { |
| 2872 | var stack1, buffer = ""; |
| 2873 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.program(12, data),"data":data}); |
| 2874 | if (stack1 != null) { buffer += stack1; } |
| 2875 | return buffer; |
| 2876 | },"10":function(depth0,helpers,partials,data) { |
| 2877 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2878 | return " <input class='parameter' class='required' type='file' name='" |
| 2879 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2880 | + "' id='" |
| 2881 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2882 | + "'/>\n"; |
| 2883 | },"12":function(depth0,helpers,partials,data) { |
| 2884 | var stack1, helperMissing=helpers.helperMissing, buffer = ""; |
| 2885 | stack1 = ((helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helperMissing).call(depth0, depth0, {"name":"renderTextParam","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data})); |
| 2886 | if (stack1 != null) { buffer += stack1; } |
| 2887 | return buffer; |
| 2888 | },"13":function(depth0,helpers,partials,data) { |
| 2889 | return ""; |
| 2890 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 2891 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code required'><label for='" |
| 2892 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2893 | + "'>" |
| 2894 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2895 | + "</label></td>\n<td>\n"; |
| 2896 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(9, data),"data":data}); |
| 2897 | if (stack1 != null) { buffer += stack1; } |
| 2898 | buffer += "</td>\n<td>\n <strong><span class=\"markdown\">"; |
| 2899 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 2900 | if (stack1 != null) { buffer += stack1; } |
| 2901 | buffer += "</span></strong>\n</td>\n<td>"; |
| 2902 | stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper)); |
| 2903 | if (stack1 != null) { buffer += stack1; } |
| 2904 | return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n"; |
| 2905 | },"useData":true}); |
| 2906 | this["Handlebars"]["templates"]["param"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 2907 | var stack1, buffer = ""; |
| 2908 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(4, data),"data":data}); |
| 2909 | if (stack1 != null) { buffer += stack1; } |
| 2910 | return buffer; |
| 2911 | },"2":function(depth0,helpers,partials,data) { |
| 2912 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2913 | return " <input type=\"file\" name='" |
| 2914 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2915 | + "' id='" |
| 2916 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2917 | + "'/>\n <div class=\"parameter-content-type\" />\n"; |
| 2918 | },"4":function(depth0,helpers,partials,data) { |
| 2919 | var stack1, buffer = ""; |
| 2920 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.program(7, data),"data":data}); |
| 2921 | if (stack1 != null) { buffer += stack1; } |
| 2922 | return buffer; |
| 2923 | },"5":function(depth0,helpers,partials,data) { |
| 2924 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2925 | return " <div class=\"editor_holder\"></div>\n <textarea class='body-textarea' name='" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2926 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2927 | + "' id='" |
| 2928 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2929 | + "'>" |
| 2930 | + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper))) |
| 2931 | + "</textarea>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
| 2932 | },"7":function(depth0,helpers,partials,data) { |
| 2933 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2934 | return " <textarea class='body-textarea' name='" |
| 2935 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2936 | + "' id='" |
| 2937 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2938 | + "'></textarea>\n <div class=\"editor_holder\"></div>\n <br />\n <div class=\"parameter-content-type\" />\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2939 | },"9":function(depth0,helpers,partials,data) { |
| 2940 | var stack1, buffer = ""; |
| 2941 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(10, data),"data":data}); |
| 2942 | if (stack1 != null) { buffer += stack1; } |
| 2943 | return buffer; |
| 2944 | },"10":function(depth0,helpers,partials,data) { |
| 2945 | var stack1, helperMissing=helpers.helperMissing, buffer = ""; |
| 2946 | stack1 = ((helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helperMissing).call(depth0, depth0, {"name":"renderTextParam","hash":{},"fn":this.program(11, data),"inverse":this.noop,"data":data})); |
| 2947 | if (stack1 != null) { buffer += stack1; } |
| 2948 | return buffer; |
| 2949 | },"11":function(depth0,helpers,partials,data) { |
| 2950 | return ""; |
| 2951 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 2952 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code'><label for='" |
| 2953 | + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper))) |
| 2954 | + "'>" |
| 2955 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 2956 | + "</label></td>\n<td>\n\n"; |
| 2957 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(9, data),"data":data}); |
| 2958 | if (stack1 != null) { buffer += stack1; } |
| 2959 | buffer += "\n</td>\n<td class=\"markdown\">"; |
| 2960 | stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)); |
| 2961 | if (stack1 != null) { buffer += stack1; } |
| 2962 | buffer += "</td>\n<td>"; |
| 2963 | stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper)); |
| 2964 | if (stack1 != null) { buffer += stack1; } |
| 2965 | return buffer + "</td>\n<td>\n <span class=\"model-signature\"></span>\n</td>\n"; |
| 2966 | },"useData":true}); |
| 2967 | this["Handlebars"]["templates"]["parameter_content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 2968 | var stack1, buffer = ""; |
| 2969 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.consumes : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); |
| 2970 | if (stack1 != null) { buffer += stack1; } |
| 2971 | return buffer; |
| 2972 | },"2":function(depth0,helpers,partials,data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2973 | var lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 2974 | return " <option value=\"" |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2975 | + escapeExpression(lambda(depth0, depth0)) |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2976 | + "\">" |
| 2977 | + escapeExpression(lambda(depth0, depth0)) |
| 2978 | + "</option>\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2979 | },"4":function(depth0,helpers,partials,data) { |
| 2980 | return " <option value=\"application/json\">application/json</option>\n"; |
| 2981 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 2982 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label for=\"" |
| 2983 | + escapeExpression(((helper = (helper = helpers.parameterContentTypeId || (depth0 != null ? depth0.parameterContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parameterContentTypeId","hash":{},"data":data}) : helper))) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 2984 | + "\" data-sw-translate>Parameter content type:</label>\n<select name=\"parameterContentType\" id=\"" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2985 | + escapeExpression(((helper = (helper = helpers.parameterContentTypeId || (depth0 != null ? depth0.parameterContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parameterContentTypeId","hash":{},"data":data}) : helper))) |
| 2986 | + "\">\n"; |
| 2987 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.consumes : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(4, data),"data":data}); |
| 2988 | if (stack1 != null) { buffer += stack1; } |
| 2989 | return buffer + "</select>\n"; |
| 2990 | },"useData":true}); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 2991 | this["Handlebars"]["templates"]["popup"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 2992 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 2993 | return "<div class=\"api-popup-dialog-wrapper\">\n <div class=\"api-popup-title\">" |
| 2994 | + escapeExpression(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"title","hash":{},"data":data}) : helper))) |
| 2995 | + "</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>"; |
| 2996 | },"useData":true}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 2997 | this["Handlebars"]["templates"]["resource"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 2998 | return " : "; |
| 2999 | },"3":function(depth0,helpers,partials,data) { |
| 3000 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 3001 | return " <li>\n <a href='" |
| 3002 | + escapeExpression(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper))) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3003 | + "' data-sw-translate>Raw</a>\n </li>\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3004 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 3005 | var stack1, helper, options, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, blockHelperMissing=helpers.blockHelperMissing, buffer = "<div class='heading'>\n <h2>\n <a href='#!/" |
| 3006 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 3007 | + "' class=\"toggleEndpointList\" data-id=\"" |
| 3008 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 3009 | + "\">" |
| 3010 | + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) |
| 3011 | + "</a> "; |
| 3012 | stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : helperMissing),(options={"name":"summary","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}),(typeof helper === functionType ? helper.call(depth0, options) : helper)); |
| 3013 | if (!helpers.summary) { stack1 = blockHelperMissing.call(depth0, stack1, options); } |
| 3014 | if (stack1 != null) { buffer += stack1; } |
| 3015 | stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"summary","hash":{},"data":data}) : helper)); |
| 3016 | if (stack1 != null) { buffer += stack1; } |
| 3017 | buffer += "\n </h2>\n <ul class='options'>\n <li>\n <a href='#!/" |
| 3018 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 3019 | + "' id='endpointListTogger_" |
| 3020 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 3021 | + "' class=\"toggleEndpointList\" data-id=\"" |
| 3022 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3023 | + "\" data-sw-translate>Show/Hide</a>\n </li>\n <li>\n <a href='#' class=\"collapseResource\" data-id=\"" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3024 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3025 | + "\" data-sw-translate>\n List Operations\n </a>\n </li>\n <li>\n <a href='#' class=\"expandResource\" data-id=\"" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3026 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3027 | + "\" data-sw-translate>\n Expand Operations\n </a>\n </li>\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3028 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.url : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data}); |
| 3029 | if (stack1 != null) { buffer += stack1; } |
| 3030 | return buffer + " </ul>\n</div>\n<ul class='endpoints' id='" |
| 3031 | + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper))) |
| 3032 | + "_endpoint_list' style='display:none'>\n\n</ul>\n"; |
| 3033 | },"useData":true}); |
| 3034 | this["Handlebars"]["templates"]["response_content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 3035 | var stack1, buffer = ""; |
| 3036 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); |
| 3037 | if (stack1 != null) { buffer += stack1; } |
| 3038 | return buffer; |
| 3039 | },"2":function(depth0,helpers,partials,data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3040 | var lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 3041 | return " <option value=\"" |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3042 | + escapeExpression(lambda(depth0, depth0)) |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3043 | + "\">" |
| 3044 | + escapeExpression(lambda(depth0, depth0)) |
| 3045 | + "</option>\n"; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3046 | },"4":function(depth0,helpers,partials,data) { |
| 3047 | return " <option value=\"application/json\">application/json</option>\n"; |
| 3048 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3049 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label data-sw-translate for=\"" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3050 | + escapeExpression(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"responseContentTypeId","hash":{},"data":data}) : helper))) |
| 3051 | + "\">Response Content Type</label>\n<select name=\"responseContentType\" id=\"" |
| 3052 | + escapeExpression(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"responseContentTypeId","hash":{},"data":data}) : helper))) |
| 3053 | + "\">\n"; |
| 3054 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(4, data),"data":data}); |
| 3055 | if (stack1 != null) { buffer += stack1; } |
| 3056 | return buffer + "</select>\n"; |
| 3057 | },"useData":true}); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3058 | this["Handlebars"]["templates"]["signature"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 3059 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "\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 "; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3060 | stack1 = ((helper = (helper = helpers.signature || (depth0 != null ? depth0.signature : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signature","hash":{},"data":data}) : helper)); |
| 3061 | if (stack1 != null) { buffer += stack1; } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3062 | buffer += "\n </div>\n\n <div class=\"snippet\">\n"; |
| 3063 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.sampleJSON : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); |
| 3064 | if (stack1 != null) { buffer += stack1; } |
| 3065 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.sampleXML : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data}); |
| 3066 | if (stack1 != null) { buffer += stack1; } |
| 3067 | return buffer + " </div>\n</div>\n"; |
| 3068 | },"2":function(depth0,helpers,partials,data) { |
| 3069 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <div class=\"snippet_json\">\n <pre><code>" |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3070 | + escapeExpression(((helper = (helper = helpers.sampleJSON || (depth0 != null ? depth0.sampleJSON : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"sampleJSON","hash":{},"data":data}) : helper))) |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3071 | + "</code></pre>\n "; |
| 3072 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isParam : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data}); |
| 3073 | if (stack1 != null) { buffer += stack1; } |
| 3074 | return buffer + "\n </div>\n"; |
| 3075 | },"3":function(depth0,helpers,partials,data) { |
| 3076 | return "<small class=\"notice\" data-sw-translate></small>"; |
| 3077 | },"5":function(depth0,helpers,partials,data) { |
| 3078 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = " <div class=\"snippet_xml\">\n <pre><code>" |
| 3079 | + escapeExpression(((helper = (helper = helpers.sampleXML || (depth0 != null ? depth0.sampleXML : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"sampleXML","hash":{},"data":data}) : helper))) |
| 3080 | + "</code></pre>\n "; |
| 3081 | stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isParam : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data}); |
| 3082 | if (stack1 != null) { buffer += stack1; } |
| 3083 | return buffer + "\n </div>\n"; |
| 3084 | },"7":function(depth0,helpers,partials,data) { |
| 3085 | var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; |
| 3086 | return " " |
| 3087 | + escapeExpression(((helper = (helper = helpers.signature || (depth0 != null ? depth0.signature : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signature","hash":{},"data":data}) : helper))) |
| 3088 | + "\n"; |
| 3089 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 3090 | var stack1, helperMissing=helpers.helperMissing; |
| 3091 | stack1 = ((helpers.ifCond || (depth0 && depth0.ifCond) || helperMissing).call(depth0, (depth0 != null ? depth0.sampleJSON : depth0), "||", (depth0 != null ? depth0.sampleXML : depth0), {"name":"ifCond","hash":{},"fn":this.program(1, data),"inverse":this.program(7, data),"data":data})); |
| 3092 | if (stack1 != null) { return stack1; } |
| 3093 | else { return ''; } |
| 3094 | },"useData":true}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3095 | this["Handlebars"]["templates"]["status_code"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { |
| 3096 | var lambda=this.lambda, escapeExpression=this.escapeExpression; |
| 3097 | return " <tr>\n <td>" |
| 3098 | + escapeExpression(lambda((data && data.key), depth0)) |
| 3099 | + "</td>\n <td>" |
| 3100 | + escapeExpression(lambda((depth0 != null ? depth0.description : depth0), depth0)) |
| 3101 | + "</td>\n <td>" |
| 3102 | + escapeExpression(lambda((depth0 != null ? depth0.type : depth0), depth0)) |
| 3103 | + "</td>\n </tr>\n"; |
| 3104 | },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { |
| 3105 | var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td width='15%' class='code'>" |
| 3106 | + escapeExpression(((helper = (helper = helpers.code || (depth0 != null ? depth0.code : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"code","hash":{},"data":data}) : helper))) |
| 3107 | + "</td>\n<td class=\"markdown\">"; |
| 3108 | stack1 = ((helper = (helper = helpers.message || (depth0 != null ? depth0.message : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"message","hash":{},"data":data}) : helper)); |
| 3109 | if (stack1 != null) { buffer += stack1; } |
| 3110 | buffer += "</td>\n<td width='50%'><span class=\"model-signature\" /></td>\n<td class=\"headers\">\n <table>\n <tbody>\n"; |
| 3111 | stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); |
| 3112 | if (stack1 != null) { buffer += stack1; } |
| 3113 | return buffer + " </tbody>\n </table>\n</td>"; |
| 3114 | },"useData":true}); |
| 3115 | /** |
| 3116 | * swagger-client - swagger-client is a javascript client for use with swaggering APIs. |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3117 | * @version v2.1.16 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3118 | * @link http://swagger.io |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3119 | * @license Apache-2.0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3120 | */ |
| 3121 | (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){ |
| 3122 | 'use strict'; |
| 3123 | |
| 3124 | var auth = require('./lib/auth'); |
| 3125 | var helpers = require('./lib/helpers'); |
| 3126 | var SwaggerClient = require('./lib/client'); |
| 3127 | var deprecationWrapper = function (url, options) { |
| 3128 | helpers.log('This is deprecated, use "new SwaggerClient" instead.'); |
| 3129 | |
| 3130 | return new SwaggerClient(url, options); |
| 3131 | }; |
| 3132 | |
| 3133 | /* Here for IE8 Support */ |
| 3134 | if (!Array.prototype.indexOf) { |
| 3135 | Array.prototype.indexOf = function(obj, start) { |
| 3136 | for (var i = (start || 0), j = this.length; i < j; i++) { |
| 3137 | if (this[i] === obj) { return i; } |
| 3138 | } |
| 3139 | return -1; |
| 3140 | }; |
| 3141 | } |
| 3142 | |
| 3143 | /* Here for IE8 Support */ |
| 3144 | if (!String.prototype.trim) { |
| 3145 | String.prototype.trim = function () { |
| 3146 | return this.replace(/^\s+|\s+$/g, ''); |
| 3147 | }; |
| 3148 | } |
| 3149 | |
| 3150 | /* Here for node 10.x support */ |
| 3151 | if (!String.prototype.endsWith) { |
| 3152 | String.prototype.endsWith = function(suffix) { |
| 3153 | return this.indexOf(suffix, this.length - suffix.length) !== -1; |
| 3154 | }; |
| 3155 | } |
| 3156 | |
| 3157 | module.exports = SwaggerClient; |
| 3158 | |
| 3159 | SwaggerClient.ApiKeyAuthorization = auth.ApiKeyAuthorization; |
| 3160 | SwaggerClient.PasswordAuthorization = auth.PasswordAuthorization; |
| 3161 | SwaggerClient.CookieAuthorization = auth.CookieAuthorization; |
| 3162 | SwaggerClient.SwaggerApi = deprecationWrapper; |
| 3163 | SwaggerClient.SwaggerClient = deprecationWrapper; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3164 | SwaggerClient.SchemaMarkup = require('./lib/schema-markup'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3165 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3166 | },{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3167 | 'use strict'; |
| 3168 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3169 | var helpers = require('./helpers'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3170 | var btoa = require('btoa'); // jshint ignore:line |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3171 | var CookieJar = require('cookiejar').CookieJar; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3172 | var _ = { |
| 3173 | each: require('lodash-compat/collection/each'), |
| 3174 | includes: require('lodash-compat/collection/includes'), |
| 3175 | isObject: require('lodash-compat/lang/isObject'), |
| 3176 | isArray: require('lodash-compat/lang/isArray') |
| 3177 | }; |
| 3178 | |
| 3179 | /** |
| 3180 | * SwaggerAuthorizations applys the correct authorization to an operation being executed |
| 3181 | */ |
| 3182 | var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function (authz) { |
| 3183 | this.authz = authz || {}; |
| 3184 | }; |
| 3185 | |
| 3186 | /** |
| 3187 | * Add auths to the hash |
| 3188 | * Will overwrite any existing |
| 3189 | * |
| 3190 | */ |
| 3191 | SwaggerAuthorizations.prototype.add = function (name, auth) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3192 | if(_.isObject(name)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3193 | for (var key in name) { |
| 3194 | this.authz[key] = name[key]; |
| 3195 | } |
| 3196 | } else if(typeof name === 'string' ){ |
| 3197 | this.authz[name] = auth; |
| 3198 | } |
| 3199 | |
| 3200 | return auth; |
| 3201 | }; |
| 3202 | |
| 3203 | SwaggerAuthorizations.prototype.remove = function (name) { |
| 3204 | return delete this.authz[name]; |
| 3205 | }; |
| 3206 | |
| 3207 | SwaggerAuthorizations.prototype.apply = function (obj, securities) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3208 | var status = true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3209 | var applyAll = !securities; |
| 3210 | var flattenedSecurities = []; |
| 3211 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3212 | // favor the object-level authorizations over global |
| 3213 | var authz = obj.clientAuthorizations || this.authz; |
| 3214 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3215 | // Securities could be [ {} ] |
| 3216 | _.each(securities, function (obj, key) { |
| 3217 | |
| 3218 | // Make sure we account for securities being [ str ] |
| 3219 | if(typeof key === 'string') { |
| 3220 | flattenedSecurities.push(key); |
| 3221 | } |
| 3222 | |
| 3223 | // Flatten keys in to our array |
| 3224 | _.each(obj, function (val, key) { |
| 3225 | flattenedSecurities.push(key); |
| 3226 | }); |
| 3227 | }); |
| 3228 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3229 | _.each(authz, function (auth, authName) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3230 | if(applyAll || _.includes(flattenedSecurities, authName)) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3231 | var newStatus = auth.apply(obj); |
| 3232 | status = status && !!newStatus; // logical ORs regarding status |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3233 | } |
| 3234 | }); |
| 3235 | |
| 3236 | return status; |
| 3237 | }; |
| 3238 | |
| 3239 | /** |
| 3240 | * ApiKeyAuthorization allows a query param or header to be injected |
| 3241 | */ |
| 3242 | var ApiKeyAuthorization = module.exports.ApiKeyAuthorization = function (name, value, type) { |
| 3243 | this.name = name; |
| 3244 | this.value = value; |
| 3245 | this.type = type; |
| 3246 | }; |
| 3247 | |
| 3248 | ApiKeyAuthorization.prototype.apply = function (obj) { |
| 3249 | if (this.type === 'query') { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3250 | // see if already applied. If so, don't do it again |
| 3251 | |
| 3252 | var qp; |
| 3253 | if (obj.url.indexOf('?') > 0) { |
| 3254 | qp = obj.url.substring(obj.url.indexOf('?') + 1); |
| 3255 | var parts = qp.split('&'); |
| 3256 | if(parts && parts.length > 0) { |
| 3257 | for(var i = 0; i < parts.length; i++) { |
| 3258 | var kv = parts[i].split('='); |
| 3259 | if(kv && kv.length > 0) { |
| 3260 | if (kv[0] === this.name) { |
| 3261 | // skip it |
| 3262 | return false; |
| 3263 | } |
| 3264 | } |
| 3265 | } |
| 3266 | } |
| 3267 | } |
| 3268 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3269 | if (obj.url.indexOf('?') > 0) { |
| 3270 | obj.url = obj.url + '&' + this.name + '=' + this.value; |
| 3271 | } else { |
| 3272 | obj.url = obj.url + '?' + this.name + '=' + this.value; |
| 3273 | } |
| 3274 | |
| 3275 | return true; |
| 3276 | } else if (this.type === 'header') { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3277 | if(typeof obj.headers[this.name] === 'undefined') { |
| 3278 | obj.headers[this.name] = this.value; |
| 3279 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3280 | |
| 3281 | return true; |
| 3282 | } |
| 3283 | }; |
| 3284 | |
| 3285 | var CookieAuthorization = module.exports.CookieAuthorization = function (cookie) { |
| 3286 | this.cookie = cookie; |
| 3287 | }; |
| 3288 | |
| 3289 | CookieAuthorization.prototype.apply = function (obj) { |
| 3290 | obj.cookieJar = obj.cookieJar || new CookieJar(); |
| 3291 | obj.cookieJar.setCookie(this.cookie); |
| 3292 | |
| 3293 | return true; |
| 3294 | }; |
| 3295 | |
| 3296 | /** |
| 3297 | * Password Authorization is a basic auth implementation |
| 3298 | */ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3299 | var PasswordAuthorization = module.exports.PasswordAuthorization = function (username, password) { |
| 3300 | if (arguments.length === 3) { |
| 3301 | helpers.log('PasswordAuthorization: the \'name\' argument has been removed, pass only username and password'); |
| 3302 | username = arguments[1]; |
| 3303 | password = arguments[2]; |
| 3304 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3305 | this.username = username; |
| 3306 | this.password = password; |
| 3307 | }; |
| 3308 | |
| 3309 | PasswordAuthorization.prototype.apply = function (obj) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3310 | if(typeof obj.headers.Authorization === 'undefined') { |
| 3311 | obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password); |
| 3312 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3313 | |
| 3314 | return true; |
| 3315 | }; |
| 3316 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3317 | },{"./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){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3318 | 'use strict'; |
| 3319 | |
| 3320 | var _ = { |
| 3321 | bind: require('lodash-compat/function/bind'), |
| 3322 | cloneDeep: require('lodash-compat/lang/cloneDeep'), |
| 3323 | find: require('lodash-compat/collection/find'), |
| 3324 | forEach: require('lodash-compat/collection/forEach'), |
| 3325 | indexOf: require('lodash-compat/array/indexOf'), |
| 3326 | isArray: require('lodash-compat/lang/isArray'), |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3327 | isObject: require('lodash-compat/lang/isObject'), |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3328 | isFunction: require('lodash-compat/lang/isFunction'), |
| 3329 | isPlainObject: require('lodash-compat/lang/isPlainObject'), |
| 3330 | isUndefined: require('lodash-compat/lang/isUndefined') |
| 3331 | }; |
| 3332 | var auth = require('./auth'); |
| 3333 | var helpers = require('./helpers'); |
| 3334 | var Model = require('./types/model'); |
| 3335 | var Operation = require('./types/operation'); |
| 3336 | var OperationGroup = require('./types/operationGroup'); |
| 3337 | var Resolver = require('./resolver'); |
| 3338 | var SwaggerHttp = require('./http'); |
| 3339 | var SwaggerSpecConverter = require('./spec-converter'); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3340 | var Q = require('q'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3341 | |
| 3342 | // We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the |
| 3343 | // following usage: 'client.{tagName}' |
| 3344 | var reservedClientTags = [ |
| 3345 | 'apis', |
| 3346 | 'authorizationScheme', |
| 3347 | 'authorizations', |
| 3348 | 'basePath', |
| 3349 | 'build', |
| 3350 | 'buildFrom1_1Spec', |
| 3351 | 'buildFrom1_2Spec', |
| 3352 | 'buildFromSpec', |
| 3353 | 'clientAuthorizations', |
| 3354 | 'convertInfo', |
| 3355 | 'debug', |
| 3356 | 'defaultErrorCallback', |
| 3357 | 'defaultSuccessCallback', |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3358 | 'enableCookies', |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3359 | 'fail', |
| 3360 | 'failure', |
| 3361 | 'finish', |
| 3362 | 'help', |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3363 | 'host', |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3364 | 'idFromOp', |
| 3365 | 'info', |
| 3366 | 'initialize', |
| 3367 | 'isBuilt', |
| 3368 | 'isValid', |
| 3369 | 'modelPropertyMacro', |
| 3370 | 'models', |
| 3371 | 'modelsArray', |
| 3372 | 'options', |
| 3373 | 'parameterMacro', |
| 3374 | 'parseUri', |
| 3375 | 'progress', |
| 3376 | 'resourceCount', |
| 3377 | 'sampleModels', |
| 3378 | 'selfReflect', |
| 3379 | 'setConsolidatedModels', |
| 3380 | 'spec', |
| 3381 | 'supportedSubmitMethods', |
| 3382 | 'swaggerRequestHeaders', |
| 3383 | 'tagFromLabel', |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3384 | 'title', |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3385 | 'url', |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3386 | 'useJQuery', |
| 3387 | 'jqueryAjaxCache' |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3388 | ]; |
| 3389 | // We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the |
| 3390 | // following usage: 'client.apis.{tagName}' |
| 3391 | var reservedApiTags = [ |
| 3392 | 'apis', |
| 3393 | 'asCurl', |
| 3394 | 'description', |
| 3395 | 'externalDocs', |
| 3396 | 'help', |
| 3397 | 'label', |
| 3398 | 'name', |
| 3399 | 'operation', |
| 3400 | 'operations', |
| 3401 | 'operationsArray', |
| 3402 | 'path', |
| 3403 | 'tag' |
| 3404 | ]; |
| 3405 | var supportedOperationMethods = ['delete', 'get', 'head', 'options', 'patch', 'post', 'put']; |
| 3406 | var SwaggerClient = module.exports = function (url, options) { |
| 3407 | this.authorizations = null; |
| 3408 | this.authorizationScheme = null; |
| 3409 | this.basePath = null; |
| 3410 | this.debug = false; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3411 | this.enableCookies = false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3412 | this.info = null; |
| 3413 | this.isBuilt = false; |
| 3414 | this.isValid = false; |
| 3415 | this.modelsArray = []; |
| 3416 | this.resourceCount = 0; |
| 3417 | this.url = null; |
| 3418 | this.useJQuery = false; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3419 | this.jqueryAjaxCache = false; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3420 | this.swaggerObject = {}; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3421 | this.deferredClient = undefined; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3422 | |
| 3423 | this.clientAuthorizations = new auth.SwaggerAuthorizations(); |
| 3424 | |
| 3425 | if (typeof url !== 'undefined') { |
| 3426 | return this.initialize(url, options); |
| 3427 | } else { |
| 3428 | return this; |
| 3429 | } |
| 3430 | }; |
| 3431 | |
| 3432 | SwaggerClient.prototype.initialize = function (url, options) { |
| 3433 | this.models = {}; |
| 3434 | this.sampleModels = {}; |
| 3435 | |
| 3436 | if (typeof url === 'string') { |
| 3437 | this.url = url; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3438 | } else if (_.isObject(url)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3439 | options = url; |
| 3440 | this.url = options.url; |
| 3441 | } |
| 3442 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3443 | if(this.url && this.url.indexOf('http:') === -1 && this.url.indexOf('https:') === -1) { |
| 3444 | // no protocol, so we can only use window if it exists |
| 3445 | if(typeof(window) !== 'undefined' && window && window.location) { |
| 3446 | this.url = window.location.origin + this.url; |
| 3447 | } |
| 3448 | } |
| 3449 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3450 | options = options || {}; |
| 3451 | this.clientAuthorizations.add(options.authorizations); |
| 3452 | this.swaggerRequestHeaders = options.swaggerRequestHeaders || 'application/json;charset=utf-8,*/*'; |
| 3453 | this.defaultSuccessCallback = options.defaultSuccessCallback || null; |
| 3454 | this.defaultErrorCallback = options.defaultErrorCallback || null; |
| 3455 | this.modelPropertyMacro = options.modelPropertyMacro || null; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3456 | this.parameterMacro = options.parameterMacro || null; |
| 3457 | this.usePromise = options.usePromise || null; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3458 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3459 | |
| 3460 | if(this.usePromise) { |
| 3461 | this.deferredClient = Q.defer(); |
| 3462 | } |
| 3463 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3464 | if (typeof options.success === 'function') { |
| 3465 | this.success = options.success; |
| 3466 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3467 | if (options.useJQuery) { |
| 3468 | this.useJQuery = options.useJQuery; |
| 3469 | } |
| 3470 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3471 | if (options.jqueryAjaxCache) { |
| 3472 | this.jqueryAjaxCache = options.jqueryAjaxCache; |
| 3473 | } |
| 3474 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3475 | if (options.enableCookies) { |
| 3476 | this.enableCookies = options.enableCookies; |
| 3477 | } |
| 3478 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3479 | this.options = options || {}; |
| 3480 | |
| 3481 | this.supportedSubmitMethods = options.supportedSubmitMethods || []; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3482 | this.failure = options.failure || function (err) { throw err; }; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3483 | this.progress = options.progress || function () {}; |
| 3484 | this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document |
| 3485 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3486 | if (options.scheme) { |
| 3487 | this.scheme = options.scheme; |
| 3488 | } |
| 3489 | |
| 3490 | if (this.usePromise || typeof options.success === 'function') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3491 | this.ready = true; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3492 | return this.build(); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3493 | } |
| 3494 | }; |
| 3495 | |
| 3496 | SwaggerClient.prototype.build = function (mock) { |
| 3497 | if (this.isBuilt) { |
| 3498 | return this; |
| 3499 | } |
| 3500 | |
| 3501 | var self = this; |
| 3502 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3503 | if (this.spec) { |
| 3504 | this.progress('fetching resource list; Please wait.'); |
| 3505 | } else { |
| 3506 | this.progress('fetching resource list: ' + this.url + '; Please wait.'); |
| 3507 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3508 | |
| 3509 | var obj = { |
| 3510 | useJQuery: this.useJQuery, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3511 | jqueryAjaxCache: this.jqueryAjaxCache, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3512 | url: this.url, |
| 3513 | method: 'get', |
| 3514 | headers: { |
| 3515 | accept: this.swaggerRequestHeaders |
| 3516 | }, |
| 3517 | on: { |
| 3518 | error: function (response) { |
| 3519 | if (self.url.substring(0, 4) !== 'http') { |
| 3520 | return self.fail('Please specify the protocol for ' + self.url); |
| 3521 | } else if (response.status === 0) { |
| 3522 | return self.fail('Can\'t read from server. It may not have the appropriate access-control-origin settings.'); |
| 3523 | } else if (response.status === 404) { |
| 3524 | return self.fail('Can\'t read swagger JSON from ' + self.url); |
| 3525 | } else { |
| 3526 | return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url); |
| 3527 | } |
| 3528 | }, |
| 3529 | response: function (resp) { |
| 3530 | |
| 3531 | var responseObj = resp.obj; |
| 3532 | if(!responseObj) { |
| 3533 | return self.fail('failed to parse JSON/YAML response'); |
| 3534 | } |
| 3535 | |
| 3536 | self.swaggerVersion = responseObj.swaggerVersion; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3537 | self.swaggerObject = responseObj; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3538 | |
| 3539 | if (responseObj.swagger && parseInt(responseObj.swagger) === 2) { |
| 3540 | self.swaggerVersion = responseObj.swagger; |
| 3541 | |
| 3542 | new Resolver().resolve(responseObj, self.url, self.buildFromSpec, self); |
| 3543 | |
| 3544 | self.isValid = true; |
| 3545 | } else { |
| 3546 | var converter = new SwaggerSpecConverter(); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3547 | self.oldSwaggerObject = self.swaggerObject; |
| 3548 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3549 | converter.setDocumentationLocation(self.url); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3550 | converter.convert(responseObj, self.clientAuthorizations, self.options, function(spec) { |
| 3551 | self.swaggerObject = spec; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3552 | new Resolver().resolve(spec, self.url, self.buildFromSpec, self); |
| 3553 | self.isValid = true; |
| 3554 | }); |
| 3555 | } |
| 3556 | } |
| 3557 | } |
| 3558 | }; |
| 3559 | |
| 3560 | if (this.spec) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3561 | self.swaggerObject = this.spec; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3562 | setTimeout(function () { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3563 | new Resolver().resolve(self.spec, self.url, self.buildFromSpec, self); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3564 | }, 10); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3565 | } else { |
| 3566 | this.clientAuthorizations.apply(obj); |
| 3567 | |
| 3568 | if (mock) { |
| 3569 | return obj; |
| 3570 | } |
| 3571 | |
| 3572 | new SwaggerHttp().execute(obj, this.options); |
| 3573 | } |
| 3574 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3575 | return (this.usePromise) ? this.deferredClient.promise : this; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3576 | }; |
| 3577 | |
| 3578 | SwaggerClient.prototype.buildFromSpec = function (response) { |
| 3579 | if (this.isBuilt) { |
| 3580 | return this; |
| 3581 | } |
| 3582 | |
| 3583 | this.apis = {}; |
| 3584 | this.apisArray = []; |
| 3585 | this.basePath = response.basePath || ''; |
| 3586 | this.consumes = response.consumes; |
| 3587 | this.host = response.host || ''; |
| 3588 | this.info = response.info || {}; |
| 3589 | this.produces = response.produces; |
| 3590 | this.schemes = response.schemes || []; |
| 3591 | this.securityDefinitions = response.securityDefinitions; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3592 | this.security = response.security; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3593 | this.title = response.title || ''; |
| 3594 | |
| 3595 | if (response.externalDocs) { |
| 3596 | this.externalDocs = response.externalDocs; |
| 3597 | } |
| 3598 | |
| 3599 | // legacy support |
| 3600 | this.authSchemes = response.securityDefinitions; |
| 3601 | |
| 3602 | var definedTags = {}; |
| 3603 | var k; |
| 3604 | |
| 3605 | if (Array.isArray(response.tags)) { |
| 3606 | definedTags = {}; |
| 3607 | |
| 3608 | for (k = 0; k < response.tags.length; k++) { |
| 3609 | var t = response.tags[k]; |
| 3610 | definedTags[t.name] = t; |
| 3611 | } |
| 3612 | } |
| 3613 | |
| 3614 | var location; |
| 3615 | |
| 3616 | if (typeof this.url === 'string') { |
| 3617 | location = this.parseUri(this.url); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3618 | if (typeof this.scheme === 'undefined' && typeof this.schemes === 'undefined' || this.schemes.length === 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3619 | this.scheme = location.scheme || 'http'; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3620 | } else if (typeof this.scheme === 'undefined') { |
| 3621 | this.scheme = this.schemes[0] || location.scheme; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3622 | } |
| 3623 | |
| 3624 | if (typeof this.host === 'undefined' || this.host === '') { |
| 3625 | this.host = location.host; |
| 3626 | |
| 3627 | if (location.port) { |
| 3628 | this.host = this.host + ':' + location.port; |
| 3629 | } |
| 3630 | } |
| 3631 | } |
| 3632 | else { |
| 3633 | if (typeof this.schemes === 'undefined' || this.schemes.length === 0) { |
| 3634 | this.scheme = 'http'; |
| 3635 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3636 | else if (typeof this.scheme === 'undefined') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3637 | this.scheme = this.schemes[0]; |
| 3638 | } |
| 3639 | } |
| 3640 | |
| 3641 | this.definitions = response.definitions; |
| 3642 | |
| 3643 | var key; |
| 3644 | |
| 3645 | for (key in this.definitions) { |
| 3646 | var model = new Model(key, this.definitions[key], this.models, this.modelPropertyMacro); |
| 3647 | |
| 3648 | if (model) { |
| 3649 | this.models[key] = model; |
| 3650 | } |
| 3651 | } |
| 3652 | |
| 3653 | // get paths, create functions for each operationId |
| 3654 | var self = this; |
| 3655 | |
| 3656 | // Bind help to 'client.apis' |
| 3657 | self.apis.help = _.bind(self.help, self); |
| 3658 | |
| 3659 | _.forEach(response.paths, function (pathObj, path) { |
| 3660 | // Only process a path if it's an object |
| 3661 | if (!_.isPlainObject(pathObj)) { |
| 3662 | return; |
| 3663 | } |
| 3664 | |
| 3665 | _.forEach(supportedOperationMethods, function (method) { |
| 3666 | var operation = pathObj[method]; |
| 3667 | |
| 3668 | if (_.isUndefined(operation)) { |
| 3669 | // Operation does not exist |
| 3670 | return; |
| 3671 | } else if (!_.isPlainObject(operation)) { |
| 3672 | // Operation exists but it is not an Operation Object. Since this is invalid, log it. |
| 3673 | helpers.log('The \'' + method + '\' operation for \'' + path + '\' path is not an Operation Object'); |
| 3674 | |
| 3675 | return; |
| 3676 | } |
| 3677 | |
| 3678 | var tags = operation.tags; |
| 3679 | |
| 3680 | if (_.isUndefined(tags) || !_.isArray(tags) || tags.length === 0) { |
| 3681 | tags = operation.tags = [ 'default' ]; |
| 3682 | } |
| 3683 | |
| 3684 | var operationId = self.idFromOp(path, method, operation); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3685 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3686 | var operationObject = new Operation(self, |
| 3687 | operation.scheme, |
| 3688 | operationId, |
| 3689 | method, |
| 3690 | path, |
| 3691 | operation, |
| 3692 | self.definitions, |
| 3693 | self.models, |
| 3694 | self.clientAuthorizations); |
| 3695 | |
| 3696 | // bind self operation's execute command to the api |
| 3697 | _.forEach(tags, function (tag) { |
| 3698 | var clientProperty = _.indexOf(reservedClientTags, tag) > -1 ? '_' + tag : tag; |
| 3699 | var apiProperty = _.indexOf(reservedApiTags, tag) > -1 ? '_' + tag : tag; |
| 3700 | var operationGroup = self[clientProperty]; |
| 3701 | |
| 3702 | if (clientProperty !== tag) { |
| 3703 | helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name. Use \'client.' + |
| 3704 | clientProperty + '\' or \'client.apis.' + tag + '\' instead of \'client.' + tag + '\'.'); |
| 3705 | } |
| 3706 | |
| 3707 | if (apiProperty !== tag) { |
| 3708 | helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name. Use ' + |
| 3709 | '\'client.apis.' + apiProperty + '\' instead of \'client.apis.' + tag + '\'.'); |
| 3710 | } |
| 3711 | |
| 3712 | if (_.indexOf(reservedApiTags, operationId) > -1) { |
| 3713 | helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' + |
| 3714 | 'function/property name. Use \'client.apis.' + apiProperty + '._' + operationId + |
| 3715 | '\' instead of \'client.apis.' + apiProperty + '.' + operationId + '\'.'); |
| 3716 | |
| 3717 | operationId = '_' + operationId; |
| 3718 | operationObject.nickname = operationId; // So 'client.apis.[tag].operationId.help() works properly |
| 3719 | } |
| 3720 | |
| 3721 | if (_.isUndefined(operationGroup)) { |
| 3722 | operationGroup = self[clientProperty] = self.apis[apiProperty] = {}; |
| 3723 | |
| 3724 | operationGroup.operations = {}; |
| 3725 | operationGroup.label = apiProperty; |
| 3726 | operationGroup.apis = {}; |
| 3727 | |
| 3728 | var tagDef = definedTags[tag]; |
| 3729 | |
| 3730 | if (!_.isUndefined(tagDef)) { |
| 3731 | operationGroup.description = tagDef.description; |
| 3732 | operationGroup.externalDocs = tagDef.externalDocs; |
| 3733 | } |
| 3734 | |
| 3735 | self[clientProperty].help = _.bind(self.help, operationGroup); |
| 3736 | self.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject)); |
| 3737 | } |
| 3738 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3739 | operationId = self.makeUniqueOperationId(operationId, self.apis[apiProperty]); |
| 3740 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3741 | // Bind tag help |
| 3742 | if (!_.isFunction(operationGroup.help)) { |
| 3743 | operationGroup.help = _.bind(self.help, operationGroup); |
| 3744 | } |
| 3745 | |
| 3746 | // bind to the apis object |
| 3747 | self.apis[apiProperty][operationId] = operationGroup[operationId] = _.bind(operationObject.execute, |
| 3748 | operationObject); |
| 3749 | self.apis[apiProperty][operationId].help = operationGroup[operationId].help = _.bind(operationObject.help, |
| 3750 | operationObject); |
| 3751 | self.apis[apiProperty][operationId].asCurl = operationGroup[operationId].asCurl = _.bind(operationObject.asCurl, |
| 3752 | operationObject); |
| 3753 | |
| 3754 | operationGroup.apis[operationId] = operationGroup.operations[operationId] = operationObject; |
| 3755 | |
| 3756 | // legacy UI feature |
| 3757 | var api = _.find(self.apisArray, function (api) { |
| 3758 | return api.tag === tag; |
| 3759 | }); |
| 3760 | |
| 3761 | if (api) { |
| 3762 | api.operationsArray.push(operationObject); |
| 3763 | } |
| 3764 | }); |
| 3765 | }); |
| 3766 | }); |
| 3767 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3768 | // sort the apisArray according to the tags |
| 3769 | var sortedApis = []; |
| 3770 | _.forEach(Object.keys(definedTags), function (tag) { |
| 3771 | var _apiToAdd; |
| 3772 | var pos; |
| 3773 | for(pos in self.apisArray) { |
| 3774 | var _api = self.apisArray[pos]; |
| 3775 | if(_api && tag === _api.name) { |
| 3776 | sortedApis.push(_api); |
| 3777 | self.apisArray[pos] = null; |
| 3778 | } |
| 3779 | } |
| 3780 | }); |
| 3781 | // add anything left |
| 3782 | _.forEach(self.apisArray, function (api) { |
| 3783 | if(api) { |
| 3784 | sortedApis.push(api); |
| 3785 | } |
| 3786 | }); |
| 3787 | self.apisArray = sortedApis; |
| 3788 | |
| 3789 | _.forEach(response.definitions, function (definitionObj, definition) { |
| 3790 | definitionObj['id'] = definition.toLowerCase(); |
| 3791 | definitionObj['name'] = definition; |
| 3792 | self.modelsArray.push(definitionObj); |
| 3793 | }); |
| 3794 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3795 | this.isBuilt = true; |
| 3796 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3797 | if (this.usePromise) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3798 | this.isValid = true; |
| 3799 | this.isBuilt = true; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3800 | this.deferredClient.resolve(this); |
| 3801 | |
| 3802 | return this.deferredClient.promise; |
| 3803 | } |
| 3804 | |
| 3805 | if (this.success) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3806 | this.success(); |
| 3807 | } |
| 3808 | |
| 3809 | return this; |
| 3810 | }; |
| 3811 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3812 | SwaggerClient.prototype.makeUniqueOperationId = function(operationId, api) { |
| 3813 | var count = 0; |
| 3814 | var name = operationId; |
| 3815 | |
| 3816 | // make unique across this operation group |
| 3817 | while(true) { |
| 3818 | var matched = false; |
| 3819 | _.forEach(api.operations, function (operation) { |
| 3820 | if(operation.nickname === name) { |
| 3821 | matched = true; |
| 3822 | } |
| 3823 | }); |
| 3824 | if(!matched) { |
| 3825 | return name; |
| 3826 | } |
| 3827 | name = operationId + '_' + count; |
| 3828 | count ++; |
| 3829 | } |
| 3830 | |
| 3831 | return operationId; |
| 3832 | }; |
| 3833 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3834 | SwaggerClient.prototype.parseUri = function (uri) { |
| 3835 | var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/; |
| 3836 | var parts = urlParseRE.exec(uri); |
| 3837 | |
| 3838 | return { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3839 | scheme: parts[4] ? parts[4].replace(':','') : undefined, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3840 | host: parts[11], |
| 3841 | port: parts[12], |
| 3842 | path: parts[15] |
| 3843 | }; |
| 3844 | }; |
| 3845 | |
| 3846 | SwaggerClient.prototype.help = function (dontPrint) { |
| 3847 | var output = ''; |
| 3848 | |
| 3849 | if (this instanceof SwaggerClient) { |
| 3850 | _.forEach(this.apis, function (api, name) { |
| 3851 | if (_.isPlainObject(api)) { |
| 3852 | output += 'operations for the \'' + name + '\' tag\n'; |
| 3853 | |
| 3854 | _.forEach(api.operations, function (operation, name) { |
| 3855 | output += ' * ' + name + ': ' + operation.summary + '\n'; |
| 3856 | }); |
| 3857 | } |
| 3858 | }); |
| 3859 | } else if (this instanceof OperationGroup || _.isPlainObject(this)) { |
| 3860 | output += 'operations for the \'' + this.label + '\' tag\n'; |
| 3861 | |
| 3862 | _.forEach(this.apis, function (operation, name) { |
| 3863 | output += ' * ' + name + ': ' + operation.summary + '\n'; |
| 3864 | }); |
| 3865 | } |
| 3866 | |
| 3867 | if (dontPrint) { |
| 3868 | return output; |
| 3869 | } else { |
| 3870 | helpers.log(output); |
| 3871 | |
| 3872 | return output; |
| 3873 | } |
| 3874 | }; |
| 3875 | |
| 3876 | SwaggerClient.prototype.tagFromLabel = function (label) { |
| 3877 | return label; |
| 3878 | }; |
| 3879 | |
| 3880 | SwaggerClient.prototype.idFromOp = function (path, httpMethod, op) { |
| 3881 | if(!op || !op.operationId) { |
| 3882 | op = op || {}; |
| 3883 | op.operationId = httpMethod + '_' + path; |
| 3884 | } |
| 3885 | var opId = op.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_') || (path.substring(1) + '_' + httpMethod); |
| 3886 | |
| 3887 | opId = opId.replace(/((_){2,})/g, '_'); |
| 3888 | opId = opId.replace(/^(_)*/g, ''); |
| 3889 | opId = opId.replace(/([_])*$/g, ''); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3890 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3891 | return opId; |
| 3892 | }; |
| 3893 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3894 | SwaggerClient.prototype.setHost = function (host) { |
| 3895 | this.host = host; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3896 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3897 | if(this.apis) { |
| 3898 | _.forEach(this.apis, function(api) { |
| 3899 | if(api.operations) { |
| 3900 | _.forEach(api.operations, function(operation) { |
| 3901 | operation.host = host; |
| 3902 | }); |
| 3903 | } |
| 3904 | }); |
| 3905 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3906 | }; |
| 3907 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3908 | SwaggerClient.prototype.setBasePath = function (basePath) { |
| 3909 | this.basePath = basePath; |
| 3910 | |
| 3911 | if(this.apis) { |
| 3912 | _.forEach(this.apis, function(api) { |
| 3913 | if(api.operations) { |
| 3914 | _.forEach(api.operations, function(operation) { |
| 3915 | operation.basePath = basePath; |
| 3916 | }); |
| 3917 | } |
| 3918 | }); |
| 3919 | } |
| 3920 | }; |
| 3921 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3922 | SwaggerClient.prototype.setSchemes = function (schemes) { |
| 3923 | this.schemes = schemes; |
| 3924 | |
| 3925 | if(schemes && schemes.length > 0) { |
| 3926 | if(this.apis) { |
| 3927 | _.forEach(this.apis, function (api) { |
| 3928 | if (api.operations) { |
| 3929 | _.forEach(api.operations, function (operation) { |
| 3930 | operation.scheme = schemes[0]; |
| 3931 | }); |
| 3932 | } |
| 3933 | }); |
| 3934 | } |
| 3935 | } |
| 3936 | }; |
| 3937 | |
| 3938 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3939 | SwaggerClient.prototype.fail = function (message) { |
| 3940 | if (this.usePromise) { |
| 3941 | this.deferredClient.reject(message); |
| 3942 | return this.deferredClient.promise; |
| 3943 | } else { |
| 3944 | if (this.failure) { |
| 3945 | this.failure(message); |
| 3946 | } |
| 3947 | else { |
| 3948 | this.failure(message); |
| 3949 | } |
| 3950 | } |
| 3951 | }; |
| 3952 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 3953 | },{"./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){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3954 | (function (process){ |
| 3955 | 'use strict'; |
| 3956 | |
| 3957 | var _ = { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3958 | isPlainObject: require('lodash-compat/lang/isPlainObject'), |
| 3959 | indexOf: require('lodash-compat/array/indexOf') |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3960 | }; |
| 3961 | |
| 3962 | module.exports.__bind = function (fn, me) { |
| 3963 | return function(){ |
| 3964 | return fn.apply(me, arguments); |
| 3965 | }; |
| 3966 | }; |
| 3967 | |
| 3968 | var log = module.exports.log = function() { |
| 3969 | // Only log if available and we're not testing |
| 3970 | if (console && process.env.NODE_ENV !== 'test') { |
| 3971 | console.log(Array.prototype.slice.call(arguments)[0]); |
| 3972 | } |
| 3973 | }; |
| 3974 | |
| 3975 | module.exports.fail = function (message) { |
| 3976 | log(message); |
| 3977 | }; |
| 3978 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 3979 | var optionHtml = module.exports.optionHtml = function (label, value) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3980 | return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>'; |
| 3981 | }; |
| 3982 | |
| 3983 | var resolveSchema = module.exports.resolveSchema = function (schema) { |
| 3984 | if (_.isPlainObject(schema.schema)) { |
| 3985 | schema = resolveSchema(schema.schema); |
| 3986 | } |
| 3987 | |
| 3988 | return schema; |
| 3989 | }; |
| 3990 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 3991 | var simpleRef = module.exports.simpleRef = function (name) { |
| 3992 | if (typeof name === 'undefined') { |
| 3993 | return null; |
| 3994 | } |
| 3995 | |
| 3996 | if (name.indexOf('#/definitions/') === 0) { |
| 3997 | return name.substring('#/definitions/'.length); |
| 3998 | } else { |
| 3999 | return name; |
| 4000 | } |
| 4001 | }; |
| 4002 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4003 | |
| 4004 | }).call(this,require('_process')) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4005 | //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9oZWxwZXJzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLl9fYmluZCA9IGZ1bmN0aW9uIChmbiwgbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuICB9O1xufTtcblxudmFyIGxvZyA9IG1vZHVsZS5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICAvLyBPbmx5IGxvZyBpZiBhdmFpbGFibGUgYW5kIHdlJ3JlIG5vdCB0ZXN0aW5nXG4gIGlmIChjb25zb2xlICYmIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAndGVzdCcpIHtcbiAgICBjb25zb2xlLmxvZyhBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpWzBdKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMuZmFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gIGxvZyhtZXNzYWdlKTtcbn07XG5cbnZhciBvcHRpb25IdG1sID0gbW9kdWxlLmV4cG9ydHMub3B0aW9uSHRtbCA9IGZ1bmN0aW9uIChsYWJlbCwgdmFsdWUpIHtcbiAgcmV0dXJuICc8dHI+PHRkIGNsYXNzPVwib3B0aW9uTmFtZVwiPicgKyBsYWJlbCArICc6PC90ZD48dGQ+JyArIHZhbHVlICsgJzwvdGQ+PC90cj4nO1xufTtcblxudmFyIHJlc29sdmVTY2hlbWEgPSBtb2R1bGUuZXhwb3J0cy5yZXNvbHZlU2NoZW1hID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5zY2hlbWEpKSB7XG4gICAgc2NoZW1hID0gcmVzb2x2ZVNjaGVtYShzY2hlbWEuc2NoZW1hKTtcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59O1xuXG52YXIgc2ltcGxlUmVmID0gbW9kdWxlLmV4cG9ydHMuc2ltcGxlUmVmID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKG5hbWUuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5hbWU7XG4gIH1cbn07XG5cbiJdfQ== |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4006 | },{"_process":12,"lodash-compat/array/indexOf":49,"lodash-compat/lang/isPlainObject":145}],5:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4007 | 'use strict'; |
| 4008 | |
| 4009 | var helpers = require('./helpers'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4010 | var request = require('superagent'); |
| 4011 | var jsyaml = require('js-yaml'); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4012 | var _ = { |
| 4013 | isObject: require('lodash-compat/lang/isObject') |
| 4014 | }; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4015 | |
| 4016 | /* |
| 4017 | * JQueryHttpClient is a light-weight, node or browser HTTP client |
| 4018 | */ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4019 | var JQueryHttpClient = function () { |
| 4020 | this.type = 'JQueryHttpClient'; |
| 4021 | }; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4022 | |
| 4023 | /* |
| 4024 | * SuperagentHttpClient is a light-weight, node or browser HTTP client |
| 4025 | */ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4026 | var SuperagentHttpClient = function () { |
| 4027 | this.type = 'SuperagentHttpClient'; |
| 4028 | }; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4029 | |
| 4030 | /** |
| 4031 | * SwaggerHttp is a wrapper for executing requests |
| 4032 | */ |
| 4033 | var SwaggerHttp = module.exports = function () {}; |
| 4034 | |
| 4035 | SwaggerHttp.prototype.execute = function (obj, opts) { |
| 4036 | var client; |
| 4037 | |
| 4038 | if(opts && opts.client) { |
| 4039 | client = opts.client; |
| 4040 | } |
| 4041 | else { |
| 4042 | client = new SuperagentHttpClient(opts); |
| 4043 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4044 | client.opts = opts || {}; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4045 | |
| 4046 | // legacy support |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4047 | var hasJQuery = false; |
| 4048 | if(typeof window !== 'undefined') { |
| 4049 | if(typeof window.jQuery !== 'undefined') { |
| 4050 | hasJQuery = true; |
| 4051 | } |
| 4052 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4053 | // OPTIONS support |
| 4054 | if(obj.method.toLowerCase() === 'options' && client.type === 'SuperagentHttpClient') { |
| 4055 | log('forcing jQuery as OPTIONS are not supported by SuperAgent'); |
| 4056 | obj.useJQuery = true; |
| 4057 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4058 | if(this.isInternetExplorer() && (obj.useJQuery === false || !hasJQuery )) { |
| 4059 | throw new Error('Unsupported configuration! JQuery is required but not available'); |
| 4060 | } |
| 4061 | if ((obj && obj.useJQuery === true) || this.isInternetExplorer() && hasJQuery) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4062 | client = new JQueryHttpClient(opts); |
| 4063 | } |
| 4064 | |
| 4065 | var success = obj.on.response; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4066 | var error = obj.on.error; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4067 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4068 | var requestInterceptor = function(data) { |
| 4069 | if(opts && opts.requestInterceptor) { |
| 4070 | data = opts.requestInterceptor.apply(data); |
| 4071 | } |
| 4072 | return data; |
| 4073 | }; |
| 4074 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4075 | var responseInterceptor = function(data) { |
| 4076 | if(opts && opts.responseInterceptor) { |
| 4077 | data = opts.responseInterceptor.apply(data); |
| 4078 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4079 | return success(data); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4080 | }; |
| 4081 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4082 | var errorInterceptor = function(data) { |
| 4083 | if(opts && opts.responseInterceptor) { |
| 4084 | data = opts.responseInterceptor.apply(data); |
| 4085 | } |
| 4086 | error(data); |
| 4087 | }; |
| 4088 | |
| 4089 | obj.on.error = function(data) { |
| 4090 | errorInterceptor(data); |
| 4091 | }; |
| 4092 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4093 | obj.on.response = function(data) { |
| 4094 | responseInterceptor(data); |
| 4095 | }; |
| 4096 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4097 | if (_.isObject(obj) && _.isObject(obj.body)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4098 | // special processing for file uploads via jquery |
| 4099 | if (obj.body.type && obj.body.type === 'formData'){ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4100 | if(opts.useJQuery) { |
| 4101 | obj.contentType = false; |
| 4102 | obj.processData = false; |
| 4103 | delete obj.headers['Content-Type']; |
| 4104 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4105 | } |
| 4106 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4107 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4108 | obj = requestInterceptor(obj) || obj; |
| 4109 | if (obj.beforeSend) { |
| 4110 | obj.beforeSend(function(_obj) { |
| 4111 | client.execute(_obj || obj); |
| 4112 | }); |
| 4113 | } else { |
| 4114 | client.execute(obj); |
| 4115 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4116 | |
| 4117 | return (obj.deferred) ? obj.deferred.promise : obj; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4118 | }; |
| 4119 | |
| 4120 | SwaggerHttp.prototype.isInternetExplorer = function () { |
| 4121 | var detectedIE = false; |
| 4122 | |
| 4123 | if (typeof navigator !== 'undefined' && navigator.userAgent) { |
| 4124 | var nav = navigator.userAgent.toLowerCase(); |
| 4125 | |
| 4126 | if (nav.indexOf('msie') !== -1) { |
| 4127 | var version = parseInt(nav.split('msie')[1]); |
| 4128 | |
| 4129 | if (version <= 8) { |
| 4130 | detectedIE = true; |
| 4131 | } |
| 4132 | } |
| 4133 | } |
| 4134 | |
| 4135 | return detectedIE; |
| 4136 | }; |
| 4137 | |
| 4138 | JQueryHttpClient.prototype.execute = function (obj) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4139 | var jq = this.jQuery || (typeof window !== 'undefined' && window.jQuery); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4140 | var cb = obj.on; |
| 4141 | var request = obj; |
| 4142 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4143 | if(typeof jq === 'undefined' || jq === false) { |
| 4144 | throw new Error('Unsupported configuration! JQuery is required but not available'); |
| 4145 | } |
| 4146 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4147 | obj.type = obj.method; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4148 | obj.cache = obj.jqueryAjaxCache; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4149 | obj.data = obj.body; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4150 | delete obj.jqueryAjaxCache; |
| 4151 | delete obj.useJQuery; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4152 | delete obj.body; |
| 4153 | |
| 4154 | obj.complete = function (response) { |
| 4155 | var headers = {}; |
| 4156 | var headerArray = response.getAllResponseHeaders().split('\n'); |
| 4157 | |
| 4158 | for (var i = 0; i < headerArray.length; i++) { |
| 4159 | var toSplit = headerArray[i].trim(); |
| 4160 | |
| 4161 | if (toSplit.length === 0) { |
| 4162 | continue; |
| 4163 | } |
| 4164 | |
| 4165 | var separator = toSplit.indexOf(':'); |
| 4166 | |
| 4167 | if (separator === -1) { |
| 4168 | // Name but no value in the header |
| 4169 | headers[toSplit] = null; |
| 4170 | |
| 4171 | continue; |
| 4172 | } |
| 4173 | |
| 4174 | var name = toSplit.substring(0, separator).trim(); |
| 4175 | var value = toSplit.substring(separator + 1).trim(); |
| 4176 | |
| 4177 | headers[name] = value; |
| 4178 | } |
| 4179 | |
| 4180 | var out = { |
| 4181 | url: request.url, |
| 4182 | method: request.method, |
| 4183 | status: response.status, |
| 4184 | statusText: response.statusText, |
| 4185 | data: response.responseText, |
| 4186 | headers: headers |
| 4187 | }; |
| 4188 | |
| 4189 | try { |
| 4190 | var possibleObj = response.responseJSON || jsyaml.safeLoad(response.responseText); |
| 4191 | out.obj = (typeof possibleObj === 'string') ? {} : possibleObj; |
| 4192 | } catch (ex) { |
| 4193 | // do not set out.obj |
| 4194 | helpers.log('unable to parse JSON/YAML content'); |
| 4195 | } |
| 4196 | |
| 4197 | // I can throw, or parse null? |
| 4198 | out.obj = out.obj || null; |
| 4199 | |
| 4200 | if (response.status >= 200 && response.status < 300) { |
| 4201 | cb.response(out); |
| 4202 | } else if (response.status === 0 || (response.status >= 400 && response.status < 599)) { |
| 4203 | cb.error(out); |
| 4204 | } else { |
| 4205 | return cb.response(out); |
| 4206 | } |
| 4207 | }; |
| 4208 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4209 | jq.support.cors = true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4210 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4211 | return jq.ajax(obj); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4212 | }; |
| 4213 | |
| 4214 | SuperagentHttpClient.prototype.execute = function (obj) { |
| 4215 | var method = obj.method.toLowerCase(); |
| 4216 | |
| 4217 | if (method === 'delete') { |
| 4218 | method = 'del'; |
| 4219 | } |
| 4220 | var headers = obj.headers || {}; |
| 4221 | var r = request[method](obj.url); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4222 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4223 | if (obj.enableCookies) { |
| 4224 | r.withCredentials(); |
| 4225 | } |
| 4226 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4227 | if(obj.body) { |
| 4228 | if(_.isObject(obj.body)) { |
| 4229 | var contentType = obj.headers['Content-Type'] || ''; |
| 4230 | if (contentType.indexOf('multipart/form-data') === 0) { |
| 4231 | delete headers['Content-Type']; |
| 4232 | if({}.toString.apply(obj.body) === '[object FormData]') { |
| 4233 | var itr = obj.body.keys(); |
| 4234 | while(true) { |
| 4235 | var v = itr.next(); |
| 4236 | if(v.done) { |
| 4237 | break; |
| 4238 | } |
| 4239 | var key = v.value; |
| 4240 | var value = obj.body.get(key); |
| 4241 | console.log({}.toString.apply(value)); |
| 4242 | if({}.toString.apply(value) === '[object File]') { |
| 4243 | r.attach(key, value); |
| 4244 | } |
| 4245 | else { |
| 4246 | r.field(key, value); |
| 4247 | } |
| 4248 | } |
| 4249 | } |
| 4250 | else { |
| 4251 | var keyname; |
| 4252 | for (var keyname in obj.body) { |
| 4253 | var value = obj.body[keyname]; |
| 4254 | r.field(keyname, value); |
| 4255 | } |
| 4256 | } |
| 4257 | } |
| 4258 | else if (_.isObject(obj.body)) { |
| 4259 | obj.body = JSON.stringify(obj.body); |
| 4260 | r.send(obj.body); |
| 4261 | } |
| 4262 | } |
| 4263 | else { |
| 4264 | r.send(obj.body); |
| 4265 | } |
| 4266 | } |
| 4267 | |
| 4268 | var name; |
| 4269 | for (name in headers) { |
| 4270 | r.set(name, headers[name]); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4271 | } |
| 4272 | |
| 4273 | if(typeof r.buffer === 'function') { |
| 4274 | r.buffer(); // force superagent to populate res.text with the raw response data |
| 4275 | } |
| 4276 | |
| 4277 | r.end(function (err, res) { |
| 4278 | res = res || { |
| 4279 | status: 0, |
| 4280 | headers: {error: 'no response from server'} |
| 4281 | }; |
| 4282 | var response = { |
| 4283 | url: obj.url, |
| 4284 | method: obj.method, |
| 4285 | headers: res.headers |
| 4286 | }; |
| 4287 | var cb; |
| 4288 | |
| 4289 | if (!err && res.error) { |
| 4290 | err = res.error; |
| 4291 | } |
| 4292 | |
| 4293 | if (err && obj.on && obj.on.error) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4294 | response.errObj = err; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4295 | response.status = res ? res.status : 500; |
| 4296 | response.statusText = res ? res.text : err.message; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4297 | if(res.headers && res.headers['content-type']) { |
| 4298 | if(res.headers['content-type'].indexOf('application/json') >= 0) { |
| 4299 | try { |
| 4300 | response.obj = JSON.parse(response.statusText); |
| 4301 | } |
| 4302 | catch (e) { |
| 4303 | response.obj = null; |
| 4304 | } |
| 4305 | } |
| 4306 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4307 | cb = obj.on.error; |
| 4308 | } else if (res && obj.on && obj.on.response) { |
| 4309 | var possibleObj; |
| 4310 | |
| 4311 | // Already parsed by by superagent? |
| 4312 | if(res.body && Object.keys(res.body).length > 0) { |
| 4313 | possibleObj = res.body; |
| 4314 | } else { |
| 4315 | try { |
| 4316 | possibleObj = jsyaml.safeLoad(res.text); |
| 4317 | // can parse into a string... which we don't need running around in the system |
| 4318 | possibleObj = (typeof possibleObj === 'string') ? null : possibleObj; |
| 4319 | } catch(e) { |
| 4320 | helpers.log('cannot parse JSON/YAML content'); |
| 4321 | } |
| 4322 | } |
| 4323 | |
| 4324 | // null means we can't parse into object |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4325 | response.obj = (typeof possibleObj === 'object') ? possibleObj : null; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4326 | |
| 4327 | response.status = res.status; |
| 4328 | response.statusText = res.text; |
| 4329 | cb = obj.on.response; |
| 4330 | } |
| 4331 | response.data = response.statusText; |
| 4332 | |
| 4333 | if (cb) { |
| 4334 | cb(response); |
| 4335 | } |
| 4336 | }); |
| 4337 | }; |
| 4338 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4339 | },{"./helpers":4,"js-yaml":19,"lodash-compat/lang/isObject":144,"superagent":158}],6:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4340 | 'use strict'; |
| 4341 | |
| 4342 | var SwaggerHttp = require('./http'); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4343 | var _ = { |
| 4344 | isObject: require('lodash-compat/lang/isObject'), |
| 4345 | cloneDeep: require('lodash-compat/lang/cloneDeep'), |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4346 | isArray: require('lodash-compat/lang/isArray'), |
| 4347 | isString: require('lodash-compat/lang/isString') |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4348 | }; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4349 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4350 | |
| 4351 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4352 | * Resolves a spec's remote references |
| 4353 | */ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4354 | var Resolver = module.exports = function () { |
| 4355 | this.failedUrls = []; |
| 4356 | }; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4357 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4358 | Resolver.prototype.processAllOf = function(root, name, definition, resolutionTable, unresolvedRefs, spec) { |
| 4359 | var i, location, property; |
| 4360 | |
| 4361 | definition['x-resolved-from'] = [ '#/definitions/' + name ]; |
| 4362 | var allOf = definition.allOf; |
| 4363 | // the refs go first |
| 4364 | allOf.sort(function(a, b) { |
| 4365 | if(a.$ref && b.$ref) { return 0; } |
| 4366 | else if(a.$ref) { return -1; } |
| 4367 | else { return 1; } |
| 4368 | }); |
| 4369 | for (i = 0; i < allOf.length; i++) { |
| 4370 | property = allOf[i]; |
| 4371 | location = '/definitions/' + name + '/allOf'; |
| 4372 | this.resolveInline(root, spec, property, resolutionTable, unresolvedRefs, location); |
| 4373 | } |
| 4374 | }; |
| 4375 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4376 | Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4377 | this.spec = spec; |
| 4378 | var root = arg1, callback = arg2, scope = arg3, opts = {}, location, i; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4379 | if(typeof arg1 === 'function') { |
| 4380 | root = null; |
| 4381 | callback = arg1; |
| 4382 | scope = arg2; |
| 4383 | } |
| 4384 | var _root = root; |
| 4385 | this.scope = (scope || this); |
| 4386 | this.iteration = this.iteration || 0; |
| 4387 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4388 | if(this.scope.options && this.scope.options.requestInterceptor){ |
| 4389 | opts.requestInterceptor = this.scope.options.requestInterceptor; |
| 4390 | } |
| 4391 | |
| 4392 | if(this.scope.options && this.scope.options.responseInterceptor){ |
| 4393 | opts.responseInterceptor = this.scope.options.responseInterceptor; |
| 4394 | } |
| 4395 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4396 | var name, path, property, propertyName; |
| 4397 | var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {}; |
| 4398 | var resolutionTable = []; // store objects for dereferencing |
| 4399 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4400 | spec.definitions = spec.definitions || {}; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4401 | // definitions |
| 4402 | for (name in spec.definitions) { |
| 4403 | var definition = spec.definitions[name]; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4404 | if(definition['$ref']) { |
| 4405 | this.resolveInline(root, spec, definition, resolutionTable, unresolvedRefs, definition); |
| 4406 | } |
| 4407 | else { |
| 4408 | for (propertyName in definition.properties) { |
| 4409 | property = definition.properties[propertyName]; |
| 4410 | if (_.isArray(property.allOf)) { |
| 4411 | this.processAllOf(root, name, property, resolutionTable, unresolvedRefs, spec); |
| 4412 | } |
| 4413 | else { |
| 4414 | this.resolveTo(root, property, resolutionTable, '/definitions'); |
| 4415 | } |
| 4416 | } |
| 4417 | |
| 4418 | if (definition.allOf) { |
| 4419 | this.processAllOf(root, name, definition, resolutionTable, unresolvedRefs, spec); |
| 4420 | } |
| 4421 | } |
| 4422 | } |
| 4423 | |
| 4424 | // shared parameters |
| 4425 | spec.parameters = spec.parameters || {}; |
| 4426 | for(name in spec.parameters) { |
| 4427 | var parameter = spec.parameters[name]; |
| 4428 | if (parameter.in === 'body' && parameter.schema) { |
| 4429 | if(_.isArray(parameter.schema.allOf)) { |
| 4430 | // move to a definition |
| 4431 | var modelName = 'inline_model'; |
| 4432 | var name = modelName; |
| 4433 | var done = false; var counter = 0; |
| 4434 | while(!done) { |
| 4435 | if(typeof spec.definitions[name] === 'undefined') { |
| 4436 | done = true; |
| 4437 | break; |
| 4438 | } |
| 4439 | name = modelName + '_' + counter; |
| 4440 | counter ++; |
| 4441 | } |
| 4442 | spec.definitions[name] = { allOf: parameter.schema.allOf }; |
| 4443 | delete parameter.schema.allOf; |
| 4444 | parameter.schema.$ref = '#/definitions/' + name; |
| 4445 | this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4446 | } |
| 4447 | else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4448 | this.resolveTo(root, parameter.schema, resolutionTable, location); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4449 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4450 | } |
| 4451 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4452 | if (parameter.$ref) { |
| 4453 | // parameter reference |
| 4454 | this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4455 | } |
| 4456 | } |
| 4457 | |
| 4458 | // operations |
| 4459 | for (name in spec.paths) { |
| 4460 | var method, operation, responseCode; |
| 4461 | path = spec.paths[name]; |
| 4462 | |
| 4463 | for (method in path) { |
| 4464 | // operation reference |
| 4465 | if(method === '$ref') { |
| 4466 | // location = path[method]; |
| 4467 | location = '/paths' + name; |
| 4468 | this.resolveInline(root, spec, path, resolutionTable, unresolvedRefs, location); |
| 4469 | } |
| 4470 | else { |
| 4471 | operation = path[method]; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4472 | var sharedParameters = path.parameters || []; |
| 4473 | var parameters = operation.parameters || []; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4474 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4475 | for (i in sharedParameters) { |
| 4476 | var parameter = sharedParameters[i]; |
| 4477 | parameters.unshift(parameter); |
| 4478 | } |
| 4479 | if(method !== 'parameters' && _.isObject(operation)) { |
| 4480 | operation.parameters = operation.parameters || parameters; |
| 4481 | } |
| 4482 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4483 | for (i in parameters) { |
| 4484 | var parameter = parameters[i]; |
| 4485 | location = '/paths' + name + '/' + method + '/parameters'; |
| 4486 | |
| 4487 | if (parameter.in === 'body' && parameter.schema) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4488 | if(_.isArray(parameter.schema.allOf)) { |
| 4489 | // move to a definition |
| 4490 | var modelName = 'inline_model'; |
| 4491 | var name = modelName; |
| 4492 | var done = false; var counter = 0; |
| 4493 | while(!done) { |
| 4494 | if(typeof spec.definitions[name] === 'undefined') { |
| 4495 | done = true; |
| 4496 | break; |
| 4497 | } |
| 4498 | name = modelName + '_' + counter; |
| 4499 | counter ++; |
| 4500 | } |
| 4501 | spec.definitions[name] = { allOf: parameter.schema.allOf }; |
| 4502 | delete parameter.schema.allOf; |
| 4503 | parameter.schema.$ref = '#/definitions/' + name; |
| 4504 | this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec); |
| 4505 | } |
| 4506 | else { |
| 4507 | this.resolveTo(root, parameter.schema, resolutionTable, location); |
| 4508 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4509 | } |
| 4510 | |
| 4511 | if (parameter.$ref) { |
| 4512 | // parameter reference |
| 4513 | this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref); |
| 4514 | } |
| 4515 | } |
| 4516 | |
| 4517 | for (responseCode in operation.responses) { |
| 4518 | var response = operation.responses[responseCode]; |
| 4519 | location = '/paths' + name + '/' + method + '/responses/' + responseCode; |
| 4520 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4521 | if(_.isObject(response)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4522 | if(response.$ref) { |
| 4523 | // response reference |
| 4524 | this.resolveInline(root, spec, response, resolutionTable, unresolvedRefs, location); |
| 4525 | } |
| 4526 | if (response.schema) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4527 | var responseObj = response; |
| 4528 | if(_.isArray(responseObj.schema.allOf)) { |
| 4529 | // move to a definition |
| 4530 | var modelName = 'inline_model'; |
| 4531 | var name = modelName; |
| 4532 | var done = false; var counter = 0; |
| 4533 | while(!done) { |
| 4534 | if(typeof spec.definitions[name] === 'undefined') { |
| 4535 | done = true; |
| 4536 | break; |
| 4537 | } |
| 4538 | name = modelName + '_' + counter; |
| 4539 | counter ++; |
| 4540 | } |
| 4541 | spec.definitions[name] = { allOf: responseObj.schema.allOf }; |
| 4542 | delete responseObj.schema.allOf; |
| 4543 | delete responseObj.schema.type; |
| 4544 | responseObj.schema.$ref = '#/definitions/' + name; |
| 4545 | this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec); |
| 4546 | } |
| 4547 | else if('array' === responseObj.schema.type) { |
| 4548 | if(responseObj.schema.items && responseObj.schema.items.$ref) { |
| 4549 | // response reference |
| 4550 | this.resolveInline(root, spec, responseObj.schema.items, resolutionTable, unresolvedRefs, location); |
| 4551 | } |
| 4552 | } |
| 4553 | else { |
| 4554 | this.resolveTo(root, response.schema, resolutionTable, location); |
| 4555 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4556 | } |
| 4557 | } |
| 4558 | } |
| 4559 | } |
| 4560 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4561 | // clear them out to avoid multiple resolutions |
| 4562 | path.parameters = []; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4563 | } |
| 4564 | |
| 4565 | var expectedCalls = 0, toResolve = []; |
| 4566 | // if the root is same as obj[i].root we can resolve locally |
| 4567 | var all = resolutionTable; |
| 4568 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4569 | var parts; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4570 | for(i = 0; i < all.length; i++) { |
| 4571 | var a = all[i]; |
| 4572 | if(root === a.root) { |
| 4573 | if(a.resolveAs === 'ref') { |
| 4574 | // resolve any path walking |
| 4575 | var joined = ((a.root || '') + '/' + a.key).split('/'); |
| 4576 | var normalized = []; |
| 4577 | var url = ''; |
| 4578 | var k; |
| 4579 | |
| 4580 | if(a.key.indexOf('../') >= 0) { |
| 4581 | for(var j = 0; j < joined.length; j++) { |
| 4582 | if(joined[j] === '..') { |
| 4583 | normalized = normalized.slice(0, normalized.length-1); |
| 4584 | } |
| 4585 | else { |
| 4586 | normalized.push(joined[j]); |
| 4587 | } |
| 4588 | } |
| 4589 | for(k = 0; k < normalized.length; k ++) { |
| 4590 | if(k > 0) { |
| 4591 | url += '/'; |
| 4592 | } |
| 4593 | url += normalized[k]; |
| 4594 | } |
| 4595 | // we now have to remote resolve this because the path has changed |
| 4596 | a.root = url; |
| 4597 | toResolve.push(a); |
| 4598 | } |
| 4599 | else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4600 | parts = a.key.split('#'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4601 | if(parts.length === 2) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4602 | if(parts[0].indexOf('http:') === 0 || parts[0].indexOf('https:') === 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4603 | a.root = parts[0]; |
| 4604 | } |
| 4605 | location = parts[1].split('/'); |
| 4606 | var r; |
| 4607 | var s = spec; |
| 4608 | for(k = 0; k < location.length; k++) { |
| 4609 | var part = location[k]; |
| 4610 | if(part !== '') { |
| 4611 | s = s[part]; |
| 4612 | if(typeof s !== 'undefined') { |
| 4613 | r = s; |
| 4614 | } |
| 4615 | else { |
| 4616 | r = null; |
| 4617 | break; |
| 4618 | } |
| 4619 | } |
| 4620 | } |
| 4621 | if(r === null) { |
| 4622 | // must resolve this too |
| 4623 | toResolve.push(a); |
| 4624 | } |
| 4625 | } |
| 4626 | } |
| 4627 | } |
| 4628 | else { |
| 4629 | if (a.resolveAs === 'inline') { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4630 | if(a.key && a.key.indexOf('#') === -1 && a.key.charAt(0) !== '/') { |
| 4631 | // handle relative schema |
| 4632 | parts = a.root.split('/'); |
| 4633 | location = ''; |
| 4634 | for(i = 0; i < parts.length - 1; i++) { |
| 4635 | location += parts[i] + '/'; |
| 4636 | } |
| 4637 | location += a.key; |
| 4638 | a.root = location; |
| 4639 | a.location = ''; |
| 4640 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4641 | toResolve.push(a); |
| 4642 | } |
| 4643 | } |
| 4644 | } |
| 4645 | else { |
| 4646 | toResolve.push(a); |
| 4647 | } |
| 4648 | } |
| 4649 | expectedCalls = toResolve.length; |
| 4650 | |
| 4651 | // resolve anything that is local |
| 4652 | for(var ii = 0; ii < toResolve.length; ii++) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4653 | (function(item, spec, self) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4654 | // NOTE: this used to be item.root === null, but I (@ponelat) have added a guard against .split, which means item.root can be '' |
| 4655 | if(!item.root || item.root === root) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4656 | // local resolve |
| 4657 | self.resolveItem(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, item); |
| 4658 | processedCalls += 1; |
| 4659 | |
| 4660 | if(processedCalls === expectedCalls) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4661 | self.finish(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, true); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4662 | } |
| 4663 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4664 | else if(self.failedUrls.indexOf(item.root) === -1) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4665 | var obj = { |
| 4666 | useJQuery: false, // TODO |
| 4667 | url: item.root, |
| 4668 | method: 'get', |
| 4669 | headers: { |
| 4670 | accept: self.scope.swaggerRequestHeaders || 'application/json' |
| 4671 | }, |
| 4672 | on: { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4673 | error: function (error) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4674 | processedCalls += 1; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4675 | console.log('failed url: ' + obj.url); |
| 4676 | self.failedUrls.push(obj.url); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4677 | unresolvedRefs[item.key] = { |
| 4678 | root: item.root, |
| 4679 | location: item.location |
| 4680 | }; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4681 | |
| 4682 | if (processedCalls === expectedCalls) { |
| 4683 | self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| 4684 | } |
| 4685 | }, // jshint ignore:line |
| 4686 | response: function (response) { |
| 4687 | var swagger = response.obj; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4688 | self.resolveItem(swagger, item.root, resolutionTable, resolvedRefs, unresolvedRefs, item); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4689 | processedCalls += 1; |
| 4690 | |
| 4691 | if (processedCalls === expectedCalls) { |
| 4692 | self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| 4693 | } |
| 4694 | } |
| 4695 | } // jshint ignore:line |
| 4696 | }; |
| 4697 | |
| 4698 | if (scope && scope.clientAuthorizations) { |
| 4699 | scope.clientAuthorizations.apply(obj); |
| 4700 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4701 | |
| 4702 | new SwaggerHttp().execute(obj, opts); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4703 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4704 | else { |
| 4705 | processedCalls += 1; |
| 4706 | unresolvedRefs[item.key] = { |
| 4707 | root: item.root, |
| 4708 | location: item.location |
| 4709 | }; |
| 4710 | if (processedCalls === expectedCalls) { |
| 4711 | self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| 4712 | } |
| 4713 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4714 | }(toResolve[ii], spec, this)); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4715 | } |
| 4716 | |
| 4717 | if (Object.keys(toResolve).length === 0) { |
| 4718 | this.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); |
| 4719 | } |
| 4720 | }; |
| 4721 | |
| 4722 | Resolver.prototype.resolveItem = function(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, item) { |
| 4723 | var path = item.location; |
| 4724 | var location = spec, parts = path.split('/'); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4725 | if(path !== '') { |
| 4726 | for (var j = 0; j < parts.length; j++) { |
| 4727 | var segment = parts[j]; |
| 4728 | if (segment.indexOf('~1') !== -1) { |
| 4729 | segment = parts[j].replace(/~0/g, '~').replace(/~1/g, '/'); |
| 4730 | if (segment.charAt(0) !== '/') { |
| 4731 | segment = '/' + segment; |
| 4732 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4733 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4734 | if (typeof location === 'undefined' || location === null) { |
| 4735 | break; |
| 4736 | } |
| 4737 | if (segment === '' && j === (parts.length - 1) && parts.length > 1) { |
| 4738 | location = null; |
| 4739 | break; |
| 4740 | } |
| 4741 | if (segment.length > 0) { |
| 4742 | location = location[segment]; |
| 4743 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4744 | } |
| 4745 | } |
| 4746 | var resolved = item.key; |
| 4747 | parts = item.key.split('/'); |
| 4748 | var resolvedName = parts[parts.length-1]; |
| 4749 | |
| 4750 | if(resolvedName.indexOf('#') >= 0) { |
| 4751 | resolvedName = resolvedName.split('#')[1]; |
| 4752 | } |
| 4753 | |
| 4754 | if (location !== null && typeof location !== 'undefined') { |
| 4755 | resolvedRefs[resolved] = { |
| 4756 | name: resolvedName, |
| 4757 | obj: location, |
| 4758 | key: item.key, |
| 4759 | root: item.root |
| 4760 | }; |
| 4761 | } else { |
| 4762 | unresolvedRefs[resolved] = { |
| 4763 | root: item.root, |
| 4764 | location: item.location |
| 4765 | }; |
| 4766 | } |
| 4767 | }; |
| 4768 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4769 | Resolver.prototype.finish = function (spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, localResolve) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4770 | // walk resolution table and replace with resolved refs |
| 4771 | var ref; |
| 4772 | for (ref in resolutionTable) { |
| 4773 | var item = resolutionTable[ref]; |
| 4774 | |
| 4775 | var key = item.key; |
| 4776 | var resolvedTo = resolvedRefs[key]; |
| 4777 | if (resolvedTo) { |
| 4778 | spec.definitions = spec.definitions || {}; |
| 4779 | if (item.resolveAs === 'ref') { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4780 | if (localResolve !== true) { |
| 4781 | // don't retain root for local definitions |
| 4782 | for (key in resolvedTo.obj) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4783 | var abs = this.retainRoot(key, resolvedTo.obj[key], item.root); |
| 4784 | resolvedTo.obj[key] = abs; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4785 | } |
| 4786 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4787 | spec.definitions[resolvedTo.name] = resolvedTo.obj; |
| 4788 | item.obj.$ref = '#/definitions/' + resolvedTo.name; |
| 4789 | } else if (item.resolveAs === 'inline') { |
| 4790 | var targetObj = item.obj; |
| 4791 | targetObj['x-resolved-from'] = [ item.key ]; |
| 4792 | delete targetObj.$ref; |
| 4793 | |
| 4794 | for (key in resolvedTo.obj) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4795 | var abs = resolvedTo.obj[key]; |
| 4796 | |
| 4797 | if (localResolve !== true) { |
| 4798 | // don't retain root for local definitions |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4799 | abs = this.retainRoot(key, resolvedTo.obj[key], item.root); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4800 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4801 | targetObj[key] = abs; |
| 4802 | } |
| 4803 | } |
| 4804 | } |
| 4805 | } |
| 4806 | var existingUnresolved = this.countUnresolvedRefs(spec); |
| 4807 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4808 | if(existingUnresolved === 0 || this.iteration > 5) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4809 | this.resolveAllOf(spec.definitions); |
| 4810 | callback.call(this.scope, spec, unresolvedRefs); |
| 4811 | } |
| 4812 | else { |
| 4813 | this.iteration += 1; |
| 4814 | this.resolve(spec, root, callback, this.scope); |
| 4815 | } |
| 4816 | }; |
| 4817 | |
| 4818 | Resolver.prototype.countUnresolvedRefs = function(spec) { |
| 4819 | var i; |
| 4820 | var refs = this.getRefs(spec); |
| 4821 | var keys = []; |
| 4822 | var unresolvedKeys = []; |
| 4823 | for(i in refs) { |
| 4824 | if(i.indexOf('#') === 0) { |
| 4825 | keys.push(i.substring(1)); |
| 4826 | } |
| 4827 | else { |
| 4828 | unresolvedKeys.push(i); |
| 4829 | } |
| 4830 | } |
| 4831 | |
| 4832 | // verify possible keys |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4833 | for (i = 0; i < keys.length; i++) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4834 | var part = keys[i]; |
| 4835 | var parts = part.split('/'); |
| 4836 | var obj = spec; |
| 4837 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4838 | for (var k = 0; k < parts.length; k++) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4839 | var key = parts[k]; |
| 4840 | if(key !== '') { |
| 4841 | obj = obj[key]; |
| 4842 | if(typeof obj === 'undefined') { |
| 4843 | unresolvedKeys.push(part); |
| 4844 | break; |
| 4845 | } |
| 4846 | } |
| 4847 | } |
| 4848 | } |
| 4849 | return unresolvedKeys.length; |
| 4850 | }; |
| 4851 | |
| 4852 | Resolver.prototype.getRefs = function(spec, obj) { |
| 4853 | obj = obj || spec; |
| 4854 | var output = {}; |
| 4855 | for(var key in obj) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4856 | if (!obj.hasOwnProperty(key)) { |
| 4857 | continue; |
| 4858 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4859 | var item = obj[key]; |
| 4860 | if(key === '$ref' && typeof item === 'string') { |
| 4861 | output[item] = null; |
| 4862 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 4863 | else if(_.isObject(item)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4864 | var o = this.getRefs(item); |
| 4865 | for(var k in o) { |
| 4866 | output[k] = null; |
| 4867 | } |
| 4868 | } |
| 4869 | } |
| 4870 | return output; |
| 4871 | }; |
| 4872 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4873 | Resolver.prototype.retainRoot = function(origKey, obj, root) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4874 | // walk object and look for relative $refs |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4875 | if(_.isObject(obj)) { |
| 4876 | for(var key in obj) { |
| 4877 | var item = obj[key]; |
| 4878 | if (key === '$ref' && typeof item === 'string') { |
| 4879 | // stop and inspect |
| 4880 | if (item.indexOf('http:') !== 0 && item.indexOf('https:') !== 0) { |
| 4881 | // TODO: check if root ends in '/'. If not, AND item has no protocol, make relative |
| 4882 | var appendHash = true; |
| 4883 | var oldRoot = root; |
| 4884 | if (root) { |
| 4885 | var lastChar = root.slice(-1); |
| 4886 | if (lastChar !== '/' && (item.indexOf('#') !== 0 && item.indexOf('http:') !== 0 && item.indexOf('https:'))) { |
| 4887 | appendHash = false; |
| 4888 | var parts = root.split('\/'); |
| 4889 | parts = parts.splice(0, parts.length - 1); |
| 4890 | root = ''; |
| 4891 | for (var i = 0; i < parts.length; i++) { |
| 4892 | root += parts[i] + '/'; |
| 4893 | } |
| 4894 | } |
| 4895 | } |
| 4896 | if (item.indexOf('#') !== 0 && appendHash) { |
| 4897 | item = '#' + item; |
| 4898 | } |
| 4899 | |
| 4900 | item = (root || '') + item; |
| 4901 | obj[key] = item; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4902 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4903 | } |
| 4904 | else if (_.isObject(item)) { |
| 4905 | this.retainRoot(key, item, root); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4906 | } |
| 4907 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4908 | } |
| 4909 | else if(_.isString(obj) && origKey === '$ref') { |
| 4910 | // look at the ref? |
| 4911 | if(obj.indexOf('http:') === -1 && obj.indexOf('https:') === -1) { |
| 4912 | obj = root + obj; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4913 | } |
| 4914 | } |
| 4915 | return obj; |
| 4916 | }; |
| 4917 | |
| 4918 | /** |
| 4919 | * immediately in-lines local refs, queues remote refs |
| 4920 | * for inline resolution |
| 4921 | */ |
| 4922 | Resolver.prototype.resolveInline = function (root, spec, property, resolutionTable, unresolvedRefs, location) { |
| 4923 | var key = property.$ref, ref = property.$ref, i, p, p2, rs; |
| 4924 | var rootTrimmed = false; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4925 | |
| 4926 | root = root || '' // Guard against .split. @fehguy, you'll need to check if this logic fits |
| 4927 | // More imporantly is how do we gracefully handle relative urls, when provided just a 'spec', not a 'url' ? |
| 4928 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4929 | if (ref) { |
| 4930 | if(ref.indexOf('../') === 0) { |
| 4931 | // reset root |
| 4932 | p = ref.split('../'); |
| 4933 | p2 = root.split('/'); |
| 4934 | ref = ''; |
| 4935 | for(i = 0; i < p.length; i++) { |
| 4936 | if(p[i] === '') { |
| 4937 | p2 = p2.slice(0, p2.length-1); |
| 4938 | } |
| 4939 | else { |
| 4940 | ref += p[i]; |
| 4941 | } |
| 4942 | } |
| 4943 | root = ''; |
| 4944 | for(i = 0; i < p2.length - 1; i++) { |
| 4945 | if(i > 0) { root += '/'; } |
| 4946 | root += p2[i]; |
| 4947 | } |
| 4948 | rootTrimmed = true; |
| 4949 | } |
| 4950 | if(ref.indexOf('#') >= 0) { |
| 4951 | if(ref.indexOf('/') === 0) { |
| 4952 | rs = ref.split('#'); |
| 4953 | p = root.split('//'); |
| 4954 | p2 = p[1].split('/'); |
| 4955 | root = p[0] + '//' + p2[0] + rs[0]; |
| 4956 | location = rs[1]; |
| 4957 | } |
| 4958 | else { |
| 4959 | rs = ref.split('#'); |
| 4960 | if(rs[0] !== '') { |
| 4961 | p2 = root.split('/'); |
| 4962 | p2 = p2.slice(0, p2.length - 1); |
| 4963 | if(!rootTrimmed) { |
| 4964 | root = ''; |
| 4965 | for (var k = 0; k < p2.length; k++) { |
| 4966 | if(k > 0) { root += '/'; } |
| 4967 | root += p2[k]; |
| 4968 | } |
| 4969 | } |
| 4970 | root += '/' + ref.split('#')[0]; |
| 4971 | } |
| 4972 | location = rs[1]; |
| 4973 | } |
| 4974 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4975 | if (ref.indexOf('http:') === 0 || ref.indexOf('https:') === 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4976 | if(ref.indexOf('#') >= 0) { |
| 4977 | root = ref.split('#')[0]; |
| 4978 | location = ref.split('#')[1]; |
| 4979 | } |
| 4980 | else { |
| 4981 | root = ref; |
| 4982 | location = ''; |
| 4983 | } |
| 4984 | resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
| 4985 | } else if (ref.indexOf('#') === 0) { |
| 4986 | location = ref.split('#')[1]; |
| 4987 | resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 4988 | } else if (ref.indexOf('/') === 0 && ref.indexOf('#') === -1) { |
| 4989 | location = ref; |
| 4990 | var matches = root.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); |
| 4991 | if(matches) { |
| 4992 | root = matches[0] + ref.substring(1); |
| 4993 | location = ''; |
| 4994 | } |
| 4995 | resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 4996 | } |
| 4997 | else { |
| 4998 | resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); |
| 4999 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5000 | } |
| 5001 | else if (property.type === 'array') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5002 | this.resolveTo(root, property.items, resolutionTable, location); |
| 5003 | } |
| 5004 | }; |
| 5005 | |
| 5006 | Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5007 | var sp, i; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5008 | var ref = property.$ref; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5009 | var lroot = root; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5010 | if ((typeof ref !== 'undefined') && (ref !== null)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5011 | if(ref.indexOf('#') >= 0) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5012 | var parts = ref.split('#'); |
| 5013 | |
| 5014 | // #/definitions/foo |
| 5015 | // foo.json#/bar |
| 5016 | if(parts[0] && ref.indexOf('/') === 0) { |
| 5017 | |
| 5018 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5019 | else if(parts[0] && (parts[0].indexOf('http:') === 0 || parts[0].indexOf('https:') === 0)) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5020 | lroot = parts[0]; |
| 5021 | ref = parts[1]; |
| 5022 | } |
| 5023 | else if(parts[0] && parts[0].length > 0) { |
| 5024 | // relative file |
| 5025 | sp = root.split('/'); |
| 5026 | lroot = ''; |
| 5027 | for(i = 0; i < sp.length - 1; i++) { |
| 5028 | lroot += sp[i] + '/'; |
| 5029 | } |
| 5030 | lroot += parts[0]; |
| 5031 | } |
| 5032 | else { |
| 5033 | |
| 5034 | } |
| 5035 | |
| 5036 | location = parts[1]; |
| 5037 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5038 | else if (ref.indexOf('http:') === 0 || ref.indexOf('https:') === 0) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5039 | lroot = ref; |
| 5040 | location = ''; |
| 5041 | } |
| 5042 | else { |
| 5043 | // relative file |
| 5044 | sp = root.split('/'); |
| 5045 | lroot = ''; |
| 5046 | for(i = 0; i < sp.length - 1; i++) { |
| 5047 | lroot += sp[i] + '/'; |
| 5048 | } |
| 5049 | lroot += ref; |
| 5050 | location = ''; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5051 | } |
| 5052 | resolutionTable.push({ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5053 | obj: property, resolveAs: 'ref', root: lroot, key: ref, location: location |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5054 | }); |
| 5055 | } else if (property.type === 'array') { |
| 5056 | var items = property.items; |
| 5057 | this.resolveTo(root, items, resolutionTable, location); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5058 | } else { |
| 5059 | if(property && property.properties) { |
| 5060 | var name = this.uniqueName('inline_model'); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5061 | if (property.title) { |
| 5062 | name = this.uniqueName(property.title); |
| 5063 | } |
| 5064 | delete property.title; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5065 | this.spec.definitions[name] = _.cloneDeep(property); |
| 5066 | property['$ref'] = '#/definitions/' + name; |
| 5067 | delete property.type; |
| 5068 | delete property.properties; |
| 5069 | } |
| 5070 | } |
| 5071 | }; |
| 5072 | |
| 5073 | Resolver.prototype.uniqueName = function(base) { |
| 5074 | var name = base; |
| 5075 | var count = 0; |
| 5076 | while(true) { |
| 5077 | if(!_.isObject(this.spec.definitions[name])) { |
| 5078 | return name; |
| 5079 | } |
| 5080 | name = base + '_' + count; |
| 5081 | count++; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5082 | } |
| 5083 | }; |
| 5084 | |
| 5085 | Resolver.prototype.resolveAllOf = function(spec, obj, depth) { |
| 5086 | depth = depth || 0; |
| 5087 | obj = obj || spec; |
| 5088 | var name; |
| 5089 | for(var key in obj) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5090 | if (!obj.hasOwnProperty(key)) { |
| 5091 | continue; |
| 5092 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5093 | var item = obj[key]; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5094 | if(item === null) { |
| 5095 | throw new TypeError('Swagger 2.0 does not support null types (' + obj + '). See https://github.com/swagger-api/swagger-spec/issues/229.'); |
| 5096 | } |
| 5097 | if(typeof item === 'object') { |
| 5098 | this.resolveAllOf(spec, item, depth + 1); |
| 5099 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5100 | if(item && typeof item.allOf !== 'undefined') { |
| 5101 | var allOf = item.allOf; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5102 | if(_.isArray(allOf)) { |
| 5103 | var output = _.cloneDeep(item); |
| 5104 | delete output.allOf; |
| 5105 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5106 | output['x-composed'] = true; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5107 | if (typeof item['x-resolved-from'] !== 'undefined') { |
| 5108 | output['x-resolved-from'] = item['x-resolved-from']; |
| 5109 | } |
| 5110 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5111 | for(var i = 0; i < allOf.length; i++) { |
| 5112 | var component = allOf[i]; |
| 5113 | var source = 'self'; |
| 5114 | if(typeof component['x-resolved-from'] !== 'undefined') { |
| 5115 | source = component['x-resolved-from'][0]; |
| 5116 | } |
| 5117 | |
| 5118 | for(var part in component) { |
| 5119 | if(!output.hasOwnProperty(part)) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5120 | output[part] = _.cloneDeep(component[part]); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5121 | if(part === 'properties') { |
| 5122 | for(name in output[part]) { |
| 5123 | output[part][name]['x-resolved-from'] = source; |
| 5124 | } |
| 5125 | } |
| 5126 | } |
| 5127 | else { |
| 5128 | if(part === 'properties') { |
| 5129 | var properties = component[part]; |
| 5130 | for(name in properties) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5131 | output.properties[name] = _.cloneDeep(properties[name]); |
| 5132 | var resolvedFrom = properties[name]['x-resolved-from']; |
| 5133 | if (typeof resolvedFrom === 'undefined' || resolvedFrom === 'self') { |
| 5134 | resolvedFrom = source; |
| 5135 | } |
| 5136 | output.properties[name]['x-resolved-from'] = resolvedFrom; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5137 | } |
| 5138 | } |
| 5139 | else if(part === 'required') { |
| 5140 | // merge & dedup the required array |
| 5141 | var a = output.required.concat(component[part]); |
| 5142 | for(var k = 0; k < a.length; ++k) { |
| 5143 | for(var j = k + 1; j < a.length; ++j) { |
| 5144 | if(a[k] === a[j]) { a.splice(j--, 1); } |
| 5145 | } |
| 5146 | } |
| 5147 | output.required = a; |
| 5148 | } |
| 5149 | else if(part === 'x-resolved-from') { |
| 5150 | output['x-resolved-from'].push(source); |
| 5151 | } |
| 5152 | else { |
| 5153 | // TODO: need to merge this property |
| 5154 | // console.log('what to do with ' + part) |
| 5155 | } |
| 5156 | } |
| 5157 | } |
| 5158 | } |
| 5159 | obj[key] = output; |
| 5160 | } |
| 5161 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5162 | } |
| 5163 | }; |
| 5164 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5165 | },{"./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){ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5166 | 'use strict'; |
| 5167 | |
| 5168 | var Helpers = require('./helpers'); |
| 5169 | |
| 5170 | var _ = { |
| 5171 | isPlainObject: require('lodash-compat/lang/isPlainObject'), |
| 5172 | isUndefined: require('lodash-compat/lang/isUndefined'), |
| 5173 | isArray: require('lodash-compat/lang/isArray'), |
| 5174 | isObject: require('lodash-compat/lang/isObject'), |
| 5175 | isEmpty: require('lodash-compat/lang/isEmpty'), |
| 5176 | map: require('lodash-compat/collection/map'), |
| 5177 | indexOf: require('lodash-compat/array/indexOf'), |
| 5178 | cloneDeep: require('lodash-compat/lang/cloneDeep'), |
| 5179 | keys: require('lodash-compat/object/keys'), |
| 5180 | forEach: require('lodash-compat/collection/forEach') |
| 5181 | }; |
| 5182 | |
| 5183 | module.exports.optionHtml = optionHtml; |
| 5184 | module.exports.typeFromJsonSchema = typeFromJsonSchema; |
| 5185 | module.exports.getStringSignature = getStringSignature; |
| 5186 | module.exports.schemaToHTML = schemaToHTML; |
| 5187 | module.exports.schemaToJSON = schemaToJSON; |
| 5188 | |
| 5189 | function optionHtml(label, value) { |
| 5190 | return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>'; |
| 5191 | } |
| 5192 | |
| 5193 | function typeFromJsonSchema(type, format) { |
| 5194 | var str; |
| 5195 | |
| 5196 | if (type === 'integer' && format === 'int32') { |
| 5197 | str = 'integer'; |
| 5198 | } else if (type === 'integer' && format === 'int64') { |
| 5199 | str = 'long'; |
| 5200 | } else if (type === 'integer' && typeof format === 'undefined') { |
| 5201 | str = 'long'; |
| 5202 | } else if (type === 'string' && format === 'date-time') { |
| 5203 | str = 'date-time'; |
| 5204 | } else if (type === 'string' && format === 'date') { |
| 5205 | str = 'date'; |
| 5206 | } else if (type === 'number' && format === 'float') { |
| 5207 | str = 'float'; |
| 5208 | } else if (type === 'number' && format === 'double') { |
| 5209 | str = 'double'; |
| 5210 | } else if (type === 'number' && typeof format === 'undefined') { |
| 5211 | str = 'double'; |
| 5212 | } else if (type === 'boolean') { |
| 5213 | str = 'boolean'; |
| 5214 | } else if (type === 'string') { |
| 5215 | str = 'string'; |
| 5216 | } |
| 5217 | |
| 5218 | return str; |
| 5219 | } |
| 5220 | |
| 5221 | function getStringSignature(obj, baseComponent) { |
| 5222 | var str = ''; |
| 5223 | |
| 5224 | if (typeof obj.$ref !== 'undefined') { |
| 5225 | str += Helpers.simpleRef(obj.$ref); |
| 5226 | } else if (typeof obj.type === 'undefined') { |
| 5227 | str += 'object'; |
| 5228 | } else if (obj.type === 'array') { |
| 5229 | if (baseComponent) { |
| 5230 | str += getStringSignature((obj.items || obj.$ref || {})); |
| 5231 | } else { |
| 5232 | str += 'Array['; |
| 5233 | str += getStringSignature((obj.items || obj.$ref || {})); |
| 5234 | str += ']'; |
| 5235 | } |
| 5236 | } else if (obj.type === 'integer' && obj.format === 'int32') { |
| 5237 | str += 'integer'; |
| 5238 | } else if (obj.type === 'integer' && obj.format === 'int64') { |
| 5239 | str += 'long'; |
| 5240 | } else if (obj.type === 'integer' && typeof obj.format === 'undefined') { |
| 5241 | str += 'long'; |
| 5242 | } else if (obj.type === 'string' && obj.format === 'date-time') { |
| 5243 | str += 'date-time'; |
| 5244 | } else if (obj.type === 'string' && obj.format === 'date') { |
| 5245 | str += 'date'; |
| 5246 | } else if (obj.type === 'string' && typeof obj.format === 'undefined') { |
| 5247 | str += 'string'; |
| 5248 | } else if (obj.type === 'number' && obj.format === 'float') { |
| 5249 | str += 'float'; |
| 5250 | } else if (obj.type === 'number' && obj.format === 'double') { |
| 5251 | str += 'double'; |
| 5252 | } else if (obj.type === 'number' && typeof obj.format === 'undefined') { |
| 5253 | str += 'double'; |
| 5254 | } else if (obj.type === 'boolean') { |
| 5255 | str += 'boolean'; |
| 5256 | } else if (obj.$ref) { |
| 5257 | str += Helpers.simpleRef(obj.$ref); |
| 5258 | } else { |
| 5259 | str += obj.type; |
| 5260 | } |
| 5261 | |
| 5262 | return str; |
| 5263 | } |
| 5264 | |
| 5265 | function schemaToJSON(schema, models, modelsToIgnore, modelPropertyMacro) { |
| 5266 | // Resolve the schema (Handle nested schemas) |
| 5267 | schema = Helpers.resolveSchema(schema); |
| 5268 | |
| 5269 | if(typeof modelPropertyMacro !== 'function') { |
| 5270 | modelPropertyMacro = function(prop){ |
| 5271 | return (prop || {}).default; |
| 5272 | }; |
| 5273 | } |
| 5274 | |
| 5275 | modelsToIgnore= modelsToIgnore || {}; |
| 5276 | |
| 5277 | var type = schema.type || 'object'; |
| 5278 | var format = schema.format; |
| 5279 | var model; |
| 5280 | var output; |
| 5281 | |
| 5282 | if (!_.isUndefined(schema.example)) { |
| 5283 | output = schema.example; |
| 5284 | } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) { |
| 5285 | output = schema.enum[0]; |
| 5286 | } |
| 5287 | |
| 5288 | if (_.isUndefined(output)) { |
| 5289 | if (schema.$ref) { |
| 5290 | model = models[Helpers.simpleRef(schema.$ref)]; |
| 5291 | |
| 5292 | if (!_.isUndefined(model)) { |
| 5293 | if (_.isUndefined(modelsToIgnore[model.name])) { |
| 5294 | modelsToIgnore[model.name] = model; |
| 5295 | output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro); |
| 5296 | delete modelsToIgnore[model.name]; |
| 5297 | } else { |
| 5298 | if (model.type === 'array') { |
| 5299 | output = []; |
| 5300 | } else { |
| 5301 | output = {}; |
| 5302 | } |
| 5303 | } |
| 5304 | } |
| 5305 | } else if (!_.isUndefined(schema.default)) { |
| 5306 | output = schema.default; |
| 5307 | } else if (type === 'string') { |
| 5308 | if (format === 'date-time') { |
| 5309 | output = new Date().toISOString(); |
| 5310 | } else if (format === 'date') { |
| 5311 | output = new Date().toISOString().split('T')[0]; |
| 5312 | } else { |
| 5313 | output = 'string'; |
| 5314 | } |
| 5315 | } else if (type === 'integer') { |
| 5316 | output = 0; |
| 5317 | } else if (type === 'number') { |
| 5318 | output = 0.0; |
| 5319 | } else if (type === 'boolean') { |
| 5320 | output = true; |
| 5321 | } else if (type === 'object') { |
| 5322 | output = {}; |
| 5323 | |
| 5324 | _.forEach(schema.properties, function (property, name) { |
| 5325 | var cProperty = _.cloneDeep(property); |
| 5326 | |
| 5327 | // Allow macro to set the default value |
| 5328 | cProperty.default = modelPropertyMacro(property); |
| 5329 | |
| 5330 | output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro); |
| 5331 | }); |
| 5332 | } else if (type === 'array') { |
| 5333 | output = []; |
| 5334 | |
| 5335 | if (_.isArray(schema.items)) { |
| 5336 | _.forEach(schema.items, function (item) { |
| 5337 | output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro)); |
| 5338 | }); |
| 5339 | } else if (_.isPlainObject(schema.items)) { |
| 5340 | output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro)); |
| 5341 | } else if (_.isUndefined(schema.items)) { |
| 5342 | output.push({}); |
| 5343 | } else { |
| 5344 | Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process'); |
| 5345 | } |
| 5346 | } |
| 5347 | } |
| 5348 | |
| 5349 | return output; |
| 5350 | } |
| 5351 | |
| 5352 | function schemaToHTML(name, schema, models, modelPropertyMacro) { |
| 5353 | |
| 5354 | var strongOpen = '<span class="strong">'; |
| 5355 | var strongClose = '</span>'; |
| 5356 | |
| 5357 | // Allow for ignoring the 'name' argument.... shifting the rest |
| 5358 | if(_.isObject(arguments[0])) { |
| 5359 | name = void 0; |
| 5360 | schema = arguments[0]; |
| 5361 | models = arguments[1]; |
| 5362 | modelPropertyMacro = arguments[2]; |
| 5363 | } |
| 5364 | |
| 5365 | models = models || {}; |
| 5366 | |
| 5367 | // Resolve the schema (Handle nested schemas) |
| 5368 | schema = Helpers.resolveSchema(schema); |
| 5369 | |
| 5370 | // Return for empty object |
| 5371 | if(_.isEmpty(schema)) { |
| 5372 | return strongOpen + 'Empty' + strongClose; |
| 5373 | } |
| 5374 | |
| 5375 | // Dereference $ref from 'models' |
| 5376 | if(typeof schema.$ref === 'string') { |
| 5377 | name = Helpers.simpleRef(schema.$ref); |
| 5378 | schema = models[name]; |
| 5379 | if(typeof schema === 'undefined') |
| 5380 | { |
| 5381 | return strongOpen + name + ' is not defined!' + strongClose; |
| 5382 | } |
| 5383 | } |
| 5384 | |
| 5385 | if(typeof name !== 'string') { |
| 5386 | name = schema.title || 'Inline Model'; |
| 5387 | } |
| 5388 | |
| 5389 | // If we are a Model object... adjust accordingly |
| 5390 | if(schema.definition) { |
| 5391 | schema = schema.definition; |
| 5392 | } |
| 5393 | |
| 5394 | if(typeof modelPropertyMacro !== 'function') { |
| 5395 | modelPropertyMacro = function(prop){ |
| 5396 | return (prop || {}).default; |
| 5397 | }; |
| 5398 | } |
| 5399 | |
| 5400 | var references = {}; |
| 5401 | var seenModels = []; |
| 5402 | var inlineModels = 0; |
| 5403 | |
| 5404 | |
| 5405 | |
| 5406 | // Generate current HTML |
| 5407 | var html = processModel(schema, name); |
| 5408 | |
| 5409 | // Generate references HTML |
| 5410 | while (_.keys(references).length > 0) { |
| 5411 | /* jshint ignore:start */ |
| 5412 | _.forEach(references, function (schema, name) { |
| 5413 | var seenModel = _.indexOf(seenModels, name) > -1; |
| 5414 | |
| 5415 | delete references[name]; |
| 5416 | |
| 5417 | if (!seenModel) { |
| 5418 | seenModels.push(name); |
| 5419 | |
| 5420 | html += '<br />' + processModel(schema, name); |
| 5421 | } |
| 5422 | }); |
| 5423 | /* jshint ignore:end */ |
| 5424 | } |
| 5425 | |
| 5426 | return html; |
| 5427 | |
| 5428 | ///////////////////////////////// |
| 5429 | |
| 5430 | function addReference(schema, name, skipRef) { |
| 5431 | var modelName = name; |
| 5432 | var model; |
| 5433 | |
| 5434 | if (schema.$ref) { |
| 5435 | modelName = schema.title || Helpers.simpleRef(schema.$ref); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5436 | model = models[modelName]; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5437 | } else if (_.isUndefined(name)) { |
| 5438 | modelName = schema.title || 'Inline Model ' + (++inlineModels); |
| 5439 | model = {definition: schema}; |
| 5440 | } |
| 5441 | |
| 5442 | if (skipRef !== true) { |
| 5443 | references[modelName] = _.isUndefined(model) ? {} : model.definition; |
| 5444 | } |
| 5445 | |
| 5446 | return modelName; |
| 5447 | } |
| 5448 | |
| 5449 | function primitiveToHTML(schema) { |
| 5450 | var html = '<span class="propType">'; |
| 5451 | var type = schema.type || 'object'; |
| 5452 | |
| 5453 | if (schema.$ref) { |
| 5454 | html += addReference(schema, Helpers.simpleRef(schema.$ref)); |
| 5455 | } else if (type === 'object') { |
| 5456 | if (!_.isUndefined(schema.properties)) { |
| 5457 | html += addReference(schema); |
| 5458 | } else { |
| 5459 | html += 'object'; |
| 5460 | } |
| 5461 | } else if (type === 'array') { |
| 5462 | html += 'Array['; |
| 5463 | |
| 5464 | if (_.isArray(schema.items)) { |
| 5465 | html += _.map(schema.items, addReference).join(','); |
| 5466 | } else if (_.isPlainObject(schema.items)) { |
| 5467 | if (_.isUndefined(schema.items.$ref)) { |
| 5468 | if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) { |
| 5469 | html += schema.items.type; |
| 5470 | } else { |
| 5471 | html += addReference(schema.items); |
| 5472 | } |
| 5473 | } else { |
| 5474 | html += addReference(schema.items, Helpers.simpleRef(schema.items.$ref)); |
| 5475 | } |
| 5476 | } else { |
| 5477 | Helpers.log('Array type\'s \'items\' schema is not an array or an object, cannot process'); |
| 5478 | html += 'object'; |
| 5479 | } |
| 5480 | |
| 5481 | html += ']'; |
| 5482 | } else { |
| 5483 | html += schema.type; |
| 5484 | } |
| 5485 | |
| 5486 | html += '</span>'; |
| 5487 | |
| 5488 | return html; |
| 5489 | } |
| 5490 | |
| 5491 | function primitiveToOptionsHTML(schema, html) { |
| 5492 | var options = ''; |
| 5493 | var type = schema.type || 'object'; |
| 5494 | var isArray = type === 'array'; |
| 5495 | |
| 5496 | if (isArray) { |
| 5497 | if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) { |
| 5498 | type = schema.items.type; |
| 5499 | } else { |
| 5500 | type = 'object'; |
| 5501 | } |
| 5502 | } |
| 5503 | |
| 5504 | if (!_.isUndefined(schema.default)) { |
| 5505 | options += optionHtml('Default', schema.default); |
| 5506 | } |
| 5507 | |
| 5508 | switch (type) { |
| 5509 | case 'string': |
| 5510 | if (schema.minLength) { |
| 5511 | options += optionHtml('Min. Length', schema.minLength); |
| 5512 | } |
| 5513 | |
| 5514 | if (schema.maxLength) { |
| 5515 | options += optionHtml('Max. Length', schema.maxLength); |
| 5516 | } |
| 5517 | |
| 5518 | if (schema.pattern) { |
| 5519 | options += optionHtml('Reg. Exp.', schema.pattern); |
| 5520 | } |
| 5521 | break; |
| 5522 | case 'integer': |
| 5523 | case 'number': |
| 5524 | if (schema.minimum) { |
| 5525 | options += optionHtml('Min. Value', schema.minimum); |
| 5526 | } |
| 5527 | |
| 5528 | if (schema.exclusiveMinimum) { |
| 5529 | options += optionHtml('Exclusive Min.', 'true'); |
| 5530 | } |
| 5531 | |
| 5532 | if (schema.maximum) { |
| 5533 | options += optionHtml('Max. Value', schema.maximum); |
| 5534 | } |
| 5535 | |
| 5536 | if (schema.exclusiveMaximum) { |
| 5537 | options += optionHtml('Exclusive Max.', 'true'); |
| 5538 | } |
| 5539 | |
| 5540 | if (schema.multipleOf) { |
| 5541 | options += optionHtml('Multiple Of', schema.multipleOf); |
| 5542 | } |
| 5543 | |
| 5544 | break; |
| 5545 | } |
| 5546 | |
| 5547 | if (isArray) { |
| 5548 | if (schema.minItems) { |
| 5549 | options += optionHtml('Min. Items', schema.minItems); |
| 5550 | } |
| 5551 | |
| 5552 | if (schema.maxItems) { |
| 5553 | options += optionHtml('Max. Items', schema.maxItems); |
| 5554 | } |
| 5555 | |
| 5556 | if (schema.uniqueItems) { |
| 5557 | options += optionHtml('Unique Items', 'true'); |
| 5558 | } |
| 5559 | |
| 5560 | if (schema.collectionFormat) { |
| 5561 | options += optionHtml('Coll. Format', schema.collectionFormat); |
| 5562 | } |
| 5563 | } |
| 5564 | |
| 5565 | if (_.isUndefined(schema.items)) { |
| 5566 | if (_.isArray(schema.enum)) { |
| 5567 | var enumString; |
| 5568 | |
| 5569 | if (type === 'number' || type === 'integer') { |
| 5570 | enumString = schema.enum.join(', '); |
| 5571 | } else { |
| 5572 | enumString = '"' + schema.enum.join('", "') + '"'; |
| 5573 | } |
| 5574 | |
| 5575 | options += optionHtml('Enum', enumString); |
| 5576 | } |
| 5577 | } |
| 5578 | |
| 5579 | if (options.length > 0) { |
| 5580 | html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>'; |
| 5581 | } |
| 5582 | |
| 5583 | return html; |
| 5584 | } |
| 5585 | |
| 5586 | function processModel(schema, name) { |
| 5587 | var type = schema.type || 'object'; |
| 5588 | var isArray = schema.type === 'array'; |
| 5589 | var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose; |
| 5590 | |
| 5591 | if (name) { |
| 5592 | seenModels.push(name); |
| 5593 | } |
| 5594 | |
| 5595 | if (isArray) { |
| 5596 | if (_.isArray(schema.items)) { |
| 5597 | html += '<div>' + _.map(schema.items, function (item) { |
| 5598 | var type = item.type || 'object'; |
| 5599 | |
| 5600 | if (_.isUndefined(item.$ref)) { |
| 5601 | if (_.indexOf(['array', 'object'], type) > -1) { |
| 5602 | if (type === 'object' && _.isUndefined(item.properties)) { |
| 5603 | return 'object'; |
| 5604 | } else { |
| 5605 | return addReference(item); |
| 5606 | } |
| 5607 | } else { |
| 5608 | return primitiveToOptionsHTML(item, type); |
| 5609 | } |
| 5610 | } else { |
| 5611 | return addReference(item, Helpers.simpleRef(item.$ref)); |
| 5612 | } |
| 5613 | }).join(',</div><div>'); |
| 5614 | } else if (_.isPlainObject(schema.items)) { |
| 5615 | if (_.isUndefined(schema.items.$ref)) { |
| 5616 | if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) { |
| 5617 | if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) { |
| 5618 | html += '<div>object</div>'; |
| 5619 | } else { |
| 5620 | html += '<div>' + addReference(schema.items) + '</div>'; |
| 5621 | } |
| 5622 | } else { |
| 5623 | html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>'; |
| 5624 | } |
| 5625 | } else { |
| 5626 | html += '<div>' + addReference(schema.items, Helpers.simpleRef(schema.items.$ref)) + '</div>'; |
| 5627 | } |
| 5628 | } else { |
| 5629 | Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process'); |
| 5630 | html += '<div>object</div>'; |
| 5631 | } |
| 5632 | } else { |
| 5633 | if (schema.$ref) { |
| 5634 | html += '<div>' + addReference(schema, name) + '</div>'; |
| 5635 | } else if (type === 'object') { |
| 5636 | if (_.isPlainObject(schema.properties)) { |
| 5637 | var contents = _.map(schema.properties, function (property, name) { |
| 5638 | var propertyIsRequired = (_.indexOf(schema.required, name) >= 0); |
| 5639 | var cProperty = _.cloneDeep(property); |
| 5640 | |
| 5641 | var requiredClass = propertyIsRequired ? 'required' : ''; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5642 | var html = '<span class="propName ' + requiredClass + '">' + name + '</span> ('; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5643 | var model; |
| 5644 | var propDescription; |
| 5645 | |
| 5646 | // Allow macro to set the default value |
| 5647 | cProperty.default = modelPropertyMacro(cProperty); |
| 5648 | |
| 5649 | // Resolve the schema (Handle nested schemas) |
| 5650 | cProperty = Helpers.resolveSchema(cProperty); |
| 5651 | |
| 5652 | propDescription = property.description || cProperty.description; |
| 5653 | |
| 5654 | // We need to handle property references to primitives (Issue 339) |
| 5655 | if (!_.isUndefined(cProperty.$ref)) { |
| 5656 | model = models[Helpers.simpleRef(cProperty.$ref)]; |
| 5657 | |
| 5658 | if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) { |
| 5659 | // Use referenced schema |
| 5660 | cProperty = Helpers.resolveSchema(model.definition); |
| 5661 | } |
| 5662 | } |
| 5663 | |
| 5664 | html += primitiveToHTML(cProperty); |
| 5665 | |
| 5666 | if(!propertyIsRequired) { |
| 5667 | html += ', <span class="propOptKey">optional</span>'; |
| 5668 | } |
| 5669 | |
| 5670 | if(property.readOnly) { |
| 5671 | html += ', <span class="propReadOnly">read only</span>'; |
| 5672 | } |
| 5673 | |
| 5674 | html += ')'; |
| 5675 | |
| 5676 | if (!_.isUndefined(propDescription)) { |
| 5677 | html += ': ' + '<span class="propDesc">' + propDescription + '</span>'; |
| 5678 | } |
| 5679 | |
| 5680 | if (cProperty.enum) { |
| 5681 | html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>'; |
| 5682 | } |
| 5683 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5684 | return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5685 | }).join(',</div>'); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5686 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5687 | if (contents) { |
| 5688 | html += contents + '</div>'; |
| 5689 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5690 | } |
| 5691 | } else { |
| 5692 | html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>'; |
| 5693 | } |
| 5694 | } |
| 5695 | |
| 5696 | return html + strongOpen + (isArray ? ']' : '}') + strongClose; |
| 5697 | } |
| 5698 | } |
| 5699 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5700 | },{"./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){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5701 | 'use strict'; |
| 5702 | |
| 5703 | var SwaggerHttp = require('./http'); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5704 | var _ = { |
| 5705 | isObject: require('lodash-compat/lang/isObject') |
| 5706 | }; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5707 | |
| 5708 | var SwaggerSpecConverter = module.exports = function () { |
| 5709 | this.errors = []; |
| 5710 | this.warnings = []; |
| 5711 | this.modelMap = {}; |
| 5712 | }; |
| 5713 | |
| 5714 | SwaggerSpecConverter.prototype.setDocumentationLocation = function (location) { |
| 5715 | this.docLocation = location; |
| 5716 | }; |
| 5717 | |
| 5718 | /** |
| 5719 | * converts a resource listing OR api declaration |
| 5720 | **/ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5721 | SwaggerSpecConverter.prototype.convert = function (obj, clientAuthorizations, opts, callback) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5722 | // not a valid spec |
| 5723 | if(!obj || !Array.isArray(obj.apis)) { |
| 5724 | return this.finish(callback, null); |
| 5725 | } |
| 5726 | this.clientAuthorizations = clientAuthorizations; |
| 5727 | |
| 5728 | // create a new swagger object to return |
| 5729 | var swagger = { swagger: '2.0' }; |
| 5730 | |
| 5731 | swagger.originalVersion = obj.swaggerVersion; |
| 5732 | |
| 5733 | // add the info |
| 5734 | this.apiInfo(obj, swagger); |
| 5735 | |
| 5736 | // add security definitions |
| 5737 | this.securityDefinitions(obj, swagger); |
| 5738 | |
| 5739 | // take basePath into account |
| 5740 | if (obj.basePath) { |
| 5741 | this.setDocumentationLocation(obj.basePath); |
| 5742 | } |
| 5743 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5744 | // see if this is a single-file swagger definition |
| 5745 | var isSingleFileSwagger = false; |
| 5746 | var i; |
| 5747 | for(i = 0; i < obj.apis.length; i++) { |
| 5748 | var api = obj.apis[i]; |
| 5749 | if(Array.isArray(api.operations)) { |
| 5750 | isSingleFileSwagger = true; |
| 5751 | } |
| 5752 | } |
| 5753 | if(isSingleFileSwagger) { |
| 5754 | this.declaration(obj, swagger); |
| 5755 | this.finish(callback, swagger); |
| 5756 | } |
| 5757 | else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5758 | this.resourceListing(obj, swagger, opts, callback); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5759 | } |
| 5760 | }; |
| 5761 | |
| 5762 | SwaggerSpecConverter.prototype.declaration = function(obj, swagger) { |
| 5763 | var name, i, p, pos; |
| 5764 | if(!obj.apis) { |
| 5765 | return; |
| 5766 | } |
| 5767 | |
| 5768 | if (obj.basePath.indexOf('http://') === 0) { |
| 5769 | p = obj.basePath.substring('http://'.length); |
| 5770 | pos = p.indexOf('/'); |
| 5771 | if (pos > 0) { |
| 5772 | swagger.host = p.substring(0, pos); |
| 5773 | swagger.basePath = p.substring(pos); |
| 5774 | } |
| 5775 | else { |
| 5776 | swagger.host = p; |
| 5777 | swagger.basePath = '/'; |
| 5778 | } |
| 5779 | } else if (obj.basePath.indexOf('https://') === 0) { |
| 5780 | p = obj.basePath.substring('https://'.length); |
| 5781 | pos = p.indexOf('/'); |
| 5782 | if (pos > 0) { |
| 5783 | swagger.host = p.substring(0, pos); |
| 5784 | swagger.basePath = p.substring(pos); |
| 5785 | } |
| 5786 | else { |
| 5787 | swagger.host = p; |
| 5788 | swagger.basePath = '/'; |
| 5789 | } |
| 5790 | } else { |
| 5791 | swagger.basePath = obj.basePath; |
| 5792 | } |
| 5793 | |
| 5794 | var resourceLevelAuth; |
| 5795 | if(obj.authorizations) { |
| 5796 | resourceLevelAuth = obj.authorizations; |
| 5797 | } |
| 5798 | if(obj.consumes) { |
| 5799 | swagger.consumes = obj.consumes; |
| 5800 | } |
| 5801 | if(obj.produces) { |
| 5802 | swagger.produces = obj.produces; |
| 5803 | } |
| 5804 | |
| 5805 | // build a mapping of id to name for 1.0 model resolutions |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5806 | if(_.isObject(obj)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5807 | for(name in obj.models) { |
| 5808 | var existingModel = obj.models[name]; |
| 5809 | var key = (existingModel.id || name); |
| 5810 | this.modelMap[key] = name; |
| 5811 | } |
| 5812 | } |
| 5813 | |
| 5814 | for(i = 0; i < obj.apis.length; i++) { |
| 5815 | var api = obj.apis[i]; |
| 5816 | var path = api.path; |
| 5817 | var operations = api.operations; |
| 5818 | this.operations(path, obj.resourcePath, operations, resourceLevelAuth, swagger); |
| 5819 | } |
| 5820 | |
| 5821 | var models = obj.models || {}; |
| 5822 | this.models(models, swagger); |
| 5823 | }; |
| 5824 | |
| 5825 | SwaggerSpecConverter.prototype.models = function(obj, swagger) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5826 | if(!_.isObject(obj)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5827 | return; |
| 5828 | } |
| 5829 | var name; |
| 5830 | |
| 5831 | swagger.definitions = swagger.definitions || {}; |
| 5832 | for(name in obj) { |
| 5833 | var existingModel = obj[name]; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5834 | var _required = []; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5835 | var schema = { properties: {}}; |
| 5836 | var propertyName; |
| 5837 | for(propertyName in existingModel.properties) { |
| 5838 | var existingProperty = existingModel.properties[propertyName]; |
| 5839 | var property = {}; |
| 5840 | this.dataType(existingProperty, property); |
| 5841 | if(existingProperty.description) { |
| 5842 | property.description = existingProperty.description; |
| 5843 | } |
| 5844 | if(existingProperty['enum']) { |
| 5845 | property['enum'] = existingProperty['enum']; |
| 5846 | } |
| 5847 | if(typeof existingProperty.required === 'boolean' && existingProperty.required === true) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5848 | _required.push(propertyName); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5849 | } |
| 5850 | if(typeof existingProperty.required === 'string' && existingProperty.required === 'true') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5851 | _required.push(propertyName); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5852 | } |
| 5853 | schema.properties[propertyName] = property; |
| 5854 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 5855 | if(_required.length > 0) { |
| 5856 | schema.required = _required; |
| 5857 | } else { |
| 5858 | schema.required = existingModel.required; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5859 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5860 | swagger.definitions[name] = schema; |
| 5861 | } |
| 5862 | }; |
| 5863 | |
| 5864 | SwaggerSpecConverter.prototype.extractTag = function(resourcePath) { |
| 5865 | var pathString = resourcePath || 'default'; |
| 5866 | if(pathString.indexOf('http:') === 0 || pathString.indexOf('https:') === 0) { |
| 5867 | pathString = pathString.split(['/']); |
| 5868 | pathString = pathString[pathString.length -1].substring(); |
| 5869 | } |
| 5870 | if(pathString.endsWith('.json')) { |
| 5871 | pathString = pathString.substring(0, pathString.length - '.json'.length); |
| 5872 | } |
| 5873 | return pathString.replace('/',''); |
| 5874 | }; |
| 5875 | |
| 5876 | SwaggerSpecConverter.prototype.operations = function(path, resourcePath, obj, resourceLevelAuth, swagger) { |
| 5877 | if(!Array.isArray(obj)) { |
| 5878 | return; |
| 5879 | } |
| 5880 | var i; |
| 5881 | |
| 5882 | if(!swagger.paths) { |
| 5883 | swagger.paths = {}; |
| 5884 | } |
| 5885 | |
| 5886 | var pathObj = swagger.paths[path] || {}; |
| 5887 | var tag = this.extractTag(resourcePath); |
| 5888 | swagger.tags = swagger.tags || []; |
| 5889 | var matched = false; |
| 5890 | for(i = 0; i < swagger.tags.length; i++) { |
| 5891 | var tagObject = swagger.tags[i]; |
| 5892 | if(tagObject.name === tag) { |
| 5893 | matched = true; |
| 5894 | } |
| 5895 | } |
| 5896 | if(!matched) { |
| 5897 | swagger.tags.push({name: tag}); |
| 5898 | } |
| 5899 | |
| 5900 | for(i = 0; i < obj.length; i++) { |
| 5901 | var existingOperation = obj[i]; |
| 5902 | var method = (existingOperation.method || existingOperation.httpMethod).toLowerCase(); |
| 5903 | var operation = {tags: [tag]}; |
| 5904 | var existingAuthorizations = existingOperation.authorizations; |
| 5905 | |
| 5906 | if(existingAuthorizations && Object.keys(existingAuthorizations).length === 0) { |
| 5907 | existingAuthorizations = resourceLevelAuth; |
| 5908 | } |
| 5909 | |
| 5910 | if(typeof existingAuthorizations !== 'undefined') { |
| 5911 | var scopesObject; |
| 5912 | for(var key in existingAuthorizations) { |
| 5913 | operation.security = operation.security || []; |
| 5914 | var scopes = existingAuthorizations[key]; |
| 5915 | if(scopes) { |
| 5916 | var securityScopes = []; |
| 5917 | for(var j in scopes) { |
| 5918 | securityScopes.push(scopes[j].scope); |
| 5919 | } |
| 5920 | scopesObject = {}; |
| 5921 | scopesObject[key] = securityScopes; |
| 5922 | operation.security.push(scopesObject); |
| 5923 | } |
| 5924 | else { |
| 5925 | scopesObject = {}; |
| 5926 | scopesObject[key] = []; |
| 5927 | operation.security.push(scopesObject); |
| 5928 | } |
| 5929 | } |
| 5930 | } |
| 5931 | |
| 5932 | if(existingOperation.consumes) { |
| 5933 | operation.consumes = existingOperation.consumes; |
| 5934 | } |
| 5935 | else if(swagger.consumes) { |
| 5936 | operation.consumes = swagger.consumes; |
| 5937 | } |
| 5938 | if(existingOperation.produces) { |
| 5939 | operation.produces = existingOperation.produces; |
| 5940 | } |
| 5941 | else if(swagger.produces) { |
| 5942 | operation.produces = swagger.produces; |
| 5943 | } |
| 5944 | if(existingOperation.summary) { |
| 5945 | operation.summary = existingOperation.summary; |
| 5946 | } |
| 5947 | if(existingOperation.notes) { |
| 5948 | operation.description = existingOperation.notes; |
| 5949 | } |
| 5950 | if(existingOperation.nickname) { |
| 5951 | operation.operationId = existingOperation.nickname; |
| 5952 | } |
| 5953 | if(existingOperation.deprecated) { |
| 5954 | operation.deprecated = existingOperation.deprecated; |
| 5955 | } |
| 5956 | |
| 5957 | this.authorizations(existingAuthorizations, swagger); |
| 5958 | this.parameters(operation, existingOperation.parameters, swagger); |
| 5959 | this.responseMessages(operation, existingOperation, swagger); |
| 5960 | |
| 5961 | pathObj[method] = operation; |
| 5962 | } |
| 5963 | |
| 5964 | swagger.paths[path] = pathObj; |
| 5965 | }; |
| 5966 | |
| 5967 | SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5968 | if(!_.isObject(existingOperation)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5969 | return; |
| 5970 | } |
| 5971 | // build default response from the operation (1.x) |
| 5972 | var defaultResponse = {}; |
| 5973 | this.dataType(existingOperation, defaultResponse); |
| 5974 | // TODO: look into the real problem of rendering responses in swagger-ui |
| 5975 | // ....should reponseType have an implicit schema? |
| 5976 | if(!defaultResponse.schema && defaultResponse.type) { |
| 5977 | defaultResponse = {schema: defaultResponse}; |
| 5978 | } |
| 5979 | |
| 5980 | operation.responses = operation.responses || {}; |
| 5981 | |
| 5982 | // grab from responseMessages (1.2) |
| 5983 | var has200 = false; |
| 5984 | if(Array.isArray(existingOperation.responseMessages)) { |
| 5985 | var i; |
| 5986 | var existingResponses = existingOperation.responseMessages; |
| 5987 | for(i = 0; i < existingResponses.length; i++) { |
| 5988 | var existingResponse = existingResponses[i]; |
| 5989 | var response = { description: existingResponse.message }; |
| 5990 | if(existingResponse.code === 200) { |
| 5991 | has200 = true; |
| 5992 | } |
| 5993 | // Convert responseModel -> schema{$ref: responseModel} |
| 5994 | if(existingResponse.responseModel) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 5995 | response.schema = {'$ref': '#/definitions/' + existingResponse.responseModel}; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 5996 | } |
| 5997 | operation.responses['' + existingResponse.code] = response; |
| 5998 | } |
| 5999 | } |
| 6000 | |
| 6001 | if(has200) { |
| 6002 | operation.responses['default'] = defaultResponse; |
| 6003 | } |
| 6004 | else { |
| 6005 | operation.responses['200'] = defaultResponse; |
| 6006 | } |
| 6007 | }; |
| 6008 | |
| 6009 | SwaggerSpecConverter.prototype.authorizations = function(obj) { |
| 6010 | // TODO |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6011 | if(!_.isObject(obj)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6012 | return; |
| 6013 | } |
| 6014 | }; |
| 6015 | |
| 6016 | SwaggerSpecConverter.prototype.parameters = function(operation, obj) { |
| 6017 | if(!Array.isArray(obj)) { |
| 6018 | return; |
| 6019 | } |
| 6020 | var i; |
| 6021 | for(i = 0; i < obj.length; i++) { |
| 6022 | var existingParameter = obj[i]; |
| 6023 | var parameter = {}; |
| 6024 | parameter.name = existingParameter.name; |
| 6025 | parameter.description = existingParameter.description; |
| 6026 | parameter.required = existingParameter.required; |
| 6027 | parameter.in = existingParameter.paramType; |
| 6028 | |
| 6029 | // per #168 |
| 6030 | if(parameter.in === 'body') { |
| 6031 | parameter.name = 'body'; |
| 6032 | } |
| 6033 | if(parameter.in === 'form') { |
| 6034 | parameter.in = 'formData'; |
| 6035 | } |
| 6036 | |
| 6037 | if(existingParameter.enum) { |
| 6038 | parameter.enum = existingParameter.enum; |
| 6039 | } |
| 6040 | |
| 6041 | if(existingParameter.allowMultiple === true || existingParameter.allowMultiple === 'true') { |
| 6042 | var innerType = {}; |
| 6043 | this.dataType(existingParameter, innerType); |
| 6044 | parameter.type = 'array'; |
| 6045 | parameter.items = innerType; |
| 6046 | |
| 6047 | if(existingParameter.allowableValues) { |
| 6048 | var av = existingParameter.allowableValues; |
| 6049 | if(av.valueType === 'LIST') { |
| 6050 | parameter['enum'] = av.values; |
| 6051 | } |
| 6052 | } |
| 6053 | } |
| 6054 | else { |
| 6055 | this.dataType(existingParameter, parameter); |
| 6056 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6057 | if(typeof existingParameter.defaultValue !== 'undefined') { |
| 6058 | parameter.default = existingParameter.defaultValue; |
| 6059 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6060 | |
| 6061 | operation.parameters = operation.parameters || []; |
| 6062 | operation.parameters.push(parameter); |
| 6063 | } |
| 6064 | }; |
| 6065 | |
| 6066 | SwaggerSpecConverter.prototype.dataType = function(source, target) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6067 | if(!_.isObject(source)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6068 | return; |
| 6069 | } |
| 6070 | |
| 6071 | if(source.minimum) { |
| 6072 | target.minimum = source.minimum; |
| 6073 | } |
| 6074 | if(source.maximum) { |
| 6075 | target.maximum = source.maximum; |
| 6076 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6077 | if (source.format) { |
| 6078 | target.format = source.format; |
| 6079 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6080 | |
| 6081 | // default can be 'false' |
| 6082 | if(typeof source.defaultValue !== 'undefined') { |
| 6083 | target.default = source.defaultValue; |
| 6084 | } |
| 6085 | |
| 6086 | var jsonSchemaType = this.toJsonSchema(source); |
| 6087 | if(jsonSchemaType) { |
| 6088 | target = target || {}; |
| 6089 | if(jsonSchemaType.type) { |
| 6090 | target.type = jsonSchemaType.type; |
| 6091 | } |
| 6092 | if(jsonSchemaType.format) { |
| 6093 | target.format = jsonSchemaType.format; |
| 6094 | } |
| 6095 | if(jsonSchemaType.$ref) { |
| 6096 | target.schema = {$ref: jsonSchemaType.$ref}; |
| 6097 | } |
| 6098 | if(jsonSchemaType.items) { |
| 6099 | target.items = jsonSchemaType.items; |
| 6100 | } |
| 6101 | } |
| 6102 | }; |
| 6103 | |
| 6104 | SwaggerSpecConverter.prototype.toJsonSchema = function(source) { |
| 6105 | if(!source) { |
| 6106 | return 'object'; |
| 6107 | } |
| 6108 | var detectedType = (source.type || source.dataType || source.responseClass || ''); |
| 6109 | var lcType = detectedType.toLowerCase(); |
| 6110 | var format = (source.format || '').toLowerCase(); |
| 6111 | |
| 6112 | if(lcType.indexOf('list[') === 0) { |
| 6113 | var innerType = detectedType.substring(5, detectedType.length - 1); |
| 6114 | var jsonType = this.toJsonSchema({type: innerType}); |
| 6115 | return {type: 'array', items: jsonType}; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6116 | } else if(lcType === 'int' || (lcType === 'integer' && format === 'int32')) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6117 | {return {type: 'integer', format: 'int32'};} |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6118 | } else if(lcType === 'long' || (lcType === 'integer' && format === 'int64')) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6119 | {return {type: 'integer', format: 'int64'};} |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6120 | } else if(lcType === 'integer') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6121 | {return {type: 'integer', format: 'int64'};} |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6122 | } else if(lcType === 'float' || (lcType === 'number' && format === 'float')) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6123 | {return {type: 'number', format: 'float'};} |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6124 | } else if(lcType === 'double' || (lcType === 'number' && format === 'double')) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6125 | {return {type: 'number', format: 'double'};} |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6126 | } else if((lcType === 'string' && format === 'date-time') || (lcType === 'date')) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6127 | {return {type: 'string', format: 'date-time'};} |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6128 | } else if(lcType === 'string') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6129 | {return {type: 'string'};} |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6130 | } else if(lcType === 'file') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6131 | {return {type: 'file'};} |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6132 | } else if(lcType === 'boolean') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6133 | {return {type: 'boolean'};} |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6134 | } else if(lcType === 'boolean') { |
| 6135 | {return {type: 'boolean'};} |
| 6136 | } else if(lcType === 'array' || lcType === 'list') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6137 | if(source.items) { |
| 6138 | var it = this.toJsonSchema(source.items); |
| 6139 | return {type: 'array', items: it}; |
| 6140 | } |
| 6141 | else { |
| 6142 | return {type: 'array', items: {type: 'object'}}; |
| 6143 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6144 | } else if(source.$ref) { |
| 6145 | return {$ref: this.modelMap[source.$ref] ? '#/definitions/' + this.modelMap[source.$ref] : source.$ref}; |
| 6146 | } else if(lcType === 'void' || lcType === '') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6147 | {return {};} |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6148 | } else if (this.modelMap[source.type]) { |
| 6149 | // If this a model using `type` instead of `$ref`, that's fine. |
| 6150 | return {$ref: '#/definitions/' + this.modelMap[source.type]}; |
| 6151 | } else { |
| 6152 | // Unknown model type or 'object', pass it along. |
| 6153 | return {type: source.type}; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6154 | } |
| 6155 | }; |
| 6156 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6157 | SwaggerSpecConverter.prototype.resourceListing = function(obj, swagger, opts, callback) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6158 | var i; |
| 6159 | var processedCount = 0; // jshint ignore:line |
| 6160 | var self = this; // jshint ignore:line |
| 6161 | var expectedCount = obj.apis.length; |
| 6162 | var _swagger = swagger; // jshint ignore:line |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6163 | var _opts = {}; |
| 6164 | |
| 6165 | if(opts && opts.requestInterceptor){ |
| 6166 | _opts.requestInterceptor = opts.requestInterceptor; |
| 6167 | } |
| 6168 | |
| 6169 | if(opts && opts.responseInterceptor){ |
| 6170 | _opts.responseInterceptor = opts.responseInterceptor; |
| 6171 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6172 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6173 | var swaggerRequestHeaders = 'application/json'; |
| 6174 | |
| 6175 | if(opts && opts.swaggerRequestHeaders) { |
| 6176 | swaggerRequestHeaders = opts.swaggerRequestHeaders; |
| 6177 | } |
| 6178 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6179 | if(expectedCount === 0) { |
| 6180 | this.finish(callback, swagger); |
| 6181 | } |
| 6182 | |
| 6183 | for(i = 0; i < expectedCount; i++) { |
| 6184 | var api = obj.apis[i]; |
| 6185 | var path = api.path; |
| 6186 | var absolutePath = this.getAbsolutePath(obj.swaggerVersion, this.docLocation, path); |
| 6187 | |
| 6188 | if(api.description) { |
| 6189 | swagger.tags = swagger.tags || []; |
| 6190 | swagger.tags.push({ |
| 6191 | name : this.extractTag(api.path), |
| 6192 | description : api.description || '' |
| 6193 | }); |
| 6194 | } |
| 6195 | var http = { |
| 6196 | url: absolutePath, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6197 | headers: { accept: swaggerRequestHeaders }, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6198 | on: {}, |
| 6199 | method: 'get' |
| 6200 | }; |
| 6201 | /* jshint ignore:start */ |
| 6202 | http.on.response = function(data) { |
| 6203 | processedCount += 1; |
| 6204 | var obj = data.obj; |
| 6205 | if(obj) { |
| 6206 | self.declaration(obj, _swagger); |
| 6207 | } |
| 6208 | if(processedCount === expectedCount) { |
| 6209 | self.finish(callback, _swagger); |
| 6210 | } |
| 6211 | }; |
| 6212 | http.on.error = function(data) { |
| 6213 | console.error(data); |
| 6214 | processedCount += 1; |
| 6215 | if(processedCount === expectedCount) { |
| 6216 | self.finish(callback, _swagger); |
| 6217 | } |
| 6218 | }; |
| 6219 | /* jshint ignore:end */ |
| 6220 | |
| 6221 | if(this.clientAuthorizations && typeof this.clientAuthorizations.apply === 'function') { |
| 6222 | this.clientAuthorizations.apply(http); |
| 6223 | } |
| 6224 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6225 | new SwaggerHttp().execute(http, _opts); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6226 | } |
| 6227 | }; |
| 6228 | |
| 6229 | SwaggerSpecConverter.prototype.getAbsolutePath = function(version, docLocation, path) { |
| 6230 | if(version === '1.0') { |
| 6231 | if(docLocation.endsWith('.json')) { |
| 6232 | // get root path |
| 6233 | var pos = docLocation.lastIndexOf('/'); |
| 6234 | if(pos > 0) { |
| 6235 | docLocation = docLocation.substring(0, pos); |
| 6236 | } |
| 6237 | } |
| 6238 | } |
| 6239 | |
| 6240 | var location = docLocation; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6241 | if(path.indexOf('http:') === 0 || path.indexOf('https:') === 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6242 | location = path; |
| 6243 | } |
| 6244 | else { |
| 6245 | if(docLocation.endsWith('/')) { |
| 6246 | location = docLocation.substring(0, docLocation.length - 1); |
| 6247 | } |
| 6248 | location += path; |
| 6249 | } |
| 6250 | location = location.replace('{format}', 'json'); |
| 6251 | return location; |
| 6252 | }; |
| 6253 | |
| 6254 | SwaggerSpecConverter.prototype.securityDefinitions = function(obj, swagger) { |
| 6255 | if(obj.authorizations) { |
| 6256 | var name; |
| 6257 | for(name in obj.authorizations) { |
| 6258 | var isValid = false; |
| 6259 | var securityDefinition = {}; |
| 6260 | var definition = obj.authorizations[name]; |
| 6261 | if(definition.type === 'apiKey') { |
| 6262 | securityDefinition.type = 'apiKey'; |
| 6263 | securityDefinition.in = definition.passAs; |
| 6264 | securityDefinition.name = definition.keyname || name; |
| 6265 | isValid = true; |
| 6266 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6267 | else if(definition.type === 'basicAuth') { |
| 6268 | securityDefinition.type = 'basicAuth'; |
| 6269 | isValid = true; |
| 6270 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6271 | else if(definition.type === 'oauth2') { |
| 6272 | var existingScopes = definition.scopes || []; |
| 6273 | var scopes = {}; |
| 6274 | var i; |
| 6275 | for(i in existingScopes) { |
| 6276 | var scope = existingScopes[i]; |
| 6277 | scopes[scope.scope] = scope.description; |
| 6278 | } |
| 6279 | securityDefinition.type = 'oauth2'; |
| 6280 | if(i > 0) { |
| 6281 | securityDefinition.scopes = scopes; |
| 6282 | } |
| 6283 | if(definition.grantTypes) { |
| 6284 | if(definition.grantTypes.implicit) { |
| 6285 | var implicit = definition.grantTypes.implicit; |
| 6286 | securityDefinition.flow = 'implicit'; |
| 6287 | securityDefinition.authorizationUrl = implicit.loginEndpoint; |
| 6288 | isValid = true; |
| 6289 | } |
| 6290 | /* jshint ignore:start */ |
| 6291 | if(definition.grantTypes['authorization_code']) { |
| 6292 | if(!securityDefinition.flow) { |
| 6293 | // cannot set if flow is already defined |
| 6294 | var authCode = definition.grantTypes['authorization_code']; |
| 6295 | securityDefinition.flow = 'accessCode'; |
| 6296 | securityDefinition.authorizationUrl = authCode.tokenRequestEndpoint.url; |
| 6297 | securityDefinition.tokenUrl = authCode.tokenEndpoint.url; |
| 6298 | isValid = true; |
| 6299 | } |
| 6300 | } |
| 6301 | /* jshint ignore:end */ |
| 6302 | } |
| 6303 | } |
| 6304 | if(isValid) { |
| 6305 | swagger.securityDefinitions = swagger.securityDefinitions || {}; |
| 6306 | swagger.securityDefinitions[name] = securityDefinition; |
| 6307 | } |
| 6308 | } |
| 6309 | } |
| 6310 | }; |
| 6311 | |
| 6312 | SwaggerSpecConverter.prototype.apiInfo = function(obj, swagger) { |
| 6313 | // info section |
| 6314 | if(obj.info) { |
| 6315 | var info = obj.info; |
| 6316 | swagger.info = {}; |
| 6317 | |
| 6318 | if(info.contact) { |
| 6319 | swagger.info.contact = {}; |
| 6320 | swagger.info.contact.email = info.contact; |
| 6321 | } |
| 6322 | if(info.description) { |
| 6323 | swagger.info.description = info.description; |
| 6324 | } |
| 6325 | if(info.title) { |
| 6326 | swagger.info.title = info.title; |
| 6327 | } |
| 6328 | if(info.termsOfServiceUrl) { |
| 6329 | swagger.info.termsOfService = info.termsOfServiceUrl; |
| 6330 | } |
| 6331 | if(info.license || info.licenseUrl) { |
| 6332 | swagger.license = {}; |
| 6333 | if(info.license) { |
| 6334 | swagger.license.name = info.license; |
| 6335 | } |
| 6336 | if(info.licenseUrl) { |
| 6337 | swagger.license.url = info.licenseUrl; |
| 6338 | } |
| 6339 | } |
| 6340 | } |
| 6341 | else { |
| 6342 | this.warnings.push('missing info section'); |
| 6343 | } |
| 6344 | }; |
| 6345 | |
| 6346 | SwaggerSpecConverter.prototype.finish = function (callback, obj) { |
| 6347 | callback(obj); |
| 6348 | }; |
| 6349 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6350 | },{"./http":5,"lodash-compat/lang/isObject":144}],9:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6351 | 'use strict'; |
| 6352 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6353 | var log = require('../helpers').log; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6354 | var _ = { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6355 | isPlainObject: require('lodash-compat/lang/isPlainObject'), |
| 6356 | isString: require('lodash-compat/lang/isString'), |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6357 | }; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6358 | |
| 6359 | var SchemaMarkup = require('../schema-markup.js'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6360 | var jsyaml = require('js-yaml'); |
| 6361 | |
| 6362 | var Model = module.exports = function (name, definition, models, modelPropertyMacro) { |
| 6363 | this.definition = definition || {}; |
| 6364 | this.isArray = definition.type === 'array'; |
| 6365 | this.models = models || {}; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6366 | this.name = name || definition.title || 'Inline Model'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6367 | this.modelPropertyMacro = modelPropertyMacro || function (property) { |
| 6368 | return property.default; |
| 6369 | }; |
| 6370 | |
| 6371 | return this; |
| 6372 | }; |
| 6373 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6374 | // Note! This function will be removed in 2.2.x! |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6375 | Model.prototype.createJSONSample = Model.prototype.getSampleValue = function (modelsToIgnore) { |
| 6376 | modelsToIgnore = modelsToIgnore || {}; |
| 6377 | |
| 6378 | modelsToIgnore[this.name] = this; |
| 6379 | |
| 6380 | // Response support |
| 6381 | if (this.examples && _.isPlainObject(this.examples) && this.examples['application/json']) { |
| 6382 | this.definition.example = this.examples['application/json']; |
| 6383 | |
| 6384 | if (_.isString(this.definition.example)) { |
| 6385 | this.definition.example = jsyaml.safeLoad(this.definition.example); |
| 6386 | } |
| 6387 | } else if (!this.definition.example) { |
| 6388 | this.definition.example = this.examples; |
| 6389 | } |
| 6390 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6391 | return SchemaMarkup.schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6392 | }; |
| 6393 | |
| 6394 | Model.prototype.getMockSignature = function () { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6395 | return SchemaMarkup.schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6396 | }; |
| 6397 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6398 | },{"../helpers":4,"../schema-markup.js":7,"js-yaml":19,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isString":146}],10:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6399 | 'use strict'; |
| 6400 | |
| 6401 | var _ = { |
| 6402 | cloneDeep: require('lodash-compat/lang/cloneDeep'), |
| 6403 | isUndefined: require('lodash-compat/lang/isUndefined'), |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6404 | isEmpty: require('lodash-compat/lang/isEmpty'), |
| 6405 | isObject: require('lodash-compat/lang/isObject') |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6406 | }; |
| 6407 | var helpers = require('../helpers'); |
| 6408 | var Model = require('./model'); |
| 6409 | var SwaggerHttp = require('../http'); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6410 | var Q = require('q'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6411 | |
| 6412 | var Operation = module.exports = function (parent, scheme, operationId, httpMethod, path, args, definitions, models, clientAuthorizations) { |
| 6413 | var errors = []; |
| 6414 | |
| 6415 | parent = parent || {}; |
| 6416 | args = args || {}; |
| 6417 | |
| 6418 | if(parent && parent.options) { |
| 6419 | this.client = parent.options.client || null; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6420 | this.requestInterceptor = parent.options.requestInterceptor || null; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6421 | this.responseInterceptor = parent.options.responseInterceptor || null; |
| 6422 | } |
| 6423 | this.authorizations = args.security; |
| 6424 | this.basePath = parent.basePath || '/'; |
| 6425 | this.clientAuthorizations = clientAuthorizations; |
| 6426 | this.consumes = args.consumes || parent.consumes || ['application/json']; |
| 6427 | this.produces = args.produces || parent.produces || ['application/json']; |
| 6428 | this.deprecated = args.deprecated; |
| 6429 | this.description = args.description; |
| 6430 | this.host = parent.host || 'localhost'; |
| 6431 | this.method = (httpMethod || errors.push('Operation ' + operationId + ' is missing method.')); |
| 6432 | this.models = models || {}; |
| 6433 | this.nickname = (operationId || errors.push('Operations must have a nickname.')); |
| 6434 | this.operation = args; |
| 6435 | this.operations = {}; |
| 6436 | this.parameters = args !== null ? (args.parameters || []) : {}; |
| 6437 | this.parent = parent; |
| 6438 | this.path = (path || errors.push('Operation ' + this.nickname + ' is missing path.')); |
| 6439 | this.responses = (args.responses || {}); |
| 6440 | this.scheme = scheme || parent.scheme || 'http'; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6441 | this.schemes = args.schemes || parent.schemes; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6442 | this.security = args.security || parent.security; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6443 | this.summary = args.summary || ''; |
| 6444 | this.type = null; |
| 6445 | this.useJQuery = parent.useJQuery; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6446 | this.jqueryAjaxCache = parent.jqueryAjaxCache; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6447 | this.enableCookies = parent.enableCookies; |
| 6448 | this.parameterMacro = parent.parameterMacro || function (operation, parameter) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6449 | return parameter.default; |
| 6450 | }; |
| 6451 | |
| 6452 | this.inlineModels = []; |
| 6453 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6454 | if(this.basePath !== '/' && this.basePath.slice(-1) === '/') { |
| 6455 | this.basePath = this.basePath.slice(0, -1); |
| 6456 | } |
| 6457 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6458 | if (typeof this.deprecated === 'string') { |
| 6459 | switch(this.deprecated.toLowerCase()) { |
| 6460 | case 'true': case 'yes': case '1': { |
| 6461 | this.deprecated = true; |
| 6462 | break; |
| 6463 | } |
| 6464 | |
| 6465 | case 'false': case 'no': case '0': case null: { |
| 6466 | this.deprecated = false; |
| 6467 | break; |
| 6468 | } |
| 6469 | |
| 6470 | default: this.deprecated = Boolean(this.deprecated); |
| 6471 | } |
| 6472 | } |
| 6473 | |
| 6474 | var i, model; |
| 6475 | |
| 6476 | if (definitions) { |
| 6477 | // add to global models |
| 6478 | var key; |
| 6479 | |
| 6480 | for (key in definitions) { |
| 6481 | model = new Model(key, definitions[key], this.models, parent.modelPropertyMacro); |
| 6482 | |
| 6483 | if (model) { |
| 6484 | this.models[key] = model; |
| 6485 | } |
| 6486 | } |
| 6487 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6488 | else { |
| 6489 | definitions = {}; |
| 6490 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6491 | |
| 6492 | for (i = 0; i < this.parameters.length; i++) { |
| 6493 | var param = this.parameters[i]; |
| 6494 | |
| 6495 | // Allow macro to set the default value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6496 | param.default = this.parameterMacro(this, param); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6497 | |
| 6498 | if (param.type === 'array') { |
| 6499 | param.isList = true; |
| 6500 | param.allowMultiple = true; |
| 6501 | // the enum can be defined at the items level |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6502 | //if (param.items && param.items.enum) { |
| 6503 | // param['enum'] = param.items.enum; |
| 6504 | //} |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6505 | } |
| 6506 | |
| 6507 | var innerType = this.getType(param); |
| 6508 | |
| 6509 | if (innerType && innerType.toString().toLowerCase() === 'boolean') { |
| 6510 | param.allowableValues = {}; |
| 6511 | param.isList = true; |
| 6512 | param['enum'] = [true, false]; // use actual primitives |
| 6513 | } |
| 6514 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6515 | if(typeof param['x-example'] !== 'undefined') { |
| 6516 | var d = param['x-example']; |
| 6517 | param.default = d; |
| 6518 | } |
| 6519 | if(param['x-examples']) { |
| 6520 | var d = param['x-examples'].default; |
| 6521 | if(typeof d !== 'undefined') { |
| 6522 | param.default = d; |
| 6523 | } |
| 6524 | } |
| 6525 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6526 | var enumValues = param['enum'] || (param.items && param.items['enum']); |
| 6527 | |
| 6528 | if (typeof enumValues !== 'undefined') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6529 | var id; |
| 6530 | |
| 6531 | param.allowableValues = {}; |
| 6532 | param.allowableValues.values = []; |
| 6533 | param.allowableValues.descriptiveValues = []; |
| 6534 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6535 | for (id = 0; id < enumValues.length; id++) { |
| 6536 | var value = enumValues[id]; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6537 | var isDefault = (value === param.default || value+'' === param.default); |
| 6538 | |
| 6539 | param.allowableValues.values.push(value); |
| 6540 | // Always have string for descriptive values.... |
| 6541 | param.allowableValues.descriptiveValues.push({value : value+'', isDefault: isDefault}); |
| 6542 | } |
| 6543 | } |
| 6544 | |
| 6545 | if (param.type === 'array') { |
| 6546 | innerType = [innerType]; |
| 6547 | |
| 6548 | if (typeof param.allowableValues === 'undefined') { |
| 6549 | // can't show as a list if no values to select from |
| 6550 | delete param.isList; |
| 6551 | delete param.allowMultiple; |
| 6552 | } |
| 6553 | } |
| 6554 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6555 | param.modelSignature = {type: innerType, definitions: this.models}; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6556 | param.signature = this.getModelSignature(innerType, this.models).toString(); |
| 6557 | param.sampleJSON = this.getModelSampleJSON(innerType, this.models); |
| 6558 | param.responseClassSignature = param.signature; |
| 6559 | } |
| 6560 | |
| 6561 | var defaultResponseCode, response, responses = this.responses; |
| 6562 | |
| 6563 | if (responses['200']) { |
| 6564 | response = responses['200']; |
| 6565 | defaultResponseCode = '200'; |
| 6566 | } else if (responses['201']) { |
| 6567 | response = responses['201']; |
| 6568 | defaultResponseCode = '201'; |
| 6569 | } else if (responses['202']) { |
| 6570 | response = responses['202']; |
| 6571 | defaultResponseCode = '202'; |
| 6572 | } else if (responses['203']) { |
| 6573 | response = responses['203']; |
| 6574 | defaultResponseCode = '203'; |
| 6575 | } else if (responses['204']) { |
| 6576 | response = responses['204']; |
| 6577 | defaultResponseCode = '204'; |
| 6578 | } else if (responses['205']) { |
| 6579 | response = responses['205']; |
| 6580 | defaultResponseCode = '205'; |
| 6581 | } else if (responses['206']) { |
| 6582 | response = responses['206']; |
| 6583 | defaultResponseCode = '206'; |
| 6584 | } else if (responses['default']) { |
| 6585 | response = responses['default']; |
| 6586 | defaultResponseCode = 'default'; |
| 6587 | } |
| 6588 | |
| 6589 | if (response && response.schema) { |
| 6590 | var resolvedModel = this.resolveModel(response.schema, definitions); |
| 6591 | var successResponse; |
| 6592 | |
| 6593 | delete responses[defaultResponseCode]; |
| 6594 | |
| 6595 | if (resolvedModel) { |
| 6596 | this.successResponse = {}; |
| 6597 | successResponse = this.successResponse[defaultResponseCode] = resolvedModel; |
| 6598 | } else if (!response.schema.type || response.schema.type === 'object' || response.schema.type === 'array') { |
| 6599 | // Inline model |
| 6600 | this.successResponse = {}; |
| 6601 | successResponse = this.successResponse[defaultResponseCode] = new Model(undefined, response.schema || {}, this.models, parent.modelPropertyMacro); |
| 6602 | } else { |
| 6603 | // Primitive |
| 6604 | this.successResponse = {}; |
| 6605 | successResponse = this.successResponse[defaultResponseCode] = response.schema; |
| 6606 | } |
| 6607 | |
| 6608 | if (successResponse) { |
| 6609 | // Attach response properties |
| 6610 | if (response.description) { |
| 6611 | successResponse.description = response.description; |
| 6612 | } |
| 6613 | |
| 6614 | if (response.examples) { |
| 6615 | successResponse.examples = response.examples; |
| 6616 | } |
| 6617 | |
| 6618 | if (response.headers) { |
| 6619 | successResponse.headers = response.headers; |
| 6620 | } |
| 6621 | } |
| 6622 | |
| 6623 | this.type = response; |
| 6624 | } |
| 6625 | |
| 6626 | if (errors.length > 0) { |
| 6627 | if (this.resource && this.resource.api && this.resource.api.fail) { |
| 6628 | this.resource.api.fail(errors); |
| 6629 | } |
| 6630 | } |
| 6631 | |
| 6632 | return this; |
| 6633 | }; |
| 6634 | |
| 6635 | Operation.prototype.isDefaultArrayItemValue = function(value, param) { |
| 6636 | if (param.default && Array.isArray(param.default)) { |
| 6637 | return param.default.indexOf(value) !== -1; |
| 6638 | } |
| 6639 | return value === param.default; |
| 6640 | }; |
| 6641 | |
| 6642 | Operation.prototype.getType = function (param) { |
| 6643 | var type = param.type; |
| 6644 | var format = param.format; |
| 6645 | var isArray = false; |
| 6646 | var str; |
| 6647 | |
| 6648 | if (type === 'integer' && format === 'int32') { |
| 6649 | str = 'integer'; |
| 6650 | } else if (type === 'integer' && format === 'int64') { |
| 6651 | str = 'long'; |
| 6652 | } else if (type === 'integer') { |
| 6653 | str = 'integer'; |
| 6654 | } else if (type === 'string') { |
| 6655 | if (format === 'date-time') { |
| 6656 | str = 'date-time'; |
| 6657 | } else if (format === 'date') { |
| 6658 | str = 'date'; |
| 6659 | } else { |
| 6660 | str = 'string'; |
| 6661 | } |
| 6662 | } else if (type === 'number' && format === 'float') { |
| 6663 | str = 'float'; |
| 6664 | } else if (type === 'number' && format === 'double') { |
| 6665 | str = 'double'; |
| 6666 | } else if (type === 'number') { |
| 6667 | str = 'double'; |
| 6668 | } else if (type === 'boolean') { |
| 6669 | str = 'boolean'; |
| 6670 | } else if (type === 'array') { |
| 6671 | isArray = true; |
| 6672 | |
| 6673 | if (param.items) { |
| 6674 | str = this.getType(param.items); |
| 6675 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6676 | } else if (type === 'file') { |
| 6677 | str = 'file'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6678 | } |
| 6679 | |
| 6680 | if (param.$ref) { |
| 6681 | str = helpers.simpleRef(param.$ref); |
| 6682 | } |
| 6683 | |
| 6684 | var schema = param.schema; |
| 6685 | |
| 6686 | if (schema) { |
| 6687 | var ref = schema.$ref; |
| 6688 | |
| 6689 | if (ref) { |
| 6690 | ref = helpers.simpleRef(ref); |
| 6691 | |
| 6692 | if (isArray) { |
| 6693 | return [ ref ]; |
| 6694 | } else { |
| 6695 | return ref; |
| 6696 | } |
| 6697 | } else { |
| 6698 | // If inline schema, we add it our interal hash -> which gives us it's ID (int) |
| 6699 | if(schema.type === 'object') { |
| 6700 | return this.addInlineModel(schema); |
| 6701 | } |
| 6702 | return this.getType(schema); |
| 6703 | } |
| 6704 | } |
| 6705 | if (isArray) { |
| 6706 | return [ str ]; |
| 6707 | } else { |
| 6708 | return str; |
| 6709 | } |
| 6710 | }; |
| 6711 | |
| 6712 | /** |
| 6713 | * adds an inline schema (model) to a hash, where we can ref it later |
| 6714 | * @param {object} schema a schema |
| 6715 | * @return {number} the ID of the schema being added, or null |
| 6716 | **/ |
| 6717 | Operation.prototype.addInlineModel = function (schema) { |
| 6718 | var len = this.inlineModels.length; |
| 6719 | var model = this.resolveModel(schema, {}); |
| 6720 | if(model) { |
| 6721 | this.inlineModels.push(model); |
| 6722 | return 'Inline Model '+len; // return string ref of the inline model (used with #getInlineModel) |
| 6723 | } |
| 6724 | return null; // report errors? |
| 6725 | }; |
| 6726 | |
| 6727 | /** |
| 6728 | * gets the internal ref to an inline model |
| 6729 | * @param {string} inline_str a string reference to an inline model |
| 6730 | * @return {Model} the model being referenced. Or null |
| 6731 | **/ |
| 6732 | Operation.prototype.getInlineModel = function(inlineStr) { |
| 6733 | if(/^Inline Model \d+$/.test(inlineStr)) { |
| 6734 | var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); // |
| 6735 | var model = this.inlineModels[id]; |
| 6736 | return model; |
| 6737 | } |
| 6738 | // I'm returning null here, should I rather throw an error? |
| 6739 | return null; |
| 6740 | }; |
| 6741 | |
| 6742 | Operation.prototype.resolveModel = function (schema, definitions) { |
| 6743 | if (typeof schema.$ref !== 'undefined') { |
| 6744 | var ref = schema.$ref; |
| 6745 | |
| 6746 | if (ref.indexOf('#/definitions/') === 0) { |
| 6747 | ref = ref.substring('#/definitions/'.length); |
| 6748 | } |
| 6749 | |
| 6750 | if (definitions[ref]) { |
| 6751 | return new Model(ref, definitions[ref], this.models, this.parent.modelPropertyMacro); |
| 6752 | } |
| 6753 | // schema must at least be an object to get resolved to an inline Model |
| 6754 | } else if (schema && typeof schema === 'object' && |
| 6755 | (schema.type === 'object' || _.isUndefined(schema.type))) { |
| 6756 | return new Model(undefined, schema, this.models, this.parent.modelPropertyMacro); |
| 6757 | } |
| 6758 | |
| 6759 | return null; |
| 6760 | }; |
| 6761 | |
| 6762 | Operation.prototype.help = function (dontPrint) { |
| 6763 | var out = this.nickname + ': ' + this.summary + '\n'; |
| 6764 | |
| 6765 | for (var i = 0; i < this.parameters.length; i++) { |
| 6766 | var param = this.parameters[i]; |
| 6767 | var typeInfo = param.signature; |
| 6768 | |
| 6769 | out += '\n * ' + param.name + ' (' + typeInfo + '): ' + param.description; |
| 6770 | } |
| 6771 | |
| 6772 | if (typeof dontPrint === 'undefined') { |
| 6773 | helpers.log(out); |
| 6774 | } |
| 6775 | |
| 6776 | return out; |
| 6777 | }; |
| 6778 | |
| 6779 | Operation.prototype.getModelSignature = function (type, definitions) { |
| 6780 | var isPrimitive, listType; |
| 6781 | |
| 6782 | if (type instanceof Array) { |
| 6783 | listType = true; |
| 6784 | type = type[0]; |
| 6785 | } |
| 6786 | |
| 6787 | // Convert undefined to string of 'undefined' |
| 6788 | if (typeof type === 'undefined') { |
| 6789 | type = 'undefined'; |
| 6790 | isPrimitive = true; |
| 6791 | |
| 6792 | } else if (definitions[type]){ |
| 6793 | // a model def exists? |
| 6794 | type = definitions[type]; /* Model */ |
| 6795 | isPrimitive = false; |
| 6796 | |
| 6797 | } else if (this.getInlineModel(type)) { |
| 6798 | type = this.getInlineModel(type); /* Model */ |
| 6799 | isPrimitive = false; |
| 6800 | |
| 6801 | } else { |
| 6802 | // We default to primitive |
| 6803 | isPrimitive = true; |
| 6804 | } |
| 6805 | |
| 6806 | if (isPrimitive) { |
| 6807 | if (listType) { |
| 6808 | return 'Array[' + type + ']'; |
| 6809 | } else { |
| 6810 | return type.toString(); |
| 6811 | } |
| 6812 | } else { |
| 6813 | if (listType) { |
| 6814 | return 'Array[' + type.getMockSignature() + ']'; |
| 6815 | } else { |
| 6816 | return type.getMockSignature(); |
| 6817 | } |
| 6818 | } |
| 6819 | }; |
| 6820 | |
| 6821 | Operation.prototype.supportHeaderParams = function () { |
| 6822 | return true; |
| 6823 | }; |
| 6824 | |
| 6825 | Operation.prototype.supportedSubmitMethods = function () { |
| 6826 | return this.parent.supportedSubmitMethods; |
| 6827 | }; |
| 6828 | |
| 6829 | Operation.prototype.getHeaderParams = function (args) { |
| 6830 | var headers = this.setContentTypes(args, {}); |
| 6831 | |
| 6832 | for (var i = 0; i < this.parameters.length; i++) { |
| 6833 | var param = this.parameters[i]; |
| 6834 | |
| 6835 | if (typeof args[param.name] !== 'undefined') { |
| 6836 | if (param.in === 'header') { |
| 6837 | var value = args[param.name]; |
| 6838 | |
| 6839 | if (Array.isArray(value)) { |
| 6840 | value = value.toString(); |
| 6841 | } |
| 6842 | |
| 6843 | headers[param.name] = value; |
| 6844 | } |
| 6845 | } |
| 6846 | } |
| 6847 | |
| 6848 | return headers; |
| 6849 | }; |
| 6850 | |
| 6851 | Operation.prototype.urlify = function (args) { |
| 6852 | var formParams = {}; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6853 | var requestUrl = this.path.replace(/#.*/, ''); // remove URL fragment |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6854 | var querystring = ''; // grab params from the args, build the querystring along the way |
| 6855 | |
| 6856 | for (var i = 0; i < this.parameters.length; i++) { |
| 6857 | var param = this.parameters[i]; |
| 6858 | |
| 6859 | if (typeof args[param.name] !== 'undefined') { |
| 6860 | if (param.in === 'path') { |
| 6861 | var reg = new RegExp('\{' + param.name + '\}', 'gi'); |
| 6862 | var value = args[param.name]; |
| 6863 | |
| 6864 | if (Array.isArray(value)) { |
| 6865 | value = this.encodePathCollection(param.collectionFormat, param.name, value); |
| 6866 | } else { |
| 6867 | value = this.encodePathParam(value); |
| 6868 | } |
| 6869 | |
| 6870 | requestUrl = requestUrl.replace(reg, value); |
| 6871 | } else if (param.in === 'query' && typeof args[param.name] !== 'undefined') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6872 | if (querystring === '' && requestUrl.indexOf('?') < 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6873 | querystring += '?'; |
| 6874 | } else { |
| 6875 | querystring += '&'; |
| 6876 | } |
| 6877 | |
| 6878 | if (typeof param.collectionFormat !== 'undefined') { |
| 6879 | var qp = args[param.name]; |
| 6880 | |
| 6881 | if (Array.isArray(qp)) { |
| 6882 | querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp); |
| 6883 | } else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6884 | querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam(args[param.name]); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6885 | } |
| 6886 | } else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6887 | querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam(args[param.name]); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6888 | } |
| 6889 | } else if (param.in === 'formData') { |
| 6890 | formParams[param.name] = args[param.name]; |
| 6891 | } |
| 6892 | } |
| 6893 | } |
| 6894 | var url = this.scheme + '://' + this.host; |
| 6895 | |
| 6896 | if (this.basePath !== '/') { |
| 6897 | url += this.basePath; |
| 6898 | } |
| 6899 | return url + requestUrl + querystring; |
| 6900 | }; |
| 6901 | |
| 6902 | Operation.prototype.getMissingParams = function (args) { |
| 6903 | var missingParams = []; // check required params, track the ones that are missing |
| 6904 | var i; |
| 6905 | |
| 6906 | for (i = 0; i < this.parameters.length; i++) { |
| 6907 | var param = this.parameters[i]; |
| 6908 | |
| 6909 | if (param.required === true) { |
| 6910 | if (typeof args[param.name] === 'undefined') { |
| 6911 | missingParams = param.name; |
| 6912 | } |
| 6913 | } |
| 6914 | } |
| 6915 | |
| 6916 | return missingParams; |
| 6917 | }; |
| 6918 | |
| 6919 | Operation.prototype.getBody = function (headers, args, opts) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6920 | var formParams = {}, hasFormParams, body, key, value, hasBody = false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6921 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6922 | // look at each param and put form params in an object |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6923 | for (var i = 0; i < this.parameters.length; i++) { |
| 6924 | var param = this.parameters[i]; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6925 | if (typeof args[param.name] !== 'undefined') { |
| 6926 | if (param.in === 'body') { |
| 6927 | body = args[param.name]; |
| 6928 | } else if (param.in === 'formData') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6929 | formParams[param.name] = { |
| 6930 | param: param, |
| 6931 | value: args[param.name] |
| 6932 | }; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6933 | hasFormParams = true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6934 | } |
| 6935 | } |
| 6936 | else { |
| 6937 | if(param.in === 'body') { |
| 6938 | hasBody = true; |
| 6939 | } |
| 6940 | } |
| 6941 | } |
| 6942 | |
| 6943 | // if body is null and hasBody is true, AND a JSON body is requested, send empty {} |
| 6944 | if(hasBody && typeof body === 'undefined') { |
| 6945 | var contentType = headers['Content-Type']; |
| 6946 | if(contentType && contentType.indexOf('application/json') === 0) { |
| 6947 | body = '{}'; |
| 6948 | } |
| 6949 | } |
| 6950 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6951 | var isMultiPart = false; |
| 6952 | if(headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) { |
| 6953 | isMultiPart = true; |
| 6954 | } |
| 6955 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6956 | // handle form params |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6957 | if (hasFormParams && !isMultiPart) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6958 | var encoded = ''; |
| 6959 | |
| 6960 | for (key in formParams) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6961 | var param = formParams[key].param; |
| 6962 | value = formParams[key].value; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6963 | |
| 6964 | if (typeof value !== 'undefined') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6965 | if (Array.isArray(value)) { |
| 6966 | if (encoded !== '') { |
| 6967 | encoded += '&'; |
| 6968 | } |
| 6969 | encoded += this.encodeQueryCollection(param.collectionFormat, key, value); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6970 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6971 | else { |
| 6972 | if (encoded !== '') { |
| 6973 | encoded += '&'; |
| 6974 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6975 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6976 | encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value); |
| 6977 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6978 | } |
| 6979 | } |
| 6980 | |
| 6981 | body = encoded; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 6982 | } else if (isMultiPart) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6983 | if (typeof FormData === 'function') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6984 | var bodyParam = new FormData(); |
| 6985 | |
| 6986 | bodyParam.type = 'formData'; |
| 6987 | |
| 6988 | for (key in formParams) { |
| 6989 | value = args[key]; |
| 6990 | |
| 6991 | if (typeof value !== 'undefined') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6992 | if({}.toString.apply(value) === '[object File]') { |
| 6993 | bodyParam.append(key, value); |
| 6994 | } |
| 6995 | else if (value.type === 'file' && value.value) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 6996 | bodyParam.append(key, value.value); |
| 6997 | } else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 6998 | if (Array.isArray(value)) { |
| 6999 | bodyParam.append(key, this.encodeQueryCollection(param.collectionFormat, key, value)); |
| 7000 | } |
| 7001 | else { |
| 7002 | bodyParam.append(key, value); |
| 7003 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7004 | } |
| 7005 | } |
| 7006 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7007 | body = bodyParam; |
| 7008 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7009 | else { |
| 7010 | bodyParam = {}; |
| 7011 | for (key in formParams) { |
| 7012 | value = args[key]; |
| 7013 | if (Array.isArray(value)) { |
| 7014 | var delimeter; |
| 7015 | var format = param.collectionFormat || 'multi'; |
| 7016 | if(format === 'ssv') { |
| 7017 | delimeter = ' '; |
| 7018 | } |
| 7019 | else if(format === 'pipes') { |
| 7020 | delimeter = '|'; |
| 7021 | } |
| 7022 | else if(format === 'tsv') { |
| 7023 | delimeter = '\t'; |
| 7024 | } |
| 7025 | else { |
| 7026 | delimeter = ','; |
| 7027 | } |
| 7028 | var data; |
| 7029 | value.forEach(function(v) { |
| 7030 | if(data) { |
| 7031 | data += delimeter; |
| 7032 | } |
| 7033 | else { |
| 7034 | data = ''; |
| 7035 | } |
| 7036 | data += v; |
| 7037 | }); |
| 7038 | bodyParam[key] = data; |
| 7039 | } |
| 7040 | else { |
| 7041 | bodyParam[key] = value; |
| 7042 | } |
| 7043 | } |
| 7044 | body = bodyParam; |
| 7045 | } |
| 7046 | headers['Content-Type'] = 'multipart/form-data'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7047 | } |
| 7048 | |
| 7049 | return body; |
| 7050 | }; |
| 7051 | |
| 7052 | /** |
| 7053 | * gets sample response for a single operation |
| 7054 | **/ |
| 7055 | Operation.prototype.getModelSampleJSON = function (type, models) { |
| 7056 | var listType, sampleJson, innerType; |
| 7057 | models = models || {}; |
| 7058 | |
| 7059 | listType = (type instanceof Array); |
| 7060 | innerType = listType ? type[0] : type; |
| 7061 | |
| 7062 | if(models[innerType]) { |
| 7063 | sampleJson = models[innerType].createJSONSample(); |
| 7064 | } else if (this.getInlineModel(innerType)){ |
| 7065 | sampleJson = this.getInlineModel(innerType).createJSONSample(); // may return null, if type isn't correct |
| 7066 | } |
| 7067 | |
| 7068 | |
| 7069 | if (sampleJson) { |
| 7070 | sampleJson = listType ? [sampleJson] : sampleJson; |
| 7071 | |
| 7072 | if (typeof sampleJson === 'string') { |
| 7073 | return sampleJson; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7074 | } else if (_.isObject(sampleJson)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7075 | var t = sampleJson; |
| 7076 | |
| 7077 | if (sampleJson instanceof Array && sampleJson.length > 0) { |
| 7078 | t = sampleJson[0]; |
| 7079 | } |
| 7080 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7081 | if (t.nodeName && typeof t === 'Node') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7082 | var xmlString = new XMLSerializer().serializeToString(t); |
| 7083 | |
| 7084 | return this.formatXml(xmlString); |
| 7085 | } else { |
| 7086 | return JSON.stringify(sampleJson, null, 2); |
| 7087 | } |
| 7088 | } else { |
| 7089 | return sampleJson; |
| 7090 | } |
| 7091 | } |
| 7092 | }; |
| 7093 | |
| 7094 | /** |
| 7095 | * legacy binding |
| 7096 | **/ |
| 7097 | Operation.prototype.do = function (args, opts, callback, error, parent) { |
| 7098 | return this.execute(args, opts, callback, error, parent); |
| 7099 | }; |
| 7100 | |
| 7101 | /** |
| 7102 | * executes an operation |
| 7103 | **/ |
| 7104 | Operation.prototype.execute = function (arg1, arg2, arg3, arg4, parent) { |
| 7105 | var args = arg1 || {}; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7106 | var opts = {}, success, error, deferred; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7107 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7108 | if (_.isObject(arg2)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7109 | opts = arg2; |
| 7110 | success = arg3; |
| 7111 | error = arg4; |
| 7112 | } |
| 7113 | |
| 7114 | if(this.client) { |
| 7115 | opts.client = this.client; |
| 7116 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7117 | |
| 7118 | // add the request interceptor from parent, if none sent from client |
| 7119 | if(!opts.requestInterceptor && this.requestInterceptor ) { |
| 7120 | opts.requestInterceptor = this.requestInterceptor ; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7121 | } |
| 7122 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7123 | if(!opts.responseInterceptor && this.responseInterceptor) { |
| 7124 | opts.responseInterceptor = this.responseInterceptor; |
| 7125 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7126 | |
| 7127 | if (typeof arg2 === 'function') { |
| 7128 | success = arg2; |
| 7129 | error = arg3; |
| 7130 | } |
| 7131 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7132 | if (this.parent.usePromise) { |
| 7133 | deferred = Q.defer(); |
| 7134 | } else { |
| 7135 | success = (success || this.parent.defaultSuccessCallback || helpers.log); |
| 7136 | error = (error || this.parent.defaultErrorCallback || helpers.log); |
| 7137 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7138 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7139 | if (typeof opts.useJQuery === 'undefined') { |
| 7140 | opts.useJQuery = this.useJQuery; |
| 7141 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7142 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7143 | if (typeof opts.jqueryAjaxCache === 'undefined') { |
| 7144 | opts.jqueryAjaxCache = this.jqueryAjaxCache; |
| 7145 | } |
| 7146 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7147 | if (typeof opts.enableCookies === 'undefined') { |
| 7148 | opts.enableCookies = this.enableCookies; |
| 7149 | } |
| 7150 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7151 | var missingParams = this.getMissingParams(args); |
| 7152 | |
| 7153 | if (missingParams.length > 0) { |
| 7154 | var message = 'missing required params: ' + missingParams; |
| 7155 | |
| 7156 | helpers.fail(message); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7157 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7158 | if (this.parent.usePromise) { |
| 7159 | deferred.reject(message); |
| 7160 | return deferred.promise; |
| 7161 | } else { |
| 7162 | error(message, parent); |
| 7163 | return {}; |
| 7164 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7165 | } |
| 7166 | |
| 7167 | var allHeaders = this.getHeaderParams(args); |
| 7168 | var contentTypeHeaders = this.setContentTypes(args, opts); |
| 7169 | var headers = {}, attrname; |
| 7170 | |
| 7171 | for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; } |
| 7172 | for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; } |
| 7173 | |
| 7174 | var body = this.getBody(contentTypeHeaders, args, opts); |
| 7175 | var url = this.urlify(args); |
| 7176 | |
| 7177 | if(url.indexOf('.{format}') > 0) { |
| 7178 | if(headers) { |
| 7179 | var format = headers.Accept || headers.accept; |
| 7180 | if(format && format.indexOf('json') > 0) { |
| 7181 | url = url.replace('.{format}', '.json'); |
| 7182 | } |
| 7183 | else if(format && format.indexOf('xml') > 0) { |
| 7184 | url = url.replace('.{format}', '.xml'); |
| 7185 | } |
| 7186 | } |
| 7187 | } |
| 7188 | |
| 7189 | var obj = { |
| 7190 | url: url, |
| 7191 | method: this.method.toUpperCase(), |
| 7192 | body: body, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7193 | enableCookies: opts.enableCookies, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7194 | useJQuery: opts.useJQuery, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7195 | jqueryAjaxCache: opts.jqueryAjaxCache, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7196 | deferred: deferred, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7197 | headers: headers, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7198 | clientAuthorizations: opts.clientAuthorizations, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7199 | on: { |
| 7200 | response: function (response) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7201 | if (deferred) { |
| 7202 | deferred.resolve(response); |
| 7203 | return deferred.promise; |
| 7204 | } else { |
| 7205 | return success(response, parent); |
| 7206 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7207 | }, |
| 7208 | error: function (response) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7209 | if (deferred) { |
| 7210 | deferred.reject(response); |
| 7211 | return deferred.promise; |
| 7212 | } else { |
| 7213 | return error(response, parent); |
| 7214 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7215 | } |
| 7216 | } |
| 7217 | }; |
| 7218 | |
| 7219 | this.clientAuthorizations.apply(obj, this.operation.security); |
| 7220 | if (opts.mock === true) { |
| 7221 | return obj; |
| 7222 | } else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7223 | return new SwaggerHttp().execute(obj, opts); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7224 | } |
| 7225 | }; |
| 7226 | |
| 7227 | function itemByPriority(col, itemPriority) { |
| 7228 | |
| 7229 | // No priorities? return first... |
| 7230 | if(_.isEmpty(itemPriority)) { |
| 7231 | return col[0]; |
| 7232 | } |
| 7233 | |
| 7234 | for (var i = 0, len = itemPriority.length; i < len; i++) { |
| 7235 | if(col.indexOf(itemPriority[i]) > -1) { |
| 7236 | return itemPriority[i]; |
| 7237 | } |
| 7238 | } |
| 7239 | |
| 7240 | // Otherwise return first |
| 7241 | return col[0]; |
| 7242 | } |
| 7243 | |
| 7244 | Operation.prototype.setContentTypes = function (args, opts) { |
| 7245 | // default type |
| 7246 | var allDefinedParams = this.parameters; |
| 7247 | var body; |
| 7248 | var consumes = args.parameterContentType || itemByPriority(this.consumes, ['application/json', 'application/yaml']); |
| 7249 | var accepts = opts.responseContentType || itemByPriority(this.produces, ['application/json', 'application/yaml']); |
| 7250 | var definedFileParams = []; |
| 7251 | var definedFormParams = []; |
| 7252 | var headers = {}; |
| 7253 | var i; |
| 7254 | |
| 7255 | // get params from the operation and set them in definedFileParams, definedFormParams, headers |
| 7256 | for (i = 0; i < allDefinedParams.length; i++) { |
| 7257 | var param = allDefinedParams[i]; |
| 7258 | |
| 7259 | if (param.in === 'formData') { |
| 7260 | if (param.type === 'file') { |
| 7261 | definedFileParams.push(param); |
| 7262 | } else { |
| 7263 | definedFormParams.push(param); |
| 7264 | } |
| 7265 | } else if (param.in === 'header' && opts) { |
| 7266 | var key = param.name; |
| 7267 | var headerValue = opts[param.name]; |
| 7268 | |
| 7269 | if (typeof opts[param.name] !== 'undefined') { |
| 7270 | headers[key] = headerValue; |
| 7271 | } |
| 7272 | } else if (param.in === 'body' && typeof args[param.name] !== 'undefined') { |
| 7273 | body = args[param.name]; |
| 7274 | } |
| 7275 | } |
| 7276 | |
| 7277 | // if there's a body, need to set the consumes header via requestContentType |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7278 | var hasBody = body || definedFileParams.length || definedFormParams.length; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7279 | if (this.method === 'post' || this.method === 'put' || this.method === 'patch' || |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7280 | ((this.method === 'delete' || this.method === 'get') && hasBody)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7281 | if (opts.requestContentType) { |
| 7282 | consumes = opts.requestContentType; |
| 7283 | } |
| 7284 | // if any form params, content type must be set |
| 7285 | if (definedFormParams.length > 0) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7286 | consumes = undefined; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7287 | if (opts.requestContentType) { // override if set |
| 7288 | consumes = opts.requestContentType; |
| 7289 | } else if (definedFileParams.length > 0) { // if a file, must be multipart/form-data |
| 7290 | consumes = 'multipart/form-data'; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7291 | } else { |
| 7292 | if (this.consumes && this.consumes.length > 0) { |
| 7293 | // use the consumes setting |
| 7294 | for(var c in this.consumes) { |
| 7295 | var chk = this.consumes[c]; |
| 7296 | if(chk.indexOf('application/x-www-form-urlencoded') === 0 || chk.indexOf('multipart/form-data') === 0) { |
| 7297 | consumes = chk; |
| 7298 | } |
| 7299 | } |
| 7300 | } |
| 7301 | } |
| 7302 | if(typeof consumes === 'undefined') { |
| 7303 | // default to x-www-from-urlencoded |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7304 | consumes = 'application/x-www-form-urlencoded'; |
| 7305 | } |
| 7306 | } |
| 7307 | } |
| 7308 | else { |
| 7309 | consumes = null; |
| 7310 | } |
| 7311 | |
| 7312 | if (consumes && this.consumes) { |
| 7313 | if (this.consumes.indexOf(consumes) === -1) { |
| 7314 | helpers.log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes)); |
| 7315 | } |
| 7316 | } |
| 7317 | |
| 7318 | if (!this.matchesAccept(accepts)) { |
| 7319 | helpers.log('server can\'t produce ' + accepts); |
| 7320 | } |
| 7321 | |
| 7322 | if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) { |
| 7323 | headers['Content-Type'] = consumes; |
| 7324 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7325 | else if(this.consumes && this.consumes.length > 0 && this.consumes[0] === 'application/x-www-form-urlencoded') { |
| 7326 | headers['Content-Type'] = this.consumes[0]; |
| 7327 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7328 | |
| 7329 | if (accepts) { |
| 7330 | headers.Accept = accepts; |
| 7331 | } |
| 7332 | |
| 7333 | return headers; |
| 7334 | }; |
| 7335 | |
| 7336 | /** |
| 7337 | * Returns true if the request accepts header matches anything in this.produces. |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7338 | * If this.produces contains * / *, ignore the accept header. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7339 | * @param {string=} accepts The client request accept header. |
| 7340 | * @return {boolean} |
| 7341 | */ |
| 7342 | Operation.prototype.matchesAccept = function(accepts) { |
| 7343 | // no accepts or produces, no problem! |
| 7344 | if (!accepts || !this.produces) { |
| 7345 | return true; |
| 7346 | } |
| 7347 | return this.produces.indexOf(accepts) !== -1 || this.produces.indexOf('*/*') !== -1; |
| 7348 | }; |
| 7349 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7350 | Operation.prototype.asCurl = function (args1, args2) { |
| 7351 | var opts = {mock: true}; |
| 7352 | if (typeof args2 === 'object') { |
| 7353 | for (var argKey in args2) { |
| 7354 | opts[argKey] = args2[argKey]; |
| 7355 | } |
| 7356 | } |
| 7357 | var obj = this.execute(args1, opts); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7358 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7359 | this.clientAuthorizations.apply(obj, this.operation.security); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7360 | |
| 7361 | var results = []; |
| 7362 | |
| 7363 | results.push('-X ' + this.method.toUpperCase()); |
| 7364 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7365 | if (typeof obj.headers !== 'undefined') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7366 | var key; |
| 7367 | |
| 7368 | for (key in obj.headers) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7369 | var value = obj.headers[key]; |
| 7370 | if(typeof value === 'string'){ |
| 7371 | value = value.replace(/\'/g, '\\u0027'); |
| 7372 | } |
| 7373 | results.push('--header \'' + key + ': ' + value + '\''); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7374 | } |
| 7375 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7376 | var isFormData = false; |
| 7377 | var isMultipart = false; |
| 7378 | |
| 7379 | var type = obj.headers['Content-Type']; |
| 7380 | if(type && type.indexOf('application/x-www-form-urlencoded') === 0) { |
| 7381 | isFormData = true; |
| 7382 | } |
| 7383 | else if (type && type.indexOf('multipart/form-data') === 0) { |
| 7384 | isFormData = true; |
| 7385 | isMultipart = true; |
| 7386 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7387 | |
| 7388 | if (obj.body) { |
| 7389 | var body; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7390 | if (_.isObject(obj.body)) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7391 | if(isMultipart) { |
| 7392 | isMultipart = true; |
| 7393 | // add the form data |
| 7394 | for(var i = 0; i < this.parameters.length; i++) { |
| 7395 | var parameter = this.parameters[i]; |
| 7396 | if(parameter.in === 'formData') { |
| 7397 | if (!body) { |
| 7398 | body = ''; |
| 7399 | } |
| 7400 | |
| 7401 | var paramValue; |
| 7402 | if(typeof FormData === 'function' && obj.body instanceof FormData) { |
| 7403 | paramValue = obj.body.get(parameter.name); |
| 7404 | } |
| 7405 | else { |
| 7406 | paramValue = obj.body[parameter.name]; |
| 7407 | } |
| 7408 | if (paramValue) { |
| 7409 | if (parameter.type === 'file') { |
| 7410 | if(paramValue.name) { |
| 7411 | body += '-F ' + parameter.name + '=@"' + paramValue.name + '" '; |
| 7412 | } |
| 7413 | } |
| 7414 | else { |
| 7415 | body += '-F '; |
| 7416 | if (Array.isArray(paramValue)) { |
| 7417 | body += this.encodeQueryCollection(parameter.collectionFormat, parameter.name, paramValue); |
| 7418 | } else { |
| 7419 | body += this.encodeQueryKey(parameter.name) + '=' + paramValue; |
| 7420 | } |
| 7421 | body += ' '; |
| 7422 | } |
| 7423 | } |
| 7424 | } |
| 7425 | |
| 7426 | } |
| 7427 | } |
| 7428 | if(!body) { |
| 7429 | body = JSON.stringify(obj.body); |
| 7430 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7431 | } else { |
| 7432 | body = obj.body; |
| 7433 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7434 | // escape @ => %40, ' => %27 |
| 7435 | body = body.replace(/\'/g, '%27').replace(/\n/g, ' \\ \n '); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7436 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7437 | if(!isFormData) { |
| 7438 | // escape & => %26 |
| 7439 | body = body.replace(/&/g, '%26'); |
| 7440 | } |
| 7441 | if(isMultipart) { |
| 7442 | results.push(body); |
| 7443 | } |
| 7444 | else { |
| 7445 | results.push('-d \'' + body.replace(/@/g, '%40') + '\''); |
| 7446 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7447 | } |
| 7448 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7449 | return 'curl ' + (results.join(' ')) + ' \'' + obj.url + '\''; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7450 | }; |
| 7451 | |
| 7452 | Operation.prototype.encodePathCollection = function (type, name, value) { |
| 7453 | var encoded = ''; |
| 7454 | var i; |
| 7455 | var separator = ''; |
| 7456 | |
| 7457 | if (type === 'ssv') { |
| 7458 | separator = '%20'; |
| 7459 | } else if (type === 'tsv') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7460 | separator = '%09'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7461 | } else if (type === 'pipes') { |
| 7462 | separator = '|'; |
| 7463 | } else { |
| 7464 | separator = ','; |
| 7465 | } |
| 7466 | |
| 7467 | for (i = 0; i < value.length; i++) { |
| 7468 | if (i === 0) { |
| 7469 | encoded = this.encodeQueryParam(value[i]); |
| 7470 | } else { |
| 7471 | encoded += separator + this.encodeQueryParam(value[i]); |
| 7472 | } |
| 7473 | } |
| 7474 | |
| 7475 | return encoded; |
| 7476 | }; |
| 7477 | |
| 7478 | Operation.prototype.encodeQueryCollection = function (type, name, value) { |
| 7479 | var encoded = ''; |
| 7480 | var i; |
| 7481 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7482 | type = type || 'default'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7483 | if (type === 'default' || type === 'multi') { |
| 7484 | for (i = 0; i < value.length; i++) { |
| 7485 | if (i > 0) {encoded += '&';} |
| 7486 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7487 | encoded += this.encodeQueryKey(name) + '=' + this.encodeQueryParam(value[i]); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7488 | } |
| 7489 | } else { |
| 7490 | var separator = ''; |
| 7491 | |
| 7492 | if (type === 'csv') { |
| 7493 | separator = ','; |
| 7494 | } else if (type === 'ssv') { |
| 7495 | separator = '%20'; |
| 7496 | } else if (type === 'tsv') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7497 | separator = '%09'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7498 | } else if (type === 'pipes') { |
| 7499 | separator = '|'; |
| 7500 | } else if (type === 'brackets') { |
| 7501 | for (i = 0; i < value.length; i++) { |
| 7502 | if (i !== 0) { |
| 7503 | encoded += '&'; |
| 7504 | } |
| 7505 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7506 | encoded += this.encodeQueryKey(name) + '[]=' + this.encodeQueryParam(value[i]); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7507 | } |
| 7508 | } |
| 7509 | |
| 7510 | if (separator !== '') { |
| 7511 | for (i = 0; i < value.length; i++) { |
| 7512 | if (i === 0) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7513 | encoded = this.encodeQueryKey(name) + '=' + this.encodeQueryParam(value[i]); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7514 | } else { |
| 7515 | encoded += separator + this.encodeQueryParam(value[i]); |
| 7516 | } |
| 7517 | } |
| 7518 | } |
| 7519 | } |
| 7520 | |
| 7521 | return encoded; |
| 7522 | }; |
| 7523 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7524 | Operation.prototype.encodeQueryKey = function (arg) { |
| 7525 | return encodeURIComponent(arg) |
| 7526 | .replace('%5B','[').replace('%5D', ']').replace('%24', '$'); |
| 7527 | }; |
| 7528 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7529 | Operation.prototype.encodeQueryParam = function (arg) { |
| 7530 | return encodeURIComponent(arg); |
| 7531 | }; |
| 7532 | |
| 7533 | /** |
| 7534 | * TODO revisit, might not want to leave '/' |
| 7535 | **/ |
| 7536 | Operation.prototype.encodePathParam = function (pathParam) { |
| 7537 | return encodeURIComponent(pathParam); |
| 7538 | }; |
| 7539 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7540 | },{"../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){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7541 | 'use strict'; |
| 7542 | |
| 7543 | var OperationGroup = module.exports = function (tag, description, externalDocs, operation) { |
| 7544 | this.description = description; |
| 7545 | this.externalDocs = externalDocs; |
| 7546 | this.name = tag; |
| 7547 | this.operation = operation; |
| 7548 | this.operationsArray = []; |
| 7549 | this.path = tag; |
| 7550 | this.tag = tag; |
| 7551 | }; |
| 7552 | |
| 7553 | OperationGroup.prototype.sort = function () { |
| 7554 | |
| 7555 | }; |
| 7556 | |
| 7557 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7558 | },{}],12:[function(require,module,exports){ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7559 | // shim for using process in browser |
| 7560 | |
| 7561 | var process = module.exports = {}; |
| 7562 | var queue = []; |
| 7563 | var draining = false; |
| 7564 | |
| 7565 | function drainQueue() { |
| 7566 | if (draining) { |
| 7567 | return; |
| 7568 | } |
| 7569 | draining = true; |
| 7570 | var currentQueue; |
| 7571 | var len = queue.length; |
| 7572 | while(len) { |
| 7573 | currentQueue = queue; |
| 7574 | queue = []; |
| 7575 | var i = -1; |
| 7576 | while (++i < len) { |
| 7577 | currentQueue[i](); |
| 7578 | } |
| 7579 | len = queue.length; |
| 7580 | } |
| 7581 | draining = false; |
| 7582 | } |
| 7583 | process.nextTick = function (fun) { |
| 7584 | queue.push(fun); |
| 7585 | if (!draining) { |
| 7586 | setTimeout(drainQueue, 0); |
| 7587 | } |
| 7588 | }; |
| 7589 | |
| 7590 | process.title = 'browser'; |
| 7591 | process.browser = true; |
| 7592 | process.env = {}; |
| 7593 | process.argv = []; |
| 7594 | process.version = ''; // empty string to avoid regexp issues |
| 7595 | process.versions = {}; |
| 7596 | |
| 7597 | function noop() {} |
| 7598 | |
| 7599 | process.on = noop; |
| 7600 | process.addListener = noop; |
| 7601 | process.once = noop; |
| 7602 | process.off = noop; |
| 7603 | process.removeListener = noop; |
| 7604 | process.removeAllListeners = noop; |
| 7605 | process.emit = noop; |
| 7606 | |
| 7607 | process.binding = function (name) { |
| 7608 | throw new Error('process.binding is not supported'); |
| 7609 | }; |
| 7610 | |
| 7611 | // TODO(shtylman) |
| 7612 | process.cwd = function () { return '/' }; |
| 7613 | process.chdir = function (dir) { |
| 7614 | throw new Error('process.chdir is not supported'); |
| 7615 | }; |
| 7616 | process.umask = function() { return 0; }; |
| 7617 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7618 | },{}],13:[function(require,module,exports){ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7619 | (function (Buffer){ |
| 7620 | (function () { |
| 7621 | "use strict"; |
| 7622 | |
| 7623 | function btoa(str) { |
| 7624 | var buffer |
| 7625 | ; |
| 7626 | |
| 7627 | if (str instanceof Buffer) { |
| 7628 | buffer = str; |
| 7629 | } else { |
| 7630 | buffer = new Buffer(str.toString(), 'binary'); |
| 7631 | } |
| 7632 | |
| 7633 | return buffer.toString('base64'); |
| 7634 | } |
| 7635 | |
| 7636 | module.exports = btoa; |
| 7637 | }()); |
| 7638 | |
| 7639 | }).call(this,require("buffer").Buffer) |
| 7640 | //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uICgpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgZnVuY3Rpb24gYnRvYShzdHIpIHtcbiAgICB2YXIgYnVmZmVyXG4gICAgICA7XG5cbiAgICBpZiAoc3RyIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICBidWZmZXIgPSBzdHI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1ZmZlciA9IG5ldyBCdWZmZXIoc3RyLnRvU3RyaW5nKCksICdiaW5hcnknKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgfVxuXG4gIG1vZHVsZS5leHBvcnRzID0gYnRvYTtcbn0oKSk7XG4iXX0= |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 7641 | },{"buffer":14}],14:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7642 | /*! |
| 7643 | * The buffer module from node.js, for the browser. |
| 7644 | * |
| 7645 | * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> |
| 7646 | * @license MIT |
| 7647 | */ |
| 7648 | |
| 7649 | var base64 = require('base64-js') |
| 7650 | var ieee754 = require('ieee754') |
| 7651 | var isArray = require('is-array') |
| 7652 | |
| 7653 | exports.Buffer = Buffer |
| 7654 | exports.SlowBuffer = SlowBuffer |
| 7655 | exports.INSPECT_MAX_BYTES = 50 |
| 7656 | Buffer.poolSize = 8192 // not used by this implementation |
| 7657 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7658 | var rootParent = {} |
| 7659 | |
| 7660 | /** |
| 7661 | * If `Buffer.TYPED_ARRAY_SUPPORT`: |
| 7662 | * === true Use Uint8Array implementation (fastest) |
| 7663 | * === false Use Object implementation (most compatible, even IE6) |
| 7664 | * |
| 7665 | * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, |
| 7666 | * Opera 11.6+, iOS 4.2+. |
| 7667 | * |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7668 | * Due to various browser bugs, sometimes the Object implementation will be used even |
| 7669 | * when the browser supports typed arrays. |
| 7670 | * |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7671 | * Note: |
| 7672 | * |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7673 | * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, |
| 7674 | * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7675 | * |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7676 | * - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property |
| 7677 | * on objects. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7678 | * |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7679 | * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7680 | * |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7681 | * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of |
| 7682 | * incorrect length in some situations. |
| 7683 | |
| 7684 | * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they |
| 7685 | * get the Object implementation, which is slower but behaves correctly. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7686 | */ |
| 7687 | Buffer.TYPED_ARRAY_SUPPORT = (function () { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7688 | function Bar () {} |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7689 | try { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7690 | var arr = new Uint8Array(1) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7691 | arr.foo = function () { return 42 } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7692 | arr.constructor = Bar |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7693 | return arr.foo() === 42 && // typed array instances can be augmented |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7694 | arr.constructor === Bar && // constructor can be set |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7695 | typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7696 | arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7697 | } catch (e) { |
| 7698 | return false |
| 7699 | } |
| 7700 | })() |
| 7701 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7702 | function kMaxLength () { |
| 7703 | return Buffer.TYPED_ARRAY_SUPPORT |
| 7704 | ? 0x7fffffff |
| 7705 | : 0x3fffffff |
| 7706 | } |
| 7707 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7708 | /** |
| 7709 | * Class: Buffer |
| 7710 | * ============= |
| 7711 | * |
| 7712 | * The Buffer constructor returns instances of `Uint8Array` that are augmented |
| 7713 | * with function properties for all the node `Buffer` API functions. We use |
| 7714 | * `Uint8Array` so that square bracket notation works as expected -- it returns |
| 7715 | * a single octet. |
| 7716 | * |
| 7717 | * By augmenting the instances, we can avoid modifying the `Uint8Array` |
| 7718 | * prototype. |
| 7719 | */ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7720 | function Buffer (arg) { |
| 7721 | if (!(this instanceof Buffer)) { |
| 7722 | // Avoid going through an ArgumentsAdaptorTrampoline in the common case. |
| 7723 | if (arguments.length > 1) return new Buffer(arg, arguments[1]) |
| 7724 | return new Buffer(arg) |
| 7725 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7726 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7727 | this.length = 0 |
| 7728 | this.parent = undefined |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7729 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7730 | // Common case. |
| 7731 | if (typeof arg === 'number') { |
| 7732 | return fromNumber(this, arg) |
| 7733 | } |
| 7734 | |
| 7735 | // Slightly less common case. |
| 7736 | if (typeof arg === 'string') { |
| 7737 | return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') |
| 7738 | } |
| 7739 | |
| 7740 | // Unusual. |
| 7741 | return fromObject(this, arg) |
| 7742 | } |
| 7743 | |
| 7744 | function fromNumber (that, length) { |
| 7745 | that = allocate(that, length < 0 ? 0 : checked(length) | 0) |
| 7746 | if (!Buffer.TYPED_ARRAY_SUPPORT) { |
| 7747 | for (var i = 0; i < length; i++) { |
| 7748 | that[i] = 0 |
| 7749 | } |
| 7750 | } |
| 7751 | return that |
| 7752 | } |
| 7753 | |
| 7754 | function fromString (that, string, encoding) { |
| 7755 | if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' |
| 7756 | |
| 7757 | // Assumption: byteLength() return value is always < kMaxLength. |
| 7758 | var length = byteLength(string, encoding) | 0 |
| 7759 | that = allocate(that, length) |
| 7760 | |
| 7761 | that.write(string, encoding) |
| 7762 | return that |
| 7763 | } |
| 7764 | |
| 7765 | function fromObject (that, object) { |
| 7766 | if (Buffer.isBuffer(object)) return fromBuffer(that, object) |
| 7767 | |
| 7768 | if (isArray(object)) return fromArray(that, object) |
| 7769 | |
| 7770 | if (object == null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7771 | throw new TypeError('must start with number, buffer, array or string') |
| 7772 | } |
| 7773 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7774 | if (typeof ArrayBuffer !== 'undefined') { |
| 7775 | if (object.buffer instanceof ArrayBuffer) { |
| 7776 | return fromTypedArray(that, object) |
| 7777 | } |
| 7778 | if (object instanceof ArrayBuffer) { |
| 7779 | return fromArrayBuffer(that, object) |
| 7780 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7781 | } |
| 7782 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7783 | if (object.length) return fromArrayLike(that, object) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7784 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7785 | return fromJsonObject(that, object) |
| 7786 | } |
| 7787 | |
| 7788 | function fromBuffer (that, buffer) { |
| 7789 | var length = checked(buffer.length) | 0 |
| 7790 | that = allocate(that, length) |
| 7791 | buffer.copy(that, 0, 0, length) |
| 7792 | return that |
| 7793 | } |
| 7794 | |
| 7795 | function fromArray (that, array) { |
| 7796 | var length = checked(array.length) | 0 |
| 7797 | that = allocate(that, length) |
| 7798 | for (var i = 0; i < length; i += 1) { |
| 7799 | that[i] = array[i] & 255 |
| 7800 | } |
| 7801 | return that |
| 7802 | } |
| 7803 | |
| 7804 | // Duplicate of fromArray() to keep fromArray() monomorphic. |
| 7805 | function fromTypedArray (that, array) { |
| 7806 | var length = checked(array.length) | 0 |
| 7807 | that = allocate(that, length) |
| 7808 | // Truncating the elements is probably not what people expect from typed |
| 7809 | // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior |
| 7810 | // of the old Buffer constructor. |
| 7811 | for (var i = 0; i < length; i += 1) { |
| 7812 | that[i] = array[i] & 255 |
| 7813 | } |
| 7814 | return that |
| 7815 | } |
| 7816 | |
| 7817 | function fromArrayBuffer (that, array) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7818 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7819 | // Return an augmented `Uint8Array` instance, for best performance |
| 7820 | array.byteLength |
| 7821 | that = Buffer._augment(new Uint8Array(array)) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7822 | } else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7823 | // Fallback: Return an object instance of the Buffer class |
| 7824 | that = fromTypedArray(that, new Uint8Array(array)) |
| 7825 | } |
| 7826 | return that |
| 7827 | } |
| 7828 | |
| 7829 | function fromArrayLike (that, array) { |
| 7830 | var length = checked(array.length) | 0 |
| 7831 | that = allocate(that, length) |
| 7832 | for (var i = 0; i < length; i += 1) { |
| 7833 | that[i] = array[i] & 255 |
| 7834 | } |
| 7835 | return that |
| 7836 | } |
| 7837 | |
| 7838 | // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. |
| 7839 | // Returns a zero-length buffer for inputs that don't conform to the spec. |
| 7840 | function fromJsonObject (that, object) { |
| 7841 | var array |
| 7842 | var length = 0 |
| 7843 | |
| 7844 | if (object.type === 'Buffer' && isArray(object.data)) { |
| 7845 | array = object.data |
| 7846 | length = checked(array.length) | 0 |
| 7847 | } |
| 7848 | that = allocate(that, length) |
| 7849 | |
| 7850 | for (var i = 0; i < length; i += 1) { |
| 7851 | that[i] = array[i] & 255 |
| 7852 | } |
| 7853 | return that |
| 7854 | } |
| 7855 | |
| 7856 | function allocate (that, length) { |
| 7857 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 7858 | // Return an augmented `Uint8Array` instance, for best performance |
| 7859 | that = Buffer._augment(new Uint8Array(length)) |
| 7860 | } else { |
| 7861 | // Fallback: Return an object instance of the Buffer class |
| 7862 | that.length = length |
| 7863 | that._isBuffer = true |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7864 | } |
| 7865 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7866 | var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 |
| 7867 | if (fromPool) that.parent = rootParent |
| 7868 | |
| 7869 | return that |
| 7870 | } |
| 7871 | |
| 7872 | function checked (length) { |
| 7873 | // Note: cannot use `length < kMaxLength` here because that fails when |
| 7874 | // length is NaN (which is otherwise coerced to zero.) |
| 7875 | if (length >= kMaxLength()) { |
| 7876 | throw new RangeError('Attempt to allocate Buffer larger than maximum ' + |
| 7877 | 'size: 0x' + kMaxLength().toString(16) + ' bytes') |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7878 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7879 | return length | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7880 | } |
| 7881 | |
| 7882 | function SlowBuffer (subject, encoding) { |
| 7883 | if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) |
| 7884 | |
| 7885 | var buf = new Buffer(subject, encoding) |
| 7886 | delete buf.parent |
| 7887 | return buf |
| 7888 | } |
| 7889 | |
| 7890 | Buffer.isBuffer = function isBuffer (b) { |
| 7891 | return !!(b != null && b._isBuffer) |
| 7892 | } |
| 7893 | |
| 7894 | Buffer.compare = function compare (a, b) { |
| 7895 | if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { |
| 7896 | throw new TypeError('Arguments must be Buffers') |
| 7897 | } |
| 7898 | |
| 7899 | if (a === b) return 0 |
| 7900 | |
| 7901 | var x = a.length |
| 7902 | var y = b.length |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7903 | |
| 7904 | var i = 0 |
| 7905 | var len = Math.min(x, y) |
| 7906 | while (i < len) { |
| 7907 | if (a[i] !== b[i]) break |
| 7908 | |
| 7909 | ++i |
| 7910 | } |
| 7911 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7912 | if (i !== len) { |
| 7913 | x = a[i] |
| 7914 | y = b[i] |
| 7915 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7916 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7917 | if (x < y) return -1 |
| 7918 | if (y < x) return 1 |
| 7919 | return 0 |
| 7920 | } |
| 7921 | |
| 7922 | Buffer.isEncoding = function isEncoding (encoding) { |
| 7923 | switch (String(encoding).toLowerCase()) { |
| 7924 | case 'hex': |
| 7925 | case 'utf8': |
| 7926 | case 'utf-8': |
| 7927 | case 'ascii': |
| 7928 | case 'binary': |
| 7929 | case 'base64': |
| 7930 | case 'raw': |
| 7931 | case 'ucs2': |
| 7932 | case 'ucs-2': |
| 7933 | case 'utf16le': |
| 7934 | case 'utf-16le': |
| 7935 | return true |
| 7936 | default: |
| 7937 | return false |
| 7938 | } |
| 7939 | } |
| 7940 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7941 | Buffer.concat = function concat (list, length) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7942 | if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') |
| 7943 | |
| 7944 | if (list.length === 0) { |
| 7945 | return new Buffer(0) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7946 | } |
| 7947 | |
| 7948 | var i |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7949 | if (length === undefined) { |
| 7950 | length = 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7951 | for (i = 0; i < list.length; i++) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7952 | length += list[i].length |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7953 | } |
| 7954 | } |
| 7955 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7956 | var buf = new Buffer(length) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7957 | var pos = 0 |
| 7958 | for (i = 0; i < list.length; i++) { |
| 7959 | var item = list[i] |
| 7960 | item.copy(buf, pos) |
| 7961 | pos += item.length |
| 7962 | } |
| 7963 | return buf |
| 7964 | } |
| 7965 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 7966 | function byteLength (string, encoding) { |
| 7967 | if (typeof string !== 'string') string = '' + string |
| 7968 | |
| 7969 | var len = string.length |
| 7970 | if (len === 0) return 0 |
| 7971 | |
| 7972 | // Use a for loop to avoid recursion |
| 7973 | var loweredCase = false |
| 7974 | for (;;) { |
| 7975 | switch (encoding) { |
| 7976 | case 'ascii': |
| 7977 | case 'binary': |
| 7978 | // Deprecated |
| 7979 | case 'raw': |
| 7980 | case 'raws': |
| 7981 | return len |
| 7982 | case 'utf8': |
| 7983 | case 'utf-8': |
| 7984 | return utf8ToBytes(string).length |
| 7985 | case 'ucs2': |
| 7986 | case 'ucs-2': |
| 7987 | case 'utf16le': |
| 7988 | case 'utf-16le': |
| 7989 | return len * 2 |
| 7990 | case 'hex': |
| 7991 | return len >>> 1 |
| 7992 | case 'base64': |
| 7993 | return base64ToBytes(string).length |
| 7994 | default: |
| 7995 | if (loweredCase) return utf8ToBytes(string).length // assume utf8 |
| 7996 | encoding = ('' + encoding).toLowerCase() |
| 7997 | loweredCase = true |
| 7998 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 7999 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8000 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8001 | Buffer.byteLength = byteLength |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8002 | |
| 8003 | // pre-set for values that may exist in the future |
| 8004 | Buffer.prototype.length = undefined |
| 8005 | Buffer.prototype.parent = undefined |
| 8006 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8007 | function slowToString (encoding, start, end) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8008 | var loweredCase = false |
| 8009 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8010 | start = start | 0 |
| 8011 | end = end === undefined || end === Infinity ? this.length : end | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8012 | |
| 8013 | if (!encoding) encoding = 'utf8' |
| 8014 | if (start < 0) start = 0 |
| 8015 | if (end > this.length) end = this.length |
| 8016 | if (end <= start) return '' |
| 8017 | |
| 8018 | while (true) { |
| 8019 | switch (encoding) { |
| 8020 | case 'hex': |
| 8021 | return hexSlice(this, start, end) |
| 8022 | |
| 8023 | case 'utf8': |
| 8024 | case 'utf-8': |
| 8025 | return utf8Slice(this, start, end) |
| 8026 | |
| 8027 | case 'ascii': |
| 8028 | return asciiSlice(this, start, end) |
| 8029 | |
| 8030 | case 'binary': |
| 8031 | return binarySlice(this, start, end) |
| 8032 | |
| 8033 | case 'base64': |
| 8034 | return base64Slice(this, start, end) |
| 8035 | |
| 8036 | case 'ucs2': |
| 8037 | case 'ucs-2': |
| 8038 | case 'utf16le': |
| 8039 | case 'utf-16le': |
| 8040 | return utf16leSlice(this, start, end) |
| 8041 | |
| 8042 | default: |
| 8043 | if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) |
| 8044 | encoding = (encoding + '').toLowerCase() |
| 8045 | loweredCase = true |
| 8046 | } |
| 8047 | } |
| 8048 | } |
| 8049 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8050 | Buffer.prototype.toString = function toString () { |
| 8051 | var length = this.length | 0 |
| 8052 | if (length === 0) return '' |
| 8053 | if (arguments.length === 0) return utf8Slice(this, 0, length) |
| 8054 | return slowToString.apply(this, arguments) |
| 8055 | } |
| 8056 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8057 | Buffer.prototype.equals = function equals (b) { |
| 8058 | if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') |
| 8059 | if (this === b) return true |
| 8060 | return Buffer.compare(this, b) === 0 |
| 8061 | } |
| 8062 | |
| 8063 | Buffer.prototype.inspect = function inspect () { |
| 8064 | var str = '' |
| 8065 | var max = exports.INSPECT_MAX_BYTES |
| 8066 | if (this.length > 0) { |
| 8067 | str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') |
| 8068 | if (this.length > max) str += ' ... ' |
| 8069 | } |
| 8070 | return '<Buffer ' + str + '>' |
| 8071 | } |
| 8072 | |
| 8073 | Buffer.prototype.compare = function compare (b) { |
| 8074 | if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') |
| 8075 | if (this === b) return 0 |
| 8076 | return Buffer.compare(this, b) |
| 8077 | } |
| 8078 | |
| 8079 | Buffer.prototype.indexOf = function indexOf (val, byteOffset) { |
| 8080 | if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff |
| 8081 | else if (byteOffset < -0x80000000) byteOffset = -0x80000000 |
| 8082 | byteOffset >>= 0 |
| 8083 | |
| 8084 | if (this.length === 0) return -1 |
| 8085 | if (byteOffset >= this.length) return -1 |
| 8086 | |
| 8087 | // Negative offsets start from the end of the buffer |
| 8088 | if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) |
| 8089 | |
| 8090 | if (typeof val === 'string') { |
| 8091 | if (val.length === 0) return -1 // special case: looking for empty string always fails |
| 8092 | return String.prototype.indexOf.call(this, val, byteOffset) |
| 8093 | } |
| 8094 | if (Buffer.isBuffer(val)) { |
| 8095 | return arrayIndexOf(this, val, byteOffset) |
| 8096 | } |
| 8097 | if (typeof val === 'number') { |
| 8098 | if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { |
| 8099 | return Uint8Array.prototype.indexOf.call(this, val, byteOffset) |
| 8100 | } |
| 8101 | return arrayIndexOf(this, [ val ], byteOffset) |
| 8102 | } |
| 8103 | |
| 8104 | function arrayIndexOf (arr, val, byteOffset) { |
| 8105 | var foundIndex = -1 |
| 8106 | for (var i = 0; byteOffset + i < arr.length; i++) { |
| 8107 | if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { |
| 8108 | if (foundIndex === -1) foundIndex = i |
| 8109 | if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex |
| 8110 | } else { |
| 8111 | foundIndex = -1 |
| 8112 | } |
| 8113 | } |
| 8114 | return -1 |
| 8115 | } |
| 8116 | |
| 8117 | throw new TypeError('val must be string, number or Buffer') |
| 8118 | } |
| 8119 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8120 | // `get` is deprecated |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8121 | Buffer.prototype.get = function get (offset) { |
| 8122 | console.log('.get() is deprecated. Access using array indexes instead.') |
| 8123 | return this.readUInt8(offset) |
| 8124 | } |
| 8125 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8126 | // `set` is deprecated |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8127 | Buffer.prototype.set = function set (v, offset) { |
| 8128 | console.log('.set() is deprecated. Access using array indexes instead.') |
| 8129 | return this.writeUInt8(v, offset) |
| 8130 | } |
| 8131 | |
| 8132 | function hexWrite (buf, string, offset, length) { |
| 8133 | offset = Number(offset) || 0 |
| 8134 | var remaining = buf.length - offset |
| 8135 | if (!length) { |
| 8136 | length = remaining |
| 8137 | } else { |
| 8138 | length = Number(length) |
| 8139 | if (length > remaining) { |
| 8140 | length = remaining |
| 8141 | } |
| 8142 | } |
| 8143 | |
| 8144 | // must be an even number of digits |
| 8145 | var strLen = string.length |
| 8146 | if (strLen % 2 !== 0) throw new Error('Invalid hex string') |
| 8147 | |
| 8148 | if (length > strLen / 2) { |
| 8149 | length = strLen / 2 |
| 8150 | } |
| 8151 | for (var i = 0; i < length; i++) { |
| 8152 | var parsed = parseInt(string.substr(i * 2, 2), 16) |
| 8153 | if (isNaN(parsed)) throw new Error('Invalid hex string') |
| 8154 | buf[offset + i] = parsed |
| 8155 | } |
| 8156 | return i |
| 8157 | } |
| 8158 | |
| 8159 | function utf8Write (buf, string, offset, length) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8160 | return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8161 | } |
| 8162 | |
| 8163 | function asciiWrite (buf, string, offset, length) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8164 | return blitBuffer(asciiToBytes(string), buf, offset, length) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8165 | } |
| 8166 | |
| 8167 | function binaryWrite (buf, string, offset, length) { |
| 8168 | return asciiWrite(buf, string, offset, length) |
| 8169 | } |
| 8170 | |
| 8171 | function base64Write (buf, string, offset, length) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8172 | return blitBuffer(base64ToBytes(string), buf, offset, length) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8173 | } |
| 8174 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8175 | function ucs2Write (buf, string, offset, length) { |
| 8176 | return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8177 | } |
| 8178 | |
| 8179 | Buffer.prototype.write = function write (string, offset, length, encoding) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8180 | // Buffer#write(string) |
| 8181 | if (offset === undefined) { |
| 8182 | encoding = 'utf8' |
| 8183 | length = this.length |
| 8184 | offset = 0 |
| 8185 | // Buffer#write(string, encoding) |
| 8186 | } else if (length === undefined && typeof offset === 'string') { |
| 8187 | encoding = offset |
| 8188 | length = this.length |
| 8189 | offset = 0 |
| 8190 | // Buffer#write(string, offset[, length][, encoding]) |
| 8191 | } else if (isFinite(offset)) { |
| 8192 | offset = offset | 0 |
| 8193 | if (isFinite(length)) { |
| 8194 | length = length | 0 |
| 8195 | if (encoding === undefined) encoding = 'utf8' |
| 8196 | } else { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8197 | encoding = length |
| 8198 | length = undefined |
| 8199 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8200 | // legacy write(string, encoding, offset, length) - remove in v0.13 |
| 8201 | } else { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8202 | var swap = encoding |
| 8203 | encoding = offset |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8204 | offset = length | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8205 | length = swap |
| 8206 | } |
| 8207 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8208 | var remaining = this.length - offset |
| 8209 | if (length === undefined || length > remaining) length = remaining |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8210 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8211 | if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8212 | throw new RangeError('attempt to write outside buffer bounds') |
| 8213 | } |
| 8214 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8215 | if (!encoding) encoding = 'utf8' |
| 8216 | |
| 8217 | var loweredCase = false |
| 8218 | for (;;) { |
| 8219 | switch (encoding) { |
| 8220 | case 'hex': |
| 8221 | return hexWrite(this, string, offset, length) |
| 8222 | |
| 8223 | case 'utf8': |
| 8224 | case 'utf-8': |
| 8225 | return utf8Write(this, string, offset, length) |
| 8226 | |
| 8227 | case 'ascii': |
| 8228 | return asciiWrite(this, string, offset, length) |
| 8229 | |
| 8230 | case 'binary': |
| 8231 | return binaryWrite(this, string, offset, length) |
| 8232 | |
| 8233 | case 'base64': |
| 8234 | // Warning: maxLength not taken into account in base64Write |
| 8235 | return base64Write(this, string, offset, length) |
| 8236 | |
| 8237 | case 'ucs2': |
| 8238 | case 'ucs-2': |
| 8239 | case 'utf16le': |
| 8240 | case 'utf-16le': |
| 8241 | return ucs2Write(this, string, offset, length) |
| 8242 | |
| 8243 | default: |
| 8244 | if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) |
| 8245 | encoding = ('' + encoding).toLowerCase() |
| 8246 | loweredCase = true |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8247 | } |
| 8248 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8249 | } |
| 8250 | |
| 8251 | Buffer.prototype.toJSON = function toJSON () { |
| 8252 | return { |
| 8253 | type: 'Buffer', |
| 8254 | data: Array.prototype.slice.call(this._arr || this, 0) |
| 8255 | } |
| 8256 | } |
| 8257 | |
| 8258 | function base64Slice (buf, start, end) { |
| 8259 | if (start === 0 && end === buf.length) { |
| 8260 | return base64.fromByteArray(buf) |
| 8261 | } else { |
| 8262 | return base64.fromByteArray(buf.slice(start, end)) |
| 8263 | } |
| 8264 | } |
| 8265 | |
| 8266 | function utf8Slice (buf, start, end) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8267 | end = Math.min(buf.length, end) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8268 | var res = [] |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8269 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8270 | var i = start |
| 8271 | while (i < end) { |
| 8272 | var firstByte = buf[i] |
| 8273 | var codePoint = null |
| 8274 | var bytesPerSequence = (firstByte > 0xEF) ? 4 |
| 8275 | : (firstByte > 0xDF) ? 3 |
| 8276 | : (firstByte > 0xBF) ? 2 |
| 8277 | : 1 |
| 8278 | |
| 8279 | if (i + bytesPerSequence <= end) { |
| 8280 | var secondByte, thirdByte, fourthByte, tempCodePoint |
| 8281 | |
| 8282 | switch (bytesPerSequence) { |
| 8283 | case 1: |
| 8284 | if (firstByte < 0x80) { |
| 8285 | codePoint = firstByte |
| 8286 | } |
| 8287 | break |
| 8288 | case 2: |
| 8289 | secondByte = buf[i + 1] |
| 8290 | if ((secondByte & 0xC0) === 0x80) { |
| 8291 | tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) |
| 8292 | if (tempCodePoint > 0x7F) { |
| 8293 | codePoint = tempCodePoint |
| 8294 | } |
| 8295 | } |
| 8296 | break |
| 8297 | case 3: |
| 8298 | secondByte = buf[i + 1] |
| 8299 | thirdByte = buf[i + 2] |
| 8300 | if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { |
| 8301 | tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) |
| 8302 | if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { |
| 8303 | codePoint = tempCodePoint |
| 8304 | } |
| 8305 | } |
| 8306 | break |
| 8307 | case 4: |
| 8308 | secondByte = buf[i + 1] |
| 8309 | thirdByte = buf[i + 2] |
| 8310 | fourthByte = buf[i + 3] |
| 8311 | if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { |
| 8312 | tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) |
| 8313 | if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { |
| 8314 | codePoint = tempCodePoint |
| 8315 | } |
| 8316 | } |
| 8317 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8318 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8319 | |
| 8320 | if (codePoint === null) { |
| 8321 | // we did not generate a valid codePoint so insert a |
| 8322 | // replacement char (U+FFFD) and advance only 1 byte |
| 8323 | codePoint = 0xFFFD |
| 8324 | bytesPerSequence = 1 |
| 8325 | } else if (codePoint > 0xFFFF) { |
| 8326 | // encode to utf16 (surrogate pair dance) |
| 8327 | codePoint -= 0x10000 |
| 8328 | res.push(codePoint >>> 10 & 0x3FF | 0xD800) |
| 8329 | codePoint = 0xDC00 | codePoint & 0x3FF |
| 8330 | } |
| 8331 | |
| 8332 | res.push(codePoint) |
| 8333 | i += bytesPerSequence |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8334 | } |
| 8335 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8336 | return decodeCodePointsArray(res) |
| 8337 | } |
| 8338 | |
| 8339 | // Based on http://stackoverflow.com/a/22747272/680742, the browser with |
| 8340 | // the lowest limit is Chrome, with 0x10000 args. |
| 8341 | // We go 1 magnitude less, for safety |
| 8342 | var MAX_ARGUMENTS_LENGTH = 0x1000 |
| 8343 | |
| 8344 | function decodeCodePointsArray (codePoints) { |
| 8345 | var len = codePoints.length |
| 8346 | if (len <= MAX_ARGUMENTS_LENGTH) { |
| 8347 | return String.fromCharCode.apply(String, codePoints) // avoid extra slice() |
| 8348 | } |
| 8349 | |
| 8350 | // Decode in chunks to avoid "call stack size exceeded". |
| 8351 | var res = '' |
| 8352 | var i = 0 |
| 8353 | while (i < len) { |
| 8354 | res += String.fromCharCode.apply( |
| 8355 | String, |
| 8356 | codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) |
| 8357 | ) |
| 8358 | } |
| 8359 | return res |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8360 | } |
| 8361 | |
| 8362 | function asciiSlice (buf, start, end) { |
| 8363 | var ret = '' |
| 8364 | end = Math.min(buf.length, end) |
| 8365 | |
| 8366 | for (var i = start; i < end; i++) { |
| 8367 | ret += String.fromCharCode(buf[i] & 0x7F) |
| 8368 | } |
| 8369 | return ret |
| 8370 | } |
| 8371 | |
| 8372 | function binarySlice (buf, start, end) { |
| 8373 | var ret = '' |
| 8374 | end = Math.min(buf.length, end) |
| 8375 | |
| 8376 | for (var i = start; i < end; i++) { |
| 8377 | ret += String.fromCharCode(buf[i]) |
| 8378 | } |
| 8379 | return ret |
| 8380 | } |
| 8381 | |
| 8382 | function hexSlice (buf, start, end) { |
| 8383 | var len = buf.length |
| 8384 | |
| 8385 | if (!start || start < 0) start = 0 |
| 8386 | if (!end || end < 0 || end > len) end = len |
| 8387 | |
| 8388 | var out = '' |
| 8389 | for (var i = start; i < end; i++) { |
| 8390 | out += toHex(buf[i]) |
| 8391 | } |
| 8392 | return out |
| 8393 | } |
| 8394 | |
| 8395 | function utf16leSlice (buf, start, end) { |
| 8396 | var bytes = buf.slice(start, end) |
| 8397 | var res = '' |
| 8398 | for (var i = 0; i < bytes.length; i += 2) { |
| 8399 | res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) |
| 8400 | } |
| 8401 | return res |
| 8402 | } |
| 8403 | |
| 8404 | Buffer.prototype.slice = function slice (start, end) { |
| 8405 | var len = this.length |
| 8406 | start = ~~start |
| 8407 | end = end === undefined ? len : ~~end |
| 8408 | |
| 8409 | if (start < 0) { |
| 8410 | start += len |
| 8411 | if (start < 0) start = 0 |
| 8412 | } else if (start > len) { |
| 8413 | start = len |
| 8414 | } |
| 8415 | |
| 8416 | if (end < 0) { |
| 8417 | end += len |
| 8418 | if (end < 0) end = 0 |
| 8419 | } else if (end > len) { |
| 8420 | end = len |
| 8421 | } |
| 8422 | |
| 8423 | if (end < start) end = start |
| 8424 | |
| 8425 | var newBuf |
| 8426 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 8427 | newBuf = Buffer._augment(this.subarray(start, end)) |
| 8428 | } else { |
| 8429 | var sliceLen = end - start |
| 8430 | newBuf = new Buffer(sliceLen, undefined) |
| 8431 | for (var i = 0; i < sliceLen; i++) { |
| 8432 | newBuf[i] = this[i + start] |
| 8433 | } |
| 8434 | } |
| 8435 | |
| 8436 | if (newBuf.length) newBuf.parent = this.parent || this |
| 8437 | |
| 8438 | return newBuf |
| 8439 | } |
| 8440 | |
| 8441 | /* |
| 8442 | * Need to make sure that buffer isn't trying to write out of bounds. |
| 8443 | */ |
| 8444 | function checkOffset (offset, ext, length) { |
| 8445 | if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') |
| 8446 | if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') |
| 8447 | } |
| 8448 | |
| 8449 | Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8450 | offset = offset | 0 |
| 8451 | byteLength = byteLength | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8452 | if (!noAssert) checkOffset(offset, byteLength, this.length) |
| 8453 | |
| 8454 | var val = this[offset] |
| 8455 | var mul = 1 |
| 8456 | var i = 0 |
| 8457 | while (++i < byteLength && (mul *= 0x100)) { |
| 8458 | val += this[offset + i] * mul |
| 8459 | } |
| 8460 | |
| 8461 | return val |
| 8462 | } |
| 8463 | |
| 8464 | Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8465 | offset = offset | 0 |
| 8466 | byteLength = byteLength | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8467 | if (!noAssert) { |
| 8468 | checkOffset(offset, byteLength, this.length) |
| 8469 | } |
| 8470 | |
| 8471 | var val = this[offset + --byteLength] |
| 8472 | var mul = 1 |
| 8473 | while (byteLength > 0 && (mul *= 0x100)) { |
| 8474 | val += this[offset + --byteLength] * mul |
| 8475 | } |
| 8476 | |
| 8477 | return val |
| 8478 | } |
| 8479 | |
| 8480 | Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { |
| 8481 | if (!noAssert) checkOffset(offset, 1, this.length) |
| 8482 | return this[offset] |
| 8483 | } |
| 8484 | |
| 8485 | Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { |
| 8486 | if (!noAssert) checkOffset(offset, 2, this.length) |
| 8487 | return this[offset] | (this[offset + 1] << 8) |
| 8488 | } |
| 8489 | |
| 8490 | Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { |
| 8491 | if (!noAssert) checkOffset(offset, 2, this.length) |
| 8492 | return (this[offset] << 8) | this[offset + 1] |
| 8493 | } |
| 8494 | |
| 8495 | Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { |
| 8496 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 8497 | |
| 8498 | return ((this[offset]) | |
| 8499 | (this[offset + 1] << 8) | |
| 8500 | (this[offset + 2] << 16)) + |
| 8501 | (this[offset + 3] * 0x1000000) |
| 8502 | } |
| 8503 | |
| 8504 | Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { |
| 8505 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 8506 | |
| 8507 | return (this[offset] * 0x1000000) + |
| 8508 | ((this[offset + 1] << 16) | |
| 8509 | (this[offset + 2] << 8) | |
| 8510 | this[offset + 3]) |
| 8511 | } |
| 8512 | |
| 8513 | Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8514 | offset = offset | 0 |
| 8515 | byteLength = byteLength | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8516 | if (!noAssert) checkOffset(offset, byteLength, this.length) |
| 8517 | |
| 8518 | var val = this[offset] |
| 8519 | var mul = 1 |
| 8520 | var i = 0 |
| 8521 | while (++i < byteLength && (mul *= 0x100)) { |
| 8522 | val += this[offset + i] * mul |
| 8523 | } |
| 8524 | mul *= 0x80 |
| 8525 | |
| 8526 | if (val >= mul) val -= Math.pow(2, 8 * byteLength) |
| 8527 | |
| 8528 | return val |
| 8529 | } |
| 8530 | |
| 8531 | Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8532 | offset = offset | 0 |
| 8533 | byteLength = byteLength | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8534 | if (!noAssert) checkOffset(offset, byteLength, this.length) |
| 8535 | |
| 8536 | var i = byteLength |
| 8537 | var mul = 1 |
| 8538 | var val = this[offset + --i] |
| 8539 | while (i > 0 && (mul *= 0x100)) { |
| 8540 | val += this[offset + --i] * mul |
| 8541 | } |
| 8542 | mul *= 0x80 |
| 8543 | |
| 8544 | if (val >= mul) val -= Math.pow(2, 8 * byteLength) |
| 8545 | |
| 8546 | return val |
| 8547 | } |
| 8548 | |
| 8549 | Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { |
| 8550 | if (!noAssert) checkOffset(offset, 1, this.length) |
| 8551 | if (!(this[offset] & 0x80)) return (this[offset]) |
| 8552 | return ((0xff - this[offset] + 1) * -1) |
| 8553 | } |
| 8554 | |
| 8555 | Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { |
| 8556 | if (!noAssert) checkOffset(offset, 2, this.length) |
| 8557 | var val = this[offset] | (this[offset + 1] << 8) |
| 8558 | return (val & 0x8000) ? val | 0xFFFF0000 : val |
| 8559 | } |
| 8560 | |
| 8561 | Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { |
| 8562 | if (!noAssert) checkOffset(offset, 2, this.length) |
| 8563 | var val = this[offset + 1] | (this[offset] << 8) |
| 8564 | return (val & 0x8000) ? val | 0xFFFF0000 : val |
| 8565 | } |
| 8566 | |
| 8567 | Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { |
| 8568 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 8569 | |
| 8570 | return (this[offset]) | |
| 8571 | (this[offset + 1] << 8) | |
| 8572 | (this[offset + 2] << 16) | |
| 8573 | (this[offset + 3] << 24) |
| 8574 | } |
| 8575 | |
| 8576 | Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { |
| 8577 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 8578 | |
| 8579 | return (this[offset] << 24) | |
| 8580 | (this[offset + 1] << 16) | |
| 8581 | (this[offset + 2] << 8) | |
| 8582 | (this[offset + 3]) |
| 8583 | } |
| 8584 | |
| 8585 | Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { |
| 8586 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 8587 | return ieee754.read(this, offset, true, 23, 4) |
| 8588 | } |
| 8589 | |
| 8590 | Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { |
| 8591 | if (!noAssert) checkOffset(offset, 4, this.length) |
| 8592 | return ieee754.read(this, offset, false, 23, 4) |
| 8593 | } |
| 8594 | |
| 8595 | Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { |
| 8596 | if (!noAssert) checkOffset(offset, 8, this.length) |
| 8597 | return ieee754.read(this, offset, true, 52, 8) |
| 8598 | } |
| 8599 | |
| 8600 | Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { |
| 8601 | if (!noAssert) checkOffset(offset, 8, this.length) |
| 8602 | return ieee754.read(this, offset, false, 52, 8) |
| 8603 | } |
| 8604 | |
| 8605 | function checkInt (buf, value, offset, ext, max, min) { |
| 8606 | if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') |
| 8607 | if (value > max || value < min) throw new RangeError('value is out of bounds') |
| 8608 | if (offset + ext > buf.length) throw new RangeError('index out of range') |
| 8609 | } |
| 8610 | |
| 8611 | Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { |
| 8612 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8613 | offset = offset | 0 |
| 8614 | byteLength = byteLength | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8615 | if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) |
| 8616 | |
| 8617 | var mul = 1 |
| 8618 | var i = 0 |
| 8619 | this[offset] = value & 0xFF |
| 8620 | while (++i < byteLength && (mul *= 0x100)) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8621 | this[offset + i] = (value / mul) & 0xFF |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8622 | } |
| 8623 | |
| 8624 | return offset + byteLength |
| 8625 | } |
| 8626 | |
| 8627 | Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { |
| 8628 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8629 | offset = offset | 0 |
| 8630 | byteLength = byteLength | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8631 | if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) |
| 8632 | |
| 8633 | var i = byteLength - 1 |
| 8634 | var mul = 1 |
| 8635 | this[offset + i] = value & 0xFF |
| 8636 | while (--i >= 0 && (mul *= 0x100)) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8637 | this[offset + i] = (value / mul) & 0xFF |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8638 | } |
| 8639 | |
| 8640 | return offset + byteLength |
| 8641 | } |
| 8642 | |
| 8643 | Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { |
| 8644 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8645 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8646 | if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) |
| 8647 | if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) |
| 8648 | this[offset] = value |
| 8649 | return offset + 1 |
| 8650 | } |
| 8651 | |
| 8652 | function objectWriteUInt16 (buf, value, offset, littleEndian) { |
| 8653 | if (value < 0) value = 0xffff + value + 1 |
| 8654 | for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { |
| 8655 | buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> |
| 8656 | (littleEndian ? i : 1 - i) * 8 |
| 8657 | } |
| 8658 | } |
| 8659 | |
| 8660 | Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { |
| 8661 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8662 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8663 | if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) |
| 8664 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 8665 | this[offset] = value |
| 8666 | this[offset + 1] = (value >>> 8) |
| 8667 | } else { |
| 8668 | objectWriteUInt16(this, value, offset, true) |
| 8669 | } |
| 8670 | return offset + 2 |
| 8671 | } |
| 8672 | |
| 8673 | Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { |
| 8674 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8675 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8676 | if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) |
| 8677 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 8678 | this[offset] = (value >>> 8) |
| 8679 | this[offset + 1] = value |
| 8680 | } else { |
| 8681 | objectWriteUInt16(this, value, offset, false) |
| 8682 | } |
| 8683 | return offset + 2 |
| 8684 | } |
| 8685 | |
| 8686 | function objectWriteUInt32 (buf, value, offset, littleEndian) { |
| 8687 | if (value < 0) value = 0xffffffff + value + 1 |
| 8688 | for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { |
| 8689 | buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff |
| 8690 | } |
| 8691 | } |
| 8692 | |
| 8693 | Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { |
| 8694 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8695 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8696 | if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) |
| 8697 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 8698 | this[offset + 3] = (value >>> 24) |
| 8699 | this[offset + 2] = (value >>> 16) |
| 8700 | this[offset + 1] = (value >>> 8) |
| 8701 | this[offset] = value |
| 8702 | } else { |
| 8703 | objectWriteUInt32(this, value, offset, true) |
| 8704 | } |
| 8705 | return offset + 4 |
| 8706 | } |
| 8707 | |
| 8708 | Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { |
| 8709 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8710 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8711 | if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) |
| 8712 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 8713 | this[offset] = (value >>> 24) |
| 8714 | this[offset + 1] = (value >>> 16) |
| 8715 | this[offset + 2] = (value >>> 8) |
| 8716 | this[offset + 3] = value |
| 8717 | } else { |
| 8718 | objectWriteUInt32(this, value, offset, false) |
| 8719 | } |
| 8720 | return offset + 4 |
| 8721 | } |
| 8722 | |
| 8723 | Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { |
| 8724 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8725 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8726 | if (!noAssert) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8727 | var limit = Math.pow(2, 8 * byteLength - 1) |
| 8728 | |
| 8729 | checkInt(this, value, offset, byteLength, limit - 1, -limit) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8730 | } |
| 8731 | |
| 8732 | var i = 0 |
| 8733 | var mul = 1 |
| 8734 | var sub = value < 0 ? 1 : 0 |
| 8735 | this[offset] = value & 0xFF |
| 8736 | while (++i < byteLength && (mul *= 0x100)) { |
| 8737 | this[offset + i] = ((value / mul) >> 0) - sub & 0xFF |
| 8738 | } |
| 8739 | |
| 8740 | return offset + byteLength |
| 8741 | } |
| 8742 | |
| 8743 | Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { |
| 8744 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8745 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8746 | if (!noAssert) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8747 | var limit = Math.pow(2, 8 * byteLength - 1) |
| 8748 | |
| 8749 | checkInt(this, value, offset, byteLength, limit - 1, -limit) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8750 | } |
| 8751 | |
| 8752 | var i = byteLength - 1 |
| 8753 | var mul = 1 |
| 8754 | var sub = value < 0 ? 1 : 0 |
| 8755 | this[offset + i] = value & 0xFF |
| 8756 | while (--i >= 0 && (mul *= 0x100)) { |
| 8757 | this[offset + i] = ((value / mul) >> 0) - sub & 0xFF |
| 8758 | } |
| 8759 | |
| 8760 | return offset + byteLength |
| 8761 | } |
| 8762 | |
| 8763 | Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { |
| 8764 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8765 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8766 | if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) |
| 8767 | if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) |
| 8768 | if (value < 0) value = 0xff + value + 1 |
| 8769 | this[offset] = value |
| 8770 | return offset + 1 |
| 8771 | } |
| 8772 | |
| 8773 | Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { |
| 8774 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8775 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8776 | if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) |
| 8777 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 8778 | this[offset] = value |
| 8779 | this[offset + 1] = (value >>> 8) |
| 8780 | } else { |
| 8781 | objectWriteUInt16(this, value, offset, true) |
| 8782 | } |
| 8783 | return offset + 2 |
| 8784 | } |
| 8785 | |
| 8786 | Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { |
| 8787 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8788 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8789 | if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) |
| 8790 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 8791 | this[offset] = (value >>> 8) |
| 8792 | this[offset + 1] = value |
| 8793 | } else { |
| 8794 | objectWriteUInt16(this, value, offset, false) |
| 8795 | } |
| 8796 | return offset + 2 |
| 8797 | } |
| 8798 | |
| 8799 | Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { |
| 8800 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8801 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8802 | if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) |
| 8803 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 8804 | this[offset] = value |
| 8805 | this[offset + 1] = (value >>> 8) |
| 8806 | this[offset + 2] = (value >>> 16) |
| 8807 | this[offset + 3] = (value >>> 24) |
| 8808 | } else { |
| 8809 | objectWriteUInt32(this, value, offset, true) |
| 8810 | } |
| 8811 | return offset + 4 |
| 8812 | } |
| 8813 | |
| 8814 | Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { |
| 8815 | value = +value |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8816 | offset = offset | 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8817 | if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) |
| 8818 | if (value < 0) value = 0xffffffff + value + 1 |
| 8819 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 8820 | this[offset] = (value >>> 24) |
| 8821 | this[offset + 1] = (value >>> 16) |
| 8822 | this[offset + 2] = (value >>> 8) |
| 8823 | this[offset + 3] = value |
| 8824 | } else { |
| 8825 | objectWriteUInt32(this, value, offset, false) |
| 8826 | } |
| 8827 | return offset + 4 |
| 8828 | } |
| 8829 | |
| 8830 | function checkIEEE754 (buf, value, offset, ext, max, min) { |
| 8831 | if (value > max || value < min) throw new RangeError('value is out of bounds') |
| 8832 | if (offset + ext > buf.length) throw new RangeError('index out of range') |
| 8833 | if (offset < 0) throw new RangeError('index out of range') |
| 8834 | } |
| 8835 | |
| 8836 | function writeFloat (buf, value, offset, littleEndian, noAssert) { |
| 8837 | if (!noAssert) { |
| 8838 | checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) |
| 8839 | } |
| 8840 | ieee754.write(buf, value, offset, littleEndian, 23, 4) |
| 8841 | return offset + 4 |
| 8842 | } |
| 8843 | |
| 8844 | Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { |
| 8845 | return writeFloat(this, value, offset, true, noAssert) |
| 8846 | } |
| 8847 | |
| 8848 | Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { |
| 8849 | return writeFloat(this, value, offset, false, noAssert) |
| 8850 | } |
| 8851 | |
| 8852 | function writeDouble (buf, value, offset, littleEndian, noAssert) { |
| 8853 | if (!noAssert) { |
| 8854 | checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) |
| 8855 | } |
| 8856 | ieee754.write(buf, value, offset, littleEndian, 52, 8) |
| 8857 | return offset + 8 |
| 8858 | } |
| 8859 | |
| 8860 | Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { |
| 8861 | return writeDouble(this, value, offset, true, noAssert) |
| 8862 | } |
| 8863 | |
| 8864 | Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { |
| 8865 | return writeDouble(this, value, offset, false, noAssert) |
| 8866 | } |
| 8867 | |
| 8868 | // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8869 | Buffer.prototype.copy = function copy (target, targetStart, start, end) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8870 | if (!start) start = 0 |
| 8871 | if (!end && end !== 0) end = this.length |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8872 | if (targetStart >= target.length) targetStart = target.length |
| 8873 | if (!targetStart) targetStart = 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8874 | if (end > 0 && end < start) end = start |
| 8875 | |
| 8876 | // Copy 0 bytes; we're done |
| 8877 | if (end === start) return 0 |
| 8878 | if (target.length === 0 || this.length === 0) return 0 |
| 8879 | |
| 8880 | // Fatal error conditions |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8881 | if (targetStart < 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8882 | throw new RangeError('targetStart out of bounds') |
| 8883 | } |
| 8884 | if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') |
| 8885 | if (end < 0) throw new RangeError('sourceEnd out of bounds') |
| 8886 | |
| 8887 | // Are we oob? |
| 8888 | if (end > this.length) end = this.length |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8889 | if (target.length - targetStart < end - start) { |
| 8890 | end = target.length - targetStart + start |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8891 | } |
| 8892 | |
| 8893 | var len = end - start |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8894 | var i |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8895 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8896 | if (this === target && start < targetStart && targetStart < end) { |
| 8897 | // descending copy from end |
| 8898 | for (i = len - 1; i >= 0; i--) { |
| 8899 | target[i + targetStart] = this[i + start] |
| 8900 | } |
| 8901 | } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { |
| 8902 | // ascending copy from start |
| 8903 | for (i = 0; i < len; i++) { |
| 8904 | target[i + targetStart] = this[i + start] |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8905 | } |
| 8906 | } else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8907 | target._set(this.subarray(start, start + len), targetStart) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8908 | } |
| 8909 | |
| 8910 | return len |
| 8911 | } |
| 8912 | |
| 8913 | // fill(value, start=0, end=buffer.length) |
| 8914 | Buffer.prototype.fill = function fill (value, start, end) { |
| 8915 | if (!value) value = 0 |
| 8916 | if (!start) start = 0 |
| 8917 | if (!end) end = this.length |
| 8918 | |
| 8919 | if (end < start) throw new RangeError('end < start') |
| 8920 | |
| 8921 | // Fill 0 bytes; we're done |
| 8922 | if (end === start) return |
| 8923 | if (this.length === 0) return |
| 8924 | |
| 8925 | if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') |
| 8926 | if (end < 0 || end > this.length) throw new RangeError('end out of bounds') |
| 8927 | |
| 8928 | var i |
| 8929 | if (typeof value === 'number') { |
| 8930 | for (i = start; i < end; i++) { |
| 8931 | this[i] = value |
| 8932 | } |
| 8933 | } else { |
| 8934 | var bytes = utf8ToBytes(value.toString()) |
| 8935 | var len = bytes.length |
| 8936 | for (i = start; i < end; i++) { |
| 8937 | this[i] = bytes[i % len] |
| 8938 | } |
| 8939 | } |
| 8940 | |
| 8941 | return this |
| 8942 | } |
| 8943 | |
| 8944 | /** |
| 8945 | * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. |
| 8946 | * Added in Node 0.12. Only available in browsers that support ArrayBuffer. |
| 8947 | */ |
| 8948 | Buffer.prototype.toArrayBuffer = function toArrayBuffer () { |
| 8949 | if (typeof Uint8Array !== 'undefined') { |
| 8950 | if (Buffer.TYPED_ARRAY_SUPPORT) { |
| 8951 | return (new Buffer(this)).buffer |
| 8952 | } else { |
| 8953 | var buf = new Uint8Array(this.length) |
| 8954 | for (var i = 0, len = buf.length; i < len; i += 1) { |
| 8955 | buf[i] = this[i] |
| 8956 | } |
| 8957 | return buf.buffer |
| 8958 | } |
| 8959 | } else { |
| 8960 | throw new TypeError('Buffer.toArrayBuffer not supported in this browser') |
| 8961 | } |
| 8962 | } |
| 8963 | |
| 8964 | // HELPER FUNCTIONS |
| 8965 | // ================ |
| 8966 | |
| 8967 | var BP = Buffer.prototype |
| 8968 | |
| 8969 | /** |
| 8970 | * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods |
| 8971 | */ |
| 8972 | Buffer._augment = function _augment (arr) { |
| 8973 | arr.constructor = Buffer |
| 8974 | arr._isBuffer = true |
| 8975 | |
| 8976 | // save reference to original Uint8Array set method before overwriting |
| 8977 | arr._set = arr.set |
| 8978 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 8979 | // deprecated |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 8980 | arr.get = BP.get |
| 8981 | arr.set = BP.set |
| 8982 | |
| 8983 | arr.write = BP.write |
| 8984 | arr.toString = BP.toString |
| 8985 | arr.toLocaleString = BP.toString |
| 8986 | arr.toJSON = BP.toJSON |
| 8987 | arr.equals = BP.equals |
| 8988 | arr.compare = BP.compare |
| 8989 | arr.indexOf = BP.indexOf |
| 8990 | arr.copy = BP.copy |
| 8991 | arr.slice = BP.slice |
| 8992 | arr.readUIntLE = BP.readUIntLE |
| 8993 | arr.readUIntBE = BP.readUIntBE |
| 8994 | arr.readUInt8 = BP.readUInt8 |
| 8995 | arr.readUInt16LE = BP.readUInt16LE |
| 8996 | arr.readUInt16BE = BP.readUInt16BE |
| 8997 | arr.readUInt32LE = BP.readUInt32LE |
| 8998 | arr.readUInt32BE = BP.readUInt32BE |
| 8999 | arr.readIntLE = BP.readIntLE |
| 9000 | arr.readIntBE = BP.readIntBE |
| 9001 | arr.readInt8 = BP.readInt8 |
| 9002 | arr.readInt16LE = BP.readInt16LE |
| 9003 | arr.readInt16BE = BP.readInt16BE |
| 9004 | arr.readInt32LE = BP.readInt32LE |
| 9005 | arr.readInt32BE = BP.readInt32BE |
| 9006 | arr.readFloatLE = BP.readFloatLE |
| 9007 | arr.readFloatBE = BP.readFloatBE |
| 9008 | arr.readDoubleLE = BP.readDoubleLE |
| 9009 | arr.readDoubleBE = BP.readDoubleBE |
| 9010 | arr.writeUInt8 = BP.writeUInt8 |
| 9011 | arr.writeUIntLE = BP.writeUIntLE |
| 9012 | arr.writeUIntBE = BP.writeUIntBE |
| 9013 | arr.writeUInt16LE = BP.writeUInt16LE |
| 9014 | arr.writeUInt16BE = BP.writeUInt16BE |
| 9015 | arr.writeUInt32LE = BP.writeUInt32LE |
| 9016 | arr.writeUInt32BE = BP.writeUInt32BE |
| 9017 | arr.writeIntLE = BP.writeIntLE |
| 9018 | arr.writeIntBE = BP.writeIntBE |
| 9019 | arr.writeInt8 = BP.writeInt8 |
| 9020 | arr.writeInt16LE = BP.writeInt16LE |
| 9021 | arr.writeInt16BE = BP.writeInt16BE |
| 9022 | arr.writeInt32LE = BP.writeInt32LE |
| 9023 | arr.writeInt32BE = BP.writeInt32BE |
| 9024 | arr.writeFloatLE = BP.writeFloatLE |
| 9025 | arr.writeFloatBE = BP.writeFloatBE |
| 9026 | arr.writeDoubleLE = BP.writeDoubleLE |
| 9027 | arr.writeDoubleBE = BP.writeDoubleBE |
| 9028 | arr.fill = BP.fill |
| 9029 | arr.inspect = BP.inspect |
| 9030 | arr.toArrayBuffer = BP.toArrayBuffer |
| 9031 | |
| 9032 | return arr |
| 9033 | } |
| 9034 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9035 | var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9036 | |
| 9037 | function base64clean (str) { |
| 9038 | // Node strips out invalid characters like \n and \t from the string, base64-js does not |
| 9039 | str = stringtrim(str).replace(INVALID_BASE64_RE, '') |
| 9040 | // Node converts strings with length < 2 to '' |
| 9041 | if (str.length < 2) return '' |
| 9042 | // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not |
| 9043 | while (str.length % 4 !== 0) { |
| 9044 | str = str + '=' |
| 9045 | } |
| 9046 | return str |
| 9047 | } |
| 9048 | |
| 9049 | function stringtrim (str) { |
| 9050 | if (str.trim) return str.trim() |
| 9051 | return str.replace(/^\s+|\s+$/g, '') |
| 9052 | } |
| 9053 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9054 | function toHex (n) { |
| 9055 | if (n < 16) return '0' + n.toString(16) |
| 9056 | return n.toString(16) |
| 9057 | } |
| 9058 | |
| 9059 | function utf8ToBytes (string, units) { |
| 9060 | units = units || Infinity |
| 9061 | var codePoint |
| 9062 | var length = string.length |
| 9063 | var leadSurrogate = null |
| 9064 | var bytes = [] |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9065 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9066 | for (var i = 0; i < length; i++) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9067 | codePoint = string.charCodeAt(i) |
| 9068 | |
| 9069 | // is surrogate component |
| 9070 | if (codePoint > 0xD7FF && codePoint < 0xE000) { |
| 9071 | // last char was a lead |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9072 | if (!leadSurrogate) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9073 | // no lead yet |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9074 | if (codePoint > 0xDBFF) { |
| 9075 | // unexpected trail |
| 9076 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| 9077 | continue |
| 9078 | } else if (i + 1 === length) { |
| 9079 | // unpaired lead |
| 9080 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| 9081 | continue |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9082 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9083 | |
| 9084 | // valid lead |
| 9085 | leadSurrogate = codePoint |
| 9086 | |
| 9087 | continue |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9088 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9089 | |
| 9090 | // 2 leads in a row |
| 9091 | if (codePoint < 0xDC00) { |
| 9092 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
| 9093 | leadSurrogate = codePoint |
| 9094 | continue |
| 9095 | } |
| 9096 | |
| 9097 | // valid surrogate pair |
| 9098 | codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9099 | } else if (leadSurrogate) { |
| 9100 | // valid bmp char, but last char was a lead |
| 9101 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9102 | } |
| 9103 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9104 | leadSurrogate = null |
| 9105 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9106 | // encode utf8 |
| 9107 | if (codePoint < 0x80) { |
| 9108 | if ((units -= 1) < 0) break |
| 9109 | bytes.push(codePoint) |
| 9110 | } else if (codePoint < 0x800) { |
| 9111 | if ((units -= 2) < 0) break |
| 9112 | bytes.push( |
| 9113 | codePoint >> 0x6 | 0xC0, |
| 9114 | codePoint & 0x3F | 0x80 |
| 9115 | ) |
| 9116 | } else if (codePoint < 0x10000) { |
| 9117 | if ((units -= 3) < 0) break |
| 9118 | bytes.push( |
| 9119 | codePoint >> 0xC | 0xE0, |
| 9120 | codePoint >> 0x6 & 0x3F | 0x80, |
| 9121 | codePoint & 0x3F | 0x80 |
| 9122 | ) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9123 | } else if (codePoint < 0x110000) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9124 | if ((units -= 4) < 0) break |
| 9125 | bytes.push( |
| 9126 | codePoint >> 0x12 | 0xF0, |
| 9127 | codePoint >> 0xC & 0x3F | 0x80, |
| 9128 | codePoint >> 0x6 & 0x3F | 0x80, |
| 9129 | codePoint & 0x3F | 0x80 |
| 9130 | ) |
| 9131 | } else { |
| 9132 | throw new Error('Invalid code point') |
| 9133 | } |
| 9134 | } |
| 9135 | |
| 9136 | return bytes |
| 9137 | } |
| 9138 | |
| 9139 | function asciiToBytes (str) { |
| 9140 | var byteArray = [] |
| 9141 | for (var i = 0; i < str.length; i++) { |
| 9142 | // Node's code seems to be doing this and not & 0x7F.. |
| 9143 | byteArray.push(str.charCodeAt(i) & 0xFF) |
| 9144 | } |
| 9145 | return byteArray |
| 9146 | } |
| 9147 | |
| 9148 | function utf16leToBytes (str, units) { |
| 9149 | var c, hi, lo |
| 9150 | var byteArray = [] |
| 9151 | for (var i = 0; i < str.length; i++) { |
| 9152 | if ((units -= 2) < 0) break |
| 9153 | |
| 9154 | c = str.charCodeAt(i) |
| 9155 | hi = c >> 8 |
| 9156 | lo = c % 256 |
| 9157 | byteArray.push(lo) |
| 9158 | byteArray.push(hi) |
| 9159 | } |
| 9160 | |
| 9161 | return byteArray |
| 9162 | } |
| 9163 | |
| 9164 | function base64ToBytes (str) { |
| 9165 | return base64.toByteArray(base64clean(str)) |
| 9166 | } |
| 9167 | |
| 9168 | function blitBuffer (src, dst, offset, length) { |
| 9169 | for (var i = 0; i < length; i++) { |
| 9170 | if ((i + offset >= dst.length) || (i >= src.length)) break |
| 9171 | dst[i + offset] = src[i] |
| 9172 | } |
| 9173 | return i |
| 9174 | } |
| 9175 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9176 | },{"base64-js":15,"ieee754":16,"is-array":17}],15:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9177 | var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; |
| 9178 | |
| 9179 | ;(function (exports) { |
| 9180 | 'use strict'; |
| 9181 | |
| 9182 | var Arr = (typeof Uint8Array !== 'undefined') |
| 9183 | ? Uint8Array |
| 9184 | : Array |
| 9185 | |
| 9186 | var PLUS = '+'.charCodeAt(0) |
| 9187 | var SLASH = '/'.charCodeAt(0) |
| 9188 | var NUMBER = '0'.charCodeAt(0) |
| 9189 | var LOWER = 'a'.charCodeAt(0) |
| 9190 | var UPPER = 'A'.charCodeAt(0) |
| 9191 | var PLUS_URL_SAFE = '-'.charCodeAt(0) |
| 9192 | var SLASH_URL_SAFE = '_'.charCodeAt(0) |
| 9193 | |
| 9194 | function decode (elt) { |
| 9195 | var code = elt.charCodeAt(0) |
| 9196 | if (code === PLUS || |
| 9197 | code === PLUS_URL_SAFE) |
| 9198 | return 62 // '+' |
| 9199 | if (code === SLASH || |
| 9200 | code === SLASH_URL_SAFE) |
| 9201 | return 63 // '/' |
| 9202 | if (code < NUMBER) |
| 9203 | return -1 //no match |
| 9204 | if (code < NUMBER + 10) |
| 9205 | return code - NUMBER + 26 + 26 |
| 9206 | if (code < UPPER + 26) |
| 9207 | return code - UPPER |
| 9208 | if (code < LOWER + 26) |
| 9209 | return code - LOWER + 26 |
| 9210 | } |
| 9211 | |
| 9212 | function b64ToByteArray (b64) { |
| 9213 | var i, j, l, tmp, placeHolders, arr |
| 9214 | |
| 9215 | if (b64.length % 4 > 0) { |
| 9216 | throw new Error('Invalid string. Length must be a multiple of 4') |
| 9217 | } |
| 9218 | |
| 9219 | // the number of equal signs (place holders) |
| 9220 | // if there are two placeholders, than the two characters before it |
| 9221 | // represent one byte |
| 9222 | // if there is only one, then the three characters before it represent 2 bytes |
| 9223 | // this is just a cheap hack to not do indexOf twice |
| 9224 | var len = b64.length |
| 9225 | placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 |
| 9226 | |
| 9227 | // base64 is 4/3 + up to two characters of the original data |
| 9228 | arr = new Arr(b64.length * 3 / 4 - placeHolders) |
| 9229 | |
| 9230 | // if there are placeholders, only get up to the last complete 4 chars |
| 9231 | l = placeHolders > 0 ? b64.length - 4 : b64.length |
| 9232 | |
| 9233 | var L = 0 |
| 9234 | |
| 9235 | function push (v) { |
| 9236 | arr[L++] = v |
| 9237 | } |
| 9238 | |
| 9239 | for (i = 0, j = 0; i < l; i += 4, j += 3) { |
| 9240 | tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) |
| 9241 | push((tmp & 0xFF0000) >> 16) |
| 9242 | push((tmp & 0xFF00) >> 8) |
| 9243 | push(tmp & 0xFF) |
| 9244 | } |
| 9245 | |
| 9246 | if (placeHolders === 2) { |
| 9247 | tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) |
| 9248 | push(tmp & 0xFF) |
| 9249 | } else if (placeHolders === 1) { |
| 9250 | tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) |
| 9251 | push((tmp >> 8) & 0xFF) |
| 9252 | push(tmp & 0xFF) |
| 9253 | } |
| 9254 | |
| 9255 | return arr |
| 9256 | } |
| 9257 | |
| 9258 | function uint8ToBase64 (uint8) { |
| 9259 | var i, |
| 9260 | extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes |
| 9261 | output = "", |
| 9262 | temp, length |
| 9263 | |
| 9264 | function encode (num) { |
| 9265 | return lookup.charAt(num) |
| 9266 | } |
| 9267 | |
| 9268 | function tripletToBase64 (num) { |
| 9269 | return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) |
| 9270 | } |
| 9271 | |
| 9272 | // go through the array every three bytes, we'll deal with trailing stuff later |
| 9273 | for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { |
| 9274 | temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) |
| 9275 | output += tripletToBase64(temp) |
| 9276 | } |
| 9277 | |
| 9278 | // pad the end with zeros, but make sure to not forget the extra bytes |
| 9279 | switch (extraBytes) { |
| 9280 | case 1: |
| 9281 | temp = uint8[uint8.length - 1] |
| 9282 | output += encode(temp >> 2) |
| 9283 | output += encode((temp << 4) & 0x3F) |
| 9284 | output += '==' |
| 9285 | break |
| 9286 | case 2: |
| 9287 | temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) |
| 9288 | output += encode(temp >> 10) |
| 9289 | output += encode((temp >> 4) & 0x3F) |
| 9290 | output += encode((temp << 2) & 0x3F) |
| 9291 | output += '=' |
| 9292 | break |
| 9293 | } |
| 9294 | |
| 9295 | return output |
| 9296 | } |
| 9297 | |
| 9298 | exports.toByteArray = b64ToByteArray |
| 9299 | exports.fromByteArray = uint8ToBase64 |
| 9300 | }(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) |
| 9301 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9302 | },{}],16:[function(require,module,exports){ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9303 | exports.read = function (buffer, offset, isLE, mLen, nBytes) { |
| 9304 | var e, m |
| 9305 | var eLen = nBytes * 8 - mLen - 1 |
| 9306 | var eMax = (1 << eLen) - 1 |
| 9307 | var eBias = eMax >> 1 |
| 9308 | var nBits = -7 |
| 9309 | var i = isLE ? (nBytes - 1) : 0 |
| 9310 | var d = isLE ? -1 : 1 |
| 9311 | var s = buffer[offset + i] |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9312 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9313 | i += d |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9314 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9315 | e = s & ((1 << (-nBits)) - 1) |
| 9316 | s >>= (-nBits) |
| 9317 | nBits += eLen |
| 9318 | for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9319 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9320 | m = e & ((1 << (-nBits)) - 1) |
| 9321 | e >>= (-nBits) |
| 9322 | nBits += mLen |
| 9323 | for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9324 | |
| 9325 | if (e === 0) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9326 | e = 1 - eBias |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9327 | } else if (e === eMax) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9328 | return m ? NaN : ((s ? -1 : 1) * Infinity) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9329 | } else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9330 | m = m + Math.pow(2, mLen) |
| 9331 | e = e - eBias |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9332 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9333 | return (s ? -1 : 1) * m * Math.pow(2, e - mLen) |
| 9334 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9335 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9336 | exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { |
| 9337 | var e, m, c |
| 9338 | var eLen = nBytes * 8 - mLen - 1 |
| 9339 | var eMax = (1 << eLen) - 1 |
| 9340 | var eBias = eMax >> 1 |
| 9341 | var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) |
| 9342 | var i = isLE ? 0 : (nBytes - 1) |
| 9343 | var d = isLE ? 1 : -1 |
| 9344 | var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9345 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9346 | value = Math.abs(value) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9347 | |
| 9348 | if (isNaN(value) || value === Infinity) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9349 | m = isNaN(value) ? 1 : 0 |
| 9350 | e = eMax |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9351 | } else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9352 | e = Math.floor(Math.log(value) / Math.LN2) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9353 | if (value * (c = Math.pow(2, -e)) < 1) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9354 | e-- |
| 9355 | c *= 2 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9356 | } |
| 9357 | if (e + eBias >= 1) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9358 | value += rt / c |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9359 | } else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9360 | value += rt * Math.pow(2, 1 - eBias) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9361 | } |
| 9362 | if (value * c >= 2) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9363 | e++ |
| 9364 | c /= 2 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9365 | } |
| 9366 | |
| 9367 | if (e + eBias >= eMax) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9368 | m = 0 |
| 9369 | e = eMax |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9370 | } else if (e + eBias >= 1) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9371 | m = (value * c - 1) * Math.pow(2, mLen) |
| 9372 | e = e + eBias |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9373 | } else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9374 | m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) |
| 9375 | e = 0 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9376 | } |
| 9377 | } |
| 9378 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9379 | for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9380 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9381 | e = (e << mLen) | m |
| 9382 | eLen += mLen |
| 9383 | for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9384 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9385 | buffer[offset + i - d] |= s * 128 |
| 9386 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9387 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9388 | },{}],17:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9389 | |
| 9390 | /** |
| 9391 | * isArray |
| 9392 | */ |
| 9393 | |
| 9394 | var isArray = Array.isArray; |
| 9395 | |
| 9396 | /** |
| 9397 | * toString |
| 9398 | */ |
| 9399 | |
| 9400 | var str = Object.prototype.toString; |
| 9401 | |
| 9402 | /** |
| 9403 | * Whether or not the given `val` |
| 9404 | * is an array. |
| 9405 | * |
| 9406 | * example: |
| 9407 | * |
| 9408 | * isArray([]); |
| 9409 | * // > true |
| 9410 | * isArray(arguments); |
| 9411 | * // > false |
| 9412 | * isArray(''); |
| 9413 | * // > false |
| 9414 | * |
| 9415 | * @param {mixed} val |
| 9416 | * @return {bool} |
| 9417 | */ |
| 9418 | |
| 9419 | module.exports = isArray || function (val) { |
| 9420 | return !! val && '[object Array]' == str.call(val); |
| 9421 | }; |
| 9422 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9423 | },{}],18:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9424 | /* jshint node: true */ |
| 9425 | (function () { |
| 9426 | "use strict"; |
| 9427 | |
| 9428 | function CookieAccessInfo(domain, path, secure, script) { |
| 9429 | if (this instanceof CookieAccessInfo) { |
| 9430 | this.domain = domain || undefined; |
| 9431 | this.path = path || "/"; |
| 9432 | this.secure = !!secure; |
| 9433 | this.script = !!script; |
| 9434 | return this; |
| 9435 | } |
| 9436 | return new CookieAccessInfo(domain, path, secure, script); |
| 9437 | } |
| 9438 | exports.CookieAccessInfo = CookieAccessInfo; |
| 9439 | |
| 9440 | function Cookie(cookiestr, request_domain, request_path) { |
| 9441 | if (cookiestr instanceof Cookie) { |
| 9442 | return cookiestr; |
| 9443 | } |
| 9444 | if (this instanceof Cookie) { |
| 9445 | this.name = null; |
| 9446 | this.value = null; |
| 9447 | this.expiration_date = Infinity; |
| 9448 | this.path = String(request_path || "/"); |
| 9449 | this.explicit_path = false; |
| 9450 | this.domain = request_domain || null; |
| 9451 | this.explicit_domain = false; |
| 9452 | this.secure = false; //how to define default? |
| 9453 | this.noscript = false; //httponly |
| 9454 | if (cookiestr) { |
| 9455 | this.parse(cookiestr, request_domain, request_path); |
| 9456 | } |
| 9457 | return this; |
| 9458 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9459 | return new Cookie(cookiestr, request_domain, request_path); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9460 | } |
| 9461 | exports.Cookie = Cookie; |
| 9462 | |
| 9463 | Cookie.prototype.toString = function toString() { |
| 9464 | var str = [this.name + "=" + this.value]; |
| 9465 | if (this.expiration_date !== Infinity) { |
| 9466 | str.push("expires=" + (new Date(this.expiration_date)).toGMTString()); |
| 9467 | } |
| 9468 | if (this.domain) { |
| 9469 | str.push("domain=" + this.domain); |
| 9470 | } |
| 9471 | if (this.path) { |
| 9472 | str.push("path=" + this.path); |
| 9473 | } |
| 9474 | if (this.secure) { |
| 9475 | str.push("secure"); |
| 9476 | } |
| 9477 | if (this.noscript) { |
| 9478 | str.push("httponly"); |
| 9479 | } |
| 9480 | return str.join("; "); |
| 9481 | }; |
| 9482 | |
| 9483 | Cookie.prototype.toValueString = function toValueString() { |
| 9484 | return this.name + "=" + this.value; |
| 9485 | }; |
| 9486 | |
| 9487 | var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g; |
| 9488 | Cookie.prototype.parse = function parse(str, request_domain, request_path) { |
| 9489 | if (this instanceof Cookie) { |
| 9490 | var parts = str.split(";").filter(function (value) { |
| 9491 | return !!value; |
| 9492 | }), |
| 9493 | pair = parts[0].match(/([^=]+)=([\s\S]*)/), |
| 9494 | key = pair[1], |
| 9495 | value = pair[2], |
| 9496 | i; |
| 9497 | this.name = key; |
| 9498 | this.value = value; |
| 9499 | |
| 9500 | for (i = 1; i < parts.length; i += 1) { |
| 9501 | pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/); |
| 9502 | key = pair[1].trim().toLowerCase(); |
| 9503 | value = pair[2]; |
| 9504 | switch (key) { |
| 9505 | case "httponly": |
| 9506 | this.noscript = true; |
| 9507 | break; |
| 9508 | case "expires": |
| 9509 | this.expiration_date = value ? |
| 9510 | Number(Date.parse(value)) : |
| 9511 | Infinity; |
| 9512 | break; |
| 9513 | case "path": |
| 9514 | this.path = value ? |
| 9515 | value.trim() : |
| 9516 | ""; |
| 9517 | this.explicit_path = true; |
| 9518 | break; |
| 9519 | case "domain": |
| 9520 | this.domain = value ? |
| 9521 | value.trim() : |
| 9522 | ""; |
| 9523 | this.explicit_domain = !!this.domain; |
| 9524 | break; |
| 9525 | case "secure": |
| 9526 | this.secure = true; |
| 9527 | break; |
| 9528 | } |
| 9529 | } |
| 9530 | |
| 9531 | if (!this.explicit_path) { |
| 9532 | this.path = request_path || "/"; |
| 9533 | } |
| 9534 | if (!this.explicit_domain) { |
| 9535 | this.domain = request_domain; |
| 9536 | } |
| 9537 | |
| 9538 | return this; |
| 9539 | } |
| 9540 | return new Cookie().parse(str, request_domain, request_path); |
| 9541 | }; |
| 9542 | |
| 9543 | Cookie.prototype.matches = function matches(access_info) { |
| 9544 | if (this.noscript && access_info.script || |
| 9545 | this.secure && !access_info.secure || |
| 9546 | !this.collidesWith(access_info)) { |
| 9547 | return false; |
| 9548 | } |
| 9549 | return true; |
| 9550 | }; |
| 9551 | |
| 9552 | Cookie.prototype.collidesWith = function collidesWith(access_info) { |
| 9553 | if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) { |
| 9554 | return false; |
| 9555 | } |
| 9556 | if (this.path && access_info.path.indexOf(this.path) !== 0) { |
| 9557 | return false; |
| 9558 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9559 | if (this.explicit_path && access_info.path.indexOf( this.path ) !== 0) { |
| 9560 | return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9561 | } |
| 9562 | var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,''); |
| 9563 | var cookie_domain = this.domain && this.domain.replace(/^[\.]/,''); |
| 9564 | if (cookie_domain === access_domain) { |
| 9565 | return true; |
| 9566 | } |
| 9567 | if (cookie_domain) { |
| 9568 | if (!this.explicit_domain) { |
| 9569 | return false; // we already checked if the domains were exactly the same |
| 9570 | } |
| 9571 | var wildcard = access_domain.indexOf(cookie_domain); |
| 9572 | if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) { |
| 9573 | return false; |
| 9574 | } |
| 9575 | return true; |
| 9576 | } |
| 9577 | return true; |
| 9578 | }; |
| 9579 | |
| 9580 | function CookieJar() { |
| 9581 | var cookies, cookies_list, collidable_cookie; |
| 9582 | if (this instanceof CookieJar) { |
| 9583 | cookies = Object.create(null); //name: [Cookie] |
| 9584 | |
| 9585 | this.setCookie = function setCookie(cookie, request_domain, request_path) { |
| 9586 | var remove, i; |
| 9587 | cookie = new Cookie(cookie, request_domain, request_path); |
| 9588 | //Delete the cookie if the set is past the current time |
| 9589 | remove = cookie.expiration_date <= Date.now(); |
| 9590 | if (cookies[cookie.name] !== undefined) { |
| 9591 | cookies_list = cookies[cookie.name]; |
| 9592 | for (i = 0; i < cookies_list.length; i += 1) { |
| 9593 | collidable_cookie = cookies_list[i]; |
| 9594 | if (collidable_cookie.collidesWith(cookie)) { |
| 9595 | if (remove) { |
| 9596 | cookies_list.splice(i, 1); |
| 9597 | if (cookies_list.length === 0) { |
| 9598 | delete cookies[cookie.name]; |
| 9599 | } |
| 9600 | return false; |
| 9601 | } |
| 9602 | cookies_list[i] = cookie; |
| 9603 | return cookie; |
| 9604 | } |
| 9605 | } |
| 9606 | if (remove) { |
| 9607 | return false; |
| 9608 | } |
| 9609 | cookies_list.push(cookie); |
| 9610 | return cookie; |
| 9611 | } |
| 9612 | if (remove) { |
| 9613 | return false; |
| 9614 | } |
| 9615 | cookies[cookie.name] = [cookie]; |
| 9616 | return cookies[cookie.name]; |
| 9617 | }; |
| 9618 | //returns a cookie |
| 9619 | this.getCookie = function getCookie(cookie_name, access_info) { |
| 9620 | var cookie, i; |
| 9621 | cookies_list = cookies[cookie_name]; |
| 9622 | if (!cookies_list) { |
| 9623 | return; |
| 9624 | } |
| 9625 | for (i = 0; i < cookies_list.length; i += 1) { |
| 9626 | cookie = cookies_list[i]; |
| 9627 | if (cookie.expiration_date <= Date.now()) { |
| 9628 | if (cookies_list.length === 0) { |
| 9629 | delete cookies[cookie.name]; |
| 9630 | } |
| 9631 | continue; |
| 9632 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9633 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9634 | if (cookie.matches(access_info)) { |
| 9635 | return cookie; |
| 9636 | } |
| 9637 | } |
| 9638 | }; |
| 9639 | //returns a list of cookies |
| 9640 | this.getCookies = function getCookies(access_info) { |
| 9641 | var matches = [], cookie_name, cookie; |
| 9642 | for (cookie_name in cookies) { |
| 9643 | cookie = this.getCookie(cookie_name, access_info); |
| 9644 | if (cookie) { |
| 9645 | matches.push(cookie); |
| 9646 | } |
| 9647 | } |
| 9648 | matches.toString = function toString() { |
| 9649 | return matches.join(":"); |
| 9650 | }; |
| 9651 | matches.toValueString = function toValueString() { |
| 9652 | return matches.map(function (c) { |
| 9653 | return c.toValueString(); |
| 9654 | }).join(';'); |
| 9655 | }; |
| 9656 | return matches; |
| 9657 | }; |
| 9658 | |
| 9659 | return this; |
| 9660 | } |
| 9661 | return new CookieJar(); |
| 9662 | } |
| 9663 | exports.CookieJar = CookieJar; |
| 9664 | |
| 9665 | //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned. |
| 9666 | CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) { |
| 9667 | cookies = Array.isArray(cookies) ? |
| 9668 | cookies : |
| 9669 | cookies.split(cookie_str_splitter); |
| 9670 | var successful = [], |
| 9671 | i, |
| 9672 | cookie; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9673 | cookies = cookies.map(function(item){ |
| 9674 | return new Cookie(item, request_domain, request_path); |
| 9675 | }); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9676 | for (i = 0; i < cookies.length; i += 1) { |
| 9677 | cookie = cookies[i]; |
| 9678 | if (this.setCookie(cookie, request_domain, request_path)) { |
| 9679 | successful.push(cookie); |
| 9680 | } |
| 9681 | } |
| 9682 | return successful; |
| 9683 | }; |
| 9684 | }()); |
| 9685 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9686 | },{}],19:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9687 | 'use strict'; |
| 9688 | |
| 9689 | |
| 9690 | var yaml = require('./lib/js-yaml.js'); |
| 9691 | |
| 9692 | |
| 9693 | module.exports = yaml; |
| 9694 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9695 | },{"./lib/js-yaml.js":20}],20:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9696 | 'use strict'; |
| 9697 | |
| 9698 | |
| 9699 | var loader = require('./js-yaml/loader'); |
| 9700 | var dumper = require('./js-yaml/dumper'); |
| 9701 | |
| 9702 | |
| 9703 | function deprecated(name) { |
| 9704 | return function () { |
| 9705 | throw new Error('Function ' + name + ' is deprecated and cannot be used.'); |
| 9706 | }; |
| 9707 | } |
| 9708 | |
| 9709 | |
| 9710 | module.exports.Type = require('./js-yaml/type'); |
| 9711 | module.exports.Schema = require('./js-yaml/schema'); |
| 9712 | module.exports.FAILSAFE_SCHEMA = require('./js-yaml/schema/failsafe'); |
| 9713 | module.exports.JSON_SCHEMA = require('./js-yaml/schema/json'); |
| 9714 | module.exports.CORE_SCHEMA = require('./js-yaml/schema/core'); |
| 9715 | module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe'); |
| 9716 | module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full'); |
| 9717 | module.exports.load = loader.load; |
| 9718 | module.exports.loadAll = loader.loadAll; |
| 9719 | module.exports.safeLoad = loader.safeLoad; |
| 9720 | module.exports.safeLoadAll = loader.safeLoadAll; |
| 9721 | module.exports.dump = dumper.dump; |
| 9722 | module.exports.safeDump = dumper.safeDump; |
| 9723 | module.exports.YAMLException = require('./js-yaml/exception'); |
| 9724 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9725 | // Deprecated schema names from JS-YAML 2.0.x |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9726 | module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe'); |
| 9727 | module.exports.SAFE_SCHEMA = require('./js-yaml/schema/default_safe'); |
| 9728 | module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full'); |
| 9729 | |
| 9730 | // Deprecated functions from JS-YAML 1.x.x |
| 9731 | module.exports.scan = deprecated('scan'); |
| 9732 | module.exports.parse = deprecated('parse'); |
| 9733 | module.exports.compose = deprecated('compose'); |
| 9734 | module.exports.addConstructor = deprecated('addConstructor'); |
| 9735 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9736 | },{"./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){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9737 | 'use strict'; |
| 9738 | |
| 9739 | |
| 9740 | function isNothing(subject) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9741 | return (typeof subject === 'undefined') || (subject === null); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9742 | } |
| 9743 | |
| 9744 | |
| 9745 | function isObject(subject) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9746 | return (typeof subject === 'object') && (subject !== null); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9747 | } |
| 9748 | |
| 9749 | |
| 9750 | function toArray(sequence) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9751 | if (Array.isArray(sequence)) return sequence; |
| 9752 | else if (isNothing(sequence)) return []; |
| 9753 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9754 | return [ sequence ]; |
| 9755 | } |
| 9756 | |
| 9757 | |
| 9758 | function extend(target, source) { |
| 9759 | var index, length, key, sourceKeys; |
| 9760 | |
| 9761 | if (source) { |
| 9762 | sourceKeys = Object.keys(source); |
| 9763 | |
| 9764 | for (index = 0, length = sourceKeys.length; index < length; index += 1) { |
| 9765 | key = sourceKeys[index]; |
| 9766 | target[key] = source[key]; |
| 9767 | } |
| 9768 | } |
| 9769 | |
| 9770 | return target; |
| 9771 | } |
| 9772 | |
| 9773 | |
| 9774 | function repeat(string, count) { |
| 9775 | var result = '', cycle; |
| 9776 | |
| 9777 | for (cycle = 0; cycle < count; cycle += 1) { |
| 9778 | result += string; |
| 9779 | } |
| 9780 | |
| 9781 | return result; |
| 9782 | } |
| 9783 | |
| 9784 | |
| 9785 | function isNegativeZero(number) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9786 | return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9787 | } |
| 9788 | |
| 9789 | |
| 9790 | module.exports.isNothing = isNothing; |
| 9791 | module.exports.isObject = isObject; |
| 9792 | module.exports.toArray = toArray; |
| 9793 | module.exports.repeat = repeat; |
| 9794 | module.exports.isNegativeZero = isNegativeZero; |
| 9795 | module.exports.extend = extend; |
| 9796 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9797 | },{}],22:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9798 | 'use strict'; |
| 9799 | |
| 9800 | /*eslint-disable no-use-before-define*/ |
| 9801 | |
| 9802 | var common = require('./common'); |
| 9803 | var YAMLException = require('./exception'); |
| 9804 | var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); |
| 9805 | var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); |
| 9806 | |
| 9807 | var _toString = Object.prototype.toString; |
| 9808 | var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| 9809 | |
| 9810 | var CHAR_TAB = 0x09; /* Tab */ |
| 9811 | var CHAR_LINE_FEED = 0x0A; /* LF */ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9812 | var CHAR_SPACE = 0x20; /* Space */ |
| 9813 | var CHAR_EXCLAMATION = 0x21; /* ! */ |
| 9814 | var CHAR_DOUBLE_QUOTE = 0x22; /* " */ |
| 9815 | var CHAR_SHARP = 0x23; /* # */ |
| 9816 | var CHAR_PERCENT = 0x25; /* % */ |
| 9817 | var CHAR_AMPERSAND = 0x26; /* & */ |
| 9818 | var CHAR_SINGLE_QUOTE = 0x27; /* ' */ |
| 9819 | var CHAR_ASTERISK = 0x2A; /* * */ |
| 9820 | var CHAR_COMMA = 0x2C; /* , */ |
| 9821 | var CHAR_MINUS = 0x2D; /* - */ |
| 9822 | var CHAR_COLON = 0x3A; /* : */ |
| 9823 | var CHAR_GREATER_THAN = 0x3E; /* > */ |
| 9824 | var CHAR_QUESTION = 0x3F; /* ? */ |
| 9825 | var CHAR_COMMERCIAL_AT = 0x40; /* @ */ |
| 9826 | var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ |
| 9827 | var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ |
| 9828 | var CHAR_GRAVE_ACCENT = 0x60; /* ` */ |
| 9829 | var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ |
| 9830 | var CHAR_VERTICAL_LINE = 0x7C; /* | */ |
| 9831 | var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ |
| 9832 | |
| 9833 | var ESCAPE_SEQUENCES = {}; |
| 9834 | |
| 9835 | ESCAPE_SEQUENCES[0x00] = '\\0'; |
| 9836 | ESCAPE_SEQUENCES[0x07] = '\\a'; |
| 9837 | ESCAPE_SEQUENCES[0x08] = '\\b'; |
| 9838 | ESCAPE_SEQUENCES[0x09] = '\\t'; |
| 9839 | ESCAPE_SEQUENCES[0x0A] = '\\n'; |
| 9840 | ESCAPE_SEQUENCES[0x0B] = '\\v'; |
| 9841 | ESCAPE_SEQUENCES[0x0C] = '\\f'; |
| 9842 | ESCAPE_SEQUENCES[0x0D] = '\\r'; |
| 9843 | ESCAPE_SEQUENCES[0x1B] = '\\e'; |
| 9844 | ESCAPE_SEQUENCES[0x22] = '\\"'; |
| 9845 | ESCAPE_SEQUENCES[0x5C] = '\\\\'; |
| 9846 | ESCAPE_SEQUENCES[0x85] = '\\N'; |
| 9847 | ESCAPE_SEQUENCES[0xA0] = '\\_'; |
| 9848 | ESCAPE_SEQUENCES[0x2028] = '\\L'; |
| 9849 | ESCAPE_SEQUENCES[0x2029] = '\\P'; |
| 9850 | |
| 9851 | var DEPRECATED_BOOLEANS_SYNTAX = [ |
| 9852 | 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', |
| 9853 | 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' |
| 9854 | ]; |
| 9855 | |
| 9856 | function compileStyleMap(schema, map) { |
| 9857 | var result, keys, index, length, tag, style, type; |
| 9858 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9859 | if (map === null) return {}; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9860 | |
| 9861 | result = {}; |
| 9862 | keys = Object.keys(map); |
| 9863 | |
| 9864 | for (index = 0, length = keys.length; index < length; index += 1) { |
| 9865 | tag = keys[index]; |
| 9866 | style = String(map[tag]); |
| 9867 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9868 | if (tag.slice(0, 2) === '!!') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9869 | tag = 'tag:yaml.org,2002:' + tag.slice(2); |
| 9870 | } |
| 9871 | |
| 9872 | type = schema.compiledTypeMap[tag]; |
| 9873 | |
| 9874 | if (type && _hasOwnProperty.call(type.styleAliases, style)) { |
| 9875 | style = type.styleAliases[style]; |
| 9876 | } |
| 9877 | |
| 9878 | result[tag] = style; |
| 9879 | } |
| 9880 | |
| 9881 | return result; |
| 9882 | } |
| 9883 | |
| 9884 | function encodeHex(character) { |
| 9885 | var string, handle, length; |
| 9886 | |
| 9887 | string = character.toString(16).toUpperCase(); |
| 9888 | |
| 9889 | if (character <= 0xFF) { |
| 9890 | handle = 'x'; |
| 9891 | length = 2; |
| 9892 | } else if (character <= 0xFFFF) { |
| 9893 | handle = 'u'; |
| 9894 | length = 4; |
| 9895 | } else if (character <= 0xFFFFFFFF) { |
| 9896 | handle = 'U'; |
| 9897 | length = 8; |
| 9898 | } else { |
| 9899 | throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF'); |
| 9900 | } |
| 9901 | |
| 9902 | return '\\' + handle + common.repeat('0', length - string.length) + string; |
| 9903 | } |
| 9904 | |
| 9905 | function State(options) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9906 | this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; |
| 9907 | this.indent = Math.max(1, (options['indent'] || 2)); |
| 9908 | this.skipInvalid = options['skipInvalid'] || false; |
| 9909 | this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); |
| 9910 | this.styleMap = compileStyleMap(this.schema, options['styles'] || null); |
| 9911 | this.sortKeys = options['sortKeys'] || false; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 9912 | this.lineWidth = options['lineWidth'] || 80; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9913 | this.noRefs = options['noRefs'] || false; |
| 9914 | this.noCompatMode = options['noCompatMode'] || false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9915 | |
| 9916 | this.implicitTypes = this.schema.compiledImplicit; |
| 9917 | this.explicitTypes = this.schema.compiledExplicit; |
| 9918 | |
| 9919 | this.tag = null; |
| 9920 | this.result = ''; |
| 9921 | |
| 9922 | this.duplicates = []; |
| 9923 | this.usedDuplicates = null; |
| 9924 | } |
| 9925 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9926 | // Indents every line in a string. Empty lines (\n only) are not indented. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9927 | function indentString(string, spaces) { |
| 9928 | var ind = common.repeat(' ', spaces), |
| 9929 | position = 0, |
| 9930 | next = -1, |
| 9931 | result = '', |
| 9932 | line, |
| 9933 | length = string.length; |
| 9934 | |
| 9935 | while (position < length) { |
| 9936 | next = string.indexOf('\n', position); |
| 9937 | if (next === -1) { |
| 9938 | line = string.slice(position); |
| 9939 | position = length; |
| 9940 | } else { |
| 9941 | line = string.slice(position, next + 1); |
| 9942 | position = next + 1; |
| 9943 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9944 | |
| 9945 | if (line.length && line !== '\n') result += ind; |
| 9946 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9947 | result += line; |
| 9948 | } |
| 9949 | |
| 9950 | return result; |
| 9951 | } |
| 9952 | |
| 9953 | function generateNextLine(state, level) { |
| 9954 | return '\n' + common.repeat(' ', state.indent * level); |
| 9955 | } |
| 9956 | |
| 9957 | function testImplicitResolving(state, str) { |
| 9958 | var index, length, type; |
| 9959 | |
| 9960 | for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { |
| 9961 | type = state.implicitTypes[index]; |
| 9962 | |
| 9963 | if (type.resolve(str)) { |
| 9964 | return true; |
| 9965 | } |
| 9966 | } |
| 9967 | |
| 9968 | return false; |
| 9969 | } |
| 9970 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9971 | // [33] s-white ::= s-space | s-tab |
| 9972 | function isWhitespace(c) { |
| 9973 | return c === CHAR_SPACE || c === CHAR_TAB; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9974 | } |
| 9975 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9976 | // Returns true if the character can be printed without escaping. |
| 9977 | // From YAML 1.2: "any allowed characters known to be non-printable |
| 9978 | // should also be escaped. [However,] This isn’t mandatory" |
| 9979 | // Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. |
| 9980 | function isPrintable(c) { |
| 9981 | return (0x00020 <= c && c <= 0x00007E) |
| 9982 | || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) |
| 9983 | || ((0x0E000 <= c && c <= 0x00FFFD) && c !== 0xFEFF /* BOM */) |
| 9984 | || (0x10000 <= c && c <= 0x10FFFF); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 9985 | } |
| 9986 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 9987 | // Simplified test for values allowed after the first character in plain style. |
| 9988 | function isPlainSafe(c) { |
| 9989 | // Uses a subset of nb-char - c-flow-indicator - ":" - "#" |
| 9990 | // where nb-char ::= c-printable - b-char - c-byte-order-mark. |
| 9991 | return isPrintable(c) && c !== 0xFEFF |
| 9992 | // - c-flow-indicator |
| 9993 | && c !== CHAR_COMMA |
| 9994 | && c !== CHAR_LEFT_SQUARE_BRACKET |
| 9995 | && c !== CHAR_RIGHT_SQUARE_BRACKET |
| 9996 | && c !== CHAR_LEFT_CURLY_BRACKET |
| 9997 | && c !== CHAR_RIGHT_CURLY_BRACKET |
| 9998 | // - ":" - "#" |
| 9999 | && c !== CHAR_COLON |
| 10000 | && c !== CHAR_SHARP; |
| 10001 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10002 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10003 | // Simplified test for values allowed as the first character in plain style. |
| 10004 | function isPlainSafeFirst(c) { |
| 10005 | // Uses a subset of ns-char - c-indicator |
| 10006 | // where ns-char = nb-char - s-white. |
| 10007 | return isPrintable(c) && c !== 0xFEFF |
| 10008 | && !isWhitespace(c) // - s-white |
| 10009 | // - (c-indicator ::= |
| 10010 | // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” |
| 10011 | && c !== CHAR_MINUS |
| 10012 | && c !== CHAR_QUESTION |
| 10013 | && c !== CHAR_COLON |
| 10014 | && c !== CHAR_COMMA |
| 10015 | && c !== CHAR_LEFT_SQUARE_BRACKET |
| 10016 | && c !== CHAR_RIGHT_SQUARE_BRACKET |
| 10017 | && c !== CHAR_LEFT_CURLY_BRACKET |
| 10018 | && c !== CHAR_RIGHT_CURLY_BRACKET |
| 10019 | // | “#” | “&” | “*” | “!” | “|” | “>” | “'” | “"” |
| 10020 | && c !== CHAR_SHARP |
| 10021 | && c !== CHAR_AMPERSAND |
| 10022 | && c !== CHAR_ASTERISK |
| 10023 | && c !== CHAR_EXCLAMATION |
| 10024 | && c !== CHAR_VERTICAL_LINE |
| 10025 | && c !== CHAR_GREATER_THAN |
| 10026 | && c !== CHAR_SINGLE_QUOTE |
| 10027 | && c !== CHAR_DOUBLE_QUOTE |
| 10028 | // | “%” | “@” | “`”) |
| 10029 | && c !== CHAR_PERCENT |
| 10030 | && c !== CHAR_COMMERCIAL_AT |
| 10031 | && c !== CHAR_GRAVE_ACCENT; |
| 10032 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10033 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10034 | var STYLE_PLAIN = 1, |
| 10035 | STYLE_SINGLE = 2, |
| 10036 | STYLE_LITERAL = 3, |
| 10037 | STYLE_FOLDED = 4, |
| 10038 | STYLE_DOUBLE = 5; |
| 10039 | |
| 10040 | // Determines which scalar styles are possible and returns the preferred style. |
| 10041 | // lineWidth = -1 => no limit. |
| 10042 | // Pre-conditions: str.length > 0. |
| 10043 | // Post-conditions: |
| 10044 | // STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. |
| 10045 | // STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). |
| 10046 | // STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). |
| 10047 | function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) { |
| 10048 | var i; |
| 10049 | var char; |
| 10050 | var hasLineBreak = false; |
| 10051 | var hasFoldableLine = false; // only checked if shouldTrackWidth |
| 10052 | var shouldTrackWidth = lineWidth !== -1; |
| 10053 | var previousLineBreak = -1; // count the first line correctly |
| 10054 | var plain = isPlainSafeFirst(string.charCodeAt(0)) |
| 10055 | && !isWhitespace(string.charCodeAt(string.length - 1)); |
| 10056 | |
| 10057 | if (singleLineOnly) { |
| 10058 | // Case: no block styles. |
| 10059 | // Check for disallowed characters to rule out plain and single. |
| 10060 | for (i = 0; i < string.length; i++) { |
| 10061 | char = string.charCodeAt(i); |
| 10062 | if (!isPrintable(char)) { |
| 10063 | return STYLE_DOUBLE; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10064 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10065 | plain = plain && isPlainSafe(char); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10066 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10067 | } else { |
| 10068 | // Case: block styles permitted. |
| 10069 | for (i = 0; i < string.length; i++) { |
| 10070 | char = string.charCodeAt(i); |
| 10071 | if (char === CHAR_LINE_FEED) { |
| 10072 | hasLineBreak = true; |
| 10073 | // Check if any line can be folded. |
| 10074 | if (shouldTrackWidth) { |
| 10075 | hasFoldableLine = hasFoldableLine || |
| 10076 | // Foldable line = too long, and not more-indented. |
| 10077 | (i - previousLineBreak - 1 > lineWidth && |
| 10078 | string[previousLineBreak + 1] !== ' '); |
| 10079 | previousLineBreak = i; |
| 10080 | } |
| 10081 | } else if (!isPrintable(char)) { |
| 10082 | return STYLE_DOUBLE; |
| 10083 | } |
| 10084 | plain = plain && isPlainSafe(char); |
| 10085 | } |
| 10086 | // in case the end is missing a \n |
| 10087 | hasFoldableLine = hasFoldableLine || (shouldTrackWidth && |
| 10088 | (i - previousLineBreak - 1 > lineWidth && |
| 10089 | string[previousLineBreak + 1] !== ' ')); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10090 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10091 | // Although every style can represent \n without escaping, prefer block styles |
| 10092 | // for multiline, since they're more readable and they don't add empty lines. |
| 10093 | // Also prefer folding a super-long line. |
| 10094 | if (!hasLineBreak && !hasFoldableLine) { |
| 10095 | // Strings interpretable as another type have to be quoted; |
| 10096 | // e.g. the string 'true' vs. the boolean true. |
| 10097 | return plain && !testAmbiguousType(string) |
| 10098 | ? STYLE_PLAIN : STYLE_SINGLE; |
| 10099 | } |
| 10100 | // Edge case: block indentation indicator can only have one digit. |
| 10101 | if (string[0] === ' ' && indentPerLevel > 9) { |
| 10102 | return STYLE_DOUBLE; |
| 10103 | } |
| 10104 | // At this point we know block styles are valid. |
| 10105 | // Prefer literal style unless we want to fold. |
| 10106 | return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; |
| 10107 | } |
| 10108 | |
| 10109 | // Note: line breaking/folding is implemented for only the folded style. |
| 10110 | // NB. We drop the last trailing newline (if any) of a returned block scalar |
| 10111 | // since the dumper adds its own newline. This always works: |
| 10112 | // • No ending newline => unaffected; already using strip "-" chomping. |
| 10113 | // • Ending newline => removed then restored. |
| 10114 | // Importantly, this keeps the "+" chomp indicator from gaining an extra line. |
| 10115 | function writeScalar(state, string, level, iskey) { |
| 10116 | state.dump = (function () { |
| 10117 | if (string.length === 0) { |
| 10118 | return "''"; |
| 10119 | } |
| 10120 | if (!state.noCompatMode && |
| 10121 | DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1) { |
| 10122 | return "'" + string + "'"; |
| 10123 | } |
| 10124 | |
| 10125 | var indent = state.indent * Math.max(1, level); // no 0-indent scalars |
| 10126 | // As indentation gets deeper, let the width decrease monotonically |
| 10127 | // to the lower bound min(state.lineWidth, 40). |
| 10128 | // Note that this implies |
| 10129 | // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. |
| 10130 | // state.lineWidth > 40 + state.indent: width decreases until the lower bound. |
| 10131 | // This behaves better than a constant minimum width which disallows narrower options, |
| 10132 | // or an indent threshold which causes the width to suddenly increase. |
| 10133 | var lineWidth = state.lineWidth === -1 |
| 10134 | ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); |
| 10135 | |
| 10136 | // Without knowing if keys are implicit/explicit, assume implicit for safety. |
| 10137 | var singleLineOnly = iskey |
| 10138 | // No block styles in flow mode. |
| 10139 | || (state.flowLevel > -1 && level >= state.flowLevel); |
| 10140 | function testAmbiguity(string) { |
| 10141 | return testImplicitResolving(state, string); |
| 10142 | } |
| 10143 | |
| 10144 | switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, testAmbiguity)) { |
| 10145 | case STYLE_PLAIN: |
| 10146 | return string; |
| 10147 | case STYLE_SINGLE: |
| 10148 | return "'" + string.replace(/'/g, "''") + "'"; |
| 10149 | case STYLE_LITERAL: |
| 10150 | return '|' + blockHeader(string, state.indent) |
| 10151 | + dropEndingNewline(indentString(string, indent)); |
| 10152 | case STYLE_FOLDED: |
| 10153 | return '>' + blockHeader(string, state.indent) |
| 10154 | + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); |
| 10155 | case STYLE_DOUBLE: |
| 10156 | return '"' + escapeString(string, lineWidth) + '"'; |
| 10157 | default: |
| 10158 | throw new YAMLException('impossible error: invalid scalar style'); |
| 10159 | } |
| 10160 | }()); |
| 10161 | } |
| 10162 | |
| 10163 | // Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. |
| 10164 | function blockHeader(string, indentPerLevel) { |
| 10165 | var indentIndicator = (string[0] === ' ') ? String(indentPerLevel) : ''; |
| 10166 | |
| 10167 | // note the special case: the string '\n' counts as a "trailing" empty line. |
| 10168 | var clip = string[string.length - 1] === '\n'; |
| 10169 | var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); |
| 10170 | var chomp = keep ? '+' : (clip ? '' : '-'); |
| 10171 | |
| 10172 | return indentIndicator + chomp + '\n'; |
| 10173 | } |
| 10174 | |
| 10175 | // (See the note for writeScalar.) |
| 10176 | function dropEndingNewline(string) { |
| 10177 | return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; |
| 10178 | } |
| 10179 | |
| 10180 | // Note: a long line without a suitable break point will exceed the width limit. |
| 10181 | // Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. |
| 10182 | function foldString(string, width) { |
| 10183 | // In folded style, $k$ consecutive newlines output as $k+1$ newlines— |
| 10184 | // unless they're before or after a more-indented line, or at the very |
| 10185 | // beginning or end, in which case $k$ maps to $k$. |
| 10186 | // Therefore, parse each chunk as newline(s) followed by a content line. |
| 10187 | var lineRe = /(\n+)([^\n]*)/g; |
| 10188 | |
| 10189 | // first line (possibly an empty line) |
| 10190 | var result = (function () { |
| 10191 | var nextLF = string.indexOf('\n'); |
| 10192 | nextLF = nextLF !== -1 ? nextLF : string.length; |
| 10193 | lineRe.lastIndex = nextLF; |
| 10194 | return foldLine(string.slice(0, nextLF), width); |
| 10195 | }()); |
| 10196 | // If we haven't reached the first content line yet, don't add an extra \n. |
| 10197 | var prevMoreIndented = string[0] === '\n' || string[0] === ' '; |
| 10198 | var moreIndented; |
| 10199 | |
| 10200 | // rest of the lines |
| 10201 | var match; |
| 10202 | while ((match = lineRe.exec(string))) { |
| 10203 | var prefix = match[1], line = match[2]; |
| 10204 | moreIndented = (line[0] === ' '); |
| 10205 | result += prefix |
| 10206 | + (!prevMoreIndented && !moreIndented && line !== '' |
| 10207 | ? '\n' : '') |
| 10208 | + foldLine(line, width); |
| 10209 | prevMoreIndented = moreIndented; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10210 | } |
| 10211 | |
| 10212 | return result; |
| 10213 | } |
| 10214 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10215 | // Greedy line breaking. |
| 10216 | // Picks the longest line under the limit each time, |
| 10217 | // otherwise settles for the shortest line over the limit. |
| 10218 | // NB. More-indented lines *cannot* be folded, as that would add an extra \n. |
| 10219 | function foldLine(line, width) { |
| 10220 | if (line === '' || line[0] === ' ') return line; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10221 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10222 | // Since a more-indented line adds a \n, breaks can't be followed by a space. |
| 10223 | var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. |
| 10224 | var match; |
| 10225 | // start is an inclusive index. end, curr, and next are exclusive. |
| 10226 | var start = 0, end, curr = 0, next = 0; |
| 10227 | var result = ''; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10228 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10229 | // Invariants: 0 <= start <= length-1. |
| 10230 | // 0 <= curr <= next <= max(0, length-2). curr - start <= width. |
| 10231 | // Inside the loop: |
| 10232 | // A match implies length >= 2, so curr and next are <= length-2. |
| 10233 | while ((match = breakRe.exec(line))) { |
| 10234 | next = match.index; |
| 10235 | // maintain invariant: curr - start <= width |
| 10236 | if (next - start > width) { |
| 10237 | end = (curr > start) ? curr : next; // derive end <= length-2 |
| 10238 | result += '\n' + line.slice(start, end); |
| 10239 | // skip the space that was output as \n |
| 10240 | start = end + 1; // derive start <= length-1 |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10241 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10242 | curr = next; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10243 | } |
| 10244 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10245 | // By the invariants, start <= length-1, so there is something left over. |
| 10246 | // It is either the whole string or a part starting from non-whitespace. |
| 10247 | result += '\n'; |
| 10248 | // Insert a break if the remainder is too long and there is a break available. |
| 10249 | if (line.length - start > width && curr > start) { |
| 10250 | result += line.slice(start, curr) + '\n' + line.slice(curr + 1); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10251 | } else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10252 | result += line.slice(start); |
| 10253 | } |
| 10254 | |
| 10255 | return result.slice(1); // drop extra \n joiner |
| 10256 | } |
| 10257 | |
| 10258 | // Escapes a double-quoted string. |
| 10259 | function escapeString(string) { |
| 10260 | var result = ''; |
| 10261 | var char; |
| 10262 | var escapeSeq; |
| 10263 | |
| 10264 | for (var i = 0; i < string.length; i++) { |
| 10265 | char = string.charCodeAt(i); |
| 10266 | escapeSeq = ESCAPE_SEQUENCES[char]; |
| 10267 | result += !escapeSeq && isPrintable(char) |
| 10268 | ? string[i] |
| 10269 | : escapeSeq || encodeHex(char); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10270 | } |
| 10271 | |
| 10272 | return result; |
| 10273 | } |
| 10274 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10275 | function writeFlowSequence(state, level, object) { |
| 10276 | var _result = '', |
| 10277 | _tag = state.tag, |
| 10278 | index, |
| 10279 | length; |
| 10280 | |
| 10281 | for (index = 0, length = object.length; index < length; index += 1) { |
| 10282 | // Write only valid elements. |
| 10283 | if (writeNode(state, level, object[index], false, false)) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10284 | if (index !== 0) _result += ', '; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10285 | _result += state.dump; |
| 10286 | } |
| 10287 | } |
| 10288 | |
| 10289 | state.tag = _tag; |
| 10290 | state.dump = '[' + _result + ']'; |
| 10291 | } |
| 10292 | |
| 10293 | function writeBlockSequence(state, level, object, compact) { |
| 10294 | var _result = '', |
| 10295 | _tag = state.tag, |
| 10296 | index, |
| 10297 | length; |
| 10298 | |
| 10299 | for (index = 0, length = object.length; index < length; index += 1) { |
| 10300 | // Write only valid elements. |
| 10301 | if (writeNode(state, level + 1, object[index], true, true)) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10302 | if (!compact || index !== 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10303 | _result += generateNextLine(state, level); |
| 10304 | } |
| 10305 | _result += '- ' + state.dump; |
| 10306 | } |
| 10307 | } |
| 10308 | |
| 10309 | state.tag = _tag; |
| 10310 | state.dump = _result || '[]'; // Empty sequence if no valid values. |
| 10311 | } |
| 10312 | |
| 10313 | function writeFlowMapping(state, level, object) { |
| 10314 | var _result = '', |
| 10315 | _tag = state.tag, |
| 10316 | objectKeyList = Object.keys(object), |
| 10317 | index, |
| 10318 | length, |
| 10319 | objectKey, |
| 10320 | objectValue, |
| 10321 | pairBuffer; |
| 10322 | |
| 10323 | for (index = 0, length = objectKeyList.length; index < length; index += 1) { |
| 10324 | pairBuffer = ''; |
| 10325 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10326 | if (index !== 0) pairBuffer += ', '; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10327 | |
| 10328 | objectKey = objectKeyList[index]; |
| 10329 | objectValue = object[objectKey]; |
| 10330 | |
| 10331 | if (!writeNode(state, level, objectKey, false, false)) { |
| 10332 | continue; // Skip this pair because of invalid key; |
| 10333 | } |
| 10334 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10335 | if (state.dump.length > 1024) pairBuffer += '? '; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10336 | |
| 10337 | pairBuffer += state.dump + ': '; |
| 10338 | |
| 10339 | if (!writeNode(state, level, objectValue, false, false)) { |
| 10340 | continue; // Skip this pair because of invalid value. |
| 10341 | } |
| 10342 | |
| 10343 | pairBuffer += state.dump; |
| 10344 | |
| 10345 | // Both key and value are valid. |
| 10346 | _result += pairBuffer; |
| 10347 | } |
| 10348 | |
| 10349 | state.tag = _tag; |
| 10350 | state.dump = '{' + _result + '}'; |
| 10351 | } |
| 10352 | |
| 10353 | function writeBlockMapping(state, level, object, compact) { |
| 10354 | var _result = '', |
| 10355 | _tag = state.tag, |
| 10356 | objectKeyList = Object.keys(object), |
| 10357 | index, |
| 10358 | length, |
| 10359 | objectKey, |
| 10360 | objectValue, |
| 10361 | explicitPair, |
| 10362 | pairBuffer; |
| 10363 | |
| 10364 | // Allow sorting keys so that the output file is deterministic |
| 10365 | if (state.sortKeys === true) { |
| 10366 | // Default sorting |
| 10367 | objectKeyList.sort(); |
| 10368 | } else if (typeof state.sortKeys === 'function') { |
| 10369 | // Custom sort function |
| 10370 | objectKeyList.sort(state.sortKeys); |
| 10371 | } else if (state.sortKeys) { |
| 10372 | // Something is wrong |
| 10373 | throw new YAMLException('sortKeys must be a boolean or a function'); |
| 10374 | } |
| 10375 | |
| 10376 | for (index = 0, length = objectKeyList.length; index < length; index += 1) { |
| 10377 | pairBuffer = ''; |
| 10378 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10379 | if (!compact || index !== 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10380 | pairBuffer += generateNextLine(state, level); |
| 10381 | } |
| 10382 | |
| 10383 | objectKey = objectKeyList[index]; |
| 10384 | objectValue = object[objectKey]; |
| 10385 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10386 | if (!writeNode(state, level + 1, objectKey, true, true, true)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10387 | continue; // Skip this pair because of invalid key. |
| 10388 | } |
| 10389 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10390 | explicitPair = (state.tag !== null && state.tag !== '?') || |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10391 | (state.dump && state.dump.length > 1024); |
| 10392 | |
| 10393 | if (explicitPair) { |
| 10394 | if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { |
| 10395 | pairBuffer += '?'; |
| 10396 | } else { |
| 10397 | pairBuffer += '? '; |
| 10398 | } |
| 10399 | } |
| 10400 | |
| 10401 | pairBuffer += state.dump; |
| 10402 | |
| 10403 | if (explicitPair) { |
| 10404 | pairBuffer += generateNextLine(state, level); |
| 10405 | } |
| 10406 | |
| 10407 | if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { |
| 10408 | continue; // Skip this pair because of invalid value. |
| 10409 | } |
| 10410 | |
| 10411 | if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { |
| 10412 | pairBuffer += ':'; |
| 10413 | } else { |
| 10414 | pairBuffer += ': '; |
| 10415 | } |
| 10416 | |
| 10417 | pairBuffer += state.dump; |
| 10418 | |
| 10419 | // Both key and value are valid. |
| 10420 | _result += pairBuffer; |
| 10421 | } |
| 10422 | |
| 10423 | state.tag = _tag; |
| 10424 | state.dump = _result || '{}'; // Empty mapping if no valid pairs. |
| 10425 | } |
| 10426 | |
| 10427 | function detectType(state, object, explicit) { |
| 10428 | var _result, typeList, index, length, type, style; |
| 10429 | |
| 10430 | typeList = explicit ? state.explicitTypes : state.implicitTypes; |
| 10431 | |
| 10432 | for (index = 0, length = typeList.length; index < length; index += 1) { |
| 10433 | type = typeList[index]; |
| 10434 | |
| 10435 | if ((type.instanceOf || type.predicate) && |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10436 | (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10437 | (!type.predicate || type.predicate(object))) { |
| 10438 | |
| 10439 | state.tag = explicit ? type.tag : '?'; |
| 10440 | |
| 10441 | if (type.represent) { |
| 10442 | style = state.styleMap[type.tag] || type.defaultStyle; |
| 10443 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10444 | if (_toString.call(type.represent) === '[object Function]') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10445 | _result = type.represent(object, style); |
| 10446 | } else if (_hasOwnProperty.call(type.represent, style)) { |
| 10447 | _result = type.represent[style](object, style); |
| 10448 | } else { |
| 10449 | throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); |
| 10450 | } |
| 10451 | |
| 10452 | state.dump = _result; |
| 10453 | } |
| 10454 | |
| 10455 | return true; |
| 10456 | } |
| 10457 | } |
| 10458 | |
| 10459 | return false; |
| 10460 | } |
| 10461 | |
| 10462 | // Serializes `object` and writes it to global `result`. |
| 10463 | // Returns true on success, or false on invalid object. |
| 10464 | // |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10465 | function writeNode(state, level, object, block, compact, iskey) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10466 | state.tag = null; |
| 10467 | state.dump = object; |
| 10468 | |
| 10469 | if (!detectType(state, object, false)) { |
| 10470 | detectType(state, object, true); |
| 10471 | } |
| 10472 | |
| 10473 | var type = _toString.call(state.dump); |
| 10474 | |
| 10475 | if (block) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10476 | block = (state.flowLevel < 0 || state.flowLevel > level); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10477 | } |
| 10478 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10479 | var objectOrArray = type === '[object Object]' || type === '[object Array]', |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10480 | duplicateIndex, |
| 10481 | duplicate; |
| 10482 | |
| 10483 | if (objectOrArray) { |
| 10484 | duplicateIndex = state.duplicates.indexOf(object); |
| 10485 | duplicate = duplicateIndex !== -1; |
| 10486 | } |
| 10487 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10488 | if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10489 | compact = false; |
| 10490 | } |
| 10491 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10492 | if (duplicate && state.usedDuplicates[duplicateIndex]) { |
| 10493 | state.dump = '*ref_' + duplicateIndex; |
| 10494 | } else { |
| 10495 | if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { |
| 10496 | state.usedDuplicates[duplicateIndex] = true; |
| 10497 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10498 | if (type === '[object Object]') { |
| 10499 | if (block && (Object.keys(state.dump).length !== 0)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10500 | writeBlockMapping(state, level, state.dump, compact); |
| 10501 | if (duplicate) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10502 | state.dump = '&ref_' + duplicateIndex + state.dump; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10503 | } |
| 10504 | } else { |
| 10505 | writeFlowMapping(state, level, state.dump); |
| 10506 | if (duplicate) { |
| 10507 | state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; |
| 10508 | } |
| 10509 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10510 | } else if (type === '[object Array]') { |
| 10511 | if (block && (state.dump.length !== 0)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10512 | writeBlockSequence(state, level, state.dump, compact); |
| 10513 | if (duplicate) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10514 | state.dump = '&ref_' + duplicateIndex + state.dump; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10515 | } |
| 10516 | } else { |
| 10517 | writeFlowSequence(state, level, state.dump); |
| 10518 | if (duplicate) { |
| 10519 | state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; |
| 10520 | } |
| 10521 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10522 | } else if (type === '[object String]') { |
| 10523 | if (state.tag !== '?') { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10524 | writeScalar(state, state.dump, level, iskey); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10525 | } |
| 10526 | } else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10527 | if (state.skipInvalid) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10528 | throw new YAMLException('unacceptable kind of an object to dump ' + type); |
| 10529 | } |
| 10530 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10531 | if (state.tag !== null && state.tag !== '?') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10532 | state.dump = '!<' + state.tag + '> ' + state.dump; |
| 10533 | } |
| 10534 | } |
| 10535 | |
| 10536 | return true; |
| 10537 | } |
| 10538 | |
| 10539 | function getDuplicateReferences(object, state) { |
| 10540 | var objects = [], |
| 10541 | duplicatesIndexes = [], |
| 10542 | index, |
| 10543 | length; |
| 10544 | |
| 10545 | inspectNode(object, objects, duplicatesIndexes); |
| 10546 | |
| 10547 | for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { |
| 10548 | state.duplicates.push(objects[duplicatesIndexes[index]]); |
| 10549 | } |
| 10550 | state.usedDuplicates = new Array(length); |
| 10551 | } |
| 10552 | |
| 10553 | function inspectNode(object, objects, duplicatesIndexes) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10554 | var objectKeyList, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10555 | index, |
| 10556 | length; |
| 10557 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10558 | if (object !== null && typeof object === 'object') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10559 | index = objects.indexOf(object); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10560 | if (index !== -1) { |
| 10561 | if (duplicatesIndexes.indexOf(index) === -1) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10562 | duplicatesIndexes.push(index); |
| 10563 | } |
| 10564 | } else { |
| 10565 | objects.push(object); |
| 10566 | |
| 10567 | if (Array.isArray(object)) { |
| 10568 | for (index = 0, length = object.length; index < length; index += 1) { |
| 10569 | inspectNode(object[index], objects, duplicatesIndexes); |
| 10570 | } |
| 10571 | } else { |
| 10572 | objectKeyList = Object.keys(object); |
| 10573 | |
| 10574 | for (index = 0, length = objectKeyList.length; index < length; index += 1) { |
| 10575 | inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); |
| 10576 | } |
| 10577 | } |
| 10578 | } |
| 10579 | } |
| 10580 | } |
| 10581 | |
| 10582 | function dump(input, options) { |
| 10583 | options = options || {}; |
| 10584 | |
| 10585 | var state = new State(options); |
| 10586 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10587 | if (!state.noRefs) getDuplicateReferences(input, state); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10588 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10589 | if (writeNode(state, 0, input, true, true)) return state.dump + '\n'; |
| 10590 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10591 | return ''; |
| 10592 | } |
| 10593 | |
| 10594 | function safeDump(input, options) { |
| 10595 | return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); |
| 10596 | } |
| 10597 | |
| 10598 | module.exports.dump = dump; |
| 10599 | module.exports.safeDump = safeDump; |
| 10600 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10601 | },{"./common":21,"./exception":23,"./schema/default_full":28,"./schema/default_safe":29}],23:[function(require,module,exports){ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10602 | // YAML error class. http://stackoverflow.com/questions/8458984 |
| 10603 | // |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10604 | 'use strict'; |
| 10605 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10606 | function YAMLException(reason, mark) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10607 | // Super constructor |
| 10608 | Error.call(this); |
| 10609 | |
| 10610 | // Include stack trace in error object |
| 10611 | if (Error.captureStackTrace) { |
| 10612 | // Chrome and NodeJS |
| 10613 | Error.captureStackTrace(this, this.constructor); |
| 10614 | } else { |
| 10615 | // FF, IE 10+ and Safari 6+. Fallback for others |
| 10616 | this.stack = (new Error()).stack || ''; |
| 10617 | } |
| 10618 | |
| 10619 | this.name = 'YAMLException'; |
| 10620 | this.reason = reason; |
| 10621 | this.mark = mark; |
| 10622 | this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : ''); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10623 | } |
| 10624 | |
| 10625 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10626 | // Inherit from Error |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10627 | YAMLException.prototype = Object.create(Error.prototype); |
| 10628 | YAMLException.prototype.constructor = YAMLException; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10629 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10630 | |
| 10631 | YAMLException.prototype.toString = function toString(compact) { |
| 10632 | var result = this.name + ': '; |
| 10633 | |
| 10634 | result += this.reason || '(unknown reason)'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10635 | |
| 10636 | if (!compact && this.mark) { |
| 10637 | result += ' ' + this.mark.toString(); |
| 10638 | } |
| 10639 | |
| 10640 | return result; |
| 10641 | }; |
| 10642 | |
| 10643 | |
| 10644 | module.exports = YAMLException; |
| 10645 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10646 | },{}],24:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10647 | 'use strict'; |
| 10648 | |
| 10649 | /*eslint-disable max-len,no-use-before-define*/ |
| 10650 | |
| 10651 | var common = require('./common'); |
| 10652 | var YAMLException = require('./exception'); |
| 10653 | var Mark = require('./mark'); |
| 10654 | var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); |
| 10655 | var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); |
| 10656 | |
| 10657 | |
| 10658 | var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| 10659 | |
| 10660 | |
| 10661 | var CONTEXT_FLOW_IN = 1; |
| 10662 | var CONTEXT_FLOW_OUT = 2; |
| 10663 | var CONTEXT_BLOCK_IN = 3; |
| 10664 | var CONTEXT_BLOCK_OUT = 4; |
| 10665 | |
| 10666 | |
| 10667 | var CHOMPING_CLIP = 1; |
| 10668 | var CHOMPING_STRIP = 2; |
| 10669 | var CHOMPING_KEEP = 3; |
| 10670 | |
| 10671 | |
| 10672 | var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; |
| 10673 | var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; |
| 10674 | var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; |
| 10675 | var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; |
| 10676 | var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; |
| 10677 | |
| 10678 | |
| 10679 | function is_EOL(c) { |
| 10680 | return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); |
| 10681 | } |
| 10682 | |
| 10683 | function is_WHITE_SPACE(c) { |
| 10684 | return (c === 0x09/* Tab */) || (c === 0x20/* Space */); |
| 10685 | } |
| 10686 | |
| 10687 | function is_WS_OR_EOL(c) { |
| 10688 | return (c === 0x09/* Tab */) || |
| 10689 | (c === 0x20/* Space */) || |
| 10690 | (c === 0x0A/* LF */) || |
| 10691 | (c === 0x0D/* CR */); |
| 10692 | } |
| 10693 | |
| 10694 | function is_FLOW_INDICATOR(c) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10695 | return c === 0x2C/* , */ || |
| 10696 | c === 0x5B/* [ */ || |
| 10697 | c === 0x5D/* ] */ || |
| 10698 | c === 0x7B/* { */ || |
| 10699 | c === 0x7D/* } */; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10700 | } |
| 10701 | |
| 10702 | function fromHexCode(c) { |
| 10703 | var lc; |
| 10704 | |
| 10705 | if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { |
| 10706 | return c - 0x30; |
| 10707 | } |
| 10708 | |
| 10709 | /*eslint-disable no-bitwise*/ |
| 10710 | lc = c | 0x20; |
| 10711 | |
| 10712 | if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { |
| 10713 | return lc - 0x61 + 10; |
| 10714 | } |
| 10715 | |
| 10716 | return -1; |
| 10717 | } |
| 10718 | |
| 10719 | function escapedHexLen(c) { |
| 10720 | if (c === 0x78/* x */) { return 2; } |
| 10721 | if (c === 0x75/* u */) { return 4; } |
| 10722 | if (c === 0x55/* U */) { return 8; } |
| 10723 | return 0; |
| 10724 | } |
| 10725 | |
| 10726 | function fromDecimalCode(c) { |
| 10727 | if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { |
| 10728 | return c - 0x30; |
| 10729 | } |
| 10730 | |
| 10731 | return -1; |
| 10732 | } |
| 10733 | |
| 10734 | function simpleEscapeSequence(c) { |
| 10735 | return (c === 0x30/* 0 */) ? '\x00' : |
| 10736 | (c === 0x61/* a */) ? '\x07' : |
| 10737 | (c === 0x62/* b */) ? '\x08' : |
| 10738 | (c === 0x74/* t */) ? '\x09' : |
| 10739 | (c === 0x09/* Tab */) ? '\x09' : |
| 10740 | (c === 0x6E/* n */) ? '\x0A' : |
| 10741 | (c === 0x76/* v */) ? '\x0B' : |
| 10742 | (c === 0x66/* f */) ? '\x0C' : |
| 10743 | (c === 0x72/* r */) ? '\x0D' : |
| 10744 | (c === 0x65/* e */) ? '\x1B' : |
| 10745 | (c === 0x20/* Space */) ? ' ' : |
| 10746 | (c === 0x22/* " */) ? '\x22' : |
| 10747 | (c === 0x2F/* / */) ? '/' : |
| 10748 | (c === 0x5C/* \ */) ? '\x5C' : |
| 10749 | (c === 0x4E/* N */) ? '\x85' : |
| 10750 | (c === 0x5F/* _ */) ? '\xA0' : |
| 10751 | (c === 0x4C/* L */) ? '\u2028' : |
| 10752 | (c === 0x50/* P */) ? '\u2029' : ''; |
| 10753 | } |
| 10754 | |
| 10755 | function charFromCodepoint(c) { |
| 10756 | if (c <= 0xFFFF) { |
| 10757 | return String.fromCharCode(c); |
| 10758 | } |
| 10759 | // Encode UTF-16 surrogate pair |
| 10760 | // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF |
| 10761 | return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800, |
| 10762 | ((c - 0x010000) & 0x03FF) + 0xDC00); |
| 10763 | } |
| 10764 | |
| 10765 | var simpleEscapeCheck = new Array(256); // integer, for fast access |
| 10766 | var simpleEscapeMap = new Array(256); |
| 10767 | for (var i = 0; i < 256; i++) { |
| 10768 | simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; |
| 10769 | simpleEscapeMap[i] = simpleEscapeSequence(i); |
| 10770 | } |
| 10771 | |
| 10772 | |
| 10773 | function State(input, options) { |
| 10774 | this.input = input; |
| 10775 | |
| 10776 | this.filename = options['filename'] || null; |
| 10777 | this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; |
| 10778 | this.onWarning = options['onWarning'] || null; |
| 10779 | this.legacy = options['legacy'] || false; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10780 | this.json = options['json'] || false; |
| 10781 | this.listener = options['listener'] || null; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10782 | |
| 10783 | this.implicitTypes = this.schema.compiledImplicit; |
| 10784 | this.typeMap = this.schema.compiledTypeMap; |
| 10785 | |
| 10786 | this.length = input.length; |
| 10787 | this.position = 0; |
| 10788 | this.line = 0; |
| 10789 | this.lineStart = 0; |
| 10790 | this.lineIndent = 0; |
| 10791 | |
| 10792 | this.documents = []; |
| 10793 | |
| 10794 | /* |
| 10795 | this.version; |
| 10796 | this.checkLineBreaks; |
| 10797 | this.tagMap; |
| 10798 | this.anchorMap; |
| 10799 | this.tag; |
| 10800 | this.anchor; |
| 10801 | this.kind; |
| 10802 | this.result;*/ |
| 10803 | |
| 10804 | } |
| 10805 | |
| 10806 | |
| 10807 | function generateError(state, message) { |
| 10808 | return new YAMLException( |
| 10809 | message, |
| 10810 | new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart))); |
| 10811 | } |
| 10812 | |
| 10813 | function throwError(state, message) { |
| 10814 | throw generateError(state, message); |
| 10815 | } |
| 10816 | |
| 10817 | function throwWarning(state, message) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10818 | if (state.onWarning) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10819 | state.onWarning.call(null, generateError(state, message)); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10820 | } |
| 10821 | } |
| 10822 | |
| 10823 | |
| 10824 | var directiveHandlers = { |
| 10825 | |
| 10826 | YAML: function handleYamlDirective(state, name, args) { |
| 10827 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10828 | var match, major, minor; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10829 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10830 | if (state.version !== null) { |
| 10831 | throwError(state, 'duplication of %YAML directive'); |
| 10832 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10833 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10834 | if (args.length !== 1) { |
| 10835 | throwError(state, 'YAML directive accepts exactly one argument'); |
| 10836 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10837 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10838 | match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10839 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10840 | if (match === null) { |
| 10841 | throwError(state, 'ill-formed argument of the YAML directive'); |
| 10842 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10843 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10844 | major = parseInt(match[1], 10); |
| 10845 | minor = parseInt(match[2], 10); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10846 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10847 | if (major !== 1) { |
| 10848 | throwError(state, 'unacceptable YAML version of the document'); |
| 10849 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10850 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10851 | state.version = args[0]; |
| 10852 | state.checkLineBreaks = (minor < 2); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10853 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10854 | if (minor !== 1 && minor !== 2) { |
| 10855 | throwWarning(state, 'unsupported YAML version of the document'); |
| 10856 | } |
| 10857 | }, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10858 | |
| 10859 | TAG: function handleTagDirective(state, name, args) { |
| 10860 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10861 | var handle, prefix; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10862 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10863 | if (args.length !== 2) { |
| 10864 | throwError(state, 'TAG directive accepts exactly two arguments'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10865 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10866 | |
| 10867 | handle = args[0]; |
| 10868 | prefix = args[1]; |
| 10869 | |
| 10870 | if (!PATTERN_TAG_HANDLE.test(handle)) { |
| 10871 | throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); |
| 10872 | } |
| 10873 | |
| 10874 | if (_hasOwnProperty.call(state.tagMap, handle)) { |
| 10875 | throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); |
| 10876 | } |
| 10877 | |
| 10878 | if (!PATTERN_TAG_URI.test(prefix)) { |
| 10879 | throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); |
| 10880 | } |
| 10881 | |
| 10882 | state.tagMap[handle] = prefix; |
| 10883 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10884 | }; |
| 10885 | |
| 10886 | |
| 10887 | function captureSegment(state, start, end, checkJson) { |
| 10888 | var _position, _length, _character, _result; |
| 10889 | |
| 10890 | if (start < end) { |
| 10891 | _result = state.input.slice(start, end); |
| 10892 | |
| 10893 | if (checkJson) { |
| 10894 | for (_position = 0, _length = _result.length; |
| 10895 | _position < _length; |
| 10896 | _position += 1) { |
| 10897 | _character = _result.charCodeAt(_position); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10898 | if (!(_character === 0x09 || |
| 10899 | (0x20 <= _character && _character <= 0x10FFFF))) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10900 | throwError(state, 'expected valid JSON character'); |
| 10901 | } |
| 10902 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 10903 | } else if (PATTERN_NON_PRINTABLE.test(_result)) { |
| 10904 | throwError(state, 'the stream contains non-printable characters'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10905 | } |
| 10906 | |
| 10907 | state.result += _result; |
| 10908 | } |
| 10909 | } |
| 10910 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10911 | function mergeMappings(state, destination, source, overridableKeys) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10912 | var sourceKeys, key, index, quantity; |
| 10913 | |
| 10914 | if (!common.isObject(source)) { |
| 10915 | throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); |
| 10916 | } |
| 10917 | |
| 10918 | sourceKeys = Object.keys(source); |
| 10919 | |
| 10920 | for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { |
| 10921 | key = sourceKeys[index]; |
| 10922 | |
| 10923 | if (!_hasOwnProperty.call(destination, key)) { |
| 10924 | destination[key] = source[key]; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10925 | overridableKeys[key] = true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10926 | } |
| 10927 | } |
| 10928 | } |
| 10929 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10930 | function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10931 | var index, quantity; |
| 10932 | |
| 10933 | keyNode = String(keyNode); |
| 10934 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10935 | if (_result === null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10936 | _result = {}; |
| 10937 | } |
| 10938 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10939 | if (keyTag === 'tag:yaml.org,2002:merge') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10940 | if (Array.isArray(valueNode)) { |
| 10941 | for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10942 | mergeMappings(state, _result, valueNode[index], overridableKeys); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10943 | } |
| 10944 | } else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10945 | mergeMappings(state, _result, valueNode, overridableKeys); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10946 | } |
| 10947 | } else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10948 | if (!state.json && |
| 10949 | !_hasOwnProperty.call(overridableKeys, keyNode) && |
| 10950 | _hasOwnProperty.call(_result, keyNode)) { |
| 10951 | throwError(state, 'duplicated mapping key'); |
| 10952 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10953 | _result[keyNode] = valueNode; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10954 | delete overridableKeys[keyNode]; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10955 | } |
| 10956 | |
| 10957 | return _result; |
| 10958 | } |
| 10959 | |
| 10960 | function readLineBreak(state) { |
| 10961 | var ch; |
| 10962 | |
| 10963 | ch = state.input.charCodeAt(state.position); |
| 10964 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10965 | if (ch === 0x0A/* LF */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10966 | state.position++; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10967 | } else if (ch === 0x0D/* CR */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10968 | state.position++; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10969 | if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10970 | state.position++; |
| 10971 | } |
| 10972 | } else { |
| 10973 | throwError(state, 'a line break is expected'); |
| 10974 | } |
| 10975 | |
| 10976 | state.line += 1; |
| 10977 | state.lineStart = state.position; |
| 10978 | } |
| 10979 | |
| 10980 | function skipSeparationSpace(state, allowComments, checkIndent) { |
| 10981 | var lineBreaks = 0, |
| 10982 | ch = state.input.charCodeAt(state.position); |
| 10983 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10984 | while (ch !== 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10985 | while (is_WHITE_SPACE(ch)) { |
| 10986 | ch = state.input.charCodeAt(++state.position); |
| 10987 | } |
| 10988 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10989 | if (allowComments && ch === 0x23/* # */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10990 | do { |
| 10991 | ch = state.input.charCodeAt(++state.position); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 10992 | } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 10993 | } |
| 10994 | |
| 10995 | if (is_EOL(ch)) { |
| 10996 | readLineBreak(state); |
| 10997 | |
| 10998 | ch = state.input.charCodeAt(state.position); |
| 10999 | lineBreaks++; |
| 11000 | state.lineIndent = 0; |
| 11001 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11002 | while (ch === 0x20/* Space */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11003 | state.lineIndent++; |
| 11004 | ch = state.input.charCodeAt(++state.position); |
| 11005 | } |
| 11006 | } else { |
| 11007 | break; |
| 11008 | } |
| 11009 | } |
| 11010 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11011 | if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11012 | throwWarning(state, 'deficient indentation'); |
| 11013 | } |
| 11014 | |
| 11015 | return lineBreaks; |
| 11016 | } |
| 11017 | |
| 11018 | function testDocumentSeparator(state) { |
| 11019 | var _position = state.position, |
| 11020 | ch; |
| 11021 | |
| 11022 | ch = state.input.charCodeAt(_position); |
| 11023 | |
| 11024 | // Condition state.position === state.lineStart is tested |
| 11025 | // in parent on each call, for efficiency. No needs to test here again. |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11026 | if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && |
| 11027 | ch === state.input.charCodeAt(_position + 1) && |
| 11028 | ch === state.input.charCodeAt(_position + 2)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11029 | |
| 11030 | _position += 3; |
| 11031 | |
| 11032 | ch = state.input.charCodeAt(_position); |
| 11033 | |
| 11034 | if (ch === 0 || is_WS_OR_EOL(ch)) { |
| 11035 | return true; |
| 11036 | } |
| 11037 | } |
| 11038 | |
| 11039 | return false; |
| 11040 | } |
| 11041 | |
| 11042 | function writeFoldedLines(state, count) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11043 | if (count === 1) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11044 | state.result += ' '; |
| 11045 | } else if (count > 1) { |
| 11046 | state.result += common.repeat('\n', count - 1); |
| 11047 | } |
| 11048 | } |
| 11049 | |
| 11050 | |
| 11051 | function readPlainScalar(state, nodeIndent, withinFlowCollection) { |
| 11052 | var preceding, |
| 11053 | following, |
| 11054 | captureStart, |
| 11055 | captureEnd, |
| 11056 | hasPendingContent, |
| 11057 | _line, |
| 11058 | _lineStart, |
| 11059 | _lineIndent, |
| 11060 | _kind = state.kind, |
| 11061 | _result = state.result, |
| 11062 | ch; |
| 11063 | |
| 11064 | ch = state.input.charCodeAt(state.position); |
| 11065 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11066 | if (is_WS_OR_EOL(ch) || |
| 11067 | is_FLOW_INDICATOR(ch) || |
| 11068 | ch === 0x23/* # */ || |
| 11069 | ch === 0x26/* & */ || |
| 11070 | ch === 0x2A/* * */ || |
| 11071 | ch === 0x21/* ! */ || |
| 11072 | ch === 0x7C/* | */ || |
| 11073 | ch === 0x3E/* > */ || |
| 11074 | ch === 0x27/* ' */ || |
| 11075 | ch === 0x22/* " */ || |
| 11076 | ch === 0x25/* % */ || |
| 11077 | ch === 0x40/* @ */ || |
| 11078 | ch === 0x60/* ` */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11079 | return false; |
| 11080 | } |
| 11081 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11082 | if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11083 | following = state.input.charCodeAt(state.position + 1); |
| 11084 | |
| 11085 | if (is_WS_OR_EOL(following) || |
| 11086 | withinFlowCollection && is_FLOW_INDICATOR(following)) { |
| 11087 | return false; |
| 11088 | } |
| 11089 | } |
| 11090 | |
| 11091 | state.kind = 'scalar'; |
| 11092 | state.result = ''; |
| 11093 | captureStart = captureEnd = state.position; |
| 11094 | hasPendingContent = false; |
| 11095 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11096 | while (ch !== 0) { |
| 11097 | if (ch === 0x3A/* : */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11098 | following = state.input.charCodeAt(state.position + 1); |
| 11099 | |
| 11100 | if (is_WS_OR_EOL(following) || |
| 11101 | withinFlowCollection && is_FLOW_INDICATOR(following)) { |
| 11102 | break; |
| 11103 | } |
| 11104 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11105 | } else if (ch === 0x23/* # */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11106 | preceding = state.input.charCodeAt(state.position - 1); |
| 11107 | |
| 11108 | if (is_WS_OR_EOL(preceding)) { |
| 11109 | break; |
| 11110 | } |
| 11111 | |
| 11112 | } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || |
| 11113 | withinFlowCollection && is_FLOW_INDICATOR(ch)) { |
| 11114 | break; |
| 11115 | |
| 11116 | } else if (is_EOL(ch)) { |
| 11117 | _line = state.line; |
| 11118 | _lineStart = state.lineStart; |
| 11119 | _lineIndent = state.lineIndent; |
| 11120 | skipSeparationSpace(state, false, -1); |
| 11121 | |
| 11122 | if (state.lineIndent >= nodeIndent) { |
| 11123 | hasPendingContent = true; |
| 11124 | ch = state.input.charCodeAt(state.position); |
| 11125 | continue; |
| 11126 | } else { |
| 11127 | state.position = captureEnd; |
| 11128 | state.line = _line; |
| 11129 | state.lineStart = _lineStart; |
| 11130 | state.lineIndent = _lineIndent; |
| 11131 | break; |
| 11132 | } |
| 11133 | } |
| 11134 | |
| 11135 | if (hasPendingContent) { |
| 11136 | captureSegment(state, captureStart, captureEnd, false); |
| 11137 | writeFoldedLines(state, state.line - _line); |
| 11138 | captureStart = captureEnd = state.position; |
| 11139 | hasPendingContent = false; |
| 11140 | } |
| 11141 | |
| 11142 | if (!is_WHITE_SPACE(ch)) { |
| 11143 | captureEnd = state.position + 1; |
| 11144 | } |
| 11145 | |
| 11146 | ch = state.input.charCodeAt(++state.position); |
| 11147 | } |
| 11148 | |
| 11149 | captureSegment(state, captureStart, captureEnd, false); |
| 11150 | |
| 11151 | if (state.result) { |
| 11152 | return true; |
| 11153 | } |
| 11154 | |
| 11155 | state.kind = _kind; |
| 11156 | state.result = _result; |
| 11157 | return false; |
| 11158 | } |
| 11159 | |
| 11160 | function readSingleQuotedScalar(state, nodeIndent) { |
| 11161 | var ch, |
| 11162 | captureStart, captureEnd; |
| 11163 | |
| 11164 | ch = state.input.charCodeAt(state.position); |
| 11165 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11166 | if (ch !== 0x27/* ' */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11167 | return false; |
| 11168 | } |
| 11169 | |
| 11170 | state.kind = 'scalar'; |
| 11171 | state.result = ''; |
| 11172 | state.position++; |
| 11173 | captureStart = captureEnd = state.position; |
| 11174 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11175 | while ((ch = state.input.charCodeAt(state.position)) !== 0) { |
| 11176 | if (ch === 0x27/* ' */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11177 | captureSegment(state, captureStart, state.position, true); |
| 11178 | ch = state.input.charCodeAt(++state.position); |
| 11179 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11180 | if (ch === 0x27/* ' */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11181 | captureStart = captureEnd = state.position; |
| 11182 | state.position++; |
| 11183 | } else { |
| 11184 | return true; |
| 11185 | } |
| 11186 | |
| 11187 | } else if (is_EOL(ch)) { |
| 11188 | captureSegment(state, captureStart, captureEnd, true); |
| 11189 | writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); |
| 11190 | captureStart = captureEnd = state.position; |
| 11191 | |
| 11192 | } else if (state.position === state.lineStart && testDocumentSeparator(state)) { |
| 11193 | throwError(state, 'unexpected end of the document within a single quoted scalar'); |
| 11194 | |
| 11195 | } else { |
| 11196 | state.position++; |
| 11197 | captureEnd = state.position; |
| 11198 | } |
| 11199 | } |
| 11200 | |
| 11201 | throwError(state, 'unexpected end of the stream within a single quoted scalar'); |
| 11202 | } |
| 11203 | |
| 11204 | function readDoubleQuotedScalar(state, nodeIndent) { |
| 11205 | var captureStart, |
| 11206 | captureEnd, |
| 11207 | hexLength, |
| 11208 | hexResult, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 11209 | tmp, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11210 | ch; |
| 11211 | |
| 11212 | ch = state.input.charCodeAt(state.position); |
| 11213 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11214 | if (ch !== 0x22/* " */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11215 | return false; |
| 11216 | } |
| 11217 | |
| 11218 | state.kind = 'scalar'; |
| 11219 | state.result = ''; |
| 11220 | state.position++; |
| 11221 | captureStart = captureEnd = state.position; |
| 11222 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11223 | while ((ch = state.input.charCodeAt(state.position)) !== 0) { |
| 11224 | if (ch === 0x22/* " */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11225 | captureSegment(state, captureStart, state.position, true); |
| 11226 | state.position++; |
| 11227 | return true; |
| 11228 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11229 | } else if (ch === 0x5C/* \ */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11230 | captureSegment(state, captureStart, state.position, true); |
| 11231 | ch = state.input.charCodeAt(++state.position); |
| 11232 | |
| 11233 | if (is_EOL(ch)) { |
| 11234 | skipSeparationSpace(state, false, nodeIndent); |
| 11235 | |
| 11236 | // TODO: rework to inline fn with no type cast? |
| 11237 | } else if (ch < 256 && simpleEscapeCheck[ch]) { |
| 11238 | state.result += simpleEscapeMap[ch]; |
| 11239 | state.position++; |
| 11240 | |
| 11241 | } else if ((tmp = escapedHexLen(ch)) > 0) { |
| 11242 | hexLength = tmp; |
| 11243 | hexResult = 0; |
| 11244 | |
| 11245 | for (; hexLength > 0; hexLength--) { |
| 11246 | ch = state.input.charCodeAt(++state.position); |
| 11247 | |
| 11248 | if ((tmp = fromHexCode(ch)) >= 0) { |
| 11249 | hexResult = (hexResult << 4) + tmp; |
| 11250 | |
| 11251 | } else { |
| 11252 | throwError(state, 'expected hexadecimal character'); |
| 11253 | } |
| 11254 | } |
| 11255 | |
| 11256 | state.result += charFromCodepoint(hexResult); |
| 11257 | |
| 11258 | state.position++; |
| 11259 | |
| 11260 | } else { |
| 11261 | throwError(state, 'unknown escape sequence'); |
| 11262 | } |
| 11263 | |
| 11264 | captureStart = captureEnd = state.position; |
| 11265 | |
| 11266 | } else if (is_EOL(ch)) { |
| 11267 | captureSegment(state, captureStart, captureEnd, true); |
| 11268 | writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); |
| 11269 | captureStart = captureEnd = state.position; |
| 11270 | |
| 11271 | } else if (state.position === state.lineStart && testDocumentSeparator(state)) { |
| 11272 | throwError(state, 'unexpected end of the document within a double quoted scalar'); |
| 11273 | |
| 11274 | } else { |
| 11275 | state.position++; |
| 11276 | captureEnd = state.position; |
| 11277 | } |
| 11278 | } |
| 11279 | |
| 11280 | throwError(state, 'unexpected end of the stream within a double quoted scalar'); |
| 11281 | } |
| 11282 | |
| 11283 | function readFlowCollection(state, nodeIndent) { |
| 11284 | var readNext = true, |
| 11285 | _line, |
| 11286 | _tag = state.tag, |
| 11287 | _result, |
| 11288 | _anchor = state.anchor, |
| 11289 | following, |
| 11290 | terminator, |
| 11291 | isPair, |
| 11292 | isExplicitPair, |
| 11293 | isMapping, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11294 | overridableKeys = {}, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11295 | keyNode, |
| 11296 | keyTag, |
| 11297 | valueNode, |
| 11298 | ch; |
| 11299 | |
| 11300 | ch = state.input.charCodeAt(state.position); |
| 11301 | |
| 11302 | if (ch === 0x5B/* [ */) { |
| 11303 | terminator = 0x5D;/* ] */ |
| 11304 | isMapping = false; |
| 11305 | _result = []; |
| 11306 | } else if (ch === 0x7B/* { */) { |
| 11307 | terminator = 0x7D;/* } */ |
| 11308 | isMapping = true; |
| 11309 | _result = {}; |
| 11310 | } else { |
| 11311 | return false; |
| 11312 | } |
| 11313 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11314 | if (state.anchor !== null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11315 | state.anchorMap[state.anchor] = _result; |
| 11316 | } |
| 11317 | |
| 11318 | ch = state.input.charCodeAt(++state.position); |
| 11319 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11320 | while (ch !== 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11321 | skipSeparationSpace(state, true, nodeIndent); |
| 11322 | |
| 11323 | ch = state.input.charCodeAt(state.position); |
| 11324 | |
| 11325 | if (ch === terminator) { |
| 11326 | state.position++; |
| 11327 | state.tag = _tag; |
| 11328 | state.anchor = _anchor; |
| 11329 | state.kind = isMapping ? 'mapping' : 'sequence'; |
| 11330 | state.result = _result; |
| 11331 | return true; |
| 11332 | } else if (!readNext) { |
| 11333 | throwError(state, 'missed comma between flow collection entries'); |
| 11334 | } |
| 11335 | |
| 11336 | keyTag = keyNode = valueNode = null; |
| 11337 | isPair = isExplicitPair = false; |
| 11338 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11339 | if (ch === 0x3F/* ? */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11340 | following = state.input.charCodeAt(state.position + 1); |
| 11341 | |
| 11342 | if (is_WS_OR_EOL(following)) { |
| 11343 | isPair = isExplicitPair = true; |
| 11344 | state.position++; |
| 11345 | skipSeparationSpace(state, true, nodeIndent); |
| 11346 | } |
| 11347 | } |
| 11348 | |
| 11349 | _line = state.line; |
| 11350 | composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); |
| 11351 | keyTag = state.tag; |
| 11352 | keyNode = state.result; |
| 11353 | skipSeparationSpace(state, true, nodeIndent); |
| 11354 | |
| 11355 | ch = state.input.charCodeAt(state.position); |
| 11356 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11357 | if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11358 | isPair = true; |
| 11359 | ch = state.input.charCodeAt(++state.position); |
| 11360 | skipSeparationSpace(state, true, nodeIndent); |
| 11361 | composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); |
| 11362 | valueNode = state.result; |
| 11363 | } |
| 11364 | |
| 11365 | if (isMapping) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11366 | storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11367 | } else if (isPair) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11368 | _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode)); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11369 | } else { |
| 11370 | _result.push(keyNode); |
| 11371 | } |
| 11372 | |
| 11373 | skipSeparationSpace(state, true, nodeIndent); |
| 11374 | |
| 11375 | ch = state.input.charCodeAt(state.position); |
| 11376 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11377 | if (ch === 0x2C/* , */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11378 | readNext = true; |
| 11379 | ch = state.input.charCodeAt(++state.position); |
| 11380 | } else { |
| 11381 | readNext = false; |
| 11382 | } |
| 11383 | } |
| 11384 | |
| 11385 | throwError(state, 'unexpected end of the stream within a flow collection'); |
| 11386 | } |
| 11387 | |
| 11388 | function readBlockScalar(state, nodeIndent) { |
| 11389 | var captureStart, |
| 11390 | folding, |
| 11391 | chomping = CHOMPING_CLIP, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11392 | didReadContent = false, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11393 | detectedIndent = false, |
| 11394 | textIndent = nodeIndent, |
| 11395 | emptyLines = 0, |
| 11396 | atMoreIndented = false, |
| 11397 | tmp, |
| 11398 | ch; |
| 11399 | |
| 11400 | ch = state.input.charCodeAt(state.position); |
| 11401 | |
| 11402 | if (ch === 0x7C/* | */) { |
| 11403 | folding = false; |
| 11404 | } else if (ch === 0x3E/* > */) { |
| 11405 | folding = true; |
| 11406 | } else { |
| 11407 | return false; |
| 11408 | } |
| 11409 | |
| 11410 | state.kind = 'scalar'; |
| 11411 | state.result = ''; |
| 11412 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11413 | while (ch !== 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11414 | ch = state.input.charCodeAt(++state.position); |
| 11415 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11416 | if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11417 | if (CHOMPING_CLIP === chomping) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11418 | chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11419 | } else { |
| 11420 | throwError(state, 'repeat of a chomping mode identifier'); |
| 11421 | } |
| 11422 | |
| 11423 | } else if ((tmp = fromDecimalCode(ch)) >= 0) { |
| 11424 | if (tmp === 0) { |
| 11425 | throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); |
| 11426 | } else if (!detectedIndent) { |
| 11427 | textIndent = nodeIndent + tmp - 1; |
| 11428 | detectedIndent = true; |
| 11429 | } else { |
| 11430 | throwError(state, 'repeat of an indentation width identifier'); |
| 11431 | } |
| 11432 | |
| 11433 | } else { |
| 11434 | break; |
| 11435 | } |
| 11436 | } |
| 11437 | |
| 11438 | if (is_WHITE_SPACE(ch)) { |
| 11439 | do { ch = state.input.charCodeAt(++state.position); } |
| 11440 | while (is_WHITE_SPACE(ch)); |
| 11441 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11442 | if (ch === 0x23/* # */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11443 | do { ch = state.input.charCodeAt(++state.position); } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11444 | while (!is_EOL(ch) && (ch !== 0)); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11445 | } |
| 11446 | } |
| 11447 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11448 | while (ch !== 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11449 | readLineBreak(state); |
| 11450 | state.lineIndent = 0; |
| 11451 | |
| 11452 | ch = state.input.charCodeAt(state.position); |
| 11453 | |
| 11454 | while ((!detectedIndent || state.lineIndent < textIndent) && |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11455 | (ch === 0x20/* Space */)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11456 | state.lineIndent++; |
| 11457 | ch = state.input.charCodeAt(++state.position); |
| 11458 | } |
| 11459 | |
| 11460 | if (!detectedIndent && state.lineIndent > textIndent) { |
| 11461 | textIndent = state.lineIndent; |
| 11462 | } |
| 11463 | |
| 11464 | if (is_EOL(ch)) { |
| 11465 | emptyLines++; |
| 11466 | continue; |
| 11467 | } |
| 11468 | |
| 11469 | // End of the scalar. |
| 11470 | if (state.lineIndent < textIndent) { |
| 11471 | |
| 11472 | // Perform the chomping. |
| 11473 | if (chomping === CHOMPING_KEEP) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11474 | state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11475 | } else if (chomping === CHOMPING_CLIP) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11476 | if (didReadContent) { // i.e. only if the scalar is not empty. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11477 | state.result += '\n'; |
| 11478 | } |
| 11479 | } |
| 11480 | |
| 11481 | // Break this `while` cycle and go to the funciton's epilogue. |
| 11482 | break; |
| 11483 | } |
| 11484 | |
| 11485 | // Folded style: use fancy rules to handle line breaks. |
| 11486 | if (folding) { |
| 11487 | |
| 11488 | // Lines starting with white space characters (more-indented lines) are not folded. |
| 11489 | if (is_WHITE_SPACE(ch)) { |
| 11490 | atMoreIndented = true; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11491 | // except for the first content line (cf. Example 8.1) |
| 11492 | state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11493 | |
| 11494 | // End of more-indented block. |
| 11495 | } else if (atMoreIndented) { |
| 11496 | atMoreIndented = false; |
| 11497 | state.result += common.repeat('\n', emptyLines + 1); |
| 11498 | |
| 11499 | // Just one line break - perceive as the same line. |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11500 | } else if (emptyLines === 0) { |
| 11501 | if (didReadContent) { // i.e. only if we have already read some scalar content. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11502 | state.result += ' '; |
| 11503 | } |
| 11504 | |
| 11505 | // Several line breaks - perceive as different lines. |
| 11506 | } else { |
| 11507 | state.result += common.repeat('\n', emptyLines); |
| 11508 | } |
| 11509 | |
| 11510 | // Literal style: just add exact number of line breaks between content lines. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11511 | } else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11512 | // Keep all line breaks except the header line break. |
| 11513 | state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11514 | } |
| 11515 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11516 | didReadContent = true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11517 | detectedIndent = true; |
| 11518 | emptyLines = 0; |
| 11519 | captureStart = state.position; |
| 11520 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11521 | while (!is_EOL(ch) && (ch !== 0)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11522 | ch = state.input.charCodeAt(++state.position); |
| 11523 | } |
| 11524 | |
| 11525 | captureSegment(state, captureStart, state.position, false); |
| 11526 | } |
| 11527 | |
| 11528 | return true; |
| 11529 | } |
| 11530 | |
| 11531 | function readBlockSequence(state, nodeIndent) { |
| 11532 | var _line, |
| 11533 | _tag = state.tag, |
| 11534 | _anchor = state.anchor, |
| 11535 | _result = [], |
| 11536 | following, |
| 11537 | detected = false, |
| 11538 | ch; |
| 11539 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11540 | if (state.anchor !== null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11541 | state.anchorMap[state.anchor] = _result; |
| 11542 | } |
| 11543 | |
| 11544 | ch = state.input.charCodeAt(state.position); |
| 11545 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11546 | while (ch !== 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11547 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11548 | if (ch !== 0x2D/* - */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11549 | break; |
| 11550 | } |
| 11551 | |
| 11552 | following = state.input.charCodeAt(state.position + 1); |
| 11553 | |
| 11554 | if (!is_WS_OR_EOL(following)) { |
| 11555 | break; |
| 11556 | } |
| 11557 | |
| 11558 | detected = true; |
| 11559 | state.position++; |
| 11560 | |
| 11561 | if (skipSeparationSpace(state, true, -1)) { |
| 11562 | if (state.lineIndent <= nodeIndent) { |
| 11563 | _result.push(null); |
| 11564 | ch = state.input.charCodeAt(state.position); |
| 11565 | continue; |
| 11566 | } |
| 11567 | } |
| 11568 | |
| 11569 | _line = state.line; |
| 11570 | composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); |
| 11571 | _result.push(state.result); |
| 11572 | skipSeparationSpace(state, true, -1); |
| 11573 | |
| 11574 | ch = state.input.charCodeAt(state.position); |
| 11575 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11576 | if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11577 | throwError(state, 'bad indentation of a sequence entry'); |
| 11578 | } else if (state.lineIndent < nodeIndent) { |
| 11579 | break; |
| 11580 | } |
| 11581 | } |
| 11582 | |
| 11583 | if (detected) { |
| 11584 | state.tag = _tag; |
| 11585 | state.anchor = _anchor; |
| 11586 | state.kind = 'sequence'; |
| 11587 | state.result = _result; |
| 11588 | return true; |
| 11589 | } |
| 11590 | return false; |
| 11591 | } |
| 11592 | |
| 11593 | function readBlockMapping(state, nodeIndent, flowIndent) { |
| 11594 | var following, |
| 11595 | allowCompact, |
| 11596 | _line, |
| 11597 | _tag = state.tag, |
| 11598 | _anchor = state.anchor, |
| 11599 | _result = {}, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11600 | overridableKeys = {}, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11601 | keyTag = null, |
| 11602 | keyNode = null, |
| 11603 | valueNode = null, |
| 11604 | atExplicitKey = false, |
| 11605 | detected = false, |
| 11606 | ch; |
| 11607 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11608 | if (state.anchor !== null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11609 | state.anchorMap[state.anchor] = _result; |
| 11610 | } |
| 11611 | |
| 11612 | ch = state.input.charCodeAt(state.position); |
| 11613 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11614 | while (ch !== 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11615 | following = state.input.charCodeAt(state.position + 1); |
| 11616 | _line = state.line; // Save the current line. |
| 11617 | |
| 11618 | // |
| 11619 | // Explicit notation case. There are two separate blocks: |
| 11620 | // first for the key (denoted by "?") and second for the value (denoted by ":") |
| 11621 | // |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11622 | if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11623 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11624 | if (ch === 0x3F/* ? */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11625 | if (atExplicitKey) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11626 | storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11627 | keyTag = keyNode = valueNode = null; |
| 11628 | } |
| 11629 | |
| 11630 | detected = true; |
| 11631 | atExplicitKey = true; |
| 11632 | allowCompact = true; |
| 11633 | |
| 11634 | } else if (atExplicitKey) { |
| 11635 | // i.e. 0x3A/* : */ === character after the explicit key. |
| 11636 | atExplicitKey = false; |
| 11637 | allowCompact = true; |
| 11638 | |
| 11639 | } else { |
| 11640 | throwError(state, 'incomplete explicit mapping pair; a key node is missed'); |
| 11641 | } |
| 11642 | |
| 11643 | state.position += 1; |
| 11644 | ch = following; |
| 11645 | |
| 11646 | // |
| 11647 | // Implicit notation case. Flow-style node as the key first, then ":", and the value. |
| 11648 | // |
| 11649 | } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { |
| 11650 | |
| 11651 | if (state.line === _line) { |
| 11652 | ch = state.input.charCodeAt(state.position); |
| 11653 | |
| 11654 | while (is_WHITE_SPACE(ch)) { |
| 11655 | ch = state.input.charCodeAt(++state.position); |
| 11656 | } |
| 11657 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11658 | if (ch === 0x3A/* : */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11659 | ch = state.input.charCodeAt(++state.position); |
| 11660 | |
| 11661 | if (!is_WS_OR_EOL(ch)) { |
| 11662 | throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); |
| 11663 | } |
| 11664 | |
| 11665 | if (atExplicitKey) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11666 | storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11667 | keyTag = keyNode = valueNode = null; |
| 11668 | } |
| 11669 | |
| 11670 | detected = true; |
| 11671 | atExplicitKey = false; |
| 11672 | allowCompact = false; |
| 11673 | keyTag = state.tag; |
| 11674 | keyNode = state.result; |
| 11675 | |
| 11676 | } else if (detected) { |
| 11677 | throwError(state, 'can not read an implicit mapping pair; a colon is missed'); |
| 11678 | |
| 11679 | } else { |
| 11680 | state.tag = _tag; |
| 11681 | state.anchor = _anchor; |
| 11682 | return true; // Keep the result of `composeNode`. |
| 11683 | } |
| 11684 | |
| 11685 | } else if (detected) { |
| 11686 | throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); |
| 11687 | |
| 11688 | } else { |
| 11689 | state.tag = _tag; |
| 11690 | state.anchor = _anchor; |
| 11691 | return true; // Keep the result of `composeNode`. |
| 11692 | } |
| 11693 | |
| 11694 | } else { |
| 11695 | break; // Reading is done. Go to the epilogue. |
| 11696 | } |
| 11697 | |
| 11698 | // |
| 11699 | // Common reading code for both explicit and implicit notations. |
| 11700 | // |
| 11701 | if (state.line === _line || state.lineIndent > nodeIndent) { |
| 11702 | if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { |
| 11703 | if (atExplicitKey) { |
| 11704 | keyNode = state.result; |
| 11705 | } else { |
| 11706 | valueNode = state.result; |
| 11707 | } |
| 11708 | } |
| 11709 | |
| 11710 | if (!atExplicitKey) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11711 | storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11712 | keyTag = keyNode = valueNode = null; |
| 11713 | } |
| 11714 | |
| 11715 | skipSeparationSpace(state, true, -1); |
| 11716 | ch = state.input.charCodeAt(state.position); |
| 11717 | } |
| 11718 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11719 | if (state.lineIndent > nodeIndent && (ch !== 0)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11720 | throwError(state, 'bad indentation of a mapping entry'); |
| 11721 | } else if (state.lineIndent < nodeIndent) { |
| 11722 | break; |
| 11723 | } |
| 11724 | } |
| 11725 | |
| 11726 | // |
| 11727 | // Epilogue. |
| 11728 | // |
| 11729 | |
| 11730 | // Special case: last mapping's node contains only the key in explicit notation. |
| 11731 | if (atExplicitKey) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11732 | storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11733 | } |
| 11734 | |
| 11735 | // Expose the resulting mapping. |
| 11736 | if (detected) { |
| 11737 | state.tag = _tag; |
| 11738 | state.anchor = _anchor; |
| 11739 | state.kind = 'mapping'; |
| 11740 | state.result = _result; |
| 11741 | } |
| 11742 | |
| 11743 | return detected; |
| 11744 | } |
| 11745 | |
| 11746 | function readTagProperty(state) { |
| 11747 | var _position, |
| 11748 | isVerbatim = false, |
| 11749 | isNamed = false, |
| 11750 | tagHandle, |
| 11751 | tagName, |
| 11752 | ch; |
| 11753 | |
| 11754 | ch = state.input.charCodeAt(state.position); |
| 11755 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11756 | if (ch !== 0x21/* ! */) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11757 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11758 | if (state.tag !== null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11759 | throwError(state, 'duplication of a tag property'); |
| 11760 | } |
| 11761 | |
| 11762 | ch = state.input.charCodeAt(++state.position); |
| 11763 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11764 | if (ch === 0x3C/* < */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11765 | isVerbatim = true; |
| 11766 | ch = state.input.charCodeAt(++state.position); |
| 11767 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11768 | } else if (ch === 0x21/* ! */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11769 | isNamed = true; |
| 11770 | tagHandle = '!!'; |
| 11771 | ch = state.input.charCodeAt(++state.position); |
| 11772 | |
| 11773 | } else { |
| 11774 | tagHandle = '!'; |
| 11775 | } |
| 11776 | |
| 11777 | _position = state.position; |
| 11778 | |
| 11779 | if (isVerbatim) { |
| 11780 | do { ch = state.input.charCodeAt(++state.position); } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11781 | while (ch !== 0 && ch !== 0x3E/* > */); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11782 | |
| 11783 | if (state.position < state.length) { |
| 11784 | tagName = state.input.slice(_position, state.position); |
| 11785 | ch = state.input.charCodeAt(++state.position); |
| 11786 | } else { |
| 11787 | throwError(state, 'unexpected end of the stream within a verbatim tag'); |
| 11788 | } |
| 11789 | } else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11790 | while (ch !== 0 && !is_WS_OR_EOL(ch)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11791 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11792 | if (ch === 0x21/* ! */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11793 | if (!isNamed) { |
| 11794 | tagHandle = state.input.slice(_position - 1, state.position + 1); |
| 11795 | |
| 11796 | if (!PATTERN_TAG_HANDLE.test(tagHandle)) { |
| 11797 | throwError(state, 'named tag handle cannot contain such characters'); |
| 11798 | } |
| 11799 | |
| 11800 | isNamed = true; |
| 11801 | _position = state.position + 1; |
| 11802 | } else { |
| 11803 | throwError(state, 'tag suffix cannot contain exclamation marks'); |
| 11804 | } |
| 11805 | } |
| 11806 | |
| 11807 | ch = state.input.charCodeAt(++state.position); |
| 11808 | } |
| 11809 | |
| 11810 | tagName = state.input.slice(_position, state.position); |
| 11811 | |
| 11812 | if (PATTERN_FLOW_INDICATORS.test(tagName)) { |
| 11813 | throwError(state, 'tag suffix cannot contain flow indicator characters'); |
| 11814 | } |
| 11815 | } |
| 11816 | |
| 11817 | if (tagName && !PATTERN_TAG_URI.test(tagName)) { |
| 11818 | throwError(state, 'tag name cannot contain such characters: ' + tagName); |
| 11819 | } |
| 11820 | |
| 11821 | if (isVerbatim) { |
| 11822 | state.tag = tagName; |
| 11823 | |
| 11824 | } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) { |
| 11825 | state.tag = state.tagMap[tagHandle] + tagName; |
| 11826 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11827 | } else if (tagHandle === '!') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11828 | state.tag = '!' + tagName; |
| 11829 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11830 | } else if (tagHandle === '!!') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11831 | state.tag = 'tag:yaml.org,2002:' + tagName; |
| 11832 | |
| 11833 | } else { |
| 11834 | throwError(state, 'undeclared tag handle "' + tagHandle + '"'); |
| 11835 | } |
| 11836 | |
| 11837 | return true; |
| 11838 | } |
| 11839 | |
| 11840 | function readAnchorProperty(state) { |
| 11841 | var _position, |
| 11842 | ch; |
| 11843 | |
| 11844 | ch = state.input.charCodeAt(state.position); |
| 11845 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11846 | if (ch !== 0x26/* & */) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11847 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11848 | if (state.anchor !== null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11849 | throwError(state, 'duplication of an anchor property'); |
| 11850 | } |
| 11851 | |
| 11852 | ch = state.input.charCodeAt(++state.position); |
| 11853 | _position = state.position; |
| 11854 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11855 | while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11856 | ch = state.input.charCodeAt(++state.position); |
| 11857 | } |
| 11858 | |
| 11859 | if (state.position === _position) { |
| 11860 | throwError(state, 'name of an anchor node must contain at least one character'); |
| 11861 | } |
| 11862 | |
| 11863 | state.anchor = state.input.slice(_position, state.position); |
| 11864 | return true; |
| 11865 | } |
| 11866 | |
| 11867 | function readAlias(state) { |
| 11868 | var _position, alias, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11869 | ch; |
| 11870 | |
| 11871 | ch = state.input.charCodeAt(state.position); |
| 11872 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11873 | if (ch !== 0x2A/* * */) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11874 | |
| 11875 | ch = state.input.charCodeAt(++state.position); |
| 11876 | _position = state.position; |
| 11877 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11878 | while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11879 | ch = state.input.charCodeAt(++state.position); |
| 11880 | } |
| 11881 | |
| 11882 | if (state.position === _position) { |
| 11883 | throwError(state, 'name of an alias node must contain at least one character'); |
| 11884 | } |
| 11885 | |
| 11886 | alias = state.input.slice(_position, state.position); |
| 11887 | |
| 11888 | if (!state.anchorMap.hasOwnProperty(alias)) { |
| 11889 | throwError(state, 'unidentified alias "' + alias + '"'); |
| 11890 | } |
| 11891 | |
| 11892 | state.result = state.anchorMap[alias]; |
| 11893 | skipSeparationSpace(state, true, -1); |
| 11894 | return true; |
| 11895 | } |
| 11896 | |
| 11897 | function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { |
| 11898 | var allowBlockStyles, |
| 11899 | allowBlockScalars, |
| 11900 | allowBlockCollections, |
| 11901 | indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent |
| 11902 | atNewLine = false, |
| 11903 | hasContent = false, |
| 11904 | typeIndex, |
| 11905 | typeQuantity, |
| 11906 | type, |
| 11907 | flowIndent, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 11908 | blockIndent; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11909 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11910 | if (state.listener !== null) { |
| 11911 | state.listener('open', state); |
| 11912 | } |
| 11913 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11914 | state.tag = null; |
| 11915 | state.anchor = null; |
| 11916 | state.kind = null; |
| 11917 | state.result = null; |
| 11918 | |
| 11919 | allowBlockStyles = allowBlockScalars = allowBlockCollections = |
| 11920 | CONTEXT_BLOCK_OUT === nodeContext || |
| 11921 | CONTEXT_BLOCK_IN === nodeContext; |
| 11922 | |
| 11923 | if (allowToSeek) { |
| 11924 | if (skipSeparationSpace(state, true, -1)) { |
| 11925 | atNewLine = true; |
| 11926 | |
| 11927 | if (state.lineIndent > parentIndent) { |
| 11928 | indentStatus = 1; |
| 11929 | } else if (state.lineIndent === parentIndent) { |
| 11930 | indentStatus = 0; |
| 11931 | } else if (state.lineIndent < parentIndent) { |
| 11932 | indentStatus = -1; |
| 11933 | } |
| 11934 | } |
| 11935 | } |
| 11936 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11937 | if (indentStatus === 1) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11938 | while (readTagProperty(state) || readAnchorProperty(state)) { |
| 11939 | if (skipSeparationSpace(state, true, -1)) { |
| 11940 | atNewLine = true; |
| 11941 | allowBlockCollections = allowBlockStyles; |
| 11942 | |
| 11943 | if (state.lineIndent > parentIndent) { |
| 11944 | indentStatus = 1; |
| 11945 | } else if (state.lineIndent === parentIndent) { |
| 11946 | indentStatus = 0; |
| 11947 | } else if (state.lineIndent < parentIndent) { |
| 11948 | indentStatus = -1; |
| 11949 | } |
| 11950 | } else { |
| 11951 | allowBlockCollections = false; |
| 11952 | } |
| 11953 | } |
| 11954 | } |
| 11955 | |
| 11956 | if (allowBlockCollections) { |
| 11957 | allowBlockCollections = atNewLine || allowCompact; |
| 11958 | } |
| 11959 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11960 | if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11961 | if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { |
| 11962 | flowIndent = parentIndent; |
| 11963 | } else { |
| 11964 | flowIndent = parentIndent + 1; |
| 11965 | } |
| 11966 | |
| 11967 | blockIndent = state.position - state.lineStart; |
| 11968 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11969 | if (indentStatus === 1) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11970 | if (allowBlockCollections && |
| 11971 | (readBlockSequence(state, blockIndent) || |
| 11972 | readBlockMapping(state, blockIndent, flowIndent)) || |
| 11973 | readFlowCollection(state, flowIndent)) { |
| 11974 | hasContent = true; |
| 11975 | } else { |
| 11976 | if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || |
| 11977 | readSingleQuotedScalar(state, flowIndent) || |
| 11978 | readDoubleQuotedScalar(state, flowIndent)) { |
| 11979 | hasContent = true; |
| 11980 | |
| 11981 | } else if (readAlias(state)) { |
| 11982 | hasContent = true; |
| 11983 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11984 | if (state.tag !== null || state.anchor !== null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11985 | throwError(state, 'alias node should not have any properties'); |
| 11986 | } |
| 11987 | |
| 11988 | } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { |
| 11989 | hasContent = true; |
| 11990 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11991 | if (state.tag === null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11992 | state.tag = '?'; |
| 11993 | } |
| 11994 | } |
| 11995 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 11996 | if (state.anchor !== null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 11997 | state.anchorMap[state.anchor] = state.result; |
| 11998 | } |
| 11999 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12000 | } else if (indentStatus === 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12001 | // Special case: block sequences are allowed to have same indentation level as the parent. |
| 12002 | // http://www.yaml.org/spec/1.2/spec.html#id2799784 |
| 12003 | hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); |
| 12004 | } |
| 12005 | } |
| 12006 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12007 | if (state.tag !== null && state.tag !== '!') { |
| 12008 | if (state.tag === '?') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12009 | for (typeIndex = 0, typeQuantity = state.implicitTypes.length; |
| 12010 | typeIndex < typeQuantity; |
| 12011 | typeIndex += 1) { |
| 12012 | type = state.implicitTypes[typeIndex]; |
| 12013 | |
| 12014 | // Implicit resolving is not allowed for non-scalar types, and '?' |
| 12015 | // non-specific tag is only assigned to plain scalars. So, it isn't |
| 12016 | // needed to check for 'kind' conformity. |
| 12017 | |
| 12018 | if (type.resolve(state.result)) { // `state.result` updated in resolver if matched |
| 12019 | state.result = type.construct(state.result); |
| 12020 | state.tag = type.tag; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12021 | if (state.anchor !== null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12022 | state.anchorMap[state.anchor] = state.result; |
| 12023 | } |
| 12024 | break; |
| 12025 | } |
| 12026 | } |
| 12027 | } else if (_hasOwnProperty.call(state.typeMap, state.tag)) { |
| 12028 | type = state.typeMap[state.tag]; |
| 12029 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12030 | if (state.result !== null && type.kind !== state.kind) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12031 | throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); |
| 12032 | } |
| 12033 | |
| 12034 | if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched |
| 12035 | throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); |
| 12036 | } else { |
| 12037 | state.result = type.construct(state.result); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12038 | if (state.anchor !== null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12039 | state.anchorMap[state.anchor] = state.result; |
| 12040 | } |
| 12041 | } |
| 12042 | } else { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 12043 | throwError(state, 'unknown tag !<' + state.tag + '>'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12044 | } |
| 12045 | } |
| 12046 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12047 | if (state.listener !== null) { |
| 12048 | state.listener('close', state); |
| 12049 | } |
| 12050 | return state.tag !== null || state.anchor !== null || hasContent; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12051 | } |
| 12052 | |
| 12053 | function readDocument(state) { |
| 12054 | var documentStart = state.position, |
| 12055 | _position, |
| 12056 | directiveName, |
| 12057 | directiveArgs, |
| 12058 | hasDirectives = false, |
| 12059 | ch; |
| 12060 | |
| 12061 | state.version = null; |
| 12062 | state.checkLineBreaks = state.legacy; |
| 12063 | state.tagMap = {}; |
| 12064 | state.anchorMap = {}; |
| 12065 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12066 | while ((ch = state.input.charCodeAt(state.position)) !== 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12067 | skipSeparationSpace(state, true, -1); |
| 12068 | |
| 12069 | ch = state.input.charCodeAt(state.position); |
| 12070 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12071 | if (state.lineIndent > 0 || ch !== 0x25/* % */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12072 | break; |
| 12073 | } |
| 12074 | |
| 12075 | hasDirectives = true; |
| 12076 | ch = state.input.charCodeAt(++state.position); |
| 12077 | _position = state.position; |
| 12078 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12079 | while (ch !== 0 && !is_WS_OR_EOL(ch)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12080 | ch = state.input.charCodeAt(++state.position); |
| 12081 | } |
| 12082 | |
| 12083 | directiveName = state.input.slice(_position, state.position); |
| 12084 | directiveArgs = []; |
| 12085 | |
| 12086 | if (directiveName.length < 1) { |
| 12087 | throwError(state, 'directive name must not be less than one character in length'); |
| 12088 | } |
| 12089 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12090 | while (ch !== 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12091 | while (is_WHITE_SPACE(ch)) { |
| 12092 | ch = state.input.charCodeAt(++state.position); |
| 12093 | } |
| 12094 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12095 | if (ch === 0x23/* # */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12096 | do { ch = state.input.charCodeAt(++state.position); } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12097 | while (ch !== 0 && !is_EOL(ch)); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12098 | break; |
| 12099 | } |
| 12100 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12101 | if (is_EOL(ch)) break; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12102 | |
| 12103 | _position = state.position; |
| 12104 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12105 | while (ch !== 0 && !is_WS_OR_EOL(ch)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12106 | ch = state.input.charCodeAt(++state.position); |
| 12107 | } |
| 12108 | |
| 12109 | directiveArgs.push(state.input.slice(_position, state.position)); |
| 12110 | } |
| 12111 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12112 | if (ch !== 0) readLineBreak(state); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12113 | |
| 12114 | if (_hasOwnProperty.call(directiveHandlers, directiveName)) { |
| 12115 | directiveHandlers[directiveName](state, directiveName, directiveArgs); |
| 12116 | } else { |
| 12117 | throwWarning(state, 'unknown document directive "' + directiveName + '"'); |
| 12118 | } |
| 12119 | } |
| 12120 | |
| 12121 | skipSeparationSpace(state, true, -1); |
| 12122 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12123 | if (state.lineIndent === 0 && |
| 12124 | state.input.charCodeAt(state.position) === 0x2D/* - */ && |
| 12125 | state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && |
| 12126 | state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12127 | state.position += 3; |
| 12128 | skipSeparationSpace(state, true, -1); |
| 12129 | |
| 12130 | } else if (hasDirectives) { |
| 12131 | throwError(state, 'directives end mark is expected'); |
| 12132 | } |
| 12133 | |
| 12134 | composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); |
| 12135 | skipSeparationSpace(state, true, -1); |
| 12136 | |
| 12137 | if (state.checkLineBreaks && |
| 12138 | PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { |
| 12139 | throwWarning(state, 'non-ASCII line breaks are interpreted as content'); |
| 12140 | } |
| 12141 | |
| 12142 | state.documents.push(state.result); |
| 12143 | |
| 12144 | if (state.position === state.lineStart && testDocumentSeparator(state)) { |
| 12145 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12146 | if (state.input.charCodeAt(state.position) === 0x2E/* . */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12147 | state.position += 3; |
| 12148 | skipSeparationSpace(state, true, -1); |
| 12149 | } |
| 12150 | return; |
| 12151 | } |
| 12152 | |
| 12153 | if (state.position < (state.length - 1)) { |
| 12154 | throwError(state, 'end of the stream or a document separator is expected'); |
| 12155 | } else { |
| 12156 | return; |
| 12157 | } |
| 12158 | } |
| 12159 | |
| 12160 | |
| 12161 | function loadDocuments(input, options) { |
| 12162 | input = String(input); |
| 12163 | options = options || {}; |
| 12164 | |
| 12165 | if (input.length !== 0) { |
| 12166 | |
| 12167 | // Add tailing `\n` if not exists |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12168 | if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && |
| 12169 | input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12170 | input += '\n'; |
| 12171 | } |
| 12172 | |
| 12173 | // Strip BOM |
| 12174 | if (input.charCodeAt(0) === 0xFEFF) { |
| 12175 | input = input.slice(1); |
| 12176 | } |
| 12177 | } |
| 12178 | |
| 12179 | var state = new State(input, options); |
| 12180 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12181 | // Use 0 as string terminator. That significantly simplifies bounds check. |
| 12182 | state.input += '\0'; |
| 12183 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12184 | while (state.input.charCodeAt(state.position) === 0x20/* Space */) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12185 | state.lineIndent += 1; |
| 12186 | state.position += 1; |
| 12187 | } |
| 12188 | |
| 12189 | while (state.position < (state.length - 1)) { |
| 12190 | readDocument(state); |
| 12191 | } |
| 12192 | |
| 12193 | return state.documents; |
| 12194 | } |
| 12195 | |
| 12196 | |
| 12197 | function loadAll(input, iterator, options) { |
| 12198 | var documents = loadDocuments(input, options), index, length; |
| 12199 | |
| 12200 | for (index = 0, length = documents.length; index < length; index += 1) { |
| 12201 | iterator(documents[index]); |
| 12202 | } |
| 12203 | } |
| 12204 | |
| 12205 | |
| 12206 | function load(input, options) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 12207 | var documents = loadDocuments(input, options); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12208 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12209 | if (documents.length === 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12210 | /*eslint-disable no-undefined*/ |
| 12211 | return undefined; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12212 | } else if (documents.length === 1) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12213 | return documents[0]; |
| 12214 | } |
| 12215 | throw new YAMLException('expected a single document in the stream, but found more'); |
| 12216 | } |
| 12217 | |
| 12218 | |
| 12219 | function safeLoadAll(input, output, options) { |
| 12220 | loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); |
| 12221 | } |
| 12222 | |
| 12223 | |
| 12224 | function safeLoad(input, options) { |
| 12225 | return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); |
| 12226 | } |
| 12227 | |
| 12228 | |
| 12229 | module.exports.loadAll = loadAll; |
| 12230 | module.exports.load = load; |
| 12231 | module.exports.safeLoadAll = safeLoadAll; |
| 12232 | module.exports.safeLoad = safeLoad; |
| 12233 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12234 | },{"./common":21,"./exception":23,"./mark":25,"./schema/default_full":28,"./schema/default_safe":29}],25:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12235 | 'use strict'; |
| 12236 | |
| 12237 | |
| 12238 | var common = require('./common'); |
| 12239 | |
| 12240 | |
| 12241 | function Mark(name, buffer, position, line, column) { |
| 12242 | this.name = name; |
| 12243 | this.buffer = buffer; |
| 12244 | this.position = position; |
| 12245 | this.line = line; |
| 12246 | this.column = column; |
| 12247 | } |
| 12248 | |
| 12249 | |
| 12250 | Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { |
| 12251 | var head, start, tail, end, snippet; |
| 12252 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12253 | if (!this.buffer) return null; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12254 | |
| 12255 | indent = indent || 4; |
| 12256 | maxLength = maxLength || 75; |
| 12257 | |
| 12258 | head = ''; |
| 12259 | start = this.position; |
| 12260 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12261 | while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12262 | start -= 1; |
| 12263 | if (this.position - start > (maxLength / 2 - 1)) { |
| 12264 | head = ' ... '; |
| 12265 | start += 5; |
| 12266 | break; |
| 12267 | } |
| 12268 | } |
| 12269 | |
| 12270 | tail = ''; |
| 12271 | end = this.position; |
| 12272 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12273 | while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12274 | end += 1; |
| 12275 | if (end - this.position > (maxLength / 2 - 1)) { |
| 12276 | tail = ' ... '; |
| 12277 | end -= 5; |
| 12278 | break; |
| 12279 | } |
| 12280 | } |
| 12281 | |
| 12282 | snippet = this.buffer.slice(start, end); |
| 12283 | |
| 12284 | return common.repeat(' ', indent) + head + snippet + tail + '\n' + |
| 12285 | common.repeat(' ', indent + this.position - start + head.length) + '^'; |
| 12286 | }; |
| 12287 | |
| 12288 | |
| 12289 | Mark.prototype.toString = function toString(compact) { |
| 12290 | var snippet, where = ''; |
| 12291 | |
| 12292 | if (this.name) { |
| 12293 | where += 'in "' + this.name + '" '; |
| 12294 | } |
| 12295 | |
| 12296 | where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1); |
| 12297 | |
| 12298 | if (!compact) { |
| 12299 | snippet = this.getSnippet(); |
| 12300 | |
| 12301 | if (snippet) { |
| 12302 | where += ':\n' + snippet; |
| 12303 | } |
| 12304 | } |
| 12305 | |
| 12306 | return where; |
| 12307 | }; |
| 12308 | |
| 12309 | |
| 12310 | module.exports = Mark; |
| 12311 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12312 | },{"./common":21}],26:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12313 | 'use strict'; |
| 12314 | |
| 12315 | /*eslint-disable max-len*/ |
| 12316 | |
| 12317 | var common = require('./common'); |
| 12318 | var YAMLException = require('./exception'); |
| 12319 | var Type = require('./type'); |
| 12320 | |
| 12321 | |
| 12322 | function compileList(schema, name, result) { |
| 12323 | var exclude = []; |
| 12324 | |
| 12325 | schema.include.forEach(function (includedSchema) { |
| 12326 | result = compileList(includedSchema, name, result); |
| 12327 | }); |
| 12328 | |
| 12329 | schema[name].forEach(function (currentType) { |
| 12330 | result.forEach(function (previousType, previousIndex) { |
| 12331 | if (previousType.tag === currentType.tag) { |
| 12332 | exclude.push(previousIndex); |
| 12333 | } |
| 12334 | }); |
| 12335 | |
| 12336 | result.push(currentType); |
| 12337 | }); |
| 12338 | |
| 12339 | return result.filter(function (type, index) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12340 | return exclude.indexOf(index) === -1; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12341 | }); |
| 12342 | } |
| 12343 | |
| 12344 | |
| 12345 | function compileMap(/* lists... */) { |
| 12346 | var result = {}, index, length; |
| 12347 | |
| 12348 | function collectType(type) { |
| 12349 | result[type.tag] = type; |
| 12350 | } |
| 12351 | |
| 12352 | for (index = 0, length = arguments.length; index < length; index += 1) { |
| 12353 | arguments[index].forEach(collectType); |
| 12354 | } |
| 12355 | |
| 12356 | return result; |
| 12357 | } |
| 12358 | |
| 12359 | |
| 12360 | function Schema(definition) { |
| 12361 | this.include = definition.include || []; |
| 12362 | this.implicit = definition.implicit || []; |
| 12363 | this.explicit = definition.explicit || []; |
| 12364 | |
| 12365 | this.implicit.forEach(function (type) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12366 | if (type.loadKind && type.loadKind !== 'scalar') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12367 | throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); |
| 12368 | } |
| 12369 | }); |
| 12370 | |
| 12371 | this.compiledImplicit = compileList(this, 'implicit', []); |
| 12372 | this.compiledExplicit = compileList(this, 'explicit', []); |
| 12373 | this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit); |
| 12374 | } |
| 12375 | |
| 12376 | |
| 12377 | Schema.DEFAULT = null; |
| 12378 | |
| 12379 | |
| 12380 | Schema.create = function createSchema() { |
| 12381 | var schemas, types; |
| 12382 | |
| 12383 | switch (arguments.length) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12384 | case 1: |
| 12385 | schemas = Schema.DEFAULT; |
| 12386 | types = arguments[0]; |
| 12387 | break; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12388 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12389 | case 2: |
| 12390 | schemas = arguments[0]; |
| 12391 | types = arguments[1]; |
| 12392 | break; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12393 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12394 | default: |
| 12395 | throw new YAMLException('Wrong number of arguments for Schema.create function'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12396 | } |
| 12397 | |
| 12398 | schemas = common.toArray(schemas); |
| 12399 | types = common.toArray(types); |
| 12400 | |
| 12401 | if (!schemas.every(function (schema) { return schema instanceof Schema; })) { |
| 12402 | throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.'); |
| 12403 | } |
| 12404 | |
| 12405 | if (!types.every(function (type) { return type instanceof Type; })) { |
| 12406 | throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); |
| 12407 | } |
| 12408 | |
| 12409 | return new Schema({ |
| 12410 | include: schemas, |
| 12411 | explicit: types |
| 12412 | }); |
| 12413 | }; |
| 12414 | |
| 12415 | |
| 12416 | module.exports = Schema; |
| 12417 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12418 | },{"./common":21,"./exception":23,"./type":32}],27:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12419 | // Standard YAML's Core schema. |
| 12420 | // http://www.yaml.org/spec/1.2/spec.html#id2804923 |
| 12421 | // |
| 12422 | // NOTE: JS-YAML does not support schema-specific tag resolution restrictions. |
| 12423 | // So, Core schema has no distinctions from JSON schema is JS-YAML. |
| 12424 | |
| 12425 | |
| 12426 | 'use strict'; |
| 12427 | |
| 12428 | |
| 12429 | var Schema = require('../schema'); |
| 12430 | |
| 12431 | |
| 12432 | module.exports = new Schema({ |
| 12433 | include: [ |
| 12434 | require('./json') |
| 12435 | ] |
| 12436 | }); |
| 12437 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12438 | },{"../schema":26,"./json":31}],28:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12439 | // JS-YAML's default schema for `load` function. |
| 12440 | // It is not described in the YAML specification. |
| 12441 | // |
| 12442 | // This schema is based on JS-YAML's default safe schema and includes |
| 12443 | // JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function. |
| 12444 | // |
| 12445 | // Also this schema is used as default base schema at `Schema.create` function. |
| 12446 | |
| 12447 | |
| 12448 | 'use strict'; |
| 12449 | |
| 12450 | |
| 12451 | var Schema = require('../schema'); |
| 12452 | |
| 12453 | |
| 12454 | module.exports = Schema.DEFAULT = new Schema({ |
| 12455 | include: [ |
| 12456 | require('./default_safe') |
| 12457 | ], |
| 12458 | explicit: [ |
| 12459 | require('../type/js/undefined'), |
| 12460 | require('../type/js/regexp'), |
| 12461 | require('../type/js/function') |
| 12462 | ] |
| 12463 | }); |
| 12464 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12465 | },{"../schema":26,"../type/js/function":37,"../type/js/regexp":38,"../type/js/undefined":39,"./default_safe":29}],29:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12466 | // JS-YAML's default schema for `safeLoad` function. |
| 12467 | // It is not described in the YAML specification. |
| 12468 | // |
| 12469 | // This schema is based on standard YAML's Core schema and includes most of |
| 12470 | // extra types described at YAML tag repository. (http://yaml.org/type/) |
| 12471 | |
| 12472 | |
| 12473 | 'use strict'; |
| 12474 | |
| 12475 | |
| 12476 | var Schema = require('../schema'); |
| 12477 | |
| 12478 | |
| 12479 | module.exports = new Schema({ |
| 12480 | include: [ |
| 12481 | require('./core') |
| 12482 | ], |
| 12483 | implicit: [ |
| 12484 | require('../type/timestamp'), |
| 12485 | require('../type/merge') |
| 12486 | ], |
| 12487 | explicit: [ |
| 12488 | require('../type/binary'), |
| 12489 | require('../type/omap'), |
| 12490 | require('../type/pairs'), |
| 12491 | require('../type/set') |
| 12492 | ] |
| 12493 | }); |
| 12494 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12495 | },{"../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){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12496 | // Standard YAML's Failsafe schema. |
| 12497 | // http://www.yaml.org/spec/1.2/spec.html#id2802346 |
| 12498 | |
| 12499 | |
| 12500 | 'use strict'; |
| 12501 | |
| 12502 | |
| 12503 | var Schema = require('../schema'); |
| 12504 | |
| 12505 | |
| 12506 | module.exports = new Schema({ |
| 12507 | explicit: [ |
| 12508 | require('../type/str'), |
| 12509 | require('../type/seq'), |
| 12510 | require('../type/map') |
| 12511 | ] |
| 12512 | }); |
| 12513 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12514 | },{"../schema":26,"../type/map":40,"../type/seq":45,"../type/str":47}],31:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12515 | // Standard YAML's JSON schema. |
| 12516 | // http://www.yaml.org/spec/1.2/spec.html#id2803231 |
| 12517 | // |
| 12518 | // NOTE: JS-YAML does not support schema-specific tag resolution restrictions. |
| 12519 | // So, this schema is not such strict as defined in the YAML specification. |
| 12520 | // It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc. |
| 12521 | |
| 12522 | |
| 12523 | 'use strict'; |
| 12524 | |
| 12525 | |
| 12526 | var Schema = require('../schema'); |
| 12527 | |
| 12528 | |
| 12529 | module.exports = new Schema({ |
| 12530 | include: [ |
| 12531 | require('./failsafe') |
| 12532 | ], |
| 12533 | implicit: [ |
| 12534 | require('../type/null'), |
| 12535 | require('../type/bool'), |
| 12536 | require('../type/int'), |
| 12537 | require('../type/float') |
| 12538 | ] |
| 12539 | }); |
| 12540 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12541 | },{"../schema":26,"../type/bool":34,"../type/float":35,"../type/int":36,"../type/null":42,"./failsafe":30}],32:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12542 | 'use strict'; |
| 12543 | |
| 12544 | var YAMLException = require('./exception'); |
| 12545 | |
| 12546 | var TYPE_CONSTRUCTOR_OPTIONS = [ |
| 12547 | 'kind', |
| 12548 | 'resolve', |
| 12549 | 'construct', |
| 12550 | 'instanceOf', |
| 12551 | 'predicate', |
| 12552 | 'represent', |
| 12553 | 'defaultStyle', |
| 12554 | 'styleAliases' |
| 12555 | ]; |
| 12556 | |
| 12557 | var YAML_NODE_KINDS = [ |
| 12558 | 'scalar', |
| 12559 | 'sequence', |
| 12560 | 'mapping' |
| 12561 | ]; |
| 12562 | |
| 12563 | function compileStyleAliases(map) { |
| 12564 | var result = {}; |
| 12565 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12566 | if (map !== null) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12567 | Object.keys(map).forEach(function (style) { |
| 12568 | map[style].forEach(function (alias) { |
| 12569 | result[String(alias)] = style; |
| 12570 | }); |
| 12571 | }); |
| 12572 | } |
| 12573 | |
| 12574 | return result; |
| 12575 | } |
| 12576 | |
| 12577 | function Type(tag, options) { |
| 12578 | options = options || {}; |
| 12579 | |
| 12580 | Object.keys(options).forEach(function (name) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12581 | if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12582 | throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); |
| 12583 | } |
| 12584 | }); |
| 12585 | |
| 12586 | // TODO: Add tag format check. |
| 12587 | this.tag = tag; |
| 12588 | this.kind = options['kind'] || null; |
| 12589 | this.resolve = options['resolve'] || function () { return true; }; |
| 12590 | this.construct = options['construct'] || function (data) { return data; }; |
| 12591 | this.instanceOf = options['instanceOf'] || null; |
| 12592 | this.predicate = options['predicate'] || null; |
| 12593 | this.represent = options['represent'] || null; |
| 12594 | this.defaultStyle = options['defaultStyle'] || null; |
| 12595 | this.styleAliases = compileStyleAliases(options['styleAliases'] || null); |
| 12596 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12597 | if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12598 | throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); |
| 12599 | } |
| 12600 | } |
| 12601 | |
| 12602 | module.exports = Type; |
| 12603 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12604 | },{"./exception":23}],33:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12605 | 'use strict'; |
| 12606 | |
| 12607 | /*eslint-disable no-bitwise*/ |
| 12608 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12609 | var NodeBuffer; |
| 12610 | |
| 12611 | try { |
| 12612 | // A trick for browserified version, to not include `Buffer` shim |
| 12613 | var _require = require; |
| 12614 | NodeBuffer = _require('buffer').Buffer; |
| 12615 | } catch (__) {} |
| 12616 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12617 | var Type = require('../type'); |
| 12618 | |
| 12619 | |
| 12620 | // [ 64, 65, 66 ] -> [ padding, CR, LF ] |
| 12621 | var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; |
| 12622 | |
| 12623 | |
| 12624 | function resolveYamlBinary(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12625 | if (data === null) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12626 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 12627 | var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12628 | |
| 12629 | // Convert one by one. |
| 12630 | for (idx = 0; idx < max; idx++) { |
| 12631 | code = map.indexOf(data.charAt(idx)); |
| 12632 | |
| 12633 | // Skip CR/LF |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12634 | if (code > 64) continue; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12635 | |
| 12636 | // Fail on illegal characters |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12637 | if (code < 0) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12638 | |
| 12639 | bitlen += 6; |
| 12640 | } |
| 12641 | |
| 12642 | // If there are any bits left, source was corrupted |
| 12643 | return (bitlen % 8) === 0; |
| 12644 | } |
| 12645 | |
| 12646 | function constructYamlBinary(data) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 12647 | var idx, tailbits, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12648 | input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan |
| 12649 | max = input.length, |
| 12650 | map = BASE64_MAP, |
| 12651 | bits = 0, |
| 12652 | result = []; |
| 12653 | |
| 12654 | // Collect by 6*4 bits (3 bytes) |
| 12655 | |
| 12656 | for (idx = 0; idx < max; idx++) { |
| 12657 | if ((idx % 4 === 0) && idx) { |
| 12658 | result.push((bits >> 16) & 0xFF); |
| 12659 | result.push((bits >> 8) & 0xFF); |
| 12660 | result.push(bits & 0xFF); |
| 12661 | } |
| 12662 | |
| 12663 | bits = (bits << 6) | map.indexOf(input.charAt(idx)); |
| 12664 | } |
| 12665 | |
| 12666 | // Dump tail |
| 12667 | |
| 12668 | tailbits = (max % 4) * 6; |
| 12669 | |
| 12670 | if (tailbits === 0) { |
| 12671 | result.push((bits >> 16) & 0xFF); |
| 12672 | result.push((bits >> 8) & 0xFF); |
| 12673 | result.push(bits & 0xFF); |
| 12674 | } else if (tailbits === 18) { |
| 12675 | result.push((bits >> 10) & 0xFF); |
| 12676 | result.push((bits >> 2) & 0xFF); |
| 12677 | } else if (tailbits === 12) { |
| 12678 | result.push((bits >> 4) & 0xFF); |
| 12679 | } |
| 12680 | |
| 12681 | // Wrap into Buffer for NodeJS and leave Array for browser |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12682 | if (NodeBuffer) return new NodeBuffer(result); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12683 | |
| 12684 | return result; |
| 12685 | } |
| 12686 | |
| 12687 | function representYamlBinary(object /*, style*/) { |
| 12688 | var result = '', bits = 0, idx, tail, |
| 12689 | max = object.length, |
| 12690 | map = BASE64_MAP; |
| 12691 | |
| 12692 | // Convert every three bytes to 4 ASCII characters. |
| 12693 | |
| 12694 | for (idx = 0; idx < max; idx++) { |
| 12695 | if ((idx % 3 === 0) && idx) { |
| 12696 | result += map[(bits >> 18) & 0x3F]; |
| 12697 | result += map[(bits >> 12) & 0x3F]; |
| 12698 | result += map[(bits >> 6) & 0x3F]; |
| 12699 | result += map[bits & 0x3F]; |
| 12700 | } |
| 12701 | |
| 12702 | bits = (bits << 8) + object[idx]; |
| 12703 | } |
| 12704 | |
| 12705 | // Dump tail |
| 12706 | |
| 12707 | tail = max % 3; |
| 12708 | |
| 12709 | if (tail === 0) { |
| 12710 | result += map[(bits >> 18) & 0x3F]; |
| 12711 | result += map[(bits >> 12) & 0x3F]; |
| 12712 | result += map[(bits >> 6) & 0x3F]; |
| 12713 | result += map[bits & 0x3F]; |
| 12714 | } else if (tail === 2) { |
| 12715 | result += map[(bits >> 10) & 0x3F]; |
| 12716 | result += map[(bits >> 4) & 0x3F]; |
| 12717 | result += map[(bits << 2) & 0x3F]; |
| 12718 | result += map[64]; |
| 12719 | } else if (tail === 1) { |
| 12720 | result += map[(bits >> 2) & 0x3F]; |
| 12721 | result += map[(bits << 4) & 0x3F]; |
| 12722 | result += map[64]; |
| 12723 | result += map[64]; |
| 12724 | } |
| 12725 | |
| 12726 | return result; |
| 12727 | } |
| 12728 | |
| 12729 | function isBinary(object) { |
| 12730 | return NodeBuffer && NodeBuffer.isBuffer(object); |
| 12731 | } |
| 12732 | |
| 12733 | module.exports = new Type('tag:yaml.org,2002:binary', { |
| 12734 | kind: 'scalar', |
| 12735 | resolve: resolveYamlBinary, |
| 12736 | construct: constructYamlBinary, |
| 12737 | predicate: isBinary, |
| 12738 | represent: representYamlBinary |
| 12739 | }); |
| 12740 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12741 | },{"../type":32}],34:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12742 | 'use strict'; |
| 12743 | |
| 12744 | var Type = require('../type'); |
| 12745 | |
| 12746 | function resolveYamlBoolean(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12747 | if (data === null) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12748 | |
| 12749 | var max = data.length; |
| 12750 | |
| 12751 | return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || |
| 12752 | (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); |
| 12753 | } |
| 12754 | |
| 12755 | function constructYamlBoolean(data) { |
| 12756 | return data === 'true' || |
| 12757 | data === 'True' || |
| 12758 | data === 'TRUE'; |
| 12759 | } |
| 12760 | |
| 12761 | function isBoolean(object) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12762 | return Object.prototype.toString.call(object) === '[object Boolean]'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12763 | } |
| 12764 | |
| 12765 | module.exports = new Type('tag:yaml.org,2002:bool', { |
| 12766 | kind: 'scalar', |
| 12767 | resolve: resolveYamlBoolean, |
| 12768 | construct: constructYamlBoolean, |
| 12769 | predicate: isBoolean, |
| 12770 | represent: { |
| 12771 | lowercase: function (object) { return object ? 'true' : 'false'; }, |
| 12772 | uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, |
| 12773 | camelcase: function (object) { return object ? 'True' : 'False'; } |
| 12774 | }, |
| 12775 | defaultStyle: 'lowercase' |
| 12776 | }); |
| 12777 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12778 | },{"../type":32}],35:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12779 | 'use strict'; |
| 12780 | |
| 12781 | var common = require('../common'); |
| 12782 | var Type = require('../type'); |
| 12783 | |
| 12784 | var YAML_FLOAT_PATTERN = new RegExp( |
| 12785 | '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + |
| 12786 | '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + |
| 12787 | '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + |
| 12788 | '|[-+]?\\.(?:inf|Inf|INF)' + |
| 12789 | '|\\.(?:nan|NaN|NAN))$'); |
| 12790 | |
| 12791 | function resolveYamlFloat(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12792 | if (data === null) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12793 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12794 | if (!YAML_FLOAT_PATTERN.test(data)) return false; |
| 12795 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12796 | return true; |
| 12797 | } |
| 12798 | |
| 12799 | function constructYamlFloat(data) { |
| 12800 | var value, sign, base, digits; |
| 12801 | |
| 12802 | value = data.replace(/_/g, '').toLowerCase(); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12803 | sign = value[0] === '-' ? -1 : 1; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12804 | digits = []; |
| 12805 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12806 | if ('+-'.indexOf(value[0]) >= 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12807 | value = value.slice(1); |
| 12808 | } |
| 12809 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12810 | if (value === '.inf') { |
| 12811 | return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12812 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12813 | } else if (value === '.nan') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12814 | return NaN; |
| 12815 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12816 | } else if (value.indexOf(':') >= 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12817 | value.split(':').forEach(function (v) { |
| 12818 | digits.unshift(parseFloat(v, 10)); |
| 12819 | }); |
| 12820 | |
| 12821 | value = 0.0; |
| 12822 | base = 1; |
| 12823 | |
| 12824 | digits.forEach(function (d) { |
| 12825 | value += d * base; |
| 12826 | base *= 60; |
| 12827 | }); |
| 12828 | |
| 12829 | return sign * value; |
| 12830 | |
| 12831 | } |
| 12832 | return sign * parseFloat(value, 10); |
| 12833 | } |
| 12834 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 12835 | |
| 12836 | var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; |
| 12837 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12838 | function representYamlFloat(object, style) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 12839 | var res; |
| 12840 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12841 | if (isNaN(object)) { |
| 12842 | switch (style) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12843 | case 'lowercase': return '.nan'; |
| 12844 | case 'uppercase': return '.NAN'; |
| 12845 | case 'camelcase': return '.NaN'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12846 | } |
| 12847 | } else if (Number.POSITIVE_INFINITY === object) { |
| 12848 | switch (style) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12849 | case 'lowercase': return '.inf'; |
| 12850 | case 'uppercase': return '.INF'; |
| 12851 | case 'camelcase': return '.Inf'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12852 | } |
| 12853 | } else if (Number.NEGATIVE_INFINITY === object) { |
| 12854 | switch (style) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12855 | case 'lowercase': return '-.inf'; |
| 12856 | case 'uppercase': return '-.INF'; |
| 12857 | case 'camelcase': return '-.Inf'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12858 | } |
| 12859 | } else if (common.isNegativeZero(object)) { |
| 12860 | return '-0.0'; |
| 12861 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 12862 | |
| 12863 | res = object.toString(10); |
| 12864 | |
| 12865 | // JS stringifier can build scientific format without dots: 5e-100, |
| 12866 | // while YAML requres dot: 5.e-100. Fix it with simple hack |
| 12867 | |
| 12868 | return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12869 | } |
| 12870 | |
| 12871 | function isFloat(object) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12872 | return (Object.prototype.toString.call(object) === '[object Number]') && |
| 12873 | (object % 1 !== 0 || common.isNegativeZero(object)); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12874 | } |
| 12875 | |
| 12876 | module.exports = new Type('tag:yaml.org,2002:float', { |
| 12877 | kind: 'scalar', |
| 12878 | resolve: resolveYamlFloat, |
| 12879 | construct: constructYamlFloat, |
| 12880 | predicate: isFloat, |
| 12881 | represent: representYamlFloat, |
| 12882 | defaultStyle: 'lowercase' |
| 12883 | }); |
| 12884 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12885 | },{"../common":21,"../type":32}],36:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12886 | 'use strict'; |
| 12887 | |
| 12888 | var common = require('../common'); |
| 12889 | var Type = require('../type'); |
| 12890 | |
| 12891 | function isHexCode(c) { |
| 12892 | return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || |
| 12893 | ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || |
| 12894 | ((0x61/* a */ <= c) && (c <= 0x66/* f */)); |
| 12895 | } |
| 12896 | |
| 12897 | function isOctCode(c) { |
| 12898 | return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); |
| 12899 | } |
| 12900 | |
| 12901 | function isDecCode(c) { |
| 12902 | return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); |
| 12903 | } |
| 12904 | |
| 12905 | function resolveYamlInteger(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12906 | if (data === null) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12907 | |
| 12908 | var max = data.length, |
| 12909 | index = 0, |
| 12910 | hasDigits = false, |
| 12911 | ch; |
| 12912 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12913 | if (!max) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12914 | |
| 12915 | ch = data[index]; |
| 12916 | |
| 12917 | // sign |
| 12918 | if (ch === '-' || ch === '+') { |
| 12919 | ch = data[++index]; |
| 12920 | } |
| 12921 | |
| 12922 | if (ch === '0') { |
| 12923 | // 0 |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12924 | if (index + 1 === max) return true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12925 | ch = data[++index]; |
| 12926 | |
| 12927 | // base 2, base 8, base 16 |
| 12928 | |
| 12929 | if (ch === 'b') { |
| 12930 | // base 2 |
| 12931 | index++; |
| 12932 | |
| 12933 | for (; index < max; index++) { |
| 12934 | ch = data[index]; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12935 | if (ch === '_') continue; |
| 12936 | if (ch !== '0' && ch !== '1') return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12937 | hasDigits = true; |
| 12938 | } |
| 12939 | return hasDigits; |
| 12940 | } |
| 12941 | |
| 12942 | |
| 12943 | if (ch === 'x') { |
| 12944 | // base 16 |
| 12945 | index++; |
| 12946 | |
| 12947 | for (; index < max; index++) { |
| 12948 | ch = data[index]; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12949 | if (ch === '_') continue; |
| 12950 | if (!isHexCode(data.charCodeAt(index))) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12951 | hasDigits = true; |
| 12952 | } |
| 12953 | return hasDigits; |
| 12954 | } |
| 12955 | |
| 12956 | // base 8 |
| 12957 | for (; index < max; index++) { |
| 12958 | ch = data[index]; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12959 | if (ch === '_') continue; |
| 12960 | if (!isOctCode(data.charCodeAt(index))) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12961 | hasDigits = true; |
| 12962 | } |
| 12963 | return hasDigits; |
| 12964 | } |
| 12965 | |
| 12966 | // base 10 (except 0) or base 60 |
| 12967 | |
| 12968 | for (; index < max; index++) { |
| 12969 | ch = data[index]; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12970 | if (ch === '_') continue; |
| 12971 | if (ch === ':') break; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12972 | if (!isDecCode(data.charCodeAt(index))) { |
| 12973 | return false; |
| 12974 | } |
| 12975 | hasDigits = true; |
| 12976 | } |
| 12977 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12978 | if (!hasDigits) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12979 | |
| 12980 | // if !base60 - done; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12981 | if (ch !== ':') return true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12982 | |
| 12983 | // base60 almost not used, no needs to optimize |
| 12984 | return /^(:[0-5]?[0-9])+$/.test(data.slice(index)); |
| 12985 | } |
| 12986 | |
| 12987 | function constructYamlInteger(data) { |
| 12988 | var value = data, sign = 1, ch, base, digits = []; |
| 12989 | |
| 12990 | if (value.indexOf('_') !== -1) { |
| 12991 | value = value.replace(/_/g, ''); |
| 12992 | } |
| 12993 | |
| 12994 | ch = value[0]; |
| 12995 | |
| 12996 | if (ch === '-' || ch === '+') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 12997 | if (ch === '-') sign = -1; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 12998 | value = value.slice(1); |
| 12999 | ch = value[0]; |
| 13000 | } |
| 13001 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13002 | if (value === '0') return 0; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13003 | |
| 13004 | if (ch === '0') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13005 | if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); |
| 13006 | if (value[1] === 'x') return sign * parseInt(value, 16); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13007 | return sign * parseInt(value, 8); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13008 | } |
| 13009 | |
| 13010 | if (value.indexOf(':') !== -1) { |
| 13011 | value.split(':').forEach(function (v) { |
| 13012 | digits.unshift(parseInt(v, 10)); |
| 13013 | }); |
| 13014 | |
| 13015 | value = 0; |
| 13016 | base = 1; |
| 13017 | |
| 13018 | digits.forEach(function (d) { |
| 13019 | value += (d * base); |
| 13020 | base *= 60; |
| 13021 | }); |
| 13022 | |
| 13023 | return sign * value; |
| 13024 | |
| 13025 | } |
| 13026 | |
| 13027 | return sign * parseInt(value, 10); |
| 13028 | } |
| 13029 | |
| 13030 | function isInteger(object) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13031 | return (Object.prototype.toString.call(object)) === '[object Number]' && |
| 13032 | (object % 1 === 0 && !common.isNegativeZero(object)); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13033 | } |
| 13034 | |
| 13035 | module.exports = new Type('tag:yaml.org,2002:int', { |
| 13036 | kind: 'scalar', |
| 13037 | resolve: resolveYamlInteger, |
| 13038 | construct: constructYamlInteger, |
| 13039 | predicate: isInteger, |
| 13040 | represent: { |
| 13041 | binary: function (object) { return '0b' + object.toString(2); }, |
| 13042 | octal: function (object) { return '0' + object.toString(8); }, |
| 13043 | decimal: function (object) { return object.toString(10); }, |
| 13044 | hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); } |
| 13045 | }, |
| 13046 | defaultStyle: 'decimal', |
| 13047 | styleAliases: { |
| 13048 | binary: [ 2, 'bin' ], |
| 13049 | octal: [ 8, 'oct' ], |
| 13050 | decimal: [ 10, 'dec' ], |
| 13051 | hexadecimal: [ 16, 'hex' ] |
| 13052 | } |
| 13053 | }); |
| 13054 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13055 | },{"../common":21,"../type":32}],37:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13056 | 'use strict'; |
| 13057 | |
| 13058 | var esprima; |
| 13059 | |
| 13060 | // Browserified version does not have esprima |
| 13061 | // |
| 13062 | // 1. For node.js just require module as deps |
| 13063 | // 2. For browser try to require mudule via external AMD system. |
| 13064 | // If not found - try to fallback to window.esprima. If not |
| 13065 | // found too - then fail to parse. |
| 13066 | // |
| 13067 | try { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13068 | // workaround to exclude package from browserify list. |
| 13069 | var _require = require; |
| 13070 | esprima = _require('esprima'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13071 | } catch (_) { |
| 13072 | /*global window */ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13073 | if (typeof window !== 'undefined') esprima = window.esprima; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13074 | } |
| 13075 | |
| 13076 | var Type = require('../../type'); |
| 13077 | |
| 13078 | function resolveJavascriptFunction(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13079 | if (data === null) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13080 | |
| 13081 | try { |
| 13082 | var source = '(' + data + ')', |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 13083 | ast = esprima.parse(source, { range: true }); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13084 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13085 | if (ast.type !== 'Program' || |
| 13086 | ast.body.length !== 1 || |
| 13087 | ast.body[0].type !== 'ExpressionStatement' || |
| 13088 | ast.body[0].expression.type !== 'FunctionExpression') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13089 | return false; |
| 13090 | } |
| 13091 | |
| 13092 | return true; |
| 13093 | } catch (err) { |
| 13094 | return false; |
| 13095 | } |
| 13096 | } |
| 13097 | |
| 13098 | function constructJavascriptFunction(data) { |
| 13099 | /*jslint evil:true*/ |
| 13100 | |
| 13101 | var source = '(' + data + ')', |
| 13102 | ast = esprima.parse(source, { range: true }), |
| 13103 | params = [], |
| 13104 | body; |
| 13105 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13106 | if (ast.type !== 'Program' || |
| 13107 | ast.body.length !== 1 || |
| 13108 | ast.body[0].type !== 'ExpressionStatement' || |
| 13109 | ast.body[0].expression.type !== 'FunctionExpression') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13110 | throw new Error('Failed to resolve function'); |
| 13111 | } |
| 13112 | |
| 13113 | ast.body[0].expression.params.forEach(function (param) { |
| 13114 | params.push(param.name); |
| 13115 | }); |
| 13116 | |
| 13117 | body = ast.body[0].expression.body.range; |
| 13118 | |
| 13119 | // Esprima's ranges include the first '{' and the last '}' characters on |
| 13120 | // function expressions. So cut them out. |
| 13121 | /*eslint-disable no-new-func*/ |
| 13122 | return new Function(params, source.slice(body[0] + 1, body[1] - 1)); |
| 13123 | } |
| 13124 | |
| 13125 | function representJavascriptFunction(object /*, style*/) { |
| 13126 | return object.toString(); |
| 13127 | } |
| 13128 | |
| 13129 | function isFunction(object) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13130 | return Object.prototype.toString.call(object) === '[object Function]'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13131 | } |
| 13132 | |
| 13133 | module.exports = new Type('tag:yaml.org,2002:js/function', { |
| 13134 | kind: 'scalar', |
| 13135 | resolve: resolveJavascriptFunction, |
| 13136 | construct: constructJavascriptFunction, |
| 13137 | predicate: isFunction, |
| 13138 | represent: representJavascriptFunction |
| 13139 | }); |
| 13140 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13141 | },{"../../type":32}],38:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13142 | 'use strict'; |
| 13143 | |
| 13144 | var Type = require('../../type'); |
| 13145 | |
| 13146 | function resolveJavascriptRegExp(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13147 | if (data === null) return false; |
| 13148 | if (data.length === 0) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13149 | |
| 13150 | var regexp = data, |
| 13151 | tail = /\/([gim]*)$/.exec(data), |
| 13152 | modifiers = ''; |
| 13153 | |
| 13154 | // if regexp starts with '/' it can have modifiers and must be properly closed |
| 13155 | // `/foo/gim` - modifiers tail can be maximum 3 chars |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13156 | if (regexp[0] === '/') { |
| 13157 | if (tail) modifiers = tail[1]; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13158 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13159 | if (modifiers.length > 3) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13160 | // if expression starts with /, is should be properly terminated |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13161 | if (regexp[regexp.length - modifiers.length - 1] !== '/') return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13162 | } |
| 13163 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13164 | return true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13165 | } |
| 13166 | |
| 13167 | function constructJavascriptRegExp(data) { |
| 13168 | var regexp = data, |
| 13169 | tail = /\/([gim]*)$/.exec(data), |
| 13170 | modifiers = ''; |
| 13171 | |
| 13172 | // `/foo/gim` - tail can be maximum 4 chars |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13173 | if (regexp[0] === '/') { |
| 13174 | if (tail) modifiers = tail[1]; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13175 | regexp = regexp.slice(1, regexp.length - modifiers.length - 1); |
| 13176 | } |
| 13177 | |
| 13178 | return new RegExp(regexp, modifiers); |
| 13179 | } |
| 13180 | |
| 13181 | function representJavascriptRegExp(object /*, style*/) { |
| 13182 | var result = '/' + object.source + '/'; |
| 13183 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13184 | if (object.global) result += 'g'; |
| 13185 | if (object.multiline) result += 'm'; |
| 13186 | if (object.ignoreCase) result += 'i'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13187 | |
| 13188 | return result; |
| 13189 | } |
| 13190 | |
| 13191 | function isRegExp(object) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13192 | return Object.prototype.toString.call(object) === '[object RegExp]'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13193 | } |
| 13194 | |
| 13195 | module.exports = new Type('tag:yaml.org,2002:js/regexp', { |
| 13196 | kind: 'scalar', |
| 13197 | resolve: resolveJavascriptRegExp, |
| 13198 | construct: constructJavascriptRegExp, |
| 13199 | predicate: isRegExp, |
| 13200 | represent: representJavascriptRegExp |
| 13201 | }); |
| 13202 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13203 | },{"../../type":32}],39:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13204 | 'use strict'; |
| 13205 | |
| 13206 | var Type = require('../../type'); |
| 13207 | |
| 13208 | function resolveJavascriptUndefined() { |
| 13209 | return true; |
| 13210 | } |
| 13211 | |
| 13212 | function constructJavascriptUndefined() { |
| 13213 | /*eslint-disable no-undefined*/ |
| 13214 | return undefined; |
| 13215 | } |
| 13216 | |
| 13217 | function representJavascriptUndefined() { |
| 13218 | return ''; |
| 13219 | } |
| 13220 | |
| 13221 | function isUndefined(object) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13222 | return typeof object === 'undefined'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13223 | } |
| 13224 | |
| 13225 | module.exports = new Type('tag:yaml.org,2002:js/undefined', { |
| 13226 | kind: 'scalar', |
| 13227 | resolve: resolveJavascriptUndefined, |
| 13228 | construct: constructJavascriptUndefined, |
| 13229 | predicate: isUndefined, |
| 13230 | represent: representJavascriptUndefined |
| 13231 | }); |
| 13232 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13233 | },{"../../type":32}],40:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13234 | 'use strict'; |
| 13235 | |
| 13236 | var Type = require('../type'); |
| 13237 | |
| 13238 | module.exports = new Type('tag:yaml.org,2002:map', { |
| 13239 | kind: 'mapping', |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13240 | construct: function (data) { return data !== null ? data : {}; } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13241 | }); |
| 13242 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13243 | },{"../type":32}],41:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13244 | 'use strict'; |
| 13245 | |
| 13246 | var Type = require('../type'); |
| 13247 | |
| 13248 | function resolveYamlMerge(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13249 | return data === '<<' || data === null; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13250 | } |
| 13251 | |
| 13252 | module.exports = new Type('tag:yaml.org,2002:merge', { |
| 13253 | kind: 'scalar', |
| 13254 | resolve: resolveYamlMerge |
| 13255 | }); |
| 13256 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13257 | },{"../type":32}],42:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13258 | 'use strict'; |
| 13259 | |
| 13260 | var Type = require('../type'); |
| 13261 | |
| 13262 | function resolveYamlNull(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13263 | if (data === null) return true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13264 | |
| 13265 | var max = data.length; |
| 13266 | |
| 13267 | return (max === 1 && data === '~') || |
| 13268 | (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); |
| 13269 | } |
| 13270 | |
| 13271 | function constructYamlNull() { |
| 13272 | return null; |
| 13273 | } |
| 13274 | |
| 13275 | function isNull(object) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13276 | return object === null; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13277 | } |
| 13278 | |
| 13279 | module.exports = new Type('tag:yaml.org,2002:null', { |
| 13280 | kind: 'scalar', |
| 13281 | resolve: resolveYamlNull, |
| 13282 | construct: constructYamlNull, |
| 13283 | predicate: isNull, |
| 13284 | represent: { |
| 13285 | canonical: function () { return '~'; }, |
| 13286 | lowercase: function () { return 'null'; }, |
| 13287 | uppercase: function () { return 'NULL'; }, |
| 13288 | camelcase: function () { return 'Null'; } |
| 13289 | }, |
| 13290 | defaultStyle: 'lowercase' |
| 13291 | }); |
| 13292 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13293 | },{"../type":32}],43:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13294 | 'use strict'; |
| 13295 | |
| 13296 | var Type = require('../type'); |
| 13297 | |
| 13298 | var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| 13299 | var _toString = Object.prototype.toString; |
| 13300 | |
| 13301 | function resolveYamlOmap(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13302 | if (data === null) return true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13303 | |
| 13304 | var objectKeys = [], index, length, pair, pairKey, pairHasKey, |
| 13305 | object = data; |
| 13306 | |
| 13307 | for (index = 0, length = object.length; index < length; index += 1) { |
| 13308 | pair = object[index]; |
| 13309 | pairHasKey = false; |
| 13310 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13311 | if (_toString.call(pair) !== '[object Object]') return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13312 | |
| 13313 | for (pairKey in pair) { |
| 13314 | if (_hasOwnProperty.call(pair, pairKey)) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13315 | if (!pairHasKey) pairHasKey = true; |
| 13316 | else return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13317 | } |
| 13318 | } |
| 13319 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13320 | if (!pairHasKey) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13321 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13322 | if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); |
| 13323 | else return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13324 | } |
| 13325 | |
| 13326 | return true; |
| 13327 | } |
| 13328 | |
| 13329 | function constructYamlOmap(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13330 | return data !== null ? data : []; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13331 | } |
| 13332 | |
| 13333 | module.exports = new Type('tag:yaml.org,2002:omap', { |
| 13334 | kind: 'sequence', |
| 13335 | resolve: resolveYamlOmap, |
| 13336 | construct: constructYamlOmap |
| 13337 | }); |
| 13338 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13339 | },{"../type":32}],44:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13340 | 'use strict'; |
| 13341 | |
| 13342 | var Type = require('../type'); |
| 13343 | |
| 13344 | var _toString = Object.prototype.toString; |
| 13345 | |
| 13346 | function resolveYamlPairs(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13347 | if (data === null) return true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13348 | |
| 13349 | var index, length, pair, keys, result, |
| 13350 | object = data; |
| 13351 | |
| 13352 | result = new Array(object.length); |
| 13353 | |
| 13354 | for (index = 0, length = object.length; index < length; index += 1) { |
| 13355 | pair = object[index]; |
| 13356 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13357 | if (_toString.call(pair) !== '[object Object]') return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13358 | |
| 13359 | keys = Object.keys(pair); |
| 13360 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13361 | if (keys.length !== 1) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13362 | |
| 13363 | result[index] = [ keys[0], pair[keys[0]] ]; |
| 13364 | } |
| 13365 | |
| 13366 | return true; |
| 13367 | } |
| 13368 | |
| 13369 | function constructYamlPairs(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13370 | if (data === null) return []; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13371 | |
| 13372 | var index, length, pair, keys, result, |
| 13373 | object = data; |
| 13374 | |
| 13375 | result = new Array(object.length); |
| 13376 | |
| 13377 | for (index = 0, length = object.length; index < length; index += 1) { |
| 13378 | pair = object[index]; |
| 13379 | |
| 13380 | keys = Object.keys(pair); |
| 13381 | |
| 13382 | result[index] = [ keys[0], pair[keys[0]] ]; |
| 13383 | } |
| 13384 | |
| 13385 | return result; |
| 13386 | } |
| 13387 | |
| 13388 | module.exports = new Type('tag:yaml.org,2002:pairs', { |
| 13389 | kind: 'sequence', |
| 13390 | resolve: resolveYamlPairs, |
| 13391 | construct: constructYamlPairs |
| 13392 | }); |
| 13393 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13394 | },{"../type":32}],45:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13395 | 'use strict'; |
| 13396 | |
| 13397 | var Type = require('../type'); |
| 13398 | |
| 13399 | module.exports = new Type('tag:yaml.org,2002:seq', { |
| 13400 | kind: 'sequence', |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13401 | construct: function (data) { return data !== null ? data : []; } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13402 | }); |
| 13403 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13404 | },{"../type":32}],46:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13405 | 'use strict'; |
| 13406 | |
| 13407 | var Type = require('../type'); |
| 13408 | |
| 13409 | var _hasOwnProperty = Object.prototype.hasOwnProperty; |
| 13410 | |
| 13411 | function resolveYamlSet(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13412 | if (data === null) return true; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13413 | |
| 13414 | var key, object = data; |
| 13415 | |
| 13416 | for (key in object) { |
| 13417 | if (_hasOwnProperty.call(object, key)) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13418 | if (object[key] !== null) return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13419 | } |
| 13420 | } |
| 13421 | |
| 13422 | return true; |
| 13423 | } |
| 13424 | |
| 13425 | function constructYamlSet(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13426 | return data !== null ? data : {}; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13427 | } |
| 13428 | |
| 13429 | module.exports = new Type('tag:yaml.org,2002:set', { |
| 13430 | kind: 'mapping', |
| 13431 | resolve: resolveYamlSet, |
| 13432 | construct: constructYamlSet |
| 13433 | }); |
| 13434 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13435 | },{"../type":32}],47:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13436 | 'use strict'; |
| 13437 | |
| 13438 | var Type = require('../type'); |
| 13439 | |
| 13440 | module.exports = new Type('tag:yaml.org,2002:str', { |
| 13441 | kind: 'scalar', |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13442 | construct: function (data) { return data !== null ? data : ''; } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13443 | }); |
| 13444 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13445 | },{"../type":32}],48:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13446 | 'use strict'; |
| 13447 | |
| 13448 | var Type = require('../type'); |
| 13449 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13450 | var YAML_DATE_REGEXP = new RegExp( |
| 13451 | '^([0-9][0-9][0-9][0-9])' + // [1] year |
| 13452 | '-([0-9][0-9])' + // [2] month |
| 13453 | '-([0-9][0-9])$'); // [3] day |
| 13454 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13455 | var YAML_TIMESTAMP_REGEXP = new RegExp( |
| 13456 | '^([0-9][0-9][0-9][0-9])' + // [1] year |
| 13457 | '-([0-9][0-9]?)' + // [2] month |
| 13458 | '-([0-9][0-9]?)' + // [3] day |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13459 | '(?:[Tt]|[ \\t]+)' + // ... |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13460 | '([0-9][0-9]?)' + // [4] hour |
| 13461 | ':([0-9][0-9])' + // [5] minute |
| 13462 | ':([0-9][0-9])' + // [6] second |
| 13463 | '(?:\\.([0-9]*))?' + // [7] fraction |
| 13464 | '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13465 | '(?::([0-9][0-9]))?))?$'); // [11] tz_minute |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13466 | |
| 13467 | function resolveYamlTimestamp(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13468 | if (data === null) return false; |
| 13469 | if (YAML_DATE_REGEXP.exec(data) !== null) return true; |
| 13470 | if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; |
| 13471 | return false; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13472 | } |
| 13473 | |
| 13474 | function constructYamlTimestamp(data) { |
| 13475 | var match, year, month, day, hour, minute, second, fraction = 0, |
| 13476 | delta = null, tz_hour, tz_minute, date; |
| 13477 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13478 | match = YAML_DATE_REGEXP.exec(data); |
| 13479 | if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13480 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13481 | if (match === null) throw new Error('Date resolve error'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13482 | |
| 13483 | // match: [1] year [2] month [3] day |
| 13484 | |
| 13485 | year = +(match[1]); |
| 13486 | month = +(match[2]) - 1; // JS month starts with 0 |
| 13487 | day = +(match[3]); |
| 13488 | |
| 13489 | if (!match[4]) { // no hour |
| 13490 | return new Date(Date.UTC(year, month, day)); |
| 13491 | } |
| 13492 | |
| 13493 | // match: [4] hour [5] minute [6] second [7] fraction |
| 13494 | |
| 13495 | hour = +(match[4]); |
| 13496 | minute = +(match[5]); |
| 13497 | second = +(match[6]); |
| 13498 | |
| 13499 | if (match[7]) { |
| 13500 | fraction = match[7].slice(0, 3); |
| 13501 | while (fraction.length < 3) { // milli-seconds |
| 13502 | fraction += '0'; |
| 13503 | } |
| 13504 | fraction = +fraction; |
| 13505 | } |
| 13506 | |
| 13507 | // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute |
| 13508 | |
| 13509 | if (match[9]) { |
| 13510 | tz_hour = +(match[10]); |
| 13511 | tz_minute = +(match[11] || 0); |
| 13512 | delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13513 | if (match[9] === '-') delta = -delta; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13514 | } |
| 13515 | |
| 13516 | date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); |
| 13517 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13518 | if (delta) date.setTime(date.getTime() - delta); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13519 | |
| 13520 | return date; |
| 13521 | } |
| 13522 | |
| 13523 | function representYamlTimestamp(object /*, style*/) { |
| 13524 | return object.toISOString(); |
| 13525 | } |
| 13526 | |
| 13527 | module.exports = new Type('tag:yaml.org,2002:timestamp', { |
| 13528 | kind: 'scalar', |
| 13529 | resolve: resolveYamlTimestamp, |
| 13530 | construct: constructYamlTimestamp, |
| 13531 | instanceOf: Date, |
| 13532 | represent: representYamlTimestamp |
| 13533 | }); |
| 13534 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13535 | },{"../type":32}],49:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13536 | var baseIndexOf = require('../internal/baseIndexOf'), |
| 13537 | binaryIndex = require('../internal/binaryIndex'); |
| 13538 | |
| 13539 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 13540 | var nativeMax = Math.max; |
| 13541 | |
| 13542 | /** |
| 13543 | * Gets the index at which the first occurrence of `value` is found in `array` |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 13544 | * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
| 13545 | * for equality comparisons. If `fromIndex` is negative, it's used as the offset |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13546 | * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` |
| 13547 | * performs a faster binary search. |
| 13548 | * |
| 13549 | * @static |
| 13550 | * @memberOf _ |
| 13551 | * @category Array |
| 13552 | * @param {Array} array The array to search. |
| 13553 | * @param {*} value The value to search for. |
| 13554 | * @param {boolean|number} [fromIndex=0] The index to search from or `true` |
| 13555 | * to perform a binary search on a sorted array. |
| 13556 | * @returns {number} Returns the index of the matched value, else `-1`. |
| 13557 | * @example |
| 13558 | * |
| 13559 | * _.indexOf([1, 2, 1, 2], 2); |
| 13560 | * // => 1 |
| 13561 | * |
| 13562 | * // using `fromIndex` |
| 13563 | * _.indexOf([1, 2, 1, 2], 2, 2); |
| 13564 | * // => 3 |
| 13565 | * |
| 13566 | * // performing a binary search |
| 13567 | * _.indexOf([1, 1, 2, 2], 2, true); |
| 13568 | * // => 2 |
| 13569 | */ |
| 13570 | function indexOf(array, value, fromIndex) { |
| 13571 | var length = array ? array.length : 0; |
| 13572 | if (!length) { |
| 13573 | return -1; |
| 13574 | } |
| 13575 | if (typeof fromIndex == 'number') { |
| 13576 | fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; |
| 13577 | } else if (fromIndex) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 13578 | var index = binaryIndex(array, value); |
| 13579 | if (index < length && |
| 13580 | (value === value ? (value === array[index]) : (array[index] !== array[index]))) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13581 | return index; |
| 13582 | } |
| 13583 | return -1; |
| 13584 | } |
| 13585 | return baseIndexOf(array, value, fromIndex || 0); |
| 13586 | } |
| 13587 | |
| 13588 | module.exports = indexOf; |
| 13589 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13590 | },{"../internal/baseIndexOf":78,"../internal/binaryIndex":92}],50:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13591 | /** |
| 13592 | * Gets the last element of `array`. |
| 13593 | * |
| 13594 | * @static |
| 13595 | * @memberOf _ |
| 13596 | * @category Array |
| 13597 | * @param {Array} array The array to query. |
| 13598 | * @returns {*} Returns the last element of `array`. |
| 13599 | * @example |
| 13600 | * |
| 13601 | * _.last([1, 2, 3]); |
| 13602 | * // => 3 |
| 13603 | */ |
| 13604 | function last(array) { |
| 13605 | var length = array ? array.length : 0; |
| 13606 | return length ? array[length - 1] : undefined; |
| 13607 | } |
| 13608 | |
| 13609 | module.exports = last; |
| 13610 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13611 | },{}],51:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13612 | var LazyWrapper = require('../internal/LazyWrapper'), |
| 13613 | LodashWrapper = require('../internal/LodashWrapper'), |
| 13614 | baseLodash = require('../internal/baseLodash'), |
| 13615 | isArray = require('../lang/isArray'), |
| 13616 | isObjectLike = require('../internal/isObjectLike'), |
| 13617 | wrapperClone = require('../internal/wrapperClone'); |
| 13618 | |
| 13619 | /** Used for native method references. */ |
| 13620 | var objectProto = Object.prototype; |
| 13621 | |
| 13622 | /** Used to check objects for own properties. */ |
| 13623 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 13624 | |
| 13625 | /** |
| 13626 | * Creates a `lodash` object which wraps `value` to enable implicit chaining. |
| 13627 | * Methods that operate on and return arrays, collections, and functions can |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 13628 | * be chained together. Methods that retrieve a single value or may return a |
| 13629 | * primitive value will automatically end the chain returning the unwrapped |
| 13630 | * value. Explicit chaining may be enabled using `_.chain`. The execution of |
| 13631 | * chained methods is lazy, that is, execution is deferred until `_#value` |
| 13632 | * is implicitly or explicitly called. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13633 | * |
| 13634 | * Lazy evaluation allows several methods to support shortcut fusion. Shortcut |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 13635 | * fusion is an optimization strategy which merge iteratee calls; this can help |
| 13636 | * to avoid the creation of intermediate data structures and greatly reduce the |
| 13637 | * number of iteratee executions. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13638 | * |
| 13639 | * Chaining is supported in custom builds as long as the `_#value` method is |
| 13640 | * directly or indirectly included in the build. |
| 13641 | * |
| 13642 | * In addition to lodash methods, wrappers have `Array` and `String` methods. |
| 13643 | * |
| 13644 | * The wrapper `Array` methods are: |
| 13645 | * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, |
| 13646 | * `splice`, and `unshift` |
| 13647 | * |
| 13648 | * The wrapper `String` methods are: |
| 13649 | * `replace` and `split` |
| 13650 | * |
| 13651 | * The wrapper methods that support shortcut fusion are: |
| 13652 | * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, |
| 13653 | * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, |
| 13654 | * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, |
| 13655 | * and `where` |
| 13656 | * |
| 13657 | * The chainable wrapper methods are: |
| 13658 | * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, |
| 13659 | * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 13660 | * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, |
| 13661 | * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, |
| 13662 | * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, |
| 13663 | * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, |
| 13664 | * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, |
| 13665 | * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, |
| 13666 | * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, |
| 13667 | * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, |
| 13668 | * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, |
| 13669 | * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, |
| 13670 | * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, |
| 13671 | * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, |
| 13672 | * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, |
| 13673 | * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, |
| 13674 | * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13675 | * |
| 13676 | * The wrapper methods that are **not** chainable by default are: |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 13677 | * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, |
| 13678 | * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, |
| 13679 | * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, |
| 13680 | * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, |
| 13681 | * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, |
| 13682 | * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, |
| 13683 | * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, |
| 13684 | * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, |
| 13685 | * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, |
| 13686 | * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, |
| 13687 | * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, |
| 13688 | * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, |
| 13689 | * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, |
| 13690 | * `unescape`, `uniqueId`, `value`, and `words` |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13691 | * |
| 13692 | * The wrapper method `sample` will return a wrapped value when `n` is provided, |
| 13693 | * otherwise an unwrapped value is returned. |
| 13694 | * |
| 13695 | * @name _ |
| 13696 | * @constructor |
| 13697 | * @category Chain |
| 13698 | * @param {*} value The value to wrap in a `lodash` instance. |
| 13699 | * @returns {Object} Returns the new `lodash` wrapper instance. |
| 13700 | * @example |
| 13701 | * |
| 13702 | * var wrapped = _([1, 2, 3]); |
| 13703 | * |
| 13704 | * // returns an unwrapped value |
| 13705 | * wrapped.reduce(function(total, n) { |
| 13706 | * return total + n; |
| 13707 | * }); |
| 13708 | * // => 6 |
| 13709 | * |
| 13710 | * // returns a wrapped value |
| 13711 | * var squares = wrapped.map(function(n) { |
| 13712 | * return n * n; |
| 13713 | * }); |
| 13714 | * |
| 13715 | * _.isArray(squares); |
| 13716 | * // => false |
| 13717 | * |
| 13718 | * _.isArray(squares.value()); |
| 13719 | * // => true |
| 13720 | */ |
| 13721 | function lodash(value) { |
| 13722 | if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { |
| 13723 | if (value instanceof LodashWrapper) { |
| 13724 | return value; |
| 13725 | } |
| 13726 | if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { |
| 13727 | return wrapperClone(value); |
| 13728 | } |
| 13729 | } |
| 13730 | return new LodashWrapper(value); |
| 13731 | } |
| 13732 | |
| 13733 | // Ensure wrappers are instances of `baseLodash`. |
| 13734 | lodash.prototype = baseLodash.prototype; |
| 13735 | |
| 13736 | module.exports = lodash; |
| 13737 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13738 | },{"../internal/LazyWrapper":60,"../internal/LodashWrapper":61,"../internal/baseLodash":82,"../internal/isObjectLike":126,"../internal/wrapperClone":137,"../lang/isArray":140}],52:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13739 | module.exports = require('./forEach'); |
| 13740 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13741 | },{"./forEach":54}],53:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13742 | var baseEach = require('../internal/baseEach'), |
| 13743 | createFind = require('../internal/createFind'); |
| 13744 | |
| 13745 | /** |
| 13746 | * Iterates over elements of `collection`, returning the first element |
| 13747 | * `predicate` returns truthy for. The predicate is bound to `thisArg` and |
| 13748 | * invoked with three arguments: (value, index|key, collection). |
| 13749 | * |
| 13750 | * If a property name is provided for `predicate` the created `_.property` |
| 13751 | * style callback returns the property value of the given element. |
| 13752 | * |
| 13753 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 13754 | * style callback returns `true` for elements that have a matching property |
| 13755 | * value, else `false`. |
| 13756 | * |
| 13757 | * If an object is provided for `predicate` the created `_.matches` style |
| 13758 | * callback returns `true` for elements that have the properties of the given |
| 13759 | * object, else `false`. |
| 13760 | * |
| 13761 | * @static |
| 13762 | * @memberOf _ |
| 13763 | * @alias detect |
| 13764 | * @category Collection |
| 13765 | * @param {Array|Object|string} collection The collection to search. |
| 13766 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
| 13767 | * per iteration. |
| 13768 | * @param {*} [thisArg] The `this` binding of `predicate`. |
| 13769 | * @returns {*} Returns the matched element, else `undefined`. |
| 13770 | * @example |
| 13771 | * |
| 13772 | * var users = [ |
| 13773 | * { 'user': 'barney', 'age': 36, 'active': true }, |
| 13774 | * { 'user': 'fred', 'age': 40, 'active': false }, |
| 13775 | * { 'user': 'pebbles', 'age': 1, 'active': true } |
| 13776 | * ]; |
| 13777 | * |
| 13778 | * _.result(_.find(users, function(chr) { |
| 13779 | * return chr.age < 40; |
| 13780 | * }), 'user'); |
| 13781 | * // => 'barney' |
| 13782 | * |
| 13783 | * // using the `_.matches` callback shorthand |
| 13784 | * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); |
| 13785 | * // => 'pebbles' |
| 13786 | * |
| 13787 | * // using the `_.matchesProperty` callback shorthand |
| 13788 | * _.result(_.find(users, 'active', false), 'user'); |
| 13789 | * // => 'fred' |
| 13790 | * |
| 13791 | * // using the `_.property` callback shorthand |
| 13792 | * _.result(_.find(users, 'active'), 'user'); |
| 13793 | * // => 'barney' |
| 13794 | */ |
| 13795 | var find = createFind(baseEach); |
| 13796 | |
| 13797 | module.exports = find; |
| 13798 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13799 | },{"../internal/baseEach":71,"../internal/createFind":102}],54:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13800 | var arrayEach = require('../internal/arrayEach'), |
| 13801 | baseEach = require('../internal/baseEach'), |
| 13802 | createForEach = require('../internal/createForEach'); |
| 13803 | |
| 13804 | /** |
| 13805 | * Iterates over elements of `collection` invoking `iteratee` for each element. |
| 13806 | * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
| 13807 | * (value, index|key, collection). Iteratee functions may exit iteration early |
| 13808 | * by explicitly returning `false`. |
| 13809 | * |
| 13810 | * **Note:** As with other "Collections" methods, objects with a "length" property |
| 13811 | * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` |
| 13812 | * may be used for object iteration. |
| 13813 | * |
| 13814 | * @static |
| 13815 | * @memberOf _ |
| 13816 | * @alias each |
| 13817 | * @category Collection |
| 13818 | * @param {Array|Object|string} collection The collection to iterate over. |
| 13819 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
| 13820 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 13821 | * @returns {Array|Object|string} Returns `collection`. |
| 13822 | * @example |
| 13823 | * |
| 13824 | * _([1, 2]).forEach(function(n) { |
| 13825 | * console.log(n); |
| 13826 | * }).value(); |
| 13827 | * // => logs each value from left to right and returns the array |
| 13828 | * |
| 13829 | * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { |
| 13830 | * console.log(n, key); |
| 13831 | * }); |
| 13832 | * // => logs each value-key pair and returns the object (iteration order is not guaranteed) |
| 13833 | */ |
| 13834 | var forEach = createForEach(arrayEach, baseEach); |
| 13835 | |
| 13836 | module.exports = forEach; |
| 13837 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13838 | },{"../internal/arrayEach":63,"../internal/baseEach":71,"../internal/createForEach":103}],55:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13839 | var baseIndexOf = require('../internal/baseIndexOf'), |
| 13840 | getLength = require('../internal/getLength'), |
| 13841 | isArray = require('../lang/isArray'), |
| 13842 | isIterateeCall = require('../internal/isIterateeCall'), |
| 13843 | isLength = require('../internal/isLength'), |
| 13844 | isString = require('../lang/isString'), |
| 13845 | values = require('../object/values'); |
| 13846 | |
| 13847 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 13848 | var nativeMax = Math.max; |
| 13849 | |
| 13850 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 13851 | * Checks if `target` is in `collection` using |
| 13852 | * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
| 13853 | * for equality comparisons. If `fromIndex` is negative, it's used as the offset |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13854 | * from the end of `collection`. |
| 13855 | * |
| 13856 | * @static |
| 13857 | * @memberOf _ |
| 13858 | * @alias contains, include |
| 13859 | * @category Collection |
| 13860 | * @param {Array|Object|string} collection The collection to search. |
| 13861 | * @param {*} target The value to search for. |
| 13862 | * @param {number} [fromIndex=0] The index to search from. |
| 13863 | * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. |
| 13864 | * @returns {boolean} Returns `true` if a matching element is found, else `false`. |
| 13865 | * @example |
| 13866 | * |
| 13867 | * _.includes([1, 2, 3], 1); |
| 13868 | * // => true |
| 13869 | * |
| 13870 | * _.includes([1, 2, 3], 1, 2); |
| 13871 | * // => false |
| 13872 | * |
| 13873 | * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); |
| 13874 | * // => true |
| 13875 | * |
| 13876 | * _.includes('pebbles', 'eb'); |
| 13877 | * // => true |
| 13878 | */ |
| 13879 | function includes(collection, target, fromIndex, guard) { |
| 13880 | var length = collection ? getLength(collection) : 0; |
| 13881 | if (!isLength(length)) { |
| 13882 | collection = values(collection); |
| 13883 | length = collection.length; |
| 13884 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13885 | if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { |
| 13886 | fromIndex = 0; |
| 13887 | } else { |
| 13888 | fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); |
| 13889 | } |
| 13890 | return (typeof collection == 'string' || !isArray(collection) && isString(collection)) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 13891 | ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) |
| 13892 | : (!!length && baseIndexOf(collection, target, fromIndex) > -1); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13893 | } |
| 13894 | |
| 13895 | module.exports = includes; |
| 13896 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13897 | },{"../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){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13898 | var arrayMap = require('../internal/arrayMap'), |
| 13899 | baseCallback = require('../internal/baseCallback'), |
| 13900 | baseMap = require('../internal/baseMap'), |
| 13901 | isArray = require('../lang/isArray'); |
| 13902 | |
| 13903 | /** |
| 13904 | * Creates an array of values by running each element in `collection` through |
| 13905 | * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three |
| 13906 | * arguments: (value, index|key, collection). |
| 13907 | * |
| 13908 | * If a property name is provided for `iteratee` the created `_.property` |
| 13909 | * style callback returns the property value of the given element. |
| 13910 | * |
| 13911 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
| 13912 | * style callback returns `true` for elements that have a matching property |
| 13913 | * value, else `false`. |
| 13914 | * |
| 13915 | * If an object is provided for `iteratee` the created `_.matches` style |
| 13916 | * callback returns `true` for elements that have the properties of the given |
| 13917 | * object, else `false`. |
| 13918 | * |
| 13919 | * Many lodash methods are guarded to work as iteratees for methods like |
| 13920 | * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. |
| 13921 | * |
| 13922 | * The guarded methods are: |
| 13923 | * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, |
| 13924 | * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, |
| 13925 | * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, |
| 13926 | * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, |
| 13927 | * `sum`, `uniq`, and `words` |
| 13928 | * |
| 13929 | * @static |
| 13930 | * @memberOf _ |
| 13931 | * @alias collect |
| 13932 | * @category Collection |
| 13933 | * @param {Array|Object|string} collection The collection to iterate over. |
| 13934 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
| 13935 | * per iteration. |
| 13936 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
| 13937 | * @returns {Array} Returns the new mapped array. |
| 13938 | * @example |
| 13939 | * |
| 13940 | * function timesThree(n) { |
| 13941 | * return n * 3; |
| 13942 | * } |
| 13943 | * |
| 13944 | * _.map([1, 2], timesThree); |
| 13945 | * // => [3, 6] |
| 13946 | * |
| 13947 | * _.map({ 'a': 1, 'b': 2 }, timesThree); |
| 13948 | * // => [3, 6] (iteration order is not guaranteed) |
| 13949 | * |
| 13950 | * var users = [ |
| 13951 | * { 'user': 'barney' }, |
| 13952 | * { 'user': 'fred' } |
| 13953 | * ]; |
| 13954 | * |
| 13955 | * // using the `_.property` callback shorthand |
| 13956 | * _.map(users, 'user'); |
| 13957 | * // => ['barney', 'fred'] |
| 13958 | */ |
| 13959 | function map(collection, iteratee, thisArg) { |
| 13960 | var func = isArray(collection) ? arrayMap : baseMap; |
| 13961 | iteratee = baseCallback(iteratee, thisArg, 3); |
| 13962 | return func(collection, iteratee); |
| 13963 | } |
| 13964 | |
| 13965 | module.exports = map; |
| 13966 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13967 | },{"../internal/arrayMap":64,"../internal/baseCallback":67,"../internal/baseMap":83,"../lang/isArray":140}],57:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13968 | var getNative = require('../internal/getNative'); |
| 13969 | |
| 13970 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 13971 | var nativeNow = getNative(Date, 'now'); |
| 13972 | |
| 13973 | /** |
| 13974 | * Gets the number of milliseconds that have elapsed since the Unix epoch |
| 13975 | * (1 January 1970 00:00:00 UTC). |
| 13976 | * |
| 13977 | * @static |
| 13978 | * @memberOf _ |
| 13979 | * @category Date |
| 13980 | * @example |
| 13981 | * |
| 13982 | * _.defer(function(stamp) { |
| 13983 | * console.log(_.now() - stamp); |
| 13984 | * }, _.now()); |
| 13985 | * // => logs the number of milliseconds it took for the deferred function to be invoked |
| 13986 | */ |
| 13987 | var now = nativeNow || function() { |
| 13988 | return new Date().getTime(); |
| 13989 | }; |
| 13990 | |
| 13991 | module.exports = now; |
| 13992 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 13993 | },{"../internal/getNative":114}],58:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 13994 | var createWrapper = require('../internal/createWrapper'), |
| 13995 | replaceHolders = require('../internal/replaceHolders'), |
| 13996 | restParam = require('./restParam'); |
| 13997 | |
| 13998 | /** Used to compose bitmasks for wrapper metadata. */ |
| 13999 | var BIND_FLAG = 1, |
| 14000 | PARTIAL_FLAG = 32; |
| 14001 | |
| 14002 | /** |
| 14003 | * Creates a function that invokes `func` with the `this` binding of `thisArg` |
| 14004 | * and prepends any additional `_.bind` arguments to those provided to the |
| 14005 | * bound function. |
| 14006 | * |
| 14007 | * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, |
| 14008 | * may be used as a placeholder for partially applied arguments. |
| 14009 | * |
| 14010 | * **Note:** Unlike native `Function#bind` this method does not set the "length" |
| 14011 | * property of bound functions. |
| 14012 | * |
| 14013 | * @static |
| 14014 | * @memberOf _ |
| 14015 | * @category Function |
| 14016 | * @param {Function} func The function to bind. |
| 14017 | * @param {*} thisArg The `this` binding of `func`. |
| 14018 | * @param {...*} [partials] The arguments to be partially applied. |
| 14019 | * @returns {Function} Returns the new bound function. |
| 14020 | * @example |
| 14021 | * |
| 14022 | * var greet = function(greeting, punctuation) { |
| 14023 | * return greeting + ' ' + this.user + punctuation; |
| 14024 | * }; |
| 14025 | * |
| 14026 | * var object = { 'user': 'fred' }; |
| 14027 | * |
| 14028 | * var bound = _.bind(greet, object, 'hi'); |
| 14029 | * bound('!'); |
| 14030 | * // => 'hi fred!' |
| 14031 | * |
| 14032 | * // using placeholders |
| 14033 | * var bound = _.bind(greet, object, _, '!'); |
| 14034 | * bound('hi'); |
| 14035 | * // => 'hi fred!' |
| 14036 | */ |
| 14037 | var bind = restParam(function(func, thisArg, partials) { |
| 14038 | var bitmask = BIND_FLAG; |
| 14039 | if (partials.length) { |
| 14040 | var holders = replaceHolders(partials, bind.placeholder); |
| 14041 | bitmask |= PARTIAL_FLAG; |
| 14042 | } |
| 14043 | return createWrapper(func, bitmask, thisArg, partials, holders); |
| 14044 | }); |
| 14045 | |
| 14046 | // Assign default placeholders. |
| 14047 | bind.placeholder = {}; |
| 14048 | |
| 14049 | module.exports = bind; |
| 14050 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14051 | },{"../internal/createWrapper":106,"../internal/replaceHolders":132,"./restParam":59}],59:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14052 | /** Used as the `TypeError` message for "Functions" methods. */ |
| 14053 | var FUNC_ERROR_TEXT = 'Expected a function'; |
| 14054 | |
| 14055 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 14056 | var nativeMax = Math.max; |
| 14057 | |
| 14058 | /** |
| 14059 | * Creates a function that invokes `func` with the `this` binding of the |
| 14060 | * created function and arguments from `start` and beyond provided as an array. |
| 14061 | * |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 14062 | * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters). |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14063 | * |
| 14064 | * @static |
| 14065 | * @memberOf _ |
| 14066 | * @category Function |
| 14067 | * @param {Function} func The function to apply a rest parameter to. |
| 14068 | * @param {number} [start=func.length-1] The start position of the rest parameter. |
| 14069 | * @returns {Function} Returns the new function. |
| 14070 | * @example |
| 14071 | * |
| 14072 | * var say = _.restParam(function(what, names) { |
| 14073 | * return what + ' ' + _.initial(names).join(', ') + |
| 14074 | * (_.size(names) > 1 ? ', & ' : '') + _.last(names); |
| 14075 | * }); |
| 14076 | * |
| 14077 | * say('hello', 'fred', 'barney', 'pebbles'); |
| 14078 | * // => 'hello fred, barney, & pebbles' |
| 14079 | */ |
| 14080 | function restParam(func, start) { |
| 14081 | if (typeof func != 'function') { |
| 14082 | throw new TypeError(FUNC_ERROR_TEXT); |
| 14083 | } |
| 14084 | start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); |
| 14085 | return function() { |
| 14086 | var args = arguments, |
| 14087 | index = -1, |
| 14088 | length = nativeMax(args.length - start, 0), |
| 14089 | rest = Array(length); |
| 14090 | |
| 14091 | while (++index < length) { |
| 14092 | rest[index] = args[start + index]; |
| 14093 | } |
| 14094 | switch (start) { |
| 14095 | case 0: return func.call(this, rest); |
| 14096 | case 1: return func.call(this, args[0], rest); |
| 14097 | case 2: return func.call(this, args[0], args[1], rest); |
| 14098 | } |
| 14099 | var otherArgs = Array(start + 1); |
| 14100 | index = -1; |
| 14101 | while (++index < start) { |
| 14102 | otherArgs[index] = args[index]; |
| 14103 | } |
| 14104 | otherArgs[start] = rest; |
| 14105 | return func.apply(this, otherArgs); |
| 14106 | }; |
| 14107 | } |
| 14108 | |
| 14109 | module.exports = restParam; |
| 14110 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14111 | },{}],60:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14112 | var baseCreate = require('./baseCreate'), |
| 14113 | baseLodash = require('./baseLodash'); |
| 14114 | |
| 14115 | /** Used as references for `-Infinity` and `Infinity`. */ |
| 14116 | var POSITIVE_INFINITY = Number.POSITIVE_INFINITY; |
| 14117 | |
| 14118 | /** |
| 14119 | * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. |
| 14120 | * |
| 14121 | * @private |
| 14122 | * @param {*} value The value to wrap. |
| 14123 | */ |
| 14124 | function LazyWrapper(value) { |
| 14125 | this.__wrapped__ = value; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 14126 | this.__actions__ = []; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14127 | this.__dir__ = 1; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14128 | this.__filtered__ = false; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 14129 | this.__iteratees__ = []; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14130 | this.__takeCount__ = POSITIVE_INFINITY; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 14131 | this.__views__ = []; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14132 | } |
| 14133 | |
| 14134 | LazyWrapper.prototype = baseCreate(baseLodash.prototype); |
| 14135 | LazyWrapper.prototype.constructor = LazyWrapper; |
| 14136 | |
| 14137 | module.exports = LazyWrapper; |
| 14138 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14139 | },{"./baseCreate":70,"./baseLodash":82}],61:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14140 | var baseCreate = require('./baseCreate'), |
| 14141 | baseLodash = require('./baseLodash'); |
| 14142 | |
| 14143 | /** |
| 14144 | * The base constructor for creating `lodash` wrapper objects. |
| 14145 | * |
| 14146 | * @private |
| 14147 | * @param {*} value The value to wrap. |
| 14148 | * @param {boolean} [chainAll] Enable chaining for all wrapper methods. |
| 14149 | * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. |
| 14150 | */ |
| 14151 | function LodashWrapper(value, chainAll, actions) { |
| 14152 | this.__wrapped__ = value; |
| 14153 | this.__actions__ = actions || []; |
| 14154 | this.__chain__ = !!chainAll; |
| 14155 | } |
| 14156 | |
| 14157 | LodashWrapper.prototype = baseCreate(baseLodash.prototype); |
| 14158 | LodashWrapper.prototype.constructor = LodashWrapper; |
| 14159 | |
| 14160 | module.exports = LodashWrapper; |
| 14161 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14162 | },{"./baseCreate":70,"./baseLodash":82}],62:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14163 | /** |
| 14164 | * Copies the values of `source` to `array`. |
| 14165 | * |
| 14166 | * @private |
| 14167 | * @param {Array} source The array to copy values from. |
| 14168 | * @param {Array} [array=[]] The array to copy values to. |
| 14169 | * @returns {Array} Returns `array`. |
| 14170 | */ |
| 14171 | function arrayCopy(source, array) { |
| 14172 | var index = -1, |
| 14173 | length = source.length; |
| 14174 | |
| 14175 | array || (array = Array(length)); |
| 14176 | while (++index < length) { |
| 14177 | array[index] = source[index]; |
| 14178 | } |
| 14179 | return array; |
| 14180 | } |
| 14181 | |
| 14182 | module.exports = arrayCopy; |
| 14183 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14184 | },{}],63:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14185 | /** |
| 14186 | * A specialized version of `_.forEach` for arrays without support for callback |
| 14187 | * shorthands and `this` binding. |
| 14188 | * |
| 14189 | * @private |
| 14190 | * @param {Array} array The array to iterate over. |
| 14191 | * @param {Function} iteratee The function invoked per iteration. |
| 14192 | * @returns {Array} Returns `array`. |
| 14193 | */ |
| 14194 | function arrayEach(array, iteratee) { |
| 14195 | var index = -1, |
| 14196 | length = array.length; |
| 14197 | |
| 14198 | while (++index < length) { |
| 14199 | if (iteratee(array[index], index, array) === false) { |
| 14200 | break; |
| 14201 | } |
| 14202 | } |
| 14203 | return array; |
| 14204 | } |
| 14205 | |
| 14206 | module.exports = arrayEach; |
| 14207 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14208 | },{}],64:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14209 | /** |
| 14210 | * A specialized version of `_.map` for arrays without support for callback |
| 14211 | * shorthands and `this` binding. |
| 14212 | * |
| 14213 | * @private |
| 14214 | * @param {Array} array The array to iterate over. |
| 14215 | * @param {Function} iteratee The function invoked per iteration. |
| 14216 | * @returns {Array} Returns the new mapped array. |
| 14217 | */ |
| 14218 | function arrayMap(array, iteratee) { |
| 14219 | var index = -1, |
| 14220 | length = array.length, |
| 14221 | result = Array(length); |
| 14222 | |
| 14223 | while (++index < length) { |
| 14224 | result[index] = iteratee(array[index], index, array); |
| 14225 | } |
| 14226 | return result; |
| 14227 | } |
| 14228 | |
| 14229 | module.exports = arrayMap; |
| 14230 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14231 | },{}],65:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14232 | /** |
| 14233 | * A specialized version of `_.some` for arrays without support for callback |
| 14234 | * shorthands and `this` binding. |
| 14235 | * |
| 14236 | * @private |
| 14237 | * @param {Array} array The array to iterate over. |
| 14238 | * @param {Function} predicate The function invoked per iteration. |
| 14239 | * @returns {boolean} Returns `true` if any element passes the predicate check, |
| 14240 | * else `false`. |
| 14241 | */ |
| 14242 | function arraySome(array, predicate) { |
| 14243 | var index = -1, |
| 14244 | length = array.length; |
| 14245 | |
| 14246 | while (++index < length) { |
| 14247 | if (predicate(array[index], index, array)) { |
| 14248 | return true; |
| 14249 | } |
| 14250 | } |
| 14251 | return false; |
| 14252 | } |
| 14253 | |
| 14254 | module.exports = arraySome; |
| 14255 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14256 | },{}],66:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14257 | var baseCopy = require('./baseCopy'), |
| 14258 | keys = require('../object/keys'); |
| 14259 | |
| 14260 | /** |
| 14261 | * The base implementation of `_.assign` without support for argument juggling, |
| 14262 | * multiple sources, and `customizer` functions. |
| 14263 | * |
| 14264 | * @private |
| 14265 | * @param {Object} object The destination object. |
| 14266 | * @param {Object} source The source object. |
| 14267 | * @returns {Object} Returns `object`. |
| 14268 | */ |
| 14269 | function baseAssign(object, source) { |
| 14270 | return source == null |
| 14271 | ? object |
| 14272 | : baseCopy(source, keys(source), object); |
| 14273 | } |
| 14274 | |
| 14275 | module.exports = baseAssign; |
| 14276 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14277 | },{"../object/keys":149,"./baseCopy":69}],67:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14278 | var baseMatches = require('./baseMatches'), |
| 14279 | baseMatchesProperty = require('./baseMatchesProperty'), |
| 14280 | bindCallback = require('./bindCallback'), |
| 14281 | identity = require('../utility/identity'), |
| 14282 | property = require('../utility/property'); |
| 14283 | |
| 14284 | /** |
| 14285 | * The base implementation of `_.callback` which supports specifying the |
| 14286 | * number of arguments to provide to `func`. |
| 14287 | * |
| 14288 | * @private |
| 14289 | * @param {*} [func=_.identity] The value to convert to a callback. |
| 14290 | * @param {*} [thisArg] The `this` binding of `func`. |
| 14291 | * @param {number} [argCount] The number of arguments to provide to `func`. |
| 14292 | * @returns {Function} Returns the callback. |
| 14293 | */ |
| 14294 | function baseCallback(func, thisArg, argCount) { |
| 14295 | var type = typeof func; |
| 14296 | if (type == 'function') { |
| 14297 | return thisArg === undefined |
| 14298 | ? func |
| 14299 | : bindCallback(func, thisArg, argCount); |
| 14300 | } |
| 14301 | if (func == null) { |
| 14302 | return identity; |
| 14303 | } |
| 14304 | if (type == 'object') { |
| 14305 | return baseMatches(func); |
| 14306 | } |
| 14307 | return thisArg === undefined |
| 14308 | ? property(func) |
| 14309 | : baseMatchesProperty(func, thisArg); |
| 14310 | } |
| 14311 | |
| 14312 | module.exports = baseCallback; |
| 14313 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14314 | },{"../utility/identity":154,"../utility/property":156,"./baseMatches":84,"./baseMatchesProperty":85,"./bindCallback":94}],68:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14315 | var arrayCopy = require('./arrayCopy'), |
| 14316 | arrayEach = require('./arrayEach'), |
| 14317 | baseAssign = require('./baseAssign'), |
| 14318 | baseForOwn = require('./baseForOwn'), |
| 14319 | initCloneArray = require('./initCloneArray'), |
| 14320 | initCloneByTag = require('./initCloneByTag'), |
| 14321 | initCloneObject = require('./initCloneObject'), |
| 14322 | isArray = require('../lang/isArray'), |
| 14323 | isHostObject = require('./isHostObject'), |
| 14324 | isObject = require('../lang/isObject'); |
| 14325 | |
| 14326 | /** `Object#toString` result references. */ |
| 14327 | var argsTag = '[object Arguments]', |
| 14328 | arrayTag = '[object Array]', |
| 14329 | boolTag = '[object Boolean]', |
| 14330 | dateTag = '[object Date]', |
| 14331 | errorTag = '[object Error]', |
| 14332 | funcTag = '[object Function]', |
| 14333 | mapTag = '[object Map]', |
| 14334 | numberTag = '[object Number]', |
| 14335 | objectTag = '[object Object]', |
| 14336 | regexpTag = '[object RegExp]', |
| 14337 | setTag = '[object Set]', |
| 14338 | stringTag = '[object String]', |
| 14339 | weakMapTag = '[object WeakMap]'; |
| 14340 | |
| 14341 | var arrayBufferTag = '[object ArrayBuffer]', |
| 14342 | float32Tag = '[object Float32Array]', |
| 14343 | float64Tag = '[object Float64Array]', |
| 14344 | int8Tag = '[object Int8Array]', |
| 14345 | int16Tag = '[object Int16Array]', |
| 14346 | int32Tag = '[object Int32Array]', |
| 14347 | uint8Tag = '[object Uint8Array]', |
| 14348 | uint8ClampedTag = '[object Uint8ClampedArray]', |
| 14349 | uint16Tag = '[object Uint16Array]', |
| 14350 | uint32Tag = '[object Uint32Array]'; |
| 14351 | |
| 14352 | /** Used to identify `toStringTag` values supported by `_.clone`. */ |
| 14353 | var cloneableTags = {}; |
| 14354 | cloneableTags[argsTag] = cloneableTags[arrayTag] = |
| 14355 | cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = |
| 14356 | cloneableTags[dateTag] = cloneableTags[float32Tag] = |
| 14357 | cloneableTags[float64Tag] = cloneableTags[int8Tag] = |
| 14358 | cloneableTags[int16Tag] = cloneableTags[int32Tag] = |
| 14359 | cloneableTags[numberTag] = cloneableTags[objectTag] = |
| 14360 | cloneableTags[regexpTag] = cloneableTags[stringTag] = |
| 14361 | cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = |
| 14362 | cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; |
| 14363 | cloneableTags[errorTag] = cloneableTags[funcTag] = |
| 14364 | cloneableTags[mapTag] = cloneableTags[setTag] = |
| 14365 | cloneableTags[weakMapTag] = false; |
| 14366 | |
| 14367 | /** Used for native method references. */ |
| 14368 | var objectProto = Object.prototype; |
| 14369 | |
| 14370 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 14371 | * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14372 | * of values. |
| 14373 | */ |
| 14374 | var objToString = objectProto.toString; |
| 14375 | |
| 14376 | /** |
| 14377 | * The base implementation of `_.clone` without support for argument juggling |
| 14378 | * and `this` binding `customizer` functions. |
| 14379 | * |
| 14380 | * @private |
| 14381 | * @param {*} value The value to clone. |
| 14382 | * @param {boolean} [isDeep] Specify a deep clone. |
| 14383 | * @param {Function} [customizer] The function to customize cloning values. |
| 14384 | * @param {string} [key] The key of `value`. |
| 14385 | * @param {Object} [object] The object `value` belongs to. |
| 14386 | * @param {Array} [stackA=[]] Tracks traversed source objects. |
| 14387 | * @param {Array} [stackB=[]] Associates clones with source counterparts. |
| 14388 | * @returns {*} Returns the cloned value. |
| 14389 | */ |
| 14390 | function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { |
| 14391 | var result; |
| 14392 | if (customizer) { |
| 14393 | result = object ? customizer(value, key, object) : customizer(value); |
| 14394 | } |
| 14395 | if (result !== undefined) { |
| 14396 | return result; |
| 14397 | } |
| 14398 | if (!isObject(value)) { |
| 14399 | return value; |
| 14400 | } |
| 14401 | var isArr = isArray(value); |
| 14402 | if (isArr) { |
| 14403 | result = initCloneArray(value); |
| 14404 | if (!isDeep) { |
| 14405 | return arrayCopy(value, result); |
| 14406 | } |
| 14407 | } else { |
| 14408 | var tag = objToString.call(value), |
| 14409 | isFunc = tag == funcTag; |
| 14410 | |
| 14411 | if (tag == objectTag || tag == argsTag || (isFunc && !object)) { |
| 14412 | if (isHostObject(value)) { |
| 14413 | return object ? value : {}; |
| 14414 | } |
| 14415 | result = initCloneObject(isFunc ? {} : value); |
| 14416 | if (!isDeep) { |
| 14417 | return baseAssign(result, value); |
| 14418 | } |
| 14419 | } else { |
| 14420 | return cloneableTags[tag] |
| 14421 | ? initCloneByTag(value, tag, isDeep) |
| 14422 | : (object ? value : {}); |
| 14423 | } |
| 14424 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 14425 | // Check for circular references and return its corresponding clone. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14426 | stackA || (stackA = []); |
| 14427 | stackB || (stackB = []); |
| 14428 | |
| 14429 | var length = stackA.length; |
| 14430 | while (length--) { |
| 14431 | if (stackA[length] == value) { |
| 14432 | return stackB[length]; |
| 14433 | } |
| 14434 | } |
| 14435 | // Add the source value to the stack of traversed objects and associate it with its clone. |
| 14436 | stackA.push(value); |
| 14437 | stackB.push(result); |
| 14438 | |
| 14439 | // Recursively populate clone (susceptible to call stack limits). |
| 14440 | (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { |
| 14441 | result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); |
| 14442 | }); |
| 14443 | return result; |
| 14444 | } |
| 14445 | |
| 14446 | module.exports = baseClone; |
| 14447 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14448 | },{"../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){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14449 | /** |
| 14450 | * Copies properties of `source` to `object`. |
| 14451 | * |
| 14452 | * @private |
| 14453 | * @param {Object} source The object to copy properties from. |
| 14454 | * @param {Array} props The property names to copy. |
| 14455 | * @param {Object} [object={}] The object to copy properties to. |
| 14456 | * @returns {Object} Returns `object`. |
| 14457 | */ |
| 14458 | function baseCopy(source, props, object) { |
| 14459 | object || (object = {}); |
| 14460 | |
| 14461 | var index = -1, |
| 14462 | length = props.length; |
| 14463 | |
| 14464 | while (++index < length) { |
| 14465 | var key = props[index]; |
| 14466 | object[key] = source[key]; |
| 14467 | } |
| 14468 | return object; |
| 14469 | } |
| 14470 | |
| 14471 | module.exports = baseCopy; |
| 14472 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14473 | },{}],70:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14474 | var isObject = require('../lang/isObject'); |
| 14475 | |
| 14476 | /** |
| 14477 | * The base implementation of `_.create` without support for assigning |
| 14478 | * properties to the created object. |
| 14479 | * |
| 14480 | * @private |
| 14481 | * @param {Object} prototype The object to inherit from. |
| 14482 | * @returns {Object} Returns the new object. |
| 14483 | */ |
| 14484 | var baseCreate = (function() { |
| 14485 | function object() {} |
| 14486 | return function(prototype) { |
| 14487 | if (isObject(prototype)) { |
| 14488 | object.prototype = prototype; |
| 14489 | var result = new object; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 14490 | object.prototype = undefined; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14491 | } |
| 14492 | return result || {}; |
| 14493 | }; |
| 14494 | }()); |
| 14495 | |
| 14496 | module.exports = baseCreate; |
| 14497 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14498 | },{"../lang/isObject":144}],71:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14499 | var baseForOwn = require('./baseForOwn'), |
| 14500 | createBaseEach = require('./createBaseEach'); |
| 14501 | |
| 14502 | /** |
| 14503 | * The base implementation of `_.forEach` without support for callback |
| 14504 | * shorthands and `this` binding. |
| 14505 | * |
| 14506 | * @private |
| 14507 | * @param {Array|Object|string} collection The collection to iterate over. |
| 14508 | * @param {Function} iteratee The function invoked per iteration. |
| 14509 | * @returns {Array|Object|string} Returns `collection`. |
| 14510 | */ |
| 14511 | var baseEach = createBaseEach(baseForOwn); |
| 14512 | |
| 14513 | module.exports = baseEach; |
| 14514 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14515 | },{"./baseForOwn":76,"./createBaseEach":98}],72:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14516 | /** |
| 14517 | * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, |
| 14518 | * without support for callback shorthands and `this` binding, which iterates |
| 14519 | * over `collection` using the provided `eachFunc`. |
| 14520 | * |
| 14521 | * @private |
| 14522 | * @param {Array|Object|string} collection The collection to search. |
| 14523 | * @param {Function} predicate The function invoked per iteration. |
| 14524 | * @param {Function} eachFunc The function to iterate over `collection`. |
| 14525 | * @param {boolean} [retKey] Specify returning the key of the found element |
| 14526 | * instead of the element itself. |
| 14527 | * @returns {*} Returns the found element or its key, else `undefined`. |
| 14528 | */ |
| 14529 | function baseFind(collection, predicate, eachFunc, retKey) { |
| 14530 | var result; |
| 14531 | eachFunc(collection, function(value, key, collection) { |
| 14532 | if (predicate(value, key, collection)) { |
| 14533 | result = retKey ? key : value; |
| 14534 | return false; |
| 14535 | } |
| 14536 | }); |
| 14537 | return result; |
| 14538 | } |
| 14539 | |
| 14540 | module.exports = baseFind; |
| 14541 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14542 | },{}],73:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14543 | /** |
| 14544 | * The base implementation of `_.findIndex` and `_.findLastIndex` without |
| 14545 | * support for callback shorthands and `this` binding. |
| 14546 | * |
| 14547 | * @private |
| 14548 | * @param {Array} array The array to search. |
| 14549 | * @param {Function} predicate The function invoked per iteration. |
| 14550 | * @param {boolean} [fromRight] Specify iterating from right to left. |
| 14551 | * @returns {number} Returns the index of the matched value, else `-1`. |
| 14552 | */ |
| 14553 | function baseFindIndex(array, predicate, fromRight) { |
| 14554 | var length = array.length, |
| 14555 | index = fromRight ? length : -1; |
| 14556 | |
| 14557 | while ((fromRight ? index-- : ++index < length)) { |
| 14558 | if (predicate(array[index], index, array)) { |
| 14559 | return index; |
| 14560 | } |
| 14561 | } |
| 14562 | return -1; |
| 14563 | } |
| 14564 | |
| 14565 | module.exports = baseFindIndex; |
| 14566 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14567 | },{}],74:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14568 | var createBaseFor = require('./createBaseFor'); |
| 14569 | |
| 14570 | /** |
| 14571 | * The base implementation of `baseForIn` and `baseForOwn` which iterates |
| 14572 | * over `object` properties returned by `keysFunc` invoking `iteratee` for |
| 14573 | * each property. Iteratee functions may exit iteration early by explicitly |
| 14574 | * returning `false`. |
| 14575 | * |
| 14576 | * @private |
| 14577 | * @param {Object} object The object to iterate over. |
| 14578 | * @param {Function} iteratee The function invoked per iteration. |
| 14579 | * @param {Function} keysFunc The function to get the keys of `object`. |
| 14580 | * @returns {Object} Returns `object`. |
| 14581 | */ |
| 14582 | var baseFor = createBaseFor(); |
| 14583 | |
| 14584 | module.exports = baseFor; |
| 14585 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14586 | },{"./createBaseFor":99}],75:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14587 | var baseFor = require('./baseFor'), |
| 14588 | keysIn = require('../object/keysIn'); |
| 14589 | |
| 14590 | /** |
| 14591 | * The base implementation of `_.forIn` without support for callback |
| 14592 | * shorthands and `this` binding. |
| 14593 | * |
| 14594 | * @private |
| 14595 | * @param {Object} object The object to iterate over. |
| 14596 | * @param {Function} iteratee The function invoked per iteration. |
| 14597 | * @returns {Object} Returns `object`. |
| 14598 | */ |
| 14599 | function baseForIn(object, iteratee) { |
| 14600 | return baseFor(object, iteratee, keysIn); |
| 14601 | } |
| 14602 | |
| 14603 | module.exports = baseForIn; |
| 14604 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14605 | },{"../object/keysIn":150,"./baseFor":74}],76:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14606 | var baseFor = require('./baseFor'), |
| 14607 | keys = require('../object/keys'); |
| 14608 | |
| 14609 | /** |
| 14610 | * The base implementation of `_.forOwn` without support for callback |
| 14611 | * shorthands and `this` binding. |
| 14612 | * |
| 14613 | * @private |
| 14614 | * @param {Object} object The object to iterate over. |
| 14615 | * @param {Function} iteratee The function invoked per iteration. |
| 14616 | * @returns {Object} Returns `object`. |
| 14617 | */ |
| 14618 | function baseForOwn(object, iteratee) { |
| 14619 | return baseFor(object, iteratee, keys); |
| 14620 | } |
| 14621 | |
| 14622 | module.exports = baseForOwn; |
| 14623 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14624 | },{"../object/keys":149,"./baseFor":74}],77:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14625 | var toObject = require('./toObject'); |
| 14626 | |
| 14627 | /** |
| 14628 | * The base implementation of `get` without support for string paths |
| 14629 | * and default values. |
| 14630 | * |
| 14631 | * @private |
| 14632 | * @param {Object} object The object to query. |
| 14633 | * @param {Array} path The path of the property to get. |
| 14634 | * @param {string} [pathKey] The key representation of path. |
| 14635 | * @returns {*} Returns the resolved value. |
| 14636 | */ |
| 14637 | function baseGet(object, path, pathKey) { |
| 14638 | if (object == null) { |
| 14639 | return; |
| 14640 | } |
| 14641 | object = toObject(object); |
| 14642 | if (pathKey !== undefined && pathKey in object) { |
| 14643 | path = [pathKey]; |
| 14644 | } |
| 14645 | var index = 0, |
| 14646 | length = path.length; |
| 14647 | |
| 14648 | while (object != null && index < length) { |
| 14649 | object = toObject(object)[path[index++]]; |
| 14650 | } |
| 14651 | return (index && index == length) ? object : undefined; |
| 14652 | } |
| 14653 | |
| 14654 | module.exports = baseGet; |
| 14655 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14656 | },{"./toObject":135}],78:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14657 | var indexOfNaN = require('./indexOfNaN'); |
| 14658 | |
| 14659 | /** |
| 14660 | * The base implementation of `_.indexOf` without support for binary searches. |
| 14661 | * |
| 14662 | * @private |
| 14663 | * @param {Array} array The array to search. |
| 14664 | * @param {*} value The value to search for. |
| 14665 | * @param {number} fromIndex The index to search from. |
| 14666 | * @returns {number} Returns the index of the matched value, else `-1`. |
| 14667 | */ |
| 14668 | function baseIndexOf(array, value, fromIndex) { |
| 14669 | if (value !== value) { |
| 14670 | return indexOfNaN(array, fromIndex); |
| 14671 | } |
| 14672 | var index = fromIndex - 1, |
| 14673 | length = array.length; |
| 14674 | |
| 14675 | while (++index < length) { |
| 14676 | if (array[index] === value) { |
| 14677 | return index; |
| 14678 | } |
| 14679 | } |
| 14680 | return -1; |
| 14681 | } |
| 14682 | |
| 14683 | module.exports = baseIndexOf; |
| 14684 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14685 | },{"./indexOfNaN":115}],79:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14686 | var baseIsEqualDeep = require('./baseIsEqualDeep'), |
| 14687 | isObject = require('../lang/isObject'), |
| 14688 | isObjectLike = require('./isObjectLike'); |
| 14689 | |
| 14690 | /** |
| 14691 | * The base implementation of `_.isEqual` without support for `this` binding |
| 14692 | * `customizer` functions. |
| 14693 | * |
| 14694 | * @private |
| 14695 | * @param {*} value The value to compare. |
| 14696 | * @param {*} other The other value to compare. |
| 14697 | * @param {Function} [customizer] The function to customize comparing values. |
| 14698 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 14699 | * @param {Array} [stackA] Tracks traversed `value` objects. |
| 14700 | * @param {Array} [stackB] Tracks traversed `other` objects. |
| 14701 | * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
| 14702 | */ |
| 14703 | function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { |
| 14704 | if (value === other) { |
| 14705 | return true; |
| 14706 | } |
| 14707 | if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { |
| 14708 | return value !== value && other !== other; |
| 14709 | } |
| 14710 | return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); |
| 14711 | } |
| 14712 | |
| 14713 | module.exports = baseIsEqual; |
| 14714 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14715 | },{"../lang/isObject":144,"./baseIsEqualDeep":80,"./isObjectLike":126}],80:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14716 | var equalArrays = require('./equalArrays'), |
| 14717 | equalByTag = require('./equalByTag'), |
| 14718 | equalObjects = require('./equalObjects'), |
| 14719 | isArray = require('../lang/isArray'), |
| 14720 | isHostObject = require('./isHostObject'), |
| 14721 | isTypedArray = require('../lang/isTypedArray'); |
| 14722 | |
| 14723 | /** `Object#toString` result references. */ |
| 14724 | var argsTag = '[object Arguments]', |
| 14725 | arrayTag = '[object Array]', |
| 14726 | objectTag = '[object Object]'; |
| 14727 | |
| 14728 | /** Used for native method references. */ |
| 14729 | var objectProto = Object.prototype; |
| 14730 | |
| 14731 | /** Used to check objects for own properties. */ |
| 14732 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 14733 | |
| 14734 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 14735 | * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14736 | * of values. |
| 14737 | */ |
| 14738 | var objToString = objectProto.toString; |
| 14739 | |
| 14740 | /** |
| 14741 | * A specialized version of `baseIsEqual` for arrays and objects which performs |
| 14742 | * deep comparisons and tracks traversed objects enabling objects with circular |
| 14743 | * references to be compared. |
| 14744 | * |
| 14745 | * @private |
| 14746 | * @param {Object} object The object to compare. |
| 14747 | * @param {Object} other The other object to compare. |
| 14748 | * @param {Function} equalFunc The function to determine equivalents of values. |
| 14749 | * @param {Function} [customizer] The function to customize comparing objects. |
| 14750 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 14751 | * @param {Array} [stackA=[]] Tracks traversed `value` objects. |
| 14752 | * @param {Array} [stackB=[]] Tracks traversed `other` objects. |
| 14753 | * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
| 14754 | */ |
| 14755 | function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { |
| 14756 | var objIsArr = isArray(object), |
| 14757 | othIsArr = isArray(other), |
| 14758 | objTag = arrayTag, |
| 14759 | othTag = arrayTag; |
| 14760 | |
| 14761 | if (!objIsArr) { |
| 14762 | objTag = objToString.call(object); |
| 14763 | if (objTag == argsTag) { |
| 14764 | objTag = objectTag; |
| 14765 | } else if (objTag != objectTag) { |
| 14766 | objIsArr = isTypedArray(object); |
| 14767 | } |
| 14768 | } |
| 14769 | if (!othIsArr) { |
| 14770 | othTag = objToString.call(other); |
| 14771 | if (othTag == argsTag) { |
| 14772 | othTag = objectTag; |
| 14773 | } else if (othTag != objectTag) { |
| 14774 | othIsArr = isTypedArray(other); |
| 14775 | } |
| 14776 | } |
| 14777 | var objIsObj = objTag == objectTag && !isHostObject(object), |
| 14778 | othIsObj = othTag == objectTag && !isHostObject(other), |
| 14779 | isSameTag = objTag == othTag; |
| 14780 | |
| 14781 | if (isSameTag && !(objIsArr || objIsObj)) { |
| 14782 | return equalByTag(object, other, objTag); |
| 14783 | } |
| 14784 | if (!isLoose) { |
| 14785 | var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), |
| 14786 | othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); |
| 14787 | |
| 14788 | if (objIsWrapped || othIsWrapped) { |
| 14789 | return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); |
| 14790 | } |
| 14791 | } |
| 14792 | if (!isSameTag) { |
| 14793 | return false; |
| 14794 | } |
| 14795 | // Assume cyclic values are equal. |
| 14796 | // For more information on detecting circular references see https://es5.github.io/#JO. |
| 14797 | stackA || (stackA = []); |
| 14798 | stackB || (stackB = []); |
| 14799 | |
| 14800 | var length = stackA.length; |
| 14801 | while (length--) { |
| 14802 | if (stackA[length] == object) { |
| 14803 | return stackB[length] == other; |
| 14804 | } |
| 14805 | } |
| 14806 | // Add `object` and `other` to the stack of traversed objects. |
| 14807 | stackA.push(object); |
| 14808 | stackB.push(other); |
| 14809 | |
| 14810 | var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); |
| 14811 | |
| 14812 | stackA.pop(); |
| 14813 | stackB.pop(); |
| 14814 | |
| 14815 | return result; |
| 14816 | } |
| 14817 | |
| 14818 | module.exports = baseIsEqualDeep; |
| 14819 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14820 | },{"../lang/isArray":140,"../lang/isTypedArray":147,"./equalArrays":107,"./equalByTag":108,"./equalObjects":109,"./isHostObject":120}],81:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14821 | var baseIsEqual = require('./baseIsEqual'), |
| 14822 | toObject = require('./toObject'); |
| 14823 | |
| 14824 | /** |
| 14825 | * The base implementation of `_.isMatch` without support for callback |
| 14826 | * shorthands and `this` binding. |
| 14827 | * |
| 14828 | * @private |
| 14829 | * @param {Object} object The object to inspect. |
| 14830 | * @param {Array} matchData The propery names, values, and compare flags to match. |
| 14831 | * @param {Function} [customizer] The function to customize comparing objects. |
| 14832 | * @returns {boolean} Returns `true` if `object` is a match, else `false`. |
| 14833 | */ |
| 14834 | function baseIsMatch(object, matchData, customizer) { |
| 14835 | var index = matchData.length, |
| 14836 | length = index, |
| 14837 | noCustomizer = !customizer; |
| 14838 | |
| 14839 | if (object == null) { |
| 14840 | return !length; |
| 14841 | } |
| 14842 | object = toObject(object); |
| 14843 | while (index--) { |
| 14844 | var data = matchData[index]; |
| 14845 | if ((noCustomizer && data[2]) |
| 14846 | ? data[1] !== object[data[0]] |
| 14847 | : !(data[0] in object) |
| 14848 | ) { |
| 14849 | return false; |
| 14850 | } |
| 14851 | } |
| 14852 | while (++index < length) { |
| 14853 | data = matchData[index]; |
| 14854 | var key = data[0], |
| 14855 | objValue = object[key], |
| 14856 | srcValue = data[1]; |
| 14857 | |
| 14858 | if (noCustomizer && data[2]) { |
| 14859 | if (objValue === undefined && !(key in object)) { |
| 14860 | return false; |
| 14861 | } |
| 14862 | } else { |
| 14863 | var result = customizer ? customizer(objValue, srcValue, key) : undefined; |
| 14864 | if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { |
| 14865 | return false; |
| 14866 | } |
| 14867 | } |
| 14868 | } |
| 14869 | return true; |
| 14870 | } |
| 14871 | |
| 14872 | module.exports = baseIsMatch; |
| 14873 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14874 | },{"./baseIsEqual":79,"./toObject":135}],82:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14875 | /** |
| 14876 | * The function whose prototype all chaining wrappers inherit from. |
| 14877 | * |
| 14878 | * @private |
| 14879 | */ |
| 14880 | function baseLodash() { |
| 14881 | // No operation performed. |
| 14882 | } |
| 14883 | |
| 14884 | module.exports = baseLodash; |
| 14885 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14886 | },{}],83:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14887 | var baseEach = require('./baseEach'), |
| 14888 | isArrayLike = require('./isArrayLike'); |
| 14889 | |
| 14890 | /** |
| 14891 | * The base implementation of `_.map` without support for callback shorthands |
| 14892 | * and `this` binding. |
| 14893 | * |
| 14894 | * @private |
| 14895 | * @param {Array|Object|string} collection The collection to iterate over. |
| 14896 | * @param {Function} iteratee The function invoked per iteration. |
| 14897 | * @returns {Array} Returns the new mapped array. |
| 14898 | */ |
| 14899 | function baseMap(collection, iteratee) { |
| 14900 | var index = -1, |
| 14901 | result = isArrayLike(collection) ? Array(collection.length) : []; |
| 14902 | |
| 14903 | baseEach(collection, function(value, key, collection) { |
| 14904 | result[++index] = iteratee(value, key, collection); |
| 14905 | }); |
| 14906 | return result; |
| 14907 | } |
| 14908 | |
| 14909 | module.exports = baseMap; |
| 14910 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14911 | },{"./baseEach":71,"./isArrayLike":119}],84:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14912 | var baseIsMatch = require('./baseIsMatch'), |
| 14913 | getMatchData = require('./getMatchData'), |
| 14914 | toObject = require('./toObject'); |
| 14915 | |
| 14916 | /** |
| 14917 | * The base implementation of `_.matches` which does not clone `source`. |
| 14918 | * |
| 14919 | * @private |
| 14920 | * @param {Object} source The object of property values to match. |
| 14921 | * @returns {Function} Returns the new function. |
| 14922 | */ |
| 14923 | function baseMatches(source) { |
| 14924 | var matchData = getMatchData(source); |
| 14925 | if (matchData.length == 1 && matchData[0][2]) { |
| 14926 | var key = matchData[0][0], |
| 14927 | value = matchData[0][1]; |
| 14928 | |
| 14929 | return function(object) { |
| 14930 | if (object == null) { |
| 14931 | return false; |
| 14932 | } |
| 14933 | object = toObject(object); |
| 14934 | return object[key] === value && (value !== undefined || (key in object)); |
| 14935 | }; |
| 14936 | } |
| 14937 | return function(object) { |
| 14938 | return baseIsMatch(object, matchData); |
| 14939 | }; |
| 14940 | } |
| 14941 | |
| 14942 | module.exports = baseMatches; |
| 14943 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14944 | },{"./baseIsMatch":81,"./getMatchData":113,"./toObject":135}],85:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14945 | var baseGet = require('./baseGet'), |
| 14946 | baseIsEqual = require('./baseIsEqual'), |
| 14947 | baseSlice = require('./baseSlice'), |
| 14948 | isArray = require('../lang/isArray'), |
| 14949 | isKey = require('./isKey'), |
| 14950 | isStrictComparable = require('./isStrictComparable'), |
| 14951 | last = require('../array/last'), |
| 14952 | toObject = require('./toObject'), |
| 14953 | toPath = require('./toPath'); |
| 14954 | |
| 14955 | /** |
| 14956 | * The base implementation of `_.matchesProperty` which does not clone `srcValue`. |
| 14957 | * |
| 14958 | * @private |
| 14959 | * @param {string} path The path of the property to get. |
| 14960 | * @param {*} srcValue The value to compare. |
| 14961 | * @returns {Function} Returns the new function. |
| 14962 | */ |
| 14963 | function baseMatchesProperty(path, srcValue) { |
| 14964 | var isArr = isArray(path), |
| 14965 | isCommon = isKey(path) && isStrictComparable(srcValue), |
| 14966 | pathKey = (path + ''); |
| 14967 | |
| 14968 | path = toPath(path); |
| 14969 | return function(object) { |
| 14970 | if (object == null) { |
| 14971 | return false; |
| 14972 | } |
| 14973 | var key = pathKey; |
| 14974 | object = toObject(object); |
| 14975 | if ((isArr || !isCommon) && !(key in object)) { |
| 14976 | object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
| 14977 | if (object == null) { |
| 14978 | return false; |
| 14979 | } |
| 14980 | key = last(path); |
| 14981 | object = toObject(object); |
| 14982 | } |
| 14983 | return object[key] === srcValue |
| 14984 | ? (srcValue !== undefined || (key in object)) |
| 14985 | : baseIsEqual(srcValue, object[key], undefined, true); |
| 14986 | }; |
| 14987 | } |
| 14988 | |
| 14989 | module.exports = baseMatchesProperty; |
| 14990 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 14991 | },{"../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){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 14992 | var toObject = require('./toObject'); |
| 14993 | |
| 14994 | /** |
| 14995 | * The base implementation of `_.property` without support for deep paths. |
| 14996 | * |
| 14997 | * @private |
| 14998 | * @param {string} key The key of the property to get. |
| 14999 | * @returns {Function} Returns the new function. |
| 15000 | */ |
| 15001 | function baseProperty(key) { |
| 15002 | return function(object) { |
| 15003 | return object == null ? undefined : toObject(object)[key]; |
| 15004 | }; |
| 15005 | } |
| 15006 | |
| 15007 | module.exports = baseProperty; |
| 15008 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15009 | },{"./toObject":135}],87:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15010 | var baseGet = require('./baseGet'), |
| 15011 | toPath = require('./toPath'); |
| 15012 | |
| 15013 | /** |
| 15014 | * A specialized version of `baseProperty` which supports deep paths. |
| 15015 | * |
| 15016 | * @private |
| 15017 | * @param {Array|string} path The path of the property to get. |
| 15018 | * @returns {Function} Returns the new function. |
| 15019 | */ |
| 15020 | function basePropertyDeep(path) { |
| 15021 | var pathKey = (path + ''); |
| 15022 | path = toPath(path); |
| 15023 | return function(object) { |
| 15024 | return baseGet(object, path, pathKey); |
| 15025 | }; |
| 15026 | } |
| 15027 | |
| 15028 | module.exports = basePropertyDeep; |
| 15029 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15030 | },{"./baseGet":77,"./toPath":136}],88:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15031 | var identity = require('../utility/identity'), |
| 15032 | metaMap = require('./metaMap'); |
| 15033 | |
| 15034 | /** |
| 15035 | * The base implementation of `setData` without support for hot loop detection. |
| 15036 | * |
| 15037 | * @private |
| 15038 | * @param {Function} func The function to associate metadata with. |
| 15039 | * @param {*} data The metadata. |
| 15040 | * @returns {Function} Returns `func`. |
| 15041 | */ |
| 15042 | var baseSetData = !metaMap ? identity : function(func, data) { |
| 15043 | metaMap.set(func, data); |
| 15044 | return func; |
| 15045 | }; |
| 15046 | |
| 15047 | module.exports = baseSetData; |
| 15048 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15049 | },{"../utility/identity":154,"./metaMap":129}],89:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15050 | /** |
| 15051 | * The base implementation of `_.slice` without an iteratee call guard. |
| 15052 | * |
| 15053 | * @private |
| 15054 | * @param {Array} array The array to slice. |
| 15055 | * @param {number} [start=0] The start position. |
| 15056 | * @param {number} [end=array.length] The end position. |
| 15057 | * @returns {Array} Returns the slice of `array`. |
| 15058 | */ |
| 15059 | function baseSlice(array, start, end) { |
| 15060 | var index = -1, |
| 15061 | length = array.length; |
| 15062 | |
| 15063 | start = start == null ? 0 : (+start || 0); |
| 15064 | if (start < 0) { |
| 15065 | start = -start > length ? 0 : (length + start); |
| 15066 | } |
| 15067 | end = (end === undefined || end > length) ? length : (+end || 0); |
| 15068 | if (end < 0) { |
| 15069 | end += length; |
| 15070 | } |
| 15071 | length = start > end ? 0 : ((end - start) >>> 0); |
| 15072 | start >>>= 0; |
| 15073 | |
| 15074 | var result = Array(length); |
| 15075 | while (++index < length) { |
| 15076 | result[index] = array[index + start]; |
| 15077 | } |
| 15078 | return result; |
| 15079 | } |
| 15080 | |
| 15081 | module.exports = baseSlice; |
| 15082 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15083 | },{}],90:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15084 | /** |
| 15085 | * Converts `value` to a string if it's not one. An empty string is returned |
| 15086 | * for `null` or `undefined` values. |
| 15087 | * |
| 15088 | * @private |
| 15089 | * @param {*} value The value to process. |
| 15090 | * @returns {string} Returns the string. |
| 15091 | */ |
| 15092 | function baseToString(value) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15093 | return value == null ? '' : (value + ''); |
| 15094 | } |
| 15095 | |
| 15096 | module.exports = baseToString; |
| 15097 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15098 | },{}],91:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15099 | /** |
| 15100 | * The base implementation of `_.values` and `_.valuesIn` which creates an |
| 15101 | * array of `object` property values corresponding to the property names |
| 15102 | * of `props`. |
| 15103 | * |
| 15104 | * @private |
| 15105 | * @param {Object} object The object to query. |
| 15106 | * @param {Array} props The property names to get values for. |
| 15107 | * @returns {Object} Returns the array of property values. |
| 15108 | */ |
| 15109 | function baseValues(object, props) { |
| 15110 | var index = -1, |
| 15111 | length = props.length, |
| 15112 | result = Array(length); |
| 15113 | |
| 15114 | while (++index < length) { |
| 15115 | result[index] = object[props[index]]; |
| 15116 | } |
| 15117 | return result; |
| 15118 | } |
| 15119 | |
| 15120 | module.exports = baseValues; |
| 15121 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15122 | },{}],92:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15123 | var binaryIndexBy = require('./binaryIndexBy'), |
| 15124 | identity = require('../utility/identity'); |
| 15125 | |
| 15126 | /** Used as references for the maximum length and index of an array. */ |
| 15127 | var MAX_ARRAY_LENGTH = 4294967295, |
| 15128 | HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; |
| 15129 | |
| 15130 | /** |
| 15131 | * Performs a binary search of `array` to determine the index at which `value` |
| 15132 | * should be inserted into `array` in order to maintain its sort order. |
| 15133 | * |
| 15134 | * @private |
| 15135 | * @param {Array} array The sorted array to inspect. |
| 15136 | * @param {*} value The value to evaluate. |
| 15137 | * @param {boolean} [retHighest] Specify returning the highest qualified index. |
| 15138 | * @returns {number} Returns the index at which `value` should be inserted |
| 15139 | * into `array`. |
| 15140 | */ |
| 15141 | function binaryIndex(array, value, retHighest) { |
| 15142 | var low = 0, |
| 15143 | high = array ? array.length : low; |
| 15144 | |
| 15145 | if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { |
| 15146 | while (low < high) { |
| 15147 | var mid = (low + high) >>> 1, |
| 15148 | computed = array[mid]; |
| 15149 | |
| 15150 | if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { |
| 15151 | low = mid + 1; |
| 15152 | } else { |
| 15153 | high = mid; |
| 15154 | } |
| 15155 | } |
| 15156 | return high; |
| 15157 | } |
| 15158 | return binaryIndexBy(array, value, identity, retHighest); |
| 15159 | } |
| 15160 | |
| 15161 | module.exports = binaryIndex; |
| 15162 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15163 | },{"../utility/identity":154,"./binaryIndexBy":93}],93:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15164 | /* Native method references for those with the same name as other `lodash` methods. */ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15165 | var nativeFloor = Math.floor, |
| 15166 | nativeMin = Math.min; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15167 | |
| 15168 | /** Used as references for the maximum length and index of an array. */ |
| 15169 | var MAX_ARRAY_LENGTH = 4294967295, |
| 15170 | MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; |
| 15171 | |
| 15172 | /** |
| 15173 | * This function is like `binaryIndex` except that it invokes `iteratee` for |
| 15174 | * `value` and each element of `array` to compute their sort ranking. The |
| 15175 | * iteratee is invoked with one argument; (value). |
| 15176 | * |
| 15177 | * @private |
| 15178 | * @param {Array} array The sorted array to inspect. |
| 15179 | * @param {*} value The value to evaluate. |
| 15180 | * @param {Function} iteratee The function invoked per iteration. |
| 15181 | * @param {boolean} [retHighest] Specify returning the highest qualified index. |
| 15182 | * @returns {number} Returns the index at which `value` should be inserted |
| 15183 | * into `array`. |
| 15184 | */ |
| 15185 | function binaryIndexBy(array, value, iteratee, retHighest) { |
| 15186 | value = iteratee(value); |
| 15187 | |
| 15188 | var low = 0, |
| 15189 | high = array ? array.length : 0, |
| 15190 | valIsNaN = value !== value, |
| 15191 | valIsNull = value === null, |
| 15192 | valIsUndef = value === undefined; |
| 15193 | |
| 15194 | while (low < high) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15195 | var mid = nativeFloor((low + high) / 2), |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15196 | computed = iteratee(array[mid]), |
| 15197 | isDef = computed !== undefined, |
| 15198 | isReflexive = computed === computed; |
| 15199 | |
| 15200 | if (valIsNaN) { |
| 15201 | var setLow = isReflexive || retHighest; |
| 15202 | } else if (valIsNull) { |
| 15203 | setLow = isReflexive && isDef && (retHighest || computed != null); |
| 15204 | } else if (valIsUndef) { |
| 15205 | setLow = isReflexive && (retHighest || isDef); |
| 15206 | } else if (computed == null) { |
| 15207 | setLow = false; |
| 15208 | } else { |
| 15209 | setLow = retHighest ? (computed <= value) : (computed < value); |
| 15210 | } |
| 15211 | if (setLow) { |
| 15212 | low = mid + 1; |
| 15213 | } else { |
| 15214 | high = mid; |
| 15215 | } |
| 15216 | } |
| 15217 | return nativeMin(high, MAX_ARRAY_INDEX); |
| 15218 | } |
| 15219 | |
| 15220 | module.exports = binaryIndexBy; |
| 15221 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15222 | },{}],94:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15223 | var identity = require('../utility/identity'); |
| 15224 | |
| 15225 | /** |
| 15226 | * A specialized version of `baseCallback` which only supports `this` binding |
| 15227 | * and specifying the number of arguments to provide to `func`. |
| 15228 | * |
| 15229 | * @private |
| 15230 | * @param {Function} func The function to bind. |
| 15231 | * @param {*} thisArg The `this` binding of `func`. |
| 15232 | * @param {number} [argCount] The number of arguments to provide to `func`. |
| 15233 | * @returns {Function} Returns the callback. |
| 15234 | */ |
| 15235 | function bindCallback(func, thisArg, argCount) { |
| 15236 | if (typeof func != 'function') { |
| 15237 | return identity; |
| 15238 | } |
| 15239 | if (thisArg === undefined) { |
| 15240 | return func; |
| 15241 | } |
| 15242 | switch (argCount) { |
| 15243 | case 1: return function(value) { |
| 15244 | return func.call(thisArg, value); |
| 15245 | }; |
| 15246 | case 3: return function(value, index, collection) { |
| 15247 | return func.call(thisArg, value, index, collection); |
| 15248 | }; |
| 15249 | case 4: return function(accumulator, value, index, collection) { |
| 15250 | return func.call(thisArg, accumulator, value, index, collection); |
| 15251 | }; |
| 15252 | case 5: return function(value, other, key, object, source) { |
| 15253 | return func.call(thisArg, value, other, key, object, source); |
| 15254 | }; |
| 15255 | } |
| 15256 | return function() { |
| 15257 | return func.apply(thisArg, arguments); |
| 15258 | }; |
| 15259 | } |
| 15260 | |
| 15261 | module.exports = bindCallback; |
| 15262 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15263 | },{"../utility/identity":154}],95:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15264 | (function (global){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15265 | /** Native method references. */ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15266 | var ArrayBuffer = global.ArrayBuffer, |
| 15267 | Uint8Array = global.Uint8Array; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15268 | |
| 15269 | /** |
| 15270 | * Creates a clone of the given array buffer. |
| 15271 | * |
| 15272 | * @private |
| 15273 | * @param {ArrayBuffer} buffer The array buffer to clone. |
| 15274 | * @returns {ArrayBuffer} Returns the cloned array buffer. |
| 15275 | */ |
| 15276 | function bufferClone(buffer) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15277 | var result = new ArrayBuffer(buffer.byteLength), |
| 15278 | view = new Uint8Array(result); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15279 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15280 | view.set(new Uint8Array(buffer)); |
| 15281 | return result; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15282 | } |
| 15283 | |
| 15284 | module.exports = bufferClone; |
| 15285 | |
| 15286 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15287 | //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2J1ZmZlckNsb25lLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgQXJyYXlCdWZmZXIgPSBnbG9iYWwuQXJyYXlCdWZmZXIsXG4gICAgVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjbG9uZSBvZiB0aGUgZ2l2ZW4gYXJyYXkgYnVmZmVyLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZmZXIgVGhlIGFycmF5IGJ1ZmZlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheUJ1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGFycmF5IGJ1ZmZlci5cbiAqL1xuZnVuY3Rpb24gYnVmZmVyQ2xvbmUoYnVmZmVyKSB7XG4gIHZhciByZXN1bHQgPSBuZXcgQXJyYXlCdWZmZXIoYnVmZmVyLmJ5dGVMZW5ndGgpLFxuICAgICAgdmlldyA9IG5ldyBVaW50OEFycmF5KHJlc3VsdCk7XG5cbiAgdmlldy5zZXQobmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnVmZmVyQ2xvbmU7XG4iXX0= |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15288 | },{}],96:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15289 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 15290 | var nativeMax = Math.max; |
| 15291 | |
| 15292 | /** |
| 15293 | * Creates an array that is the composition of partially applied arguments, |
| 15294 | * placeholders, and provided arguments into a single array of arguments. |
| 15295 | * |
| 15296 | * @private |
| 15297 | * @param {Array|Object} args The provided arguments. |
| 15298 | * @param {Array} partials The arguments to prepend to those provided. |
| 15299 | * @param {Array} holders The `partials` placeholder indexes. |
| 15300 | * @returns {Array} Returns the new array of composed arguments. |
| 15301 | */ |
| 15302 | function composeArgs(args, partials, holders) { |
| 15303 | var holdersLength = holders.length, |
| 15304 | argsIndex = -1, |
| 15305 | argsLength = nativeMax(args.length - holdersLength, 0), |
| 15306 | leftIndex = -1, |
| 15307 | leftLength = partials.length, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15308 | result = Array(leftLength + argsLength); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15309 | |
| 15310 | while (++leftIndex < leftLength) { |
| 15311 | result[leftIndex] = partials[leftIndex]; |
| 15312 | } |
| 15313 | while (++argsIndex < holdersLength) { |
| 15314 | result[holders[argsIndex]] = args[argsIndex]; |
| 15315 | } |
| 15316 | while (argsLength--) { |
| 15317 | result[leftIndex++] = args[argsIndex++]; |
| 15318 | } |
| 15319 | return result; |
| 15320 | } |
| 15321 | |
| 15322 | module.exports = composeArgs; |
| 15323 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15324 | },{}],97:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15325 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 15326 | var nativeMax = Math.max; |
| 15327 | |
| 15328 | /** |
| 15329 | * This function is like `composeArgs` except that the arguments composition |
| 15330 | * is tailored for `_.partialRight`. |
| 15331 | * |
| 15332 | * @private |
| 15333 | * @param {Array|Object} args The provided arguments. |
| 15334 | * @param {Array} partials The arguments to append to those provided. |
| 15335 | * @param {Array} holders The `partials` placeholder indexes. |
| 15336 | * @returns {Array} Returns the new array of composed arguments. |
| 15337 | */ |
| 15338 | function composeArgsRight(args, partials, holders) { |
| 15339 | var holdersIndex = -1, |
| 15340 | holdersLength = holders.length, |
| 15341 | argsIndex = -1, |
| 15342 | argsLength = nativeMax(args.length - holdersLength, 0), |
| 15343 | rightIndex = -1, |
| 15344 | rightLength = partials.length, |
| 15345 | result = Array(argsLength + rightLength); |
| 15346 | |
| 15347 | while (++argsIndex < argsLength) { |
| 15348 | result[argsIndex] = args[argsIndex]; |
| 15349 | } |
| 15350 | var offset = argsIndex; |
| 15351 | while (++rightIndex < rightLength) { |
| 15352 | result[offset + rightIndex] = partials[rightIndex]; |
| 15353 | } |
| 15354 | while (++holdersIndex < holdersLength) { |
| 15355 | result[offset + holders[holdersIndex]] = args[argsIndex++]; |
| 15356 | } |
| 15357 | return result; |
| 15358 | } |
| 15359 | |
| 15360 | module.exports = composeArgsRight; |
| 15361 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15362 | },{}],98:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15363 | var getLength = require('./getLength'), |
| 15364 | isLength = require('./isLength'), |
| 15365 | toObject = require('./toObject'); |
| 15366 | |
| 15367 | /** |
| 15368 | * Creates a `baseEach` or `baseEachRight` function. |
| 15369 | * |
| 15370 | * @private |
| 15371 | * @param {Function} eachFunc The function to iterate over a collection. |
| 15372 | * @param {boolean} [fromRight] Specify iterating from right to left. |
| 15373 | * @returns {Function} Returns the new base function. |
| 15374 | */ |
| 15375 | function createBaseEach(eachFunc, fromRight) { |
| 15376 | return function(collection, iteratee) { |
| 15377 | var length = collection ? getLength(collection) : 0; |
| 15378 | if (!isLength(length)) { |
| 15379 | return eachFunc(collection, iteratee); |
| 15380 | } |
| 15381 | var index = fromRight ? length : -1, |
| 15382 | iterable = toObject(collection); |
| 15383 | |
| 15384 | while ((fromRight ? index-- : ++index < length)) { |
| 15385 | if (iteratee(iterable[index], index, iterable) === false) { |
| 15386 | break; |
| 15387 | } |
| 15388 | } |
| 15389 | return collection; |
| 15390 | }; |
| 15391 | } |
| 15392 | |
| 15393 | module.exports = createBaseEach; |
| 15394 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15395 | },{"./getLength":112,"./isLength":125,"./toObject":135}],99:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15396 | var toObject = require('./toObject'); |
| 15397 | |
| 15398 | /** |
| 15399 | * Creates a base function for `_.forIn` or `_.forInRight`. |
| 15400 | * |
| 15401 | * @private |
| 15402 | * @param {boolean} [fromRight] Specify iterating from right to left. |
| 15403 | * @returns {Function} Returns the new base function. |
| 15404 | */ |
| 15405 | function createBaseFor(fromRight) { |
| 15406 | return function(object, iteratee, keysFunc) { |
| 15407 | var iterable = toObject(object), |
| 15408 | props = keysFunc(object), |
| 15409 | length = props.length, |
| 15410 | index = fromRight ? length : -1; |
| 15411 | |
| 15412 | while ((fromRight ? index-- : ++index < length)) { |
| 15413 | var key = props[index]; |
| 15414 | if (iteratee(iterable[key], key, iterable) === false) { |
| 15415 | break; |
| 15416 | } |
| 15417 | } |
| 15418 | return object; |
| 15419 | }; |
| 15420 | } |
| 15421 | |
| 15422 | module.exports = createBaseFor; |
| 15423 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15424 | },{"./toObject":135}],100:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15425 | (function (global){ |
| 15426 | var createCtorWrapper = require('./createCtorWrapper'); |
| 15427 | |
| 15428 | /** |
| 15429 | * Creates a function that wraps `func` and invokes it with the `this` |
| 15430 | * binding of `thisArg`. |
| 15431 | * |
| 15432 | * @private |
| 15433 | * @param {Function} func The function to bind. |
| 15434 | * @param {*} [thisArg] The `this` binding of `func`. |
| 15435 | * @returns {Function} Returns the new bound function. |
| 15436 | */ |
| 15437 | function createBindWrapper(func, thisArg) { |
| 15438 | var Ctor = createCtorWrapper(func); |
| 15439 | |
| 15440 | function wrapper() { |
| 15441 | var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func; |
| 15442 | return fn.apply(thisArg, arguments); |
| 15443 | } |
| 15444 | return wrapper; |
| 15445 | } |
| 15446 | |
| 15447 | module.exports = createBindWrapper; |
| 15448 | |
| 15449 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15450 | //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUJpbmRXcmFwcGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmRXcmFwcGVyKGZ1bmMsIHRoaXNBcmcpIHtcbiAgdmFyIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kV3JhcHBlcjtcbiJdfQ== |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15451 | },{"./createCtorWrapper":101}],101:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15452 | var baseCreate = require('./baseCreate'), |
| 15453 | isObject = require('../lang/isObject'); |
| 15454 | |
| 15455 | /** |
| 15456 | * Creates a function that produces an instance of `Ctor` regardless of |
| 15457 | * whether it was invoked as part of a `new` expression or by `call` or `apply`. |
| 15458 | * |
| 15459 | * @private |
| 15460 | * @param {Function} Ctor The constructor to wrap. |
| 15461 | * @returns {Function} Returns the new wrapped function. |
| 15462 | */ |
| 15463 | function createCtorWrapper(Ctor) { |
| 15464 | return function() { |
| 15465 | // Use a `switch` statement to work with class constructors. |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15466 | // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15467 | // for more details. |
| 15468 | var args = arguments; |
| 15469 | switch (args.length) { |
| 15470 | case 0: return new Ctor; |
| 15471 | case 1: return new Ctor(args[0]); |
| 15472 | case 2: return new Ctor(args[0], args[1]); |
| 15473 | case 3: return new Ctor(args[0], args[1], args[2]); |
| 15474 | case 4: return new Ctor(args[0], args[1], args[2], args[3]); |
| 15475 | case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15476 | case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); |
| 15477 | case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15478 | } |
| 15479 | var thisBinding = baseCreate(Ctor.prototype), |
| 15480 | result = Ctor.apply(thisBinding, args); |
| 15481 | |
| 15482 | // Mimic the constructor's `return` behavior. |
| 15483 | // See https://es5.github.io/#x13.2.2 for more details. |
| 15484 | return isObject(result) ? result : thisBinding; |
| 15485 | }; |
| 15486 | } |
| 15487 | |
| 15488 | module.exports = createCtorWrapper; |
| 15489 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15490 | },{"../lang/isObject":144,"./baseCreate":70}],102:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15491 | var baseCallback = require('./baseCallback'), |
| 15492 | baseFind = require('./baseFind'), |
| 15493 | baseFindIndex = require('./baseFindIndex'), |
| 15494 | isArray = require('../lang/isArray'); |
| 15495 | |
| 15496 | /** |
| 15497 | * Creates a `_.find` or `_.findLast` function. |
| 15498 | * |
| 15499 | * @private |
| 15500 | * @param {Function} eachFunc The function to iterate over a collection. |
| 15501 | * @param {boolean} [fromRight] Specify iterating from right to left. |
| 15502 | * @returns {Function} Returns the new find function. |
| 15503 | */ |
| 15504 | function createFind(eachFunc, fromRight) { |
| 15505 | return function(collection, predicate, thisArg) { |
| 15506 | predicate = baseCallback(predicate, thisArg, 3); |
| 15507 | if (isArray(collection)) { |
| 15508 | var index = baseFindIndex(collection, predicate, fromRight); |
| 15509 | return index > -1 ? collection[index] : undefined; |
| 15510 | } |
| 15511 | return baseFind(collection, predicate, eachFunc); |
| 15512 | }; |
| 15513 | } |
| 15514 | |
| 15515 | module.exports = createFind; |
| 15516 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15517 | },{"../lang/isArray":140,"./baseCallback":67,"./baseFind":72,"./baseFindIndex":73}],103:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15518 | var bindCallback = require('./bindCallback'), |
| 15519 | isArray = require('../lang/isArray'); |
| 15520 | |
| 15521 | /** |
| 15522 | * Creates a function for `_.forEach` or `_.forEachRight`. |
| 15523 | * |
| 15524 | * @private |
| 15525 | * @param {Function} arrayFunc The function to iterate over an array. |
| 15526 | * @param {Function} eachFunc The function to iterate over a collection. |
| 15527 | * @returns {Function} Returns the new each function. |
| 15528 | */ |
| 15529 | function createForEach(arrayFunc, eachFunc) { |
| 15530 | return function(collection, iteratee, thisArg) { |
| 15531 | return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) |
| 15532 | ? arrayFunc(collection, iteratee) |
| 15533 | : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); |
| 15534 | }; |
| 15535 | } |
| 15536 | |
| 15537 | module.exports = createForEach; |
| 15538 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15539 | },{"../lang/isArray":140,"./bindCallback":94}],104:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15540 | (function (global){ |
| 15541 | var arrayCopy = require('./arrayCopy'), |
| 15542 | composeArgs = require('./composeArgs'), |
| 15543 | composeArgsRight = require('./composeArgsRight'), |
| 15544 | createCtorWrapper = require('./createCtorWrapper'), |
| 15545 | isLaziable = require('./isLaziable'), |
| 15546 | reorder = require('./reorder'), |
| 15547 | replaceHolders = require('./replaceHolders'), |
| 15548 | setData = require('./setData'); |
| 15549 | |
| 15550 | /** Used to compose bitmasks for wrapper metadata. */ |
| 15551 | var BIND_FLAG = 1, |
| 15552 | BIND_KEY_FLAG = 2, |
| 15553 | CURRY_BOUND_FLAG = 4, |
| 15554 | CURRY_FLAG = 8, |
| 15555 | CURRY_RIGHT_FLAG = 16, |
| 15556 | PARTIAL_FLAG = 32, |
| 15557 | PARTIAL_RIGHT_FLAG = 64, |
| 15558 | ARY_FLAG = 128; |
| 15559 | |
| 15560 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 15561 | var nativeMax = Math.max; |
| 15562 | |
| 15563 | /** |
| 15564 | * Creates a function that wraps `func` and invokes it with optional `this` |
| 15565 | * binding of, partial application, and currying. |
| 15566 | * |
| 15567 | * @private |
| 15568 | * @param {Function|string} func The function or method name to reference. |
| 15569 | * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. |
| 15570 | * @param {*} [thisArg] The `this` binding of `func`. |
| 15571 | * @param {Array} [partials] The arguments to prepend to those provided to the new function. |
| 15572 | * @param {Array} [holders] The `partials` placeholder indexes. |
| 15573 | * @param {Array} [partialsRight] The arguments to append to those provided to the new function. |
| 15574 | * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. |
| 15575 | * @param {Array} [argPos] The argument positions of the new function. |
| 15576 | * @param {number} [ary] The arity cap of `func`. |
| 15577 | * @param {number} [arity] The arity of `func`. |
| 15578 | * @returns {Function} Returns the new wrapped function. |
| 15579 | */ |
| 15580 | function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { |
| 15581 | var isAry = bitmask & ARY_FLAG, |
| 15582 | isBind = bitmask & BIND_FLAG, |
| 15583 | isBindKey = bitmask & BIND_KEY_FLAG, |
| 15584 | isCurry = bitmask & CURRY_FLAG, |
| 15585 | isCurryBound = bitmask & CURRY_BOUND_FLAG, |
| 15586 | isCurryRight = bitmask & CURRY_RIGHT_FLAG, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15587 | Ctor = isBindKey ? undefined : createCtorWrapper(func); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15588 | |
| 15589 | function wrapper() { |
| 15590 | // Avoid `arguments` object use disqualifying optimizations by |
| 15591 | // converting it to an array before providing it to other functions. |
| 15592 | var length = arguments.length, |
| 15593 | index = length, |
| 15594 | args = Array(length); |
| 15595 | |
| 15596 | while (index--) { |
| 15597 | args[index] = arguments[index]; |
| 15598 | } |
| 15599 | if (partials) { |
| 15600 | args = composeArgs(args, partials, holders); |
| 15601 | } |
| 15602 | if (partialsRight) { |
| 15603 | args = composeArgsRight(args, partialsRight, holdersRight); |
| 15604 | } |
| 15605 | if (isCurry || isCurryRight) { |
| 15606 | var placeholder = wrapper.placeholder, |
| 15607 | argsHolders = replaceHolders(args, placeholder); |
| 15608 | |
| 15609 | length -= argsHolders.length; |
| 15610 | if (length < arity) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15611 | var newArgPos = argPos ? arrayCopy(argPos) : undefined, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15612 | newArity = nativeMax(arity - length, 0), |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15613 | newsHolders = isCurry ? argsHolders : undefined, |
| 15614 | newHoldersRight = isCurry ? undefined : argsHolders, |
| 15615 | newPartials = isCurry ? args : undefined, |
| 15616 | newPartialsRight = isCurry ? undefined : args; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15617 | |
| 15618 | bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); |
| 15619 | bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); |
| 15620 | |
| 15621 | if (!isCurryBound) { |
| 15622 | bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); |
| 15623 | } |
| 15624 | var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], |
| 15625 | result = createHybridWrapper.apply(undefined, newData); |
| 15626 | |
| 15627 | if (isLaziable(func)) { |
| 15628 | setData(result, newData); |
| 15629 | } |
| 15630 | result.placeholder = placeholder; |
| 15631 | return result; |
| 15632 | } |
| 15633 | } |
| 15634 | var thisBinding = isBind ? thisArg : this, |
| 15635 | fn = isBindKey ? thisBinding[func] : func; |
| 15636 | |
| 15637 | if (argPos) { |
| 15638 | args = reorder(args, argPos); |
| 15639 | } |
| 15640 | if (isAry && ary < args.length) { |
| 15641 | args.length = ary; |
| 15642 | } |
| 15643 | if (this && this !== global && this instanceof wrapper) { |
| 15644 | fn = Ctor || createCtorWrapper(func); |
| 15645 | } |
| 15646 | return fn.apply(thisBinding, args); |
| 15647 | } |
| 15648 | return wrapper; |
| 15649 | } |
| 15650 | |
| 15651 | module.exports = createHybridWrapper; |
| 15652 | |
| 15653 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15654 | //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUh5YnJpZFdyYXBwZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKSxcbiAgICBjb21wb3NlQXJncyA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3MnKSxcbiAgICBjb21wb3NlQXJnc1JpZ2h0ID0gcmVxdWlyZSgnLi9jb21wb3NlQXJnc1JpZ2h0JyksXG4gICAgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyksXG4gICAgaXNMYXppYWJsZSA9IHJlcXVpcmUoJy4vaXNMYXppYWJsZScpLFxuICAgIHJlb3JkZXIgPSByZXF1aXJlKCcuL3Jlb3JkZXInKSxcbiAgICByZXBsYWNlSG9sZGVycyA9IHJlcXVpcmUoJy4vcmVwbGFjZUhvbGRlcnMnKSxcbiAgICBzZXREYXRhID0gcmVxdWlyZSgnLi9zZXREYXRhJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMSxcbiAgICBCSU5EX0tFWV9GTEFHID0gMixcbiAgICBDVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICBDVVJSWV9GTEFHID0gOCxcbiAgICBDVVJSWV9SSUdIVF9GTEFHID0gMTYsXG4gICAgUEFSVElBTF9GTEFHID0gMzIsXG4gICAgUEFSVElBTF9SSUdIVF9GTEFHID0gNjQsXG4gICAgQVJZX0ZMQUcgPSAxMjg7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mLCBwYXJ0aWFsIGFwcGxpY2F0aW9uLCBhbmQgY3VycnlpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBvZiBmbGFncy4gU2VlIGBjcmVhdGVXcmFwcGVyYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc1JpZ2h0XSBUaGUgYXJndW1lbnRzIHRvIGFwcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNSaWdodF0gVGhlIGBwYXJ0aWFsc1JpZ2h0YCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcnldIFRoZSBhcml0eSBjYXAgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUh5YnJpZFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCwgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gIHZhciBpc0FyeSA9IGJpdG1hc2sgJiBBUllfRkxBRyxcbiAgICAgIGlzQmluZCA9IGJpdG1hc2sgJiBCSU5EX0ZMQUcsXG4gICAgICBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRyxcbiAgICAgIGlzQ3VycnkgPSBiaXRtYXNrICYgQ1VSUllfRkxBRyxcbiAgICAgIGlzQ3VycnlCb3VuZCA9IGJpdG1hc2sgJiBDVVJSWV9CT1VORF9GTEFHLFxuICAgICAgaXNDdXJyeVJpZ2h0ID0gYml0bWFzayAmIENVUlJZX1JJR0hUX0ZMQUcsXG4gICAgICBDdG9yID0gaXNCaW5kS2V5ID8gdW5kZWZpbmVkIDogY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgIC8vIGNvbnZlcnRpbmcgaXQgdG8gYW4gYXJyYXkgYmVmb3JlIHByb3ZpZGluZyBpdCB0byBvdGhlciBmdW5jdGlvbnMuXG4gICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKTtcblxuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgfVxuICAgIGlmIChwYXJ0aWFscykge1xuICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9XG4gICAgaWYgKHBhcnRpYWxzUmlnaHQpIHtcbiAgICAgIGFyZ3MgPSBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCk7XG4gICAgfVxuICAgIGlmIChpc0N1cnJ5IHx8IGlzQ3VycnlSaWdodCkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0gd3JhcHBlci5wbGFjZWhvbGRlcixcbiAgICAgICAgICBhcmdzSG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKGFyZ3MsIHBsYWNlaG9sZGVyKTtcblxuICAgICAgbGVuZ3RoIC09IGFyZ3NIb2xkZXJzLmxlbmd0aDtcbiAgICAgIGlmIChsZW5ndGggPCBhcml0eSkge1xuICAgICAgICB2YXIgbmV3QXJnUG9zID0gYXJnUG9zID8gYXJyYXlDb3B5KGFyZ1BvcykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdBcml0eSA9IG5hdGl2ZU1heChhcml0eSAtIGxlbmd0aCwgMCksXG4gICAgICAgICAgICBuZXdzSG9sZGVycyA9IGlzQ3VycnkgPyBhcmdzSG9sZGVycyA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG5ld0hvbGRlcnNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBhcmdzSG9sZGVycyxcbiAgICAgICAgICAgIG5ld1BhcnRpYWxzID0gaXNDdXJyeSA/IGFyZ3MgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdQYXJ0aWFsc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGFyZ3M7XG5cbiAgICAgICAgYml0bWFzayB8PSAoaXNDdXJyeSA/IFBBUlRJQUxfRkxBRyA6IFBBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgICAgIGJpdG1hc2sgJj0gfihpc0N1cnJ5ID8gUEFSVElBTF9SSUdIVF9GTEFHIDogUEFSVElBTF9GTEFHKTtcblxuICAgICAgICBpZiAoIWlzQ3VycnlCb3VuZCkge1xuICAgICAgICAgIGJpdG1hc2sgJj0gfihCSU5EX0ZMQUcgfCBCSU5EX0tFWV9GTEFHKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3c0hvbGRlcnMsIG5ld1BhcnRpYWxzUmlnaHQsIG5ld0hvbGRlcnNSaWdodCwgbmV3QXJnUG9zLCBhcnksIG5ld0FyaXR5XSxcbiAgICAgICAgICAgIHJlc3VsdCA9IGNyZWF0ZUh5YnJpZFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcblxuICAgICAgICBpZiAoaXNMYXppYWJsZShmdW5jKSkge1xuICAgICAgICAgIHNldERhdGEocmVzdWx0LCBuZXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBwbGFjZWhvbGRlcjtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHRoaXNCaW5kaW5nID0gaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsXG4gICAgICAgIGZuID0gaXNCaW5kS2V5ID8gdGhpc0JpbmRpbmdbZnVuY10gOiBmdW5jO1xuXG4gICAgaWYgKGFyZ1Bvcykge1xuICAgICAgYXJncyA9IHJlb3JkZXIoYXJncywgYXJnUG9zKTtcbiAgICB9XG4gICAgaWYgKGlzQXJ5ICYmIGFyeSA8IGFyZ3MubGVuZ3RoKSB7XG4gICAgICBhcmdzLmxlbmd0aCA9IGFyeTtcbiAgICB9XG4gICAgaWYgKHRoaXMgJiYgdGhpcyAhPT0gZ2xvYmFsICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSB7XG4gICAgICBmbiA9IEN0b3IgfHwgY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQmluZGluZywgYXJncyk7XG4gIH1cbiAgcmV0dXJuIHdyYXBwZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlSHlicmlkV3JhcHBlcjtcbiJdfQ== |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15655 | },{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./createCtorWrapper":101,"./isLaziable":124,"./reorder":131,"./replaceHolders":132,"./setData":133}],105:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15656 | (function (global){ |
| 15657 | var createCtorWrapper = require('./createCtorWrapper'); |
| 15658 | |
| 15659 | /** Used to compose bitmasks for wrapper metadata. */ |
| 15660 | var BIND_FLAG = 1; |
| 15661 | |
| 15662 | /** |
| 15663 | * Creates a function that wraps `func` and invokes it with the optional `this` |
| 15664 | * binding of `thisArg` and the `partials` prepended to those provided to |
| 15665 | * the wrapper. |
| 15666 | * |
| 15667 | * @private |
| 15668 | * @param {Function} func The function to partially apply arguments to. |
| 15669 | * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. |
| 15670 | * @param {*} thisArg The `this` binding of `func`. |
| 15671 | * @param {Array} partials The arguments to prepend to those provided to the new function. |
| 15672 | * @returns {Function} Returns the new bound function. |
| 15673 | */ |
| 15674 | function createPartialWrapper(func, bitmask, thisArg, partials) { |
| 15675 | var isBind = bitmask & BIND_FLAG, |
| 15676 | Ctor = createCtorWrapper(func); |
| 15677 | |
| 15678 | function wrapper() { |
| 15679 | // Avoid `arguments` object use disqualifying optimizations by |
| 15680 | // converting it to an array before providing it `func`. |
| 15681 | var argsIndex = -1, |
| 15682 | argsLength = arguments.length, |
| 15683 | leftIndex = -1, |
| 15684 | leftLength = partials.length, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15685 | args = Array(leftLength + argsLength); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15686 | |
| 15687 | while (++leftIndex < leftLength) { |
| 15688 | args[leftIndex] = partials[leftIndex]; |
| 15689 | } |
| 15690 | while (argsLength--) { |
| 15691 | args[leftIndex++] = arguments[++argsIndex]; |
| 15692 | } |
| 15693 | var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func; |
| 15694 | return fn.apply(isBind ? thisArg : this, args); |
| 15695 | } |
| 15696 | return wrapper; |
| 15697 | } |
| 15698 | |
| 15699 | module.exports = createPartialWrapper; |
| 15700 | |
| 15701 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15702 | //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZVBhcnRpYWxXcmFwcGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgYW5kIGludm9rZXMgaXQgd2l0aCB0aGUgb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mIGB0aGlzQXJnYCBhbmQgdGhlIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gKiB0aGUgd3JhcHBlci5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcGFydGlhbGx5IGFwcGx5IGFyZ3VtZW50cyB0by5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIG9mIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBwZXJgIGZvciBtb3JlIGRldGFpbHMuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnRpYWxzIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVBhcnRpYWxXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzKSB7XG4gIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgQ3RvciA9IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgLy8gQXZvaWQgYGFyZ3VtZW50c2Agb2JqZWN0IHVzZSBkaXNxdWFsaWZ5aW5nIG9wdGltaXphdGlvbnMgYnlcbiAgICAvLyBjb252ZXJ0aW5nIGl0IHRvIGFuIGFycmF5IGJlZm9yZSBwcm92aWRpbmcgaXQgYGZ1bmNgLlxuICAgIHZhciBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgYXJnc0xlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgICBsZWZ0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICBhcmdzID0gQXJyYXkobGVmdExlbmd0aCArIGFyZ3NMZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgICAgYXJnc1tsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgICB9XG4gICAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgICAgYXJnc1tsZWZ0SW5kZXgrK10gPSBhcmd1bWVudHNbKythcmdzSW5kZXhdO1xuICAgIH1cbiAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSBnbG9iYWwgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpID8gQ3RvciA6IGZ1bmM7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLCBhcmdzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVQYXJ0aWFsV3JhcHBlcjtcbiJdfQ== |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15703 | },{"./createCtorWrapper":101}],106:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15704 | var baseSetData = require('./baseSetData'), |
| 15705 | createBindWrapper = require('./createBindWrapper'), |
| 15706 | createHybridWrapper = require('./createHybridWrapper'), |
| 15707 | createPartialWrapper = require('./createPartialWrapper'), |
| 15708 | getData = require('./getData'), |
| 15709 | mergeData = require('./mergeData'), |
| 15710 | setData = require('./setData'); |
| 15711 | |
| 15712 | /** Used to compose bitmasks for wrapper metadata. */ |
| 15713 | var BIND_FLAG = 1, |
| 15714 | BIND_KEY_FLAG = 2, |
| 15715 | PARTIAL_FLAG = 32, |
| 15716 | PARTIAL_RIGHT_FLAG = 64; |
| 15717 | |
| 15718 | /** Used as the `TypeError` message for "Functions" methods. */ |
| 15719 | var FUNC_ERROR_TEXT = 'Expected a function'; |
| 15720 | |
| 15721 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 15722 | var nativeMax = Math.max; |
| 15723 | |
| 15724 | /** |
| 15725 | * Creates a function that either curries or invokes `func` with optional |
| 15726 | * `this` binding and partially applied arguments. |
| 15727 | * |
| 15728 | * @private |
| 15729 | * @param {Function|string} func The function or method name to reference. |
| 15730 | * @param {number} bitmask The bitmask of flags. |
| 15731 | * The bitmask may be composed of the following flags: |
| 15732 | * 1 - `_.bind` |
| 15733 | * 2 - `_.bindKey` |
| 15734 | * 4 - `_.curry` or `_.curryRight` of a bound function |
| 15735 | * 8 - `_.curry` |
| 15736 | * 16 - `_.curryRight` |
| 15737 | * 32 - `_.partial` |
| 15738 | * 64 - `_.partialRight` |
| 15739 | * 128 - `_.rearg` |
| 15740 | * 256 - `_.ary` |
| 15741 | * @param {*} [thisArg] The `this` binding of `func`. |
| 15742 | * @param {Array} [partials] The arguments to be partially applied. |
| 15743 | * @param {Array} [holders] The `partials` placeholder indexes. |
| 15744 | * @param {Array} [argPos] The argument positions of the new function. |
| 15745 | * @param {number} [ary] The arity cap of `func`. |
| 15746 | * @param {number} [arity] The arity of `func`. |
| 15747 | * @returns {Function} Returns the new wrapped function. |
| 15748 | */ |
| 15749 | function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { |
| 15750 | var isBindKey = bitmask & BIND_KEY_FLAG; |
| 15751 | if (!isBindKey && typeof func != 'function') { |
| 15752 | throw new TypeError(FUNC_ERROR_TEXT); |
| 15753 | } |
| 15754 | var length = partials ? partials.length : 0; |
| 15755 | if (!length) { |
| 15756 | bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15757 | partials = holders = undefined; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15758 | } |
| 15759 | length -= (holders ? holders.length : 0); |
| 15760 | if (bitmask & PARTIAL_RIGHT_FLAG) { |
| 15761 | var partialsRight = partials, |
| 15762 | holdersRight = holders; |
| 15763 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15764 | partials = holders = undefined; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15765 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15766 | var data = isBindKey ? undefined : getData(func), |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15767 | newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; |
| 15768 | |
| 15769 | if (data) { |
| 15770 | mergeData(newData, data); |
| 15771 | bitmask = newData[1]; |
| 15772 | arity = newData[9]; |
| 15773 | } |
| 15774 | newData[9] = arity == null |
| 15775 | ? (isBindKey ? 0 : func.length) |
| 15776 | : (nativeMax(arity - length, 0) || 0); |
| 15777 | |
| 15778 | if (bitmask == BIND_FLAG) { |
| 15779 | var result = createBindWrapper(newData[0], newData[2]); |
| 15780 | } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { |
| 15781 | result = createPartialWrapper.apply(undefined, newData); |
| 15782 | } else { |
| 15783 | result = createHybridWrapper.apply(undefined, newData); |
| 15784 | } |
| 15785 | var setter = data ? baseSetData : setData; |
| 15786 | return setter(result, newData); |
| 15787 | } |
| 15788 | |
| 15789 | module.exports = createWrapper; |
| 15790 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15791 | },{"./baseSetData":88,"./createBindWrapper":100,"./createHybridWrapper":104,"./createPartialWrapper":105,"./getData":110,"./mergeData":128,"./setData":133}],107:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15792 | var arraySome = require('./arraySome'); |
| 15793 | |
| 15794 | /** |
| 15795 | * A specialized version of `baseIsEqualDeep` for arrays with support for |
| 15796 | * partial deep comparisons. |
| 15797 | * |
| 15798 | * @private |
| 15799 | * @param {Array} array The array to compare. |
| 15800 | * @param {Array} other The other array to compare. |
| 15801 | * @param {Function} equalFunc The function to determine equivalents of values. |
| 15802 | * @param {Function} [customizer] The function to customize comparing arrays. |
| 15803 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 15804 | * @param {Array} [stackA] Tracks traversed `value` objects. |
| 15805 | * @param {Array} [stackB] Tracks traversed `other` objects. |
| 15806 | * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. |
| 15807 | */ |
| 15808 | function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { |
| 15809 | var index = -1, |
| 15810 | arrLength = array.length, |
| 15811 | othLength = other.length; |
| 15812 | |
| 15813 | if (arrLength != othLength && !(isLoose && othLength > arrLength)) { |
| 15814 | return false; |
| 15815 | } |
| 15816 | // Ignore non-index properties. |
| 15817 | while (++index < arrLength) { |
| 15818 | var arrValue = array[index], |
| 15819 | othValue = other[index], |
| 15820 | result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; |
| 15821 | |
| 15822 | if (result !== undefined) { |
| 15823 | if (result) { |
| 15824 | continue; |
| 15825 | } |
| 15826 | return false; |
| 15827 | } |
| 15828 | // Recursively compare arrays (susceptible to call stack limits). |
| 15829 | if (isLoose) { |
| 15830 | if (!arraySome(other, function(othValue) { |
| 15831 | return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); |
| 15832 | })) { |
| 15833 | return false; |
| 15834 | } |
| 15835 | } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { |
| 15836 | return false; |
| 15837 | } |
| 15838 | } |
| 15839 | return true; |
| 15840 | } |
| 15841 | |
| 15842 | module.exports = equalArrays; |
| 15843 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15844 | },{"./arraySome":65}],108:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15845 | /** `Object#toString` result references. */ |
| 15846 | var boolTag = '[object Boolean]', |
| 15847 | dateTag = '[object Date]', |
| 15848 | errorTag = '[object Error]', |
| 15849 | numberTag = '[object Number]', |
| 15850 | regexpTag = '[object RegExp]', |
| 15851 | stringTag = '[object String]'; |
| 15852 | |
| 15853 | /** |
| 15854 | * A specialized version of `baseIsEqualDeep` for comparing objects of |
| 15855 | * the same `toStringTag`. |
| 15856 | * |
| 15857 | * **Note:** This function only supports comparing values with tags of |
| 15858 | * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
| 15859 | * |
| 15860 | * @private |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15861 | * @param {Object} object The object to compare. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15862 | * @param {Object} other The other object to compare. |
| 15863 | * @param {string} tag The `toStringTag` of the objects to compare. |
| 15864 | * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
| 15865 | */ |
| 15866 | function equalByTag(object, other, tag) { |
| 15867 | switch (tag) { |
| 15868 | case boolTag: |
| 15869 | case dateTag: |
| 15870 | // Coerce dates and booleans to numbers, dates to milliseconds and booleans |
| 15871 | // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. |
| 15872 | return +object == +other; |
| 15873 | |
| 15874 | case errorTag: |
| 15875 | return object.name == other.name && object.message == other.message; |
| 15876 | |
| 15877 | case numberTag: |
| 15878 | // Treat `NaN` vs. `NaN` as equal. |
| 15879 | return (object != +object) |
| 15880 | ? other != +other |
| 15881 | : object == +other; |
| 15882 | |
| 15883 | case regexpTag: |
| 15884 | case stringTag: |
| 15885 | // Coerce regexes to strings and treat strings primitives and string |
| 15886 | // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. |
| 15887 | return object == (other + ''); |
| 15888 | } |
| 15889 | return false; |
| 15890 | } |
| 15891 | |
| 15892 | module.exports = equalByTag; |
| 15893 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15894 | },{}],109:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15895 | var keys = require('../object/keys'); |
| 15896 | |
| 15897 | /** Used for native method references. */ |
| 15898 | var objectProto = Object.prototype; |
| 15899 | |
| 15900 | /** Used to check objects for own properties. */ |
| 15901 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 15902 | |
| 15903 | /** |
| 15904 | * A specialized version of `baseIsEqualDeep` for objects with support for |
| 15905 | * partial deep comparisons. |
| 15906 | * |
| 15907 | * @private |
| 15908 | * @param {Object} object The object to compare. |
| 15909 | * @param {Object} other The other object to compare. |
| 15910 | * @param {Function} equalFunc The function to determine equivalents of values. |
| 15911 | * @param {Function} [customizer] The function to customize comparing values. |
| 15912 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
| 15913 | * @param {Array} [stackA] Tracks traversed `value` objects. |
| 15914 | * @param {Array} [stackB] Tracks traversed `other` objects. |
| 15915 | * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
| 15916 | */ |
| 15917 | function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { |
| 15918 | var objProps = keys(object), |
| 15919 | objLength = objProps.length, |
| 15920 | othProps = keys(other), |
| 15921 | othLength = othProps.length; |
| 15922 | |
| 15923 | if (objLength != othLength && !isLoose) { |
| 15924 | return false; |
| 15925 | } |
| 15926 | var index = objLength; |
| 15927 | while (index--) { |
| 15928 | var key = objProps[index]; |
| 15929 | if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { |
| 15930 | return false; |
| 15931 | } |
| 15932 | } |
| 15933 | var skipCtor = isLoose; |
| 15934 | while (++index < objLength) { |
| 15935 | key = objProps[index]; |
| 15936 | var objValue = object[key], |
| 15937 | othValue = other[key], |
| 15938 | result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; |
| 15939 | |
| 15940 | // Recursively compare objects (susceptible to call stack limits). |
| 15941 | if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { |
| 15942 | return false; |
| 15943 | } |
| 15944 | skipCtor || (skipCtor = key == 'constructor'); |
| 15945 | } |
| 15946 | if (!skipCtor) { |
| 15947 | var objCtor = object.constructor, |
| 15948 | othCtor = other.constructor; |
| 15949 | |
| 15950 | // Non `Object` object instances with different constructors are not equal. |
| 15951 | if (objCtor != othCtor && |
| 15952 | ('constructor' in object && 'constructor' in other) && |
| 15953 | !(typeof objCtor == 'function' && objCtor instanceof objCtor && |
| 15954 | typeof othCtor == 'function' && othCtor instanceof othCtor)) { |
| 15955 | return false; |
| 15956 | } |
| 15957 | } |
| 15958 | return true; |
| 15959 | } |
| 15960 | |
| 15961 | module.exports = equalObjects; |
| 15962 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15963 | },{"../object/keys":149}],110:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15964 | var metaMap = require('./metaMap'), |
| 15965 | noop = require('../utility/noop'); |
| 15966 | |
| 15967 | /** |
| 15968 | * Gets metadata for `func`. |
| 15969 | * |
| 15970 | * @private |
| 15971 | * @param {Function} func The function to query. |
| 15972 | * @returns {*} Returns the metadata for `func`. |
| 15973 | */ |
| 15974 | var getData = !metaMap ? noop : function(func) { |
| 15975 | return metaMap.get(func); |
| 15976 | }; |
| 15977 | |
| 15978 | module.exports = getData; |
| 15979 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 15980 | },{"../utility/noop":155,"./metaMap":129}],111:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15981 | var realNames = require('./realNames'); |
| 15982 | |
| 15983 | /** |
| 15984 | * Gets the name of `func`. |
| 15985 | * |
| 15986 | * @private |
| 15987 | * @param {Function} func The function to query. |
| 15988 | * @returns {string} Returns the function name. |
| 15989 | */ |
| 15990 | function getFuncName(func) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 15991 | var result = (func.name + ''), |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 15992 | array = realNames[result], |
| 15993 | length = array ? array.length : 0; |
| 15994 | |
| 15995 | while (length--) { |
| 15996 | var data = array[length], |
| 15997 | otherFunc = data.func; |
| 15998 | if (otherFunc == null || otherFunc == func) { |
| 15999 | return data.name; |
| 16000 | } |
| 16001 | } |
| 16002 | return result; |
| 16003 | } |
| 16004 | |
| 16005 | module.exports = getFuncName; |
| 16006 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16007 | },{"./realNames":130}],112:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16008 | var baseProperty = require('./baseProperty'); |
| 16009 | |
| 16010 | /** |
| 16011 | * Gets the "length" property value of `object`. |
| 16012 | * |
| 16013 | * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) |
| 16014 | * that affects Safari on at least iOS 8.1-8.3 ARM64. |
| 16015 | * |
| 16016 | * @private |
| 16017 | * @param {Object} object The object to query. |
| 16018 | * @returns {*} Returns the "length" value. |
| 16019 | */ |
| 16020 | var getLength = baseProperty('length'); |
| 16021 | |
| 16022 | module.exports = getLength; |
| 16023 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16024 | },{"./baseProperty":86}],113:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16025 | var isStrictComparable = require('./isStrictComparable'), |
| 16026 | pairs = require('../object/pairs'); |
| 16027 | |
| 16028 | /** |
| 16029 | * Gets the propery names, values, and compare flags of `object`. |
| 16030 | * |
| 16031 | * @private |
| 16032 | * @param {Object} object The object to query. |
| 16033 | * @returns {Array} Returns the match data of `object`. |
| 16034 | */ |
| 16035 | function getMatchData(object) { |
| 16036 | var result = pairs(object), |
| 16037 | length = result.length; |
| 16038 | |
| 16039 | while (length--) { |
| 16040 | result[length][2] = isStrictComparable(result[length][1]); |
| 16041 | } |
| 16042 | return result; |
| 16043 | } |
| 16044 | |
| 16045 | module.exports = getMatchData; |
| 16046 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16047 | },{"../object/pairs":151,"./isStrictComparable":127}],114:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16048 | var isNative = require('../lang/isNative'); |
| 16049 | |
| 16050 | /** |
| 16051 | * Gets the native function at `key` of `object`. |
| 16052 | * |
| 16053 | * @private |
| 16054 | * @param {Object} object The object to query. |
| 16055 | * @param {string} key The key of the method to get. |
| 16056 | * @returns {*} Returns the function if it's native, else `undefined`. |
| 16057 | */ |
| 16058 | function getNative(object, key) { |
| 16059 | var value = object == null ? undefined : object[key]; |
| 16060 | return isNative(value) ? value : undefined; |
| 16061 | } |
| 16062 | |
| 16063 | module.exports = getNative; |
| 16064 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16065 | },{"../lang/isNative":143}],115:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16066 | /** |
| 16067 | * Gets the index at which the first occurrence of `NaN` is found in `array`. |
| 16068 | * |
| 16069 | * @private |
| 16070 | * @param {Array} array The array to search. |
| 16071 | * @param {number} fromIndex The index to search from. |
| 16072 | * @param {boolean} [fromRight] Specify iterating from right to left. |
| 16073 | * @returns {number} Returns the index of the matched `NaN`, else `-1`. |
| 16074 | */ |
| 16075 | function indexOfNaN(array, fromIndex, fromRight) { |
| 16076 | var length = array.length, |
| 16077 | index = fromIndex + (fromRight ? 0 : -1); |
| 16078 | |
| 16079 | while ((fromRight ? index-- : ++index < length)) { |
| 16080 | var other = array[index]; |
| 16081 | if (other !== other) { |
| 16082 | return index; |
| 16083 | } |
| 16084 | } |
| 16085 | return -1; |
| 16086 | } |
| 16087 | |
| 16088 | module.exports = indexOfNaN; |
| 16089 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16090 | },{}],116:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16091 | /** Used for native method references. */ |
| 16092 | var objectProto = Object.prototype; |
| 16093 | |
| 16094 | /** Used to check objects for own properties. */ |
| 16095 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 16096 | |
| 16097 | /** |
| 16098 | * Initializes an array clone. |
| 16099 | * |
| 16100 | * @private |
| 16101 | * @param {Array} array The array to clone. |
| 16102 | * @returns {Array} Returns the initialized clone. |
| 16103 | */ |
| 16104 | function initCloneArray(array) { |
| 16105 | var length = array.length, |
| 16106 | result = new array.constructor(length); |
| 16107 | |
| 16108 | // Add array properties assigned by `RegExp#exec`. |
| 16109 | if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { |
| 16110 | result.index = array.index; |
| 16111 | result.input = array.input; |
| 16112 | } |
| 16113 | return result; |
| 16114 | } |
| 16115 | |
| 16116 | module.exports = initCloneArray; |
| 16117 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16118 | },{}],117:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16119 | (function (global){ |
| 16120 | var bufferClone = require('./bufferClone'); |
| 16121 | |
| 16122 | /** `Object#toString` result references. */ |
| 16123 | var boolTag = '[object Boolean]', |
| 16124 | dateTag = '[object Date]', |
| 16125 | numberTag = '[object Number]', |
| 16126 | regexpTag = '[object RegExp]', |
| 16127 | stringTag = '[object String]'; |
| 16128 | |
| 16129 | var arrayBufferTag = '[object ArrayBuffer]', |
| 16130 | float32Tag = '[object Float32Array]', |
| 16131 | float64Tag = '[object Float64Array]', |
| 16132 | int8Tag = '[object Int8Array]', |
| 16133 | int16Tag = '[object Int16Array]', |
| 16134 | int32Tag = '[object Int32Array]', |
| 16135 | uint8Tag = '[object Uint8Array]', |
| 16136 | uint8ClampedTag = '[object Uint8ClampedArray]', |
| 16137 | uint16Tag = '[object Uint16Array]', |
| 16138 | uint32Tag = '[object Uint32Array]'; |
| 16139 | |
| 16140 | /** Used to match `RegExp` flags from their coerced string values. */ |
| 16141 | var reFlags = /\w*$/; |
| 16142 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16143 | /** Native method references. */ |
| 16144 | var Uint8Array = global.Uint8Array; |
| 16145 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16146 | /** Used to lookup a type array constructors by `toStringTag`. */ |
| 16147 | var ctorByTag = {}; |
| 16148 | ctorByTag[float32Tag] = global.Float32Array; |
| 16149 | ctorByTag[float64Tag] = global.Float64Array; |
| 16150 | ctorByTag[int8Tag] = global.Int8Array; |
| 16151 | ctorByTag[int16Tag] = global.Int16Array; |
| 16152 | ctorByTag[int32Tag] = global.Int32Array; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16153 | ctorByTag[uint8Tag] = Uint8Array; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16154 | ctorByTag[uint8ClampedTag] = global.Uint8ClampedArray; |
| 16155 | ctorByTag[uint16Tag] = global.Uint16Array; |
| 16156 | ctorByTag[uint32Tag] = global.Uint32Array; |
| 16157 | |
| 16158 | /** |
| 16159 | * Initializes an object clone based on its `toStringTag`. |
| 16160 | * |
| 16161 | * **Note:** This function only supports cloning values with tags of |
| 16162 | * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
| 16163 | * |
| 16164 | * @private |
| 16165 | * @param {Object} object The object to clone. |
| 16166 | * @param {string} tag The `toStringTag` of the object to clone. |
| 16167 | * @param {boolean} [isDeep] Specify a deep clone. |
| 16168 | * @returns {Object} Returns the initialized clone. |
| 16169 | */ |
| 16170 | function initCloneByTag(object, tag, isDeep) { |
| 16171 | var Ctor = object.constructor; |
| 16172 | switch (tag) { |
| 16173 | case arrayBufferTag: |
| 16174 | return bufferClone(object); |
| 16175 | |
| 16176 | case boolTag: |
| 16177 | case dateTag: |
| 16178 | return new Ctor(+object); |
| 16179 | |
| 16180 | case float32Tag: case float64Tag: |
| 16181 | case int8Tag: case int16Tag: case int32Tag: |
| 16182 | case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: |
| 16183 | // Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays. |
| 16184 | if (Ctor instanceof Ctor) { |
| 16185 | Ctor = ctorByTag[tag]; |
| 16186 | } |
| 16187 | var buffer = object.buffer; |
| 16188 | return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); |
| 16189 | |
| 16190 | case numberTag: |
| 16191 | case stringTag: |
| 16192 | return new Ctor(object); |
| 16193 | |
| 16194 | case regexpTag: |
| 16195 | var result = new Ctor(object.source, reFlags.exec(object)); |
| 16196 | result.lastIndex = object.lastIndex; |
| 16197 | } |
| 16198 | return result; |
| 16199 | } |
| 16200 | |
| 16201 | module.exports = initCloneByTag; |
| 16202 | |
| 16203 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16204 | //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUJ5VGFnLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYnVmZmVyQ2xvbmUgPSByZXF1aXJlKCcuL2J1ZmZlckNsb25lJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheTtcblxuLyoqIFVzZWQgdG8gbG9va3VwIGEgdHlwZSBhcnJheSBjb25zdHJ1Y3RvcnMgYnkgYHRvU3RyaW5nVGFnYC4gKi9cbnZhciBjdG9yQnlUYWcgPSB7fTtcbmN0b3JCeVRhZ1tmbG9hdDMyVGFnXSA9IGdsb2JhbC5GbG9hdDMyQXJyYXk7XG5jdG9yQnlUYWdbZmxvYXQ2NFRhZ10gPSBnbG9iYWwuRmxvYXQ2NEFycmF5O1xuY3RvckJ5VGFnW2ludDhUYWddID0gZ2xvYmFsLkludDhBcnJheTtcbmN0b3JCeVRhZ1tpbnQxNlRhZ10gPSBnbG9iYWwuSW50MTZBcnJheTtcbmN0b3JCeVRhZ1tpbnQzMlRhZ10gPSBnbG9iYWwuSW50MzJBcnJheTtcbmN0b3JCeVRhZ1t1aW50OFRhZ10gPSBVaW50OEFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4Q2xhbXBlZFRhZ10gPSBnbG9iYWwuVWludDhDbGFtcGVkQXJyYXk7XG5jdG9yQnlUYWdbdWludDE2VGFnXSA9IGdsb2JhbC5VaW50MTZBcnJheTtcbmN0b3JCeVRhZ1t1aW50MzJUYWddID0gZ2xvYmFsLlVpbnQzMkFycmF5O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgcmV0dXJuIGJ1ZmZlckNsb25lKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAvLyBTYWZhcmkgNSBtb2JpbGUgaW5jb3JyZWN0bHkgaGFzIGBPYmplY3RgIGFzIHRoZSBjb25zdHJ1Y3RvciBvZiB0eXBlZCBhcnJheXMuXG4gICAgICBpZiAoQ3RvciBpbnN0YW5jZW9mIEN0b3IpIHtcbiAgICAgICAgQ3RvciA9IGN0b3JCeVRhZ1t0YWddO1xuICAgICAgfVxuICAgICAgdmFyIGJ1ZmZlciA9IG9iamVjdC5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IEN0b3IoaXNEZWVwID8gYnVmZmVyQ2xvbmUoYnVmZmVyKSA6IGJ1ZmZlciwgb2JqZWN0LmJ5dGVPZmZzZXQsIG9iamVjdC5sZW5ndGgpO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBDdG9yKG9iamVjdC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhvYmplY3QpKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSBvYmplY3QubGFzdEluZGV4O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG4iXX0= |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16205 | },{"./bufferClone":95}],118:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16206 | /** |
| 16207 | * Initializes an object clone. |
| 16208 | * |
| 16209 | * @private |
| 16210 | * @param {Object} object The object to clone. |
| 16211 | * @returns {Object} Returns the initialized clone. |
| 16212 | */ |
| 16213 | function initCloneObject(object) { |
| 16214 | var Ctor = object.constructor; |
| 16215 | if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { |
| 16216 | Ctor = Object; |
| 16217 | } |
| 16218 | return new Ctor; |
| 16219 | } |
| 16220 | |
| 16221 | module.exports = initCloneObject; |
| 16222 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16223 | },{}],119:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16224 | var getLength = require('./getLength'), |
| 16225 | isLength = require('./isLength'); |
| 16226 | |
| 16227 | /** |
| 16228 | * Checks if `value` is array-like. |
| 16229 | * |
| 16230 | * @private |
| 16231 | * @param {*} value The value to check. |
| 16232 | * @returns {boolean} Returns `true` if `value` is array-like, else `false`. |
| 16233 | */ |
| 16234 | function isArrayLike(value) { |
| 16235 | return value != null && isLength(getLength(value)); |
| 16236 | } |
| 16237 | |
| 16238 | module.exports = isArrayLike; |
| 16239 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16240 | },{"./getLength":112,"./isLength":125}],120:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16241 | /** |
| 16242 | * Checks if `value` is a host object in IE < 9. |
| 16243 | * |
| 16244 | * @private |
| 16245 | * @param {*} value The value to check. |
| 16246 | * @returns {boolean} Returns `true` if `value` is a host object, else `false`. |
| 16247 | */ |
| 16248 | var isHostObject = (function() { |
| 16249 | try { |
| 16250 | Object({ 'toString': 0 } + ''); |
| 16251 | } catch(e) { |
| 16252 | return function() { return false; }; |
| 16253 | } |
| 16254 | return function(value) { |
| 16255 | // IE < 9 presents many host objects as `Object` objects that can coerce |
| 16256 | // to strings despite having improperly defined `toString` methods. |
| 16257 | return typeof value.toString != 'function' && typeof (value + '') == 'string'; |
| 16258 | }; |
| 16259 | }()); |
| 16260 | |
| 16261 | module.exports = isHostObject; |
| 16262 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16263 | },{}],121:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16264 | /** Used to detect unsigned integer values. */ |
| 16265 | var reIsUint = /^\d+$/; |
| 16266 | |
| 16267 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16268 | * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16269 | * of an array-like value. |
| 16270 | */ |
| 16271 | var MAX_SAFE_INTEGER = 9007199254740991; |
| 16272 | |
| 16273 | /** |
| 16274 | * Checks if `value` is a valid array-like index. |
| 16275 | * |
| 16276 | * @private |
| 16277 | * @param {*} value The value to check. |
| 16278 | * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. |
| 16279 | * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. |
| 16280 | */ |
| 16281 | function isIndex(value, length) { |
| 16282 | value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; |
| 16283 | length = length == null ? MAX_SAFE_INTEGER : length; |
| 16284 | return value > -1 && value % 1 == 0 && value < length; |
| 16285 | } |
| 16286 | |
| 16287 | module.exports = isIndex; |
| 16288 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16289 | },{}],122:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16290 | var isArrayLike = require('./isArrayLike'), |
| 16291 | isIndex = require('./isIndex'), |
| 16292 | isObject = require('../lang/isObject'); |
| 16293 | |
| 16294 | /** |
| 16295 | * Checks if the provided arguments are from an iteratee call. |
| 16296 | * |
| 16297 | * @private |
| 16298 | * @param {*} value The potential iteratee value argument. |
| 16299 | * @param {*} index The potential iteratee index or key argument. |
| 16300 | * @param {*} object The potential iteratee object argument. |
| 16301 | * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. |
| 16302 | */ |
| 16303 | function isIterateeCall(value, index, object) { |
| 16304 | if (!isObject(object)) { |
| 16305 | return false; |
| 16306 | } |
| 16307 | var type = typeof index; |
| 16308 | if (type == 'number' |
| 16309 | ? (isArrayLike(object) && isIndex(index, object.length)) |
| 16310 | : (type == 'string' && index in object)) { |
| 16311 | var other = object[index]; |
| 16312 | return value === value ? (value === other) : (other !== other); |
| 16313 | } |
| 16314 | return false; |
| 16315 | } |
| 16316 | |
| 16317 | module.exports = isIterateeCall; |
| 16318 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16319 | },{"../lang/isObject":144,"./isArrayLike":119,"./isIndex":121}],123:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16320 | var isArray = require('../lang/isArray'), |
| 16321 | toObject = require('./toObject'); |
| 16322 | |
| 16323 | /** Used to match property names within property paths. */ |
| 16324 | var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, |
| 16325 | reIsPlainProp = /^\w*$/; |
| 16326 | |
| 16327 | /** |
| 16328 | * Checks if `value` is a property name and not a property path. |
| 16329 | * |
| 16330 | * @private |
| 16331 | * @param {*} value The value to check. |
| 16332 | * @param {Object} [object] The object to query keys on. |
| 16333 | * @returns {boolean} Returns `true` if `value` is a property name, else `false`. |
| 16334 | */ |
| 16335 | function isKey(value, object) { |
| 16336 | var type = typeof value; |
| 16337 | if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { |
| 16338 | return true; |
| 16339 | } |
| 16340 | if (isArray(value)) { |
| 16341 | return false; |
| 16342 | } |
| 16343 | var result = !reIsDeepProp.test(value); |
| 16344 | return result || (object != null && value in toObject(object)); |
| 16345 | } |
| 16346 | |
| 16347 | module.exports = isKey; |
| 16348 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16349 | },{"../lang/isArray":140,"./toObject":135}],124:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16350 | var LazyWrapper = require('./LazyWrapper'), |
| 16351 | getData = require('./getData'), |
| 16352 | getFuncName = require('./getFuncName'), |
| 16353 | lodash = require('../chain/lodash'); |
| 16354 | |
| 16355 | /** |
| 16356 | * Checks if `func` has a lazy counterpart. |
| 16357 | * |
| 16358 | * @private |
| 16359 | * @param {Function} func The function to check. |
| 16360 | * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. |
| 16361 | */ |
| 16362 | function isLaziable(func) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16363 | var funcName = getFuncName(func), |
| 16364 | other = lodash[funcName]; |
| 16365 | |
| 16366 | if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16367 | return false; |
| 16368 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16369 | if (func === other) { |
| 16370 | return true; |
| 16371 | } |
| 16372 | var data = getData(other); |
| 16373 | return !!data && func === data[0]; |
| 16374 | } |
| 16375 | |
| 16376 | module.exports = isLaziable; |
| 16377 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16378 | },{"../chain/lodash":51,"./LazyWrapper":60,"./getData":110,"./getFuncName":111}],125:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16379 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16380 | * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16381 | * of an array-like value. |
| 16382 | */ |
| 16383 | var MAX_SAFE_INTEGER = 9007199254740991; |
| 16384 | |
| 16385 | /** |
| 16386 | * Checks if `value` is a valid array-like length. |
| 16387 | * |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16388 | * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16389 | * |
| 16390 | * @private |
| 16391 | * @param {*} value The value to check. |
| 16392 | * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. |
| 16393 | */ |
| 16394 | function isLength(value) { |
| 16395 | return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; |
| 16396 | } |
| 16397 | |
| 16398 | module.exports = isLength; |
| 16399 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16400 | },{}],126:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16401 | /** |
| 16402 | * Checks if `value` is object-like. |
| 16403 | * |
| 16404 | * @private |
| 16405 | * @param {*} value The value to check. |
| 16406 | * @returns {boolean} Returns `true` if `value` is object-like, else `false`. |
| 16407 | */ |
| 16408 | function isObjectLike(value) { |
| 16409 | return !!value && typeof value == 'object'; |
| 16410 | } |
| 16411 | |
| 16412 | module.exports = isObjectLike; |
| 16413 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16414 | },{}],127:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16415 | var isObject = require('../lang/isObject'); |
| 16416 | |
| 16417 | /** |
| 16418 | * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. |
| 16419 | * |
| 16420 | * @private |
| 16421 | * @param {*} value The value to check. |
| 16422 | * @returns {boolean} Returns `true` if `value` if suitable for strict |
| 16423 | * equality comparisons, else `false`. |
| 16424 | */ |
| 16425 | function isStrictComparable(value) { |
| 16426 | return value === value && !isObject(value); |
| 16427 | } |
| 16428 | |
| 16429 | module.exports = isStrictComparable; |
| 16430 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16431 | },{"../lang/isObject":144}],128:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16432 | var arrayCopy = require('./arrayCopy'), |
| 16433 | composeArgs = require('./composeArgs'), |
| 16434 | composeArgsRight = require('./composeArgsRight'), |
| 16435 | replaceHolders = require('./replaceHolders'); |
| 16436 | |
| 16437 | /** Used to compose bitmasks for wrapper metadata. */ |
| 16438 | var BIND_FLAG = 1, |
| 16439 | CURRY_BOUND_FLAG = 4, |
| 16440 | CURRY_FLAG = 8, |
| 16441 | ARY_FLAG = 128, |
| 16442 | REARG_FLAG = 256; |
| 16443 | |
| 16444 | /** Used as the internal argument placeholder. */ |
| 16445 | var PLACEHOLDER = '__lodash_placeholder__'; |
| 16446 | |
| 16447 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 16448 | var nativeMin = Math.min; |
| 16449 | |
| 16450 | /** |
| 16451 | * Merges the function metadata of `source` into `data`. |
| 16452 | * |
| 16453 | * Merging metadata reduces the number of wrappers required to invoke a function. |
| 16454 | * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` |
| 16455 | * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` |
| 16456 | * augment function arguments, making the order in which they are executed important, |
| 16457 | * preventing the merging of metadata. However, we make an exception for a safe |
| 16458 | * common case where curried functions have `_.ary` and or `_.rearg` applied. |
| 16459 | * |
| 16460 | * @private |
| 16461 | * @param {Array} data The destination metadata. |
| 16462 | * @param {Array} source The source metadata. |
| 16463 | * @returns {Array} Returns `data`. |
| 16464 | */ |
| 16465 | function mergeData(data, source) { |
| 16466 | var bitmask = data[1], |
| 16467 | srcBitmask = source[1], |
| 16468 | newBitmask = bitmask | srcBitmask, |
| 16469 | isCommon = newBitmask < ARY_FLAG; |
| 16470 | |
| 16471 | var isCombo = |
| 16472 | (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || |
| 16473 | (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || |
| 16474 | (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); |
| 16475 | |
| 16476 | // Exit early if metadata can't be merged. |
| 16477 | if (!(isCommon || isCombo)) { |
| 16478 | return data; |
| 16479 | } |
| 16480 | // Use source `thisArg` if available. |
| 16481 | if (srcBitmask & BIND_FLAG) { |
| 16482 | data[2] = source[2]; |
| 16483 | // Set when currying a bound function. |
| 16484 | newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; |
| 16485 | } |
| 16486 | // Compose partial arguments. |
| 16487 | var value = source[3]; |
| 16488 | if (value) { |
| 16489 | var partials = data[3]; |
| 16490 | data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); |
| 16491 | data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); |
| 16492 | } |
| 16493 | // Compose partial right arguments. |
| 16494 | value = source[5]; |
| 16495 | if (value) { |
| 16496 | partials = data[5]; |
| 16497 | data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); |
| 16498 | data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); |
| 16499 | } |
| 16500 | // Use source `argPos` if available. |
| 16501 | value = source[7]; |
| 16502 | if (value) { |
| 16503 | data[7] = arrayCopy(value); |
| 16504 | } |
| 16505 | // Use source `ary` if it's smaller. |
| 16506 | if (srcBitmask & ARY_FLAG) { |
| 16507 | data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); |
| 16508 | } |
| 16509 | // Use source `arity` if one is not provided. |
| 16510 | if (data[9] == null) { |
| 16511 | data[9] = source[9]; |
| 16512 | } |
| 16513 | // Use source `func` and merge bitmasks. |
| 16514 | data[0] = source[0]; |
| 16515 | data[1] = newBitmask; |
| 16516 | |
| 16517 | return data; |
| 16518 | } |
| 16519 | |
| 16520 | module.exports = mergeData; |
| 16521 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16522 | },{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./replaceHolders":132}],129:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16523 | (function (global){ |
| 16524 | var getNative = require('./getNative'); |
| 16525 | |
| 16526 | /** Native method references. */ |
| 16527 | var WeakMap = getNative(global, 'WeakMap'); |
| 16528 | |
| 16529 | /** Used to store function metadata. */ |
| 16530 | var metaMap = WeakMap && new WeakMap; |
| 16531 | |
| 16532 | module.exports = metaMap; |
| 16533 | |
| 16534 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16535 | //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21ldGFNYXAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9nZXROYXRpdmUnKTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKGdsb2JhbCwgJ1dlYWtNYXAnKTtcblxuLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgbWV0YU1hcCA9IFdlYWtNYXAgJiYgbmV3IFdlYWtNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gbWV0YU1hcDtcbiJdfQ== |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16536 | },{"./getNative":114}],130:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16537 | /** Used to lookup unminified function names. */ |
| 16538 | var realNames = {}; |
| 16539 | |
| 16540 | module.exports = realNames; |
| 16541 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16542 | },{}],131:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16543 | var arrayCopy = require('./arrayCopy'), |
| 16544 | isIndex = require('./isIndex'); |
| 16545 | |
| 16546 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 16547 | var nativeMin = Math.min; |
| 16548 | |
| 16549 | /** |
| 16550 | * Reorder `array` according to the specified indexes where the element at |
| 16551 | * the first index is assigned as the first element, the element at |
| 16552 | * the second index is assigned as the second element, and so on. |
| 16553 | * |
| 16554 | * @private |
| 16555 | * @param {Array} array The array to reorder. |
| 16556 | * @param {Array} indexes The arranged array indexes. |
| 16557 | * @returns {Array} Returns `array`. |
| 16558 | */ |
| 16559 | function reorder(array, indexes) { |
| 16560 | var arrLength = array.length, |
| 16561 | length = nativeMin(indexes.length, arrLength), |
| 16562 | oldArray = arrayCopy(array); |
| 16563 | |
| 16564 | while (length--) { |
| 16565 | var index = indexes[length]; |
| 16566 | array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; |
| 16567 | } |
| 16568 | return array; |
| 16569 | } |
| 16570 | |
| 16571 | module.exports = reorder; |
| 16572 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16573 | },{"./arrayCopy":62,"./isIndex":121}],132:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16574 | /** Used as the internal argument placeholder. */ |
| 16575 | var PLACEHOLDER = '__lodash_placeholder__'; |
| 16576 | |
| 16577 | /** |
| 16578 | * Replaces all `placeholder` elements in `array` with an internal placeholder |
| 16579 | * and returns an array of their indexes. |
| 16580 | * |
| 16581 | * @private |
| 16582 | * @param {Array} array The array to modify. |
| 16583 | * @param {*} placeholder The placeholder to replace. |
| 16584 | * @returns {Array} Returns the new array of placeholder indexes. |
| 16585 | */ |
| 16586 | function replaceHolders(array, placeholder) { |
| 16587 | var index = -1, |
| 16588 | length = array.length, |
| 16589 | resIndex = -1, |
| 16590 | result = []; |
| 16591 | |
| 16592 | while (++index < length) { |
| 16593 | if (array[index] === placeholder) { |
| 16594 | array[index] = PLACEHOLDER; |
| 16595 | result[++resIndex] = index; |
| 16596 | } |
| 16597 | } |
| 16598 | return result; |
| 16599 | } |
| 16600 | |
| 16601 | module.exports = replaceHolders; |
| 16602 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16603 | },{}],133:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16604 | var baseSetData = require('./baseSetData'), |
| 16605 | now = require('../date/now'); |
| 16606 | |
| 16607 | /** Used to detect when a function becomes hot. */ |
| 16608 | var HOT_COUNT = 150, |
| 16609 | HOT_SPAN = 16; |
| 16610 | |
| 16611 | /** |
| 16612 | * Sets metadata for `func`. |
| 16613 | * |
| 16614 | * **Note:** If this function becomes hot, i.e. is invoked a lot in a short |
| 16615 | * period of time, it will trip its breaker and transition to an identity function |
| 16616 | * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) |
| 16617 | * for more details. |
| 16618 | * |
| 16619 | * @private |
| 16620 | * @param {Function} func The function to associate metadata with. |
| 16621 | * @param {*} data The metadata. |
| 16622 | * @returns {Function} Returns `func`. |
| 16623 | */ |
| 16624 | var setData = (function() { |
| 16625 | var count = 0, |
| 16626 | lastCalled = 0; |
| 16627 | |
| 16628 | return function(key, value) { |
| 16629 | var stamp = now(), |
| 16630 | remaining = HOT_SPAN - (stamp - lastCalled); |
| 16631 | |
| 16632 | lastCalled = stamp; |
| 16633 | if (remaining > 0) { |
| 16634 | if (++count >= HOT_COUNT) { |
| 16635 | return key; |
| 16636 | } |
| 16637 | } else { |
| 16638 | count = 0; |
| 16639 | } |
| 16640 | return baseSetData(key, value); |
| 16641 | }; |
| 16642 | }()); |
| 16643 | |
| 16644 | module.exports = setData; |
| 16645 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16646 | },{"../date/now":57,"./baseSetData":88}],134:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16647 | var isArguments = require('../lang/isArguments'), |
| 16648 | isArray = require('../lang/isArray'), |
| 16649 | isIndex = require('./isIndex'), |
| 16650 | isLength = require('./isLength'), |
| 16651 | isString = require('../lang/isString'), |
| 16652 | keysIn = require('../object/keysIn'); |
| 16653 | |
| 16654 | /** Used for native method references. */ |
| 16655 | var objectProto = Object.prototype; |
| 16656 | |
| 16657 | /** Used to check objects for own properties. */ |
| 16658 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 16659 | |
| 16660 | /** |
| 16661 | * A fallback implementation of `Object.keys` which creates an array of the |
| 16662 | * own enumerable property names of `object`. |
| 16663 | * |
| 16664 | * @private |
| 16665 | * @param {Object} object The object to query. |
| 16666 | * @returns {Array} Returns the array of property names. |
| 16667 | */ |
| 16668 | function shimKeys(object) { |
| 16669 | var props = keysIn(object), |
| 16670 | propsLength = props.length, |
| 16671 | length = propsLength && object.length; |
| 16672 | |
| 16673 | var allowIndexes = !!length && isLength(length) && |
| 16674 | (isArray(object) || isArguments(object) || isString(object)); |
| 16675 | |
| 16676 | var index = -1, |
| 16677 | result = []; |
| 16678 | |
| 16679 | while (++index < propsLength) { |
| 16680 | var key = props[index]; |
| 16681 | if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { |
| 16682 | result.push(key); |
| 16683 | } |
| 16684 | } |
| 16685 | return result; |
| 16686 | } |
| 16687 | |
| 16688 | module.exports = shimKeys; |
| 16689 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16690 | },{"../lang/isArguments":139,"../lang/isArray":140,"../lang/isString":146,"../object/keysIn":150,"./isIndex":121,"./isLength":125}],135:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16691 | var isObject = require('../lang/isObject'), |
| 16692 | isString = require('../lang/isString'), |
| 16693 | support = require('../support'); |
| 16694 | |
| 16695 | /** |
| 16696 | * Converts `value` to an object if it's not one. |
| 16697 | * |
| 16698 | * @private |
| 16699 | * @param {*} value The value to process. |
| 16700 | * @returns {Object} Returns the object. |
| 16701 | */ |
| 16702 | function toObject(value) { |
| 16703 | if (support.unindexedChars && isString(value)) { |
| 16704 | var index = -1, |
| 16705 | length = value.length, |
| 16706 | result = Object(value); |
| 16707 | |
| 16708 | while (++index < length) { |
| 16709 | result[index] = value.charAt(index); |
| 16710 | } |
| 16711 | return result; |
| 16712 | } |
| 16713 | return isObject(value) ? value : Object(value); |
| 16714 | } |
| 16715 | |
| 16716 | module.exports = toObject; |
| 16717 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16718 | },{"../lang/isObject":144,"../lang/isString":146,"../support":153}],136:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16719 | var baseToString = require('./baseToString'), |
| 16720 | isArray = require('../lang/isArray'); |
| 16721 | |
| 16722 | /** Used to match property names within property paths. */ |
| 16723 | var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; |
| 16724 | |
| 16725 | /** Used to match backslashes in property paths. */ |
| 16726 | var reEscapeChar = /\\(\\)?/g; |
| 16727 | |
| 16728 | /** |
| 16729 | * Converts `value` to property path array if it's not one. |
| 16730 | * |
| 16731 | * @private |
| 16732 | * @param {*} value The value to process. |
| 16733 | * @returns {Array} Returns the property path array. |
| 16734 | */ |
| 16735 | function toPath(value) { |
| 16736 | if (isArray(value)) { |
| 16737 | return value; |
| 16738 | } |
| 16739 | var result = []; |
| 16740 | baseToString(value).replace(rePropName, function(match, number, quote, string) { |
| 16741 | result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); |
| 16742 | }); |
| 16743 | return result; |
| 16744 | } |
| 16745 | |
| 16746 | module.exports = toPath; |
| 16747 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16748 | },{"../lang/isArray":140,"./baseToString":90}],137:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16749 | var LazyWrapper = require('./LazyWrapper'), |
| 16750 | LodashWrapper = require('./LodashWrapper'), |
| 16751 | arrayCopy = require('./arrayCopy'); |
| 16752 | |
| 16753 | /** |
| 16754 | * Creates a clone of `wrapper`. |
| 16755 | * |
| 16756 | * @private |
| 16757 | * @param {Object} wrapper The wrapper to clone. |
| 16758 | * @returns {Object} Returns the cloned wrapper. |
| 16759 | */ |
| 16760 | function wrapperClone(wrapper) { |
| 16761 | return wrapper instanceof LazyWrapper |
| 16762 | ? wrapper.clone() |
| 16763 | : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); |
| 16764 | } |
| 16765 | |
| 16766 | module.exports = wrapperClone; |
| 16767 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16768 | },{"./LazyWrapper":60,"./LodashWrapper":61,"./arrayCopy":62}],138:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16769 | var baseClone = require('../internal/baseClone'), |
| 16770 | bindCallback = require('../internal/bindCallback'); |
| 16771 | |
| 16772 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16773 | * Creates a deep clone of `value`. If `customizer` is provided it's invoked |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16774 | * to produce the cloned values. If `customizer` returns `undefined` cloning |
| 16775 | * is handled by the method instead. The `customizer` is bound to `thisArg` |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16776 | * and invoked with up to three argument; (value [, index|key, object]). |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16777 | * |
| 16778 | * **Note:** This method is loosely based on the |
| 16779 | * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). |
| 16780 | * The enumerable properties of `arguments` objects and objects created by |
| 16781 | * constructors other than `Object` are cloned to plain `Object` objects. An |
| 16782 | * empty object is returned for uncloneable values such as functions, DOM nodes, |
| 16783 | * Maps, Sets, and WeakMaps. |
| 16784 | * |
| 16785 | * @static |
| 16786 | * @memberOf _ |
| 16787 | * @category Lang |
| 16788 | * @param {*} value The value to deep clone. |
| 16789 | * @param {Function} [customizer] The function to customize cloning values. |
| 16790 | * @param {*} [thisArg] The `this` binding of `customizer`. |
| 16791 | * @returns {*} Returns the deep cloned value. |
| 16792 | * @example |
| 16793 | * |
| 16794 | * var users = [ |
| 16795 | * { 'user': 'barney' }, |
| 16796 | * { 'user': 'fred' } |
| 16797 | * ]; |
| 16798 | * |
| 16799 | * var deep = _.cloneDeep(users); |
| 16800 | * deep[0] === users[0]; |
| 16801 | * // => false |
| 16802 | * |
| 16803 | * // using a customizer callback |
| 16804 | * var el = _.cloneDeep(document.body, function(value) { |
| 16805 | * if (_.isElement(value)) { |
| 16806 | * return value.cloneNode(true); |
| 16807 | * } |
| 16808 | * }); |
| 16809 | * |
| 16810 | * el === document.body |
| 16811 | * // => false |
| 16812 | * el.nodeName |
| 16813 | * // => BODY |
| 16814 | * el.childNodes.length; |
| 16815 | * // => 20 |
| 16816 | */ |
| 16817 | function cloneDeep(value, customizer, thisArg) { |
| 16818 | return typeof customizer == 'function' |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16819 | ? baseClone(value, true, bindCallback(customizer, thisArg, 3)) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16820 | : baseClone(value, true); |
| 16821 | } |
| 16822 | |
| 16823 | module.exports = cloneDeep; |
| 16824 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16825 | },{"../internal/baseClone":68,"../internal/bindCallback":94}],139:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16826 | var isArrayLike = require('../internal/isArrayLike'), |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16827 | isObjectLike = require('../internal/isObjectLike'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16828 | |
| 16829 | /** Used for native method references. */ |
| 16830 | var objectProto = Object.prototype; |
| 16831 | |
| 16832 | /** Used to check objects for own properties. */ |
| 16833 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 16834 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16835 | /** Native method references. */ |
| 16836 | var propertyIsEnumerable = objectProto.propertyIsEnumerable; |
| 16837 | |
| 16838 | /** |
| 16839 | * Checks if `value` is classified as an `arguments` object. |
| 16840 | * |
| 16841 | * @static |
| 16842 | * @memberOf _ |
| 16843 | * @category Lang |
| 16844 | * @param {*} value The value to check. |
| 16845 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 16846 | * @example |
| 16847 | * |
| 16848 | * _.isArguments(function() { return arguments; }()); |
| 16849 | * // => true |
| 16850 | * |
| 16851 | * _.isArguments([1, 2, 3]); |
| 16852 | * // => false |
| 16853 | */ |
| 16854 | function isArguments(value) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16855 | return isObjectLike(value) && isArrayLike(value) && |
| 16856 | hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16857 | } |
| 16858 | |
| 16859 | module.exports = isArguments; |
| 16860 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16861 | },{"../internal/isArrayLike":119,"../internal/isObjectLike":126}],140:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16862 | var getNative = require('../internal/getNative'), |
| 16863 | isLength = require('../internal/isLength'), |
| 16864 | isObjectLike = require('../internal/isObjectLike'); |
| 16865 | |
| 16866 | /** `Object#toString` result references. */ |
| 16867 | var arrayTag = '[object Array]'; |
| 16868 | |
| 16869 | /** Used for native method references. */ |
| 16870 | var objectProto = Object.prototype; |
| 16871 | |
| 16872 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16873 | * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16874 | * of values. |
| 16875 | */ |
| 16876 | var objToString = objectProto.toString; |
| 16877 | |
| 16878 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 16879 | var nativeIsArray = getNative(Array, 'isArray'); |
| 16880 | |
| 16881 | /** |
| 16882 | * Checks if `value` is classified as an `Array` object. |
| 16883 | * |
| 16884 | * @static |
| 16885 | * @memberOf _ |
| 16886 | * @category Lang |
| 16887 | * @param {*} value The value to check. |
| 16888 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 16889 | * @example |
| 16890 | * |
| 16891 | * _.isArray([1, 2, 3]); |
| 16892 | * // => true |
| 16893 | * |
| 16894 | * _.isArray(function() { return arguments; }()); |
| 16895 | * // => false |
| 16896 | */ |
| 16897 | var isArray = nativeIsArray || function(value) { |
| 16898 | return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; |
| 16899 | }; |
| 16900 | |
| 16901 | module.exports = isArray; |
| 16902 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16903 | },{"../internal/getNative":114,"../internal/isLength":125,"../internal/isObjectLike":126}],141:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16904 | var isArguments = require('./isArguments'), |
| 16905 | isArray = require('./isArray'), |
| 16906 | isArrayLike = require('../internal/isArrayLike'), |
| 16907 | isFunction = require('./isFunction'), |
| 16908 | isObjectLike = require('../internal/isObjectLike'), |
| 16909 | isString = require('./isString'), |
| 16910 | keys = require('../object/keys'); |
| 16911 | |
| 16912 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16913 | * Checks if `value` is empty. A value is considered empty unless it's an |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16914 | * `arguments` object, array, string, or jQuery-like collection with a length |
| 16915 | * greater than `0` or an object with own enumerable properties. |
| 16916 | * |
| 16917 | * @static |
| 16918 | * @memberOf _ |
| 16919 | * @category Lang |
| 16920 | * @param {Array|Object|string} value The value to inspect. |
| 16921 | * @returns {boolean} Returns `true` if `value` is empty, else `false`. |
| 16922 | * @example |
| 16923 | * |
| 16924 | * _.isEmpty(null); |
| 16925 | * // => true |
| 16926 | * |
| 16927 | * _.isEmpty(true); |
| 16928 | * // => true |
| 16929 | * |
| 16930 | * _.isEmpty(1); |
| 16931 | * // => true |
| 16932 | * |
| 16933 | * _.isEmpty([1, 2, 3]); |
| 16934 | * // => false |
| 16935 | * |
| 16936 | * _.isEmpty({ 'a': 1 }); |
| 16937 | * // => false |
| 16938 | */ |
| 16939 | function isEmpty(value) { |
| 16940 | if (value == null) { |
| 16941 | return true; |
| 16942 | } |
| 16943 | if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || |
| 16944 | (isObjectLike(value) && isFunction(value.splice)))) { |
| 16945 | return !value.length; |
| 16946 | } |
| 16947 | return !keys(value).length; |
| 16948 | } |
| 16949 | |
| 16950 | module.exports = isEmpty; |
| 16951 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16952 | },{"../internal/isArrayLike":119,"../internal/isObjectLike":126,"../object/keys":149,"./isArguments":139,"./isArray":140,"./isFunction":142,"./isString":146}],142:[function(require,module,exports){ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16953 | var isObject = require('./isObject'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16954 | |
| 16955 | /** `Object#toString` result references. */ |
| 16956 | var funcTag = '[object Function]'; |
| 16957 | |
| 16958 | /** Used for native method references. */ |
| 16959 | var objectProto = Object.prototype; |
| 16960 | |
| 16961 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16962 | * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16963 | * of values. |
| 16964 | */ |
| 16965 | var objToString = objectProto.toString; |
| 16966 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16967 | /** |
| 16968 | * Checks if `value` is classified as a `Function` object. |
| 16969 | * |
| 16970 | * @static |
| 16971 | * @memberOf _ |
| 16972 | * @category Lang |
| 16973 | * @param {*} value The value to check. |
| 16974 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 16975 | * @example |
| 16976 | * |
| 16977 | * _.isFunction(_); |
| 16978 | * // => true |
| 16979 | * |
| 16980 | * _.isFunction(/abc/); |
| 16981 | * // => false |
| 16982 | */ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16983 | function isFunction(value) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16984 | // The use of `Object#toString` avoids issues with the `typeof` operator |
| 16985 | // in older versions of Chrome and Safari which return 'function' for regexes |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16986 | // and Safari 8 which returns 'object' for typed array constructors. |
| 16987 | return isObject(value) && objToString.call(value) == funcTag; |
| 16988 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16989 | |
| 16990 | module.exports = isFunction; |
| 16991 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 16992 | },{"./isObject":144}],143:[function(require,module,exports){ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 16993 | var isFunction = require('./isFunction'), |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16994 | isHostObject = require('../internal/isHostObject'), |
| 16995 | isObjectLike = require('../internal/isObjectLike'); |
| 16996 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 16997 | /** Used to detect host constructors (Safari > 5). */ |
| 16998 | var reIsHostCtor = /^\[object .+?Constructor\]$/; |
| 16999 | |
| 17000 | /** Used for native method references. */ |
| 17001 | var objectProto = Object.prototype; |
| 17002 | |
| 17003 | /** Used to resolve the decompiled source of functions. */ |
| 17004 | var fnToString = Function.prototype.toString; |
| 17005 | |
| 17006 | /** Used to check objects for own properties. */ |
| 17007 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 17008 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17009 | /** Used to detect if a method is native. */ |
| 17010 | var reIsNative = RegExp('^' + |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17011 | fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17012 | .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' |
| 17013 | ); |
| 17014 | |
| 17015 | /** |
| 17016 | * Checks if `value` is a native function. |
| 17017 | * |
| 17018 | * @static |
| 17019 | * @memberOf _ |
| 17020 | * @category Lang |
| 17021 | * @param {*} value The value to check. |
| 17022 | * @returns {boolean} Returns `true` if `value` is a native function, else `false`. |
| 17023 | * @example |
| 17024 | * |
| 17025 | * _.isNative(Array.prototype.push); |
| 17026 | * // => true |
| 17027 | * |
| 17028 | * _.isNative(_); |
| 17029 | * // => false |
| 17030 | */ |
| 17031 | function isNative(value) { |
| 17032 | if (value == null) { |
| 17033 | return false; |
| 17034 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17035 | if (isFunction(value)) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17036 | return reIsNative.test(fnToString.call(value)); |
| 17037 | } |
| 17038 | return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); |
| 17039 | } |
| 17040 | |
| 17041 | module.exports = isNative; |
| 17042 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17043 | },{"../internal/isHostObject":120,"../internal/isObjectLike":126,"./isFunction":142}],144:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17044 | /** |
| 17045 | * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. |
| 17046 | * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) |
| 17047 | * |
| 17048 | * @static |
| 17049 | * @memberOf _ |
| 17050 | * @category Lang |
| 17051 | * @param {*} value The value to check. |
| 17052 | * @returns {boolean} Returns `true` if `value` is an object, else `false`. |
| 17053 | * @example |
| 17054 | * |
| 17055 | * _.isObject({}); |
| 17056 | * // => true |
| 17057 | * |
| 17058 | * _.isObject([1, 2, 3]); |
| 17059 | * // => true |
| 17060 | * |
| 17061 | * _.isObject(1); |
| 17062 | * // => false |
| 17063 | */ |
| 17064 | function isObject(value) { |
| 17065 | // Avoid a V8 JIT bug in Chrome 19-20. |
| 17066 | // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. |
| 17067 | var type = typeof value; |
| 17068 | return !!value && (type == 'object' || type == 'function'); |
| 17069 | } |
| 17070 | |
| 17071 | module.exports = isObject; |
| 17072 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17073 | },{}],145:[function(require,module,exports){ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17074 | var baseForIn = require('../internal/baseForIn'), |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17075 | isArguments = require('./isArguments'), |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17076 | isHostObject = require('../internal/isHostObject'), |
| 17077 | isObjectLike = require('../internal/isObjectLike'), |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17078 | support = require('../support'); |
| 17079 | |
| 17080 | /** `Object#toString` result references. */ |
| 17081 | var objectTag = '[object Object]'; |
| 17082 | |
| 17083 | /** Used for native method references. */ |
| 17084 | var objectProto = Object.prototype; |
| 17085 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17086 | /** Used to check objects for own properties. */ |
| 17087 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 17088 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17089 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17090 | * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17091 | * of values. |
| 17092 | */ |
| 17093 | var objToString = objectProto.toString; |
| 17094 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17095 | /** |
| 17096 | * Checks if `value` is a plain object, that is, an object created by the |
| 17097 | * `Object` constructor or one with a `[[Prototype]]` of `null`. |
| 17098 | * |
| 17099 | * **Note:** This method assumes objects created by the `Object` constructor |
| 17100 | * have no inherited enumerable properties. |
| 17101 | * |
| 17102 | * @static |
| 17103 | * @memberOf _ |
| 17104 | * @category Lang |
| 17105 | * @param {*} value The value to check. |
| 17106 | * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
| 17107 | * @example |
| 17108 | * |
| 17109 | * function Foo() { |
| 17110 | * this.a = 1; |
| 17111 | * } |
| 17112 | * |
| 17113 | * _.isPlainObject(new Foo); |
| 17114 | * // => false |
| 17115 | * |
| 17116 | * _.isPlainObject([1, 2, 3]); |
| 17117 | * // => false |
| 17118 | * |
| 17119 | * _.isPlainObject({ 'x': 0, 'y': 0 }); |
| 17120 | * // => true |
| 17121 | * |
| 17122 | * _.isPlainObject(Object.create(null)); |
| 17123 | * // => true |
| 17124 | */ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17125 | function isPlainObject(value) { |
| 17126 | var Ctor; |
| 17127 | |
| 17128 | // Exit early for non `Object` objects. |
| 17129 | if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) || |
| 17130 | (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17131 | return false; |
| 17132 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17133 | // IE < 9 iterates inherited properties before own properties. If the first |
| 17134 | // iterated property is an object's own property then there are no inherited |
| 17135 | // enumerable properties. |
| 17136 | var result; |
| 17137 | if (support.ownLast) { |
| 17138 | baseForIn(value, function(subValue, key, object) { |
| 17139 | result = hasOwnProperty.call(object, key); |
| 17140 | return false; |
| 17141 | }); |
| 17142 | return result !== false; |
| 17143 | } |
| 17144 | // In most environments an object's own properties are iterated before |
| 17145 | // its inherited properties. If the last iterated property is an object's |
| 17146 | // own property then there are no inherited enumerable properties. |
| 17147 | baseForIn(value, function(subValue, key) { |
| 17148 | result = key; |
| 17149 | }); |
| 17150 | return result === undefined || hasOwnProperty.call(value, result); |
| 17151 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17152 | |
| 17153 | module.exports = isPlainObject; |
| 17154 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17155 | },{"../internal/baseForIn":75,"../internal/isHostObject":120,"../internal/isObjectLike":126,"../support":153,"./isArguments":139}],146:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17156 | var isObjectLike = require('../internal/isObjectLike'); |
| 17157 | |
| 17158 | /** `Object#toString` result references. */ |
| 17159 | var stringTag = '[object String]'; |
| 17160 | |
| 17161 | /** Used for native method references. */ |
| 17162 | var objectProto = Object.prototype; |
| 17163 | |
| 17164 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17165 | * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17166 | * of values. |
| 17167 | */ |
| 17168 | var objToString = objectProto.toString; |
| 17169 | |
| 17170 | /** |
| 17171 | * Checks if `value` is classified as a `String` primitive or object. |
| 17172 | * |
| 17173 | * @static |
| 17174 | * @memberOf _ |
| 17175 | * @category Lang |
| 17176 | * @param {*} value The value to check. |
| 17177 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 17178 | * @example |
| 17179 | * |
| 17180 | * _.isString('abc'); |
| 17181 | * // => true |
| 17182 | * |
| 17183 | * _.isString(1); |
| 17184 | * // => false |
| 17185 | */ |
| 17186 | function isString(value) { |
| 17187 | return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); |
| 17188 | } |
| 17189 | |
| 17190 | module.exports = isString; |
| 17191 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17192 | },{"../internal/isObjectLike":126}],147:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17193 | var isLength = require('../internal/isLength'), |
| 17194 | isObjectLike = require('../internal/isObjectLike'); |
| 17195 | |
| 17196 | /** `Object#toString` result references. */ |
| 17197 | var argsTag = '[object Arguments]', |
| 17198 | arrayTag = '[object Array]', |
| 17199 | boolTag = '[object Boolean]', |
| 17200 | dateTag = '[object Date]', |
| 17201 | errorTag = '[object Error]', |
| 17202 | funcTag = '[object Function]', |
| 17203 | mapTag = '[object Map]', |
| 17204 | numberTag = '[object Number]', |
| 17205 | objectTag = '[object Object]', |
| 17206 | regexpTag = '[object RegExp]', |
| 17207 | setTag = '[object Set]', |
| 17208 | stringTag = '[object String]', |
| 17209 | weakMapTag = '[object WeakMap]'; |
| 17210 | |
| 17211 | var arrayBufferTag = '[object ArrayBuffer]', |
| 17212 | float32Tag = '[object Float32Array]', |
| 17213 | float64Tag = '[object Float64Array]', |
| 17214 | int8Tag = '[object Int8Array]', |
| 17215 | int16Tag = '[object Int16Array]', |
| 17216 | int32Tag = '[object Int32Array]', |
| 17217 | uint8Tag = '[object Uint8Array]', |
| 17218 | uint8ClampedTag = '[object Uint8ClampedArray]', |
| 17219 | uint16Tag = '[object Uint16Array]', |
| 17220 | uint32Tag = '[object Uint32Array]'; |
| 17221 | |
| 17222 | /** Used to identify `toStringTag` values of typed arrays. */ |
| 17223 | var typedArrayTags = {}; |
| 17224 | typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = |
| 17225 | typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = |
| 17226 | typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = |
| 17227 | typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = |
| 17228 | typedArrayTags[uint32Tag] = true; |
| 17229 | typedArrayTags[argsTag] = typedArrayTags[arrayTag] = |
| 17230 | typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = |
| 17231 | typedArrayTags[dateTag] = typedArrayTags[errorTag] = |
| 17232 | typedArrayTags[funcTag] = typedArrayTags[mapTag] = |
| 17233 | typedArrayTags[numberTag] = typedArrayTags[objectTag] = |
| 17234 | typedArrayTags[regexpTag] = typedArrayTags[setTag] = |
| 17235 | typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; |
| 17236 | |
| 17237 | /** Used for native method references. */ |
| 17238 | var objectProto = Object.prototype; |
| 17239 | |
| 17240 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17241 | * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17242 | * of values. |
| 17243 | */ |
| 17244 | var objToString = objectProto.toString; |
| 17245 | |
| 17246 | /** |
| 17247 | * Checks if `value` is classified as a typed array. |
| 17248 | * |
| 17249 | * @static |
| 17250 | * @memberOf _ |
| 17251 | * @category Lang |
| 17252 | * @param {*} value The value to check. |
| 17253 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
| 17254 | * @example |
| 17255 | * |
| 17256 | * _.isTypedArray(new Uint8Array); |
| 17257 | * // => true |
| 17258 | * |
| 17259 | * _.isTypedArray([]); |
| 17260 | * // => false |
| 17261 | */ |
| 17262 | function isTypedArray(value) { |
| 17263 | return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; |
| 17264 | } |
| 17265 | |
| 17266 | module.exports = isTypedArray; |
| 17267 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17268 | },{"../internal/isLength":125,"../internal/isObjectLike":126}],148:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17269 | /** |
| 17270 | * Checks if `value` is `undefined`. |
| 17271 | * |
| 17272 | * @static |
| 17273 | * @memberOf _ |
| 17274 | * @category Lang |
| 17275 | * @param {*} value The value to check. |
| 17276 | * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. |
| 17277 | * @example |
| 17278 | * |
| 17279 | * _.isUndefined(void 0); |
| 17280 | * // => true |
| 17281 | * |
| 17282 | * _.isUndefined(null); |
| 17283 | * // => false |
| 17284 | */ |
| 17285 | function isUndefined(value) { |
| 17286 | return value === undefined; |
| 17287 | } |
| 17288 | |
| 17289 | module.exports = isUndefined; |
| 17290 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17291 | },{}],149:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17292 | var getNative = require('../internal/getNative'), |
| 17293 | isArrayLike = require('../internal/isArrayLike'), |
| 17294 | isObject = require('../lang/isObject'), |
| 17295 | shimKeys = require('../internal/shimKeys'), |
| 17296 | support = require('../support'); |
| 17297 | |
| 17298 | /* Native method references for those with the same name as other `lodash` methods. */ |
| 17299 | var nativeKeys = getNative(Object, 'keys'); |
| 17300 | |
| 17301 | /** |
| 17302 | * Creates an array of the own enumerable property names of `object`. |
| 17303 | * |
| 17304 | * **Note:** Non-object values are coerced to objects. See the |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17305 | * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17306 | * for more details. |
| 17307 | * |
| 17308 | * @static |
| 17309 | * @memberOf _ |
| 17310 | * @category Object |
| 17311 | * @param {Object} object The object to query. |
| 17312 | * @returns {Array} Returns the array of property names. |
| 17313 | * @example |
| 17314 | * |
| 17315 | * function Foo() { |
| 17316 | * this.a = 1; |
| 17317 | * this.b = 2; |
| 17318 | * } |
| 17319 | * |
| 17320 | * Foo.prototype.c = 3; |
| 17321 | * |
| 17322 | * _.keys(new Foo); |
| 17323 | * // => ['a', 'b'] (iteration order is not guaranteed) |
| 17324 | * |
| 17325 | * _.keys('hi'); |
| 17326 | * // => ['0', '1'] |
| 17327 | */ |
| 17328 | var keys = !nativeKeys ? shimKeys : function(object) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17329 | var Ctor = object == null ? undefined : object.constructor; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17330 | if ((typeof Ctor == 'function' && Ctor.prototype === object) || |
| 17331 | (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) { |
| 17332 | return shimKeys(object); |
| 17333 | } |
| 17334 | return isObject(object) ? nativeKeys(object) : []; |
| 17335 | }; |
| 17336 | |
| 17337 | module.exports = keys; |
| 17338 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17339 | },{"../internal/getNative":114,"../internal/isArrayLike":119,"../internal/shimKeys":134,"../lang/isObject":144,"../support":153}],150:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17340 | var arrayEach = require('../internal/arrayEach'), |
| 17341 | isArguments = require('../lang/isArguments'), |
| 17342 | isArray = require('../lang/isArray'), |
| 17343 | isFunction = require('../lang/isFunction'), |
| 17344 | isIndex = require('../internal/isIndex'), |
| 17345 | isLength = require('../internal/isLength'), |
| 17346 | isObject = require('../lang/isObject'), |
| 17347 | isString = require('../lang/isString'), |
| 17348 | support = require('../support'); |
| 17349 | |
| 17350 | /** `Object#toString` result references. */ |
| 17351 | var arrayTag = '[object Array]', |
| 17352 | boolTag = '[object Boolean]', |
| 17353 | dateTag = '[object Date]', |
| 17354 | errorTag = '[object Error]', |
| 17355 | funcTag = '[object Function]', |
| 17356 | numberTag = '[object Number]', |
| 17357 | objectTag = '[object Object]', |
| 17358 | regexpTag = '[object RegExp]', |
| 17359 | stringTag = '[object String]'; |
| 17360 | |
| 17361 | /** Used to fix the JScript `[[DontEnum]]` bug. */ |
| 17362 | var shadowProps = [ |
| 17363 | 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', |
| 17364 | 'toLocaleString', 'toString', 'valueOf' |
| 17365 | ]; |
| 17366 | |
| 17367 | /** Used for native method references. */ |
| 17368 | var errorProto = Error.prototype, |
| 17369 | objectProto = Object.prototype, |
| 17370 | stringProto = String.prototype; |
| 17371 | |
| 17372 | /** Used to check objects for own properties. */ |
| 17373 | var hasOwnProperty = objectProto.hasOwnProperty; |
| 17374 | |
| 17375 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17376 | * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17377 | * of values. |
| 17378 | */ |
| 17379 | var objToString = objectProto.toString; |
| 17380 | |
| 17381 | /** Used to avoid iterating over non-enumerable properties in IE < 9. */ |
| 17382 | var nonEnumProps = {}; |
| 17383 | nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; |
| 17384 | nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true }; |
| 17385 | nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true }; |
| 17386 | nonEnumProps[objectTag] = { 'constructor': true }; |
| 17387 | |
| 17388 | arrayEach(shadowProps, function(key) { |
| 17389 | for (var tag in nonEnumProps) { |
| 17390 | if (hasOwnProperty.call(nonEnumProps, tag)) { |
| 17391 | var props = nonEnumProps[tag]; |
| 17392 | props[key] = hasOwnProperty.call(props, key); |
| 17393 | } |
| 17394 | } |
| 17395 | }); |
| 17396 | |
| 17397 | /** |
| 17398 | * Creates an array of the own and inherited enumerable property names of `object`. |
| 17399 | * |
| 17400 | * **Note:** Non-object values are coerced to objects. |
| 17401 | * |
| 17402 | * @static |
| 17403 | * @memberOf _ |
| 17404 | * @category Object |
| 17405 | * @param {Object} object The object to query. |
| 17406 | * @returns {Array} Returns the array of property names. |
| 17407 | * @example |
| 17408 | * |
| 17409 | * function Foo() { |
| 17410 | * this.a = 1; |
| 17411 | * this.b = 2; |
| 17412 | * } |
| 17413 | * |
| 17414 | * Foo.prototype.c = 3; |
| 17415 | * |
| 17416 | * _.keysIn(new Foo); |
| 17417 | * // => ['a', 'b', 'c'] (iteration order is not guaranteed) |
| 17418 | */ |
| 17419 | function keysIn(object) { |
| 17420 | if (object == null) { |
| 17421 | return []; |
| 17422 | } |
| 17423 | if (!isObject(object)) { |
| 17424 | object = Object(object); |
| 17425 | } |
| 17426 | var length = object.length; |
| 17427 | |
| 17428 | length = (length && isLength(length) && |
| 17429 | (isArray(object) || isArguments(object) || isString(object)) && length) || 0; |
| 17430 | |
| 17431 | var Ctor = object.constructor, |
| 17432 | index = -1, |
| 17433 | proto = (isFunction(Ctor) && Ctor.prototype) || objectProto, |
| 17434 | isProto = proto === object, |
| 17435 | result = Array(length), |
| 17436 | skipIndexes = length > 0, |
| 17437 | skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error), |
| 17438 | skipProto = support.enumPrototypes && isFunction(object); |
| 17439 | |
| 17440 | while (++index < length) { |
| 17441 | result[index] = (index + ''); |
| 17442 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17443 | // lodash skips the `constructor` property when it infers it's iterating |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17444 | // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]` |
| 17445 | // attribute of an existing property and the `constructor` property of a |
| 17446 | // prototype defaults to non-enumerable. |
| 17447 | for (var key in object) { |
| 17448 | if (!(skipProto && key == 'prototype') && |
| 17449 | !(skipErrorProps && (key == 'message' || key == 'name')) && |
| 17450 | !(skipIndexes && isIndex(key, length)) && |
| 17451 | !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { |
| 17452 | result.push(key); |
| 17453 | } |
| 17454 | } |
| 17455 | if (support.nonEnumShadows && object !== objectProto) { |
| 17456 | var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)), |
| 17457 | nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag]; |
| 17458 | |
| 17459 | if (tag == objectTag) { |
| 17460 | proto = objectProto; |
| 17461 | } |
| 17462 | length = shadowProps.length; |
| 17463 | while (length--) { |
| 17464 | key = shadowProps[length]; |
| 17465 | var nonEnum = nonEnums[key]; |
| 17466 | if (!(isProto && nonEnum) && |
| 17467 | (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) { |
| 17468 | result.push(key); |
| 17469 | } |
| 17470 | } |
| 17471 | } |
| 17472 | return result; |
| 17473 | } |
| 17474 | |
| 17475 | module.exports = keysIn; |
| 17476 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17477 | },{"../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){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17478 | var keys = require('./keys'), |
| 17479 | toObject = require('../internal/toObject'); |
| 17480 | |
| 17481 | /** |
| 17482 | * Creates a two dimensional array of the key-value pairs for `object`, |
| 17483 | * e.g. `[[key1, value1], [key2, value2]]`. |
| 17484 | * |
| 17485 | * @static |
| 17486 | * @memberOf _ |
| 17487 | * @category Object |
| 17488 | * @param {Object} object The object to query. |
| 17489 | * @returns {Array} Returns the new array of key-value pairs. |
| 17490 | * @example |
| 17491 | * |
| 17492 | * _.pairs({ 'barney': 36, 'fred': 40 }); |
| 17493 | * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) |
| 17494 | */ |
| 17495 | function pairs(object) { |
| 17496 | object = toObject(object); |
| 17497 | |
| 17498 | var index = -1, |
| 17499 | props = keys(object), |
| 17500 | length = props.length, |
| 17501 | result = Array(length); |
| 17502 | |
| 17503 | while (++index < length) { |
| 17504 | var key = props[index]; |
| 17505 | result[index] = [key, object[key]]; |
| 17506 | } |
| 17507 | return result; |
| 17508 | } |
| 17509 | |
| 17510 | module.exports = pairs; |
| 17511 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17512 | },{"../internal/toObject":135,"./keys":149}],152:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17513 | var baseValues = require('../internal/baseValues'), |
| 17514 | keys = require('./keys'); |
| 17515 | |
| 17516 | /** |
| 17517 | * Creates an array of the own enumerable property values of `object`. |
| 17518 | * |
| 17519 | * **Note:** Non-object values are coerced to objects. |
| 17520 | * |
| 17521 | * @static |
| 17522 | * @memberOf _ |
| 17523 | * @category Object |
| 17524 | * @param {Object} object The object to query. |
| 17525 | * @returns {Array} Returns the array of property values. |
| 17526 | * @example |
| 17527 | * |
| 17528 | * function Foo() { |
| 17529 | * this.a = 1; |
| 17530 | * this.b = 2; |
| 17531 | * } |
| 17532 | * |
| 17533 | * Foo.prototype.c = 3; |
| 17534 | * |
| 17535 | * _.values(new Foo); |
| 17536 | * // => [1, 2] (iteration order is not guaranteed) |
| 17537 | * |
| 17538 | * _.values('hi'); |
| 17539 | * // => ['h', 'i'] |
| 17540 | */ |
| 17541 | function values(object) { |
| 17542 | return baseValues(object, keys(object)); |
| 17543 | } |
| 17544 | |
| 17545 | module.exports = values; |
| 17546 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17547 | },{"../internal/baseValues":91,"./keys":149}],153:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17548 | /** Used for native method references. */ |
| 17549 | var arrayProto = Array.prototype, |
| 17550 | errorProto = Error.prototype, |
| 17551 | objectProto = Object.prototype; |
| 17552 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17553 | /** Native method references. */ |
| 17554 | var propertyIsEnumerable = objectProto.propertyIsEnumerable, |
| 17555 | splice = arrayProto.splice; |
| 17556 | |
| 17557 | /** |
| 17558 | * An object environment feature flags. |
| 17559 | * |
| 17560 | * @static |
| 17561 | * @memberOf _ |
| 17562 | * @type Object |
| 17563 | */ |
| 17564 | var support = {}; |
| 17565 | |
| 17566 | (function(x) { |
| 17567 | var Ctor = function() { this.x = x; }, |
| 17568 | object = { '0': x, 'length': x }, |
| 17569 | props = []; |
| 17570 | |
| 17571 | Ctor.prototype = { 'valueOf': x, 'y': x }; |
| 17572 | for (var key in new Ctor) { props.push(key); } |
| 17573 | |
| 17574 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17575 | * Detect if `name` or `message` properties of `Error.prototype` are |
| 17576 | * enumerable by default (IE < 9, Safari < 5.1). |
| 17577 | * |
| 17578 | * @memberOf _.support |
| 17579 | * @type boolean |
| 17580 | */ |
| 17581 | support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || |
| 17582 | propertyIsEnumerable.call(errorProto, 'name'); |
| 17583 | |
| 17584 | /** |
| 17585 | * Detect if `prototype` properties are enumerable by default. |
| 17586 | * |
| 17587 | * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 |
| 17588 | * (if the prototype or a property on the prototype has been set) |
| 17589 | * incorrectly set the `[[Enumerable]]` value of a function's `prototype` |
| 17590 | * property to `true`. |
| 17591 | * |
| 17592 | * @memberOf _.support |
| 17593 | * @type boolean |
| 17594 | */ |
| 17595 | support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype'); |
| 17596 | |
| 17597 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17598 | * Detect if properties shadowing those on `Object.prototype` are non-enumerable. |
| 17599 | * |
| 17600 | * In IE < 9 an object's own properties, shadowing non-enumerable ones, |
| 17601 | * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug). |
| 17602 | * |
| 17603 | * @memberOf _.support |
| 17604 | * @type boolean |
| 17605 | */ |
| 17606 | support.nonEnumShadows = !/valueOf/.test(props); |
| 17607 | |
| 17608 | /** |
| 17609 | * Detect if own properties are iterated after inherited properties (IE < 9). |
| 17610 | * |
| 17611 | * @memberOf _.support |
| 17612 | * @type boolean |
| 17613 | */ |
| 17614 | support.ownLast = props[0] != 'x'; |
| 17615 | |
| 17616 | /** |
| 17617 | * Detect if `Array#shift` and `Array#splice` augment array-like objects |
| 17618 | * correctly. |
| 17619 | * |
| 17620 | * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array |
| 17621 | * `shift()` and `splice()` functions that fail to remove the last element, |
| 17622 | * `value[0]`, of array-like objects even though the "length" property is |
| 17623 | * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8, |
| 17624 | * while `splice()` is buggy regardless of mode in IE < 9. |
| 17625 | * |
| 17626 | * @memberOf _.support |
| 17627 | * @type boolean |
| 17628 | */ |
| 17629 | support.spliceObjects = (splice.call(object, 0, 1), !object[0]); |
| 17630 | |
| 17631 | /** |
| 17632 | * Detect lack of support for accessing string characters by index. |
| 17633 | * |
| 17634 | * IE < 8 can't access characters by index. IE 8 can only access characters |
| 17635 | * by index on string literals, not string objects. |
| 17636 | * |
| 17637 | * @memberOf _.support |
| 17638 | * @type boolean |
| 17639 | */ |
| 17640 | support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17641 | }(1, 0)); |
| 17642 | |
| 17643 | module.exports = support; |
| 17644 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17645 | },{}],154:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17646 | /** |
| 17647 | * This method returns the first argument provided to it. |
| 17648 | * |
| 17649 | * @static |
| 17650 | * @memberOf _ |
| 17651 | * @category Utility |
| 17652 | * @param {*} value Any value. |
| 17653 | * @returns {*} Returns `value`. |
| 17654 | * @example |
| 17655 | * |
| 17656 | * var object = { 'user': 'fred' }; |
| 17657 | * |
| 17658 | * _.identity(object) === object; |
| 17659 | * // => true |
| 17660 | */ |
| 17661 | function identity(value) { |
| 17662 | return value; |
| 17663 | } |
| 17664 | |
| 17665 | module.exports = identity; |
| 17666 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17667 | },{}],155:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17668 | /** |
| 17669 | * A no-operation function that returns `undefined` regardless of the |
| 17670 | * arguments it receives. |
| 17671 | * |
| 17672 | * @static |
| 17673 | * @memberOf _ |
| 17674 | * @category Utility |
| 17675 | * @example |
| 17676 | * |
| 17677 | * var object = { 'user': 'fred' }; |
| 17678 | * |
| 17679 | * _.noop(object) === undefined; |
| 17680 | * // => true |
| 17681 | */ |
| 17682 | function noop() { |
| 17683 | // No operation performed. |
| 17684 | } |
| 17685 | |
| 17686 | module.exports = noop; |
| 17687 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17688 | },{}],156:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 17689 | var baseProperty = require('../internal/baseProperty'), |
| 17690 | basePropertyDeep = require('../internal/basePropertyDeep'), |
| 17691 | isKey = require('../internal/isKey'); |
| 17692 | |
| 17693 | /** |
| 17694 | * Creates a function that returns the property value at `path` on a |
| 17695 | * given object. |
| 17696 | * |
| 17697 | * @static |
| 17698 | * @memberOf _ |
| 17699 | * @category Utility |
| 17700 | * @param {Array|string} path The path of the property to get. |
| 17701 | * @returns {Function} Returns the new function. |
| 17702 | * @example |
| 17703 | * |
| 17704 | * var objects = [ |
| 17705 | * { 'a': { 'b': { 'c': 2 } } }, |
| 17706 | * { 'a': { 'b': { 'c': 1 } } } |
| 17707 | * ]; |
| 17708 | * |
| 17709 | * _.map(objects, _.property('a.b.c')); |
| 17710 | * // => [2, 1] |
| 17711 | * |
| 17712 | * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); |
| 17713 | * // => [1, 2] |
| 17714 | */ |
| 17715 | function property(path) { |
| 17716 | return isKey(path) ? baseProperty(path) : basePropertyDeep(path); |
| 17717 | } |
| 17718 | |
| 17719 | module.exports = property; |
| 17720 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 17721 | },{"../internal/baseProperty":86,"../internal/basePropertyDeep":87,"../internal/isKey":123}],157:[function(require,module,exports){ |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 17722 | (function (process){ |
| 17723 | // vim:ts=4:sts=4:sw=4: |
| 17724 | /*! |
| 17725 | * |
| 17726 | * Copyright 2009-2012 Kris Kowal under the terms of the MIT |
| 17727 | * license found at http://github.com/kriskowal/q/raw/master/LICENSE |
| 17728 | * |
| 17729 | * With parts by Tyler Close |
| 17730 | * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found |
| 17731 | * at http://www.opensource.org/licenses/mit-license.html |
| 17732 | * Forked at ref_send.js version: 2009-05-11 |
| 17733 | * |
| 17734 | * With parts by Mark Miller |
| 17735 | * Copyright (C) 2011 Google Inc. |
| 17736 | * |
| 17737 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 17738 | * you may not use this file except in compliance with the License. |
| 17739 | * You may obtain a copy of the License at |
| 17740 | * |
| 17741 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 17742 | * |
| 17743 | * Unless required by applicable law or agreed to in writing, software |
| 17744 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 17745 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 17746 | * See the License for the specific language governing permissions and |
| 17747 | * limitations under the License. |
| 17748 | * |
| 17749 | */ |
| 17750 | |
| 17751 | (function (definition) { |
| 17752 | "use strict"; |
| 17753 | |
| 17754 | // This file will function properly as a <script> tag, or a module |
| 17755 | // using CommonJS and NodeJS or RequireJS module formats. In |
| 17756 | // Common/Node/RequireJS, the module exports the Q API and when |
| 17757 | // executed as a simple <script>, it creates a Q global instead. |
| 17758 | |
| 17759 | // Montage Require |
| 17760 | if (typeof bootstrap === "function") { |
| 17761 | bootstrap("promise", definition); |
| 17762 | |
| 17763 | // CommonJS |
| 17764 | } else if (typeof exports === "object" && typeof module === "object") { |
| 17765 | module.exports = definition(); |
| 17766 | |
| 17767 | // RequireJS |
| 17768 | } else if (typeof define === "function" && define.amd) { |
| 17769 | define(definition); |
| 17770 | |
| 17771 | // SES (Secure EcmaScript) |
| 17772 | } else if (typeof ses !== "undefined") { |
| 17773 | if (!ses.ok()) { |
| 17774 | return; |
| 17775 | } else { |
| 17776 | ses.makeQ = definition; |
| 17777 | } |
| 17778 | |
| 17779 | // <script> |
| 17780 | } else if (typeof window !== "undefined" || typeof self !== "undefined") { |
| 17781 | // Prefer window over self for add-on scripts. Use self for |
| 17782 | // non-windowed contexts. |
| 17783 | var global = typeof window !== "undefined" ? window : self; |
| 17784 | |
| 17785 | // Get the `window` object, save the previous Q global |
| 17786 | // and initialize Q as a global. |
| 17787 | var previousQ = global.Q; |
| 17788 | global.Q = definition(); |
| 17789 | |
| 17790 | // Add a noConflict function so Q can be removed from the |
| 17791 | // global namespace. |
| 17792 | global.Q.noConflict = function () { |
| 17793 | global.Q = previousQ; |
| 17794 | return this; |
| 17795 | }; |
| 17796 | |
| 17797 | } else { |
| 17798 | throw new Error("This environment was not anticipated by Q. Please file a bug."); |
| 17799 | } |
| 17800 | |
| 17801 | })(function () { |
| 17802 | "use strict"; |
| 17803 | |
| 17804 | var hasStacks = false; |
| 17805 | try { |
| 17806 | throw new Error(); |
| 17807 | } catch (e) { |
| 17808 | hasStacks = !!e.stack; |
| 17809 | } |
| 17810 | |
| 17811 | // All code after this point will be filtered from stack traces reported |
| 17812 | // by Q. |
| 17813 | var qStartingLine = captureLine(); |
| 17814 | var qFileName; |
| 17815 | |
| 17816 | // shims |
| 17817 | |
| 17818 | // used for fallback in "allResolved" |
| 17819 | var noop = function () {}; |
| 17820 | |
| 17821 | // Use the fastest possible means to execute a task in a future turn |
| 17822 | // of the event loop. |
| 17823 | var nextTick =(function () { |
| 17824 | // linked list of tasks (single, with head node) |
| 17825 | var head = {task: void 0, next: null}; |
| 17826 | var tail = head; |
| 17827 | var flushing = false; |
| 17828 | var requestTick = void 0; |
| 17829 | var isNodeJS = false; |
| 17830 | // queue for late tasks, used by unhandled rejection tracking |
| 17831 | var laterQueue = []; |
| 17832 | |
| 17833 | function flush() { |
| 17834 | /* jshint loopfunc: true */ |
| 17835 | var task, domain; |
| 17836 | |
| 17837 | while (head.next) { |
| 17838 | head = head.next; |
| 17839 | task = head.task; |
| 17840 | head.task = void 0; |
| 17841 | domain = head.domain; |
| 17842 | |
| 17843 | if (domain) { |
| 17844 | head.domain = void 0; |
| 17845 | domain.enter(); |
| 17846 | } |
| 17847 | runSingle(task, domain); |
| 17848 | |
| 17849 | } |
| 17850 | while (laterQueue.length) { |
| 17851 | task = laterQueue.pop(); |
| 17852 | runSingle(task); |
| 17853 | } |
| 17854 | flushing = false; |
| 17855 | } |
| 17856 | // runs a single function in the async queue |
| 17857 | function runSingle(task, domain) { |
| 17858 | try { |
| 17859 | task(); |
| 17860 | |
| 17861 | } catch (e) { |
| 17862 | if (isNodeJS) { |
| 17863 | // In node, uncaught exceptions are considered fatal errors. |
| 17864 | // Re-throw them synchronously to interrupt flushing! |
| 17865 | |
| 17866 | // Ensure continuation if the uncaught exception is suppressed |
| 17867 | // listening "uncaughtException" events (as domains does). |
| 17868 | // Continue in next event to avoid tick recursion. |
| 17869 | if (domain) { |
| 17870 | domain.exit(); |
| 17871 | } |
| 17872 | setTimeout(flush, 0); |
| 17873 | if (domain) { |
| 17874 | domain.enter(); |
| 17875 | } |
| 17876 | |
| 17877 | throw e; |
| 17878 | |
| 17879 | } else { |
| 17880 | // In browsers, uncaught exceptions are not fatal. |
| 17881 | // Re-throw them asynchronously to avoid slow-downs. |
| 17882 | setTimeout(function () { |
| 17883 | throw e; |
| 17884 | }, 0); |
| 17885 | } |
| 17886 | } |
| 17887 | |
| 17888 | if (domain) { |
| 17889 | domain.exit(); |
| 17890 | } |
| 17891 | } |
| 17892 | |
| 17893 | nextTick = function (task) { |
| 17894 | tail = tail.next = { |
| 17895 | task: task, |
| 17896 | domain: isNodeJS && process.domain, |
| 17897 | next: null |
| 17898 | }; |
| 17899 | |
| 17900 | if (!flushing) { |
| 17901 | flushing = true; |
| 17902 | requestTick(); |
| 17903 | } |
| 17904 | }; |
| 17905 | |
| 17906 | if (typeof process === "object" && |
| 17907 | process.toString() === "[object process]" && process.nextTick) { |
| 17908 | // Ensure Q is in a real Node environment, with a `process.nextTick`. |
| 17909 | // To see through fake Node environments: |
| 17910 | // * Mocha test runner - exposes a `process` global without a `nextTick` |
| 17911 | // * Browserify - exposes a `process.nexTick` function that uses |
| 17912 | // `setTimeout`. In this case `setImmediate` is preferred because |
| 17913 | // it is faster. Browserify's `process.toString()` yields |
| 17914 | // "[object Object]", while in a real Node environment |
| 17915 | // `process.nextTick()` yields "[object process]". |
| 17916 | isNodeJS = true; |
| 17917 | |
| 17918 | requestTick = function () { |
| 17919 | process.nextTick(flush); |
| 17920 | }; |
| 17921 | |
| 17922 | } else if (typeof setImmediate === "function") { |
| 17923 | // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate |
| 17924 | if (typeof window !== "undefined") { |
| 17925 | requestTick = setImmediate.bind(window, flush); |
| 17926 | } else { |
| 17927 | requestTick = function () { |
| 17928 | setImmediate(flush); |
| 17929 | }; |
| 17930 | } |
| 17931 | |
| 17932 | } else if (typeof MessageChannel !== "undefined") { |
| 17933 | // modern browsers |
| 17934 | // http://www.nonblocking.io/2011/06/windownexttick.html |
| 17935 | var channel = new MessageChannel(); |
| 17936 | // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create |
| 17937 | // working message ports the first time a page loads. |
| 17938 | channel.port1.onmessage = function () { |
| 17939 | requestTick = requestPortTick; |
| 17940 | channel.port1.onmessage = flush; |
| 17941 | flush(); |
| 17942 | }; |
| 17943 | var requestPortTick = function () { |
| 17944 | // Opera requires us to provide a message payload, regardless of |
| 17945 | // whether we use it. |
| 17946 | channel.port2.postMessage(0); |
| 17947 | }; |
| 17948 | requestTick = function () { |
| 17949 | setTimeout(flush, 0); |
| 17950 | requestPortTick(); |
| 17951 | }; |
| 17952 | |
| 17953 | } else { |
| 17954 | // old browsers |
| 17955 | requestTick = function () { |
| 17956 | setTimeout(flush, 0); |
| 17957 | }; |
| 17958 | } |
| 17959 | // runs a task after all other tasks have been run |
| 17960 | // this is useful for unhandled rejection tracking that needs to happen |
| 17961 | // after all `then`d tasks have been run. |
| 17962 | nextTick.runAfter = function (task) { |
| 17963 | laterQueue.push(task); |
| 17964 | if (!flushing) { |
| 17965 | flushing = true; |
| 17966 | requestTick(); |
| 17967 | } |
| 17968 | }; |
| 17969 | return nextTick; |
| 17970 | })(); |
| 17971 | |
| 17972 | // Attempt to make generics safe in the face of downstream |
| 17973 | // modifications. |
| 17974 | // There is no situation where this is necessary. |
| 17975 | // If you need a security guarantee, these primordials need to be |
| 17976 | // deeply frozen anyway, and if you don’t need a security guarantee, |
| 17977 | // this is just plain paranoid. |
| 17978 | // However, this **might** have the nice side-effect of reducing the size of |
| 17979 | // the minified code by reducing x.call() to merely x() |
| 17980 | // See Mark Miller’s explanation of what this does. |
| 17981 | // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming |
| 17982 | var call = Function.call; |
| 17983 | function uncurryThis(f) { |
| 17984 | return function () { |
| 17985 | return call.apply(f, arguments); |
| 17986 | }; |
| 17987 | } |
| 17988 | // This is equivalent, but slower: |
| 17989 | // uncurryThis = Function_bind.bind(Function_bind.call); |
| 17990 | // http://jsperf.com/uncurrythis |
| 17991 | |
| 17992 | var array_slice = uncurryThis(Array.prototype.slice); |
| 17993 | |
| 17994 | var array_reduce = uncurryThis( |
| 17995 | Array.prototype.reduce || function (callback, basis) { |
| 17996 | var index = 0, |
| 17997 | length = this.length; |
| 17998 | // concerning the initial value, if one is not provided |
| 17999 | if (arguments.length === 1) { |
| 18000 | // seek to the first value in the array, accounting |
| 18001 | // for the possibility that is is a sparse array |
| 18002 | do { |
| 18003 | if (index in this) { |
| 18004 | basis = this[index++]; |
| 18005 | break; |
| 18006 | } |
| 18007 | if (++index >= length) { |
| 18008 | throw new TypeError(); |
| 18009 | } |
| 18010 | } while (1); |
| 18011 | } |
| 18012 | // reduce |
| 18013 | for (; index < length; index++) { |
| 18014 | // account for the possibility that the array is sparse |
| 18015 | if (index in this) { |
| 18016 | basis = callback(basis, this[index], index); |
| 18017 | } |
| 18018 | } |
| 18019 | return basis; |
| 18020 | } |
| 18021 | ); |
| 18022 | |
| 18023 | var array_indexOf = uncurryThis( |
| 18024 | Array.prototype.indexOf || function (value) { |
| 18025 | // not a very good shim, but good enough for our one use of it |
| 18026 | for (var i = 0; i < this.length; i++) { |
| 18027 | if (this[i] === value) { |
| 18028 | return i; |
| 18029 | } |
| 18030 | } |
| 18031 | return -1; |
| 18032 | } |
| 18033 | ); |
| 18034 | |
| 18035 | var array_map = uncurryThis( |
| 18036 | Array.prototype.map || function (callback, thisp) { |
| 18037 | var self = this; |
| 18038 | var collect = []; |
| 18039 | array_reduce(self, function (undefined, value, index) { |
| 18040 | collect.push(callback.call(thisp, value, index, self)); |
| 18041 | }, void 0); |
| 18042 | return collect; |
| 18043 | } |
| 18044 | ); |
| 18045 | |
| 18046 | var object_create = Object.create || function (prototype) { |
| 18047 | function Type() { } |
| 18048 | Type.prototype = prototype; |
| 18049 | return new Type(); |
| 18050 | }; |
| 18051 | |
| 18052 | var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty); |
| 18053 | |
| 18054 | var object_keys = Object.keys || function (object) { |
| 18055 | var keys = []; |
| 18056 | for (var key in object) { |
| 18057 | if (object_hasOwnProperty(object, key)) { |
| 18058 | keys.push(key); |
| 18059 | } |
| 18060 | } |
| 18061 | return keys; |
| 18062 | }; |
| 18063 | |
| 18064 | var object_toString = uncurryThis(Object.prototype.toString); |
| 18065 | |
| 18066 | function isObject(value) { |
| 18067 | return value === Object(value); |
| 18068 | } |
| 18069 | |
| 18070 | // generator related shims |
| 18071 | |
| 18072 | // FIXME: Remove this function once ES6 generators are in SpiderMonkey. |
| 18073 | function isStopIteration(exception) { |
| 18074 | return ( |
| 18075 | object_toString(exception) === "[object StopIteration]" || |
| 18076 | exception instanceof QReturnValue |
| 18077 | ); |
| 18078 | } |
| 18079 | |
| 18080 | // FIXME: Remove this helper and Q.return once ES6 generators are in |
| 18081 | // SpiderMonkey. |
| 18082 | var QReturnValue; |
| 18083 | if (typeof ReturnValue !== "undefined") { |
| 18084 | QReturnValue = ReturnValue; |
| 18085 | } else { |
| 18086 | QReturnValue = function (value) { |
| 18087 | this.value = value; |
| 18088 | }; |
| 18089 | } |
| 18090 | |
| 18091 | // long stack traces |
| 18092 | |
| 18093 | var STACK_JUMP_SEPARATOR = "From previous event:"; |
| 18094 | |
| 18095 | function makeStackTraceLong(error, promise) { |
| 18096 | // If possible, transform the error stack trace by removing Node and Q |
| 18097 | // cruft, then concatenating with the stack trace of `promise`. See #57. |
| 18098 | if (hasStacks && |
| 18099 | promise.stack && |
| 18100 | typeof error === "object" && |
| 18101 | error !== null && |
| 18102 | error.stack && |
| 18103 | error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1 |
| 18104 | ) { |
| 18105 | var stacks = []; |
| 18106 | for (var p = promise; !!p; p = p.source) { |
| 18107 | if (p.stack) { |
| 18108 | stacks.unshift(p.stack); |
| 18109 | } |
| 18110 | } |
| 18111 | stacks.unshift(error.stack); |
| 18112 | |
| 18113 | var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n"); |
| 18114 | error.stack = filterStackString(concatedStacks); |
| 18115 | } |
| 18116 | } |
| 18117 | |
| 18118 | function filterStackString(stackString) { |
| 18119 | var lines = stackString.split("\n"); |
| 18120 | var desiredLines = []; |
| 18121 | for (var i = 0; i < lines.length; ++i) { |
| 18122 | var line = lines[i]; |
| 18123 | |
| 18124 | if (!isInternalFrame(line) && !isNodeFrame(line) && line) { |
| 18125 | desiredLines.push(line); |
| 18126 | } |
| 18127 | } |
| 18128 | return desiredLines.join("\n"); |
| 18129 | } |
| 18130 | |
| 18131 | function isNodeFrame(stackLine) { |
| 18132 | return stackLine.indexOf("(module.js:") !== -1 || |
| 18133 | stackLine.indexOf("(node.js:") !== -1; |
| 18134 | } |
| 18135 | |
| 18136 | function getFileNameAndLineNumber(stackLine) { |
| 18137 | // Named functions: "at functionName (filename:lineNumber:columnNumber)" |
| 18138 | // In IE10 function name can have spaces ("Anonymous function") O_o |
| 18139 | var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine); |
| 18140 | if (attempt1) { |
| 18141 | return [attempt1[1], Number(attempt1[2])]; |
| 18142 | } |
| 18143 | |
| 18144 | // Anonymous functions: "at filename:lineNumber:columnNumber" |
| 18145 | var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine); |
| 18146 | if (attempt2) { |
| 18147 | return [attempt2[1], Number(attempt2[2])]; |
| 18148 | } |
| 18149 | |
| 18150 | // Firefox style: "function@filename:lineNumber or @filename:lineNumber" |
| 18151 | var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine); |
| 18152 | if (attempt3) { |
| 18153 | return [attempt3[1], Number(attempt3[2])]; |
| 18154 | } |
| 18155 | } |
| 18156 | |
| 18157 | function isInternalFrame(stackLine) { |
| 18158 | var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine); |
| 18159 | |
| 18160 | if (!fileNameAndLineNumber) { |
| 18161 | return false; |
| 18162 | } |
| 18163 | |
| 18164 | var fileName = fileNameAndLineNumber[0]; |
| 18165 | var lineNumber = fileNameAndLineNumber[1]; |
| 18166 | |
| 18167 | return fileName === qFileName && |
| 18168 | lineNumber >= qStartingLine && |
| 18169 | lineNumber <= qEndingLine; |
| 18170 | } |
| 18171 | |
| 18172 | // discover own file name and line number range for filtering stack |
| 18173 | // traces |
| 18174 | function captureLine() { |
| 18175 | if (!hasStacks) { |
| 18176 | return; |
| 18177 | } |
| 18178 | |
| 18179 | try { |
| 18180 | throw new Error(); |
| 18181 | } catch (e) { |
| 18182 | var lines = e.stack.split("\n"); |
| 18183 | var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2]; |
| 18184 | var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine); |
| 18185 | if (!fileNameAndLineNumber) { |
| 18186 | return; |
| 18187 | } |
| 18188 | |
| 18189 | qFileName = fileNameAndLineNumber[0]; |
| 18190 | return fileNameAndLineNumber[1]; |
| 18191 | } |
| 18192 | } |
| 18193 | |
| 18194 | function deprecate(callback, name, alternative) { |
| 18195 | return function () { |
| 18196 | if (typeof console !== "undefined" && |
| 18197 | typeof console.warn === "function") { |
| 18198 | console.warn(name + " is deprecated, use " + alternative + |
| 18199 | " instead.", new Error("").stack); |
| 18200 | } |
| 18201 | return callback.apply(callback, arguments); |
| 18202 | }; |
| 18203 | } |
| 18204 | |
| 18205 | // end of shims |
| 18206 | // beginning of real work |
| 18207 | |
| 18208 | /** |
| 18209 | * Constructs a promise for an immediate reference, passes promises through, or |
| 18210 | * coerces promises from different systems. |
| 18211 | * @param value immediate reference or promise |
| 18212 | */ |
| 18213 | function Q(value) { |
| 18214 | // If the object is already a Promise, return it directly. This enables |
| 18215 | // the resolve function to both be used to created references from objects, |
| 18216 | // but to tolerably coerce non-promises to promises. |
| 18217 | if (value instanceof Promise) { |
| 18218 | return value; |
| 18219 | } |
| 18220 | |
| 18221 | // assimilate thenables |
| 18222 | if (isPromiseAlike(value)) { |
| 18223 | return coerce(value); |
| 18224 | } else { |
| 18225 | return fulfill(value); |
| 18226 | } |
| 18227 | } |
| 18228 | Q.resolve = Q; |
| 18229 | |
| 18230 | /** |
| 18231 | * Performs a task in a future turn of the event loop. |
| 18232 | * @param {Function} task |
| 18233 | */ |
| 18234 | Q.nextTick = nextTick; |
| 18235 | |
| 18236 | /** |
| 18237 | * Controls whether or not long stack traces will be on |
| 18238 | */ |
| 18239 | Q.longStackSupport = false; |
| 18240 | |
| 18241 | // enable long stacks if Q_DEBUG is set |
| 18242 | if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) { |
| 18243 | Q.longStackSupport = true; |
| 18244 | } |
| 18245 | |
| 18246 | /** |
| 18247 | * Constructs a {promise, resolve, reject} object. |
| 18248 | * |
| 18249 | * `resolve` is a callback to invoke with a more resolved value for the |
| 18250 | * promise. To fulfill the promise, invoke `resolve` with any value that is |
| 18251 | * not a thenable. To reject the promise, invoke `resolve` with a rejected |
| 18252 | * thenable, or invoke `reject` with the reason directly. To resolve the |
| 18253 | * promise to another thenable, thus putting it in the same state, invoke |
| 18254 | * `resolve` with that other thenable. |
| 18255 | */ |
| 18256 | Q.defer = defer; |
| 18257 | function defer() { |
| 18258 | // if "messages" is an "Array", that indicates that the promise has not yet |
| 18259 | // been resolved. If it is "undefined", it has been resolved. Each |
| 18260 | // element of the messages array is itself an array of complete arguments to |
| 18261 | // forward to the resolved promise. We coerce the resolution value to a |
| 18262 | // promise using the `resolve` function because it handles both fully |
| 18263 | // non-thenable values and other thenables gracefully. |
| 18264 | var messages = [], progressListeners = [], resolvedPromise; |
| 18265 | |
| 18266 | var deferred = object_create(defer.prototype); |
| 18267 | var promise = object_create(Promise.prototype); |
| 18268 | |
| 18269 | promise.promiseDispatch = function (resolve, op, operands) { |
| 18270 | var args = array_slice(arguments); |
| 18271 | if (messages) { |
| 18272 | messages.push(args); |
| 18273 | if (op === "when" && operands[1]) { // progress operand |
| 18274 | progressListeners.push(operands[1]); |
| 18275 | } |
| 18276 | } else { |
| 18277 | Q.nextTick(function () { |
| 18278 | resolvedPromise.promiseDispatch.apply(resolvedPromise, args); |
| 18279 | }); |
| 18280 | } |
| 18281 | }; |
| 18282 | |
| 18283 | // XXX deprecated |
| 18284 | promise.valueOf = function () { |
| 18285 | if (messages) { |
| 18286 | return promise; |
| 18287 | } |
| 18288 | var nearerValue = nearer(resolvedPromise); |
| 18289 | if (isPromise(nearerValue)) { |
| 18290 | resolvedPromise = nearerValue; // shorten chain |
| 18291 | } |
| 18292 | return nearerValue; |
| 18293 | }; |
| 18294 | |
| 18295 | promise.inspect = function () { |
| 18296 | if (!resolvedPromise) { |
| 18297 | return { state: "pending" }; |
| 18298 | } |
| 18299 | return resolvedPromise.inspect(); |
| 18300 | }; |
| 18301 | |
| 18302 | if (Q.longStackSupport && hasStacks) { |
| 18303 | try { |
| 18304 | throw new Error(); |
| 18305 | } catch (e) { |
| 18306 | // NOTE: don't try to use `Error.captureStackTrace` or transfer the |
| 18307 | // accessor around; that causes memory leaks as per GH-111. Just |
| 18308 | // reify the stack trace as a string ASAP. |
| 18309 | // |
| 18310 | // At the same time, cut off the first line; it's always just |
| 18311 | // "[object Promise]\n", as per the `toString`. |
| 18312 | promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1); |
| 18313 | } |
| 18314 | } |
| 18315 | |
| 18316 | // NOTE: we do the checks for `resolvedPromise` in each method, instead of |
| 18317 | // consolidating them into `become`, since otherwise we'd create new |
| 18318 | // promises with the lines `become(whatever(value))`. See e.g. GH-252. |
| 18319 | |
| 18320 | function become(newPromise) { |
| 18321 | resolvedPromise = newPromise; |
| 18322 | promise.source = newPromise; |
| 18323 | |
| 18324 | array_reduce(messages, function (undefined, message) { |
| 18325 | Q.nextTick(function () { |
| 18326 | newPromise.promiseDispatch.apply(newPromise, message); |
| 18327 | }); |
| 18328 | }, void 0); |
| 18329 | |
| 18330 | messages = void 0; |
| 18331 | progressListeners = void 0; |
| 18332 | } |
| 18333 | |
| 18334 | deferred.promise = promise; |
| 18335 | deferred.resolve = function (value) { |
| 18336 | if (resolvedPromise) { |
| 18337 | return; |
| 18338 | } |
| 18339 | |
| 18340 | become(Q(value)); |
| 18341 | }; |
| 18342 | |
| 18343 | deferred.fulfill = function (value) { |
| 18344 | if (resolvedPromise) { |
| 18345 | return; |
| 18346 | } |
| 18347 | |
| 18348 | become(fulfill(value)); |
| 18349 | }; |
| 18350 | deferred.reject = function (reason) { |
| 18351 | if (resolvedPromise) { |
| 18352 | return; |
| 18353 | } |
| 18354 | |
| 18355 | become(reject(reason)); |
| 18356 | }; |
| 18357 | deferred.notify = function (progress) { |
| 18358 | if (resolvedPromise) { |
| 18359 | return; |
| 18360 | } |
| 18361 | |
| 18362 | array_reduce(progressListeners, function (undefined, progressListener) { |
| 18363 | Q.nextTick(function () { |
| 18364 | progressListener(progress); |
| 18365 | }); |
| 18366 | }, void 0); |
| 18367 | }; |
| 18368 | |
| 18369 | return deferred; |
| 18370 | } |
| 18371 | |
| 18372 | /** |
| 18373 | * Creates a Node-style callback that will resolve or reject the deferred |
| 18374 | * promise. |
| 18375 | * @returns a nodeback |
| 18376 | */ |
| 18377 | defer.prototype.makeNodeResolver = function () { |
| 18378 | var self = this; |
| 18379 | return function (error, value) { |
| 18380 | if (error) { |
| 18381 | self.reject(error); |
| 18382 | } else if (arguments.length > 2) { |
| 18383 | self.resolve(array_slice(arguments, 1)); |
| 18384 | } else { |
| 18385 | self.resolve(value); |
| 18386 | } |
| 18387 | }; |
| 18388 | }; |
| 18389 | |
| 18390 | /** |
| 18391 | * @param resolver {Function} a function that returns nothing and accepts |
| 18392 | * the resolve, reject, and notify functions for a deferred. |
| 18393 | * @returns a promise that may be resolved with the given resolve and reject |
| 18394 | * functions, or rejected by a thrown exception in resolver |
| 18395 | */ |
| 18396 | Q.Promise = promise; // ES6 |
| 18397 | Q.promise = promise; |
| 18398 | function promise(resolver) { |
| 18399 | if (typeof resolver !== "function") { |
| 18400 | throw new TypeError("resolver must be a function."); |
| 18401 | } |
| 18402 | var deferred = defer(); |
| 18403 | try { |
| 18404 | resolver(deferred.resolve, deferred.reject, deferred.notify); |
| 18405 | } catch (reason) { |
| 18406 | deferred.reject(reason); |
| 18407 | } |
| 18408 | return deferred.promise; |
| 18409 | } |
| 18410 | |
| 18411 | promise.race = race; // ES6 |
| 18412 | promise.all = all; // ES6 |
| 18413 | promise.reject = reject; // ES6 |
| 18414 | promise.resolve = Q; // ES6 |
| 18415 | |
| 18416 | // XXX experimental. This method is a way to denote that a local value is |
| 18417 | // serializable and should be immediately dispatched to a remote upon request, |
| 18418 | // instead of passing a reference. |
| 18419 | Q.passByCopy = function (object) { |
| 18420 | //freeze(object); |
| 18421 | //passByCopies.set(object, true); |
| 18422 | return object; |
| 18423 | }; |
| 18424 | |
| 18425 | Promise.prototype.passByCopy = function () { |
| 18426 | //freeze(object); |
| 18427 | //passByCopies.set(object, true); |
| 18428 | return this; |
| 18429 | }; |
| 18430 | |
| 18431 | /** |
| 18432 | * If two promises eventually fulfill to the same value, promises that value, |
| 18433 | * but otherwise rejects. |
| 18434 | * @param x {Any*} |
| 18435 | * @param y {Any*} |
| 18436 | * @returns {Any*} a promise for x and y if they are the same, but a rejection |
| 18437 | * otherwise. |
| 18438 | * |
| 18439 | */ |
| 18440 | Q.join = function (x, y) { |
| 18441 | return Q(x).join(y); |
| 18442 | }; |
| 18443 | |
| 18444 | Promise.prototype.join = function (that) { |
| 18445 | return Q([this, that]).spread(function (x, y) { |
| 18446 | if (x === y) { |
| 18447 | // TODO: "===" should be Object.is or equiv |
| 18448 | return x; |
| 18449 | } else { |
| 18450 | throw new Error("Can't join: not the same: " + x + " " + y); |
| 18451 | } |
| 18452 | }); |
| 18453 | }; |
| 18454 | |
| 18455 | /** |
| 18456 | * Returns a promise for the first of an array of promises to become settled. |
| 18457 | * @param answers {Array[Any*]} promises to race |
| 18458 | * @returns {Any*} the first promise to be settled |
| 18459 | */ |
| 18460 | Q.race = race; |
| 18461 | function race(answerPs) { |
| 18462 | return promise(function (resolve, reject) { |
| 18463 | // Switch to this once we can assume at least ES5 |
| 18464 | // answerPs.forEach(function (answerP) { |
| 18465 | // Q(answerP).then(resolve, reject); |
| 18466 | // }); |
| 18467 | // Use this in the meantime |
| 18468 | for (var i = 0, len = answerPs.length; i < len; i++) { |
| 18469 | Q(answerPs[i]).then(resolve, reject); |
| 18470 | } |
| 18471 | }); |
| 18472 | } |
| 18473 | |
| 18474 | Promise.prototype.race = function () { |
| 18475 | return this.then(Q.race); |
| 18476 | }; |
| 18477 | |
| 18478 | /** |
| 18479 | * Constructs a Promise with a promise descriptor object and optional fallback |
| 18480 | * function. The descriptor contains methods like when(rejected), get(name), |
| 18481 | * set(name, value), post(name, args), and delete(name), which all |
| 18482 | * return either a value, a promise for a value, or a rejection. The fallback |
| 18483 | * accepts the operation name, a resolver, and any further arguments that would |
| 18484 | * have been forwarded to the appropriate method above had a method been |
| 18485 | * provided with the proper name. The API makes no guarantees about the nature |
| 18486 | * of the returned object, apart from that it is usable whereever promises are |
| 18487 | * bought and sold. |
| 18488 | */ |
| 18489 | Q.makePromise = Promise; |
| 18490 | function Promise(descriptor, fallback, inspect) { |
| 18491 | if (fallback === void 0) { |
| 18492 | fallback = function (op) { |
| 18493 | return reject(new Error( |
| 18494 | "Promise does not support operation: " + op |
| 18495 | )); |
| 18496 | }; |
| 18497 | } |
| 18498 | if (inspect === void 0) { |
| 18499 | inspect = function () { |
| 18500 | return {state: "unknown"}; |
| 18501 | }; |
| 18502 | } |
| 18503 | |
| 18504 | var promise = object_create(Promise.prototype); |
| 18505 | |
| 18506 | promise.promiseDispatch = function (resolve, op, args) { |
| 18507 | var result; |
| 18508 | try { |
| 18509 | if (descriptor[op]) { |
| 18510 | result = descriptor[op].apply(promise, args); |
| 18511 | } else { |
| 18512 | result = fallback.call(promise, op, args); |
| 18513 | } |
| 18514 | } catch (exception) { |
| 18515 | result = reject(exception); |
| 18516 | } |
| 18517 | if (resolve) { |
| 18518 | resolve(result); |
| 18519 | } |
| 18520 | }; |
| 18521 | |
| 18522 | promise.inspect = inspect; |
| 18523 | |
| 18524 | // XXX deprecated `valueOf` and `exception` support |
| 18525 | if (inspect) { |
| 18526 | var inspected = inspect(); |
| 18527 | if (inspected.state === "rejected") { |
| 18528 | promise.exception = inspected.reason; |
| 18529 | } |
| 18530 | |
| 18531 | promise.valueOf = function () { |
| 18532 | var inspected = inspect(); |
| 18533 | if (inspected.state === "pending" || |
| 18534 | inspected.state === "rejected") { |
| 18535 | return promise; |
| 18536 | } |
| 18537 | return inspected.value; |
| 18538 | }; |
| 18539 | } |
| 18540 | |
| 18541 | return promise; |
| 18542 | } |
| 18543 | |
| 18544 | Promise.prototype.toString = function () { |
| 18545 | return "[object Promise]"; |
| 18546 | }; |
| 18547 | |
| 18548 | Promise.prototype.then = function (fulfilled, rejected, progressed) { |
| 18549 | var self = this; |
| 18550 | var deferred = defer(); |
| 18551 | var done = false; // ensure the untrusted promise makes at most a |
| 18552 | // single call to one of the callbacks |
| 18553 | |
| 18554 | function _fulfilled(value) { |
| 18555 | try { |
| 18556 | return typeof fulfilled === "function" ? fulfilled(value) : value; |
| 18557 | } catch (exception) { |
| 18558 | return reject(exception); |
| 18559 | } |
| 18560 | } |
| 18561 | |
| 18562 | function _rejected(exception) { |
| 18563 | if (typeof rejected === "function") { |
| 18564 | makeStackTraceLong(exception, self); |
| 18565 | try { |
| 18566 | return rejected(exception); |
| 18567 | } catch (newException) { |
| 18568 | return reject(newException); |
| 18569 | } |
| 18570 | } |
| 18571 | return reject(exception); |
| 18572 | } |
| 18573 | |
| 18574 | function _progressed(value) { |
| 18575 | return typeof progressed === "function" ? progressed(value) : value; |
| 18576 | } |
| 18577 | |
| 18578 | Q.nextTick(function () { |
| 18579 | self.promiseDispatch(function (value) { |
| 18580 | if (done) { |
| 18581 | return; |
| 18582 | } |
| 18583 | done = true; |
| 18584 | |
| 18585 | deferred.resolve(_fulfilled(value)); |
| 18586 | }, "when", [function (exception) { |
| 18587 | if (done) { |
| 18588 | return; |
| 18589 | } |
| 18590 | done = true; |
| 18591 | |
| 18592 | deferred.resolve(_rejected(exception)); |
| 18593 | }]); |
| 18594 | }); |
| 18595 | |
| 18596 | // Progress propagator need to be attached in the current tick. |
| 18597 | self.promiseDispatch(void 0, "when", [void 0, function (value) { |
| 18598 | var newValue; |
| 18599 | var threw = false; |
| 18600 | try { |
| 18601 | newValue = _progressed(value); |
| 18602 | } catch (e) { |
| 18603 | threw = true; |
| 18604 | if (Q.onerror) { |
| 18605 | Q.onerror(e); |
| 18606 | } else { |
| 18607 | throw e; |
| 18608 | } |
| 18609 | } |
| 18610 | |
| 18611 | if (!threw) { |
| 18612 | deferred.notify(newValue); |
| 18613 | } |
| 18614 | }]); |
| 18615 | |
| 18616 | return deferred.promise; |
| 18617 | }; |
| 18618 | |
| 18619 | Q.tap = function (promise, callback) { |
| 18620 | return Q(promise).tap(callback); |
| 18621 | }; |
| 18622 | |
| 18623 | /** |
| 18624 | * Works almost like "finally", but not called for rejections. |
| 18625 | * Original resolution value is passed through callback unaffected. |
| 18626 | * Callback may return a promise that will be awaited for. |
| 18627 | * @param {Function} callback |
| 18628 | * @returns {Q.Promise} |
| 18629 | * @example |
| 18630 | * doSomething() |
| 18631 | * .then(...) |
| 18632 | * .tap(console.log) |
| 18633 | * .then(...); |
| 18634 | */ |
| 18635 | Promise.prototype.tap = function (callback) { |
| 18636 | callback = Q(callback); |
| 18637 | |
| 18638 | return this.then(function (value) { |
| 18639 | return callback.fcall(value).thenResolve(value); |
| 18640 | }); |
| 18641 | }; |
| 18642 | |
| 18643 | /** |
| 18644 | * Registers an observer on a promise. |
| 18645 | * |
| 18646 | * Guarantees: |
| 18647 | * |
| 18648 | * 1. that fulfilled and rejected will be called only once. |
| 18649 | * 2. that either the fulfilled callback or the rejected callback will be |
| 18650 | * called, but not both. |
| 18651 | * 3. that fulfilled and rejected will not be called in this turn. |
| 18652 | * |
| 18653 | * @param value promise or immediate reference to observe |
| 18654 | * @param fulfilled function to be called with the fulfilled value |
| 18655 | * @param rejected function to be called with the rejection exception |
| 18656 | * @param progressed function to be called on any progress notifications |
| 18657 | * @return promise for the return value from the invoked callback |
| 18658 | */ |
| 18659 | Q.when = when; |
| 18660 | function when(value, fulfilled, rejected, progressed) { |
| 18661 | return Q(value).then(fulfilled, rejected, progressed); |
| 18662 | } |
| 18663 | |
| 18664 | Promise.prototype.thenResolve = function (value) { |
| 18665 | return this.then(function () { return value; }); |
| 18666 | }; |
| 18667 | |
| 18668 | Q.thenResolve = function (promise, value) { |
| 18669 | return Q(promise).thenResolve(value); |
| 18670 | }; |
| 18671 | |
| 18672 | Promise.prototype.thenReject = function (reason) { |
| 18673 | return this.then(function () { throw reason; }); |
| 18674 | }; |
| 18675 | |
| 18676 | Q.thenReject = function (promise, reason) { |
| 18677 | return Q(promise).thenReject(reason); |
| 18678 | }; |
| 18679 | |
| 18680 | /** |
| 18681 | * If an object is not a promise, it is as "near" as possible. |
| 18682 | * If a promise is rejected, it is as "near" as possible too. |
| 18683 | * If it’s a fulfilled promise, the fulfillment value is nearer. |
| 18684 | * If it’s a deferred promise and the deferred has been resolved, the |
| 18685 | * resolution is "nearer". |
| 18686 | * @param object |
| 18687 | * @returns most resolved (nearest) form of the object |
| 18688 | */ |
| 18689 | |
| 18690 | // XXX should we re-do this? |
| 18691 | Q.nearer = nearer; |
| 18692 | function nearer(value) { |
| 18693 | if (isPromise(value)) { |
| 18694 | var inspected = value.inspect(); |
| 18695 | if (inspected.state === "fulfilled") { |
| 18696 | return inspected.value; |
| 18697 | } |
| 18698 | } |
| 18699 | return value; |
| 18700 | } |
| 18701 | |
| 18702 | /** |
| 18703 | * @returns whether the given object is a promise. |
| 18704 | * Otherwise it is a fulfilled value. |
| 18705 | */ |
| 18706 | Q.isPromise = isPromise; |
| 18707 | function isPromise(object) { |
| 18708 | return object instanceof Promise; |
| 18709 | } |
| 18710 | |
| 18711 | Q.isPromiseAlike = isPromiseAlike; |
| 18712 | function isPromiseAlike(object) { |
| 18713 | return isObject(object) && typeof object.then === "function"; |
| 18714 | } |
| 18715 | |
| 18716 | /** |
| 18717 | * @returns whether the given object is a pending promise, meaning not |
| 18718 | * fulfilled or rejected. |
| 18719 | */ |
| 18720 | Q.isPending = isPending; |
| 18721 | function isPending(object) { |
| 18722 | return isPromise(object) && object.inspect().state === "pending"; |
| 18723 | } |
| 18724 | |
| 18725 | Promise.prototype.isPending = function () { |
| 18726 | return this.inspect().state === "pending"; |
| 18727 | }; |
| 18728 | |
| 18729 | /** |
| 18730 | * @returns whether the given object is a value or fulfilled |
| 18731 | * promise. |
| 18732 | */ |
| 18733 | Q.isFulfilled = isFulfilled; |
| 18734 | function isFulfilled(object) { |
| 18735 | return !isPromise(object) || object.inspect().state === "fulfilled"; |
| 18736 | } |
| 18737 | |
| 18738 | Promise.prototype.isFulfilled = function () { |
| 18739 | return this.inspect().state === "fulfilled"; |
| 18740 | }; |
| 18741 | |
| 18742 | /** |
| 18743 | * @returns whether the given object is a rejected promise. |
| 18744 | */ |
| 18745 | Q.isRejected = isRejected; |
| 18746 | function isRejected(object) { |
| 18747 | return isPromise(object) && object.inspect().state === "rejected"; |
| 18748 | } |
| 18749 | |
| 18750 | Promise.prototype.isRejected = function () { |
| 18751 | return this.inspect().state === "rejected"; |
| 18752 | }; |
| 18753 | |
| 18754 | //// BEGIN UNHANDLED REJECTION TRACKING |
| 18755 | |
| 18756 | // This promise library consumes exceptions thrown in handlers so they can be |
| 18757 | // handled by a subsequent promise. The exceptions get added to this array when |
| 18758 | // they are created, and removed when they are handled. Note that in ES6 or |
| 18759 | // shimmed environments, this would naturally be a `Set`. |
| 18760 | var unhandledReasons = []; |
| 18761 | var unhandledRejections = []; |
| 18762 | var reportedUnhandledRejections = []; |
| 18763 | var trackUnhandledRejections = true; |
| 18764 | |
| 18765 | function resetUnhandledRejections() { |
| 18766 | unhandledReasons.length = 0; |
| 18767 | unhandledRejections.length = 0; |
| 18768 | |
| 18769 | if (!trackUnhandledRejections) { |
| 18770 | trackUnhandledRejections = true; |
| 18771 | } |
| 18772 | } |
| 18773 | |
| 18774 | function trackRejection(promise, reason) { |
| 18775 | if (!trackUnhandledRejections) { |
| 18776 | return; |
| 18777 | } |
| 18778 | if (typeof process === "object" && typeof process.emit === "function") { |
| 18779 | Q.nextTick.runAfter(function () { |
| 18780 | if (array_indexOf(unhandledRejections, promise) !== -1) { |
| 18781 | process.emit("unhandledRejection", reason, promise); |
| 18782 | reportedUnhandledRejections.push(promise); |
| 18783 | } |
| 18784 | }); |
| 18785 | } |
| 18786 | |
| 18787 | unhandledRejections.push(promise); |
| 18788 | if (reason && typeof reason.stack !== "undefined") { |
| 18789 | unhandledReasons.push(reason.stack); |
| 18790 | } else { |
| 18791 | unhandledReasons.push("(no stack) " + reason); |
| 18792 | } |
| 18793 | } |
| 18794 | |
| 18795 | function untrackRejection(promise) { |
| 18796 | if (!trackUnhandledRejections) { |
| 18797 | return; |
| 18798 | } |
| 18799 | |
| 18800 | var at = array_indexOf(unhandledRejections, promise); |
| 18801 | if (at !== -1) { |
| 18802 | if (typeof process === "object" && typeof process.emit === "function") { |
| 18803 | Q.nextTick.runAfter(function () { |
| 18804 | var atReport = array_indexOf(reportedUnhandledRejections, promise); |
| 18805 | if (atReport !== -1) { |
| 18806 | process.emit("rejectionHandled", unhandledReasons[at], promise); |
| 18807 | reportedUnhandledRejections.splice(atReport, 1); |
| 18808 | } |
| 18809 | }); |
| 18810 | } |
| 18811 | unhandledRejections.splice(at, 1); |
| 18812 | unhandledReasons.splice(at, 1); |
| 18813 | } |
| 18814 | } |
| 18815 | |
| 18816 | Q.resetUnhandledRejections = resetUnhandledRejections; |
| 18817 | |
| 18818 | Q.getUnhandledReasons = function () { |
| 18819 | // Make a copy so that consumers can't interfere with our internal state. |
| 18820 | return unhandledReasons.slice(); |
| 18821 | }; |
| 18822 | |
| 18823 | Q.stopUnhandledRejectionTracking = function () { |
| 18824 | resetUnhandledRejections(); |
| 18825 | trackUnhandledRejections = false; |
| 18826 | }; |
| 18827 | |
| 18828 | resetUnhandledRejections(); |
| 18829 | |
| 18830 | //// END UNHANDLED REJECTION TRACKING |
| 18831 | |
| 18832 | /** |
| 18833 | * Constructs a rejected promise. |
| 18834 | * @param reason value describing the failure |
| 18835 | */ |
| 18836 | Q.reject = reject; |
| 18837 | function reject(reason) { |
| 18838 | var rejection = Promise({ |
| 18839 | "when": function (rejected) { |
| 18840 | // note that the error has been handled |
| 18841 | if (rejected) { |
| 18842 | untrackRejection(this); |
| 18843 | } |
| 18844 | return rejected ? rejected(reason) : this; |
| 18845 | } |
| 18846 | }, function fallback() { |
| 18847 | return this; |
| 18848 | }, function inspect() { |
| 18849 | return { state: "rejected", reason: reason }; |
| 18850 | }); |
| 18851 | |
| 18852 | // Note that the reason has not been handled. |
| 18853 | trackRejection(rejection, reason); |
| 18854 | |
| 18855 | return rejection; |
| 18856 | } |
| 18857 | |
| 18858 | /** |
| 18859 | * Constructs a fulfilled promise for an immediate reference. |
| 18860 | * @param value immediate reference |
| 18861 | */ |
| 18862 | Q.fulfill = fulfill; |
| 18863 | function fulfill(value) { |
| 18864 | return Promise({ |
| 18865 | "when": function () { |
| 18866 | return value; |
| 18867 | }, |
| 18868 | "get": function (name) { |
| 18869 | return value[name]; |
| 18870 | }, |
| 18871 | "set": function (name, rhs) { |
| 18872 | value[name] = rhs; |
| 18873 | }, |
| 18874 | "delete": function (name) { |
| 18875 | delete value[name]; |
| 18876 | }, |
| 18877 | "post": function (name, args) { |
| 18878 | // Mark Miller proposes that post with no name should apply a |
| 18879 | // promised function. |
| 18880 | if (name === null || name === void 0) { |
| 18881 | return value.apply(void 0, args); |
| 18882 | } else { |
| 18883 | return value[name].apply(value, args); |
| 18884 | } |
| 18885 | }, |
| 18886 | "apply": function (thisp, args) { |
| 18887 | return value.apply(thisp, args); |
| 18888 | }, |
| 18889 | "keys": function () { |
| 18890 | return object_keys(value); |
| 18891 | } |
| 18892 | }, void 0, function inspect() { |
| 18893 | return { state: "fulfilled", value: value }; |
| 18894 | }); |
| 18895 | } |
| 18896 | |
| 18897 | /** |
| 18898 | * Converts thenables to Q promises. |
| 18899 | * @param promise thenable promise |
| 18900 | * @returns a Q promise |
| 18901 | */ |
| 18902 | function coerce(promise) { |
| 18903 | var deferred = defer(); |
| 18904 | Q.nextTick(function () { |
| 18905 | try { |
| 18906 | promise.then(deferred.resolve, deferred.reject, deferred.notify); |
| 18907 | } catch (exception) { |
| 18908 | deferred.reject(exception); |
| 18909 | } |
| 18910 | }); |
| 18911 | return deferred.promise; |
| 18912 | } |
| 18913 | |
| 18914 | /** |
| 18915 | * Annotates an object such that it will never be |
| 18916 | * transferred away from this process over any promise |
| 18917 | * communication channel. |
| 18918 | * @param object |
| 18919 | * @returns promise a wrapping of that object that |
| 18920 | * additionally responds to the "isDef" message |
| 18921 | * without a rejection. |
| 18922 | */ |
| 18923 | Q.master = master; |
| 18924 | function master(object) { |
| 18925 | return Promise({ |
| 18926 | "isDef": function () {} |
| 18927 | }, function fallback(op, args) { |
| 18928 | return dispatch(object, op, args); |
| 18929 | }, function () { |
| 18930 | return Q(object).inspect(); |
| 18931 | }); |
| 18932 | } |
| 18933 | |
| 18934 | /** |
| 18935 | * Spreads the values of a promised array of arguments into the |
| 18936 | * fulfillment callback. |
| 18937 | * @param fulfilled callback that receives variadic arguments from the |
| 18938 | * promised array |
| 18939 | * @param rejected callback that receives the exception if the promise |
| 18940 | * is rejected. |
| 18941 | * @returns a promise for the return value or thrown exception of |
| 18942 | * either callback. |
| 18943 | */ |
| 18944 | Q.spread = spread; |
| 18945 | function spread(value, fulfilled, rejected) { |
| 18946 | return Q(value).spread(fulfilled, rejected); |
| 18947 | } |
| 18948 | |
| 18949 | Promise.prototype.spread = function (fulfilled, rejected) { |
| 18950 | return this.all().then(function (array) { |
| 18951 | return fulfilled.apply(void 0, array); |
| 18952 | }, rejected); |
| 18953 | }; |
| 18954 | |
| 18955 | /** |
| 18956 | * The async function is a decorator for generator functions, turning |
| 18957 | * them into asynchronous generators. Although generators are only part |
| 18958 | * of the newest ECMAScript 6 drafts, this code does not cause syntax |
| 18959 | * errors in older engines. This code should continue to work and will |
| 18960 | * in fact improve over time as the language improves. |
| 18961 | * |
| 18962 | * ES6 generators are currently part of V8 version 3.19 with the |
| 18963 | * --harmony-generators runtime flag enabled. SpiderMonkey has had them |
| 18964 | * for longer, but under an older Python-inspired form. This function |
| 18965 | * works on both kinds of generators. |
| 18966 | * |
| 18967 | * Decorates a generator function such that: |
| 18968 | * - it may yield promises |
| 18969 | * - execution will continue when that promise is fulfilled |
| 18970 | * - the value of the yield expression will be the fulfilled value |
| 18971 | * - it returns a promise for the return value (when the generator |
| 18972 | * stops iterating) |
| 18973 | * - the decorated function returns a promise for the return value |
| 18974 | * of the generator or the first rejected promise among those |
| 18975 | * yielded. |
| 18976 | * - if an error is thrown in the generator, it propagates through |
| 18977 | * every following yield until it is caught, or until it escapes |
| 18978 | * the generator function altogether, and is translated into a |
| 18979 | * rejection for the promise returned by the decorated generator. |
| 18980 | */ |
| 18981 | Q.async = async; |
| 18982 | function async(makeGenerator) { |
| 18983 | return function () { |
| 18984 | // when verb is "send", arg is a value |
| 18985 | // when verb is "throw", arg is an exception |
| 18986 | function continuer(verb, arg) { |
| 18987 | var result; |
| 18988 | |
| 18989 | // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only |
| 18990 | // engine that has a deployed base of browsers that support generators. |
| 18991 | // However, SM's generators use the Python-inspired semantics of |
| 18992 | // outdated ES6 drafts. We would like to support ES6, but we'd also |
| 18993 | // like to make it possible to use generators in deployed browsers, so |
| 18994 | // we also support Python-style generators. At some point we can remove |
| 18995 | // this block. |
| 18996 | |
| 18997 | if (typeof StopIteration === "undefined") { |
| 18998 | // ES6 Generators |
| 18999 | try { |
| 19000 | result = generator[verb](arg); |
| 19001 | } catch (exception) { |
| 19002 | return reject(exception); |
| 19003 | } |
| 19004 | if (result.done) { |
| 19005 | return Q(result.value); |
| 19006 | } else { |
| 19007 | return when(result.value, callback, errback); |
| 19008 | } |
| 19009 | } else { |
| 19010 | // SpiderMonkey Generators |
| 19011 | // FIXME: Remove this case when SM does ES6 generators. |
| 19012 | try { |
| 19013 | result = generator[verb](arg); |
| 19014 | } catch (exception) { |
| 19015 | if (isStopIteration(exception)) { |
| 19016 | return Q(exception.value); |
| 19017 | } else { |
| 19018 | return reject(exception); |
| 19019 | } |
| 19020 | } |
| 19021 | return when(result, callback, errback); |
| 19022 | } |
| 19023 | } |
| 19024 | var generator = makeGenerator.apply(this, arguments); |
| 19025 | var callback = continuer.bind(continuer, "next"); |
| 19026 | var errback = continuer.bind(continuer, "throw"); |
| 19027 | return callback(); |
| 19028 | }; |
| 19029 | } |
| 19030 | |
| 19031 | /** |
| 19032 | * The spawn function is a small wrapper around async that immediately |
| 19033 | * calls the generator and also ends the promise chain, so that any |
| 19034 | * unhandled errors are thrown instead of forwarded to the error |
| 19035 | * handler. This is useful because it's extremely common to run |
| 19036 | * generators at the top-level to work with libraries. |
| 19037 | */ |
| 19038 | Q.spawn = spawn; |
| 19039 | function spawn(makeGenerator) { |
| 19040 | Q.done(Q.async(makeGenerator)()); |
| 19041 | } |
| 19042 | |
| 19043 | // FIXME: Remove this interface once ES6 generators are in SpiderMonkey. |
| 19044 | /** |
| 19045 | * Throws a ReturnValue exception to stop an asynchronous generator. |
| 19046 | * |
| 19047 | * This interface is a stop-gap measure to support generator return |
| 19048 | * values in older Firefox/SpiderMonkey. In browsers that support ES6 |
| 19049 | * generators like Chromium 29, just use "return" in your generator |
| 19050 | * functions. |
| 19051 | * |
| 19052 | * @param value the return value for the surrounding generator |
| 19053 | * @throws ReturnValue exception with the value. |
| 19054 | * @example |
| 19055 | * // ES6 style |
| 19056 | * Q.async(function* () { |
| 19057 | * var foo = yield getFooPromise(); |
| 19058 | * var bar = yield getBarPromise(); |
| 19059 | * return foo + bar; |
| 19060 | * }) |
| 19061 | * // Older SpiderMonkey style |
| 19062 | * Q.async(function () { |
| 19063 | * var foo = yield getFooPromise(); |
| 19064 | * var bar = yield getBarPromise(); |
| 19065 | * Q.return(foo + bar); |
| 19066 | * }) |
| 19067 | */ |
| 19068 | Q["return"] = _return; |
| 19069 | function _return(value) { |
| 19070 | throw new QReturnValue(value); |
| 19071 | } |
| 19072 | |
| 19073 | /** |
| 19074 | * The promised function decorator ensures that any promise arguments |
| 19075 | * are settled and passed as values (`this` is also settled and passed |
| 19076 | * as a value). It will also ensure that the result of a function is |
| 19077 | * always a promise. |
| 19078 | * |
| 19079 | * @example |
| 19080 | * var add = Q.promised(function (a, b) { |
| 19081 | * return a + b; |
| 19082 | * }); |
| 19083 | * add(Q(a), Q(B)); |
| 19084 | * |
| 19085 | * @param {function} callback The function to decorate |
| 19086 | * @returns {function} a function that has been decorated. |
| 19087 | */ |
| 19088 | Q.promised = promised; |
| 19089 | function promised(callback) { |
| 19090 | return function () { |
| 19091 | return spread([this, all(arguments)], function (self, args) { |
| 19092 | return callback.apply(self, args); |
| 19093 | }); |
| 19094 | }; |
| 19095 | } |
| 19096 | |
| 19097 | /** |
| 19098 | * sends a message to a value in a future turn |
| 19099 | * @param object* the recipient |
| 19100 | * @param op the name of the message operation, e.g., "when", |
| 19101 | * @param args further arguments to be forwarded to the operation |
| 19102 | * @returns result {Promise} a promise for the result of the operation |
| 19103 | */ |
| 19104 | Q.dispatch = dispatch; |
| 19105 | function dispatch(object, op, args) { |
| 19106 | return Q(object).dispatch(op, args); |
| 19107 | } |
| 19108 | |
| 19109 | Promise.prototype.dispatch = function (op, args) { |
| 19110 | var self = this; |
| 19111 | var deferred = defer(); |
| 19112 | Q.nextTick(function () { |
| 19113 | self.promiseDispatch(deferred.resolve, op, args); |
| 19114 | }); |
| 19115 | return deferred.promise; |
| 19116 | }; |
| 19117 | |
| 19118 | /** |
| 19119 | * Gets the value of a property in a future turn. |
| 19120 | * @param object promise or immediate reference for target object |
| 19121 | * @param name name of property to get |
| 19122 | * @return promise for the property value |
| 19123 | */ |
| 19124 | Q.get = function (object, key) { |
| 19125 | return Q(object).dispatch("get", [key]); |
| 19126 | }; |
| 19127 | |
| 19128 | Promise.prototype.get = function (key) { |
| 19129 | return this.dispatch("get", [key]); |
| 19130 | }; |
| 19131 | |
| 19132 | /** |
| 19133 | * Sets the value of a property in a future turn. |
| 19134 | * @param object promise or immediate reference for object object |
| 19135 | * @param name name of property to set |
| 19136 | * @param value new value of property |
| 19137 | * @return promise for the return value |
| 19138 | */ |
| 19139 | Q.set = function (object, key, value) { |
| 19140 | return Q(object).dispatch("set", [key, value]); |
| 19141 | }; |
| 19142 | |
| 19143 | Promise.prototype.set = function (key, value) { |
| 19144 | return this.dispatch("set", [key, value]); |
| 19145 | }; |
| 19146 | |
| 19147 | /** |
| 19148 | * Deletes a property in a future turn. |
| 19149 | * @param object promise or immediate reference for target object |
| 19150 | * @param name name of property to delete |
| 19151 | * @return promise for the return value |
| 19152 | */ |
| 19153 | Q.del = // XXX legacy |
| 19154 | Q["delete"] = function (object, key) { |
| 19155 | return Q(object).dispatch("delete", [key]); |
| 19156 | }; |
| 19157 | |
| 19158 | Promise.prototype.del = // XXX legacy |
| 19159 | Promise.prototype["delete"] = function (key) { |
| 19160 | return this.dispatch("delete", [key]); |
| 19161 | }; |
| 19162 | |
| 19163 | /** |
| 19164 | * Invokes a method in a future turn. |
| 19165 | * @param object promise or immediate reference for target object |
| 19166 | * @param name name of method to invoke |
| 19167 | * @param value a value to post, typically an array of |
| 19168 | * invocation arguments for promises that |
| 19169 | * are ultimately backed with `resolve` values, |
| 19170 | * as opposed to those backed with URLs |
| 19171 | * wherein the posted value can be any |
| 19172 | * JSON serializable object. |
| 19173 | * @return promise for the return value |
| 19174 | */ |
| 19175 | // bound locally because it is used by other methods |
| 19176 | Q.mapply = // XXX As proposed by "Redsandro" |
| 19177 | Q.post = function (object, name, args) { |
| 19178 | return Q(object).dispatch("post", [name, args]); |
| 19179 | }; |
| 19180 | |
| 19181 | Promise.prototype.mapply = // XXX As proposed by "Redsandro" |
| 19182 | Promise.prototype.post = function (name, args) { |
| 19183 | return this.dispatch("post", [name, args]); |
| 19184 | }; |
| 19185 | |
| 19186 | /** |
| 19187 | * Invokes a method in a future turn. |
| 19188 | * @param object promise or immediate reference for target object |
| 19189 | * @param name name of method to invoke |
| 19190 | * @param ...args array of invocation arguments |
| 19191 | * @return promise for the return value |
| 19192 | */ |
| 19193 | Q.send = // XXX Mark Miller's proposed parlance |
| 19194 | Q.mcall = // XXX As proposed by "Redsandro" |
| 19195 | Q.invoke = function (object, name /*...args*/) { |
| 19196 | return Q(object).dispatch("post", [name, array_slice(arguments, 2)]); |
| 19197 | }; |
| 19198 | |
| 19199 | Promise.prototype.send = // XXX Mark Miller's proposed parlance |
| 19200 | Promise.prototype.mcall = // XXX As proposed by "Redsandro" |
| 19201 | Promise.prototype.invoke = function (name /*...args*/) { |
| 19202 | return this.dispatch("post", [name, array_slice(arguments, 1)]); |
| 19203 | }; |
| 19204 | |
| 19205 | /** |
| 19206 | * Applies the promised function in a future turn. |
| 19207 | * @param object promise or immediate reference for target function |
| 19208 | * @param args array of application arguments |
| 19209 | */ |
| 19210 | Q.fapply = function (object, args) { |
| 19211 | return Q(object).dispatch("apply", [void 0, args]); |
| 19212 | }; |
| 19213 | |
| 19214 | Promise.prototype.fapply = function (args) { |
| 19215 | return this.dispatch("apply", [void 0, args]); |
| 19216 | }; |
| 19217 | |
| 19218 | /** |
| 19219 | * Calls the promised function in a future turn. |
| 19220 | * @param object promise or immediate reference for target function |
| 19221 | * @param ...args array of application arguments |
| 19222 | */ |
| 19223 | Q["try"] = |
| 19224 | Q.fcall = function (object /* ...args*/) { |
| 19225 | return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]); |
| 19226 | }; |
| 19227 | |
| 19228 | Promise.prototype.fcall = function (/*...args*/) { |
| 19229 | return this.dispatch("apply", [void 0, array_slice(arguments)]); |
| 19230 | }; |
| 19231 | |
| 19232 | /** |
| 19233 | * Binds the promised function, transforming return values into a fulfilled |
| 19234 | * promise and thrown errors into a rejected one. |
| 19235 | * @param object promise or immediate reference for target function |
| 19236 | * @param ...args array of application arguments |
| 19237 | */ |
| 19238 | Q.fbind = function (object /*...args*/) { |
| 19239 | var promise = Q(object); |
| 19240 | var args = array_slice(arguments, 1); |
| 19241 | return function fbound() { |
| 19242 | return promise.dispatch("apply", [ |
| 19243 | this, |
| 19244 | args.concat(array_slice(arguments)) |
| 19245 | ]); |
| 19246 | }; |
| 19247 | }; |
| 19248 | Promise.prototype.fbind = function (/*...args*/) { |
| 19249 | var promise = this; |
| 19250 | var args = array_slice(arguments); |
| 19251 | return function fbound() { |
| 19252 | return promise.dispatch("apply", [ |
| 19253 | this, |
| 19254 | args.concat(array_slice(arguments)) |
| 19255 | ]); |
| 19256 | }; |
| 19257 | }; |
| 19258 | |
| 19259 | /** |
| 19260 | * Requests the names of the owned properties of a promised |
| 19261 | * object in a future turn. |
| 19262 | * @param object promise or immediate reference for target object |
| 19263 | * @return promise for the keys of the eventually settled object |
| 19264 | */ |
| 19265 | Q.keys = function (object) { |
| 19266 | return Q(object).dispatch("keys", []); |
| 19267 | }; |
| 19268 | |
| 19269 | Promise.prototype.keys = function () { |
| 19270 | return this.dispatch("keys", []); |
| 19271 | }; |
| 19272 | |
| 19273 | /** |
| 19274 | * Turns an array of promises into a promise for an array. If any of |
| 19275 | * the promises gets rejected, the whole array is rejected immediately. |
| 19276 | * @param {Array*} an array (or promise for an array) of values (or |
| 19277 | * promises for values) |
| 19278 | * @returns a promise for an array of the corresponding values |
| 19279 | */ |
| 19280 | // By Mark Miller |
| 19281 | // http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled |
| 19282 | Q.all = all; |
| 19283 | function all(promises) { |
| 19284 | return when(promises, function (promises) { |
| 19285 | var pendingCount = 0; |
| 19286 | var deferred = defer(); |
| 19287 | array_reduce(promises, function (undefined, promise, index) { |
| 19288 | var snapshot; |
| 19289 | if ( |
| 19290 | isPromise(promise) && |
| 19291 | (snapshot = promise.inspect()).state === "fulfilled" |
| 19292 | ) { |
| 19293 | promises[index] = snapshot.value; |
| 19294 | } else { |
| 19295 | ++pendingCount; |
| 19296 | when( |
| 19297 | promise, |
| 19298 | function (value) { |
| 19299 | promises[index] = value; |
| 19300 | if (--pendingCount === 0) { |
| 19301 | deferred.resolve(promises); |
| 19302 | } |
| 19303 | }, |
| 19304 | deferred.reject, |
| 19305 | function (progress) { |
| 19306 | deferred.notify({ index: index, value: progress }); |
| 19307 | } |
| 19308 | ); |
| 19309 | } |
| 19310 | }, void 0); |
| 19311 | if (pendingCount === 0) { |
| 19312 | deferred.resolve(promises); |
| 19313 | } |
| 19314 | return deferred.promise; |
| 19315 | }); |
| 19316 | } |
| 19317 | |
| 19318 | Promise.prototype.all = function () { |
| 19319 | return all(this); |
| 19320 | }; |
| 19321 | |
| 19322 | /** |
| 19323 | * Returns the first resolved promise of an array. Prior rejected promises are |
| 19324 | * ignored. Rejects only if all promises are rejected. |
| 19325 | * @param {Array*} an array containing values or promises for values |
| 19326 | * @returns a promise fulfilled with the value of the first resolved promise, |
| 19327 | * or a rejected promise if all promises are rejected. |
| 19328 | */ |
| 19329 | Q.any = any; |
| 19330 | |
| 19331 | function any(promises) { |
| 19332 | if (promises.length === 0) { |
| 19333 | return Q.resolve(); |
| 19334 | } |
| 19335 | |
| 19336 | var deferred = Q.defer(); |
| 19337 | var pendingCount = 0; |
| 19338 | array_reduce(promises, function (prev, current, index) { |
| 19339 | var promise = promises[index]; |
| 19340 | |
| 19341 | pendingCount++; |
| 19342 | |
| 19343 | when(promise, onFulfilled, onRejected, onProgress); |
| 19344 | function onFulfilled(result) { |
| 19345 | deferred.resolve(result); |
| 19346 | } |
| 19347 | function onRejected() { |
| 19348 | pendingCount--; |
| 19349 | if (pendingCount === 0) { |
| 19350 | deferred.reject(new Error( |
| 19351 | "Can't get fulfillment value from any promise, all " + |
| 19352 | "promises were rejected." |
| 19353 | )); |
| 19354 | } |
| 19355 | } |
| 19356 | function onProgress(progress) { |
| 19357 | deferred.notify({ |
| 19358 | index: index, |
| 19359 | value: progress |
| 19360 | }); |
| 19361 | } |
| 19362 | }, undefined); |
| 19363 | |
| 19364 | return deferred.promise; |
| 19365 | } |
| 19366 | |
| 19367 | Promise.prototype.any = function () { |
| 19368 | return any(this); |
| 19369 | }; |
| 19370 | |
| 19371 | /** |
| 19372 | * Waits for all promises to be settled, either fulfilled or |
| 19373 | * rejected. This is distinct from `all` since that would stop |
| 19374 | * waiting at the first rejection. The promise returned by |
| 19375 | * `allResolved` will never be rejected. |
| 19376 | * @param promises a promise for an array (or an array) of promises |
| 19377 | * (or values) |
| 19378 | * @return a promise for an array of promises |
| 19379 | */ |
| 19380 | Q.allResolved = deprecate(allResolved, "allResolved", "allSettled"); |
| 19381 | function allResolved(promises) { |
| 19382 | return when(promises, function (promises) { |
| 19383 | promises = array_map(promises, Q); |
| 19384 | return when(all(array_map(promises, function (promise) { |
| 19385 | return when(promise, noop, noop); |
| 19386 | })), function () { |
| 19387 | return promises; |
| 19388 | }); |
| 19389 | }); |
| 19390 | } |
| 19391 | |
| 19392 | Promise.prototype.allResolved = function () { |
| 19393 | return allResolved(this); |
| 19394 | }; |
| 19395 | |
| 19396 | /** |
| 19397 | * @see Promise#allSettled |
| 19398 | */ |
| 19399 | Q.allSettled = allSettled; |
| 19400 | function allSettled(promises) { |
| 19401 | return Q(promises).allSettled(); |
| 19402 | } |
| 19403 | |
| 19404 | /** |
| 19405 | * Turns an array of promises into a promise for an array of their states (as |
| 19406 | * returned by `inspect`) when they have all settled. |
| 19407 | * @param {Array[Any*]} values an array (or promise for an array) of values (or |
| 19408 | * promises for values) |
| 19409 | * @returns {Array[State]} an array of states for the respective values. |
| 19410 | */ |
| 19411 | Promise.prototype.allSettled = function () { |
| 19412 | return this.then(function (promises) { |
| 19413 | return all(array_map(promises, function (promise) { |
| 19414 | promise = Q(promise); |
| 19415 | function regardless() { |
| 19416 | return promise.inspect(); |
| 19417 | } |
| 19418 | return promise.then(regardless, regardless); |
| 19419 | })); |
| 19420 | }); |
| 19421 | }; |
| 19422 | |
| 19423 | /** |
| 19424 | * Captures the failure of a promise, giving an oportunity to recover |
| 19425 | * with a callback. If the given promise is fulfilled, the returned |
| 19426 | * promise is fulfilled. |
| 19427 | * @param {Any*} promise for something |
| 19428 | * @param {Function} callback to fulfill the returned promise if the |
| 19429 | * given promise is rejected |
| 19430 | * @returns a promise for the return value of the callback |
| 19431 | */ |
| 19432 | Q.fail = // XXX legacy |
| 19433 | Q["catch"] = function (object, rejected) { |
| 19434 | return Q(object).then(void 0, rejected); |
| 19435 | }; |
| 19436 | |
| 19437 | Promise.prototype.fail = // XXX legacy |
| 19438 | Promise.prototype["catch"] = function (rejected) { |
| 19439 | return this.then(void 0, rejected); |
| 19440 | }; |
| 19441 | |
| 19442 | /** |
| 19443 | * Attaches a listener that can respond to progress notifications from a |
| 19444 | * promise's originating deferred. This listener receives the exact arguments |
| 19445 | * passed to ``deferred.notify``. |
| 19446 | * @param {Any*} promise for something |
| 19447 | * @param {Function} callback to receive any progress notifications |
| 19448 | * @returns the given promise, unchanged |
| 19449 | */ |
| 19450 | Q.progress = progress; |
| 19451 | function progress(object, progressed) { |
| 19452 | return Q(object).then(void 0, void 0, progressed); |
| 19453 | } |
| 19454 | |
| 19455 | Promise.prototype.progress = function (progressed) { |
| 19456 | return this.then(void 0, void 0, progressed); |
| 19457 | }; |
| 19458 | |
| 19459 | /** |
| 19460 | * Provides an opportunity to observe the settling of a promise, |
| 19461 | * regardless of whether the promise is fulfilled or rejected. Forwards |
| 19462 | * the resolution to the returned promise when the callback is done. |
| 19463 | * The callback can return a promise to defer completion. |
| 19464 | * @param {Any*} promise |
| 19465 | * @param {Function} callback to observe the resolution of the given |
| 19466 | * promise, takes no arguments. |
| 19467 | * @returns a promise for the resolution of the given promise when |
| 19468 | * ``fin`` is done. |
| 19469 | */ |
| 19470 | Q.fin = // XXX legacy |
| 19471 | Q["finally"] = function (object, callback) { |
| 19472 | return Q(object)["finally"](callback); |
| 19473 | }; |
| 19474 | |
| 19475 | Promise.prototype.fin = // XXX legacy |
| 19476 | Promise.prototype["finally"] = function (callback) { |
| 19477 | callback = Q(callback); |
| 19478 | return this.then(function (value) { |
| 19479 | return callback.fcall().then(function () { |
| 19480 | return value; |
| 19481 | }); |
| 19482 | }, function (reason) { |
| 19483 | // TODO attempt to recycle the rejection with "this". |
| 19484 | return callback.fcall().then(function () { |
| 19485 | throw reason; |
| 19486 | }); |
| 19487 | }); |
| 19488 | }; |
| 19489 | |
| 19490 | /** |
| 19491 | * Terminates a chain of promises, forcing rejections to be |
| 19492 | * thrown as exceptions. |
| 19493 | * @param {Any*} promise at the end of a chain of promises |
| 19494 | * @returns nothing |
| 19495 | */ |
| 19496 | Q.done = function (object, fulfilled, rejected, progress) { |
| 19497 | return Q(object).done(fulfilled, rejected, progress); |
| 19498 | }; |
| 19499 | |
| 19500 | Promise.prototype.done = function (fulfilled, rejected, progress) { |
| 19501 | var onUnhandledError = function (error) { |
| 19502 | // forward to a future turn so that ``when`` |
| 19503 | // does not catch it and turn it into a rejection. |
| 19504 | Q.nextTick(function () { |
| 19505 | makeStackTraceLong(error, promise); |
| 19506 | if (Q.onerror) { |
| 19507 | Q.onerror(error); |
| 19508 | } else { |
| 19509 | throw error; |
| 19510 | } |
| 19511 | }); |
| 19512 | }; |
| 19513 | |
| 19514 | // Avoid unnecessary `nextTick`ing via an unnecessary `when`. |
| 19515 | var promise = fulfilled || rejected || progress ? |
| 19516 | this.then(fulfilled, rejected, progress) : |
| 19517 | this; |
| 19518 | |
| 19519 | if (typeof process === "object" && process && process.domain) { |
| 19520 | onUnhandledError = process.domain.bind(onUnhandledError); |
| 19521 | } |
| 19522 | |
| 19523 | promise.then(void 0, onUnhandledError); |
| 19524 | }; |
| 19525 | |
| 19526 | /** |
| 19527 | * Causes a promise to be rejected if it does not get fulfilled before |
| 19528 | * some milliseconds time out. |
| 19529 | * @param {Any*} promise |
| 19530 | * @param {Number} milliseconds timeout |
| 19531 | * @param {Any*} custom error message or Error object (optional) |
| 19532 | * @returns a promise for the resolution of the given promise if it is |
| 19533 | * fulfilled before the timeout, otherwise rejected. |
| 19534 | */ |
| 19535 | Q.timeout = function (object, ms, error) { |
| 19536 | return Q(object).timeout(ms, error); |
| 19537 | }; |
| 19538 | |
| 19539 | Promise.prototype.timeout = function (ms, error) { |
| 19540 | var deferred = defer(); |
| 19541 | var timeoutId = setTimeout(function () { |
| 19542 | if (!error || "string" === typeof error) { |
| 19543 | error = new Error(error || "Timed out after " + ms + " ms"); |
| 19544 | error.code = "ETIMEDOUT"; |
| 19545 | } |
| 19546 | deferred.reject(error); |
| 19547 | }, ms); |
| 19548 | |
| 19549 | this.then(function (value) { |
| 19550 | clearTimeout(timeoutId); |
| 19551 | deferred.resolve(value); |
| 19552 | }, function (exception) { |
| 19553 | clearTimeout(timeoutId); |
| 19554 | deferred.reject(exception); |
| 19555 | }, deferred.notify); |
| 19556 | |
| 19557 | return deferred.promise; |
| 19558 | }; |
| 19559 | |
| 19560 | /** |
| 19561 | * Returns a promise for the given value (or promised value), some |
| 19562 | * milliseconds after it resolved. Passes rejections immediately. |
| 19563 | * @param {Any*} promise |
| 19564 | * @param {Number} milliseconds |
| 19565 | * @returns a promise for the resolution of the given promise after milliseconds |
| 19566 | * time has elapsed since the resolution of the given promise. |
| 19567 | * If the given promise rejects, that is passed immediately. |
| 19568 | */ |
| 19569 | Q.delay = function (object, timeout) { |
| 19570 | if (timeout === void 0) { |
| 19571 | timeout = object; |
| 19572 | object = void 0; |
| 19573 | } |
| 19574 | return Q(object).delay(timeout); |
| 19575 | }; |
| 19576 | |
| 19577 | Promise.prototype.delay = function (timeout) { |
| 19578 | return this.then(function (value) { |
| 19579 | var deferred = defer(); |
| 19580 | setTimeout(function () { |
| 19581 | deferred.resolve(value); |
| 19582 | }, timeout); |
| 19583 | return deferred.promise; |
| 19584 | }); |
| 19585 | }; |
| 19586 | |
| 19587 | /** |
| 19588 | * Passes a continuation to a Node function, which is called with the given |
| 19589 | * arguments provided as an array, and returns a promise. |
| 19590 | * |
| 19591 | * Q.nfapply(FS.readFile, [__filename]) |
| 19592 | * .then(function (content) { |
| 19593 | * }) |
| 19594 | * |
| 19595 | */ |
| 19596 | Q.nfapply = function (callback, args) { |
| 19597 | return Q(callback).nfapply(args); |
| 19598 | }; |
| 19599 | |
| 19600 | Promise.prototype.nfapply = function (args) { |
| 19601 | var deferred = defer(); |
| 19602 | var nodeArgs = array_slice(args); |
| 19603 | nodeArgs.push(deferred.makeNodeResolver()); |
| 19604 | this.fapply(nodeArgs).fail(deferred.reject); |
| 19605 | return deferred.promise; |
| 19606 | }; |
| 19607 | |
| 19608 | /** |
| 19609 | * Passes a continuation to a Node function, which is called with the given |
| 19610 | * arguments provided individually, and returns a promise. |
| 19611 | * @example |
| 19612 | * Q.nfcall(FS.readFile, __filename) |
| 19613 | * .then(function (content) { |
| 19614 | * }) |
| 19615 | * |
| 19616 | */ |
| 19617 | Q.nfcall = function (callback /*...args*/) { |
| 19618 | var args = array_slice(arguments, 1); |
| 19619 | return Q(callback).nfapply(args); |
| 19620 | }; |
| 19621 | |
| 19622 | Promise.prototype.nfcall = function (/*...args*/) { |
| 19623 | var nodeArgs = array_slice(arguments); |
| 19624 | var deferred = defer(); |
| 19625 | nodeArgs.push(deferred.makeNodeResolver()); |
| 19626 | this.fapply(nodeArgs).fail(deferred.reject); |
| 19627 | return deferred.promise; |
| 19628 | }; |
| 19629 | |
| 19630 | /** |
| 19631 | * Wraps a NodeJS continuation passing function and returns an equivalent |
| 19632 | * version that returns a promise. |
| 19633 | * @example |
| 19634 | * Q.nfbind(FS.readFile, __filename)("utf-8") |
| 19635 | * .then(console.log) |
| 19636 | * .done() |
| 19637 | */ |
| 19638 | Q.nfbind = |
| 19639 | Q.denodeify = function (callback /*...args*/) { |
| 19640 | var baseArgs = array_slice(arguments, 1); |
| 19641 | return function () { |
| 19642 | var nodeArgs = baseArgs.concat(array_slice(arguments)); |
| 19643 | var deferred = defer(); |
| 19644 | nodeArgs.push(deferred.makeNodeResolver()); |
| 19645 | Q(callback).fapply(nodeArgs).fail(deferred.reject); |
| 19646 | return deferred.promise; |
| 19647 | }; |
| 19648 | }; |
| 19649 | |
| 19650 | Promise.prototype.nfbind = |
| 19651 | Promise.prototype.denodeify = function (/*...args*/) { |
| 19652 | var args = array_slice(arguments); |
| 19653 | args.unshift(this); |
| 19654 | return Q.denodeify.apply(void 0, args); |
| 19655 | }; |
| 19656 | |
| 19657 | Q.nbind = function (callback, thisp /*...args*/) { |
| 19658 | var baseArgs = array_slice(arguments, 2); |
| 19659 | return function () { |
| 19660 | var nodeArgs = baseArgs.concat(array_slice(arguments)); |
| 19661 | var deferred = defer(); |
| 19662 | nodeArgs.push(deferred.makeNodeResolver()); |
| 19663 | function bound() { |
| 19664 | return callback.apply(thisp, arguments); |
| 19665 | } |
| 19666 | Q(bound).fapply(nodeArgs).fail(deferred.reject); |
| 19667 | return deferred.promise; |
| 19668 | }; |
| 19669 | }; |
| 19670 | |
| 19671 | Promise.prototype.nbind = function (/*thisp, ...args*/) { |
| 19672 | var args = array_slice(arguments, 0); |
| 19673 | args.unshift(this); |
| 19674 | return Q.nbind.apply(void 0, args); |
| 19675 | }; |
| 19676 | |
| 19677 | /** |
| 19678 | * Calls a method of a Node-style object that accepts a Node-style |
| 19679 | * callback with a given array of arguments, plus a provided callback. |
| 19680 | * @param object an object that has the named method |
| 19681 | * @param {String} name name of the method of object |
| 19682 | * @param {Array} args arguments to pass to the method; the callback |
| 19683 | * will be provided by Q and appended to these arguments. |
| 19684 | * @returns a promise for the value or error |
| 19685 | */ |
| 19686 | Q.nmapply = // XXX As proposed by "Redsandro" |
| 19687 | Q.npost = function (object, name, args) { |
| 19688 | return Q(object).npost(name, args); |
| 19689 | }; |
| 19690 | |
| 19691 | Promise.prototype.nmapply = // XXX As proposed by "Redsandro" |
| 19692 | Promise.prototype.npost = function (name, args) { |
| 19693 | var nodeArgs = array_slice(args || []); |
| 19694 | var deferred = defer(); |
| 19695 | nodeArgs.push(deferred.makeNodeResolver()); |
| 19696 | this.dispatch("post", [name, nodeArgs]).fail(deferred.reject); |
| 19697 | return deferred.promise; |
| 19698 | }; |
| 19699 | |
| 19700 | /** |
| 19701 | * Calls a method of a Node-style object that accepts a Node-style |
| 19702 | * callback, forwarding the given variadic arguments, plus a provided |
| 19703 | * callback argument. |
| 19704 | * @param object an object that has the named method |
| 19705 | * @param {String} name name of the method of object |
| 19706 | * @param ...args arguments to pass to the method; the callback will |
| 19707 | * be provided by Q and appended to these arguments. |
| 19708 | * @returns a promise for the value or error |
| 19709 | */ |
| 19710 | Q.nsend = // XXX Based on Mark Miller's proposed "send" |
| 19711 | Q.nmcall = // XXX Based on "Redsandro's" proposal |
| 19712 | Q.ninvoke = function (object, name /*...args*/) { |
| 19713 | var nodeArgs = array_slice(arguments, 2); |
| 19714 | var deferred = defer(); |
| 19715 | nodeArgs.push(deferred.makeNodeResolver()); |
| 19716 | Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject); |
| 19717 | return deferred.promise; |
| 19718 | }; |
| 19719 | |
| 19720 | Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send" |
| 19721 | Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal |
| 19722 | Promise.prototype.ninvoke = function (name /*...args*/) { |
| 19723 | var nodeArgs = array_slice(arguments, 1); |
| 19724 | var deferred = defer(); |
| 19725 | nodeArgs.push(deferred.makeNodeResolver()); |
| 19726 | this.dispatch("post", [name, nodeArgs]).fail(deferred.reject); |
| 19727 | return deferred.promise; |
| 19728 | }; |
| 19729 | |
| 19730 | /** |
| 19731 | * If a function would like to support both Node continuation-passing-style and |
| 19732 | * promise-returning-style, it can end its internal promise chain with |
| 19733 | * `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user |
| 19734 | * elects to use a nodeback, the result will be sent there. If they do not |
| 19735 | * pass a nodeback, they will receive the result promise. |
| 19736 | * @param object a result (or a promise for a result) |
| 19737 | * @param {Function} nodeback a Node.js-style callback |
| 19738 | * @returns either the promise or nothing |
| 19739 | */ |
| 19740 | Q.nodeify = nodeify; |
| 19741 | function nodeify(object, nodeback) { |
| 19742 | return Q(object).nodeify(nodeback); |
| 19743 | } |
| 19744 | |
| 19745 | Promise.prototype.nodeify = function (nodeback) { |
| 19746 | if (nodeback) { |
| 19747 | this.then(function (value) { |
| 19748 | Q.nextTick(function () { |
| 19749 | nodeback(null, value); |
| 19750 | }); |
| 19751 | }, function (error) { |
| 19752 | Q.nextTick(function () { |
| 19753 | nodeback(error); |
| 19754 | }); |
| 19755 | }); |
| 19756 | } else { |
| 19757 | return this; |
| 19758 | } |
| 19759 | }; |
| 19760 | |
| 19761 | Q.noConflict = function() { |
| 19762 | throw new Error("Q.noConflict only works when Q is used as a global"); |
| 19763 | }; |
| 19764 | |
| 19765 | // All code before this point will be filtered from stack traces. |
| 19766 | var qEndingLine = captureLine(); |
| 19767 | |
| 19768 | return Q; |
| 19769 | |
| 19770 | }); |
| 19771 | |
| 19772 | }).call(this,require('_process')) |
| 19773 | //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9xL3EuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdmltOnRzPTQ6c3RzPTQ6c3c9NDpcbi8qIVxuICpcbiAqIENvcHlyaWdodCAyMDA5LTIwMTIgS3JpcyBLb3dhbCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVFxuICogbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9yYXcvbWFzdGVyL0xJQ0VOU0VcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IFR5bGVyIENsb3NlXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDA5IFR5bGVyIENsb3NlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUIFggbGljZW5zZSBmb3VuZFxuICogYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5odG1sXG4gKiBGb3JrZWQgYXQgcmVmX3NlbmQuanMgdmVyc2lvbjogMjAwOS0wNS0xMVxuICpcbiAqIFdpdGggcGFydHMgYnkgTWFyayBNaWxsZXJcbiAqIENvcHlyaWdodCAoQykgMjAxMSBHb29nbGUgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4oZnVuY3Rpb24gKGRlZmluaXRpb24pIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIC8vIFRoaXMgZmlsZSB3aWxsIGZ1bmN0aW9uIHByb3Blcmx5IGFzIGEgPHNjcmlwdD4gdGFnLCBvciBhIG1vZHVsZVxuICAgIC8vIHVzaW5nIENvbW1vbkpTIGFuZCBOb2RlSlMgb3IgUmVxdWlyZUpTIG1vZHVsZSBmb3JtYXRzLiAgSW5cbiAgICAvLyBDb21tb24vTm9kZS9SZXF1aXJlSlMsIHRoZSBtb2R1bGUgZXhwb3J0cyB0aGUgUSBBUEkgYW5kIHdoZW5cbiAgICAvLyBleGVjdXRlZCBhcyBhIHNpbXBsZSA8c2NyaXB0PiwgaXQgY3JlYXRlcyBhIFEgZ2xvYmFsIGluc3RlYWQuXG5cbiAgICAvLyBNb250YWdlIFJlcXVpcmVcbiAgICBpZiAodHlwZW9mIGJvb3RzdHJhcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGJvb3RzdHJhcChcInByb21pc2VcIiwgZGVmaW5pdGlvbik7XG5cbiAgICAvLyBDb21tb25KU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcblxuICAgIC8vIFJlcXVpcmVKU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGRlZmluaXRpb24pO1xuXG4gICAgLy8gU0VTIChTZWN1cmUgRWNtYVNjcmlwdClcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKCFzZXMub2soKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VzLm1ha2VRID0gZGVmaW5pdGlvbjtcbiAgICAgICAgfVxuXG4gICAgLy8gPHNjcmlwdD5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgLy8gUHJlZmVyIHdpbmRvdyBvdmVyIHNlbGYgZm9yIGFkZC1vbiBzY3JpcHRzLiBVc2Ugc2VsZiBmb3JcbiAgICAgICAgLy8gbm9uLXdpbmRvd2VkIGNvbnRleHRzLlxuICAgICAgICB2YXIgZ2xvYmFsID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHNlbGY7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBgd2luZG93YCBvYmplY3QsIHNhdmUgdGhlIHByZXZpb3VzIFEgZ2xvYmFsXG4gICAgICAgIC8vIGFuZCBpbml0aWFsaXplIFEgYXMgYSBnbG9iYWwuXG4gICAgICAgIHZhciBwcmV2aW91c1EgPSBnbG9iYWwuUTtcbiAgICAgICAgZ2xvYmFsLlEgPSBkZWZpbml0aW9uKCk7XG5cbiAgICAgICAgLy8gQWRkIGEgbm9Db25mbGljdCBmdW5jdGlvbiBzbyBRIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlXG4gICAgICAgIC8vIGdsb2JhbCBuYW1lc3BhY2UuXG4gICAgICAgIGdsb2JhbC5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnbG9iYWwuUSA9IHByZXZpb3VzUTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnZpcm9ubWVudCB3YXMgbm90IGFudGljaXBhdGVkIGJ5IFEuIFBsZWFzZSBmaWxlIGEgYnVnLlwiKTtcbiAgICB9XG5cbn0pKGZ1bmN0aW9uICgpIHtcblwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzU3RhY2tzID0gZmFsc2U7XG50cnkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufSBjYXRjaCAoZSkge1xuICAgIGhhc1N0YWNrcyA9ICEhZS5zdGFjaztcbn1cblxuLy8gQWxsIGNvZGUgYWZ0ZXIgdGhpcyBwb2ludCB3aWxsIGJlIGZpbHRlcmVkIGZyb20gc3RhY2sgdHJhY2VzIHJlcG9ydGVkXG4vLyBieSBRLlxudmFyIHFTdGFydGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xudmFyIHFGaWxlTmFtZTtcblxuLy8gc2hpbXNcblxuLy8gdXNlZCBmb3IgZmFsbGJhY2sgaW4gXCJhbGxSZXNvbHZlZFwiXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgcG9zc2libGUgbWVhbnMgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gYSBmdXR1cmUgdHVyblxuLy8gb2YgdGhlIGV2ZW50IGxvb3AuXG52YXIgbmV4dFRpY2sgPShmdW5jdGlvbiAoKSB7XG4gICAgLy8gbGlua2VkIGxpc3Qgb2YgdGFza3MgKHNpbmdsZSwgd2l0aCBoZWFkIG5vZGUpXG4gICAgdmFyIGhlYWQgPSB7dGFzazogdm9pZCAwLCBuZXh0OiBudWxsfTtcbiAgICB2YXIgdGFpbCA9IGhlYWQ7XG4gICAgdmFyIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlcXVlc3RUaWNrID0gdm9pZCAwO1xuICAgIHZhciBpc05vZGVKUyA9IGZhbHNlO1xuICAgIC8vIHF1ZXVlIGZvciBsYXRlIHRhc2tzLCB1c2VkIGJ5IHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmdcbiAgICB2YXIgbGF0ZXJRdWV1ZSA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgICAgIC8qIGpzaGludCBsb29wZnVuYzogdHJ1ZSAqL1xuICAgICAgICB2YXIgdGFzaywgZG9tYWluO1xuXG4gICAgICAgIHdoaWxlIChoZWFkLm5leHQpIHtcbiAgICAgICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICAgICAgICB0YXNrID0gaGVhZC50YXNrO1xuICAgICAgICAgICAgaGVhZC50YXNrID0gdm9pZCAwO1xuICAgICAgICAgICAgZG9tYWluID0gaGVhZC5kb21haW47XG5cbiAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICBoZWFkLmRvbWFpbiA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pO1xuXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGxhdGVyUXVldWUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXNrID0gbGF0ZXJRdWV1ZS5wb3AoKTtcbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrKTtcbiAgICAgICAgfVxuICAgICAgICBmbHVzaGluZyA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBydW5zIGEgc2luZ2xlIGZ1bmN0aW9uIGluIHRoZSBhc3luYyBxdWV1ZVxuICAgIGZ1bmN0aW9uIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRhc2soKTtcblxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNOb2RlSlMpIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBub2RlLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBjb25zaWRlcmVkIGZhdGFsIGVycm9ycy5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIHN5bmNocm9ub3VzbHkgdG8gaW50ZXJydXB0IGZsdXNoaW5nIVxuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIGNvbnRpbnVhdGlvbiBpZiB0aGUgdW5jYXVnaHQgZXhjZXB0aW9uIGlzIHN1cHByZXNzZWRcbiAgICAgICAgICAgICAgICAvLyBsaXN0ZW5pbmcgXCJ1bmNhdWdodEV4Y2VwdGlvblwiIGV2ZW50cyAoYXMgZG9tYWlucyBkb2VzKS5cbiAgICAgICAgICAgICAgICAvLyBDb250aW51ZSBpbiBuZXh0IGV2ZW50IHRvIGF2b2lkIHRpY2sgcmVjdXJzaW9uLlxuICAgICAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEluIGJyb3dzZXJzLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBub3QgZmF0YWwuXG4gICAgICAgICAgICAgICAgLy8gUmUtdGhyb3cgdGhlbSBhc3luY2hyb25vdXNseSB0byBhdm9pZCBzbG93LWRvd25zLlxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5leHRUaWNrID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgdGFpbCA9IHRhaWwubmV4dCA9IHtcbiAgICAgICAgICAgIHRhc2s6IHRhc2ssXG4gICAgICAgICAgICBkb21haW46IGlzTm9kZUpTICYmIHByb2Nlc3MuZG9tYWluLFxuICAgICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghZmx1c2hpbmcpIHtcbiAgICAgICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHByb2Nlc3MudG9TdHJpbmcoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIgJiYgcHJvY2Vzcy5uZXh0VGljaykge1xuICAgICAgICAvLyBFbnN1cmUgUSBpcyBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudCwgd2l0aCBhIGBwcm9jZXNzLm5leHRUaWNrYC5cbiAgICAgICAgLy8gVG8gc2VlIHRocm91Z2ggZmFrZSBOb2RlIGVudmlyb25tZW50czpcbiAgICAgICAgLy8gKiBNb2NoYSB0ZXN0IHJ1bm5lciAtIGV4cG9zZXMgYSBgcHJvY2Vzc2AgZ2xvYmFsIHdpdGhvdXQgYSBgbmV4dFRpY2tgXG4gICAgICAgIC8vICogQnJvd3NlcmlmeSAtIGV4cG9zZXMgYSBgcHJvY2Vzcy5uZXhUaWNrYCBmdW5jdGlvbiB0aGF0IHVzZXNcbiAgICAgICAgLy8gICBgc2V0VGltZW91dGAuIEluIHRoaXMgY2FzZSBgc2V0SW1tZWRpYXRlYCBpcyBwcmVmZXJyZWQgYmVjYXVzZVxuICAgICAgICAvLyAgICBpdCBpcyBmYXN0ZXIuIEJyb3dzZXJpZnkncyBgcHJvY2Vzcy50b1N0cmluZygpYCB5aWVsZHNcbiAgICAgICAgLy8gICBcIltvYmplY3QgT2JqZWN0XVwiLCB3aGlsZSBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudFxuICAgICAgICAvLyAgIGBwcm9jZXNzLm5leHRUaWNrKClgIHlpZWxkcyBcIltvYmplY3QgcHJvY2Vzc11cIi5cbiAgICAgICAgaXNOb2RlSlMgPSB0cnVlO1xuXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBJbiBJRTEwLCBOb2RlLmpzIDAuOSssIG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9Ob2JsZUpTL3NldEltbWVkaWF0ZVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBzZXRJbW1lZGlhdGUuYmluZCh3aW5kb3csIGZsdXNoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbHVzaCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgLy8gQXQgbGVhc3QgU2FmYXJpIFZlcnNpb24gNi4wLjUgKDg1MzYuMzAuMSkgaW50ZXJtaXR0ZW50bHkgY2Fubm90IGNyZWF0ZVxuICAgICAgICAvLyB3b3JraW5nIG1lc3NhZ2UgcG9ydHMgdGhlIGZpcnN0IHRpbWUgYSBwYWdlIGxvYWRzLlxuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gcmVxdWVzdFBvcnRUaWNrO1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmbHVzaDtcbiAgICAgICAgICAgIGZsdXNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciByZXF1ZXN0UG9ydFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBPcGVyYSByZXF1aXJlcyB1cyB0byBwcm92aWRlIGEgbWVzc2FnZSBwYXlsb2FkLCByZWdhcmRsZXNzIG9mXG4gICAgICAgICAgICAvLyB3aGV0aGVyIHdlIHVzZSBpdC5cbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgICAgIH07XG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICByZXF1ZXN0UG9ydFRpY2soKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9sZCBicm93c2Vyc1xuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBydW5zIGEgdGFzayBhZnRlciBhbGwgb3RoZXIgdGFza3MgaGF2ZSBiZWVuIHJ1blxuICAgIC8vIHRoaXMgaXMgdXNlZnVsIGZvciB1bmhhbmRsZWQgcmVqZWN0aW9uIHRyYWNraW5nIHRoYXQgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgYWxsIGB0aGVuYGQgdGFza3MgaGF2ZSBiZWVuIHJ1bi5cbiAgICBuZXh0VGljay5ydW5BZnRlciA9IGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgIGxhdGVyUXVldWUucHVzaCh0YXNrKTtcbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIG5leHRUaWNrO1xufSkoKTtcblxuLy8gQXR0ZW1wdCB0byBtYWtlIGdlbmVyaWNzIHNhZmUgaW4gdGhlIGZhY2Ugb2YgZG93bnN0cmVhbVxuLy8gbW9kaWZpY2F0aW9ucy5cbi8vIFRoZXJlIGlzIG5vIHNpdHVhdGlvbiB3aGVyZSB0aGlzIGlzIG5lY2Vzc2FyeS5cbi8vIElmIHlvdSBuZWVkIGEgc2VjdXJpdHkgZ3VhcmFudGVlLCB0aGVzZSBwcmltb3JkaWFscyBuZWVkIHRvIGJlXG4vLyBkZWVwbHkgZnJvemVuIGFueXdheSwgYW5kIGlmIHlvdSBkb27igJl0IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsXG4vLyB0aGlzIGlzIGp1c3QgcGxhaW4gcGFyYW5vaWQuXG4vLyBIb3dldmVyLCB0aGlzICoqbWlnaHQqKiBoYXZlIHRoZSBuaWNlIHNpZGUtZWZmZWN0IG9mIHJlZHVjaW5nIHRoZSBzaXplIG9mXG4vLyB0aGUgbWluaWZpZWQgY29kZSBieSByZWR1Y2luZyB4LmNhbGwoKSB0byBtZXJlbHkgeCgpXG4vLyBTZWUgTWFyayBNaWxsZXLigJlzIGV4cGxhbmF0aW9uIG9mIHdoYXQgdGhpcyBkb2VzLlxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9Y29udmVudGlvbnM6c2FmZV9tZXRhX3Byb2dyYW1taW5nXG52YXIgY2FsbCA9IEZ1bmN0aW9uLmNhbGw7XG5mdW5jdGlvbiB1bmN1cnJ5VGhpcyhmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNhbGwuYXBwbHkoZiwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuLy8gVGhpcyBpcyBlcXVpdmFsZW50LCBidXQgc2xvd2VyOlxuLy8gdW5jdXJyeVRoaXMgPSBGdW5jdGlvbl9iaW5kLmJpbmQoRnVuY3Rpb25fYmluZC5jYWxsKTtcbi8vIGh0dHA6Ly9qc3BlcmYuY29tL3VuY3Vycnl0aGlzXG5cbnZhciBhcnJheV9zbGljZSA9IHVuY3VycnlUaGlzKEFycmF5LnByb3RvdHlwZS5zbGljZSk7XG5cbnZhciBhcnJheV9yZWR1Y2UgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUucmVkdWNlIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgYmFzaXMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgICAgICAvLyBjb25jZXJuaW5nIHRoZSBpbml0aWFsIHZhbHVlLCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyBzZWVrIHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXksIGFjY291bnRpbmdcbiAgICAgICAgICAgIC8vIGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCBpcyBpcyBhIHNwYXJzZSBhcnJheVxuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGJhc2lzID0gdGhpc1tpbmRleCsrXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgrK2luZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAoMSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVkdWNlXG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhlIGFycmF5IGlzIHNwYXJzZVxuICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICBiYXNpcyA9IGNhbGxiYWNrKGJhc2lzLCB0aGlzW2luZGV4XSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNpcztcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfaW5kZXhPZiA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIHx8IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBub3QgYSB2ZXJ5IGdvb2Qgc2hpbSwgYnV0IGdvb2QgZW5vdWdoIGZvciBvdXIgb25lIHVzZSBvZiBpdFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfbWFwID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLm1hcCB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGNvbGxlY3QgPSBbXTtcbiAgICAgICAgYXJyYXlfcmVkdWNlKHNlbGYsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgY29sbGVjdC5wdXNoKGNhbGxiYWNrLmNhbGwodGhpc3AsIHZhbHVlLCBpbmRleCwgc2VsZikpO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICByZXR1cm4gY29sbGVjdDtcbiAgICB9XG4pO1xuXG52YXIgb2JqZWN0X2NyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gKHByb3RvdHlwZSkge1xuICAgIGZ1bmN0aW9uIFR5cGUoKSB7IH1cbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3IFR5cGUoKTtcbn07XG5cbnZhciBvYmplY3RfaGFzT3duUHJvcGVydHkgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcblxudmFyIG9iamVjdF9rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0X2hhc093blByb3BlcnR5KG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgb2JqZWN0X3RvU3RyaW5nID0gdW5jdXJyeVRoaXMoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBPYmplY3QodmFsdWUpO1xufVxuXG4vLyBnZW5lcmF0b3IgcmVsYXRlZCBzaGltc1xuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgZnVuY3Rpb24gb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuZnVuY3Rpb24gaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikge1xuICAgIHJldHVybiAoXG4gICAgICAgIG9iamVjdF90b1N0cmluZyhleGNlcHRpb24pID09PSBcIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIiB8fFxuICAgICAgICBleGNlcHRpb24gaW5zdGFuY2VvZiBRUmV0dXJuVmFsdWVcbiAgICApO1xufVxuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgaGVscGVyIGFuZCBRLnJldHVybiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpblxuLy8gU3BpZGVyTW9ua2V5LlxudmFyIFFSZXR1cm5WYWx1ZTtcbmlmICh0eXBlb2YgUmV0dXJuVmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBSZXR1cm5WYWx1ZTtcbn0gZWxzZSB7XG4gICAgUVJldHVyblZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9O1xufVxuXG4vLyBsb25nIHN0YWNrIHRyYWNlc1xuXG52YXIgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgPSBcIkZyb20gcHJldmlvdXMgZXZlbnQ6XCI7XG5cbmZ1bmN0aW9uIG1ha2VTdGFja1RyYWNlTG9uZyhlcnJvciwgcHJvbWlzZSkge1xuICAgIC8vIElmIHBvc3NpYmxlLCB0cmFuc2Zvcm0gdGhlIGVycm9yIHN0YWNrIHRyYWNlIGJ5IHJlbW92aW5nIE5vZGUgYW5kIFFcbiAgICAvLyBjcnVmdCwgdGhlbiBjb25jYXRlbmF0aW5nIHdpdGggdGhlIHN0YWNrIHRyYWNlIG9mIGBwcm9taXNlYC4gU2VlICM1Ny5cbiAgICBpZiAoaGFzU3RhY2tzICYmXG4gICAgICAgIHByb21pc2Uuc3RhY2sgJiZcbiAgICAgICAgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIGVycm9yICE9PSBudWxsICYmXG4gICAgICAgIGVycm9yLnN0YWNrICYmXG4gICAgICAgIGVycm9yLnN0YWNrLmluZGV4T2YoU1RBQ0tfSlVNUF9TRVBBUkFUT1IpID09PSAtMVxuICAgICkge1xuICAgICAgICB2YXIgc3RhY2tzID0gW107XG4gICAgICAgIGZvciAodmFyIHAgPSBwcm9taXNlOyAhIXA7IHAgPSBwLnNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKHAuc3RhY2spIHtcbiAgICAgICAgICAgICAgICBzdGFja3MudW5zaGlmdChwLnN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFja3MudW5zaGlmdChlcnJvci5zdGFjayk7XG5cbiAgICAgICAgdmFyIGNvbmNhdGVkU3RhY2tzID0gc3RhY2tzLmpvaW4oXCJcXG5cIiArIFNUQUNLX0pVTVBfU0VQQVJBVE9SICsgXCJcXG5cIik7XG4gICAgICAgIGVycm9yLnN0YWNrID0gZmlsdGVyU3RhY2tTdHJpbmcoY29uY2F0ZWRTdGFja3MpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZmlsdGVyU3RhY2tTdHJpbmcoc3RhY2tTdHJpbmcpIHtcbiAgICB2YXIgbGluZXMgPSBzdGFja1N0cmluZy5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgZGVzaXJlZExpbmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuXG4gICAgICAgIGlmICghaXNJbnRlcm5hbEZyYW1lKGxpbmUpICYmICFpc05vZGVGcmFtZShsaW5lKSAmJiBsaW5lKSB7XG4gICAgICAgICAgICBkZXNpcmVkTGluZXMucHVzaChsaW5lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzaXJlZExpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIGlzTm9kZUZyYW1lKHN0YWNrTGluZSkge1xuICAgIHJldHVybiBzdGFja0xpbmUuaW5kZXhPZihcIihtb2R1bGUuanM6XCIpICE9PSAtMSB8fFxuICAgICAgICAgICBzdGFja0xpbmUuaW5kZXhPZihcIihub2RlLmpzOlwiKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpIHtcbiAgICAvLyBOYW1lZCBmdW5jdGlvbnM6IFwiYXQgZnVuY3Rpb25OYW1lIChmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlcilcIlxuICAgIC8vIEluIElFMTAgZnVuY3Rpb24gbmFtZSBjYW4gaGF2ZSBzcGFjZXMgKFwiQW5vbnltb3VzIGZ1bmN0aW9uXCIpIE9fb1xuICAgIHZhciBhdHRlbXB0MSA9IC9hdCAuKyBcXCgoLispOihcXGQrKTooPzpcXGQrKVxcKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDEpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0MVsxXSwgTnVtYmVyKGF0dGVtcHQxWzJdKV07XG4gICAgfVxuXG4gICAgLy8gQW5vbnltb3VzIGZ1bmN0aW9uczogXCJhdCBmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQyID0gL2F0IChbXiBdKyk6KFxcZCspOig/OlxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mikge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQyWzFdLCBOdW1iZXIoYXR0ZW1wdDJbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBGaXJlZm94IHN0eWxlOiBcImZ1bmN0aW9uQGZpbGVuYW1lOmxpbmVOdW1iZXIgb3IgQGZpbGVuYW1lOmxpbmVOdW1iZXJcIlxuICAgIHZhciBhdHRlbXB0MyA9IC8uKkAoLispOihcXGQrKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDMpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0M1sxXSwgTnVtYmVyKGF0dGVtcHQzWzJdKV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0ludGVybmFsRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgdmFyIGZpbGVOYW1lQW5kTGluZU51bWJlciA9IGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpO1xuXG4gICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBmaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICB2YXIgbGluZU51bWJlciA9IGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcblxuICAgIHJldHVybiBmaWxlTmFtZSA9PT0gcUZpbGVOYW1lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPj0gcVN0YXJ0aW5nTGluZSAmJlxuICAgICAgICBsaW5lTnVtYmVyIDw9IHFFbmRpbmdMaW5lO1xufVxuXG4vLyBkaXNjb3ZlciBvd24gZmlsZSBuYW1lIGFuZCBsaW5lIG51bWJlciByYW5nZSBmb3IgZmlsdGVyaW5nIHN0YWNrXG4vLyB0cmFjZXNcbmZ1bmN0aW9uIGNhcHR1cmVMaW5lKCkge1xuICAgIGlmICghaGFzU3RhY2tzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZhciBsaW5lcyA9IGUuc3RhY2suc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIHZhciBmaXJzdExpbmUgPSBsaW5lc1swXS5pbmRleE9mKFwiQFwiKSA+IDAgPyBsaW5lc1sxXSA6IGxpbmVzWzJdO1xuICAgICAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKGZpcnN0TGluZSk7XG4gICAgICAgIGlmICghZmlsZU5hbWVBbmRMaW5lTnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBxRmlsZU5hbWUgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMF07XG4gICAgICAgIHJldHVybiBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGUoY2FsbGJhY2ssIG5hbWUsIGFsdGVybmF0aXZlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS53YXJuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihuYW1lICsgXCIgaXMgZGVwcmVjYXRlZCwgdXNlIFwiICsgYWx0ZXJuYXRpdmUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgIFwiIGluc3RlYWQuXCIsIG5ldyBFcnJvcihcIlwiKS5zdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGNhbGxiYWNrLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG5cbi8vIGVuZCBvZiBzaGltc1xuLy8gYmVnaW5uaW5nIG9mIHJlYWwgd29ya1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLCBwYXNzZXMgcHJvbWlzZXMgdGhyb3VnaCwgb3JcbiAqIGNvZXJjZXMgcHJvbWlzZXMgZnJvbSBkaWZmZXJlbnQgc3lzdGVtcy5cbiAqIEBwYXJhbSB2YWx1ZSBpbW1lZGlhdGUgcmVmZXJlbmNlIG9yIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gUSh2YWx1ZSkge1xuICAgIC8vIElmIHRoZSBvYmplY3QgaXMgYWxyZWFkeSBhIFByb21pc2UsIHJldHVybiBpdCBkaXJlY3RseS4gIFRoaXMgZW5hYmxlc1xuICAgIC8vIHRoZSByZXNvbHZlIGZ1bmN0aW9uIHRvIGJvdGggYmUgdXNlZCB0byBjcmVhdGVkIHJlZmVyZW5jZXMgZnJvbSBvYmplY3RzLFxuICAgIC8vIGJ1dCB0byB0b2xlcmFibHkgY29lcmNlIG5vbi1wcm9taXNlcyB0byBwcm9taXNlcy5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBhc3NpbWlsYXRlIHRoZW5hYmxlc1xuICAgIGlmIChpc1Byb21pc2VBbGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGNvZXJjZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGwodmFsdWUpO1xuICAgIH1cbn1cblEucmVzb2x2ZSA9IFE7XG5cbi8qKlxuICogUGVyZm9ybXMgYSB0YXNrIGluIGEgZnV0dXJlIHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0YXNrXG4gKi9cblEubmV4dFRpY2sgPSBuZXh0VGljaztcblxuLyoqXG4gKiBDb250cm9scyB3aGV0aGVyIG9yIG5vdCBsb25nIHN0YWNrIHRyYWNlcyB3aWxsIGJlIG9uXG4gKi9cblEubG9uZ1N0YWNrU3VwcG9ydCA9IGZhbHNlO1xuXG4vLyBlbmFibGUgbG9uZyBzdGFja3MgaWYgUV9ERUJVRyBpcyBzZXRcbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzICYmIHByb2Nlc3MuZW52ICYmIHByb2Nlc3MuZW52LlFfREVCVUcpIHtcbiAgICBRLmxvbmdTdGFja1N1cHBvcnQgPSB0cnVlO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSB7cHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0fSBvYmplY3QuXG4gKlxuICogYHJlc29sdmVgIGlzIGEgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggYSBtb3JlIHJlc29sdmVkIHZhbHVlIGZvciB0aGVcbiAqIHByb21pc2UuIFRvIGZ1bGZpbGwgdGhlIHByb21pc2UsIGludm9rZSBgcmVzb2x2ZWAgd2l0aCBhbnkgdmFsdWUgdGhhdCBpc1xuICogbm90IGEgdGhlbmFibGUuIFRvIHJlamVjdCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGEgcmVqZWN0ZWRcbiAqIHRoZW5hYmxlLCBvciBpbnZva2UgYHJlamVjdGAgd2l0aCB0aGUgcmVhc29uIGRpcmVjdGx5LiBUbyByZXNvbHZlIHRoZVxuICogcHJvbWlzZSB0byBhbm90aGVyIHRoZW5hYmxlLCB0aHVzIHB1dHRpbmcgaXQgaW4gdGhlIHNhbWUgc3RhdGUsIGludm9rZVxuICogYHJlc29sdmVgIHdpdGggdGhhdCBvdGhlciB0aGVuYWJsZS5cbiAqL1xuUS5kZWZlciA9IGRlZmVyO1xuZnVuY3Rpb24gZGVmZXIoKSB7XG4gICAgLy8gaWYgXCJtZXNzYWdlc1wiIGlzIGFuIFwiQXJyYXlcIiwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvbWlzZSBoYXMgbm90IHlldFxuICAgIC8vIGJlZW4gcmVzb2x2ZWQuICBJZiBpdCBpcyBcInVuZGVmaW5lZFwiLCBpdCBoYXMgYmVlbiByZXNvbHZlZC4gIEVhY2hcbiAgICAvLyBlbGVtZW50IG9mIHRoZSBtZXNzYWdlcyBhcnJheSBpcyBpdHNlbGYgYW4gYXJyYXkgb2YgY29tcGxldGUgYXJndW1lbnRzIHRvXG4gICAgLy8gZm9yd2FyZCB0byB0aGUgcmVzb2x2ZWQgcHJvbWlzZS4gIFdlIGNvZXJjZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSB0byBhXG4gICAgLy8gcHJvbWlzZSB1c2luZyB0aGUgYHJlc29sdmVgIGZ1bmN0aW9uIGJlY2F1c2UgaXQgaGFuZGxlcyBib3RoIGZ1bGx5XG4gICAgLy8gbm9uLXRoZW5hYmxlIHZhbHVlcyBhbmQgb3RoZXIgdGhlbmFibGVzIGdyYWNlZnVsbHkuXG4gICAgdmFyIG1lc3NhZ2VzID0gW10sIHByb2dyZXNzTGlzdGVuZXJzID0gW10sIHJlc29sdmVkUHJvbWlzZTtcblxuICAgIHZhciBkZWZlcnJlZCA9IG9iamVjdF9jcmVhdGUoZGVmZXIucHJvdG90eXBlKTtcbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIG9wZXJhbmRzKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICBtZXNzYWdlcy5wdXNoKGFyZ3MpO1xuICAgICAgICAgICAgaWYgKG9wID09PSBcIndoZW5cIiAmJiBvcGVyYW5kc1sxXSkgeyAvLyBwcm9ncmVzcyBvcGVyYW5kXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChvcGVyYW5kc1sxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFByb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KHJlc29sdmVkUHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZFxuICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmVhcmVyVmFsdWUgPSBuZWFyZXIocmVzb2x2ZWRQcm9taXNlKTtcbiAgICAgICAgaWYgKGlzUHJvbWlzZShuZWFyZXJWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5lYXJlclZhbHVlOyAvLyBzaG9ydGVuIGNoYWluXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5lYXJlclZhbHVlO1xuICAgIH07XG5cbiAgICBwcm9taXNlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghcmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJwZW5kaW5nXCIgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZWRQcm9taXNlLmluc3BlY3QoKTtcbiAgICB9O1xuXG4gICAgaWYgKFEubG9uZ1N0YWNrU3VwcG9ydCAmJiBoYXNTdGFja3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBkb24ndCB0cnkgdG8gdXNlIGBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZWAgb3IgdHJhbnNmZXIgdGhlXG4gICAgICAgICAgICAvLyBhY2Nlc3NvciBhcm91bmQ7IHRoYXQgY2F1c2VzIG1lbW9yeSBsZWFrcyBhcyBwZXIgR0gtMTExLiBKdXN0XG4gICAgICAgICAgICAvLyByZWlmeSB0aGUgc3RhY2sgdHJhY2UgYXMgYSBzdHJpbmcgQVNBUC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lLCBjdXQgb2ZmIHRoZSBmaXJzdCBsaW5lOyBpdCdzIGFsd2F5cyBqdXN0XG4gICAgICAgICAgICAvLyBcIltvYmplY3QgUHJvbWlzZV1cXG5cIiwgYXMgcGVyIHRoZSBgdG9TdHJpbmdgLlxuICAgICAgICAgICAgcHJvbWlzZS5zdGFjayA9IGUuc3RhY2suc3Vic3RyaW5nKGUuc3RhY2suaW5kZXhPZihcIlxcblwiKSArIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTk9URTogd2UgZG8gdGhlIGNoZWNrcyBmb3IgYHJlc29sdmVkUHJvbWlzZWAgaW4gZWFjaCBtZXRob2QsIGluc3RlYWQgb2ZcbiAgICAvLyBjb25zb2xpZGF0aW5nIHRoZW0gaW50byBgYmVjb21lYCwgc2luY2Ugb3RoZXJ3aXNlIHdlJ2QgY3JlYXRlIG5ld1xuICAgIC8vIHByb21pc2VzIHdpdGggdGhlIGxpbmVzIGBiZWNvbWUod2hhdGV2ZXIodmFsdWUpKWAuIFNlZSBlLmcuIEdILTI1Mi5cblxuICAgIGZ1bmN0aW9uIGJlY29tZShuZXdQcm9taXNlKSB7XG4gICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5ld1Byb21pc2U7XG4gICAgICAgIHByb21pc2Uuc291cmNlID0gbmV3UHJvbWlzZTtcblxuICAgICAgICBhcnJheV9yZWR1Y2UobWVzc2FnZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5ld1Byb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KG5ld1Byb21pc2UsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG5cbiAgICAgICAgbWVzc2FnZXMgPSB2b2lkIDA7XG4gICAgICAgIHByb2dyZXNzTGlzdGVuZXJzID0gdm9pZCAwO1xuICAgIH1cblxuICAgIGRlZmVycmVkLnByb21pc2UgPSBwcm9taXNlO1xuICAgIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKFEodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgZGVmZXJyZWQuZnVsZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoZnVsZmlsbCh2YWx1ZSkpO1xuICAgIH07XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUocmVqZWN0KHJlYXNvbikpO1xuICAgIH07XG4gICAgZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9ncmVzc0xpc3RlbmVycywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvZ3Jlc3NMaXN0ZW5lcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcihwcm9ncmVzcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlZmVycmVkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBOb2RlLXN0eWxlIGNhbGxiYWNrIHRoYXQgd2lsbCByZXNvbHZlIG9yIHJlamVjdCB0aGUgZGVmZXJyZWRcbiAqIHByb21pc2UuXG4gKiBAcmV0dXJucyBhIG5vZGViYWNrXG4gKi9cbmRlZmVyLnByb3RvdHlwZS5tYWtlTm9kZVJlc29sdmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVycm9yLCB2YWx1ZSkge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHNlbGYucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKipcbiAqIEBwYXJhbSByZXNvbHZlciB7RnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG5vdGhpbmcgYW5kIGFjY2VwdHNcbiAqIHRoZSByZXNvbHZlLCByZWplY3QsIGFuZCBub3RpZnkgZnVuY3Rpb25zIGZvciBhIGRlZmVycmVkLlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgbWF5IGJlIHJlc29sdmVkIHdpdGggdGhlIGdpdmVuIHJlc29sdmUgYW5kIHJlamVjdFxuICogZnVuY3Rpb25zLCBvciByZWplY3RlZCBieSBhIHRocm93biBleGNlcHRpb24gaW4gcmVzb2x2ZXJcbiAqL1xuUS5Qcm9taXNlID0gcHJvbWlzZTsgLy8gRVM2XG5RLnByb21pc2UgPSBwcm9taXNlO1xuZnVuY3Rpb24gcHJvbWlzZShyZXNvbHZlcikge1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVzb2x2ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB0cnkge1xuICAgICAgICByZXNvbHZlcihkZWZlcnJlZC5yZXNvbHZlLCBkZWZlcnJlZC5yZWplY3QsIGRlZmVycmVkLm5vdGlmeSk7XG4gICAgfSBjYXRjaCAocmVhc29uKSB7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChyZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxucHJvbWlzZS5yYWNlID0gcmFjZTsgLy8gRVM2XG5wcm9taXNlLmFsbCA9IGFsbDsgLy8gRVM2XG5wcm9taXNlLnJlamVjdCA9IHJlamVjdDsgLy8gRVM2XG5wcm9taXNlLnJlc29sdmUgPSBROyAvLyBFUzZcblxuLy8gWFhYIGV4cGVyaW1lbnRhbC4gIFRoaXMgbWV0aG9kIGlzIGEgd2F5IHRvIGRlbm90ZSB0aGF0IGEgbG9jYWwgdmFsdWUgaXNcbi8vIHNlcmlhbGl6YWJsZSBhbmQgc2hvdWxkIGJlIGltbWVkaWF0ZWx5IGRpc3BhdGNoZWQgdG8gYSByZW1vdGUgdXBvbiByZXF1ZXN0LFxuLy8gaW5zdGVhZCBvZiBwYXNzaW5nIGEgcmVmZXJlbmNlLlxuUS5wYXNzQnlDb3B5ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIC8vZnJlZXplKG9iamVjdCk7XG4gICAgLy9wYXNzQnlDb3BpZXMuc2V0KG9iamVjdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIG9iamVjdDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSWYgdHdvIHByb21pc2VzIGV2ZW50dWFsbHkgZnVsZmlsbCB0byB0aGUgc2FtZSB2YWx1ZSwgcHJvbWlzZXMgdGhhdCB2YWx1ZSxcbiAqIGJ1dCBvdGhlcndpc2UgcmVqZWN0cy5cbiAqIEBwYXJhbSB4IHtBbnkqfVxuICogQHBhcmFtIHkge0FueSp9XG4gKiBAcmV0dXJucyB7QW55Kn0gYSBwcm9taXNlIGZvciB4IGFuZCB5IGlmIHRoZXkgYXJlIHRoZSBzYW1lLCBidXQgYSByZWplY3Rpb25cbiAqIG90aGVyd2lzZS5cbiAqXG4gKi9cblEuam9pbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIFEoeCkuam9pbih5KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAodGhhdCkge1xuICAgIHJldHVybiBRKFt0aGlzLCB0aGF0XSkuc3ByZWFkKGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIGlmICh4ID09PSB5KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBcIj09PVwiIHNob3VsZCBiZSBPYmplY3QuaXMgb3IgZXF1aXZcbiAgICAgICAgICAgIHJldHVybiB4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3Qgam9pbjogbm90IHRoZSBzYW1lOiBcIiArIHggKyBcIiBcIiArIHkpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZmlyc3Qgb2YgYW4gYXJyYXkgb2YgcHJvbWlzZXMgdG8gYmVjb21lIHNldHRsZWQuXG4gKiBAcGFyYW0gYW5zd2VycyB7QXJyYXlbQW55Kl19IHByb21pc2VzIHRvIHJhY2VcbiAqIEByZXR1cm5zIHtBbnkqfSB0aGUgZmlyc3QgcHJvbWlzZSB0byBiZSBzZXR0bGVkXG4gKi9cblEucmFjZSA9IHJhY2U7XG5mdW5jdGlvbiByYWNlKGFuc3dlclBzKSB7XG4gICAgcmV0dXJuIHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdGhpcyBvbmNlIHdlIGNhbiBhc3N1bWUgYXQgbGVhc3QgRVM1XG4gICAgICAgIC8vIGFuc3dlclBzLmZvckVhY2goZnVuY3Rpb24gKGFuc3dlclApIHtcbiAgICAgICAgLy8gICAgIFEoYW5zd2VyUCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAvLyB9KTtcbiAgICAgICAgLy8gVXNlIHRoaXMgaW4gdGhlIG1lYW50aW1lXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhbnN3ZXJQcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgUShhbnN3ZXJQc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnJhY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihRLnJhY2UpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgUHJvbWlzZSB3aXRoIGEgcHJvbWlzZSBkZXNjcmlwdG9yIG9iamVjdCBhbmQgb3B0aW9uYWwgZmFsbGJhY2tcbiAqIGZ1bmN0aW9uLiAgVGhlIGRlc2NyaXB0b3IgY29udGFpbnMgbWV0aG9kcyBsaWtlIHdoZW4ocmVqZWN0ZWQpLCBnZXQobmFtZSksXG4gKiBzZXQobmFtZSwgdmFsdWUpLCBwb3N0KG5hbWUsIGFyZ3MpLCBhbmQgZGVsZXRlKG5hbWUpLCB3aGljaCBhbGxcbiAqIHJldHVybiBlaXRoZXIgYSB2YWx1ZSwgYSBwcm9taXNlIGZvciBhIHZhbHVlLCBvciBhIHJlamVjdGlvbi4gIFRoZSBmYWxsYmFja1xuICogYWNjZXB0cyB0aGUgb3BlcmF0aW9uIG5hbWUsIGEgcmVzb2x2ZXIsIGFuZCBhbnkgZnVydGhlciBhcmd1bWVudHMgdGhhdCB3b3VsZFxuICogaGF2ZSBiZWVuIGZvcndhcmRlZCB0byB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kIGFib3ZlIGhhZCBhIG1ldGhvZCBiZWVuXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBwcm9wZXIgbmFtZS4gIFRoZSBBUEkgbWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCB0aGUgbmF0dXJlXG4gKiBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LCBhcGFydCBmcm9tIHRoYXQgaXQgaXMgdXNhYmxlIHdoZXJlZXZlciBwcm9taXNlcyBhcmVcbiAqIGJvdWdodCBhbmQgc29sZC5cbiAqL1xuUS5tYWtlUHJvbWlzZSA9IFByb21pc2U7XG5mdW5jdGlvbiBQcm9taXNlKGRlc2NyaXB0b3IsIGZhbGxiYWNrLCBpbnNwZWN0KSB7XG4gICAgaWYgKGZhbGxiYWNrID09PSB2b2lkIDApIHtcbiAgICAgICAgZmFsbGJhY2sgPSBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiUHJvbWlzZSBkb2VzIG5vdCBzdXBwb3J0IG9wZXJhdGlvbjogXCIgKyBvcFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChpbnNwZWN0ID09PSB2b2lkIDApIHtcbiAgICAgICAgaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGU6IFwidW5rbm93blwifTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIGFyZ3MpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yW29wXSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlc2NyaXB0b3Jbb3BdLmFwcGx5KHByb21pc2UsIGFyZ3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxsYmFjay5jYWxsKHByb21pc2UsIG9wLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXN1bHQgPSByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGluc3BlY3Q7XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZCBgdmFsdWVPZmAgYW5kIGBleGNlcHRpb25gIHN1cHBvcnRcbiAgICBpZiAoaW5zcGVjdCkge1xuICAgICAgICB2YXIgaW5zcGVjdGVkID0gaW5zcGVjdCgpO1xuICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgIHByb21pc2UuZXhjZXB0aW9uID0gaW5zcGVjdGVkLnJlYXNvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInBlbmRpbmdcIiB8fFxuICAgICAgICAgICAgICAgIGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdGVkLnZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgZG9uZSA9IGZhbHNlOyAgIC8vIGVuc3VyZSB0aGUgdW50cnVzdGVkIHByb21pc2UgbWFrZXMgYXQgbW9zdCBhXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5nbGUgY2FsbCB0byBvbmUgb2YgdGhlIGNhbGxiYWNrc1xuXG4gICAgZnVuY3Rpb24gX2Z1bGZpbGxlZCh2YWx1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBmdWxmaWxsZWQgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bGZpbGxlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcmVqZWN0ZWQoZXhjZXB0aW9uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGV4Y2VwdGlvbiwgc2VsZik7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3RlZChleGNlcHRpb24pO1xuICAgICAgICAgICAgfSBjYXRjaCAobmV3RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXdFeGNlcHRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHJvZ3Jlc3NlZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHByb2dyZXNzZWQgPT09IFwiZnVuY3Rpb25cIiA/IHByb2dyZXNzZWQodmFsdWUpIDogdmFsdWU7XG4gICAgfVxuXG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfZnVsZmlsbGVkKHZhbHVlKSk7XG4gICAgICAgIH0sIFwid2hlblwiLCBbZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfcmVqZWN0ZWQoZXhjZXB0aW9uKSk7XG4gICAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIC8vIFByb2dyZXNzIHByb3BhZ2F0b3IgbmVlZCB0byBiZSBhdHRhY2hlZCBpbiB0aGUgY3VycmVudCB0aWNrLlxuICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKHZvaWQgMCwgXCJ3aGVuXCIsIFt2b2lkIDAsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG4gICAgICAgIHZhciB0aHJldyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBfcHJvZ3Jlc3NlZCh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocmV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRocmV3KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkobmV3VmFsdWUpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5RLnRhcCA9IGZ1bmN0aW9uIChwcm9taXNlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRhcChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFdvcmtzIGFsbW9zdCBsaWtlIFwiZmluYWxseVwiLCBidXQgbm90IGNhbGxlZCBmb3IgcmVqZWN0aW9ucy5cbiAqIE9yaWdpbmFsIHJlc29sdXRpb24gdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggY2FsbGJhY2sgdW5hZmZlY3RlZC5cbiAqIENhbGxiYWNrIG1heSByZXR1cm4gYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBhd2FpdGVkIGZvci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7US5Qcm9taXNlfVxuICogQGV4YW1wbGVcbiAqIGRvU29tZXRoaW5nKClcbiAqICAgLnRoZW4oLi4uKVxuICogICAudGFwKGNvbnNvbGUubG9nKVxuICogICAudGhlbiguLi4pO1xuICovXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IFEoY2FsbGJhY2spO1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKHZhbHVlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBvbiBhIHByb21pc2UuXG4gKlxuICogR3VhcmFudGVlczpcbiAqXG4gKiAxLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLlxuICogMi4gdGhhdCBlaXRoZXIgdGhlIGZ1bGZpbGxlZCBjYWxsYmFjayBvciB0aGUgcmVqZWN0ZWQgY2FsbGJhY2sgd2lsbCBiZVxuICogICAgY2FsbGVkLCBidXQgbm90IGJvdGguXG4gKiAzLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoaXMgdHVybi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgICAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgdG8gb2JzZXJ2ZVxuICogQHBhcmFtIGZ1bGZpbGxlZCAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogQHBhcmFtIHJlamVjdGVkICAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIHJlamVjdGlvbiBleGNlcHRpb25cbiAqIEBwYXJhbSBwcm9ncmVzc2VkIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIGludm9rZWQgY2FsbGJhY2tcbiAqL1xuUS53aGVuID0gd2hlbjtcbmZ1bmN0aW9uIHdoZW4odmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUSh2YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGhlblJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9KTtcbn07XG5cblEudGhlblJlc29sdmUgPSBmdW5jdGlvbiAocHJvbWlzZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyByZWFzb247IH0pO1xufTtcblxuUS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHByb21pc2UsIHJlYXNvbikge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZWplY3QocmVhc29uKTtcbn07XG5cbi8qKlxuICogSWYgYW4gb2JqZWN0IGlzIG5vdCBhIHByb21pc2UsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlLlxuICogSWYgYSBwcm9taXNlIGlzIHJlamVjdGVkLCBpdCBpcyBhcyBcIm5lYXJcIiBhcyBwb3NzaWJsZSB0b28uXG4gKiBJZiBpdOKAmXMgYSBmdWxmaWxsZWQgcHJvbWlzZSwgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5lYXJlci5cbiAqIElmIGl04oCZcyBhIGRlZmVycmVkIHByb21pc2UgYW5kIHRoZSBkZWZlcnJlZCBoYXMgYmVlbiByZXNvbHZlZCwgdGhlXG4gKiByZXNvbHV0aW9uIGlzIFwibmVhcmVyXCIuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBtb3N0IHJlc29sdmVkIChuZWFyZXN0KSBmb3JtIG9mIHRoZSBvYmplY3RcbiAqL1xuXG4vLyBYWFggc2hvdWxkIHdlIHJlLWRvIHRoaXM/XG5RLm5lYXJlciA9IG5lYXJlcjtcbmZ1bmN0aW9uIG5lYXJlcih2YWx1ZSkge1xuICAgIGlmIChpc1Byb21pc2UodmFsdWUpKSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSB2YWx1ZS5pbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHByb21pc2UuXG4gKiBPdGhlcndpc2UgaXQgaXMgYSBmdWxmaWxsZWQgdmFsdWUuXG4gKi9cblEuaXNQcm9taXNlID0gaXNQcm9taXNlO1xuZnVuY3Rpb24gaXNQcm9taXNlKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBQcm9taXNlO1xufVxuXG5RLmlzUHJvbWlzZUFsaWtlID0gaXNQcm9taXNlQWxpa2U7XG5mdW5jdGlvbiBpc1Byb21pc2VBbGlrZShvYmplY3QpIHtcbiAgICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSAmJiB0eXBlb2Ygb2JqZWN0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBwZW5kaW5nIHByb21pc2UsIG1lYW5pbmcgbm90XG4gKiBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG4gKi9cblEuaXNQZW5kaW5nID0gaXNQZW5kaW5nO1xuZnVuY3Rpb24gaXNQZW5kaW5nKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJwZW5kaW5nXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHZhbHVlIG9yIGZ1bGZpbGxlZFxuICogcHJvbWlzZS5cbiAqL1xuUS5pc0Z1bGZpbGxlZCA9IGlzRnVsZmlsbGVkO1xuZnVuY3Rpb24gaXNGdWxmaWxsZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuICFpc1Byb21pc2Uob2JqZWN0KSB8fCBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0Z1bGZpbGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHJlamVjdGVkIHByb21pc2UuXG4gKi9cblEuaXNSZWplY3RlZCA9IGlzUmVqZWN0ZWQ7XG5mdW5jdGlvbiBpc1JlamVjdGVkKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzUmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59O1xuXG4vLy8vIEJFR0lOIFVOSEFORExFRCBSRUpFQ1RJT04gVFJBQ0tJTkdcblxuLy8gVGhpcyBwcm9taXNlIGxpYnJhcnkgY29uc3VtZXMgZXhjZXB0aW9ucyB0aHJvd24gaW4gaGFuZGxlcnMgc28gdGhleSBjYW4gYmVcbi8vIGhhbmRsZWQgYnkgYSBzdWJzZXF1ZW50IHByb21pc2UuICBUaGUgZXhjZXB0aW9ucyBnZXQgYWRkZWQgdG8gdGhpcyBhcnJheSB3aGVuXG4vLyB0aGV5IGFyZSBjcmVhdGVkLCBhbmQgcmVtb3ZlZCB3aGVuIHRoZXkgYXJlIGhhbmRsZWQuICBOb3RlIHRoYXQgaW4gRVM2IG9yXG4vLyBzaGltbWVkIGVudmlyb25tZW50cywgdGhpcyB3b3VsZCBuYXR1cmFsbHkgYmUgYSBgU2V0YC5cbnZhciB1bmhhbmRsZWRSZWFzb25zID0gW107XG52YXIgdW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IHRydWU7XG5cbmZ1bmN0aW9uIHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpIHtcbiAgICB1bmhhbmRsZWRSZWFzb25zLmxlbmd0aCA9IDA7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyYWNrUmVqZWN0aW9uKHByb21pc2UsIHJlYXNvbikge1xuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBwcm9jZXNzLmVtaXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChhcnJheV9pbmRleE9mKHVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInVuaGFuZGxlZFJlamVjdGlvblwiLCByZWFzb24sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucy5wdXNoKHByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgaWYgKHJlYXNvbiAmJiB0eXBlb2YgcmVhc29uLnN0YWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChyZWFzb24uc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChcIihubyBzdGFjaykgXCIgKyByZWFzb24pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdW50cmFja1JlamVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhdCA9IGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgaWYgKGF0ICE9PSAtMSkge1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXRSZXBvcnQgPSBhcnJheV9pbmRleE9mKHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgaWYgKGF0UmVwb3J0ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmVtaXQoXCJyZWplY3Rpb25IYW5kbGVkXCIsIHVuaGFuZGxlZFJlYXNvbnNbYXRdLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdFJlcG9ydCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5zcGxpY2UoYXQsIDEpO1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnNwbGljZShhdCwgMSk7XG4gICAgfVxufVxuXG5RLnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucyA9IHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucztcblxuUS5nZXRVbmhhbmRsZWRSZWFzb25zID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIE1ha2UgYSBjb3B5IHNvIHRoYXQgY29uc3VtZXJzIGNhbid0IGludGVyZmVyZSB3aXRoIG91ciBpbnRlcm5hbCBzdGF0ZS5cbiAgICByZXR1cm4gdW5oYW5kbGVkUmVhc29ucy5zbGljZSgpO1xufTtcblxuUS5zdG9wVW5oYW5kbGVkUmVqZWN0aW9uVHJhY2tpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCk7XG4gICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gZmFsc2U7XG59O1xuXG5yZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcblxuLy8vLyBFTkQgVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSByZWplY3RlZCBwcm9taXNlLlxuICogQHBhcmFtIHJlYXNvbiB2YWx1ZSBkZXNjcmliaW5nIHRoZSBmYWlsdXJlXG4gKi9cblEucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgIHZhciByZWplY3Rpb24gPSBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uIChyZWplY3RlZCkge1xuICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoZSBlcnJvciBoYXMgYmVlbiBoYW5kbGVkXG4gICAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICB1bnRyYWNrUmVqZWN0aW9uKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkID8gcmVqZWN0ZWQocmVhc29uKSA6IHRoaXM7XG4gICAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwicmVqZWN0ZWRcIiwgcmVhc29uOiByZWFzb24gfTtcbiAgICB9KTtcblxuICAgIC8vIE5vdGUgdGhhdCB0aGUgcmVhc29uIGhhcyBub3QgYmVlbiBoYW5kbGVkLlxuICAgIHRyYWNrUmVqZWN0aW9uKHJlamVjdGlvbiwgcmVhc29uKTtcblxuICAgIHJldHVybiByZWplY3Rpb247XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIGZ1bGZpbGxlZCBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2VcbiAqL1xuUS5mdWxmaWxsID0gZnVsZmlsbDtcbmZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHtcbiAgICByZXR1cm4gUHJvbWlzZSh7XG4gICAgICAgIFwid2hlblwiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZ2V0XCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwic2V0XCI6IGZ1bmN0aW9uIChuYW1lLCByaHMpIHtcbiAgICAgICAgICAgIHZhbHVlW25hbWVdID0gcmhzO1xuICAgICAgICB9LFxuICAgICAgICBcImRlbGV0ZVwiOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgZGVsZXRlIHZhbHVlW25hbWVdO1xuICAgICAgICB9LFxuICAgICAgICBcInBvc3RcIjogZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICAgICAgICAgIC8vIE1hcmsgTWlsbGVyIHByb3Bvc2VzIHRoYXQgcG9zdCB3aXRoIG5vIG5hbWUgc2hvdWxkIGFwcGx5IGFcbiAgICAgICAgICAgIC8vIHByb21pc2VkIGZ1bmN0aW9uLlxuICAgICAgICAgICAgaWYgKG5hbWUgPT09IG51bGwgfHwgbmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHZvaWQgMCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXS5hcHBseSh2YWx1ZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFwiYXBwbHlcIjogZnVuY3Rpb24gKHRoaXNwLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodGhpc3AsIGFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBcImtleXNcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdF9rZXlzKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0sIHZvaWQgMCwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwiZnVsZmlsbGVkXCIsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZW5hYmxlcyB0byBRIHByb21pc2VzLlxuICogQHBhcmFtIHByb21pc2UgdGhlbmFibGUgcHJvbWlzZVxuICogQHJldHVybnMgYSBRIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gY29lcmNlKHByb21pc2UpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvbWlzZS50aGVuKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG4vKipcbiAqIEFubm90YXRlcyBhbiBvYmplY3Qgc3VjaCB0aGF0IGl0IHdpbGwgbmV2ZXIgYmVcbiAqIHRyYW5zZmVycmVkIGF3YXkgZnJvbSB0aGlzIHByb2Nlc3Mgb3ZlciBhbnkgcHJvbWlzZVxuICogY29tbXVuaWNhdGlvbiBjaGFubmVsLlxuICogQHBhcmFtIG9iamVjdFxuICogQHJldHVybnMgcHJvbWlzZSBhIHdyYXBwaW5nIG9mIHRoYXQgb2JqZWN0IHRoYXRcbiAqIGFkZGl0aW9uYWxseSByZXNwb25kcyB0byB0aGUgXCJpc0RlZlwiIG1lc3NhZ2VcbiAqIHdpdGhvdXQgYSByZWplY3Rpb24uXG4gKi9cblEubWFzdGVyID0gbWFzdGVyO1xuZnVuY3Rpb24gbWFzdGVyKG9iamVjdCkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJpc0RlZlwiOiBmdW5jdGlvbiAoKSB7fVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKG9wLCBhcmdzKSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKTtcbiAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBRKG9iamVjdCkuaW5zcGVjdCgpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFNwcmVhZHMgdGhlIHZhbHVlcyBvZiBhIHByb21pc2VkIGFycmF5IG9mIGFyZ3VtZW50cyBpbnRvIHRoZVxuICogZnVsZmlsbG1lbnQgY2FsbGJhY2suXG4gKiBAcGFyYW0gZnVsZmlsbGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdmFyaWFkaWMgYXJndW1lbnRzIGZyb20gdGhlXG4gKiBwcm9taXNlZCBhcnJheVxuICogQHBhcmFtIHJlamVjdGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgcHJvbWlzZVxuICogaXMgcmVqZWN0ZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb3IgdGhyb3duIGV4Y2VwdGlvbiBvZlxuICogZWl0aGVyIGNhbGxiYWNrLlxuICovXG5RLnNwcmVhZCA9IHNwcmVhZDtcbmZ1bmN0aW9uIHNwcmVhZCh2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS5zcHJlYWQoZnVsZmlsbGVkLCByZWplY3RlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkudGhlbihmdW5jdGlvbiAoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGxlZC5hcHBseSh2b2lkIDAsIGFycmF5KTtcbiAgICB9LCByZWplY3RlZCk7XG59O1xuXG4vKipcbiAqIFRoZSBhc3luYyBmdW5jdGlvbiBpcyBhIGRlY29yYXRvciBmb3IgZ2VuZXJhdG9yIGZ1bmN0aW9ucywgdHVybmluZ1xuICogdGhlbSBpbnRvIGFzeW5jaHJvbm91cyBnZW5lcmF0b3JzLiAgQWx0aG91Z2ggZ2VuZXJhdG9ycyBhcmUgb25seSBwYXJ0XG4gKiBvZiB0aGUgbmV3ZXN0IEVDTUFTY3JpcHQgNiBkcmFmdHMsIHRoaXMgY29kZSBkb2VzIG5vdCBjYXVzZSBzeW50YXhcbiAqIGVycm9ycyBpbiBvbGRlciBlbmdpbmVzLiAgVGhpcyBjb2RlIHNob3VsZCBjb250aW51ZSB0byB3b3JrIGFuZCB3aWxsXG4gKiBpbiBmYWN0IGltcHJvdmUgb3ZlciB0aW1lIGFzIHRoZSBsYW5ndWFnZSBpbXByb3Zlcy5cbiAqXG4gKiBFUzYgZ2VuZXJhdG9ycyBhcmUgY3VycmVudGx5IHBhcnQgb2YgVjggdmVyc2lvbiAzLjE5IHdpdGggdGhlXG4gKiAtLWhhcm1vbnktZ2VuZXJhdG9ycyBydW50aW1lIGZsYWcgZW5hYmxlZC4gIFNwaWRlck1vbmtleSBoYXMgaGFkIHRoZW1cbiAqIGZvciBsb25nZXIsIGJ1dCB1bmRlciBhbiBvbGRlciBQeXRob24taW5zcGlyZWQgZm9ybS4gIFRoaXMgZnVuY3Rpb25cbiAqIHdvcmtzIG9uIGJvdGgga2luZHMgb2YgZ2VuZXJhdG9ycy5cbiAqXG4gKiBEZWNvcmF0ZXMgYSBnZW5lcmF0b3IgZnVuY3Rpb24gc3VjaCB0aGF0OlxuICogIC0gaXQgbWF5IHlpZWxkIHByb21pc2VzXG4gKiAgLSBleGVjdXRpb24gd2lsbCBjb250aW51ZSB3aGVuIHRoYXQgcHJvbWlzZSBpcyBmdWxmaWxsZWRcbiAqICAtIHRoZSB2YWx1ZSBvZiB0aGUgeWllbGQgZXhwcmVzc2lvbiB3aWxsIGJlIHRoZSBmdWxmaWxsZWQgdmFsdWVcbiAqICAtIGl0IHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlICh3aGVuIHRoZSBnZW5lcmF0b3JcbiAqICAgIHN0b3BzIGl0ZXJhdGluZylcbiAqICAtIHRoZSBkZWNvcmF0ZWQgZnVuY3Rpb24gcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqICAgIG9mIHRoZSBnZW5lcmF0b3Igb3IgdGhlIGZpcnN0IHJlamVjdGVkIHByb21pc2UgYW1vbmcgdGhvc2VcbiAqICAgIHlpZWxkZWQuXG4gKiAgLSBpZiBhbiBlcnJvciBpcyB0aHJvd24gaW4gdGhlIGdlbmVyYXRvciwgaXQgcHJvcGFnYXRlcyB0aHJvdWdoXG4gKiAgICBldmVyeSBmb2xsb3dpbmcgeWllbGQgdW50aWwgaXQgaXMgY2F1Z2h0LCBvciB1bnRpbCBpdCBlc2NhcGVzXG4gKiAgICB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGFsdG9nZXRoZXIsIGFuZCBpcyB0cmFuc2xhdGVkIGludG8gYVxuICogICAgcmVqZWN0aW9uIGZvciB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZGVjb3JhdGVkIGdlbmVyYXRvci5cbiAqL1xuUS5hc3luYyA9IGFzeW5jO1xuZnVuY3Rpb24gYXN5bmMobWFrZUdlbmVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHdoZW4gdmVyYiBpcyBcInNlbmRcIiwgYXJnIGlzIGEgdmFsdWVcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwidGhyb3dcIiwgYXJnIGlzIGFuIGV4Y2VwdGlvblxuICAgICAgICBmdW5jdGlvbiBjb250aW51ZXIodmVyYiwgYXJnKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICAgICAgICAvLyBVbnRpbCBWOCAzLjE5IC8gQ2hyb21pdW0gMjkgaXMgcmVsZWFzZWQsIFNwaWRlck1vbmtleSBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gZW5naW5lIHRoYXQgaGFzIGEgZGVwbG95ZWQgYmFzZSBvZiBicm93c2VycyB0aGF0IHN1cHBvcnQgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgIC8vIEhvd2V2ZXIsIFNNJ3MgZ2VuZXJhdG9ycyB1c2UgdGhlIFB5dGhvbi1pbnNwaXJlZCBzZW1hbnRpY3Mgb2ZcbiAgICAgICAgICAgIC8vIG91dGRhdGVkIEVTNiBkcmFmdHMuICBXZSB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgRVM2LCBidXQgd2UnZCBhbHNvXG4gICAgICAgICAgICAvLyBsaWtlIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gdXNlIGdlbmVyYXRvcnMgaW4gZGVwbG95ZWQgYnJvd3NlcnMsIHNvXG4gICAgICAgICAgICAvLyB3ZSBhbHNvIHN1cHBvcnQgUHl0aG9uLXN0eWxlIGdlbmVyYXRvcnMuICBBdCBzb21lIHBvaW50IHdlIGNhbiByZW1vdmVcbiAgICAgICAgICAgIC8vIHRoaXMgYmxvY2suXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgU3RvcEl0ZXJhdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIC8vIEVTNiBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdG9yW3ZlcmJdKGFyZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBRKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LnZhbHVlLCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTcGlkZXJNb25rZXkgR2VuZXJhdG9yc1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBSZW1vdmUgdGhpcyBjYXNlIHdoZW4gU00gZG9lcyBFUzYgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RvcEl0ZXJhdGlvbihleGNlcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUShleGNlcHRpb24udmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB3aGVuKHJlc3VsdCwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBnZW5lcmF0b3IgPSBtYWtlR2VuZXJhdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJuZXh0XCIpO1xuICAgICAgICB2YXIgZXJyYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJ0aHJvd1wiKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBUaGUgc3Bhd24gZnVuY3Rpb24gaXMgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZCBhc3luYyB0aGF0IGltbWVkaWF0ZWx5XG4gKiBjYWxscyB0aGUgZ2VuZXJhdG9yIGFuZCBhbHNvIGVuZHMgdGhlIHByb21pc2UgY2hhaW4sIHNvIHRoYXQgYW55XG4gKiB1bmhhbmRsZWQgZXJyb3JzIGFyZSB0aHJvd24gaW5zdGVhZCBvZiBmb3J3YXJkZWQgdG8gdGhlIGVycm9yXG4gKiBoYW5kbGVyLiBUaGlzIGlzIHVzZWZ1bCBiZWNhdXNlIGl0J3MgZXh0cmVtZWx5IGNvbW1vbiB0byBydW5cbiAqIGdlbmVyYXRvcnMgYXQgdGhlIHRvcC1sZXZlbCB0byB3b3JrIHdpdGggbGlicmFyaWVzLlxuICovXG5RLnNwYXduID0gc3Bhd247XG5mdW5jdGlvbiBzcGF3bihtYWtlR2VuZXJhdG9yKSB7XG4gICAgUS5kb25lKFEuYXN5bmMobWFrZUdlbmVyYXRvcikoKSk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBpbnRlcmZhY2Ugb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuLyoqXG4gKiBUaHJvd3MgYSBSZXR1cm5WYWx1ZSBleGNlcHRpb24gdG8gc3RvcCBhbiBhc3luY2hyb25vdXMgZ2VuZXJhdG9yLlxuICpcbiAqIFRoaXMgaW50ZXJmYWNlIGlzIGEgc3RvcC1nYXAgbWVhc3VyZSB0byBzdXBwb3J0IGdlbmVyYXRvciByZXR1cm5cbiAqIHZhbHVlcyBpbiBvbGRlciBGaXJlZm94L1NwaWRlck1vbmtleS4gIEluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBFUzZcbiAqIGdlbmVyYXRvcnMgbGlrZSBDaHJvbWl1bSAyOSwganVzdCB1c2UgXCJyZXR1cm5cIiBpbiB5b3VyIGdlbmVyYXRvclxuICogZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSB0aGUgcmV0dXJuIHZhbHVlIGZvciB0aGUgc3Vycm91bmRpbmcgZ2VuZXJhdG9yXG4gKiBAdGhyb3dzIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB3aXRoIHRoZSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBFUzYgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24qICgpIHtcbiAqICAgICAgdmFyIGZvbyA9IHlpZWxkIGdldEZvb1Byb21pc2UoKTtcbiAqICAgICAgdmFyIGJhciA9IHlpZWxkIGdldEJhclByb21pc2UoKTtcbiAqICAgICAgcmV0dXJuIGZvbyArIGJhcjtcbiAqIH0pXG4gKiAvLyBPbGRlciBTcGlkZXJNb25rZXkgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24gKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICBRLnJldHVybihmb28gKyBiYXIpO1xuICogfSlcbiAqL1xuUVtcInJldHVyblwiXSA9IF9yZXR1cm47XG5mdW5jdGlvbiBfcmV0dXJuKHZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IFFSZXR1cm5WYWx1ZSh2YWx1ZSk7XG59XG5cbi8qKlxuICogVGhlIHByb21pc2VkIGZ1bmN0aW9uIGRlY29yYXRvciBlbnN1cmVzIHRoYXQgYW55IHByb21pc2UgYXJndW1lbnRzXG4gKiBhcmUgc2V0dGxlZCBhbmQgcGFzc2VkIGFzIHZhbHVlcyAoYHRoaXNgIGlzIGFsc28gc2V0dGxlZCBhbmQgcGFzc2VkXG4gKiBhcyBhIHZhbHVlKS4gIEl0IHdpbGwgYWxzbyBlbnN1cmUgdGhhdCB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb24gaXNcbiAqIGFsd2F5cyBhIHByb21pc2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBRLnByb21pc2VkKGZ1bmN0aW9uIChhLCBiKSB7XG4gKiAgICAgcmV0dXJuIGEgKyBiO1xuICogfSk7XG4gKiBhZGQoUShhKSwgUShCKSk7XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGRlY29yYXRlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBoYXMgYmVlbiBkZWNvcmF0ZWQuXG4gKi9cblEucHJvbWlzZWQgPSBwcm9taXNlZDtcbmZ1bmN0aW9uIHByb21pc2VkKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNwcmVhZChbdGhpcywgYWxsKGFyZ3VtZW50cyldLCBmdW5jdGlvbiAoc2VsZiwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vKipcbiAqIHNlbmRzIGEgbWVzc2FnZSB0byBhIHZhbHVlIGluIGEgZnV0dXJlIHR1cm5cbiAqIEBwYXJhbSBvYmplY3QqIHRoZSByZWNpcGllbnRcbiAqIEBwYXJhbSBvcCB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBvcGVyYXRpb24sIGUuZy4sIFwid2hlblwiLFxuICogQHBhcmFtIGFyZ3MgZnVydGhlciBhcmd1bWVudHMgdG8gYmUgZm9yd2FyZGVkIHRvIHRoZSBvcGVyYXRpb25cbiAqIEByZXR1cm5zIHJlc3VsdCB7UHJvbWlzZX0gYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb25cbiAqL1xuUS5kaXNwYXRjaCA9IGRpc3BhdGNoO1xuZnVuY3Rpb24gZGlzcGF0Y2gob2JqZWN0LCBvcCwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2gob3AsIGFyZ3MpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uIChvcCwgYXJncykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnByb21pc2VEaXNwYXRjaChkZWZlcnJlZC5yZXNvbHZlLCBvcCwgYXJncyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZ2V0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBwcm9wZXJ0eSB2YWx1ZVxuICovXG5RLmdldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZ2V0XCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIG9iamVjdCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBzZXRcbiAqIEBwYXJhbSB2YWx1ZSAgICAgbmV3IHZhbHVlIG9mIHByb3BlcnR5XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5zZXQgPSBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBEZWxldGVzIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5kZWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kZWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImRlbGV0ZVwiXSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIHZhbHVlICAgICBhIHZhbHVlIHRvIHBvc3QsIHR5cGljYWxseSBhbiBhcnJheSBvZlxuICogICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uIGFyZ3VtZW50cyBmb3IgcHJvbWlzZXMgdGhhdFxuICogICAgICAgICAgICAgICAgICBhcmUgdWx0aW1hdGVseSBiYWNrZWQgd2l0aCBgcmVzb2x2ZWAgdmFsdWVzLFxuICogICAgICAgICAgICAgICAgICBhcyBvcHBvc2VkIHRvIHRob3NlIGJhY2tlZCB3aXRoIFVSTHNcbiAqICAgICAgICAgICAgICAgICAgd2hlcmVpbiB0aGUgcG9zdGVkIHZhbHVlIGNhbiBiZSBhbnlcbiAqICAgICAgICAgICAgICAgICAgSlNPTiBzZXJpYWxpemFibGUgb2JqZWN0LlxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cbi8vIGJvdW5kIGxvY2FsbHkgYmVjYXVzZSBpdCBpcyB1c2VkIGJ5IG90aGVyIG1ldGhvZHNcblEubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEucG9zdCA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuLyoqXG4gKiBJbnZva2VzIGEgbWV0aG9kIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIG1ldGhvZCB0byBpbnZva2VcbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgaW52b2NhdGlvbiBhcmd1bWVudHNcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNlbmQgPSAvLyBYWFggTWFyayBNaWxsZXIncyBwcm9wb3NlZCBwYXJsYW5jZVxuUS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLmludm9rZSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5Qcm9taXNlLnByb3RvdHlwZS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIGFyZ3MgICAgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUS5mYXBwbHkgPSBmdW5jdGlvbiAob2JqZWN0LCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIENhbGxzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUVtcInRyeVwiXSA9XG5RLmZjYWxsID0gZnVuY3Rpb24gKG9iamVjdCAvKiAuLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFycmF5X3NsaWNlKGFyZ3VtZW50cyldKTtcbn07XG5cbi8qKlxuICogQmluZHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uLCB0cmFuc2Zvcm1pbmcgcmV0dXJuIHZhbHVlcyBpbnRvIGEgZnVsZmlsbGVkXG4gKiBwcm9taXNlIGFuZCB0aHJvd24gZXJyb3JzIGludG8gYSByZWplY3RlZCBvbmUuXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZiaW5kID0gZnVuY3Rpb24gKG9iamVjdCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBwcm9taXNlID0gUShvYmplY3QpO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblByb21pc2UucHJvdG90eXBlLmZiaW5kID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBSZXF1ZXN0cyB0aGUgbmFtZXMgb2YgdGhlIG93bmVkIHByb3BlcnRpZXMgb2YgYSBwcm9taXNlZFxuICogb2JqZWN0IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUga2V5cyBvZiB0aGUgZXZlbnR1YWxseSBzZXR0bGVkIG9iamVjdFxuICovXG5RLmtleXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkuICBJZiBhbnkgb2ZcbiAqIHRoZSBwcm9taXNlcyBnZXRzIHJlamVjdGVkLCB0aGUgd2hvbGUgYXJyYXkgaXMgcmVqZWN0ZWQgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXNcbiAqL1xuLy8gQnkgTWFyayBNaWxsZXJcbi8vIGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPXN0cmF3bWFuOmNvbmN1cnJlbmN5JnJldj0xMzA4Nzc2NTIxI2FsbGZ1bGZpbGxlZFxuUS5hbGwgPSBhbGw7XG5mdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gd2hlbihwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHByb21pc2UsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc25hcHNob3Q7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgaXNQcm9taXNlKHByb21pc2UpICYmXG4gICAgICAgICAgICAgICAgKHNuYXBzaG90ID0gcHJvbWlzZS5pbnNwZWN0KCkpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSBzbmFwc2hvdC52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgKytwZW5kaW5nQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hlbihcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtLXBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChwcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHsgaW5kZXg6IGluZGV4LCB2YWx1ZTogcHJvZ3Jlc3MgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHByb21pc2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2Ugb2YgYW4gYXJyYXkuIFByaW9yIHJlamVjdGVkIHByb21pc2VzIGFyZVxuICogaWdub3JlZC4gIFJlamVjdHMgb25seSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICogQHBhcmFtIHtBcnJheSp9IGFuIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIG9yIHByb21pc2VzIGZvciB2YWx1ZXNcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmdWxmaWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2UsXG4gKiBvciBhIHJlamVjdGVkIHByb21pc2UgaWYgYWxsIHByb21pc2VzIGFyZSByZWplY3RlZC5cbiAqL1xuUS5hbnkgPSBhbnk7XG5cbmZ1bmN0aW9uIGFueShwcm9taXNlcykge1xuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHZhciBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgICB2YXIgcGVuZGluZ0NvdW50ID0gMDtcbiAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uIChwcmV2LCBjdXJyZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHByb21pc2VzW2luZGV4XTtcblxuICAgICAgICBwZW5kaW5nQ291bnQrKztcblxuICAgICAgICB3aGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBvblByb2dyZXNzKTtcbiAgICAgICAgZnVuY3Rpb24gb25GdWxmaWxsZWQocmVzdWx0KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25SZWplY3RlZCgpIHtcbiAgICAgICAgICAgIHBlbmRpbmdDb3VudC0tO1xuICAgICAgICAgICAgaWYgKHBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiQ2FuJ3QgZ2V0IGZ1bGZpbGxtZW50IHZhbHVlIGZyb20gYW55IHByb21pc2UsIGFsbCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwicHJvbWlzZXMgd2VyZSByZWplY3RlZC5cIlxuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeSh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBwcm9ncmVzc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB1bmRlZmluZWQpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxuLyoqXG4gKiBXYWl0cyBmb3IgYWxsIHByb21pc2VzIHRvIGJlIHNldHRsZWQsIGVpdGhlciBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLiAgVGhpcyBpcyBkaXN0aW5jdCBmcm9tIGBhbGxgIHNpbmNlIHRoYXQgd291bGQgc3RvcFxuICogd2FpdGluZyBhdCB0aGUgZmlyc3QgcmVqZWN0aW9uLiAgVGhlIHByb21pc2UgcmV0dXJuZWQgYnlcbiAqIGBhbGxSZXNvbHZlZGAgd2lsbCBuZXZlciBiZSByZWplY3RlZC5cbiAqIEBwYXJhbSBwcm9taXNlcyBhIHByb21pc2UgZm9yIGFuIGFycmF5IChvciBhbiBhcnJheSkgb2YgcHJvbWlzZXNcbiAqIChvciB2YWx1ZXMpXG4gKiBAcmV0dXJuIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgcHJvbWlzZXNcbiAqL1xuUS5hbGxSZXNvbHZlZCA9IGRlcHJlY2F0ZShhbGxSZXNvbHZlZCwgXCJhbGxSZXNvbHZlZFwiLCBcImFsbFNldHRsZWRcIik7XG5mdW5jdGlvbiBhbGxSZXNvbHZlZChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcHJvbWlzZXMgPSBhcnJheV9tYXAocHJvbWlzZXMsIFEpO1xuICAgICAgICByZXR1cm4gd2hlbihhbGwoYXJyYXlfbWFwKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHdoZW4ocHJvbWlzZSwgbm9vcCwgbm9vcCk7XG4gICAgICAgIH0pKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbFJlc29sdmVkKHRoaXMpO1xufTtcblxuLyoqXG4gKiBAc2VlIFByb21pc2UjYWxsU2V0dGxlZFxuICovXG5RLmFsbFNldHRsZWQgPSBhbGxTZXR0bGVkO1xuZnVuY3Rpb24gYWxsU2V0dGxlZChwcm9taXNlcykge1xuICAgIHJldHVybiBRKHByb21pc2VzKS5hbGxTZXR0bGVkKCk7XG59XG5cbi8qKlxuICogVHVybnMgYW4gYXJyYXkgb2YgcHJvbWlzZXMgaW50byBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZWlyIHN0YXRlcyAoYXNcbiAqIHJldHVybmVkIGJ5IGBpbnNwZWN0YCkgd2hlbiB0aGV5IGhhdmUgYWxsIHNldHRsZWQuXG4gKiBAcGFyYW0ge0FycmF5W0FueSpdfSB2YWx1ZXMgYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMge0FycmF5W1N0YXRlXX0gYW4gYXJyYXkgb2Ygc3RhdGVzIGZvciB0aGUgcmVzcGVjdGl2ZSB2YWx1ZXMuXG4gKi9cblByb21pc2UucHJvdG90eXBlLmFsbFNldHRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcmV0dXJuIGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlID0gUShwcm9taXNlKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJlZ2FyZGxlc3MoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuaW5zcGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihyZWdhcmRsZXNzLCByZWdhcmRsZXNzKTtcbiAgICAgICAgfSkpO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBDYXB0dXJlcyB0aGUgZmFpbHVyZSBvZiBhIHByb21pc2UsIGdpdmluZyBhbiBvcG9ydHVuaXR5IHRvIHJlY292ZXJcbiAqIHdpdGggYSBjYWxsYmFjay4gIElmIHRoZSBnaXZlbiBwcm9taXNlIGlzIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gKiBwcm9taXNlIGlzIGZ1bGZpbGxlZC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBmdWxmaWxsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlmIHRoZVxuICogZ2l2ZW4gcHJvbWlzZSBpcyByZWplY3RlZFxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFja1xuICovXG5RLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogQXR0YWNoZXMgYSBsaXN0ZW5lciB0aGF0IGNhbiByZXNwb25kIHRvIHByb2dyZXNzIG5vdGlmaWNhdGlvbnMgZnJvbSBhXG4gKiBwcm9taXNlJ3Mgb3JpZ2luYXRpbmcgZGVmZXJyZWQuIFRoaXMgbGlzdGVuZXIgcmVjZWl2ZXMgdGhlIGV4YWN0IGFyZ3VtZW50c1xuICogcGFzc2VkIHRvIGBgZGVmZXJyZWQubm90aWZ5YGAuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgZm9yIHNvbWV0aGluZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gcmVjZWl2ZSBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybnMgdGhlIGdpdmVuIHByb21pc2UsIHVuY2hhbmdlZFxuICovXG5RLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG5mdW5jdGlvbiBwcm9ncmVzcyhvYmplY3QsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRoZW4odm9pZCAwLCB2b2lkIDAsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5wcm9ncmVzcyA9IGZ1bmN0aW9uIChwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIG9wcG9ydHVuaXR5IHRvIG9ic2VydmUgdGhlIHNldHRsaW5nIG9mIGEgcHJvbWlzZSxcbiAqIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcHJvbWlzZSBpcyBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuICBGb3J3YXJkc1xuICogdGhlIHJlc29sdXRpb24gdG8gdGhlIHJldHVybmVkIHByb21pc2Ugd2hlbiB0aGUgY2FsbGJhY2sgaXMgZG9uZS5cbiAqIFRoZSBjYWxsYmFjayBjYW4gcmV0dXJuIGEgcHJvbWlzZSB0byBkZWZlciBjb21wbGV0aW9uLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBvYnNlcnZlIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlblxuICogcHJvbWlzZSwgdGFrZXMgbm8gYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSB3aGVuXG4gKiBgYGZpbmBgIGlzIGRvbmUuXG4gKi9cblEuZmluID0gLy8gWFhYIGxlZ2FjeVxuUVtcImZpbmFsbHlcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdClbXCJmaW5hbGx5XCJdKGNhbGxiYWNrKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZpbiA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gVE9ETyBhdHRlbXB0IHRvIHJlY3ljbGUgdGhlIHJlamVjdGlvbiB3aXRoIFwidGhpc1wiLlxuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFRlcm1pbmF0ZXMgYSBjaGFpbiBvZiBwcm9taXNlcywgZm9yY2luZyByZWplY3Rpb25zIHRvIGJlXG4gKiB0aHJvd24gYXMgZXhjZXB0aW9ucy5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBhdCB0aGUgZW5kIG9mIGEgY2hhaW4gb2YgcHJvbWlzZXNcbiAqIEByZXR1cm5zIG5vdGhpbmdcbiAqL1xuUS5kb25lID0gZnVuY3Rpb24gKG9iamVjdCwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRvbmUoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHZhciBvblVuaGFuZGxlZEVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIC8vIGZvcndhcmQgdG8gYSBmdXR1cmUgdHVybiBzbyB0aGF0IGBgd2hlbmBgXG4gICAgICAgIC8vIGRvZXMgbm90IGNhdGNoIGl0IGFuZCB0dXJuIGl0IGludG8gYSByZWplY3Rpb24uXG4gICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIEF2b2lkIHVubmVjZXNzYXJ5IGBuZXh0VGlja2BpbmcgdmlhIGFuIHVubmVjZXNzYXJ5IGB3aGVuYC5cbiAgICB2YXIgcHJvbWlzZSA9IGZ1bGZpbGxlZCB8fCByZWplY3RlZCB8fCBwcm9ncmVzcyA/XG4gICAgICAgIHRoaXMudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykgOlxuICAgICAgICB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5kb21haW4pIHtcbiAgICAgICAgb25VbmhhbmRsZWRFcnJvciA9IHByb2Nlc3MuZG9tYWluLmJpbmQob25VbmhhbmRsZWRFcnJvcik7XG4gICAgfVxuXG4gICAgcHJvbWlzZS50aGVuKHZvaWQgMCwgb25VbmhhbmRsZWRFcnJvcik7XG59O1xuXG4vKipcbiAqIENhdXNlcyBhIHByb21pc2UgdG8gYmUgcmVqZWN0ZWQgaWYgaXQgZG9lcyBub3QgZ2V0IGZ1bGZpbGxlZCBiZWZvcmVcbiAqIHNvbWUgbWlsbGlzZWNvbmRzIHRpbWUgb3V0LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzIHRpbWVvdXRcbiAqIEBwYXJhbSB7QW55Kn0gY3VzdG9tIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0IChvcHRpb25hbClcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UgaWYgaXQgaXNcbiAqIGZ1bGZpbGxlZCBiZWZvcmUgdGhlIHRpbWVvdXQsIG90aGVyd2lzZSByZWplY3RlZC5cbiAqL1xuUS50aW1lb3V0ID0gZnVuY3Rpb24gKG9iamVjdCwgbXMsIGVycm9yKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aW1lb3V0KG1zLCBlcnJvcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24gKG1zLCBlcnJvcikge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWVycm9yIHx8IFwic3RyaW5nXCIgPT09IHR5cGVvZiBlcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IgfHwgXCJUaW1lZCBvdXQgYWZ0ZXIgXCIgKyBtcyArIFwiIG1zXCIpO1xuICAgICAgICAgICAgZXJyb3IuY29kZSA9IFwiRVRJTUVET1VUXCI7XG4gICAgICAgIH1cbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycm9yKTtcbiAgICB9LCBtcyk7XG5cbiAgICB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9LCBkZWZlcnJlZC5ub3RpZnkpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZ2l2ZW4gdmFsdWUgKG9yIHByb21pc2VkIHZhbHVlKSwgc29tZVxuICogbWlsbGlzZWNvbmRzIGFmdGVyIGl0IHJlc29sdmVkLiBQYXNzZXMgcmVqZWN0aW9ucyBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbGxpc2Vjb25kc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBhZnRlciBtaWxsaXNlY29uZHNcbiAqIHRpbWUgaGFzIGVsYXBzZWQgc2luY2UgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UuXG4gKiBJZiB0aGUgZ2l2ZW4gcHJvbWlzZSByZWplY3RzLCB0aGF0IGlzIHBhc3NlZCBpbW1lZGlhdGVseS5cbiAqL1xuUS5kZWxheSA9IGZ1bmN0aW9uIChvYmplY3QsIHRpbWVvdXQpIHtcbiAgICBpZiAodGltZW91dCA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBvYmplY3Q7XG4gICAgICAgIG9iamVjdCA9IHZvaWQgMDtcbiAgICB9XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kZWxheSh0aW1lb3V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3NlcyBhIGNvbnRpbnVhdGlvbiB0byBhIE5vZGUgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCB3aXRoIHRoZSBnaXZlblxuICogYXJndW1lbnRzIHByb3ZpZGVkIGFzIGFuIGFycmF5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKlxuICogICAgICBRLm5mYXBwbHkoRlMucmVhZEZpbGUsIFtfX2ZpbGVuYW1lXSlcbiAqICAgICAgLnRoZW4oZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAqICAgICAgfSlcbiAqXG4gKi9cblEubmZhcHBseSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgYXJncykge1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgaW5kaXZpZHVhbGx5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmNhbGwoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpXG4gKiAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogfSlcbiAqXG4gKi9cblEubmZjYWxsID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZjYWxsID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBXcmFwcyBhIE5vZGVKUyBjb250aW51YXRpb24gcGFzc2luZyBmdW5jdGlvbiBhbmQgcmV0dXJucyBhbiBlcXVpdmFsZW50XG4gKiB2ZXJzaW9uIHRoYXQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmJpbmQoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpKFwidXRmLThcIilcbiAqIC50aGVuKGNvbnNvbGUubG9nKVxuICogLmRvbmUoKVxuICovXG5RLm5mYmluZCA9XG5RLmRlbm9kZWlmeSA9IGZ1bmN0aW9uIChjYWxsYmFjayAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIFEoY2FsbGJhY2spLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZiaW5kID1cblByb21pc2UucHJvdG90eXBlLmRlbm9kZWlmeSA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgcmV0dXJuIFEuZGVub2RlaWZ5LmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG5RLm5iaW5kID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzcCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIGZ1bmN0aW9uIGJvdW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXNwLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIFEoYm91bmQpLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmJpbmQgPSBmdW5jdGlvbiAoLyp0aGlzcCwgLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDApO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5uYmluZC5hcHBseSh2b2lkIDAsIGFyZ3MpO1xufTtcblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvZiBhIE5vZGUtc3R5bGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIE5vZGUtc3R5bGVcbiAqIGNhbGxiYWNrIHdpdGggYSBnaXZlbiBhcnJheSBvZiBhcmd1bWVudHMsIHBsdXMgYSBwcm92aWRlZCBjYWxsYmFjay5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrXG4gKiB3aWxsIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLm5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkubnBvc3QobmFtZSwgYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLm5wb3N0ID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzIHx8IFtdKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2ssIGZvcndhcmRpbmcgdGhlIGdpdmVuIHZhcmlhZGljIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkXG4gKiBjYWxsYmFjayBhcmd1bWVudC5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSAuLi5hcmdzIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2Q7IHRoZSBjYWxsYmFjayB3aWxsXG4gKiBiZSBwcm92aWRlZCBieSBRIGFuZCBhcHBlbmRlZCB0byB0aGVzZSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSB2YWx1ZSBvciBlcnJvclxuICovXG5RLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblEubm1jYWxsID0gLy8gWFhYIEJhc2VkIG9uIFwiUmVkc2FuZHJvJ3NcIiBwcm9wb3NhbFxuUS5uaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uc2VuZCA9IC8vIFhYWCBCYXNlZCBvbiBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIFwic2VuZFwiXG5Qcm9taXNlLnByb3RvdHlwZS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5Qcm9taXNlLnByb3RvdHlwZS5uaW52b2tlID0gZnVuY3Rpb24gKG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogSWYgYSBmdW5jdGlvbiB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgYm90aCBOb2RlIGNvbnRpbnVhdGlvbi1wYXNzaW5nLXN0eWxlIGFuZFxuICogcHJvbWlzZS1yZXR1cm5pbmctc3R5bGUsIGl0IGNhbiBlbmQgaXRzIGludGVybmFsIHByb21pc2UgY2hhaW4gd2l0aFxuICogYG5vZGVpZnkobm9kZWJhY2spYCwgZm9yd2FyZGluZyB0aGUgb3B0aW9uYWwgbm9kZWJhY2sgYXJndW1lbnQuICBJZiB0aGUgdXNlclxuICogZWxlY3RzIHRvIHVzZSBhIG5vZGViYWNrLCB0aGUgcmVzdWx0IHdpbGwgYmUgc2VudCB0aGVyZS4gIElmIHRoZXkgZG8gbm90XG4gKiBwYXNzIGEgbm9kZWJhY2ssIHRoZXkgd2lsbCByZWNlaXZlIHRoZSByZXN1bHQgcHJvbWlzZS5cbiAqIEBwYXJhbSBvYmplY3QgYSByZXN1bHQgKG9yIGEgcHJvbWlzZSBmb3IgYSByZXN1bHQpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBub2RlYmFjayBhIE5vZGUuanMtc3R5bGUgY2FsbGJhY2tcbiAqIEByZXR1cm5zIGVpdGhlciB0aGUgcHJvbWlzZSBvciBub3RoaW5nXG4gKi9cblEubm9kZWlmeSA9IG5vZGVpZnk7XG5mdW5jdGlvbiBub2RlaWZ5KG9iamVjdCwgbm9kZWJhY2spIHtcbiAgICByZXR1cm4gUShvYmplY3QpLm5vZGVpZnkobm9kZWJhY2spO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrKSB7XG4gICAgaWYgKG5vZGViYWNrKSB7XG4gICAgICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKG51bGwsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuXG5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJRLm5vQ29uZmxpY3Qgb25seSB3b3JrcyB3aGVuIFEgaXMgdXNlZCBhcyBhIGdsb2JhbFwiKTtcbn07XG5cbi8vIEFsbCBjb2RlIGJlZm9yZSB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMuXG52YXIgcUVuZGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xuXG5yZXR1cm4gUTtcblxufSk7XG4iXX0= |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 19774 | },{"_process":12}],158:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 19775 | /** |
| 19776 | * Module dependencies. |
| 19777 | */ |
| 19778 | |
| 19779 | var Emitter = require('emitter'); |
| 19780 | var reduce = require('reduce'); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 19781 | var requestBase = require('./request-base'); |
| 19782 | var isObject = require('./is-object'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 19783 | |
| 19784 | /** |
| 19785 | * Root reference for iframes. |
| 19786 | */ |
| 19787 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 19788 | var root; |
| 19789 | if (typeof window !== 'undefined') { // Browser window |
| 19790 | root = window; |
| 19791 | } else if (typeof self !== 'undefined') { // Web Worker |
| 19792 | root = self; |
| 19793 | } else { // Other environments |
| 19794 | root = this; |
| 19795 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 19796 | |
| 19797 | /** |
| 19798 | * Noop. |
| 19799 | */ |
| 19800 | |
| 19801 | function noop(){}; |
| 19802 | |
| 19803 | /** |
| 19804 | * Check if `obj` is a host object, |
| 19805 | * we don't want to serialize these :) |
| 19806 | * |
| 19807 | * TODO: future proof, move to compoent land |
| 19808 | * |
| 19809 | * @param {Object} obj |
| 19810 | * @return {Boolean} |
| 19811 | * @api private |
| 19812 | */ |
| 19813 | |
| 19814 | function isHost(obj) { |
| 19815 | var str = {}.toString.call(obj); |
| 19816 | |
| 19817 | switch (str) { |
| 19818 | case '[object File]': |
| 19819 | case '[object Blob]': |
| 19820 | case '[object FormData]': |
| 19821 | return true; |
| 19822 | default: |
| 19823 | return false; |
| 19824 | } |
| 19825 | } |
| 19826 | |
| 19827 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 19828 | * Expose `request`. |
| 19829 | */ |
| 19830 | |
| 19831 | var request = module.exports = require('./request').bind(null, Request); |
| 19832 | |
| 19833 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 19834 | * Determine XHR. |
| 19835 | */ |
| 19836 | |
| 19837 | request.getXHR = function () { |
| 19838 | if (root.XMLHttpRequest |
| 19839 | && (!root.location || 'file:' != root.location.protocol |
| 19840 | || !root.ActiveXObject)) { |
| 19841 | return new XMLHttpRequest; |
| 19842 | } else { |
| 19843 | try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} |
| 19844 | try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} |
| 19845 | try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} |
| 19846 | try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} |
| 19847 | } |
| 19848 | return false; |
| 19849 | }; |
| 19850 | |
| 19851 | /** |
| 19852 | * Removes leading and trailing whitespace, added to support IE. |
| 19853 | * |
| 19854 | * @param {String} s |
| 19855 | * @return {String} |
| 19856 | * @api private |
| 19857 | */ |
| 19858 | |
| 19859 | var trim = ''.trim |
| 19860 | ? function(s) { return s.trim(); } |
| 19861 | : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; |
| 19862 | |
| 19863 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 19864 | * Serialize the given `obj`. |
| 19865 | * |
| 19866 | * @param {Object} obj |
| 19867 | * @return {String} |
| 19868 | * @api private |
| 19869 | */ |
| 19870 | |
| 19871 | function serialize(obj) { |
| 19872 | if (!isObject(obj)) return obj; |
| 19873 | var pairs = []; |
| 19874 | for (var key in obj) { |
| 19875 | if (null != obj[key]) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 19876 | pushEncodedKeyValuePair(pairs, key, obj[key]); |
| 19877 | } |
| 19878 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 19879 | return pairs.join('&'); |
| 19880 | } |
| 19881 | |
| 19882 | /** |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 19883 | * Helps 'serialize' with serializing arrays. |
| 19884 | * Mutates the pairs array. |
| 19885 | * |
| 19886 | * @param {Array} pairs |
| 19887 | * @param {String} key |
| 19888 | * @param {Mixed} val |
| 19889 | */ |
| 19890 | |
| 19891 | function pushEncodedKeyValuePair(pairs, key, val) { |
| 19892 | if (Array.isArray(val)) { |
| 19893 | return val.forEach(function(v) { |
| 19894 | pushEncodedKeyValuePair(pairs, key, v); |
| 19895 | }); |
| 19896 | } |
| 19897 | pairs.push(encodeURIComponent(key) |
| 19898 | + '=' + encodeURIComponent(val)); |
| 19899 | } |
| 19900 | |
| 19901 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 19902 | * Expose serialization method. |
| 19903 | */ |
| 19904 | |
| 19905 | request.serializeObject = serialize; |
| 19906 | |
| 19907 | /** |
| 19908 | * Parse the given x-www-form-urlencoded `str`. |
| 19909 | * |
| 19910 | * @param {String} str |
| 19911 | * @return {Object} |
| 19912 | * @api private |
| 19913 | */ |
| 19914 | |
| 19915 | function parseString(str) { |
| 19916 | var obj = {}; |
| 19917 | var pairs = str.split('&'); |
| 19918 | var parts; |
| 19919 | var pair; |
| 19920 | |
| 19921 | for (var i = 0, len = pairs.length; i < len; ++i) { |
| 19922 | pair = pairs[i]; |
| 19923 | parts = pair.split('='); |
| 19924 | obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); |
| 19925 | } |
| 19926 | |
| 19927 | return obj; |
| 19928 | } |
| 19929 | |
| 19930 | /** |
| 19931 | * Expose parser. |
| 19932 | */ |
| 19933 | |
| 19934 | request.parseString = parseString; |
| 19935 | |
| 19936 | /** |
| 19937 | * Default MIME type map. |
| 19938 | * |
| 19939 | * superagent.types.xml = 'application/xml'; |
| 19940 | * |
| 19941 | */ |
| 19942 | |
| 19943 | request.types = { |
| 19944 | html: 'text/html', |
| 19945 | json: 'application/json', |
| 19946 | xml: 'application/xml', |
| 19947 | urlencoded: 'application/x-www-form-urlencoded', |
| 19948 | 'form': 'application/x-www-form-urlencoded', |
| 19949 | 'form-data': 'application/x-www-form-urlencoded' |
| 19950 | }; |
| 19951 | |
| 19952 | /** |
| 19953 | * Default serialization map. |
| 19954 | * |
| 19955 | * superagent.serialize['application/xml'] = function(obj){ |
| 19956 | * return 'generated xml here'; |
| 19957 | * }; |
| 19958 | * |
| 19959 | */ |
| 19960 | |
| 19961 | request.serialize = { |
| 19962 | 'application/x-www-form-urlencoded': serialize, |
| 19963 | 'application/json': JSON.stringify |
| 19964 | }; |
| 19965 | |
| 19966 | /** |
| 19967 | * Default parsers. |
| 19968 | * |
| 19969 | * superagent.parse['application/xml'] = function(str){ |
| 19970 | * return { object parsed from str }; |
| 19971 | * }; |
| 19972 | * |
| 19973 | */ |
| 19974 | |
| 19975 | request.parse = { |
| 19976 | 'application/x-www-form-urlencoded': parseString, |
| 19977 | 'application/json': JSON.parse |
| 19978 | }; |
| 19979 | |
| 19980 | /** |
| 19981 | * Parse the given header `str` into |
| 19982 | * an object containing the mapped fields. |
| 19983 | * |
| 19984 | * @param {String} str |
| 19985 | * @return {Object} |
| 19986 | * @api private |
| 19987 | */ |
| 19988 | |
| 19989 | function parseHeader(str) { |
| 19990 | var lines = str.split(/\r?\n/); |
| 19991 | var fields = {}; |
| 19992 | var index; |
| 19993 | var line; |
| 19994 | var field; |
| 19995 | var val; |
| 19996 | |
| 19997 | lines.pop(); // trailing CRLF |
| 19998 | |
| 19999 | for (var i = 0, len = lines.length; i < len; ++i) { |
| 20000 | line = lines[i]; |
| 20001 | index = line.indexOf(':'); |
| 20002 | field = line.slice(0, index).toLowerCase(); |
| 20003 | val = trim(line.slice(index + 1)); |
| 20004 | fields[field] = val; |
| 20005 | } |
| 20006 | |
| 20007 | return fields; |
| 20008 | } |
| 20009 | |
| 20010 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20011 | * Check if `mime` is json or has +json structured syntax suffix. |
| 20012 | * |
| 20013 | * @param {String} mime |
| 20014 | * @return {Boolean} |
| 20015 | * @api private |
| 20016 | */ |
| 20017 | |
| 20018 | function isJSON(mime) { |
| 20019 | return /[\/+]json\b/.test(mime); |
| 20020 | } |
| 20021 | |
| 20022 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20023 | * Return the mime type for the given `str`. |
| 20024 | * |
| 20025 | * @param {String} str |
| 20026 | * @return {String} |
| 20027 | * @api private |
| 20028 | */ |
| 20029 | |
| 20030 | function type(str){ |
| 20031 | return str.split(/ *; */).shift(); |
| 20032 | }; |
| 20033 | |
| 20034 | /** |
| 20035 | * Return header field parameters. |
| 20036 | * |
| 20037 | * @param {String} str |
| 20038 | * @return {Object} |
| 20039 | * @api private |
| 20040 | */ |
| 20041 | |
| 20042 | function params(str){ |
| 20043 | return reduce(str.split(/ *; */), function(obj, str){ |
| 20044 | var parts = str.split(/ *= */) |
| 20045 | , key = parts.shift() |
| 20046 | , val = parts.shift(); |
| 20047 | |
| 20048 | if (key && val) obj[key] = val; |
| 20049 | return obj; |
| 20050 | }, {}); |
| 20051 | }; |
| 20052 | |
| 20053 | /** |
| 20054 | * Initialize a new `Response` with the given `xhr`. |
| 20055 | * |
| 20056 | * - set flags (.ok, .error, etc) |
| 20057 | * - parse header |
| 20058 | * |
| 20059 | * Examples: |
| 20060 | * |
| 20061 | * Aliasing `superagent` as `request` is nice: |
| 20062 | * |
| 20063 | * request = superagent; |
| 20064 | * |
| 20065 | * We can use the promise-like API, or pass callbacks: |
| 20066 | * |
| 20067 | * request.get('/').end(function(res){}); |
| 20068 | * request.get('/', function(res){}); |
| 20069 | * |
| 20070 | * Sending data can be chained: |
| 20071 | * |
| 20072 | * request |
| 20073 | * .post('/user') |
| 20074 | * .send({ name: 'tj' }) |
| 20075 | * .end(function(res){}); |
| 20076 | * |
| 20077 | * Or passed to `.send()`: |
| 20078 | * |
| 20079 | * request |
| 20080 | * .post('/user') |
| 20081 | * .send({ name: 'tj' }, function(res){}); |
| 20082 | * |
| 20083 | * Or passed to `.post()`: |
| 20084 | * |
| 20085 | * request |
| 20086 | * .post('/user', { name: 'tj' }) |
| 20087 | * .end(function(res){}); |
| 20088 | * |
| 20089 | * Or further reduced to a single call for simple cases: |
| 20090 | * |
| 20091 | * request |
| 20092 | * .post('/user', { name: 'tj' }, function(res){}); |
| 20093 | * |
| 20094 | * @param {XMLHTTPRequest} xhr |
| 20095 | * @param {Object} options |
| 20096 | * @api private |
| 20097 | */ |
| 20098 | |
| 20099 | function Response(req, options) { |
| 20100 | options = options || {}; |
| 20101 | this.req = req; |
| 20102 | this.xhr = this.req.xhr; |
| 20103 | // responseText is accessible only if responseType is '' or 'text' and on older browsers |
| 20104 | this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') |
| 20105 | ? this.xhr.responseText |
| 20106 | : null; |
| 20107 | this.statusText = this.req.xhr.statusText; |
| 20108 | this.setStatusProperties(this.xhr.status); |
| 20109 | this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); |
| 20110 | // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but |
| 20111 | // getResponseHeader still works. so we get content-type even if getting |
| 20112 | // other headers fails. |
| 20113 | this.header['content-type'] = this.xhr.getResponseHeader('content-type'); |
| 20114 | this.setHeaderProperties(this.header); |
| 20115 | this.body = this.req.method != 'HEAD' |
| 20116 | ? this.parseBody(this.text ? this.text : this.xhr.response) |
| 20117 | : null; |
| 20118 | } |
| 20119 | |
| 20120 | /** |
| 20121 | * Get case-insensitive `field` value. |
| 20122 | * |
| 20123 | * @param {String} field |
| 20124 | * @return {String} |
| 20125 | * @api public |
| 20126 | */ |
| 20127 | |
| 20128 | Response.prototype.get = function(field){ |
| 20129 | return this.header[field.toLowerCase()]; |
| 20130 | }; |
| 20131 | |
| 20132 | /** |
| 20133 | * Set header related properties: |
| 20134 | * |
| 20135 | * - `.type` the content type without params |
| 20136 | * |
| 20137 | * A response of "Content-Type: text/plain; charset=utf-8" |
| 20138 | * will provide you with a `.type` of "text/plain". |
| 20139 | * |
| 20140 | * @param {Object} header |
| 20141 | * @api private |
| 20142 | */ |
| 20143 | |
| 20144 | Response.prototype.setHeaderProperties = function(header){ |
| 20145 | // content-type |
| 20146 | var ct = this.header['content-type'] || ''; |
| 20147 | this.type = type(ct); |
| 20148 | |
| 20149 | // params |
| 20150 | var obj = params(ct); |
| 20151 | for (var key in obj) this[key] = obj[key]; |
| 20152 | }; |
| 20153 | |
| 20154 | /** |
| 20155 | * Parse the given body `str`. |
| 20156 | * |
| 20157 | * Used for auto-parsing of bodies. Parsers |
| 20158 | * are defined on the `superagent.parse` object. |
| 20159 | * |
| 20160 | * @param {String} str |
| 20161 | * @return {Mixed} |
| 20162 | * @api private |
| 20163 | */ |
| 20164 | |
| 20165 | Response.prototype.parseBody = function(str){ |
| 20166 | var parse = request.parse[this.type]; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20167 | if (!parse && isJSON(this.type)) { |
| 20168 | parse = request.parse['application/json']; |
| 20169 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20170 | return parse && str && (str.length || str instanceof Object) |
| 20171 | ? parse(str) |
| 20172 | : null; |
| 20173 | }; |
| 20174 | |
| 20175 | /** |
| 20176 | * Set flags such as `.ok` based on `status`. |
| 20177 | * |
| 20178 | * For example a 2xx response will give you a `.ok` of __true__ |
| 20179 | * whereas 5xx will be __false__ and `.error` will be __true__. The |
| 20180 | * `.clientError` and `.serverError` are also available to be more |
| 20181 | * specific, and `.statusType` is the class of error ranging from 1..5 |
| 20182 | * sometimes useful for mapping respond colors etc. |
| 20183 | * |
| 20184 | * "sugar" properties are also defined for common cases. Currently providing: |
| 20185 | * |
| 20186 | * - .noContent |
| 20187 | * - .badRequest |
| 20188 | * - .unauthorized |
| 20189 | * - .notAcceptable |
| 20190 | * - .notFound |
| 20191 | * |
| 20192 | * @param {Number} status |
| 20193 | * @api private |
| 20194 | */ |
| 20195 | |
| 20196 | Response.prototype.setStatusProperties = function(status){ |
| 20197 | // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request |
| 20198 | if (status === 1223) { |
| 20199 | status = 204; |
| 20200 | } |
| 20201 | |
| 20202 | var type = status / 100 | 0; |
| 20203 | |
| 20204 | // status / class |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20205 | this.status = this.statusCode = status; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20206 | this.statusType = type; |
| 20207 | |
| 20208 | // basics |
| 20209 | this.info = 1 == type; |
| 20210 | this.ok = 2 == type; |
| 20211 | this.clientError = 4 == type; |
| 20212 | this.serverError = 5 == type; |
| 20213 | this.error = (4 == type || 5 == type) |
| 20214 | ? this.toError() |
| 20215 | : false; |
| 20216 | |
| 20217 | // sugar |
| 20218 | this.accepted = 202 == status; |
| 20219 | this.noContent = 204 == status; |
| 20220 | this.badRequest = 400 == status; |
| 20221 | this.unauthorized = 401 == status; |
| 20222 | this.notAcceptable = 406 == status; |
| 20223 | this.notFound = 404 == status; |
| 20224 | this.forbidden = 403 == status; |
| 20225 | }; |
| 20226 | |
| 20227 | /** |
| 20228 | * Return an `Error` representative of this response. |
| 20229 | * |
| 20230 | * @return {Error} |
| 20231 | * @api public |
| 20232 | */ |
| 20233 | |
| 20234 | Response.prototype.toError = function(){ |
| 20235 | var req = this.req; |
| 20236 | var method = req.method; |
| 20237 | var url = req.url; |
| 20238 | |
| 20239 | var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; |
| 20240 | var err = new Error(msg); |
| 20241 | err.status = this.status; |
| 20242 | err.method = method; |
| 20243 | err.url = url; |
| 20244 | |
| 20245 | return err; |
| 20246 | }; |
| 20247 | |
| 20248 | /** |
| 20249 | * Expose `Response`. |
| 20250 | */ |
| 20251 | |
| 20252 | request.Response = Response; |
| 20253 | |
| 20254 | /** |
| 20255 | * Initialize a new `Request` with the given `method` and `url`. |
| 20256 | * |
| 20257 | * @param {String} method |
| 20258 | * @param {String} url |
| 20259 | * @api public |
| 20260 | */ |
| 20261 | |
| 20262 | function Request(method, url) { |
| 20263 | var self = this; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20264 | this._query = this._query || []; |
| 20265 | this.method = method; |
| 20266 | this.url = url; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20267 | this.header = {}; // preserves header name case |
| 20268 | this._header = {}; // coerces header names to lowercase |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20269 | this.on('end', function(){ |
| 20270 | var err = null; |
| 20271 | var res = null; |
| 20272 | |
| 20273 | try { |
| 20274 | res = new Response(self); |
| 20275 | } catch(e) { |
| 20276 | err = new Error('Parser is unable to parse the response'); |
| 20277 | err.parse = true; |
| 20278 | err.original = e; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20279 | // issue #675: return the raw response if the response parsing fails |
| 20280 | err.rawResponse = self.xhr && self.xhr.responseText ? self.xhr.responseText : null; |
| 20281 | // issue #876: return the http status code if the response parsing fails |
| 20282 | err.statusCode = self.xhr && self.xhr.status ? self.xhr.status : null; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20283 | return self.callback(err); |
| 20284 | } |
| 20285 | |
| 20286 | self.emit('response', res); |
| 20287 | |
| 20288 | if (err) { |
| 20289 | return self.callback(err, res); |
| 20290 | } |
| 20291 | |
| 20292 | if (res.status >= 200 && res.status < 300) { |
| 20293 | return self.callback(err, res); |
| 20294 | } |
| 20295 | |
| 20296 | var new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); |
| 20297 | new_err.original = err; |
| 20298 | new_err.response = res; |
| 20299 | new_err.status = res.status; |
| 20300 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20301 | self.callback(new_err, res); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20302 | }); |
| 20303 | } |
| 20304 | |
| 20305 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20306 | * Mixin `Emitter` and `requestBase`. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20307 | */ |
| 20308 | |
| 20309 | Emitter(Request.prototype); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20310 | for (var key in requestBase) { |
| 20311 | Request.prototype[key] = requestBase[key]; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20312 | } |
| 20313 | |
| 20314 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20315 | * Abort the request, and clear potential timeout. |
| 20316 | * |
| 20317 | * @return {Request} |
| 20318 | * @api public |
| 20319 | */ |
| 20320 | |
| 20321 | Request.prototype.abort = function(){ |
| 20322 | if (this.aborted) return; |
| 20323 | this.aborted = true; |
| 20324 | this.xhr.abort(); |
| 20325 | this.clearTimeout(); |
| 20326 | this.emit('abort'); |
| 20327 | return this; |
| 20328 | }; |
| 20329 | |
| 20330 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20331 | * Set Content-Type to `type`, mapping values from `request.types`. |
| 20332 | * |
| 20333 | * Examples: |
| 20334 | * |
| 20335 | * superagent.types.xml = 'application/xml'; |
| 20336 | * |
| 20337 | * request.post('/') |
| 20338 | * .type('xml') |
| 20339 | * .send(xmlstring) |
| 20340 | * .end(callback); |
| 20341 | * |
| 20342 | * request.post('/') |
| 20343 | * .type('application/xml') |
| 20344 | * .send(xmlstring) |
| 20345 | * .end(callback); |
| 20346 | * |
| 20347 | * @param {String} type |
| 20348 | * @return {Request} for chaining |
| 20349 | * @api public |
| 20350 | */ |
| 20351 | |
| 20352 | Request.prototype.type = function(type){ |
| 20353 | this.set('Content-Type', request.types[type] || type); |
| 20354 | return this; |
| 20355 | }; |
| 20356 | |
| 20357 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20358 | * Set responseType to `val`. Presently valid responseTypes are 'blob' and |
| 20359 | * 'arraybuffer'. |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20360 | * |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20361 | * Examples: |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20362 | * |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20363 | * req.get('/') |
| 20364 | * .responseType('blob') |
| 20365 | * .end(callback); |
| 20366 | * |
| 20367 | * @param {String} val |
| 20368 | * @return {Request} for chaining |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20369 | * @api public |
| 20370 | */ |
| 20371 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20372 | Request.prototype.responseType = function(val){ |
| 20373 | this._responseType = val; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20374 | return this; |
| 20375 | }; |
| 20376 | |
| 20377 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20378 | * Set Accept to `type`, mapping values from `request.types`. |
| 20379 | * |
| 20380 | * Examples: |
| 20381 | * |
| 20382 | * superagent.types.json = 'application/json'; |
| 20383 | * |
| 20384 | * request.get('/agent') |
| 20385 | * .accept('json') |
| 20386 | * .end(callback); |
| 20387 | * |
| 20388 | * request.get('/agent') |
| 20389 | * .accept('application/json') |
| 20390 | * .end(callback); |
| 20391 | * |
| 20392 | * @param {String} accept |
| 20393 | * @return {Request} for chaining |
| 20394 | * @api public |
| 20395 | */ |
| 20396 | |
| 20397 | Request.prototype.accept = function(type){ |
| 20398 | this.set('Accept', request.types[type] || type); |
| 20399 | return this; |
| 20400 | }; |
| 20401 | |
| 20402 | /** |
| 20403 | * Set Authorization field value with `user` and `pass`. |
| 20404 | * |
| 20405 | * @param {String} user |
| 20406 | * @param {String} pass |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20407 | * @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic') |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20408 | * @return {Request} for chaining |
| 20409 | * @api public |
| 20410 | */ |
| 20411 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20412 | Request.prototype.auth = function(user, pass, options){ |
| 20413 | if (!options) { |
| 20414 | options = { |
| 20415 | type: 'basic' |
| 20416 | } |
| 20417 | } |
| 20418 | |
| 20419 | switch (options.type) { |
| 20420 | case 'basic': |
| 20421 | var str = btoa(user + ':' + pass); |
| 20422 | this.set('Authorization', 'Basic ' + str); |
| 20423 | break; |
| 20424 | |
| 20425 | case 'auto': |
| 20426 | this.username = user; |
| 20427 | this.password = pass; |
| 20428 | break; |
| 20429 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20430 | return this; |
| 20431 | }; |
| 20432 | |
| 20433 | /** |
| 20434 | * Add query-string `val`. |
| 20435 | * |
| 20436 | * Examples: |
| 20437 | * |
| 20438 | * request.get('/shoes') |
| 20439 | * .query('size=10') |
| 20440 | * .query({ color: 'blue' }) |
| 20441 | * |
| 20442 | * @param {Object|String} val |
| 20443 | * @return {Request} for chaining |
| 20444 | * @api public |
| 20445 | */ |
| 20446 | |
| 20447 | Request.prototype.query = function(val){ |
| 20448 | if ('string' != typeof val) val = serialize(val); |
| 20449 | if (val) this._query.push(val); |
| 20450 | return this; |
| 20451 | }; |
| 20452 | |
| 20453 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20454 | * Queue the given `file` as an attachment to the specified `field`, |
| 20455 | * with optional `filename`. |
| 20456 | * |
| 20457 | * ``` js |
| 20458 | * request.post('/upload') |
| 20459 | * .attach(new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"})) |
| 20460 | * .end(callback); |
| 20461 | * ``` |
| 20462 | * |
| 20463 | * @param {String} field |
| 20464 | * @param {Blob|File} file |
| 20465 | * @param {String} filename |
| 20466 | * @return {Request} for chaining |
| 20467 | * @api public |
| 20468 | */ |
| 20469 | |
| 20470 | Request.prototype.attach = function(field, file, filename){ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20471 | this._getFormData().append(field, file, filename || file.name); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20472 | return this; |
| 20473 | }; |
| 20474 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20475 | Request.prototype._getFormData = function(){ |
| 20476 | if (!this._formData) { |
| 20477 | this._formData = new root.FormData(); |
| 20478 | } |
| 20479 | return this._formData; |
| 20480 | }; |
| 20481 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20482 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20483 | * Send `data` as the request body, defaulting the `.type()` to "json" when |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20484 | * an object is given. |
| 20485 | * |
| 20486 | * Examples: |
| 20487 | * |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20488 | * // manual json |
| 20489 | * request.post('/user') |
| 20490 | * .type('json') |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20491 | * .send('{"name":"tj"}') |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20492 | * .end(callback) |
| 20493 | * |
| 20494 | * // auto json |
| 20495 | * request.post('/user') |
| 20496 | * .send({ name: 'tj' }) |
| 20497 | * .end(callback) |
| 20498 | * |
| 20499 | * // manual x-www-form-urlencoded |
| 20500 | * request.post('/user') |
| 20501 | * .type('form') |
| 20502 | * .send('name=tj') |
| 20503 | * .end(callback) |
| 20504 | * |
| 20505 | * // auto x-www-form-urlencoded |
| 20506 | * request.post('/user') |
| 20507 | * .type('form') |
| 20508 | * .send({ name: 'tj' }) |
| 20509 | * .end(callback) |
| 20510 | * |
| 20511 | * // defaults to x-www-form-urlencoded |
| 20512 | * request.post('/user') |
| 20513 | * .send('name=tobi') |
| 20514 | * .send('species=ferret') |
| 20515 | * .end(callback) |
| 20516 | * |
| 20517 | * @param {String|Object} data |
| 20518 | * @return {Request} for chaining |
| 20519 | * @api public |
| 20520 | */ |
| 20521 | |
| 20522 | Request.prototype.send = function(data){ |
| 20523 | var obj = isObject(data); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20524 | var type = this._header['content-type']; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20525 | |
| 20526 | // merge |
| 20527 | if (obj && isObject(this._data)) { |
| 20528 | for (var key in data) { |
| 20529 | this._data[key] = data[key]; |
| 20530 | } |
| 20531 | } else if ('string' == typeof data) { |
| 20532 | if (!type) this.type('form'); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20533 | type = this._header['content-type']; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20534 | if ('application/x-www-form-urlencoded' == type) { |
| 20535 | this._data = this._data |
| 20536 | ? this._data + '&' + data |
| 20537 | : data; |
| 20538 | } else { |
| 20539 | this._data = (this._data || '') + data; |
| 20540 | } |
| 20541 | } else { |
| 20542 | this._data = data; |
| 20543 | } |
| 20544 | |
| 20545 | if (!obj || isHost(data)) return this; |
| 20546 | if (!type) this.type('json'); |
| 20547 | return this; |
| 20548 | }; |
| 20549 | |
| 20550 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20551 | * @deprecated |
| 20552 | */ |
| 20553 | Response.prototype.parse = function serialize(fn){ |
| 20554 | if (root.console) { |
| 20555 | console.warn("Client-side parse() method has been renamed to serialize(). This method is not compatible with superagent v2.0"); |
| 20556 | } |
| 20557 | this.serialize(fn); |
| 20558 | return this; |
| 20559 | }; |
| 20560 | |
| 20561 | Response.prototype.serialize = function serialize(fn){ |
| 20562 | this._parser = fn; |
| 20563 | return this; |
| 20564 | }; |
| 20565 | |
| 20566 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20567 | * Invoke the callback with `err` and `res` |
| 20568 | * and handle arity check. |
| 20569 | * |
| 20570 | * @param {Error} err |
| 20571 | * @param {Response} res |
| 20572 | * @api private |
| 20573 | */ |
| 20574 | |
| 20575 | Request.prototype.callback = function(err, res){ |
| 20576 | var fn = this._callback; |
| 20577 | this.clearTimeout(); |
| 20578 | fn(err, res); |
| 20579 | }; |
| 20580 | |
| 20581 | /** |
| 20582 | * Invoke callback with x-domain error. |
| 20583 | * |
| 20584 | * @api private |
| 20585 | */ |
| 20586 | |
| 20587 | Request.prototype.crossDomainError = function(){ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20588 | 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.'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20589 | err.crossDomain = true; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20590 | |
| 20591 | err.status = this.status; |
| 20592 | err.method = this.method; |
| 20593 | err.url = this.url; |
| 20594 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20595 | this.callback(err); |
| 20596 | }; |
| 20597 | |
| 20598 | /** |
| 20599 | * Invoke callback with timeout error. |
| 20600 | * |
| 20601 | * @api private |
| 20602 | */ |
| 20603 | |
| 20604 | Request.prototype.timeoutError = function(){ |
| 20605 | var timeout = this._timeout; |
| 20606 | var err = new Error('timeout of ' + timeout + 'ms exceeded'); |
| 20607 | err.timeout = timeout; |
| 20608 | this.callback(err); |
| 20609 | }; |
| 20610 | |
| 20611 | /** |
| 20612 | * Enable transmission of cookies with x-domain requests. |
| 20613 | * |
| 20614 | * Note that for this to work the origin must not be |
| 20615 | * using "Access-Control-Allow-Origin" with a wildcard, |
| 20616 | * and also must set "Access-Control-Allow-Credentials" |
| 20617 | * to "true". |
| 20618 | * |
| 20619 | * @api public |
| 20620 | */ |
| 20621 | |
| 20622 | Request.prototype.withCredentials = function(){ |
| 20623 | this._withCredentials = true; |
| 20624 | return this; |
| 20625 | }; |
| 20626 | |
| 20627 | /** |
| 20628 | * Initiate request, invoking callback `fn(res)` |
| 20629 | * with an instanceof `Response`. |
| 20630 | * |
| 20631 | * @param {Function} fn |
| 20632 | * @return {Request} for chaining |
| 20633 | * @api public |
| 20634 | */ |
| 20635 | |
| 20636 | Request.prototype.end = function(fn){ |
| 20637 | var self = this; |
| 20638 | var xhr = this.xhr = request.getXHR(); |
| 20639 | var query = this._query.join('&'); |
| 20640 | var timeout = this._timeout; |
| 20641 | var data = this._formData || this._data; |
| 20642 | |
| 20643 | // store callback |
| 20644 | this._callback = fn || noop; |
| 20645 | |
| 20646 | // state change |
| 20647 | xhr.onreadystatechange = function(){ |
| 20648 | if (4 != xhr.readyState) return; |
| 20649 | |
| 20650 | // In IE9, reads to any property (e.g. status) off of an aborted XHR will |
| 20651 | // result in the error "Could not complete the operation due to error c00c023f" |
| 20652 | var status; |
| 20653 | try { status = xhr.status } catch(e) { status = 0; } |
| 20654 | |
| 20655 | if (0 == status) { |
| 20656 | if (self.timedout) return self.timeoutError(); |
| 20657 | if (self.aborted) return; |
| 20658 | return self.crossDomainError(); |
| 20659 | } |
| 20660 | self.emit('end'); |
| 20661 | }; |
| 20662 | |
| 20663 | // progress |
| 20664 | var handleProgress = function(e){ |
| 20665 | if (e.total > 0) { |
| 20666 | e.percent = e.loaded / e.total * 100; |
| 20667 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20668 | e.direction = 'download'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20669 | self.emit('progress', e); |
| 20670 | }; |
| 20671 | if (this.hasListeners('progress')) { |
| 20672 | xhr.onprogress = handleProgress; |
| 20673 | } |
| 20674 | try { |
| 20675 | if (xhr.upload && this.hasListeners('progress')) { |
| 20676 | xhr.upload.onprogress = handleProgress; |
| 20677 | } |
| 20678 | } catch(e) { |
| 20679 | // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. |
| 20680 | // Reported here: |
| 20681 | // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context |
| 20682 | } |
| 20683 | |
| 20684 | // timeout |
| 20685 | if (timeout && !this._timer) { |
| 20686 | this._timer = setTimeout(function(){ |
| 20687 | self.timedout = true; |
| 20688 | self.abort(); |
| 20689 | }, timeout); |
| 20690 | } |
| 20691 | |
| 20692 | // querystring |
| 20693 | if (query) { |
| 20694 | query = request.serializeObject(query); |
| 20695 | this.url += ~this.url.indexOf('?') |
| 20696 | ? '&' + query |
| 20697 | : '?' + query; |
| 20698 | } |
| 20699 | |
| 20700 | // initiate request |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20701 | if (this.username && this.password) { |
| 20702 | xhr.open(this.method, this.url, true, this.username, this.password); |
| 20703 | } else { |
| 20704 | xhr.open(this.method, this.url, true); |
| 20705 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20706 | |
| 20707 | // CORS |
| 20708 | if (this._withCredentials) xhr.withCredentials = true; |
| 20709 | |
| 20710 | // body |
| 20711 | if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) { |
| 20712 | // serialize stuff |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20713 | var contentType = this._header['content-type']; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20714 | var serialize = this._parser || request.serialize[contentType ? contentType.split(';')[0] : '']; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20715 | if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json']; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20716 | if (serialize) data = serialize(data); |
| 20717 | } |
| 20718 | |
| 20719 | // set header fields |
| 20720 | for (var field in this.header) { |
| 20721 | if (null == this.header[field]) continue; |
| 20722 | xhr.setRequestHeader(field, this.header[field]); |
| 20723 | } |
| 20724 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20725 | if (this._responseType) { |
| 20726 | xhr.responseType = this._responseType; |
| 20727 | } |
| 20728 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20729 | // send stuff |
| 20730 | this.emit('request', this); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20731 | |
| 20732 | // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) |
| 20733 | // We need null here if data is undefined |
| 20734 | xhr.send(typeof data !== 'undefined' ? data : null); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20735 | return this; |
| 20736 | }; |
| 20737 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20738 | |
| 20739 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20740 | * Expose `Request`. |
| 20741 | */ |
| 20742 | |
| 20743 | request.Request = Request; |
| 20744 | |
| 20745 | /** |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20746 | * GET `url` with optional callback `fn(res)`. |
| 20747 | * |
| 20748 | * @param {String} url |
| 20749 | * @param {Mixed|Function} data or fn |
| 20750 | * @param {Function} fn |
| 20751 | * @return {Request} |
| 20752 | * @api public |
| 20753 | */ |
| 20754 | |
| 20755 | request.get = function(url, data, fn){ |
| 20756 | var req = request('GET', url); |
| 20757 | if ('function' == typeof data) fn = data, data = null; |
| 20758 | if (data) req.query(data); |
| 20759 | if (fn) req.end(fn); |
| 20760 | return req; |
| 20761 | }; |
| 20762 | |
| 20763 | /** |
| 20764 | * HEAD `url` with optional callback `fn(res)`. |
| 20765 | * |
| 20766 | * @param {String} url |
| 20767 | * @param {Mixed|Function} data or fn |
| 20768 | * @param {Function} fn |
| 20769 | * @return {Request} |
| 20770 | * @api public |
| 20771 | */ |
| 20772 | |
| 20773 | request.head = function(url, data, fn){ |
| 20774 | var req = request('HEAD', url); |
| 20775 | if ('function' == typeof data) fn = data, data = null; |
| 20776 | if (data) req.send(data); |
| 20777 | if (fn) req.end(fn); |
| 20778 | return req; |
| 20779 | }; |
| 20780 | |
| 20781 | /** |
| 20782 | * DELETE `url` with optional callback `fn(res)`. |
| 20783 | * |
| 20784 | * @param {String} url |
| 20785 | * @param {Function} fn |
| 20786 | * @return {Request} |
| 20787 | * @api public |
| 20788 | */ |
| 20789 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20790 | function del(url, fn){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20791 | var req = request('DELETE', url); |
| 20792 | if (fn) req.end(fn); |
| 20793 | return req; |
| 20794 | }; |
| 20795 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20796 | request['del'] = del; |
| 20797 | request['delete'] = del; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 20798 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20799 | /** |
| 20800 | * PATCH `url` with optional `data` and callback `fn(res)`. |
| 20801 | * |
| 20802 | * @param {String} url |
| 20803 | * @param {Mixed} data |
| 20804 | * @param {Function} fn |
| 20805 | * @return {Request} |
| 20806 | * @api public |
| 20807 | */ |
| 20808 | |
| 20809 | request.patch = function(url, data, fn){ |
| 20810 | var req = request('PATCH', url); |
| 20811 | if ('function' == typeof data) fn = data, data = null; |
| 20812 | if (data) req.send(data); |
| 20813 | if (fn) req.end(fn); |
| 20814 | return req; |
| 20815 | }; |
| 20816 | |
| 20817 | /** |
| 20818 | * POST `url` with optional `data` and callback `fn(res)`. |
| 20819 | * |
| 20820 | * @param {String} url |
| 20821 | * @param {Mixed} data |
| 20822 | * @param {Function} fn |
| 20823 | * @return {Request} |
| 20824 | * @api public |
| 20825 | */ |
| 20826 | |
| 20827 | request.post = function(url, data, fn){ |
| 20828 | var req = request('POST', url); |
| 20829 | if ('function' == typeof data) fn = data, data = null; |
| 20830 | if (data) req.send(data); |
| 20831 | if (fn) req.end(fn); |
| 20832 | return req; |
| 20833 | }; |
| 20834 | |
| 20835 | /** |
| 20836 | * PUT `url` with optional `data` and callback `fn(res)`. |
| 20837 | * |
| 20838 | * @param {String} url |
| 20839 | * @param {Mixed|Function} data or fn |
| 20840 | * @param {Function} fn |
| 20841 | * @return {Request} |
| 20842 | * @api public |
| 20843 | */ |
| 20844 | |
| 20845 | request.put = function(url, data, fn){ |
| 20846 | var req = request('PUT', url); |
| 20847 | if ('function' == typeof data) fn = data, data = null; |
| 20848 | if (data) req.send(data); |
| 20849 | if (fn) req.end(fn); |
| 20850 | return req; |
| 20851 | }; |
| 20852 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20853 | },{"./is-object":159,"./request":161,"./request-base":160,"emitter":162,"reduce":163}],159:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20854 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20855 | * Check if `obj` is an object. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20856 | * |
| 20857 | * @param {Object} obj |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20858 | * @return {Boolean} |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20859 | * @api private |
| 20860 | */ |
| 20861 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20862 | function isObject(obj) { |
| 20863 | return null != obj && 'object' == typeof obj; |
| 20864 | } |
| 20865 | |
| 20866 | module.exports = isObject; |
| 20867 | |
| 20868 | },{}],160:[function(require,module,exports){ |
| 20869 | /** |
| 20870 | * Module of mixed-in functions shared between node and client code |
| 20871 | */ |
| 20872 | var isObject = require('./is-object'); |
| 20873 | |
| 20874 | /** |
| 20875 | * Clear previous timeout. |
| 20876 | * |
| 20877 | * @return {Request} for chaining |
| 20878 | * @api public |
| 20879 | */ |
| 20880 | |
| 20881 | exports.clearTimeout = function _clearTimeout(){ |
| 20882 | this._timeout = 0; |
| 20883 | clearTimeout(this._timer); |
| 20884 | return this; |
| 20885 | }; |
| 20886 | |
| 20887 | /** |
| 20888 | * Force given parser |
| 20889 | * |
| 20890 | * Sets the body parser no matter type. |
| 20891 | * |
| 20892 | * @param {Function} |
| 20893 | * @api public |
| 20894 | */ |
| 20895 | |
| 20896 | exports.parse = function parse(fn){ |
| 20897 | this._parser = fn; |
| 20898 | return this; |
| 20899 | }; |
| 20900 | |
| 20901 | /** |
| 20902 | * Set timeout to `ms`. |
| 20903 | * |
| 20904 | * @param {Number} ms |
| 20905 | * @return {Request} for chaining |
| 20906 | * @api public |
| 20907 | */ |
| 20908 | |
| 20909 | exports.timeout = function timeout(ms){ |
| 20910 | this._timeout = ms; |
| 20911 | return this; |
| 20912 | }; |
| 20913 | |
| 20914 | /** |
| 20915 | * Faux promise support |
| 20916 | * |
| 20917 | * @param {Function} fulfill |
| 20918 | * @param {Function} reject |
| 20919 | * @return {Request} |
| 20920 | */ |
| 20921 | |
| 20922 | exports.then = function then(fulfill, reject) { |
| 20923 | return this.end(function(err, res) { |
| 20924 | err ? reject(err) : fulfill(res); |
| 20925 | }); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20926 | } |
| 20927 | |
| 20928 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20929 | * Allow for extension |
| 20930 | */ |
| 20931 | |
| 20932 | exports.use = function use(fn) { |
| 20933 | fn(this); |
| 20934 | return this; |
| 20935 | } |
| 20936 | |
| 20937 | |
| 20938 | /** |
| 20939 | * Get request header `field`. |
| 20940 | * Case-insensitive. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20941 | * |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20942 | * @param {String} field |
| 20943 | * @return {String} |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20944 | * @api public |
| 20945 | */ |
| 20946 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20947 | exports.get = function(field){ |
| 20948 | return this._header[field.toLowerCase()]; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20949 | }; |
| 20950 | |
| 20951 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20952 | * Get case-insensitive header `field` value. |
| 20953 | * This is a deprecated internal API. Use `.get(field)` instead. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20954 | * |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20955 | * (getHeader is no longer used internally by the superagent code base) |
| 20956 | * |
| 20957 | * @param {String} field |
| 20958 | * @return {String} |
| 20959 | * @api private |
| 20960 | * @deprecated |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20961 | */ |
| 20962 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20963 | exports.getHeader = exports.get; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20964 | |
| 20965 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20966 | * Set header `field` to `val`, or multiple fields with one object. |
| 20967 | * Case-insensitive. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20968 | * |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20969 | * Examples: |
| 20970 | * |
| 20971 | * req.get('/') |
| 20972 | * .set('Accept', 'application/json') |
| 20973 | * .set('X-API-Key', 'foobar') |
| 20974 | * .end(callback); |
| 20975 | * |
| 20976 | * req.get('/') |
| 20977 | * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) |
| 20978 | * .end(callback); |
| 20979 | * |
| 20980 | * @param {String|Object} field |
| 20981 | * @param {String} val |
| 20982 | * @return {Request} for chaining |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20983 | * @api public |
| 20984 | */ |
| 20985 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20986 | exports.set = function(field, val){ |
| 20987 | if (isObject(field)) { |
| 20988 | for (var key in field) { |
| 20989 | this.set(key, field[key]); |
| 20990 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20991 | return this; |
| 20992 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20993 | this._header[field.toLowerCase()] = val; |
| 20994 | this.header[field] = val; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 20995 | return this; |
| 20996 | }; |
| 20997 | |
| 20998 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 20999 | * Remove header `field`. |
| 21000 | * Case-insensitive. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21001 | * |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21002 | * Example: |
| 21003 | * |
| 21004 | * req.get('/') |
| 21005 | * .unset('User-Agent') |
| 21006 | * .end(callback); |
| 21007 | * |
| 21008 | * @param {String} field |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21009 | */ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21010 | exports.unset = function(field){ |
| 21011 | delete this._header[field.toLowerCase()]; |
| 21012 | delete this.header[field]; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21013 | return this; |
| 21014 | }; |
| 21015 | |
| 21016 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21017 | * Write the field `name` and `val` for "multipart/form-data" |
| 21018 | * request bodies. |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21019 | * |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21020 | * ``` js |
| 21021 | * request.post('/upload') |
| 21022 | * .field('foo', 'bar') |
| 21023 | * .end(callback); |
| 21024 | * ``` |
| 21025 | * |
| 21026 | * @param {String} name |
| 21027 | * @param {String|Blob|File|Buffer|fs.ReadStream} val |
| 21028 | * @return {Request} for chaining |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21029 | * @api public |
| 21030 | */ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21031 | exports.field = function(name, val) { |
| 21032 | this._getFormData().append(name, val); |
| 21033 | return this; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21034 | }; |
| 21035 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21036 | },{"./is-object":159}],161:[function(require,module,exports){ |
| 21037 | // The node and browser modules expose versions of this with the |
| 21038 | // appropriate constructor function bound as first argument |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21039 | /** |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21040 | * Issue a request: |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21041 | * |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21042 | * Examples: |
| 21043 | * |
| 21044 | * request('GET', '/users').end(callback) |
| 21045 | * request('/users').end(callback) |
| 21046 | * request('/users', callback) |
| 21047 | * |
| 21048 | * @param {String} method |
| 21049 | * @param {String|Function} url or callback |
| 21050 | * @return {Request} |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21051 | * @api public |
| 21052 | */ |
| 21053 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21054 | function request(RequestConstructor, method, url) { |
| 21055 | // callback |
| 21056 | if ('function' == typeof url) { |
| 21057 | return new RequestConstructor('GET', method).end(url); |
| 21058 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21059 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21060 | // url first |
| 21061 | if (2 == arguments.length) { |
| 21062 | return new RequestConstructor('GET', method); |
| 21063 | } |
| 21064 | |
| 21065 | return new RequestConstructor(method, url); |
| 21066 | } |
| 21067 | |
| 21068 | module.exports = request; |
| 21069 | |
| 21070 | },{}],162:[function(require,module,exports){ |
| 21071 |
|
| 21072 | /**
|
| 21073 | * Expose `Emitter`.
|
| 21074 | */
|
| 21075 |
|
| 21076 | if (typeof module !== 'undefined') {
|
| 21077 | module.exports = Emitter;
|
| 21078 | }
|
| 21079 |
|
| 21080 | /**
|
| 21081 | * Initialize a new `Emitter`.
|
| 21082 | *
|
| 21083 | * @api public
|
| 21084 | */
|
| 21085 |
|
| 21086 | function Emitter(obj) {
|
| 21087 | if (obj) return mixin(obj);
|
| 21088 | };
|
| 21089 |
|
| 21090 | /**
|
| 21091 | * Mixin the emitter properties.
|
| 21092 | *
|
| 21093 | * @param {Object} obj
|
| 21094 | * @return {Object}
|
| 21095 | * @api private
|
| 21096 | */
|
| 21097 |
|
| 21098 | function mixin(obj) {
|
| 21099 | for (var key in Emitter.prototype) {
|
| 21100 | obj[key] = Emitter.prototype[key];
|
| 21101 | }
|
| 21102 | return obj;
|
| 21103 | }
|
| 21104 |
|
| 21105 | /**
|
| 21106 | * Listen on the given `event` with `fn`.
|
| 21107 | *
|
| 21108 | * @param {String} event
|
| 21109 | * @param {Function} fn
|
| 21110 | * @return {Emitter}
|
| 21111 | * @api public
|
| 21112 | */
|
| 21113 |
|
| 21114 | Emitter.prototype.on =
|
| 21115 | Emitter.prototype.addEventListener = function(event, fn){
|
| 21116 | this._callbacks = this._callbacks || {};
|
| 21117 | (this._callbacks['$' + event] = this._callbacks['$' + event] || [])
|
| 21118 | .push(fn);
|
| 21119 | return this;
|
| 21120 | };
|
| 21121 |
|
| 21122 | /**
|
| 21123 | * Adds an `event` listener that will be invoked a single
|
| 21124 | * time then automatically removed.
|
| 21125 | *
|
| 21126 | * @param {String} event
|
| 21127 | * @param {Function} fn
|
| 21128 | * @return {Emitter}
|
| 21129 | * @api public
|
| 21130 | */
|
| 21131 |
|
| 21132 | Emitter.prototype.once = function(event, fn){
|
| 21133 | function on() {
|
| 21134 | this.off(event, on);
|
| 21135 | fn.apply(this, arguments);
|
| 21136 | }
|
| 21137 |
|
| 21138 | on.fn = fn;
|
| 21139 | this.on(event, on);
|
| 21140 | return this;
|
| 21141 | };
|
| 21142 |
|
| 21143 | /**
|
| 21144 | * Remove the given callback for `event` or all
|
| 21145 | * registered callbacks.
|
| 21146 | *
|
| 21147 | * @param {String} event
|
| 21148 | * @param {Function} fn
|
| 21149 | * @return {Emitter}
|
| 21150 | * @api public
|
| 21151 | */
|
| 21152 |
|
| 21153 | Emitter.prototype.off =
|
| 21154 | Emitter.prototype.removeListener =
|
| 21155 | Emitter.prototype.removeAllListeners =
|
| 21156 | Emitter.prototype.removeEventListener = function(event, fn){
|
| 21157 | this._callbacks = this._callbacks || {};
|
| 21158 |
|
| 21159 | // all
|
| 21160 | if (0 == arguments.length) {
|
| 21161 | this._callbacks = {};
|
| 21162 | return this;
|
| 21163 | }
|
| 21164 |
|
| 21165 | // specific event
|
| 21166 | var callbacks = this._callbacks['$' + event];
|
| 21167 | if (!callbacks) return this;
|
| 21168 |
|
| 21169 | // remove all handlers
|
| 21170 | if (1 == arguments.length) {
|
| 21171 | delete this._callbacks['$' + event];
|
| 21172 | return this;
|
| 21173 | }
|
| 21174 |
|
| 21175 | // remove specific handler
|
| 21176 | var cb;
|
| 21177 | for (var i = 0; i < callbacks.length; i++) {
|
| 21178 | cb = callbacks[i];
|
| 21179 | if (cb === fn || cb.fn === fn) {
|
| 21180 | callbacks.splice(i, 1);
|
| 21181 | break;
|
| 21182 | }
|
| 21183 | }
|
| 21184 | return this;
|
| 21185 | };
|
| 21186 |
|
| 21187 | /**
|
| 21188 | * Emit `event` with the given args.
|
| 21189 | *
|
| 21190 | * @param {String} event
|
| 21191 | * @param {Mixed} ...
|
| 21192 | * @return {Emitter}
|
| 21193 | */
|
| 21194 |
|
| 21195 | Emitter.prototype.emit = function(event){
|
| 21196 | this._callbacks = this._callbacks || {};
|
| 21197 | var args = [].slice.call(arguments, 1)
|
| 21198 | , callbacks = this._callbacks['$' + event];
|
| 21199 |
|
| 21200 | if (callbacks) {
|
| 21201 | callbacks = callbacks.slice(0);
|
| 21202 | for (var i = 0, len = callbacks.length; i < len; ++i) {
|
| 21203 | callbacks[i].apply(this, args);
|
| 21204 | }
|
| 21205 | }
|
| 21206 |
|
| 21207 | return this;
|
| 21208 | };
|
| 21209 |
|
| 21210 | /**
|
| 21211 | * Return array of callbacks for `event`.
|
| 21212 | *
|
| 21213 | * @param {String} event
|
| 21214 | * @return {Array}
|
| 21215 | * @api public
|
| 21216 | */
|
| 21217 |
|
| 21218 | Emitter.prototype.listeners = function(event){
|
| 21219 | this._callbacks = this._callbacks || {};
|
| 21220 | return this._callbacks['$' + event] || [];
|
| 21221 | };
|
| 21222 |
|
| 21223 | /**
|
| 21224 | * Check if this emitter has `event` handlers.
|
| 21225 | *
|
| 21226 | * @param {String} event
|
| 21227 | * @return {Boolean}
|
| 21228 | * @api public
|
| 21229 | */
|
| 21230 |
|
| 21231 | Emitter.prototype.hasListeners = function(event){
|
| 21232 | return !! this.listeners(event).length;
|
| 21233 | };
|
| 21234 | |
| 21235 | },{}],163:[function(require,module,exports){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21236 | |
| 21237 | /** |
| 21238 | * Reduce `arr` with `fn`. |
| 21239 | * |
| 21240 | * @param {Array} arr |
| 21241 | * @param {Function} fn |
| 21242 | * @param {Mixed} initial |
| 21243 | * |
| 21244 | * TODO: combatible error handling? |
| 21245 | */ |
| 21246 | |
| 21247 | module.exports = function(arr, fn, initial){ |
| 21248 | var idx = 0; |
| 21249 | var len = arr.length; |
| 21250 | var curr = arguments.length == 3 |
| 21251 | ? initial |
| 21252 | : arr[idx++]; |
| 21253 | |
| 21254 | while (idx < len) { |
| 21255 | curr = fn.call(null, curr, arr[idx], ++idx, arr); |
| 21256 | } |
| 21257 | |
| 21258 | return curr; |
| 21259 | }; |
| 21260 | },{}]},{},[1])(1) |
| 21261 | }); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21262 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJpbmRleC5qcyIsImxpYi9hdXRoLmpzIiwibGliL2NsaWVudC5qcyIsImxpYi9oZWxwZXJzLmpzIiwibGliL2h0dHAuanMiLCJsaWIvcmVzb2x2ZXIuanMiLCJsaWIvc2NoZW1hLW1hcmt1cC5qcyIsImxpYi9zcGVjLWNvbnZlcnRlci5qcyIsImxpYi90eXBlcy9tb2RlbC5qcyIsImxpYi90eXBlcy9vcGVyYXRpb24uanMiLCJsaWIvdHlwZXMvb3BlcmF0aW9uR3JvdXAuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2J0b2EvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYi9iNjQuanMiLCJub2RlX21vZHVsZXMvYnVmZmVyL25vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaXMtYXJyYXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY29va2llamFyL2Nvb2tpZWphci5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9jb21tb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9kdW1wZXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9leGNlcHRpb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9sb2FkZXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9tYXJrLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2NvcmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvZGVmYXVsdF9mdWxsLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfc2FmZS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9mYWlsc2FmZS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9qc29uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvYmluYXJ5LmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9ib29sLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9mbG9hdC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvaW50LmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9qcy9mdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvcmVnZXhwLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9qcy91bmRlZmluZWQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL21hcC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvbWVyZ2UuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL251bGwuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL29tYXAuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3BhaXJzLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9zZXEuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3NldC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvc3RyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS90aW1lc3RhbXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvYXJyYXkvbGFzdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2NoYWluL2xvZGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZmluZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZm9yRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vaW5jbHVkZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL21hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2RhdGUvbm93LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvZnVuY3Rpb24vYmluZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL3Jlc3RQYXJhbS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL0xhenlXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvTG9kYXNoV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5Q29weS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5RWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5TWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYXJyYXlTb21lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUFzc2lnbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDYWxsYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDbG9uZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDb3B5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUNyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRmluZEluZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUZvci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGb3JJbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGb3JPd24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlR2V0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUluZGV4T2YuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNFcXVhbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJc0VxdWFsRGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJc01hdGNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUxvZGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWF0Y2hlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VNYXRjaGVzUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlUHJvcGVydHlEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVNldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlU2xpY2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlVG9TdHJpbmcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlVmFsdWVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluYXJ5SW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iaW5hcnlJbmRleEJ5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluZENhbGxiYWNrLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYnVmZmVyQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jb21wb3NlQXJncy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NvbXBvc2VBcmdzUmlnaHQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUJhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCaW5kV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUN0b3JXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlRmluZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVIeWJyaWRXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlUGFydGlhbFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxBcnJheXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9lcXVhbEJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxPYmplY3RzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZ2V0RGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldEZ1bmNOYW1lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZ2V0TGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZ2V0TWF0Y2hEYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZ2V0TmF0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5kZXhPZk5hTi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5pdENsb25lQnlUYWcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pbml0Q2xvbmVPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0FycmF5TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzSG9zdE9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzSW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0l0ZXJhdGVlQ2FsbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzS2V5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNMYXppYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzTGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNPYmplY3RMaWtlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNTdHJpY3RDb21wYXJhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvbWVyZ2VEYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvbWV0YU1hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3JlYWxOYW1lcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3Jlb3JkZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZXBsYWNlSG9sZGVycy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3NldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9zaGltS2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3RvT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvdG9QYXRoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvd3JhcHBlckNsb25lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJndW1lbnRzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc0VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc0Z1bmN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc05hdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzU3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1R5cGVkQXJyYXkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzVW5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9vYmplY3Qva2V5c0luLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvb2JqZWN0L3BhaXJzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvb2JqZWN0L3ZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3N1cHBvcnQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC91dGlsaXR5L2lkZW50aXR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvdXRpbGl0eS9ub29wLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvdXRpbGl0eS9wcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9xL3EuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvY2xpZW50LmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL2lzLW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9zdXBlcmFnZW50L2xpYi9yZXF1ZXN0LWJhc2UuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvcmVxdWVzdC5qcyIsIm5vZGVfbW9kdWxlcy9zdXBlcmFnZW50L25vZGVfbW9kdWxlcy9jb21wb25lbnQtZW1pdHRlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zdXBlcmFnZW50L25vZGVfbW9kdWxlcy9yZWR1Y2UtY29tcG9uZW50L2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4ekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcG5DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbHlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbGpEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SEE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbmdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25LQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXV0aCA9IHJlcXVpcmUoJy4vbGliL2F1dGgnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9saWIvaGVscGVycycpO1xudmFyIFN3YWdnZXJDbGllbnQgPSByZXF1aXJlKCcuL2xpYi9jbGllbnQnKTtcbnZhciBkZXByZWNhdGlvbldyYXBwZXIgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIGhlbHBlcnMubG9nKCdUaGlzIGlzIGRlcHJlY2F0ZWQsIHVzZSBcIm5ldyBTd2FnZ2VyQ2xpZW50XCIgaW5zdGVhZC4nKTtcblxuICByZXR1cm4gbmV3IFN3YWdnZXJDbGllbnQodXJsLCBvcHRpb25zKTtcbn07XG5cbi8qIEhlcmUgZm9yIElFOCBTdXBwb3J0ICovXG5pZiAoIUFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XG4gIEFycmF5LnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24ob2JqLCBzdGFydCkge1xuICAgIGZvciAodmFyIGkgPSAoc3RhcnQgfHwgMCksIGogPSB0aGlzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuICAgICAgaWYgKHRoaXNbaV0gPT09IG9iaikgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH07XG59XG5cbi8qIEhlcmUgZm9yIElFOCBTdXBwb3J0ICovXG5pZiAoIVN0cmluZy5wcm90b3R5cGUudHJpbSkge1xuICBTdHJpbmcucHJvdG90eXBlLnRyaW0gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xuICB9O1xufVxuXG4vKiBIZXJlIGZvciBub2RlIDEwLnggc3VwcG9ydCAqL1xuaWYgKCFTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKSB7XG4gIFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGggPSBmdW5jdGlvbihzdWZmaXgpIHtcbiAgICByZXR1cm4gdGhpcy5pbmRleE9mKHN1ZmZpeCwgdGhpcy5sZW5ndGggLSBzdWZmaXgubGVuZ3RoKSAhPT0gLTE7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gU3dhZ2dlckNsaWVudDtcblxuU3dhZ2dlckNsaWVudC5BcGlLZXlBdXRob3JpemF0aW9uID0gYXV0aC5BcGlLZXlBdXRob3JpemF0aW9uO1xuU3dhZ2dlckNsaWVudC5QYXNzd29yZEF1dGhvcml6YXRpb24gPSBhdXRoLlBhc3N3b3JkQXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuQ29va2llQXV0aG9yaXphdGlvbiA9IGF1dGguQ29va2llQXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuU3dhZ2dlckFwaSA9IGRlcHJlY2F0aW9uV3JhcHBlcjtcblN3YWdnZXJDbGllbnQuU3dhZ2dlckNsaWVudCA9IGRlcHJlY2F0aW9uV3JhcHBlcjtcblN3YWdnZXJDbGllbnQuU2NoZW1hTWFya3VwID0gcmVxdWlyZSgnLi9saWIvc2NoZW1hLW1hcmt1cCcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIGJ0b2EgPSByZXF1aXJlKCdidG9hJyk7IC8vIGpzaGludCBpZ25vcmU6bGluZVxudmFyIENvb2tpZUphciA9IHJlcXVpcmUoJ2Nvb2tpZWphcicpLkNvb2tpZUphcjtcbnZhciBfID0ge1xuICBlYWNoOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZWFjaCcpLFxuICBpbmNsdWRlczogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzJyksXG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgaXNBcnJheTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXknKVxufTtcblxuLyoqXG4gKiBTd2FnZ2VyQXV0aG9yaXphdGlvbnMgYXBwbHlzIHRoZSBjb3JyZWN0IGF1dGhvcml6YXRpb24gdG8gYW4gb3BlcmF0aW9uIGJlaW5nIGV4ZWN1dGVkXG4gKi9cbnZhciBTd2FnZ2VyQXV0aG9yaXphdGlvbnMgPSBtb2R1bGUuZXhwb3J0cy5Td2FnZ2VyQXV0aG9yaXphdGlvbnMgPSBmdW5jdGlvbiAoYXV0aHopIHtcbiAgdGhpcy5hdXRoeiA9IGF1dGh6IHx8IHt9O1xufTtcblxuLyoqXG4gKiBBZGQgYXV0aHMgdG8gdGhlIGhhc2hcbiAqIFdpbGwgb3ZlcndyaXRlIGFueSBleGlzdGluZ1xuICpcbiAqL1xuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAobmFtZSwgYXV0aCkge1xuICBpZihfLmlzT2JqZWN0KG5hbWUpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG5hbWUpIHtcbiAgICAgIHRoaXMuYXV0aHpba2V5XSA9IG5hbWVba2V5XTtcbiAgICB9XG4gIH0gZWxzZSBpZih0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZycgKXtcbiAgICB0aGlzLmF1dGh6W25hbWVdID0gYXV0aDtcbiAgfVxuXG4gIHJldHVybiBhdXRoO1xufTtcblxuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gZGVsZXRlIHRoaXMuYXV0aHpbbmFtZV07XG59O1xuXG5Td2FnZ2VyQXV0aG9yaXphdGlvbnMucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaiwgc2VjdXJpdGllcykge1xuICB2YXIgc3RhdHVzID0gdHJ1ZTtcbiAgdmFyIGFwcGx5QWxsID0gIXNlY3VyaXRpZXM7XG4gIHZhciBmbGF0dGVuZWRTZWN1cml0aWVzID0gW107XG5cbiAgLy8gZmF2b3IgdGhlIG9iamVjdC1sZXZlbCBhdXRob3JpemF0aW9ucyBvdmVyIGdsb2JhbFxuICB2YXIgYXV0aHogPSBvYmouY2xpZW50QXV0aG9yaXphdGlvbnMgfHwgdGhpcy5hdXRoejtcblxuICAvLyBTZWN1cml0aWVzIGNvdWxkIGJlIFsge30gXVxuICBfLmVhY2goc2VjdXJpdGllcywgZnVuY3Rpb24gKG9iaiwga2V5KSB7XG5cbiAgICAvLyBNYWtlIHN1cmUgd2UgYWNjb3VudCBmb3Igc2VjdXJpdGllcyBiZWluZyBbIHN0ciBdXG4gICAgaWYodHlwZW9mIGtleSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGZsYXR0ZW5lZFNlY3VyaXRpZXMucHVzaChrZXkpO1xuICAgIH1cblxuICAgIC8vIEZsYXR0ZW4ga2V5cyBpbiB0byBvdXIgYXJyYXlcbiAgICBfLmVhY2gob2JqLCBmdW5jdGlvbiAodmFsLCBrZXkpIHtcbiAgICAgIGZsYXR0ZW5lZFNlY3VyaXRpZXMucHVzaChrZXkpO1xuICAgIH0pO1xuICB9KTtcblxuICBfLmVhY2goYXV0aHosIGZ1bmN0aW9uIChhdXRoLCBhdXRoTmFtZSkge1xuICAgIGlmKGFwcGx5QWxsIHx8IF8uaW5jbHVkZXMoZmxhdHRlbmVkU2VjdXJpdGllcywgYXV0aE5hbWUpKSB7XG4gICAgICB2YXIgbmV3U3RhdHVzID0gYXV0aC5hcHBseShvYmopO1xuICAgICAgc3RhdHVzID0gc3RhdHVzICYmICEhbmV3U3RhdHVzOyAvLyBsb2dpY2FsIE9ScyByZWdhcmRpbmcgc3RhdHVzXG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gc3RhdHVzO1xufTtcblxuLyoqXG4gKiBBcGlLZXlBdXRob3JpemF0aW9uIGFsbG93cyBhIHF1ZXJ5IHBhcmFtIG9yIGhlYWRlciB0byBiZSBpbmplY3RlZFxuICovXG52YXIgQXBpS2V5QXV0aG9yaXphdGlvbiA9IG1vZHVsZS5leHBvcnRzLkFwaUtleUF1dGhvcml6YXRpb24gPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIHR5cGUpIHtcbiAgdGhpcy5uYW1lID0gbmFtZTtcbiAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICB0aGlzLnR5cGUgPSB0eXBlO1xufTtcblxuQXBpS2V5QXV0aG9yaXphdGlvbi5wcm90b3R5cGUuYXBwbHkgPSBmdW5jdGlvbiAob2JqKSB7XG4gIGlmICh0aGlzLnR5cGUgPT09ICdxdWVyeScpIHtcbiAgICAvLyBzZWUgaWYgYWxyZWFkeSBhcHBsaWVkLiAgSWYgc28sIGRvbid0IGRvIGl0IGFnYWluXG5cbiAgICB2YXIgcXA7XG4gICAgaWYgKG9iai51cmwuaW5kZXhPZignPycpID4gMCkge1xuICAgICAgcXAgPSBvYmoudXJsLnN1YnN0cmluZyhvYmoudXJsLmluZGV4T2YoJz8nKSArIDEpO1xuICAgICAgdmFyIHBhcnRzID0gcXAuc3BsaXQoJyYnKTtcbiAgICAgIGlmKHBhcnRzICYmIHBhcnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIGt2ID0gcGFydHNbaV0uc3BsaXQoJz0nKTtcbiAgICAgICAgICBpZihrdiAmJiBrdi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBpZiAoa3ZbMF0gPT09IHRoaXMubmFtZSkge1xuICAgICAgICAgICAgICAvLyBza2lwIGl0XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAob2JqLnVybC5pbmRleE9mKCc/JykgPiAwKSB7XG4gICAgICBvYmoudXJsID0gb2JqLnVybCArICcmJyArIHRoaXMubmFtZSArICc9JyArIHRoaXMudmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9iai51cmwgPSBvYmoudXJsICsgJz8nICsgdGhpcy5uYW1lICsgJz0nICsgdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmICh0aGlzLnR5cGUgPT09ICdoZWFkZXInKSB7XG4gICAgaWYodHlwZW9mIG9iai5oZWFkZXJzW3RoaXMubmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBvYmouaGVhZGVyc1t0aGlzLm5hbWVdID0gdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcblxudmFyIENvb2tpZUF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5Db29raWVBdXRob3JpemF0aW9uID0gZnVuY3Rpb24gKGNvb2tpZSkge1xuICB0aGlzLmNvb2tpZSA9IGNvb2tpZTtcbn07XG5cbkNvb2tpZUF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBvYmouY29va2llSmFyID0gb2JqLmNvb2tpZUphciB8fCBuZXcgQ29va2llSmFyKCk7XG4gIG9iai5jb29raWVKYXIuc2V0Q29va2llKHRoaXMuY29va2llKTtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogUGFzc3dvcmQgQXV0aG9yaXphdGlvbiBpcyBhIGJhc2ljIGF1dGggaW1wbGVtZW50YXRpb25cbiAqL1xudmFyIFBhc3N3b3JkQXV0aG9yaXphdGlvbiA9IG1vZHVsZS5leHBvcnRzLlBhc3N3b3JkQXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uICh1c2VybmFtZSwgcGFzc3dvcmQpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICBoZWxwZXJzLmxvZygnUGFzc3dvcmRBdXRob3JpemF0aW9uOiB0aGUgXFwnbmFtZVxcJyBhcmd1bWVudCBoYXMgYmVlbiByZW1vdmVkLCBwYXNzIG9ubHkgdXNlcm5hbWUgYW5kIHBhc3N3b3JkJyk7XG4gICAgdXNlcm5hbWUgPSBhcmd1bWVudHNbMV07XG4gICAgcGFzc3dvcmQgPSBhcmd1bWVudHNbMl07XG4gIH1cbiAgdGhpcy51c2VybmFtZSA9IHVzZXJuYW1lO1xuICB0aGlzLnBhc3N3b3JkID0gcGFzc3dvcmQ7XG59O1xuXG5QYXNzd29yZEF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBpZih0eXBlb2Ygb2JqLmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvYmouaGVhZGVycy5BdXRob3JpemF0aW9uID0gJ0Jhc2ljICcgKyBidG9hKHRoaXMudXNlcm5hbWUgKyAnOicgKyB0aGlzLnBhc3N3b3JkKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIF8gPSB7XG4gIGJpbmQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvZnVuY3Rpb24vYmluZCcpLFxuICBjbG9uZURlZXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAnKSxcbiAgZmluZDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZpbmQnKSxcbiAgZm9yRWFjaDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2gnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5JyksXG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgaXNGdW5jdGlvbjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzRnVuY3Rpb24nKSxcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpXG59O1xudmFyIGF1dGggPSByZXF1aXJlKCcuL2F1dGgnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG52YXIgTW9kZWwgPSByZXF1aXJlKCcuL3R5cGVzL21vZGVsJyk7XG52YXIgT3BlcmF0aW9uID0gcmVxdWlyZSgnLi90eXBlcy9vcGVyYXRpb24nKTtcbnZhciBPcGVyYXRpb25Hcm91cCA9IHJlcXVpcmUoJy4vdHlwZXMvb3BlcmF0aW9uR3JvdXAnKTtcbnZhciBSZXNvbHZlciA9IHJlcXVpcmUoJy4vcmVzb2x2ZXInKTtcbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4vaHR0cCcpO1xudmFyIFN3YWdnZXJTcGVjQ29udmVydGVyID0gcmVxdWlyZSgnLi9zcGVjLWNvbnZlcnRlcicpO1xudmFyIFEgPSByZXF1aXJlKCdxJyk7XG5cbi8vIFdlIGhhdmUgdG8ga2VlcCB0cmFjayBvZiB0aGUgZnVuY3Rpb24vcHJvcGVydHkgbmFtZXMgdG8gYXZvaWQgY29sbGlzaW9ucyBmb3IgdGFnIG5hbWVzIHdoaWNoIGFyZSB1c2VkIHRvIGFsbG93IHRoZVxuLy8gZm9sbG93aW5nIHVzYWdlOiAnY2xpZW50Lnt0YWdOYW1lfSdcbnZhciByZXNlcnZlZENsaWVudFRhZ3MgPSBbXG4gICdhcGlzJyxcbiAgJ2F1dGhvcml6YXRpb25TY2hlbWUnLFxuICAnYXV0aG9yaXphdGlvbnMnLFxuICAnYmFzZVBhdGgnLFxuICAnYnVpbGQnLFxuICAnYnVpbGRGcm9tMV8xU3BlYycsXG4gICdidWlsZEZyb20xXzJTcGVjJyxcbiAgJ2J1aWxkRnJvbVNwZWMnLFxuICAnY2xpZW50QXV0aG9yaXphdGlvbnMnLFxuICAnY29udmVydEluZm8nLFxuICAnZGVidWcnLFxuICAnZGVmYXVsdEVycm9yQ2FsbGJhY2snLFxuICAnZGVmYXVsdFN1Y2Nlc3NDYWxsYmFjaycsXG4gICdlbmFibGVDb29raWVzJyxcbiAgJ2ZhaWwnLFxuICAnZmFpbHVyZScsXG4gICdmaW5pc2gnLFxuICAnaGVscCcsXG4gICdob3N0JyxcbiAgJ2lkRnJvbU9wJyxcbiAgJ2luZm8nLFxuICAnaW5pdGlhbGl6ZScsXG4gICdpc0J1aWx0JyxcbiAgJ2lzVmFsaWQnLFxuICAnbW9kZWxQcm9wZXJ0eU1hY3JvJyxcbiAgJ21vZGVscycsXG4gICdtb2RlbHNBcnJheScsXG4gICdvcHRpb25zJyxcbiAgJ3BhcmFtZXRlck1hY3JvJyxcbiAgJ3BhcnNlVXJpJyxcbiAgJ3Byb2dyZXNzJyxcbiAgJ3Jlc291cmNlQ291bnQnLFxuICAnc2FtcGxlTW9kZWxzJyxcbiAgJ3NlbGZSZWZsZWN0JyxcbiAgJ3NldENvbnNvbGlkYXRlZE1vZGVscycsXG4gICdzcGVjJyxcbiAgJ3N1cHBvcnRlZFN1Ym1pdE1ldGhvZHMnLFxuICAnc3dhZ2dlclJlcXVlc3RIZWFkZXJzJyxcbiAgJ3RhZ0Zyb21MYWJlbCcsXG4gICd0aXRsZScsXG4gICd1cmwnLFxuICAndXNlSlF1ZXJ5JyxcbiAgJ2pxdWVyeUFqYXhDYWNoZSdcbl07XG4vLyBXZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWVzIHRvIGF2b2lkIGNvbGxpc2lvbnMgZm9yIHRhZyBuYW1lcyB3aGljaCBhcmUgdXNlZCB0byBhbGxvdyB0aGVcbi8vIGZvbGxvd2luZyB1c2FnZTogJ2NsaWVudC5hcGlzLnt0YWdOYW1lfSdcbnZhciByZXNlcnZlZEFwaVRhZ3MgPSBbXG4gICdhcGlzJyxcbiAgJ2FzQ3VybCcsXG4gICdkZXNjcmlwdGlvbicsXG4gICdleHRlcm5hbERvY3MnLFxuICAnaGVscCcsXG4gICdsYWJlbCcsXG4gICduYW1lJyxcbiAgJ29wZXJhdGlvbicsXG4gICdvcGVyYXRpb25zJyxcbiAgJ29wZXJhdGlvbnNBcnJheScsXG4gICdwYXRoJyxcbiAgJ3RhZydcbl07XG52YXIgc3VwcG9ydGVkT3BlcmF0aW9uTWV0aG9kcyA9IFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ29wdGlvbnMnLCAncGF0Y2gnLCAncG9zdCcsICdwdXQnXTtcbnZhciBTd2FnZ2VyQ2xpZW50ID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIHRoaXMuYXV0aG9yaXphdGlvbnMgPSBudWxsO1xuICB0aGlzLmF1dGhvcml6YXRpb25TY2hlbWUgPSBudWxsO1xuICB0aGlzLmJhc2VQYXRoID0gbnVsbDtcbiAgdGhpcy5kZWJ1ZyA9IGZhbHNlO1xuICB0aGlzLmVuYWJsZUNvb2tpZXMgPSBmYWxzZTtcbiAgdGhpcy5pbmZvID0gbnVsbDtcbiAgdGhpcy5pc0J1aWx0ID0gZmFsc2U7XG4gIHRoaXMuaXNWYWxpZCA9IGZhbHNlO1xuICB0aGlzLm1vZGVsc0FycmF5ID0gW107XG4gIHRoaXMucmVzb3VyY2VDb3VudCA9IDA7XG4gIHRoaXMudXJsID0gbnVsbDtcbiAgdGhpcy51c2VKUXVlcnkgPSBmYWxzZTtcbiAgdGhpcy5qcXVlcnlBamF4Q2FjaGUgPSBmYWxzZTtcbiAgdGhpcy5zd2FnZ2VyT2JqZWN0ID0ge307XG4gIHRoaXMuZGVmZXJyZWRDbGllbnQgPSB1bmRlZmluZWQ7XG5cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IG5ldyBhdXRoLlN3YWdnZXJBdXRob3JpemF0aW9ucygpO1xuXG4gIGlmICh0eXBlb2YgdXJsICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiB0aGlzLmluaXRpYWxpemUodXJsLCBvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMpIHtcbiAgdGhpcy5tb2RlbHMgPSB7fTtcbiAgdGhpcy5zYW1wbGVNb2RlbHMgPSB7fTtcblxuICBpZiAodHlwZW9mIHVybCA9PT0gJ3N0cmluZycpIHtcbiAgICB0aGlzLnVybCA9IHVybDtcbiAgfSBlbHNlIGlmIChfLmlzT2JqZWN0KHVybCkpIHtcbiAgICBvcHRpb25zID0gdXJsO1xuICAgIHRoaXMudXJsID0gb3B0aW9ucy51cmw7XG4gIH1cblxuICBpZih0aGlzLnVybCAmJiB0aGlzLnVybC5pbmRleE9mKCdodHRwOicpID09PSAtMSAmJiB0aGlzLnVybC5pbmRleE9mKCdodHRwczonKSA9PT0gLTEpIHtcbiAgICAvLyBubyBwcm90b2NvbCwgc28gd2UgY2FuIG9ubHkgdXNlIHdpbmRvdyBpZiBpdCBleGlzdHNcbiAgICBpZih0eXBlb2Yod2luZG93KSAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93ICYmIHdpbmRvdy5sb2NhdGlvbikge1xuICAgICAgdGhpcy51cmwgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgdGhpcy51cmw7XG4gICAgfVxuICB9XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKG9wdGlvbnMuYXV0aG9yaXphdGlvbnMpO1xuICB0aGlzLnN3YWdnZXJSZXF1ZXN0SGVhZGVycyA9IG9wdGlvbnMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzIHx8ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTgsKi8qJztcbiAgdGhpcy5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrID0gb3B0aW9ucy5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrIHx8IG51bGw7XG4gIHRoaXMuZGVmYXVsdEVycm9yQ2FsbGJhY2sgPSBvcHRpb25zLmRlZmF1bHRFcnJvckNhbGxiYWNrIHx8IG51bGw7XG4gIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvID0gb3B0aW9ucy5tb2RlbFByb3BlcnR5TWFjcm8gfHwgbnVsbDtcbiAgdGhpcy5wYXJhbWV0ZXJNYWNybyA9IG9wdGlvbnMucGFyYW1ldGVyTWFjcm8gfHwgbnVsbDtcbiAgdGhpcy51c2VQcm9taXNlID0gb3B0aW9ucy51c2VQcm9taXNlIHx8IG51bGw7XG5cblxuICBpZih0aGlzLnVzZVByb21pc2UpIHtcbiAgICB0aGlzLmRlZmVycmVkQ2xpZW50ID0gUS5kZWZlcigpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRpb25zLnN1Y2Nlc3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLnN1Y2Nlc3MgPSBvcHRpb25zLnN1Y2Nlc3M7XG4gIH1cbiAgaWYgKG9wdGlvbnMudXNlSlF1ZXJ5KSB7XG4gICAgdGhpcy51c2VKUXVlcnkgPSBvcHRpb25zLnVzZUpRdWVyeTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLmpxdWVyeUFqYXhDYWNoZSkge1xuICAgIHRoaXMuanF1ZXJ5QWpheENhY2hlID0gb3B0aW9ucy5qcXVlcnlBamF4Q2FjaGU7XG4gIH1cblxuICBpZiAob3B0aW9ucy5lbmFibGVDb29raWVzKSB7XG4gICAgdGhpcy5lbmFibGVDb29raWVzID0gb3B0aW9ucy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB0aGlzLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgfHwgW107XG4gIHRoaXMuZmFpbHVyZSA9IG9wdGlvbnMuZmFpbHVyZSB8fCBmdW5jdGlvbiAoZXJyKSB7IHRocm93IGVycjsgfTtcbiAgdGhpcy5wcm9ncmVzcyA9IG9wdGlvbnMucHJvZ3Jlc3MgfHwgZnVuY3Rpb24gKCkge307XG4gIHRoaXMuc3BlYyA9IF8uY2xvbmVEZWVwKG9wdGlvbnMuc3BlYyk7IC8vIENsb25lIHNvIHdlIGRvIG5vdCBhbHRlciB0aGUgcHJvdmlkZWQgZG9jdW1lbnRcblxuICBpZiAob3B0aW9ucy5zY2hlbWUpIHtcbiAgICB0aGlzLnNjaGVtZSA9IG9wdGlvbnMuc2NoZW1lO1xuICB9XG5cbiAgaWYgKHRoaXMudXNlUHJvbWlzZSB8fCB0eXBlb2Ygb3B0aW9ucy5zdWNjZXNzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5yZWFkeSA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXMuYnVpbGQoKTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbiAobW9jaykge1xuICBpZiAodGhpcy5pc0J1aWx0KSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHRoaXMuc3BlYykge1xuICAgIHRoaXMucHJvZ3Jlc3MoJ2ZldGNoaW5nIHJlc291cmNlIGxpc3Q7IFBsZWFzZSB3YWl0LicpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucHJvZ3Jlc3MoJ2ZldGNoaW5nIHJlc291cmNlIGxpc3Q6ICcgKyB0aGlzLnVybCArICc7IFBsZWFzZSB3YWl0LicpO1xuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1c2VKUXVlcnk6IHRoaXMudXNlSlF1ZXJ5LFxuICAgIGpxdWVyeUFqYXhDYWNoZTogdGhpcy5qcXVlcnlBamF4Q2FjaGUsXG4gICAgdXJsOiB0aGlzLnVybCxcbiAgICBtZXRob2Q6ICdnZXQnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIGFjY2VwdDogdGhpcy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnNcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBlcnJvcjogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChzZWxmLnVybC5zdWJzdHJpbmcoMCwgNCkgIT09ICdodHRwJykge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ1BsZWFzZSBzcGVjaWZ5IHRoZSBwcm90b2NvbCBmb3IgJyArIHNlbGYudXJsKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdDYW5cXCd0IHJlYWQgZnJvbSBzZXJ2ZXIuICBJdCBtYXkgbm90IGhhdmUgdGhlIGFwcHJvcHJpYXRlIGFjY2Vzcy1jb250cm9sLW9yaWdpbiBzZXR0aW5ncy4nKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDQwNCkge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ0NhblxcJ3QgcmVhZCBzd2FnZ2VyIEpTT04gZnJvbSAnICsgc2VsZi51cmwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwocmVzcG9uc2Uuc3RhdHVzICsgJyA6ICcgKyByZXNwb25zZS5zdGF0dXNUZXh0ICsgJyAnICsgc2VsZi51cmwpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgcmVzcG9uc2U6IGZ1bmN0aW9uIChyZXNwKSB7XG5cbiAgICAgICAgdmFyIHJlc3BvbnNlT2JqID0gcmVzcC5vYmo7XG4gICAgICAgIGlmKCFyZXNwb25zZU9iaikge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ2ZhaWxlZCB0byBwYXJzZSBKU09OL1lBTUwgcmVzcG9uc2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYuc3dhZ2dlclZlcnNpb24gPSByZXNwb25zZU9iai5zd2FnZ2VyVmVyc2lvbjtcbiAgICAgICAgc2VsZi5zd2FnZ2VyT2JqZWN0ID0gcmVzcG9uc2VPYmo7XG5cbiAgICAgICAgaWYgKHJlc3BvbnNlT2JqLnN3YWdnZXIgJiYgcGFyc2VJbnQocmVzcG9uc2VPYmouc3dhZ2dlcikgPT09IDIpIHtcbiAgICAgICAgICBzZWxmLnN3YWdnZXJWZXJzaW9uID0gcmVzcG9uc2VPYmouc3dhZ2dlcjtcblxuICAgICAgICAgIG5ldyBSZXNvbHZlcigpLnJlc29sdmUocmVzcG9uc2VPYmosIHNlbGYudXJsLCBzZWxmLmJ1aWxkRnJvbVNwZWMsIHNlbGYpO1xuXG4gICAgICAgICAgc2VsZi5pc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgY29udmVydGVyID0gbmV3IFN3YWdnZXJTcGVjQ29udmVydGVyKCk7XG4gICAgICAgICAgc2VsZi5vbGRTd2FnZ2VyT2JqZWN0ID0gc2VsZi5zd2FnZ2VyT2JqZWN0O1xuXG4gICAgICAgICAgY29udmVydGVyLnNldERvY3VtZW50YXRpb25Mb2NhdGlvbihzZWxmLnVybCk7XG4gICAgICAgICAgY29udmVydGVyLmNvbnZlcnQocmVzcG9uc2VPYmosIHNlbGYuY2xpZW50QXV0aG9yaXphdGlvbnMsIHNlbGYub3B0aW9ucywgZnVuY3Rpb24oc3BlYykge1xuICAgICAgICAgICAgc2VsZi5zd2FnZ2VyT2JqZWN0ID0gc3BlYztcbiAgICAgICAgICAgIG5ldyBSZXNvbHZlcigpLnJlc29sdmUoc3BlYywgc2VsZi51cmwsIHNlbGYuYnVpbGRGcm9tU3BlYywgc2VsZik7XG4gICAgICAgICAgICBzZWxmLmlzVmFsaWQgPSB0cnVlO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGlmICh0aGlzLnNwZWMpIHtcbiAgICBzZWxmLnN3YWdnZXJPYmplY3QgPSB0aGlzLnNwZWM7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBuZXcgUmVzb2x2ZXIoKS5yZXNvbHZlKHNlbGYuc3BlYywgc2VsZi51cmwsIHNlbGYuYnVpbGRGcm9tU3BlYywgc2VsZik7XG4gICAgfSwgMTApO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkob2JqKTtcblxuICAgIGlmIChtb2NrKSB7XG4gICAgICByZXR1cm4gb2JqO1xuICAgIH1cblxuICAgIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUob2JqLCB0aGlzLm9wdGlvbnMpO1xuICB9XG5cbiAgcmV0dXJuICh0aGlzLnVzZVByb21pc2UpID8gdGhpcy5kZWZlcnJlZENsaWVudC5wcm9taXNlIDogdGhpcztcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmJ1aWxkRnJvbVNwZWMgPSBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgaWYgKHRoaXMuaXNCdWlsdCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdGhpcy5hcGlzID0ge307XG4gIHRoaXMuYXBpc0FycmF5ID0gW107XG4gIHRoaXMuYmFzZVBhdGggPSByZXNwb25zZS5iYXNlUGF0aCB8fCAnJztcbiAgdGhpcy5jb25zdW1lcyA9IHJlc3BvbnNlLmNvbnN1bWVzO1xuICB0aGlzLmhvc3QgPSByZXNwb25zZS5ob3N0IHx8ICcnO1xuICB0aGlzLmluZm8gPSByZXNwb25zZS5pbmZvIHx8IHt9O1xuICB0aGlzLnByb2R1Y2VzID0gcmVzcG9uc2UucHJvZHVjZXM7XG4gIHRoaXMuc2NoZW1lcyA9IHJlc3BvbnNlLnNjaGVtZXMgfHwgW107XG4gIHRoaXMuc2VjdXJpdHlEZWZpbml0aW9ucyA9IHJlc3BvbnNlLnNlY3VyaXR5RGVmaW5pdGlvbnM7XG4gIHRoaXMuc2VjdXJpdHkgPSByZXNwb25zZS5zZWN1cml0eTtcbiAgdGhpcy50aXRsZSA9IHJlc3BvbnNlLnRpdGxlIHx8ICcnO1xuXG4gIGlmIChyZXNwb25zZS5leHRlcm5hbERvY3MpIHtcbiAgICB0aGlzLmV4dGVybmFsRG9jcyA9IHJlc3BvbnNlLmV4dGVybmFsRG9jcztcbiAgfVxuXG4gIC8vIGxlZ2FjeSBzdXBwb3J0XG4gIHRoaXMuYXV0aFNjaGVtZXMgPSByZXNwb25zZS5zZWN1cml0eURlZmluaXRpb25zO1xuXG4gIHZhciBkZWZpbmVkVGFncyA9IHt9O1xuICB2YXIgaztcblxuICBpZiAoQXJyYXkuaXNBcnJheShyZXNwb25zZS50YWdzKSkge1xuICAgIGRlZmluZWRUYWdzID0ge307XG5cbiAgICBmb3IgKGsgPSAwOyBrIDwgcmVzcG9uc2UudGFncy5sZW5ndGg7IGsrKykge1xuICAgICAgdmFyIHQgPSByZXNwb25zZS50YWdzW2tdO1xuICAgICAgZGVmaW5lZFRhZ3NbdC5uYW1lXSA9IHQ7XG4gICAgfVxuICB9XG5cbiAgdmFyIGxvY2F0aW9uO1xuXG4gIGlmICh0eXBlb2YgdGhpcy51cmwgPT09ICdzdHJpbmcnKSB7XG4gICAgbG9jYXRpb24gPSB0aGlzLnBhcnNlVXJpKHRoaXMudXJsKTtcbiAgICBpZiAodHlwZW9mIHRoaXMuc2NoZW1lID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgdGhpcy5zY2hlbWVzID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLnNjaGVtZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnNjaGVtZSA9IGxvY2F0aW9uLnNjaGVtZSB8fCAnaHR0cCc7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5zY2hlbWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLnNjaGVtZSA9IHRoaXMuc2NoZW1lc1swXSB8fCBsb2NhdGlvbi5zY2hlbWU7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmhvc3QgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMuaG9zdCA9PT0gJycpIHtcbiAgICAgIHRoaXMuaG9zdCA9IGxvY2F0aW9uLmhvc3Q7XG5cbiAgICAgIGlmIChsb2NhdGlvbi5wb3J0KSB7XG4gICAgICAgIHRoaXMuaG9zdCA9IHRoaXMuaG9zdCArICc6JyArIGxvY2F0aW9uLnBvcnQ7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGlmICh0eXBlb2YgdGhpcy5zY2hlbWVzID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLnNjaGVtZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnNjaGVtZSA9ICdodHRwJztcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHRoaXMuc2NoZW1lID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5zY2hlbWUgPSB0aGlzLnNjaGVtZXNbMF07XG4gICAgfVxuICB9XG5cbiAgdGhpcy5kZWZpbml0aW9ucyA9IHJlc3BvbnNlLmRlZmluaXRpb25zO1xuXG4gIHZhciBrZXk7XG5cbiAgZm9yIChrZXkgaW4gdGhpcy5kZWZpbml0aW9ucykge1xuICAgIHZhciBtb2RlbCA9IG5ldyBNb2RlbChrZXksIHRoaXMuZGVmaW5pdGlvbnNba2V5XSwgdGhpcy5tb2RlbHMsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcblxuICAgIGlmIChtb2RlbCkge1xuICAgICAgdGhpcy5tb2RlbHNba2V5XSA9IG1vZGVsO1xuICAgIH1cbiAgfVxuXG4gIC8vIGdldCBwYXRocywgY3JlYXRlIGZ1bmN0aW9ucyBmb3IgZWFjaCBvcGVyYXRpb25JZFxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgLy8gQmluZCBoZWxwIHRvICdjbGllbnQuYXBpcydcbiAgc2VsZi5hcGlzLmhlbHAgPSBfLmJpbmQoc2VsZi5oZWxwLCBzZWxmKTtcblxuICBfLmZvckVhY2gocmVzcG9uc2UucGF0aHMsIGZ1bmN0aW9uIChwYXRoT2JqLCBwYXRoKSB7XG4gICAgLy8gT25seSBwcm9jZXNzIGEgcGF0aCBpZiBpdCdzIGFuIG9iamVjdFxuICAgIGlmICghXy5pc1BsYWluT2JqZWN0KHBhdGhPYmopKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgXy5mb3JFYWNoKHN1cHBvcnRlZE9wZXJhdGlvbk1ldGhvZHMsIGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgICAgIHZhciBvcGVyYXRpb24gPSBwYXRoT2JqW21ldGhvZF07XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG9wZXJhdGlvbikpIHtcbiAgICAgICAgLy8gT3BlcmF0aW9uIGRvZXMgbm90IGV4aXN0XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAoIV8uaXNQbGFpbk9iamVjdChvcGVyYXRpb24pKSB7XG4gICAgICAgIC8vIE9wZXJhdGlvbiBleGlzdHMgYnV0IGl0IGlzIG5vdCBhbiBPcGVyYXRpb24gT2JqZWN0LiAgU2luY2UgdGhpcyBpcyBpbnZhbGlkLCBsb2cgaXQuXG4gICAgICAgIGhlbHBlcnMubG9nKCdUaGUgXFwnJyArIG1ldGhvZCArICdcXCcgb3BlcmF0aW9uIGZvciBcXCcnICsgcGF0aCArICdcXCcgcGF0aCBpcyBub3QgYW4gT3BlcmF0aW9uIE9iamVjdCcpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHRhZ3MgPSBvcGVyYXRpb24udGFncztcblxuICAgICAgaWYgKF8uaXNVbmRlZmluZWQodGFncykgfHwgIV8uaXNBcnJheSh0YWdzKSB8fCB0YWdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0YWdzID0gb3BlcmF0aW9uLnRhZ3MgPSBbICdkZWZhdWx0JyBdO1xuICAgICAgfVxuXG4gICAgICB2YXIgb3BlcmF0aW9uSWQgPSBzZWxmLmlkRnJvbU9wKHBhdGgsIG1ldGhvZCwgb3BlcmF0aW9uKTtcblxuICAgICAgdmFyIG9wZXJhdGlvbk9iamVjdCA9IG5ldyBPcGVyYXRpb24oc2VsZixcbiAgICAgICAgb3BlcmF0aW9uLnNjaGVtZSxcbiAgICAgICAgb3BlcmF0aW9uSWQsXG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgcGF0aCxcbiAgICAgICAgb3BlcmF0aW9uLFxuICAgICAgICBzZWxmLmRlZmluaXRpb25zLFxuICAgICAgICBzZWxmLm1vZGVscyxcbiAgICAgICAgc2VsZi5jbGllbnRBdXRob3JpemF0aW9ucyk7XG5cbiAgICAgIC8vIGJpbmQgc2VsZiBvcGVyYXRpb24ncyBleGVjdXRlIGNvbW1hbmQgdG8gdGhlIGFwaVxuICAgICAgXy5mb3JFYWNoKHRhZ3MsIGZ1bmN0aW9uICh0YWcpIHtcbiAgICAgICAgdmFyIGNsaWVudFByb3BlcnR5ID0gXy5pbmRleE9mKHJlc2VydmVkQ2xpZW50VGFncywgdGFnKSA+IC0xID8gJ18nICsgdGFnIDogdGFnO1xuICAgICAgICB2YXIgYXBpUHJvcGVydHkgPSBfLmluZGV4T2YocmVzZXJ2ZWRBcGlUYWdzLCB0YWcpID4gLTEgPyAnXycgKyB0YWcgOiB0YWc7XG4gICAgICAgIHZhciBvcGVyYXRpb25Hcm91cCA9IHNlbGZbY2xpZW50UHJvcGVydHldO1xuXG4gICAgICAgIGlmIChjbGllbnRQcm9wZXJ0eSAhPT0gdGFnKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgdGFnICsgJ1xcJyB0YWcgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWUuICBVc2UgXFwnY2xpZW50LicgK1xuICAgICAgICAgICAgICAgICAgICAgIGNsaWVudFByb3BlcnR5ICsgJ1xcJyBvciBcXCdjbGllbnQuYXBpcy4nICsgdGFnICsgJ1xcJyBpbnN0ZWFkIG9mIFxcJ2NsaWVudC4nICsgdGFnICsgJ1xcJy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhcGlQcm9wZXJ0eSAhPT0gdGFnKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgdGFnICsgJ1xcJyB0YWcgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IG9wZXJhdGlvbiBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lLiAgVXNlICcgK1xuICAgICAgICAgICAgICAgICAgICAgICdcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnXFwnIGluc3RlYWQgb2YgXFwnY2xpZW50LmFwaXMuJyArIHRhZyArICdcXCcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXy5pbmRleE9mKHJlc2VydmVkQXBpVGFncywgb3BlcmF0aW9uSWQpID4gLTEpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyBvcGVyYXRpb25JZCArICdcXCcgb3BlcmF0aW9uSWQgY29uZmxpY3RzIHdpdGggYSBTd2FnZ2VyQ2xpZW50IG9wZXJhdGlvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAnZnVuY3Rpb24vcHJvcGVydHkgbmFtZS4gIFVzZSBcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnLl8nICsgb3BlcmF0aW9uSWQgK1xuICAgICAgICAgICAgICAgICAgICAgICdcXCcgaW5zdGVhZCBvZiBcXCdjbGllbnQuYXBpcy4nICsgYXBpUHJvcGVydHkgKyAnLicgKyBvcGVyYXRpb25JZCArICdcXCcuJyk7XG5cbiAgICAgICAgICBvcGVyYXRpb25JZCA9ICdfJyArIG9wZXJhdGlvbklkO1xuICAgICAgICAgIG9wZXJhdGlvbk9iamVjdC5uaWNrbmFtZSA9IG9wZXJhdGlvbklkOyAvLyBTbyAnY2xpZW50LmFwaXMuW3RhZ10ub3BlcmF0aW9uSWQuaGVscCgpIHdvcmtzIHByb3Blcmx5XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChvcGVyYXRpb25Hcm91cCkpIHtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cCA9IHNlbGZbY2xpZW50UHJvcGVydHldID0gc2VsZi5hcGlzW2FwaVByb3BlcnR5XSA9IHt9O1xuXG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAub3BlcmF0aW9ucyA9IHt9O1xuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmxhYmVsID0gYXBpUHJvcGVydHk7XG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAuYXBpcyA9IHt9O1xuXG4gICAgICAgICAgdmFyIHRhZ0RlZiA9IGRlZmluZWRUYWdzW3RhZ107XG5cbiAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQodGFnRGVmKSkge1xuICAgICAgICAgICAgb3BlcmF0aW9uR3JvdXAuZGVzY3JpcHRpb24gPSB0YWdEZWYuZGVzY3JpcHRpb247XG4gICAgICAgICAgICBvcGVyYXRpb25Hcm91cC5leHRlcm5hbERvY3MgPSB0YWdEZWYuZXh0ZXJuYWxEb2NzO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHNlbGZbY2xpZW50UHJvcGVydHldLmhlbHAgPSBfLmJpbmQoc2VsZi5oZWxwLCBvcGVyYXRpb25Hcm91cCk7XG4gICAgICAgICAgc2VsZi5hcGlzQXJyYXkucHVzaChuZXcgT3BlcmF0aW9uR3JvdXAodGFnLCBvcGVyYXRpb25Hcm91cC5kZXNjcmlwdGlvbiwgb3BlcmF0aW9uR3JvdXAuZXh0ZXJuYWxEb2NzLCBvcGVyYXRpb25PYmplY3QpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wZXJhdGlvbklkID0gc2VsZi5tYWtlVW5pcXVlT3BlcmF0aW9uSWQob3BlcmF0aW9uSWQsIHNlbGYuYXBpc1thcGlQcm9wZXJ0eV0pO1xuXG4gICAgICAgIC8vIEJpbmQgdGFnIGhlbHBcbiAgICAgICAgaWYgKCFfLmlzRnVuY3Rpb24ob3BlcmF0aW9uR3JvdXAuaGVscCkpIHtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cC5oZWxwID0gXy5iaW5kKHNlbGYuaGVscCwgb3BlcmF0aW9uR3JvdXApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYmluZCB0byB0aGUgYXBpcyBvYmplY3RcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0gPSBvcGVyYXRpb25Hcm91cFtvcGVyYXRpb25JZF0gPSBfLmJpbmQob3BlcmF0aW9uT2JqZWN0LmV4ZWN1dGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uT2JqZWN0KTtcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0uaGVscCA9IG9wZXJhdGlvbkdyb3VwW29wZXJhdGlvbklkXS5oZWxwID0gXy5iaW5kKG9wZXJhdGlvbk9iamVjdC5oZWxwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uT2JqZWN0KTtcbiAgICAgICAgc2VsZi5hcGlzW2FwaVByb3BlcnR5XVtvcGVyYXRpb25JZF0uYXNDdXJsID0gb3BlcmF0aW9uR3JvdXBbb3BlcmF0aW9uSWRdLmFzQ3VybCA9IF8uYmluZChvcGVyYXRpb25PYmplY3QuYXNDdXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbk9iamVjdCk7XG5cbiAgICAgICAgb3BlcmF0aW9uR3JvdXAuYXBpc1tvcGVyYXRpb25JZF0gPSBvcGVyYXRpb25Hcm91cC5vcGVyYXRpb25zW29wZXJhdGlvbklkXSA9IG9wZXJhdGlvbk9iamVjdDtcblxuICAgICAgICAvLyBsZWdhY3kgVUkgZmVhdHVyZVxuICAgICAgICB2YXIgYXBpID0gXy5maW5kKHNlbGYuYXBpc0FycmF5LCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgICAgICAgcmV0dXJuIGFwaS50YWcgPT09IHRhZztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGFwaSkge1xuICAgICAgICAgIGFwaS5vcGVyYXRpb25zQXJyYXkucHVzaChvcGVyYXRpb25PYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gc29ydCB0aGUgYXBpc0FycmF5IGFjY29yZGluZyB0byB0aGUgdGFnc1xuICB2YXIgc29ydGVkQXBpcyA9IFtdO1xuICBfLmZvckVhY2goT2JqZWN0LmtleXMoZGVmaW5lZFRhZ3MpLCBmdW5jdGlvbiAodGFnKSB7XG4gICAgdmFyIF9hcGlUb0FkZDtcbiAgICB2YXIgcG9zO1xuICAgIGZvcihwb3MgaW4gc2VsZi5hcGlzQXJyYXkpIHtcbiAgICAgIHZhciBfYXBpID0gc2VsZi5hcGlzQXJyYXlbcG9zXTtcbiAgICAgIGlmKF9hcGkgJiYgdGFnID09PSBfYXBpLm5hbWUpIHtcbiAgICAgICAgc29ydGVkQXBpcy5wdXNoKF9hcGkpO1xuICAgICAgICBzZWxmLmFwaXNBcnJheVtwb3NdID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICAvLyBhZGQgYW55dGhpbmcgbGVmdFxuICBfLmZvckVhY2goc2VsZi5hcGlzQXJyYXksIGZ1bmN0aW9uIChhcGkpIHtcbiAgICBpZihhcGkpIHtcbiAgICAgIHNvcnRlZEFwaXMucHVzaChhcGkpO1xuICAgIH1cbiAgfSk7XG4gIHNlbGYuYXBpc0FycmF5ID0gc29ydGVkQXBpcztcblxuICBfLmZvckVhY2gocmVzcG9uc2UuZGVmaW5pdGlvbnMsIGZ1bmN0aW9uIChkZWZpbml0aW9uT2JqLCBkZWZpbml0aW9uKSB7XG4gICAgZGVmaW5pdGlvbk9ialsnaWQnXSA9IGRlZmluaXRpb24udG9Mb3dlckNhc2UoKTtcbiAgICBkZWZpbml0aW9uT2JqWyduYW1lJ10gPSBkZWZpbml0aW9uO1xuICAgIHNlbGYubW9kZWxzQXJyYXkucHVzaChkZWZpbml0aW9uT2JqKTtcbiAgfSk7XG5cbiAgdGhpcy5pc0J1aWx0ID0gdHJ1ZTtcblxuICBpZiAodGhpcy51c2VQcm9taXNlKSB7XG4gICAgdGhpcy5pc1ZhbGlkID0gdHJ1ZTtcbiAgICB0aGlzLmlzQnVpbHQgPSB0cnVlO1xuICAgIHRoaXMuZGVmZXJyZWRDbGllbnQucmVzb2x2ZSh0aGlzKTtcblxuICAgIHJldHVybiB0aGlzLmRlZmVycmVkQ2xpZW50LnByb21pc2U7XG4gIH1cblxuICBpZiAodGhpcy5zdWNjZXNzKSB7XG4gICAgdGhpcy5zdWNjZXNzKCk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLm1ha2VVbmlxdWVPcGVyYXRpb25JZCA9IGZ1bmN0aW9uKG9wZXJhdGlvbklkLCBhcGkpIHtcbiAgdmFyIGNvdW50ID0gMDtcbiAgdmFyIG5hbWUgPSBvcGVyYXRpb25JZDtcblxuICAvLyBtYWtlIHVuaXF1ZSBhY3Jvc3MgdGhpcyBvcGVyYXRpb24gZ3JvdXBcbiAgd2hpbGUodHJ1ZSkge1xuICAgIHZhciBtYXRjaGVkID0gZmFsc2U7XG4gICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbiAob3BlcmF0aW9uKSB7XG4gICAgICBpZihvcGVyYXRpb24ubmlja25hbWUgPT09IG5hbWUpIHtcbiAgICAgICAgbWF0Y2hlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYoIW1hdGNoZWQpIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cbiAgICBuYW1lID0gb3BlcmF0aW9uSWQgKyAnXycgKyBjb3VudDtcbiAgICBjb3VudCArKztcbiAgfVxuXG4gIHJldHVybiBvcGVyYXRpb25JZDtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnBhcnNlVXJpID0gZnVuY3Rpb24gKHVyaSkge1xuICB2YXIgdXJsUGFyc2VSRSA9IC9eKCgoKFteOlxcLyNcXD9dKzopPyg/OihcXC9cXC8pKCg/OigoW146QFxcLyNcXD9dKykoPzpcXDooW146QFxcLyNcXD9dKykpPylAKT8oKFteOlxcLyNcXD9cXF1cXFtdK3xcXFtbXlxcL1xcXUAjP10rXFxdKSg/OlxcOihbMC05XSspKT8pKT8pPyk/KChcXC8/KD86W15cXC9cXD8jXStcXC8rKSopKFteXFw/I10qKSkpPyhcXD9bXiNdKyk/KSgjLiopPy87XG4gIHZhciBwYXJ0cyA9IHVybFBhcnNlUkUuZXhlYyh1cmkpO1xuXG4gIHJldHVybiB7XG4gICAgc2NoZW1lOiBwYXJ0c1s0XSA/IHBhcnRzWzRdLnJlcGxhY2UoJzonLCcnKSA6IHVuZGVmaW5lZCxcbiAgICBob3N0OiBwYXJ0c1sxMV0sXG4gICAgcG9ydDogcGFydHNbMTJdLFxuICAgIHBhdGg6IHBhcnRzWzE1XVxuICB9O1xufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaGVscCA9IGZ1bmN0aW9uIChkb250UHJpbnQpIHtcbiAgdmFyIG91dHB1dCA9ICcnO1xuXG4gIGlmICh0aGlzIGluc3RhbmNlb2YgU3dhZ2dlckNsaWVudCkge1xuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uIChhcGksIG5hbWUpIHtcbiAgICAgIGlmIChfLmlzUGxhaW5PYmplY3QoYXBpKSkge1xuICAgICAgICBvdXRwdXQgKz0gJ29wZXJhdGlvbnMgZm9yIHRoZSBcXCcnICsgbmFtZSArICdcXCcgdGFnXFxuJztcblxuICAgICAgICBfLmZvckVhY2goYXBpLm9wZXJhdGlvbnMsIGZ1bmN0aW9uIChvcGVyYXRpb24sIG5hbWUpIHtcbiAgICAgICAgICBvdXRwdXQgKz0gJyAgKiAnICsgbmFtZSArICc6ICcgKyBvcGVyYXRpb24uc3VtbWFyeSArICdcXG4nO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIGlmICh0aGlzIGluc3RhbmNlb2YgT3BlcmF0aW9uR3JvdXAgfHwgXy5pc1BsYWluT2JqZWN0KHRoaXMpKSB7XG4gICAgb3V0cHV0ICs9ICdvcGVyYXRpb25zIGZvciB0aGUgXFwnJyArIHRoaXMubGFiZWwgKyAnXFwnIHRhZ1xcbic7XG5cbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAob3BlcmF0aW9uLCBuYW1lKSB7XG4gICAgICBvdXRwdXQgKz0gJyAgKiAnICsgbmFtZSArICc6ICcgKyBvcGVyYXRpb24uc3VtbWFyeSArICdcXG4nO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGRvbnRQcmludCkge1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH0gZWxzZSB7XG4gICAgaGVscGVycy5sb2cob3V0cHV0KTtcblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnRhZ0Zyb21MYWJlbCA9IGZ1bmN0aW9uIChsYWJlbCkge1xuICByZXR1cm4gbGFiZWw7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5pZEZyb21PcCA9IGZ1bmN0aW9uIChwYXRoLCBodHRwTWV0aG9kLCBvcCkge1xuICBpZighb3AgfHwgIW9wLm9wZXJhdGlvbklkKSB7XG4gICAgb3AgPSBvcCB8fCB7fTtcbiAgICBvcC5vcGVyYXRpb25JZCA9IGh0dHBNZXRob2QgKyAnXycgKyBwYXRoO1xuICB9XG4gIHZhciBvcElkID0gb3Aub3BlcmF0aW9uSWQucmVwbGFjZSgvW1xccyFAIyQlXiYqKClfKz1cXFt7XFxdfTs6PD58LlxcLz8sXFxcXCdcIlwiLV0vZywgJ18nKSB8fCAocGF0aC5zdWJzdHJpbmcoMSkgKyAnXycgKyBodHRwTWV0aG9kKTtcblxuICBvcElkID0gb3BJZC5yZXBsYWNlKC8oKF8pezIsfSkvZywgJ18nKTtcbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvXihfKSovZywgJycpO1xuICBvcElkID0gb3BJZC5yZXBsYWNlKC8oW19dKSokL2csICcnKTtcblxuICByZXR1cm4gb3BJZDtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnNldEhvc3QgPSBmdW5jdGlvbiAoaG9zdCkge1xuICB0aGlzLmhvc3QgPSBob3N0O1xuXG4gIGlmKHRoaXMuYXBpcykge1xuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uKGFwaSkge1xuICAgICAgaWYoYXBpLm9wZXJhdGlvbnMpIHtcbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbihvcGVyYXRpb24pIHtcbiAgICAgICAgICBvcGVyYXRpb24uaG9zdCA9IGhvc3Q7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5zZXRCYXNlUGF0aCA9IGZ1bmN0aW9uIChiYXNlUGF0aCkge1xuICB0aGlzLmJhc2VQYXRoID0gYmFzZVBhdGg7XG5cbiAgaWYodGhpcy5hcGlzKSB7XG4gICAgXy5mb3JFYWNoKHRoaXMuYXBpcywgZnVuY3Rpb24oYXBpKSB7XG4gICAgICBpZihhcGkub3BlcmF0aW9ucykge1xuICAgICAgICBfLmZvckVhY2goYXBpLm9wZXJhdGlvbnMsIGZ1bmN0aW9uKG9wZXJhdGlvbikge1xuICAgICAgICAgIG9wZXJhdGlvbi5iYXNlUGF0aCA9IGJhc2VQYXRoO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuc2V0U2NoZW1lcyA9IGZ1bmN0aW9uIChzY2hlbWVzKSB7XG4gIHRoaXMuc2NoZW1lcyA9IHNjaGVtZXM7XG5cbiAgaWYoc2NoZW1lcyAmJiBzY2hlbWVzLmxlbmd0aCA+IDApIHtcbiAgICBpZih0aGlzLmFwaXMpIHtcbiAgICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uIChhcGkpIHtcbiAgICAgICAgaWYgKGFwaS5vcGVyYXRpb25zKSB7XG4gICAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbiAob3BlcmF0aW9uKSB7XG4gICAgICAgICAgICBvcGVyYXRpb24uc2NoZW1lID0gc2NoZW1lc1swXTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59O1xuXG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmZhaWwgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICBpZiAodGhpcy51c2VQcm9taXNlKSB7XG4gICAgdGhpcy5kZWZlcnJlZENsaWVudC5yZWplY3QobWVzc2FnZSk7XG4gICAgcmV0dXJuIHRoaXMuZGVmZXJyZWRDbGllbnQucHJvbWlzZTtcbiAgfSBlbHNlIHtcbiAgICBpZiAodGhpcy5mYWlsdXJlKSB7XG4gICAgICB0aGlzLmZhaWx1cmUobWVzc2FnZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy5mYWlsdXJlKG1lc3NhZ2UpO1xuICAgIH1cbiAgfVxufTtcbiIsIihmdW5jdGlvbiAocHJvY2Vzcyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBpc1BsYWluT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdCcpLFxuICBpbmRleE9mOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2FycmF5L2luZGV4T2YnKVxufTtcblxubW9kdWxlLmV4cG9ydHMuX19iaW5kID0gZnVuY3Rpb24gKGZuLCBtZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKXtcbiAgICByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7XG4gIH07XG59O1xuXG52YXIgbG9nID0gbW9kdWxlLmV4cG9ydHMubG9nID0gZnVuY3Rpb24oKSB7XG4gIC8vIE9ubHkgbG9nIGlmIGF2YWlsYWJsZSBhbmQgd2UncmUgbm90IHRlc3RpbmdcbiAgaWYgKGNvbnNvbGUgJiYgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICd0ZXN0Jykge1xuICAgIGNvbnNvbGUubG9nKEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cylbMF0pO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5mYWlsID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgbG9nKG1lc3NhZ2UpO1xufTtcblxudmFyIG9wdGlvbkh0bWwgPSBtb2R1bGUuZXhwb3J0cy5vcHRpb25IdG1sID0gZnVuY3Rpb24gKGxhYmVsLCB2YWx1ZSkge1xuICByZXR1cm4gJzx0cj48dGQgY2xhc3M9XCJvcHRpb25OYW1lXCI+JyArIGxhYmVsICsgJzo8L3RkPjx0ZD4nICsgdmFsdWUgKyAnPC90ZD48L3RyPic7XG59O1xuXG52YXIgcmVzb2x2ZVNjaGVtYSA9IG1vZHVsZS5leHBvcnRzLnJlc29sdmVTY2hlbWEgPSBmdW5jdGlvbiAoc2NoZW1hKSB7XG4gIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLnNjaGVtYSkpIHtcbiAgICBzY2hlbWEgPSByZXNvbHZlU2NoZW1hKHNjaGVtYS5zY2hlbWEpO1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn07XG5cbnZhciBzaW1wbGVSZWYgPSBtb2R1bGUuZXhwb3J0cy5zaW1wbGVSZWYgPSBmdW5jdGlvbiAobmFtZSkge1xuICBpZiAodHlwZW9mIG5hbWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAobmFtZS5pbmRleE9mKCcjL2RlZmluaXRpb25zLycpID09PSAwKSB7XG4gICAgcmV0dXJuIG5hbWUuc3Vic3RyaW5nKCcjL2RlZmluaXRpb25zLycubGVuZ3RoKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmFtZTtcbiAgfVxufTtcblxuXG59KS5jYWxsKHRoaXMscmVxdWlyZSgnX3Byb2Nlc3MnKSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYklteHBZaTlvWld4d1pYSnpMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVNJc0ltWnBiR1VpT2lKblpXNWxjbUYwWldRdWFuTWlMQ0p6YjNWeVkyVlNiMjkwSWpvaUlpd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sc2lKM1Z6WlNCemRISnBZM1FuTzF4dVhHNTJZWElnWHlBOUlIdGNiaUFnYVhOUWJHRnBiazlpYW1WamREb2djbVZ4ZFdseVpTZ25iRzlrWVhOb0xXTnZiWEJoZEM5c1lXNW5MMmx6VUd4aGFXNVBZbXBsWTNRbktTeGNiaUFnYVc1a1pYaFBaam9nY21WeGRXbHlaU2duYkc5a1lYTm9MV052YlhCaGRDOWhjbkpoZVM5cGJtUmxlRTltSnlsY2JuMDdYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpMbDlmWW1sdVpDQTlJR1oxYm1OMGFXOXVJQ2htYml3Z2JXVXBJSHRjYmlBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1S0NsN1hHNGdJQ0FnY21WMGRYSnVJR1p1TG1Gd2NHeDVLRzFsTENCaGNtZDFiV1Z1ZEhNcE8xeHVJQ0I5TzF4dWZUdGNibHh1ZG1GeUlHeHZaeUE5SUcxdlpIVnNaUzVsZUhCdmNuUnpMbXh2WnlBOUlHWjFibU4wYVc5dUtDa2dlMXh1SUNBdkx5QlBibXg1SUd4dlp5QnBaaUJoZG1GcGJHRmliR1VnWVc1a0lIZGxKM0psSUc1dmRDQjBaWE4wYVc1blhHNGdJR2xtSUNoamIyNXpiMnhsSUNZbUlIQnliMk5sYzNNdVpXNTJMazVQUkVWZlJVNVdJQ0U5UFNBbmRHVnpkQ2NwSUh0Y2JpQWdJQ0JqYjI1emIyeGxMbXh2WnloQmNuSmhlUzV3Y205MGIzUjVjR1V1YzJ4cFkyVXVZMkZzYkNoaGNtZDFiV1Z1ZEhNcFd6QmRLVHRjYmlBZ2ZWeHVmVHRjYmx4dWJXOWtkV3hsTG1WNGNHOXlkSE11Wm1GcGJDQTlJR1oxYm1OMGFXOXVJQ2h0WlhOellXZGxLU0I3WEc0Z0lHeHZaeWh0WlhOellXZGxLVHRjYm4wN1hHNWNiblpoY2lCdmNIUnBiMjVJZEcxc0lEMGdiVzlrZFd4bExtVjRjRzl5ZEhNdWIzQjBhVzl1U0hSdGJDQTlJR1oxYm1OMGFXOXVJQ2hzWVdKbGJDd2dkbUZzZFdVcElIdGNiaUFnY21WMGRYSnVJQ2M4ZEhJK1BIUmtJR05zWVhOelBWd2liM0IwYVc5dVRtRnRaVndpUGljZ0t5QnNZV0psYkNBcklDYzZQQzkwWkQ0OGRHUStKeUFySUhaaGJIVmxJQ3NnSnp3dmRHUStQQzkwY2o0bk8xeHVmVHRjYmx4dWRtRnlJSEpsYzI5c2RtVlRZMmhsYldFZ1BTQnRiMlIxYkdVdVpYaHdiM0owY3k1eVpYTnZiSFpsVTJOb1pXMWhJRDBnWm5WdVkzUnBiMjRnS0hOamFHVnRZU2tnZTF4dUlDQnBaaUFvWHk1cGMxQnNZV2x1VDJKcVpXTjBLSE5qYUdWdFlTNXpZMmhsYldFcEtTQjdYRzRnSUNBZ2MyTm9aVzFoSUQwZ2NtVnpiMngyWlZOamFHVnRZU2h6WTJobGJXRXVjMk5vWlcxaEtUdGNiaUFnZlZ4dVhHNGdJSEpsZEhWeWJpQnpZMmhsYldFN1hHNTlPMXh1WEc1MllYSWdjMmx0Y0d4bFVtVm1JRDBnYlc5a2RXeGxMbVY0Y0c5eWRITXVjMmx0Y0d4bFVtVm1JRDBnWm5WdVkzUnBiMjRnS0c1aGJXVXBJSHRjYmlBZ2FXWWdLSFI1Y0dWdlppQnVZVzFsSUQwOVBTQW5kVzVrWldacGJtVmtKeWtnZTF4dUlDQWdJSEpsZEhWeWJpQnVkV3hzTzF4dUlDQjlYRzVjYmlBZ2FXWWdLRzVoYldVdWFXNWtaWGhQWmlnbkl5OWtaV1pwYm1sMGFXOXVjeThuS1NBOVBUMGdNQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQnVZVzFsTG5OMVluTjBjbWx1Wnlnbkl5OWtaV1pwYm1sMGFXOXVjeThuTG14bGJtZDBhQ2s3WEc0Z0lIMGdaV3h6WlNCN1hHNGdJQ0FnY21WMGRYSnVJRzVoYldVN1hHNGdJSDFjYm4wN1hHNWNiaUpkZlE9PSIsIid1c2Ugc3RyaWN0JztcblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcbnZhciByZXF1ZXN0ID0gcmVxdWlyZSgnc3VwZXJhZ2VudCcpO1xudmFyIGpzeWFtbCA9IHJlcXVpcmUoJ2pzLXlhbWwnKTtcbnZhciBfID0ge1xuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0Jylcbn07XG5cbi8qXG4gKiBKUXVlcnlIdHRwQ2xpZW50IGlzIGEgbGlnaHQtd2VpZ2h0LCBub2RlIG9yIGJyb3dzZXIgSFRUUCBjbGllbnRcbiAqL1xudmFyIEpRdWVyeUh0dHBDbGllbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMudHlwZSA9ICdKUXVlcnlIdHRwQ2xpZW50Jztcbn07XG5cbi8qXG4gKiBTdXBlcmFnZW50SHR0cENsaWVudCBpcyBhIGxpZ2h0LXdlaWdodCwgbm9kZSBvciBicm93c2VyIEhUVFAgY2xpZW50XG4gKi9cbnZhciBTdXBlcmFnZW50SHR0cENsaWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy50eXBlID0gJ1N1cGVyYWdlbnRIdHRwQ2xpZW50Jztcbn07XG5cbi8qKlxuICogU3dhZ2dlckh0dHAgaXMgYSB3cmFwcGVyIGZvciBleGVjdXRpbmcgcmVxdWVzdHNcbiAqL1xudmFyIFN3YWdnZXJIdHRwID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7fTtcblxuU3dhZ2dlckh0dHAucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAob2JqLCBvcHRzKSB7XG4gIHZhciBjbGllbnQ7XG5cbiAgaWYob3B0cyAmJiBvcHRzLmNsaWVudCkge1xuICAgIGNsaWVudCA9IG9wdHMuY2xpZW50O1xuICB9XG4gIGVsc2Uge1xuICAgIGNsaWVudCA9IG5ldyBTdXBlcmFnZW50SHR0cENsaWVudChvcHRzKTtcbiAgfVxuICBjbGllbnQub3B0cyA9IG9wdHMgfHwge307XG5cbiAgLy8gbGVnYWN5IHN1cHBvcnRcbiAgdmFyIGhhc0pRdWVyeSA9IGZhbHNlO1xuICBpZih0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmKHR5cGVvZiB3aW5kb3cualF1ZXJ5ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaGFzSlF1ZXJ5ID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgLy8gT1BUSU9OUyBzdXBwb3J0XG4gIGlmKG9iai5tZXRob2QudG9Mb3dlckNhc2UoKSA9PT0gJ29wdGlvbnMnICYmIGNsaWVudC50eXBlID09PSAnU3VwZXJhZ2VudEh0dHBDbGllbnQnKSB7XG4gICAgbG9nKCdmb3JjaW5nIGpRdWVyeSBhcyBPUFRJT05TIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IFN1cGVyQWdlbnQnKTtcbiAgICBvYmoudXNlSlF1ZXJ5ID0gdHJ1ZTtcbiAgfVxuICBpZih0aGlzLmlzSW50ZXJuZXRFeHBsb3JlcigpICYmIChvYmoudXNlSlF1ZXJ5ID09PSBmYWxzZSB8fCAhaGFzSlF1ZXJ5ICkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGNvbmZpZ3VyYXRpb24hIEpRdWVyeSBpcyByZXF1aXJlZCBidXQgbm90IGF2YWlsYWJsZScpO1xuICB9XG4gIGlmICgob2JqICYmIG9iai51c2VKUXVlcnkgPT09IHRydWUpIHx8IHRoaXMuaXNJbnRlcm5ldEV4cGxvcmVyKCkgJiYgaGFzSlF1ZXJ5KSB7XG4gICAgY2xpZW50ID0gbmV3IEpRdWVyeUh0dHBDbGllbnQob3B0cyk7XG4gIH1cblxuICB2YXIgc3VjY2VzcyA9IG9iai5vbi5yZXNwb25zZTtcbiAgdmFyIGVycm9yID0gb2JqLm9uLmVycm9yO1xuXG4gIHZhciByZXF1ZXN0SW50ZXJjZXB0b3IgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgaWYob3B0cyAmJiBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvcikge1xuICAgICAgZGF0YSA9IG9wdHMucmVxdWVzdEludGVyY2VwdG9yLmFwcGx5KGRhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfTtcblxuICB2YXIgcmVzcG9uc2VJbnRlcmNlcHRvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZihvcHRzICYmIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvcikge1xuICAgICAgZGF0YSA9IG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvci5hcHBseShkYXRhKTtcbiAgICB9XG4gICAgcmV0dXJuIHN1Y2Nlc3MoZGF0YSk7XG4gIH07XG5cbiAgdmFyIGVycm9ySW50ZXJjZXB0b3IgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgaWYob3B0cyAmJiBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IpIHtcbiAgICAgIGRhdGEgPSBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IuYXBwbHkoZGF0YSk7XG4gICAgfVxuICAgIGVycm9yKGRhdGEpO1xuICB9O1xuXG4gIG9iai5vbi5lcnJvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBlcnJvckludGVyY2VwdG9yKGRhdGEpO1xuICB9O1xuXG4gIG9iai5vbi5yZXNwb25zZSA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICByZXNwb25zZUludGVyY2VwdG9yKGRhdGEpO1xuICB9O1xuXG4gIGlmIChfLmlzT2JqZWN0KG9iaikgJiYgXy5pc09iamVjdChvYmouYm9keSkpIHtcbiAgICAvLyBzcGVjaWFsIHByb2Nlc3NpbmcgZm9yIGZpbGUgdXBsb2FkcyB2aWEganF1ZXJ5XG4gICAgaWYgKG9iai5ib2R5LnR5cGUgJiYgb2JqLmJvZHkudHlwZSA9PT0gJ2Zvcm1EYXRhJyl7XG4gICAgICBpZihvcHRzLnVzZUpRdWVyeSkge1xuICAgICAgICBvYmouY29udGVudFR5cGUgPSBmYWxzZTtcbiAgICAgICAgb2JqLnByb2Nlc3NEYXRhID0gZmFsc2U7XG4gICAgICAgIGRlbGV0ZSBvYmouaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb2JqID0gcmVxdWVzdEludGVyY2VwdG9yKG9iaikgfHwgb2JqO1xuICBpZiAob2JqLmJlZm9yZVNlbmQpIHtcbiAgICBvYmouYmVmb3JlU2VuZChmdW5jdGlvbihfb2JqKSB7XG4gICAgICBjbGllbnQuZXhlY3V0ZShfb2JqIHx8IG9iaik7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY2xpZW50LmV4ZWN1dGUob2JqKTtcbiAgfVxuXG4gIHJldHVybiAob2JqLmRlZmVycmVkKSA/IG9iai5kZWZlcnJlZC5wcm9taXNlIDogb2JqO1xufTtcblxuU3dhZ2dlckh0dHAucHJvdG90eXBlLmlzSW50ZXJuZXRFeHBsb3JlciA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGRldGVjdGVkSUUgPSBmYWxzZTtcblxuICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCkge1xuICAgIHZhciBuYXYgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAobmF2LmluZGV4T2YoJ21zaWUnKSAhPT0gLTEpIHtcbiAgICAgIHZhciB2ZXJzaW9uID0gcGFyc2VJbnQobmF2LnNwbGl0KCdtc2llJylbMV0pO1xuXG4gICAgICBpZiAodmVyc2lvbiA8PSA4KSB7XG4gICAgICAgIGRldGVjdGVkSUUgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkZXRlY3RlZElFO1xufTtcblxuSlF1ZXJ5SHR0cENsaWVudC5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGpxID0gdGhpcy5qUXVlcnkgfHwgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5qUXVlcnkpO1xuICB2YXIgY2IgPSBvYmoub247XG4gIHZhciByZXF1ZXN0ID0gb2JqO1xuXG4gIGlmKHR5cGVvZiBqcSA9PT0gJ3VuZGVmaW5lZCcgfHwganEgPT09IGZhbHNlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb25maWd1cmF0aW9uISBKUXVlcnkgaXMgcmVxdWlyZWQgYnV0IG5vdCBhdmFpbGFibGUnKTtcbiAgfVxuXG4gIG9iai50eXBlID0gb2JqLm1ldGhvZDtcbiAgb2JqLmNhY2hlID0gb2JqLmpxdWVyeUFqYXhDYWNoZTtcbiAgb2JqLmRhdGEgPSBvYmouYm9keTtcbiAgZGVsZXRlIG9iai5qcXVlcnlBamF4Q2FjaGU7XG4gIGRlbGV0ZSBvYmoudXNlSlF1ZXJ5O1xuICBkZWxldGUgb2JqLmJvZHk7XG5cbiAgb2JqLmNvbXBsZXRlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgICB2YXIgaGVhZGVyQXJyYXkgPSByZXNwb25zZS5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKS5zcGxpdCgnXFxuJyk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhlYWRlckFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdG9TcGxpdCA9IGhlYWRlckFycmF5W2ldLnRyaW0oKTtcblxuICAgICAgaWYgKHRvU3BsaXQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2VwYXJhdG9yID0gdG9TcGxpdC5pbmRleE9mKCc6Jyk7XG5cbiAgICAgIGlmIChzZXBhcmF0b3IgPT09IC0xKSB7XG4gICAgICAgIC8vIE5hbWUgYnV0IG5vIHZhbHVlIGluIHRoZSBoZWFkZXJcbiAgICAgICAgaGVhZGVyc1t0b1NwbGl0XSA9IG51bGw7XG5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBuYW1lID0gdG9TcGxpdC5zdWJzdHJpbmcoMCwgc2VwYXJhdG9yKS50cmltKCk7XG4gICAgICB2YXIgdmFsdWUgPSB0b1NwbGl0LnN1YnN0cmluZyhzZXBhcmF0b3IgKyAxKS50cmltKCk7XG5cbiAgICAgIGhlYWRlcnNbbmFtZV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgb3V0ID0ge1xuICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICBkYXRhOiByZXNwb25zZS5yZXNwb25zZVRleHQsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgcG9zc2libGVPYmogPSAgcmVzcG9uc2UucmVzcG9uc2VKU09OIHx8IGpzeWFtbC5zYWZlTG9hZChyZXNwb25zZS5yZXNwb25zZVRleHQpO1xuICAgICAgb3V0Lm9iaiA9ICh0eXBlb2YgcG9zc2libGVPYmogPT09ICdzdHJpbmcnKSA/IHt9IDogcG9zc2libGVPYmo7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIC8vIGRvIG5vdCBzZXQgb3V0Lm9ialxuICAgICAgaGVscGVycy5sb2coJ3VuYWJsZSB0byBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgIH1cblxuICAgIC8vIEkgY2FuIHRocm93LCBvciBwYXJzZSBudWxsP1xuICAgIG91dC5vYmogPSBvdXQub2JqIHx8IG51bGw7XG5cbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDIwMCAmJiByZXNwb25zZS5zdGF0dXMgPCAzMDApIHtcbiAgICAgIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDAgfHwgKHJlc3BvbnNlLnN0YXR1cyA+PSA0MDAgJiYgcmVzcG9uc2Uuc3RhdHVzIDwgNTk5KSkge1xuICAgICAgY2IuZXJyb3Iob3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfVxuICB9O1xuXG4gIGpxLnN1cHBvcnQuY29ycyA9IHRydWU7XG5cbiAgcmV0dXJuIGpxLmFqYXgob2JqKTtcbn07XG5cblN1cGVyYWdlbnRIdHRwQ2xpZW50LnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKG9iaikge1xuICB2YXIgbWV0aG9kID0gb2JqLm1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmIChtZXRob2QgPT09ICdkZWxldGUnKSB7XG4gICAgbWV0aG9kID0gJ2RlbCc7XG4gIH1cbiAgdmFyIGhlYWRlcnMgPSBvYmouaGVhZGVycyB8fCB7fTtcbiAgdmFyIHIgPSByZXF1ZXN0W21ldGhvZF0ob2JqLnVybCk7XG5cbiAgaWYgKG9iai5lbmFibGVDb29raWVzKSB7XG4gICAgci53aXRoQ3JlZGVudGlhbHMoKTtcbiAgfVxuXG4gIGlmKG9iai5ib2R5KSB7XG4gICAgaWYoXy5pc09iamVjdChvYmouYm9keSkpIHtcbiAgICAgIHZhciBjb250ZW50VHlwZSA9IG9iai5oZWFkZXJzWydDb250ZW50LVR5cGUnXSB8fCAnJztcbiAgICAgIGlmIChjb250ZW50VHlwZS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPT09IDApIHtcbiAgICAgICAgZGVsZXRlIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgICAgICBpZih7fS50b1N0cmluZy5hcHBseShvYmouYm9keSkgPT09ICdbb2JqZWN0IEZvcm1EYXRhXScpIHtcbiAgICAgICAgICB2YXIgaXRyID0gb2JqLmJvZHkua2V5cygpO1xuICAgICAgICAgIHdoaWxlKHRydWUpIHtcbiAgICAgICAgICAgIHZhciB2ID0gaXRyLm5leHQoKTtcbiAgICAgICAgICAgIGlmKHYuZG9uZSkge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBrZXkgPSB2LnZhbHVlO1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gb2JqLmJvZHkuZ2V0KGtleSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh7fS50b1N0cmluZy5hcHBseSh2YWx1ZSkpO1xuICAgICAgICAgICAgaWYoe30udG9TdHJpbmcuYXBwbHkodmFsdWUpID09PSAnW29iamVjdCBGaWxlXScpIHtcbiAgICAgICAgICAgICAgci5hdHRhY2goa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgci5maWVsZChrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdmFyIGtleW5hbWU7XG4gICAgICAgICAgZm9yICh2YXIga2V5bmFtZSBpbiBvYmouYm9keSkge1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gb2JqLmJvZHlba2V5bmFtZV07XG4gICAgICAgICAgICByLmZpZWxkKGtleW5hbWUsIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgICAgIG9iai5ib2R5ID0gSlNPTi5zdHJpbmdpZnkob2JqLmJvZHkpO1xuICAgICAgICByLnNlbmQob2JqLmJvZHkpO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHIuc2VuZChvYmouYm9keSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIG5hbWU7XG4gIGZvciAobmFtZSBpbiBoZWFkZXJzKSB7XG4gICAgci5zZXQobmFtZSwgaGVhZGVyc1tuYW1lXSk7XG4gIH1cblxuICBpZih0eXBlb2Ygci5idWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByLmJ1ZmZlcigpOyAvLyBmb3JjZSBzdXBlcmFnZW50IHRvIHBvcHVsYXRlIHJlcy50ZXh0IHdpdGggdGhlIHJhdyByZXNwb25zZSBkYXRhXG4gIH1cblxuICByLmVuZChmdW5jdGlvbiAoZXJyLCByZXMpIHtcbiAgICByZXMgPSByZXMgfHwge1xuICAgICAgc3RhdHVzOiAwLFxuICAgICAgaGVhZGVyczoge2Vycm9yOiAnbm8gcmVzcG9uc2UgZnJvbSBzZXJ2ZXInfVxuICAgIH07XG4gICAgdmFyIHJlc3BvbnNlID0ge1xuICAgICAgdXJsOiBvYmoudXJsLFxuICAgICAgbWV0aG9kOiBvYmoubWV0aG9kLFxuICAgICAgaGVhZGVyczogcmVzLmhlYWRlcnNcbiAgICB9O1xuICAgIHZhciBjYjtcblxuICAgIGlmICghZXJyICYmIHJlcy5lcnJvcikge1xuICAgICAgZXJyID0gcmVzLmVycm9yO1xuICAgIH1cblxuICAgIGlmIChlcnIgJiYgb2JqLm9uICYmIG9iai5vbi5lcnJvcikge1xuICAgICAgcmVzcG9uc2UuZXJyT2JqID0gZXJyO1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzID0gcmVzID8gcmVzLnN0YXR1cyA6IDUwMDtcbiAgICAgIHJlc3BvbnNlLnN0YXR1c1RleHQgPSByZXMgPyByZXMudGV4dCA6IGVyci5tZXNzYWdlO1xuICAgICAgaWYocmVzLmhlYWRlcnMgJiYgcmVzLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddKSB7XG4gICAgICAgIGlmKHJlcy5oZWFkZXJzWydjb250ZW50LXR5cGUnXS5pbmRleE9mKCdhcHBsaWNhdGlvbi9qc29uJykgPj0gMCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXNwb25zZS5vYmogPSBKU09OLnBhcnNlKHJlc3BvbnNlLnN0YXR1c1RleHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmVzcG9uc2Uub2JqID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNiID0gb2JqLm9uLmVycm9yO1xuICAgIH0gZWxzZSBpZiAocmVzICYmIG9iai5vbiAmJiBvYmoub24ucmVzcG9uc2UpIHtcbiAgICAgIHZhciBwb3NzaWJsZU9iajtcblxuICAgICAgLy8gQWxyZWFkeSBwYXJzZWQgYnkgYnkgc3VwZXJhZ2VudD9cbiAgICAgIGlmKHJlcy5ib2R5ICYmIE9iamVjdC5rZXlzKHJlcy5ib2R5KS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHBvc3NpYmxlT2JqID0gcmVzLmJvZHk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwb3NzaWJsZU9iaiA9IGpzeWFtbC5zYWZlTG9hZChyZXMudGV4dCk7XG4gICAgICAgICAgICAvLyBjYW4gcGFyc2UgaW50byBhIHN0cmluZy4uLiB3aGljaCB3ZSBkb24ndCBuZWVkIHJ1bm5pbmcgYXJvdW5kIGluIHRoZSBzeXN0ZW1cbiAgICAgICAgICAgIHBvc3NpYmxlT2JqID0gKHR5cGVvZiBwb3NzaWJsZU9iaiA9PT0gJ3N0cmluZycpID8gbnVsbCA6IHBvc3NpYmxlT2JqO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaGVscGVycy5sb2coJ2Nhbm5vdCBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbnVsbCBtZWFucyB3ZSBjYW4ndCBwYXJzZSBpbnRvIG9iamVjdFxuICAgICAgcmVzcG9uc2Uub2JqID0gKHR5cGVvZiBwb3NzaWJsZU9iaiA9PT0gJ29iamVjdCcpID8gcG9zc2libGVPYmogOiBudWxsO1xuXG4gICAgICByZXNwb25zZS5zdGF0dXMgPSByZXMuc3RhdHVzO1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzVGV4dCA9IHJlcy50ZXh0O1xuICAgICAgY2IgPSBvYmoub24ucmVzcG9uc2U7XG4gICAgfVxuICAgIHJlc3BvbnNlLmRhdGEgPSByZXNwb25zZS5zdGF0dXNUZXh0O1xuXG4gICAgaWYgKGNiKSB7XG4gICAgICBjYihyZXNwb25zZSk7XG4gICAgfVxuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4vaHR0cCcpO1xudmFyIF8gPSB7XG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5JyksXG4gIGlzU3RyaW5nOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNTdHJpbmcnKVxufTtcblxuXG4vKipcbiAqIFJlc29sdmVzIGEgc3BlYydzIHJlbW90ZSByZWZlcmVuY2VzXG4gKi9cbnZhciBSZXNvbHZlciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmZhaWxlZFVybHMgPSBbXTtcbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5wcm9jZXNzQWxsT2YgPSBmdW5jdGlvbihyb290LCBuYW1lLCBkZWZpbml0aW9uLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKSB7XG4gIHZhciBpLCBsb2NhdGlvbiwgcHJvcGVydHk7XG5cbiAgZGVmaW5pdGlvblsneC1yZXNvbHZlZC1mcm9tJ10gPSBbICcjL2RlZmluaXRpb25zLycgKyBuYW1lIF07XG4gIHZhciBhbGxPZiA9IGRlZmluaXRpb24uYWxsT2Y7XG4gIC8vIHRoZSByZWZzIGdvIGZpcnN0XG4gIGFsbE9mLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgIGlmKGEuJHJlZiAmJiBiLiRyZWYpIHsgcmV0dXJuIDA7IH1cbiAgICBlbHNlIGlmKGEuJHJlZikgeyByZXR1cm4gLTE7IH1cbiAgICBlbHNlIHsgcmV0dXJuIDE7IH1cbiAgfSk7XG4gIGZvciAoaSA9IDA7IGkgPCBhbGxPZi5sZW5ndGg7IGkrKykge1xuICAgIHByb3BlcnR5ID0gYWxsT2ZbaV07XG4gICAgbG9jYXRpb24gPSAnL2RlZmluaXRpb25zLycgKyBuYW1lICsgJy9hbGxPZic7XG4gICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlID0gZnVuY3Rpb24gKHNwZWMsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgdGhpcy5zcGVjID0gc3BlYztcbiAgdmFyIHJvb3QgPSBhcmcxLCBjYWxsYmFjayA9IGFyZzIsIHNjb3BlID0gYXJnMywgb3B0cyA9IHt9LCBsb2NhdGlvbiwgaTtcbiAgaWYodHlwZW9mIGFyZzEgPT09ICdmdW5jdGlvbicpIHtcbiAgICByb290ID0gbnVsbDtcbiAgICBjYWxsYmFjayA9IGFyZzE7XG4gICAgc2NvcGUgPSBhcmcyO1xuICB9XG4gIHZhciBfcm9vdCA9IHJvb3Q7XG4gIHRoaXMuc2NvcGUgPSAoc2NvcGUgfHwgdGhpcyk7XG4gIHRoaXMuaXRlcmF0aW9uID0gdGhpcy5pdGVyYXRpb24gfHwgMDtcblxuICBpZih0aGlzLnNjb3BlLm9wdGlvbnMgJiYgdGhpcy5zY29wZS5vcHRpb25zLnJlcXVlc3RJbnRlcmNlcHRvcil7XG4gICAgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgPSB0aGlzLnNjb3BlLm9wdGlvbnMucmVxdWVzdEludGVyY2VwdG9yO1xuICB9XG5cbiAgaWYodGhpcy5zY29wZS5vcHRpb25zICYmIHRoaXMuc2NvcGUub3B0aW9ucy5yZXNwb25zZUludGVyY2VwdG9yKXtcbiAgICBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IgPSB0aGlzLnNjb3BlLm9wdGlvbnMucmVzcG9uc2VJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIHZhciBuYW1lLCBwYXRoLCBwcm9wZXJ0eSwgcHJvcGVydHlOYW1lO1xuICB2YXIgcHJvY2Vzc2VkQ2FsbHMgPSAwLCByZXNvbHZlZFJlZnMgPSB7fSwgdW5yZXNvbHZlZFJlZnMgPSB7fTtcbiAgdmFyIHJlc29sdXRpb25UYWJsZSA9IFtdOyAvLyBzdG9yZSBvYmplY3RzIGZvciBkZXJlZmVyZW5jaW5nXG5cbiAgc3BlYy5kZWZpbml0aW9ucyA9IHNwZWMuZGVmaW5pdGlvbnMgfHwge307XG4gIC8vIGRlZmluaXRpb25zXG4gIGZvciAobmFtZSBpbiBzcGVjLmRlZmluaXRpb25zKSB7XG4gICAgdmFyIGRlZmluaXRpb24gPSBzcGVjLmRlZmluaXRpb25zW25hbWVdO1xuICAgIGlmKGRlZmluaXRpb25bJyRyZWYnXSkge1xuICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIGRlZmluaXRpb24sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGRlZmluaXRpb24pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGZvciAocHJvcGVydHlOYW1lIGluIGRlZmluaXRpb24ucHJvcGVydGllcykge1xuICAgICAgICBwcm9wZXJ0eSA9IGRlZmluaXRpb24ucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuICAgICAgICBpZiAoXy5pc0FycmF5KHByb3BlcnR5LmFsbE9mKSkge1xuICAgICAgICAgIHRoaXMucHJvY2Vzc0FsbE9mKHJvb3QsIG5hbWUsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB0aGlzLnJlc29sdmVUbyhyb290LCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCAnL2RlZmluaXRpb25zJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGRlZmluaXRpb24uYWxsT2YpIHtcbiAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgZGVmaW5pdGlvbiwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gc2hhcmVkIHBhcmFtZXRlcnNcbiAgc3BlYy5wYXJhbWV0ZXJzID0gc3BlYy5wYXJhbWV0ZXJzIHx8IHt9O1xuICBmb3IobmFtZSBpbiBzcGVjLnBhcmFtZXRlcnMpIHtcbiAgICB2YXIgcGFyYW1ldGVyID0gc3BlYy5wYXJhbWV0ZXJzW25hbWVdO1xuICAgIGlmIChwYXJhbWV0ZXIuaW4gPT09ICdib2R5JyAmJiBwYXJhbWV0ZXIuc2NoZW1hKSB7XG4gICAgICBpZihfLmlzQXJyYXkocGFyYW1ldGVyLnNjaGVtYS5hbGxPZikpIHtcbiAgICAgICAgLy8gbW92ZSB0byBhIGRlZmluaXRpb25cbiAgICAgICAgdmFyIG1vZGVsTmFtZSA9ICdpbmxpbmVfbW9kZWwnO1xuICAgICAgICB2YXIgbmFtZSA9IG1vZGVsTmFtZTtcbiAgICAgICAgdmFyIGRvbmUgPSBmYWxzZTsgdmFyIGNvdW50ZXIgPSAwO1xuICAgICAgICB3aGlsZSghZG9uZSkge1xuICAgICAgICAgIGlmKHR5cGVvZiBzcGVjLmRlZmluaXRpb25zW25hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgbmFtZSA9IG1vZGVsTmFtZSArICdfJyArIGNvdW50ZXI7XG4gICAgICAgICAgY291bnRlciArKztcbiAgICAgICAgfVxuICAgICAgICBzcGVjLmRlZmluaXRpb25zW25hbWVdID0geyBhbGxPZjogcGFyYW1ldGVyLnNjaGVtYS5hbGxPZiB9O1xuICAgICAgICBkZWxldGUgcGFyYW1ldGVyLnNjaGVtYS5hbGxPZjtcbiAgICAgICAgcGFyYW1ldGVyLnNjaGVtYS4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIG5hbWU7XG4gICAgICAgIHRoaXMucHJvY2Vzc0FsbE9mKHJvb3QsIG5hbWUsIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHNwZWMpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHBhcmFtZXRlci5zY2hlbWEsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwYXJhbWV0ZXIuJHJlZikge1xuICAgICAgLy8gcGFyYW1ldGVyIHJlZmVyZW5jZVxuICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHBhcmFtZXRlciwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgcGFyYW1ldGVyLiRyZWYpO1xuICAgIH1cbiAgfVxuXG4gIC8vIG9wZXJhdGlvbnNcbiAgZm9yIChuYW1lIGluIHNwZWMucGF0aHMpIHtcbiAgICB2YXIgbWV0aG9kLCBvcGVyYXRpb24sIHJlc3BvbnNlQ29kZTtcbiAgICBwYXRoID0gc3BlYy5wYXRoc1tuYW1lXTtcblxuICAgIGZvciAobWV0aG9kIGluIHBhdGgpIHtcbiAgICAgIC8vIG9wZXJhdGlvbiByZWZlcmVuY2VcbiAgICAgIGlmKG1ldGhvZCA9PT0gJyRyZWYnKSB7XG4gICAgICAgIC8vIGxvY2F0aW9uID0gcGF0aFttZXRob2RdO1xuICAgICAgICBsb2NhdGlvbiA9ICcvcGF0aHMnICsgbmFtZTtcbiAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHBhdGgsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGxvY2F0aW9uKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBvcGVyYXRpb24gPSBwYXRoW21ldGhvZF07XG4gICAgICAgIHZhciBzaGFyZWRQYXJhbWV0ZXJzID0gcGF0aC5wYXJhbWV0ZXJzIHx8IFtdO1xuICAgICAgICB2YXIgcGFyYW1ldGVycyA9IG9wZXJhdGlvbi5wYXJhbWV0ZXJzIHx8IFtdO1xuXG4gICAgICAgIGZvciAoaSBpbiBzaGFyZWRQYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgdmFyIHBhcmFtZXRlciA9IHNoYXJlZFBhcmFtZXRlcnNbaV07XG4gICAgICAgICAgcGFyYW1ldGVycy51bnNoaWZ0KHBhcmFtZXRlcik7XG4gICAgICAgIH1cbiAgICAgICAgaWYobWV0aG9kICE9PSAncGFyYW1ldGVycycgJiYgXy5pc09iamVjdChvcGVyYXRpb24pKSB7XG4gICAgICAgICAgb3BlcmF0aW9uLnBhcmFtZXRlcnMgPSBvcGVyYXRpb24ucGFyYW1ldGVycyB8fCBwYXJhbWV0ZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChpIGluIHBhcmFtZXRlcnMpIHtcbiAgICAgICAgICB2YXIgcGFyYW1ldGVyID0gcGFyYW1ldGVyc1tpXTtcbiAgICAgICAgICBsb2NhdGlvbiA9ICcvcGF0aHMnICsgbmFtZSArICcvJyArIG1ldGhvZCArICcvcGFyYW1ldGVycyc7XG5cbiAgICAgICAgICBpZiAocGFyYW1ldGVyLmluID09PSAnYm9keScgJiYgcGFyYW1ldGVyLnNjaGVtYSkge1xuICAgICAgICAgICAgaWYoXy5pc0FycmF5KHBhcmFtZXRlci5zY2hlbWEuYWxsT2YpKSB7XG4gICAgICAgICAgICAgIC8vIG1vdmUgdG8gYSBkZWZpbml0aW9uXG4gICAgICAgICAgICAgIHZhciBtb2RlbE5hbWUgPSAnaW5saW5lX21vZGVsJztcbiAgICAgICAgICAgICAgdmFyIG5hbWUgPSBtb2RlbE5hbWU7XG4gICAgICAgICAgICAgIHZhciBkb25lID0gZmFsc2U7IHZhciBjb3VudGVyID0gMDtcbiAgICAgICAgICAgICAgd2hpbGUoIWRvbmUpIHtcbiAgICAgICAgICAgICAgICBpZih0eXBlb2Ygc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5hbWUgPSBtb2RlbE5hbWUgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICAgICAgICAgIGNvdW50ZXIgKys7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9IHsgYWxsT2Y6IHBhcmFtZXRlci5zY2hlbWEuYWxsT2YgfTtcbiAgICAgICAgICAgICAgZGVsZXRlIHBhcmFtZXRlci5zY2hlbWEuYWxsT2Y7XG4gICAgICAgICAgICAgIHBhcmFtZXRlci5zY2hlbWEuJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyBuYW1lO1xuICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBzcGVjLmRlZmluaXRpb25zW25hbWVdLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLnJlc29sdmVUbyhyb290LCBwYXJhbWV0ZXIuc2NoZW1hLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocGFyYW1ldGVyLiRyZWYpIHtcbiAgICAgICAgICAgIC8vIHBhcmFtZXRlciByZWZlcmVuY2VcbiAgICAgICAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwYXJhbWV0ZXIsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHBhcmFtZXRlci4kcmVmKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHJlc3BvbnNlQ29kZSBpbiBvcGVyYXRpb24ucmVzcG9uc2VzKSB7XG4gICAgICAgICAgdmFyIHJlc3BvbnNlID0gb3BlcmF0aW9uLnJlc3BvbnNlc1tyZXNwb25zZUNvZGVdO1xuICAgICAgICAgIGxvY2F0aW9uID0gJy9wYXRocycgKyBuYW1lICsgJy8nICsgbWV0aG9kICsgJy9yZXNwb25zZXMvJyArIHJlc3BvbnNlQ29kZTtcblxuICAgICAgICAgIGlmKF8uaXNPYmplY3QocmVzcG9uc2UpKSB7XG4gICAgICAgICAgICBpZihyZXNwb25zZS4kcmVmKSB7XG4gICAgICAgICAgICAgIC8vIHJlc3BvbnNlIHJlZmVyZW5jZVxuICAgICAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcmVzcG9uc2UsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGxvY2F0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5zY2hlbWEpIHtcbiAgICAgICAgICAgICAgdmFyIHJlc3BvbnNlT2JqID0gcmVzcG9uc2U7XG4gICAgICAgICAgICAgIGlmKF8uaXNBcnJheShyZXNwb25zZU9iai5zY2hlbWEuYWxsT2YpKSB7XG4gICAgICAgICAgICAgICAgLy8gbW92ZSB0byBhIGRlZmluaXRpb25cbiAgICAgICAgICAgICAgICB2YXIgbW9kZWxOYW1lID0gJ2lubGluZV9tb2RlbCc7XG4gICAgICAgICAgICAgICAgdmFyIG5hbWUgPSBtb2RlbE5hbWU7XG4gICAgICAgICAgICAgICAgdmFyIGRvbmUgPSBmYWxzZTsgdmFyIGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgICAgIHdoaWxlKCFkb25lKSB7XG4gICAgICAgICAgICAgICAgICBpZih0eXBlb2Ygc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgbmFtZSA9IG1vZGVsTmFtZSArICdfJyArIGNvdW50ZXI7XG4gICAgICAgICAgICAgICAgICBjb3VudGVyICsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzcGVjLmRlZmluaXRpb25zW25hbWVdID0geyBhbGxPZjogcmVzcG9uc2VPYmouc2NoZW1hLmFsbE9mIH07XG4gICAgICAgICAgICAgICAgZGVsZXRlIHJlc3BvbnNlT2JqLnNjaGVtYS5hbGxPZjtcbiAgICAgICAgICAgICAgICBkZWxldGUgcmVzcG9uc2VPYmouc2NoZW1hLnR5cGU7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2VPYmouc2NoZW1hLiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgbmFtZTtcbiAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBzcGVjLmRlZmluaXRpb25zW25hbWVdLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIGlmKCdhcnJheScgPT09IHJlc3BvbnNlT2JqLnNjaGVtYS50eXBlKSB7XG4gICAgICAgICAgICAgICAgaWYocmVzcG9uc2VPYmouc2NoZW1hLml0ZW1zICYmIHJlc3BvbnNlT2JqLnNjaGVtYS5pdGVtcy4kcmVmKSB7XG4gICAgICAgICAgICAgICAgICAvLyByZXNwb25zZSByZWZlcmVuY2VcbiAgICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCByZXNwb25zZU9iai5zY2hlbWEuaXRlbXMsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIGxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcmVzcG9uc2Uuc2NoZW1hLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBjbGVhciB0aGVtIG91dCB0byBhdm9pZCBtdWx0aXBsZSByZXNvbHV0aW9uc1xuICAgIHBhdGgucGFyYW1ldGVycyA9IFtdO1xuICB9XG5cbiAgdmFyIGV4cGVjdGVkQ2FsbHMgPSAwLCB0b1Jlc29sdmUgPSBbXTtcbiAgLy8gaWYgdGhlIHJvb3QgaXMgc2FtZSBhcyBvYmpbaV0ucm9vdCB3ZSBjYW4gcmVzb2x2ZSBsb2NhbGx5XG4gIHZhciBhbGwgPSByZXNvbHV0aW9uVGFibGU7XG5cbiAgdmFyIHBhcnRzO1xuICBmb3IoaSA9IDA7IGkgPCBhbGwubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYSA9IGFsbFtpXTtcbiAgICBpZihyb290ID09PSBhLnJvb3QpIHtcbiAgICAgIGlmKGEucmVzb2x2ZUFzID09PSAncmVmJykge1xuICAgICAgICAvLyByZXNvbHZlIGFueSBwYXRoIHdhbGtpbmdcbiAgICAgICAgdmFyIGpvaW5lZCA9ICgoYS5yb290IHx8ICcnKSArICcvJyArIGEua2V5KS5zcGxpdCgnLycpO1xuICAgICAgICB2YXIgbm9ybWFsaXplZCA9IFtdO1xuICAgICAgICB2YXIgdXJsID0gJyc7XG4gICAgICAgIHZhciBrO1xuXG4gICAgICAgIGlmKGEua2V5LmluZGV4T2YoJy4uLycpID49IDApIHtcbiAgICAgICAgICBmb3IodmFyIGogPSAwOyBqIDwgam9pbmVkLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBpZihqb2luZWRbal0gPT09ICcuLicpIHtcbiAgICAgICAgICAgICAgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZWQuc2xpY2UoMCwgbm9ybWFsaXplZC5sZW5ndGgtMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgbm9ybWFsaXplZC5wdXNoKGpvaW5lZFtqXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGZvcihrID0gMDsgayA8IG5vcm1hbGl6ZWQubGVuZ3RoOyBrICsrKSB7XG4gICAgICAgICAgICBpZihrID4gMCkge1xuICAgICAgICAgICAgICB1cmwgKz0gJy8nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXJsICs9IG5vcm1hbGl6ZWRba107XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHdlIG5vdyBoYXZlIHRvIHJlbW90ZSByZXNvbHZlIHRoaXMgYmVjYXVzZSB0aGUgcGF0aCBoYXMgY2hhbmdlZFxuICAgICAgICAgIGEucm9vdCA9IHVybDtcbiAgICAgICAgICB0b1Jlc29sdmUucHVzaChhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBwYXJ0cyA9IGEua2V5LnNwbGl0KCcjJyk7XG4gICAgICAgICAgaWYocGFydHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBpZihwYXJ0c1swXS5pbmRleE9mKCdodHRwOicpID09PSAwIHx8IHBhcnRzWzBdLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgICAgICAgICAgIGEucm9vdCA9IHBhcnRzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24gPSBwYXJ0c1sxXS5zcGxpdCgnLycpO1xuICAgICAgICAgICAgdmFyIHI7XG4gICAgICAgICAgICB2YXIgcyA9IHNwZWM7XG4gICAgICAgICAgICBmb3IoayA9IDA7IGsgPCBsb2NhdGlvbi5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgICB2YXIgcGFydCA9IGxvY2F0aW9uW2tdO1xuICAgICAgICAgICAgICBpZihwYXJ0ICE9PSAnJykge1xuICAgICAgICAgICAgICAgIHMgPSBzW3BhcnRdO1xuICAgICAgICAgICAgICAgIGlmKHR5cGVvZiBzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgciA9IHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgciA9IG51bGw7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmKHIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gbXVzdCByZXNvbHZlIHRoaXMgdG9vXG4gICAgICAgICAgICAgIHRvUmVzb2x2ZS5wdXNoKGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGlmIChhLnJlc29sdmVBcyA9PT0gJ2lubGluZScpIHtcbiAgICAgICAgICBpZihhLmtleSAmJiBhLmtleS5pbmRleE9mKCcjJykgPT09IC0xICYmIGEua2V5LmNoYXJBdCgwKSAhPT0gJy8nKSB7XG4gICAgICAgICAgICAvLyBoYW5kbGUgcmVsYXRpdmUgc2NoZW1hXG4gICAgICAgICAgICBwYXJ0cyA9IGEucm9vdC5zcGxpdCgnLycpO1xuICAgICAgICAgICAgbG9jYXRpb24gPSAnJztcbiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IHBhcnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgICAgICBsb2NhdGlvbiArPSBwYXJ0c1tpXSArICcvJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvY2F0aW9uICs9IGEua2V5O1xuICAgICAgICAgICAgYS5yb290ID0gbG9jYXRpb247XG4gICAgICAgICAgICBhLmxvY2F0aW9uID0gJyc7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRvUmVzb2x2ZS5wdXNoKGEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgfVxuICB9XG4gIGV4cGVjdGVkQ2FsbHMgPSB0b1Jlc29sdmUubGVuZ3RoO1xuXG4gIC8vIHJlc29sdmUgYW55dGhpbmcgdGhhdCBpcyBsb2NhbFxuICBmb3IodmFyIGlpID0gMDsgaWkgPCB0b1Jlc29sdmUubGVuZ3RoOyBpaSsrKSB7XG4gICAgKGZ1bmN0aW9uKGl0ZW0sIHNwZWMsIHNlbGYpIHtcbiAgICAgIC8vIE5PVEU6IHRoaXMgdXNlZCB0byBiZSBpdGVtLnJvb3QgPT09IG51bGwsIGJ1dCBJIChAcG9uZWxhdCkgaGF2ZSBhZGRlZCBhIGd1YXJkIGFnYWluc3QgLnNwbGl0LCB3aGljaCBtZWFucyBpdGVtLnJvb3QgY2FuIGJlICcnXG4gICAgICBpZighaXRlbS5yb290IHx8IGl0ZW0ucm9vdCA9PT0gcm9vdCkge1xuICAgICAgICAvLyBsb2NhbCByZXNvbHZlXG4gICAgICAgIHNlbGYucmVzb2x2ZUl0ZW0oc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSk7XG4gICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG5cbiAgICAgICAgaWYocHJvY2Vzc2VkQ2FsbHMgPT09IGV4cGVjdGVkQ2FsbHMpIHtcbiAgICAgICAgICBzZWxmLmZpbmlzaChzcGVjLCByb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSBpZihzZWxmLmZhaWxlZFVybHMuaW5kZXhPZihpdGVtLnJvb3QpID09PSAtMSkge1xuICAgICAgICB2YXIgb2JqID0ge1xuICAgICAgICAgIHVzZUpRdWVyeTogZmFsc2UsICAvLyBUT0RPXG4gICAgICAgICAgdXJsOiBpdGVtLnJvb3QsXG4gICAgICAgICAgbWV0aG9kOiAnZ2V0JyxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICBhY2NlcHQ6IHNlbGYuc2NvcGUuc3dhZ2dlclJlcXVlc3RIZWFkZXJzIHx8ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICAgIH0sXG4gICAgICAgICAgb246IHtcbiAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgcHJvY2Vzc2VkQ2FsbHMgKz0gMTtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2ZhaWxlZCB1cmw6ICcgKyBvYmoudXJsKTtcbiAgICAgICAgICAgICAgc2VsZi5mYWlsZWRVcmxzLnB1c2gob2JqLnVybCk7XG4gICAgICAgICAgICAgIHVucmVzb2x2ZWRSZWZzW2l0ZW0ua2V5XSA9IHtcbiAgICAgICAgICAgICAgICByb290OiBpdGVtLnJvb3QsXG4gICAgICAgICAgICAgICAgbG9jYXRpb246IGl0ZW0ubG9jYXRpb25cbiAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICBpZiAocHJvY2Vzc2VkQ2FsbHMgPT09IGV4cGVjdGVkQ2FsbHMpIHtcbiAgICAgICAgICAgICAgICBzZWxmLmZpbmlzaChzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICAgICAgICAgIHJlc3BvbnNlOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgdmFyIHN3YWdnZXIgPSByZXNwb25zZS5vYmo7XG4gICAgICAgICAgICAgIHNlbGYucmVzb2x2ZUl0ZW0oc3dhZ2dlciwgaXRlbS5yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGl0ZW0pO1xuICAgICAgICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuXG4gICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHNjb3BlICYmIHNjb3BlLmNsaWVudEF1dGhvcml6YXRpb25zKSB7XG4gICAgICAgICAgc2NvcGUuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkob2JqKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUob2JqLCBvcHRzKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuICAgICAgICB1bnJlc29sdmVkUmVmc1tpdGVtLmtleV0gPSB7XG4gICAgICAgICAgcm9vdDogaXRlbS5yb290LFxuICAgICAgICAgIGxvY2F0aW9uOiBpdGVtLmxvY2F0aW9uXG4gICAgICAgIH07XG4gICAgICAgIGlmIChwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0odG9SZXNvbHZlW2lpXSwgc3BlYywgdGhpcykpO1xuICB9XG5cbiAgaWYgKE9iamVjdC5rZXlzKHRvUmVzb2x2ZSkubGVuZ3RoID09PSAwKSB7XG4gICAgdGhpcy5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZUl0ZW0gPSBmdW5jdGlvbihzcGVjLCByb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGl0ZW0pIHtcbiAgdmFyIHBhdGggPSBpdGVtLmxvY2F0aW9uO1xuICB2YXIgbG9jYXRpb24gPSBzcGVjLCBwYXJ0cyA9IHBhdGguc3BsaXQoJy8nKTtcbiAgaWYocGF0aCAhPT0gJycpIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHBhcnRzLmxlbmd0aDsgaisrKSB7XG4gICAgICB2YXIgc2VnbWVudCA9IHBhcnRzW2pdO1xuICAgICAgaWYgKHNlZ21lbnQuaW5kZXhPZignfjEnKSAhPT0gLTEpIHtcbiAgICAgICAgc2VnbWVudCA9IHBhcnRzW2pdLnJlcGxhY2UoL34wL2csICd+JykucmVwbGFjZSgvfjEvZywgJy8nKTtcbiAgICAgICAgaWYgKHNlZ21lbnQuY2hhckF0KDApICE9PSAnLycpIHtcbiAgICAgICAgICBzZWdtZW50ID0gJy8nICsgc2VnbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBsb2NhdGlvbiA9PT0gJ3VuZGVmaW5lZCcgfHwgbG9jYXRpb24gPT09IG51bGwpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoc2VnbWVudCA9PT0gJycgJiYgaiA9PT0gKHBhcnRzLmxlbmd0aCAtIDEpICYmIHBhcnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgbG9jYXRpb24gPSBudWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzZWdtZW50Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgbG9jYXRpb24gPSBsb2NhdGlvbltzZWdtZW50XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIHJlc29sdmVkID0gaXRlbS5rZXk7XG4gIHBhcnRzID0gaXRlbS5rZXkuc3BsaXQoJy8nKTtcbiAgdmFyIHJlc29sdmVkTmFtZSA9IHBhcnRzW3BhcnRzLmxlbmd0aC0xXTtcblxuICBpZihyZXNvbHZlZE5hbWUuaW5kZXhPZignIycpID49IDApIHtcbiAgICByZXNvbHZlZE5hbWUgPSByZXNvbHZlZE5hbWUuc3BsaXQoJyMnKVsxXTtcbiAgfVxuXG4gIGlmIChsb2NhdGlvbiAhPT0gbnVsbCAmJiB0eXBlb2YgbG9jYXRpb24gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmVzb2x2ZWRSZWZzW3Jlc29sdmVkXSA9IHtcbiAgICAgIG5hbWU6IHJlc29sdmVkTmFtZSxcbiAgICAgIG9iajogbG9jYXRpb24sXG4gICAgICBrZXk6IGl0ZW0ua2V5LFxuICAgICAgcm9vdDogaXRlbS5yb290XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB1bnJlc29sdmVkUmVmc1tyZXNvbHZlZF0gPSB7XG4gICAgICByb290OiBpdGVtLnJvb3QsXG4gICAgICBsb2NhdGlvbjogaXRlbS5sb2NhdGlvblxuICAgIH07XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbiAoc3BlYywgcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjaywgbG9jYWxSZXNvbHZlKSB7XG4gIC8vIHdhbGsgcmVzb2x1dGlvbiB0YWJsZSBhbmQgcmVwbGFjZSB3aXRoIHJlc29sdmVkIHJlZnNcbiAgdmFyIHJlZjtcbiAgZm9yIChyZWYgaW4gcmVzb2x1dGlvblRhYmxlKSB7XG4gICAgdmFyIGl0ZW0gPSByZXNvbHV0aW9uVGFibGVbcmVmXTtcblxuICAgIHZhciBrZXkgPSBpdGVtLmtleTtcbiAgICB2YXIgcmVzb2x2ZWRUbyA9IHJlc29sdmVkUmVmc1trZXldO1xuICAgIGlmIChyZXNvbHZlZFRvKSB7XG4gICAgICBzcGVjLmRlZmluaXRpb25zID0gc3BlYy5kZWZpbml0aW9ucyB8fCB7fTtcbiAgICAgIGlmIChpdGVtLnJlc29sdmVBcyA9PT0gJ3JlZicpIHtcbiAgICAgICAgaWYgKGxvY2FsUmVzb2x2ZSAhPT0gdHJ1ZSkge1xuICAgICAgICAgIC8vIGRvbid0IHJldGFpbiByb290IGZvciBsb2NhbCBkZWZpbml0aW9uc1xuICAgICAgICAgIGZvciAoa2V5IGluIHJlc29sdmVkVG8ub2JqKSB7XG4gICAgICAgICAgICB2YXIgYWJzID0gdGhpcy5yZXRhaW5Sb290KGtleSwgcmVzb2x2ZWRUby5vYmpba2V5XSwgaXRlbS5yb290KTtcbiAgICAgICAgICAgIHJlc29sdmVkVG8ub2JqW2tleV0gPSBhYnM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHNwZWMuZGVmaW5pdGlvbnNbcmVzb2x2ZWRUby5uYW1lXSA9IHJlc29sdmVkVG8ub2JqO1xuICAgICAgICBpdGVtLm9iai4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIHJlc29sdmVkVG8ubmFtZTtcbiAgICAgIH0gZWxzZSBpZiAoaXRlbS5yZXNvbHZlQXMgPT09ICdpbmxpbmUnKSB7XG4gICAgICAgIHZhciB0YXJnZXRPYmogPSBpdGVtLm9iajtcbiAgICAgICAgdGFyZ2V0T2JqWyd4LXJlc29sdmVkLWZyb20nXSA9IFsgaXRlbS5rZXkgXTtcbiAgICAgICAgZGVsZXRlIHRhcmdldE9iai4kcmVmO1xuXG4gICAgICAgIGZvciAoa2V5IGluIHJlc29sdmVkVG8ub2JqKSB7XG4gICAgICAgICAgdmFyIGFicyA9IHJlc29sdmVkVG8ub2JqW2tleV07XG4gICAgICAgICAgXG4gICAgICAgICAgaWYgKGxvY2FsUmVzb2x2ZSAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgLy8gZG9uJ3QgcmV0YWluIHJvb3QgZm9yIGxvY2FsIGRlZmluaXRpb25zXG4gICAgICAgICAgICBhYnMgPSB0aGlzLnJldGFpblJvb3Qoa2V5LCByZXNvbHZlZFRvLm9ialtrZXldLCBpdGVtLnJvb3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0YXJnZXRPYmpba2V5XSA9IGFicztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICB2YXIgZXhpc3RpbmdVbnJlc29sdmVkID0gdGhpcy5jb3VudFVucmVzb2x2ZWRSZWZzKHNwZWMpO1xuXG4gIGlmKGV4aXN0aW5nVW5yZXNvbHZlZCA9PT0gMCB8fCB0aGlzLml0ZXJhdGlvbiA+IDUpIHtcbiAgICB0aGlzLnJlc29sdmVBbGxPZihzcGVjLmRlZmluaXRpb25zKTtcbiAgICBjYWxsYmFjay5jYWxsKHRoaXMuc2NvcGUsIHNwZWMsIHVucmVzb2x2ZWRSZWZzKTtcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLml0ZXJhdGlvbiArPSAxO1xuICAgIHRoaXMucmVzb2x2ZShzcGVjLCByb290LCBjYWxsYmFjaywgdGhpcy5zY29wZSk7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5jb3VudFVucmVzb2x2ZWRSZWZzID0gZnVuY3Rpb24oc3BlYykge1xuICB2YXIgaTtcbiAgdmFyIHJlZnMgPSB0aGlzLmdldFJlZnMoc3BlYyk7XG4gIHZhciBrZXlzID0gW107XG4gIHZhciB1bnJlc29sdmVkS2V5cyA9IFtdO1xuICBmb3IoaSBpbiByZWZzKSB7XG4gICAgaWYoaS5pbmRleE9mKCcjJykgPT09IDApIHtcbiAgICAgIGtleXMucHVzaChpLnN1YnN0cmluZygxKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdW5yZXNvbHZlZEtleXMucHVzaChpKTtcbiAgICB9XG4gIH1cblxuICAvLyB2ZXJpZnkgcG9zc2libGUga2V5c1xuICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJ0ID0ga2V5c1tpXTtcbiAgICB2YXIgcGFydHMgPSBwYXJ0LnNwbGl0KCcvJyk7XG4gICAgdmFyIG9iaiA9IHNwZWM7XG5cbiAgICBmb3IgKHZhciBrID0gMDsgayA8IHBhcnRzLmxlbmd0aDsgaysrKSB7XG4gICAgICB2YXIga2V5ID0gcGFydHNba107XG4gICAgICBpZihrZXkgIT09ICcnKSB7XG4gICAgICAgIG9iaiA9IG9ialtrZXldO1xuICAgICAgICBpZih0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHVucmVzb2x2ZWRLZXlzLnB1c2gocGFydCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVucmVzb2x2ZWRLZXlzLmxlbmd0aDtcbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5nZXRSZWZzID0gZnVuY3Rpb24oc3BlYywgb2JqKSB7XG4gIG9iaiA9IG9iaiB8fCBzcGVjO1xuICB2YXIgb3V0cHV0ID0ge307XG4gIGZvcih2YXIga2V5IGluIG9iaikge1xuICAgIGlmICghb2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgaXRlbSA9IG9ialtrZXldO1xuICAgIGlmKGtleSA9PT0gJyRyZWYnICYmIHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgb3V0cHV0W2l0ZW1dID0gbnVsbDtcbiAgICB9XG4gICAgZWxzZSBpZihfLmlzT2JqZWN0KGl0ZW0pKSB7XG4gICAgICB2YXIgbyA9IHRoaXMuZ2V0UmVmcyhpdGVtKTtcbiAgICAgIGZvcih2YXIgayBpbiBvKSB7XG4gICAgICAgIG91dHB1dFtrXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmV0YWluUm9vdCA9IGZ1bmN0aW9uKG9yaWdLZXksIG9iaiwgcm9vdCkge1xuICAvLyB3YWxrIG9iamVjdCBhbmQgbG9vayBmb3IgcmVsYXRpdmUgJHJlZnNcbiAgaWYoXy5pc09iamVjdChvYmopKSB7XG4gICAgZm9yKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICB2YXIgaXRlbSA9IG9ialtrZXldO1xuICAgICAgaWYgKGtleSA9PT0gJyRyZWYnICYmIHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgICAvLyBzdG9wIGFuZCBpbnNwZWN0XG4gICAgICAgIGlmIChpdGVtLmluZGV4T2YoJ2h0dHA6JykgIT09IDAgJiYgaXRlbS5pbmRleE9mKCdodHRwczonKSAhPT0gMCkge1xuICAgICAgICAgIC8vIFRPRE86IGNoZWNrIGlmIHJvb3QgZW5kcyBpbiAnLycuICBJZiBub3QsIEFORCBpdGVtIGhhcyBubyBwcm90b2NvbCwgbWFrZSByZWxhdGl2ZVxuICAgICAgICAgIHZhciBhcHBlbmRIYXNoID0gdHJ1ZTtcbiAgICAgICAgICB2YXIgb2xkUm9vdCA9IHJvb3Q7XG4gICAgICAgICAgaWYgKHJvb3QpIHtcbiAgICAgICAgICAgIHZhciBsYXN0Q2hhciA9IHJvb3Quc2xpY2UoLTEpO1xuICAgICAgICAgICAgaWYgKGxhc3RDaGFyICE9PSAnLycgJiYgKGl0ZW0uaW5kZXhPZignIycpICE9PSAwICYmIGl0ZW0uaW5kZXhPZignaHR0cDonKSAhPT0gMCAmJiBpdGVtLmluZGV4T2YoJ2h0dHBzOicpKSkge1xuICAgICAgICAgICAgICBhcHBlbmRIYXNoID0gZmFsc2U7XG4gICAgICAgICAgICAgIHZhciBwYXJ0cyA9IHJvb3Quc3BsaXQoJ1xcLycpO1xuICAgICAgICAgICAgICBwYXJ0cyA9IHBhcnRzLnNwbGljZSgwLCBwYXJ0cy5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgICAgcm9vdCA9ICcnO1xuICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcm9vdCArPSBwYXJ0c1tpXSArICcvJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaXRlbS5pbmRleE9mKCcjJykgIT09IDAgJiYgYXBwZW5kSGFzaCkge1xuICAgICAgICAgICAgaXRlbSA9ICcjJyArIGl0ZW07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaXRlbSA9IChyb290IHx8ICcnKSArIGl0ZW07XG4gICAgICAgICAgb2JqW2tleV0gPSBpdGVtO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChfLmlzT2JqZWN0KGl0ZW0pKSB7XG4gICAgICAgIHRoaXMucmV0YWluUm9vdChrZXksIGl0ZW0sIHJvb3QpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIGlmKF8uaXNTdHJpbmcob2JqKSAmJiBvcmlnS2V5ID09PSAnJHJlZicpIHtcbiAgICAvLyBsb29rIGF0IHRoZSByZWY/XG4gICAgaWYob2JqLmluZGV4T2YoJ2h0dHA6JykgPT09IC0xICYmIG9iai5pbmRleE9mKCdodHRwczonKSA9PT0gLTEpIHtcbiAgICAgIG9iaiA9IHJvb3QgKyBvYmo7XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59O1xuXG4vKipcbiAqIGltbWVkaWF0ZWx5IGluLWxpbmVzIGxvY2FsIHJlZnMsIHF1ZXVlcyByZW1vdGUgcmVmc1xuICogZm9yIGlubGluZSByZXNvbHV0aW9uXG4gKi9cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlSW5saW5lID0gZnVuY3Rpb24gKHJvb3QsIHNwZWMsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbikge1xuICB2YXIga2V5ID0gcHJvcGVydHkuJHJlZiwgcmVmID0gcHJvcGVydHkuJHJlZiwgaSwgcCwgcDIsIHJzO1xuICB2YXIgcm9vdFRyaW1tZWQgPSBmYWxzZTtcblxuICByb290ID0gcm9vdCB8fCAnJyAvLyBHdWFyZCBhZ2FpbnN0IC5zcGxpdC4gQGZlaGd1eSwgeW91J2xsIG5lZWQgdG8gY2hlY2sgaWYgdGhpcyBsb2dpYyBmaXRzXG4gIC8vIE1vcmUgaW1wb3JhbnRseSBpcyBob3cgZG8gd2UgZ3JhY2VmdWxseSBoYW5kbGUgcmVsYXRpdmUgdXJscywgd2hlbiBwcm92aWRlZCBqdXN0IGEgJ3NwZWMnLCBub3QgYSAndXJsJyA/XG5cbiAgaWYgKHJlZikge1xuICAgIGlmKHJlZi5pbmRleE9mKCcuLi8nKSA9PT0gMCkge1xuICAgICAgLy8gcmVzZXQgcm9vdFxuICAgICAgcCA9IHJlZi5zcGxpdCgnLi4vJyk7XG4gICAgICBwMiA9IHJvb3Quc3BsaXQoJy8nKTtcbiAgICAgIHJlZiA9ICcnO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZihwW2ldID09PSAnJykge1xuICAgICAgICAgIHAyID0gcDIuc2xpY2UoMCwgcDIubGVuZ3RoLTEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHJlZiArPSBwW2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByb290ID0gJyc7XG4gICAgICBmb3IoaSA9IDA7IGkgPCBwMi5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgaWYoaSA+IDApIHsgcm9vdCArPSAnLyc7IH1cbiAgICAgICAgcm9vdCArPSBwMltpXTtcbiAgICAgIH1cbiAgICAgIHJvb3RUcmltbWVkID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYocmVmLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgICBpZihyZWYuaW5kZXhPZignLycpID09PSAwKSB7XG4gICAgICAgIHJzID0gcmVmLnNwbGl0KCcjJyk7XG4gICAgICAgIHAgID0gcm9vdC5zcGxpdCgnLy8nKTtcbiAgICAgICAgcDIgPSBwWzFdLnNwbGl0KCcvJyk7XG4gICAgICAgIHJvb3QgPSBwWzBdICsgJy8vJyArIHAyWzBdICsgcnNbMF07XG4gICAgICAgIGxvY2F0aW9uID0gcnNbMV07XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcnMgPSByZWYuc3BsaXQoJyMnKTtcbiAgICAgICAgaWYocnNbMF0gIT09ICcnKSB7XG4gICAgICAgICAgcDIgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICAgICAgcDIgPSBwMi5zbGljZSgwLCBwMi5sZW5ndGggLSAxKTtcbiAgICAgICAgICBpZighcm9vdFRyaW1tZWQpIHtcbiAgICAgICAgICAgIHJvb3QgPSAnJztcbiAgICAgICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgcDIubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgICAgaWYoayA+IDApIHsgcm9vdCArPSAnLyc7IH1cbiAgICAgICAgICAgICAgcm9vdCArPSBwMltrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcm9vdCArPSAnLycgKyByZWYuc3BsaXQoJyMnKVswXTtcbiAgICAgICAgfVxuICAgICAgICBsb2NhdGlvbiA9IHJzWzFdO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocmVmLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcmVmLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgICBpZihyZWYuaW5kZXhPZignIycpID49IDApIHtcbiAgICAgICAgcm9vdCA9IHJlZi5zcGxpdCgnIycpWzBdO1xuICAgICAgICBsb2NhdGlvbiA9IHJlZi5zcGxpdCgnIycpWzFdO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHJvb3QgPSByZWY7XG4gICAgICAgIGxvY2F0aW9uID0gJyc7XG4gICAgICB9XG4gICAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7b2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAnaW5saW5lJywgcm9vdDogcm9vdCwga2V5OiBrZXksIGxvY2F0aW9uOiBsb2NhdGlvbn0pO1xuICAgIH0gZWxzZSBpZiAocmVmLmluZGV4T2YoJyMnKSA9PT0gMCkge1xuICAgICAgbG9jYXRpb24gPSByZWYuc3BsaXQoJyMnKVsxXTtcbiAgICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdpbmxpbmUnLCByb290OiByb290LCBrZXk6IGtleSwgbG9jYXRpb246IGxvY2F0aW9ufSk7XG4gICAgfSBlbHNlIGlmIChyZWYuaW5kZXhPZignLycpID09PSAwICYmIHJlZi5pbmRleE9mKCcjJykgPT09IC0xKSB7XG4gICAgICBsb2NhdGlvbiA9IHJlZjtcbiAgICAgIHZhciBtYXRjaGVzID0gcm9vdC5tYXRjaCgvXmh0dHBzP1xcOlxcL1xcLyhbXlxcLz8jXSspKD86W1xcLz8jXXwkKS9pKTtcbiAgICAgIGlmKG1hdGNoZXMpIHtcbiAgICAgICAgcm9vdCA9IG1hdGNoZXNbMF0gKyByZWYuc3Vic3RyaW5nKDEpO1xuICAgICAgICBsb2NhdGlvbiA9ICcnO1xuICAgICAgfVxuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7b2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAnaW5saW5lJywgcm9vdDogcm9vdCwga2V5OiBrZXksIGxvY2F0aW9uOiBsb2NhdGlvbn0pO1xuICAgIH1cbiAgfVxuICBlbHNlIGlmIChwcm9wZXJ0eS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcHJvcGVydHkuaXRlbXMsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZVRvID0gZnVuY3Rpb24gKHJvb3QsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKSB7XG4gIHZhciBzcCwgaTtcbiAgdmFyIHJlZiA9IHByb3BlcnR5LiRyZWY7XG4gIHZhciBscm9vdCA9IHJvb3Q7XG4gIGlmICgodHlwZW9mIHJlZiAhPT0gJ3VuZGVmaW5lZCcpICYmIChyZWYgIT09IG51bGwpKSB7XG4gICAgaWYocmVmLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgICB2YXIgcGFydHMgPSByZWYuc3BsaXQoJyMnKTtcblxuICAgICAgLy8gIy9kZWZpbml0aW9ucy9mb29cbiAgICAgIC8vIGZvby5qc29uIy9iYXJcbiAgICAgIGlmKHBhcnRzWzBdICYmIHJlZi5pbmRleE9mKCcvJykgPT09IDApIHtcblxuICAgICAgfVxuICAgICAgZWxzZSBpZihwYXJ0c1swXSAmJiAocGFydHNbMF0uaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCBwYXJ0c1swXS5pbmRleE9mKCdodHRwczonKSA9PT0gMCkpIHtcbiAgICAgICAgbHJvb3QgPSBwYXJ0c1swXTtcbiAgICAgICAgcmVmID0gcGFydHNbMV07XG4gICAgICB9XG4gICAgICBlbHNlIGlmKHBhcnRzWzBdICYmIHBhcnRzWzBdLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gcmVsYXRpdmUgZmlsZVxuICAgICAgICBzcCA9IHJvb3Quc3BsaXQoJy8nKTtcbiAgICAgICAgbHJvb3QgPSAnJztcbiAgICAgICAgZm9yKGkgPSAwOyBpIDwgc3AubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgbHJvb3QgKz0gc3BbaV0gKyAnLyc7XG4gICAgICAgIH1cbiAgICAgICAgbHJvb3QgKz0gcGFydHNbMF07XG4gICAgICB9XG4gICAgICBlbHNlIHtcblxuICAgICAgfVxuXG4gICAgICBsb2NhdGlvbiA9IHBhcnRzWzFdO1xuICAgIH1cbiAgICBlbHNlIGlmIChyZWYuaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCByZWYuaW5kZXhPZignaHR0cHM6JykgPT09IDApIHtcbiAgICAgIGxyb290ID0gcmVmO1xuICAgICAgbG9jYXRpb24gPSAnJztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAvLyByZWxhdGl2ZSBmaWxlXG4gICAgICBzcCA9IHJvb3Quc3BsaXQoJy8nKTtcbiAgICAgIGxyb290ID0gJyc7XG4gICAgICBmb3IoaSA9IDA7IGkgPCBzcC5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgbHJvb3QgKz0gc3BbaV0gKyAnLyc7XG4gICAgICB9XG4gICAgICBscm9vdCArPSByZWY7XG4gICAgICBsb2NhdGlvbiA9ICcnO1xuICAgIH1cbiAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7XG4gICAgICBvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdyZWYnLCByb290OiBscm9vdCwga2V5OiByZWYsIGxvY2F0aW9uOiBsb2NhdGlvblxuICAgIH0pO1xuICB9IGVsc2UgaWYgKHByb3BlcnR5LnR5cGUgPT09ICdhcnJheScpIHtcbiAgICB2YXIgaXRlbXMgPSBwcm9wZXJ0eS5pdGVtcztcbiAgICB0aGlzLnJlc29sdmVUbyhyb290LCBpdGVtcywgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgaWYocHJvcGVydHkgJiYgcHJvcGVydHkucHJvcGVydGllcykge1xuICAgICAgdmFyIG5hbWUgPSB0aGlzLnVuaXF1ZU5hbWUoJ2lubGluZV9tb2RlbCcpO1xuICAgICAgaWYgKHByb3BlcnR5LnRpdGxlKSB7XG4gICAgICAgIG5hbWUgPSB0aGlzLnVuaXF1ZU5hbWUocHJvcGVydHkudGl0bGUpO1xuICAgICAgfVxuICAgICAgZGVsZXRlIHByb3BlcnR5LnRpdGxlO1xuICAgICAgdGhpcy5zcGVjLmRlZmluaXRpb25zW25hbWVdID0gXy5jbG9uZURlZXAocHJvcGVydHkpO1xuICAgICAgcHJvcGVydHlbJyRyZWYnXSA9ICcjL2RlZmluaXRpb25zLycgKyBuYW1lO1xuICAgICAgZGVsZXRlIHByb3BlcnR5LnR5cGU7XG4gICAgICBkZWxldGUgcHJvcGVydHkucHJvcGVydGllcztcbiAgICB9XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS51bmlxdWVOYW1lID0gZnVuY3Rpb24oYmFzZSkge1xuICB2YXIgbmFtZSA9IGJhc2U7XG4gIHZhciBjb3VudCA9IDA7XG4gIHdoaWxlKHRydWUpIHtcbiAgICBpZighXy5pc09iamVjdCh0aGlzLnNwZWMuZGVmaW5pdGlvbnNbbmFtZV0pKSB7XG4gICAgICByZXR1cm4gbmFtZTtcbiAgICB9XG4gICAgbmFtZSA9IGJhc2UgKyAnXycgKyBjb3VudDtcbiAgICBjb3VudCsrO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZUFsbE9mID0gZnVuY3Rpb24oc3BlYywgb2JqLCBkZXB0aCkge1xuICBkZXB0aCA9IGRlcHRoIHx8IDA7XG4gIG9iaiA9IG9iaiB8fCBzcGVjO1xuICB2YXIgbmFtZTtcbiAgZm9yKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKCFvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHZhciBpdGVtID0gb2JqW2tleV07XG4gICAgaWYoaXRlbSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignU3dhZ2dlciAyLjAgZG9lcyBub3Qgc3VwcG9ydCBudWxsIHR5cGVzICgnICsgb2JqICsgJykuICBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItc3BlYy9pc3N1ZXMvMjI5LicpO1xuICAgIH1cbiAgICBpZih0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHRoaXMucmVzb2x2ZUFsbE9mKHNwZWMsIGl0ZW0sIGRlcHRoICsgMSk7XG4gICAgfVxuICAgIGlmKGl0ZW0gJiYgdHlwZW9mIGl0ZW0uYWxsT2YgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgYWxsT2YgPSBpdGVtLmFsbE9mO1xuICAgICAgaWYoXy5pc0FycmF5KGFsbE9mKSkge1xuICAgICAgICB2YXIgb3V0cHV0ID0gXy5jbG9uZURlZXAoaXRlbSk7XG4gICAgICAgIGRlbGV0ZSBvdXRwdXQuYWxsT2Y7XG5cbiAgICAgICAgb3V0cHV0Wyd4LWNvbXBvc2VkJ10gPSB0cnVlO1xuICAgICAgICBpZiAodHlwZW9mIGl0ZW1bJ3gtcmVzb2x2ZWQtZnJvbSddICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIG91dHB1dFsneC1yZXNvbHZlZC1mcm9tJ10gPSBpdGVtWyd4LXJlc29sdmVkLWZyb20nXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhbGxPZi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBjb21wb25lbnQgPSBhbGxPZltpXTtcbiAgICAgICAgICB2YXIgc291cmNlID0gJ3NlbGYnO1xuICAgICAgICAgIGlmKHR5cGVvZiBjb21wb25lbnRbJ3gtcmVzb2x2ZWQtZnJvbSddICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgc291cmNlID0gY29tcG9uZW50Wyd4LXJlc29sdmVkLWZyb20nXVswXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IodmFyIHBhcnQgaW4gY29tcG9uZW50KSB7XG4gICAgICAgICAgICBpZighb3V0cHV0Lmhhc093blByb3BlcnR5KHBhcnQpKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtwYXJ0XSA9IF8uY2xvbmVEZWVwKGNvbXBvbmVudFtwYXJ0XSk7XG4gICAgICAgICAgICAgIGlmKHBhcnQgPT09ICdwcm9wZXJ0aWVzJykge1xuICAgICAgICAgICAgICAgIGZvcihuYW1lIGluIG91dHB1dFtwYXJ0XSkge1xuICAgICAgICAgICAgICAgICAgb3V0cHV0W3BhcnRdW25hbWVdWyd4LXJlc29sdmVkLWZyb20nXSA9IHNvdXJjZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBpZihwYXJ0ID09PSAncHJvcGVydGllcycpIHtcbiAgICAgICAgICAgICAgICB2YXIgcHJvcGVydGllcyA9IGNvbXBvbmVudFtwYXJ0XTtcbiAgICAgICAgICAgICAgICBmb3IobmFtZSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXQucHJvcGVydGllc1tuYW1lXSA9IF8uY2xvbmVEZWVwKHByb3BlcnRpZXNbbmFtZV0pO1xuICAgICAgICAgICAgICAgICAgdmFyIHJlc29sdmVkRnJvbSA9IHByb3BlcnRpZXNbbmFtZV1bJ3gtcmVzb2x2ZWQtZnJvbSddO1xuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiByZXNvbHZlZEZyb20gPT09ICd1bmRlZmluZWQnIHx8IHJlc29sdmVkRnJvbSA9PT0gJ3NlbGYnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmVkRnJvbSA9IHNvdXJjZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIG91dHB1dC5wcm9wZXJ0aWVzW25hbWVdWyd4LXJlc29sdmVkLWZyb20nXSA9IHJlc29sdmVkRnJvbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSBpZihwYXJ0ID09PSAncmVxdWlyZWQnKSB7XG4gICAgICAgICAgICAgICAgLy8gbWVyZ2UgJiBkZWR1cCB0aGUgcmVxdWlyZWQgYXJyYXlcbiAgICAgICAgICAgICAgICB2YXIgYSA9IG91dHB1dC5yZXF1aXJlZC5jb25jYXQoY29tcG9uZW50W3BhcnRdKTtcbiAgICAgICAgICAgICAgICBmb3IodmFyIGsgPSAwOyBrIDwgYS5sZW5ndGg7ICsraykge1xuICAgICAgICAgICAgICAgICAgZm9yKHZhciBqID0gayArIDE7IGogPCBhLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmKGFba10gPT09IGFbal0pIHsgYS5zcGxpY2Uoai0tLCAxKTsgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvdXRwdXQucmVxdWlyZWQgPSBhO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2UgaWYocGFydCA9PT0gJ3gtcmVzb2x2ZWQtZnJvbScpIHtcbiAgICAgICAgICAgICAgICBvdXRwdXRbJ3gtcmVzb2x2ZWQtZnJvbSddLnB1c2goc291cmNlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIG1lcmdlIHRoaXMgcHJvcGVydHlcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnd2hhdCB0byBkbyB3aXRoICcgKyBwYXJ0KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG9ialtrZXldID0gb3V0cHV0O1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcblxudmFyIF8gPSB7XG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGlzVW5kZWZpbmVkOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNVbmRlZmluZWQnKSxcbiAgaXNBcnJheTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXknKSxcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpLFxuICBpc0VtcHR5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eScpLFxuICBtYXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJyksXG4gIGNsb25lRGVlcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2Nsb25lRGVlcCcpLFxuICBrZXlzOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzJyksXG4gIGZvckVhY2g6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9mb3JFYWNoJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLm9wdGlvbkh0bWwgPSBvcHRpb25IdG1sO1xubW9kdWxlLmV4cG9ydHMudHlwZUZyb21Kc29uU2NoZW1hID0gdHlwZUZyb21Kc29uU2NoZW1hO1xubW9kdWxlLmV4cG9ydHMuZ2V0U3RyaW5nU2lnbmF0dXJlID0gZ2V0U3RyaW5nU2lnbmF0dXJlO1xubW9kdWxlLmV4cG9ydHMuc2NoZW1hVG9IVE1MID0gc2NoZW1hVG9IVE1MO1xubW9kdWxlLmV4cG9ydHMuc2NoZW1hVG9KU09OID0gc2NoZW1hVG9KU09OO1xuXG5mdW5jdGlvbiBvcHRpb25IdG1sKGxhYmVsLCB2YWx1ZSkge1xuICByZXR1cm4gJzx0cj48dGQgY2xhc3M9XCJvcHRpb25OYW1lXCI+JyArIGxhYmVsICsgJzo8L3RkPjx0ZD4nICsgdmFsdWUgKyAnPC90ZD48L3RyPic7XG59XG5cbmZ1bmN0aW9uIHR5cGVGcm9tSnNvblNjaGVtYSh0eXBlLCBmb3JtYXQpIHtcbiAgdmFyIHN0cjtcblxuICBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDMyJykge1xuICAgIHN0ciA9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50NjQnKSB7XG4gICAgc3RyID0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiB0eXBlb2YgZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciA9ICdsb25nJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgc3RyID0gJ2RhdGUtdGltZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICBzdHIgPSAnZGF0ZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSB7XG4gICAgc3RyID0gJ2Zsb2F0JztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdkb3VibGUnKSB7XG4gICAgc3RyID0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIGZvcm1hdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgPSAnYm9vbGVhbic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBzdHIgPSAnc3RyaW5nJztcbiAgfVxuXG4gIHJldHVybiBzdHI7XG59XG5cbmZ1bmN0aW9uIGdldFN0cmluZ1NpZ25hdHVyZShvYmosIGJhc2VDb21wb25lbnQpIHtcbiAgdmFyIHN0ciA9ICcnO1xuXG4gIGlmICh0eXBlb2Ygb2JqLiRyZWYgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9IEhlbHBlcnMuc2ltcGxlUmVmKG9iai4kcmVmKTtcbiAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqLnR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdvYmplY3QnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnYXJyYXknKSB7XG4gICAgaWYgKGJhc2VDb21wb25lbnQpIHtcbiAgICAgIHN0ciArPSBnZXRTdHJpbmdTaWduYXR1cmUoKG9iai5pdGVtcyB8fCBvYmouJHJlZiB8fCB7fSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJ0FycmF5Wyc7XG4gICAgICBzdHIgKz0gZ2V0U3RyaW5nU2lnbmF0dXJlKChvYmouaXRlbXMgfHwgb2JqLiRyZWYgfHwge30pKTtcbiAgICAgIHN0ciArPSAnXSc7XG4gICAgfVxuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnaW50ZWdlcicgJiYgb2JqLmZvcm1hdCA9PT0gJ2ludDMyJykge1xuICAgIHN0ciArPSAnaW50ZWdlcic7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdpbnRlZ2VyJyAmJiBvYmouZm9ybWF0ID09PSAnaW50NjQnKSB7XG4gICAgc3RyICs9ICdsb25nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2ludGVnZXInICYmIHR5cGVvZiBvYmouZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSAnbG9uZyc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIG9iai5mb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgc3RyICs9ICdkYXRlLXRpbWUnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnc3RyaW5nJyAmJiBvYmouZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICBzdHIgKz0gJ2RhdGUnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnc3RyaW5nJyAmJiB0eXBlb2Ygb2JqLmZvcm1hdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gJ3N0cmluZyc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdudW1iZXInICYmIG9iai5mb3JtYXQgPT09ICdmbG9hdCcpIHtcbiAgICBzdHIgKz0gJ2Zsb2F0JztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgb2JqLmZvcm1hdCA9PT0gJ2RvdWJsZScpIHtcbiAgICBzdHIgKz0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdudW1iZXInICYmIHR5cGVvZiBvYmouZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgc3RyICs9ICdib29sZWFuJztcbiAgfSBlbHNlIGlmIChvYmouJHJlZikge1xuICAgIHN0ciArPSBIZWxwZXJzLnNpbXBsZVJlZihvYmouJHJlZik7XG4gIH0gZWxzZSB7XG4gICAgc3RyICs9IG9iai50eXBlO1xuICB9XG5cbiAgcmV0dXJuIHN0cjtcbn1cblxuZnVuY3Rpb24gc2NoZW1hVG9KU09OKHNjaGVtYSwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSB7XG4gIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICBzY2hlbWEgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEoc2NoZW1hKTtcblxuICBpZih0eXBlb2YgbW9kZWxQcm9wZXJ0eU1hY3JvICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgbW9kZWxQcm9wZXJ0eU1hY3JvID0gZnVuY3Rpb24ocHJvcCl7XG4gICAgICByZXR1cm4gKHByb3AgfHwge30pLmRlZmF1bHQ7XG4gICAgfTtcbiAgfVxuXG4gIG1vZGVsc1RvSWdub3JlPSBtb2RlbHNUb0lnbm9yZSB8fCB7fTtcblxuICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICB2YXIgZm9ybWF0ID0gc2NoZW1hLmZvcm1hdDtcbiAgdmFyIG1vZGVsO1xuICB2YXIgb3V0cHV0O1xuXG4gIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuZXhhbXBsZSkpIHtcbiAgICBvdXRwdXQgPSBzY2hlbWEuZXhhbXBsZTtcbiAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykgJiYgXy5pc0FycmF5KHNjaGVtYS5lbnVtKSkge1xuICAgIG91dHB1dCA9IHNjaGVtYS5lbnVtWzBdO1xuICB9XG5cbiAgaWYgKF8uaXNVbmRlZmluZWQob3V0cHV0KSkge1xuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgbW9kZWwgPSBtb2RlbHNbSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLiRyZWYpXTtcblxuICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKG1vZGVsKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChtb2RlbHNUb0lnbm9yZVttb2RlbC5uYW1lXSkpIHtcbiAgICAgICAgICBtb2RlbHNUb0lnbm9yZVttb2RlbC5uYW1lXSA9IG1vZGVsO1xuICAgICAgICAgIG91dHB1dCA9IHNjaGVtYVRvSlNPTihtb2RlbC5kZWZpbml0aW9uLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgICAgIGRlbGV0ZSBtb2RlbHNUb0lnbm9yZVttb2RlbC5uYW1lXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAobW9kZWwudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICAgICAgb3V0cHV0ID0gW107XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG91dHB1dCA9IHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICBvdXRwdXQgPSBzY2hlbWEuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAoZm9ybWF0ID09PSAnZGF0ZS10aW1lJykge1xuICAgICAgICBvdXRwdXQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2RhdGUnKSB7XG4gICAgICAgIG91dHB1dCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0ID0gJ3N0cmluZyc7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicpIHtcbiAgICAgIG91dHB1dCA9IDA7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgb3V0cHV0ID0gMC4wO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBvdXRwdXQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIG91dHB1dCA9IHt9O1xuXG4gICAgICBfLmZvckVhY2goc2NoZW1hLnByb3BlcnRpZXMsIGZ1bmN0aW9uIChwcm9wZXJ0eSwgbmFtZSkge1xuICAgICAgICB2YXIgY1Byb3BlcnR5ID0gXy5jbG9uZURlZXAocHJvcGVydHkpO1xuXG4gICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICBjUHJvcGVydHkuZGVmYXVsdCA9IG1vZGVsUHJvcGVydHlNYWNybyhwcm9wZXJ0eSk7XG5cbiAgICAgICAgb3V0cHV0W25hbWVdID0gc2NoZW1hVG9KU09OKGNQcm9wZXJ0eSwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgb3V0cHV0ID0gW107XG5cbiAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBfLmZvckVhY2goc2NoZW1hLml0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgIG91dHB1dC5wdXNoKHNjaGVtYVRvSlNPTihpdGVtLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIG91dHB1dC5wdXNoKHNjaGVtYVRvSlNPTihzY2hlbWEuaXRlbXMsIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgb3V0cHV0LnB1c2goe30pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgSGVscGVycy5sb2coJ0FycmF5IHR5cGVcXCdzIFxcJ2l0ZW1zXFwnIHByb3BlcnR5IGlzIG5vdCBhbiBhcnJheSBvciBhbiBvYmplY3QsIGNhbm5vdCBwcm9jZXNzJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuZnVuY3Rpb24gc2NoZW1hVG9IVE1MKG5hbWUsIHNjaGVtYSwgbW9kZWxzLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcblxuICB2YXIgc3Ryb25nT3BlbiA9ICc8c3BhbiBjbGFzcz1cInN0cm9uZ1wiPic7XG4gIHZhciBzdHJvbmdDbG9zZSA9ICc8L3NwYW4+JztcblxuICAvLyBBbGxvdyBmb3IgaWdub3JpbmcgdGhlICduYW1lJyBhcmd1bWVudC4uLi4gc2hpZnRpbmcgdGhlIHJlc3RcbiAgaWYoXy5pc09iamVjdChhcmd1bWVudHNbMF0pKSB7XG4gICAgbmFtZSA9IHZvaWQgMDtcbiAgICBzY2hlbWEgPSBhcmd1bWVudHNbMF07XG4gICAgbW9kZWxzID0gYXJndW1lbnRzWzFdO1xuICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGFyZ3VtZW50c1syXTtcbiAgfVxuXG4gIG1vZGVscyA9IG1vZGVscyB8fCB7fTtcblxuICAvLyBSZXNvbHZlIHRoZSBzY2hlbWEgKEhhbmRsZSBuZXN0ZWQgc2NoZW1hcylcbiAgc2NoZW1hID0gSGVscGVycy5yZXNvbHZlU2NoZW1hKHNjaGVtYSk7XG5cbiAgLy8gUmV0dXJuIGZvciBlbXB0eSBvYmplY3RcbiAgaWYoXy5pc0VtcHR5KHNjaGVtYSkpIHtcbiAgICByZXR1cm4gc3Ryb25nT3BlbiArICdFbXB0eScgKyBzdHJvbmdDbG9zZTtcbiAgfVxuXG4gIC8vIERlcmVmZXJlbmNlICRyZWYgZnJvbSAnbW9kZWxzJ1xuICBpZih0eXBlb2Ygc2NoZW1hLiRyZWYgPT09ICdzdHJpbmcnKSB7XG4gICAgbmFtZSA9IEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS4kcmVmKTtcbiAgICBzY2hlbWEgPSBtb2RlbHNbbmFtZV07XG4gICAgaWYodHlwZW9mIHNjaGVtYSA9PT0gJ3VuZGVmaW5lZCcpXG4gICAge1xuICAgICAgcmV0dXJuIHN0cm9uZ09wZW4gKyBuYW1lICsgJyBpcyBub3QgZGVmaW5lZCEnICsgc3Ryb25nQ2xvc2U7XG4gICAgfVxuICB9XG5cbiAgaWYodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgbmFtZSA9IHNjaGVtYS50aXRsZSB8fCAnSW5saW5lIE1vZGVsJztcbiAgfVxuXG4gIC8vIElmIHdlIGFyZSBhIE1vZGVsIG9iamVjdC4uLiBhZGp1c3QgYWNjb3JkaW5nbHlcbiAgaWYoc2NoZW1hLmRlZmluaXRpb24pIHtcbiAgICBzY2hlbWEgPSBzY2hlbWEuZGVmaW5pdGlvbjtcbiAgfVxuXG4gIGlmKHR5cGVvZiBtb2RlbFByb3BlcnR5TWFjcm8gIT09ICdmdW5jdGlvbicpIHtcbiAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBmdW5jdGlvbihwcm9wKXtcbiAgICAgIHJldHVybiAocHJvcCB8fCB7fSkuZGVmYXVsdDtcbiAgICB9O1xuICB9XG5cbiAgdmFyIHJlZmVyZW5jZXMgPSB7fTtcbiAgdmFyIHNlZW5Nb2RlbHMgPSBbXTtcbiAgdmFyIGlubGluZU1vZGVscyA9IDA7XG5cblxuXG4gIC8vIEdlbmVyYXRlIGN1cnJlbnQgSFRNTFxuICB2YXIgaHRtbCA9IHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpO1xuXG4gIC8vIEdlbmVyYXRlIHJlZmVyZW5jZXMgSFRNTFxuICB3aGlsZSAoXy5rZXlzKHJlZmVyZW5jZXMpLmxlbmd0aCA+IDApIHtcbiAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgXy5mb3JFYWNoKHJlZmVyZW5jZXMsIGZ1bmN0aW9uIChzY2hlbWEsIG5hbWUpIHtcbiAgICAgIHZhciBzZWVuTW9kZWwgPSBfLmluZGV4T2Yoc2Vlbk1vZGVscywgbmFtZSkgPiAtMTtcblxuICAgICAgZGVsZXRlIHJlZmVyZW5jZXNbbmFtZV07XG5cbiAgICAgIGlmICghc2Vlbk1vZGVsKSB7XG4gICAgICAgIHNlZW5Nb2RlbHMucHVzaChuYW1lKTtcblxuICAgICAgICBodG1sICs9ICc8YnIgLz4nICsgcHJvY2Vzc01vZGVsKHNjaGVtYSwgbmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cbiAgfVxuXG4gIHJldHVybiBodG1sO1xuXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIGZ1bmN0aW9uIGFkZFJlZmVyZW5jZShzY2hlbWEsIG5hbWUsIHNraXBSZWYpIHtcbiAgICB2YXIgbW9kZWxOYW1lID0gbmFtZTtcbiAgICB2YXIgbW9kZWw7XG5cbiAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgIG1vZGVsTmFtZSA9IHNjaGVtYS50aXRsZSB8fCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZik7XG4gICAgICBtb2RlbCA9IG1vZGVsc1ttb2RlbE5hbWVdO1xuICAgIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChuYW1lKSkge1xuICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwgJyArICgrK2lubGluZU1vZGVscyk7XG4gICAgICBtb2RlbCA9IHtkZWZpbml0aW9uOiBzY2hlbWF9O1xuICAgIH1cblxuICAgIGlmIChza2lwUmVmICE9PSB0cnVlKSB7XG4gICAgICByZWZlcmVuY2VzW21vZGVsTmFtZV0gPSBfLmlzVW5kZWZpbmVkKG1vZGVsKSA/IHt9IDogbW9kZWwuZGVmaW5pdGlvbjtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9kZWxOYW1lO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJpbWl0aXZlVG9IVE1MKHNjaGVtYSkge1xuICAgIHZhciBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcFR5cGVcIj4nO1xuICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG5cbiAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYSwgSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLiRyZWYpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLnByb3BlcnRpZXMpKSB7XG4gICAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBodG1sICs9ICdvYmplY3QnO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgaHRtbCArPSAnQXJyYXlbJztcblxuICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIGh0bWwgKz0gXy5tYXAoc2NoZW1hLml0ZW1zLCBhZGRSZWZlcmVuY2UpLmpvaW4oJywnKTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLiRyZWYpKSB7XG4gICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSAmJiBfLmluZGV4T2YoWydhcnJheScsICdvYmplY3QnXSwgc2NoZW1hLml0ZW1zLnR5cGUpID09PSAtMSkge1xuICAgICAgICAgICAgaHRtbCArPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zLCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuaXRlbXMuJHJlZikpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBIZWxwZXJzLmxvZygnQXJyYXkgdHlwZVxcJ3MgXFwnaXRlbXNcXCcgc2NoZW1hIGlzIG5vdCBhbiBhcnJheSBvciBhbiBvYmplY3QsIGNhbm5vdCBwcm9jZXNzJyk7XG4gICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICB9XG5cbiAgICAgIGh0bWwgKz0gJ10nO1xuICAgIH0gZWxzZSB7XG4gICAgICBodG1sICs9IHNjaGVtYS50eXBlO1xuICAgIH1cblxuICAgIGh0bWwgKz0gJzwvc3Bhbj4nO1xuXG4gICAgcmV0dXJuIGh0bWw7XG4gIH1cblxuICBmdW5jdGlvbiBwcmltaXRpdmVUb09wdGlvbnNIVE1MKHNjaGVtYSwgaHRtbCkge1xuICAgIHZhciBvcHRpb25zID0gJyc7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcbiAgICB2YXIgaXNBcnJheSA9IHR5cGUgPT09ICdhcnJheSc7XG5cbiAgICBpZiAoaXNBcnJheSkge1xuICAgICAgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpICYmICFfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSkge1xuICAgICAgICB0eXBlID0gc2NoZW1hLml0ZW1zLnR5cGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0eXBlID0gJ29iamVjdCc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5kZWZhdWx0KSkge1xuICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdEZWZhdWx0Jywgc2NoZW1hLmRlZmF1bHQpO1xuICAgIH1cblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICBpZiAoc2NoZW1hLm1pbkxlbmd0aCkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gTGVuZ3RoJywgc2NoZW1hLm1pbkxlbmd0aCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEubWF4TGVuZ3RoKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBMZW5ndGgnLCBzY2hlbWEubWF4TGVuZ3RoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5wYXR0ZXJuKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnUmVnLiBFeHAuJywgc2NoZW1hLnBhdHRlcm4pO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnaW50ZWdlcic6XG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgIGlmIChzY2hlbWEubWluaW11bSkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gVmFsdWUnLCBzY2hlbWEubWluaW11bSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEuZXhjbHVzaXZlTWluaW11bSkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0V4Y2x1c2l2ZSBNaW4uJywgJ3RydWUnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5tYXhpbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBWYWx1ZScsIHNjaGVtYS5tYXhpbXVtKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5leGNsdXNpdmVNYXhpbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1heC4nLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm11bHRpcGxlT2YpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNdWx0aXBsZSBPZicsIHNjaGVtYS5tdWx0aXBsZU9mKTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgIGlmIChzY2hlbWEubWluSXRlbXMpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNaW4uIEl0ZW1zJywgc2NoZW1hLm1pbkl0ZW1zKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5tYXhJdGVtcykge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01heC4gSXRlbXMnLCBzY2hlbWEubWF4SXRlbXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLnVuaXF1ZUl0ZW1zKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnVW5pcXVlIEl0ZW1zJywgJ3RydWUnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5jb2xsZWN0aW9uRm9ybWF0KSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnQ29sbC4gRm9ybWF0Jywgc2NoZW1hLmNvbGxlY3Rpb25Gb3JtYXQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykpIHtcbiAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLmVudW0pKSB7XG4gICAgICAgIHZhciBlbnVtU3RyaW5nO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAnbnVtYmVyJyB8fCB0eXBlID09PSAnaW50ZWdlcicpIHtcbiAgICAgICAgICBlbnVtU3RyaW5nID0gc2NoZW1hLmVudW0uam9pbignLCAnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbnVtU3RyaW5nID0gJ1wiJyArIHNjaGVtYS5lbnVtLmpvaW4oJ1wiLCBcIicpICsgJ1wiJztcbiAgICAgICAgfVxuXG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRW51bScsIGVudW1TdHJpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wV3JhcFwiPicgKyBodG1sICsgJzx0YWJsZSBjbGFzcz1cIm9wdGlvbnNXcmFwcGVyXCI+PHRyPjx0aCBjb2xzcGFuPVwiMlwiPicgKyB0eXBlICsgJzwvdGg+PC90cj4nICsgb3B0aW9ucyArICc8L3RhYmxlPjwvc3Bhbj4nO1xuICAgIH1cblxuICAgIHJldHVybiBodG1sO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJvY2Vzc01vZGVsKHNjaGVtYSwgbmFtZSkge1xuICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgdmFyIGlzQXJyYXkgPSBzY2hlbWEudHlwZSA9PT0gJ2FycmF5JztcbiAgICB2YXIgaHRtbCA9IHN0cm9uZ09wZW4gKyBuYW1lICsgJyAnICsgKGlzQXJyYXkgPyAnWycgOiAneycpICsgc3Ryb25nQ2xvc2U7XG5cbiAgICBpZiAobmFtZSkge1xuICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChpc0FycmF5KSB7XG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgXy5tYXAoc2NoZW1hLml0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgIHZhciB0eXBlID0gaXRlbS50eXBlIHx8ICdvYmplY3QnO1xuXG4gICAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoaXRlbS4kcmVmKSkge1xuICAgICAgICAgICAgaWYgKF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCB0eXBlKSA+IC0xKSB7XG4gICAgICAgICAgICAgIGlmICh0eXBlID09PSAnb2JqZWN0JyAmJiBfLmlzVW5kZWZpbmVkKGl0ZW0ucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJ29iamVjdCc7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFkZFJlZmVyZW5jZShpdGVtKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoaXRlbSwgdHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBhZGRSZWZlcmVuY2UoaXRlbSwgSGVscGVycy5zaW1wbGVSZWYoaXRlbS4kcmVmKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KS5qb2luKCcsPC9kaXY+PGRpdj4nKTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLiRyZWYpKSB7XG4gICAgICAgICAgaWYgKF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCBzY2hlbWEuaXRlbXMudHlwZSB8fCAnb2JqZWN0JykgPiAtMSkge1xuICAgICAgICAgICAgaWYgKChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSB8fCBzY2hlbWEuaXRlbXMudHlwZSA9PT0gJ29iamVjdCcpICYmIF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+b2JqZWN0PC9kaXY+JztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMpICsgJzwvZGl2Pic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoc2NoZW1hLml0ZW1zLCBzY2hlbWEuaXRlbXMudHlwZSkgKyAnPC9kaXY+JztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcywgSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLml0ZW1zLiRyZWYpKSArICc8L2Rpdj4nO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBIZWxwZXJzLmxvZygnQXJyYXkgdHlwZVxcJ3MgXFwnaXRlbXNcXCcgcHJvcGVydHkgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgaHRtbCArPSAnPGRpdj5vYmplY3Q8L2Rpdj4nO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSkgKyAnPC9kaXY+JztcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEucHJvcGVydGllcykpIHtcbiAgICAgICAgICB2YXIgY29udGVudHMgPSBfLm1hcChzY2hlbWEucHJvcGVydGllcywgZnVuY3Rpb24gKHByb3BlcnR5LCBuYW1lKSB7XG4gICAgICAgICAgICB2YXIgcHJvcGVydHlJc1JlcXVpcmVkID0gKF8uaW5kZXhPZihzY2hlbWEucmVxdWlyZWQsIG5hbWUpID49IDApO1xuICAgICAgICAgICAgdmFyIGNQcm9wZXJ0eSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcblxuICAgICAgICAgICAgdmFyIHJlcXVpcmVkQ2xhc3MgPSBwcm9wZXJ0eUlzUmVxdWlyZWQgPyAncmVxdWlyZWQnIDogJyc7XG4gICAgICAgICAgICB2YXIgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BOYW1lICcgKyByZXF1aXJlZENsYXNzICsgJ1wiPicgKyBuYW1lICsgJzwvc3Bhbj4gKCc7XG4gICAgICAgICAgICB2YXIgbW9kZWw7XG4gICAgICAgICAgICB2YXIgcHJvcERlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAvLyBBbGxvdyBtYWNybyB0byBzZXQgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICAgICAgICAgIGNQcm9wZXJ0eS5kZWZhdWx0ID0gbW9kZWxQcm9wZXJ0eU1hY3JvKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICAgICAgICAgICAgY1Byb3BlcnR5ID0gSGVscGVycy5yZXNvbHZlU2NoZW1hKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgIHByb3BEZXNjcmlwdGlvbiA9IHByb3BlcnR5LmRlc2NyaXB0aW9uIHx8IGNQcm9wZXJ0eS5kZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBoYW5kbGUgcHJvcGVydHkgcmVmZXJlbmNlcyB0byBwcmltaXRpdmVzIChJc3N1ZSAzMzkpXG4gICAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoY1Byb3BlcnR5LiRyZWYpKSB7XG4gICAgICAgICAgICAgIG1vZGVsID0gbW9kZWxzW0hlbHBlcnMuc2ltcGxlUmVmKGNQcm9wZXJ0eS4kcmVmKV07XG5cbiAgICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKG1vZGVsKSAmJiBfLmluZGV4T2YoW3VuZGVmaW5lZCwgJ2FycmF5JywgJ29iamVjdCddLCBtb2RlbC5kZWZpbml0aW9uLnR5cGUpID09PSAtMSkge1xuICAgICAgICAgICAgICAgIC8vIFVzZSByZWZlcmVuY2VkIHNjaGVtYVxuICAgICAgICAgICAgICAgIGNQcm9wZXJ0eSA9IEhlbHBlcnMucmVzb2x2ZVNjaGVtYShtb2RlbC5kZWZpbml0aW9uKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBodG1sICs9IHByaW1pdGl2ZVRvSFRNTChjUHJvcGVydHkpO1xuXG4gICAgICAgICAgICBpZighcHJvcGVydHlJc1JlcXVpcmVkKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJywgPHNwYW4gY2xhc3M9XCJwcm9wT3B0S2V5XCI+b3B0aW9uYWw8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYocHJvcGVydHkucmVhZE9ubHkpIHtcbiAgICAgICAgICAgICAgICBodG1sICs9ICcsIDxzcGFuIGNsYXNzPVwicHJvcFJlYWRPbmx5XCI+cmVhZCBvbmx5PC9zcGFuPic7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGh0bWwgKz0gJyknO1xuXG4gICAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQocHJvcERlc2NyaXB0aW9uKSkge1xuICAgICAgICAgICAgICBodG1sICs9ICc6ICcgKyAnPHNwYW4gY2xhc3M9XCJwcm9wRGVzY1wiPicgKyBwcm9wRGVzY3JpcHRpb24gKyAnPC9zcGFuPic7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjUHJvcGVydHkuZW51bSkge1xuICAgICAgICAgICAgICBodG1sICs9ICcgPSA8c3BhbiBjbGFzcz1cInByb3BWYWxzXCI+W1xcJycgKyBjUHJvcGVydHkuZW51bS5qb2luKCdcXCcsIFxcJycpICsgJ1xcJ108L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuICc8ZGl2JyArIChwcm9wZXJ0eS5yZWFkT25seSA/ICcgY2xhc3M9XCJyZWFkT25seVwiJyA6ICcnKSArICc+JyArIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoY1Byb3BlcnR5LCBodG1sKTtcbiAgICAgICAgICB9KS5qb2luKCcsPC9kaXY+Jyk7XG5cbiAgICAgICAgICBpZiAoY29udGVudHMpIHtcbiAgICAgICAgICAgIGh0bWwgKz0gY29udGVudHMgKyAnPC9kaXY+JztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoc2NoZW1hLCB0eXBlKSArICc8L2Rpdj4nO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBodG1sICsgc3Ryb25nT3BlbiArIChpc0FycmF5ID8gJ10nIDogJ30nKSArIHN0cm9uZ0Nsb3NlO1xuICB9XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4vaHR0cCcpO1xudmFyIF8gPSB7XG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKVxufTtcblxudmFyIFN3YWdnZXJTcGVjQ29udmVydGVyID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZXJyb3JzID0gW107XG4gIHRoaXMud2FybmluZ3MgPSBbXTtcbiAgdGhpcy5tb2RlbE1hcCA9IHt9O1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnNldERvY3VtZW50YXRpb25Mb2NhdGlvbiA9IGZ1bmN0aW9uIChsb2NhdGlvbikge1xuICB0aGlzLmRvY0xvY2F0aW9uID0gbG9jYXRpb247XG59O1xuXG4vKipcbiAqIGNvbnZlcnRzIGEgcmVzb3VyY2UgbGlzdGluZyBPUiBhcGkgZGVjbGFyYXRpb25cbiAqKi9cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5jb252ZXJ0ID0gZnVuY3Rpb24gKG9iaiwgY2xpZW50QXV0aG9yaXphdGlvbnMsIG9wdHMsIGNhbGxiYWNrKSB7XG4gIC8vIG5vdCBhIHZhbGlkIHNwZWNcbiAgaWYoIW9iaiB8fCAhQXJyYXkuaXNBcnJheShvYmouYXBpcykpIHtcbiAgICByZXR1cm4gdGhpcy5maW5pc2goY2FsbGJhY2ssIG51bGwpO1xuICB9XG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMgPSBjbGllbnRBdXRob3JpemF0aW9ucztcblxuICAvLyBjcmVhdGUgYSBuZXcgc3dhZ2dlciBvYmplY3QgdG8gcmV0dXJuXG4gIHZhciBzd2FnZ2VyID0geyBzd2FnZ2VyOiAnMi4wJyB9O1xuXG4gIHN3YWdnZXIub3JpZ2luYWxWZXJzaW9uID0gb2JqLnN3YWdnZXJWZXJzaW9uO1xuXG4gIC8vIGFkZCB0aGUgaW5mb1xuICB0aGlzLmFwaUluZm8ob2JqLCBzd2FnZ2VyKTtcblxuICAvLyBhZGQgc2VjdXJpdHkgZGVmaW5pdGlvbnNcbiAgdGhpcy5zZWN1cml0eURlZmluaXRpb25zKG9iaiwgc3dhZ2dlcik7XG5cbiAgLy8gdGFrZSBiYXNlUGF0aCBpbnRvIGFjY291bnRcbiAgaWYgKG9iai5iYXNlUGF0aCkge1xuICAgIHRoaXMuc2V0RG9jdW1lbnRhdGlvbkxvY2F0aW9uKG9iai5iYXNlUGF0aCk7XG4gIH1cblxuICAvLyBzZWUgaWYgdGhpcyBpcyBhIHNpbmdsZS1maWxlIHN3YWdnZXIgZGVmaW5pdGlvblxuICB2YXIgaXNTaW5nbGVGaWxlU3dhZ2dlciA9IGZhbHNlO1xuICB2YXIgaTtcbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmFwaXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYXBpID0gb2JqLmFwaXNbaV07XG4gICAgaWYoQXJyYXkuaXNBcnJheShhcGkub3BlcmF0aW9ucykpIHtcbiAgICAgIGlzU2luZ2xlRmlsZVN3YWdnZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBpZihpc1NpbmdsZUZpbGVTd2FnZ2VyKSB7XG4gICAgdGhpcy5kZWNsYXJhdGlvbihvYmosIHN3YWdnZXIpO1xuICAgIHRoaXMuZmluaXNoKGNhbGxiYWNrLCBzd2FnZ2VyKTtcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLnJlc291cmNlTGlzdGluZyhvYmosIHN3YWdnZXIsIG9wdHMsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmRlY2xhcmF0aW9uID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIHZhciBuYW1lLCBpLCBwLCBwb3M7XG4gIGlmKCFvYmouYXBpcykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChvYmouYmFzZVBhdGguaW5kZXhPZignaHR0cDovLycpID09PSAwKSB7XG4gICAgcCA9IG9iai5iYXNlUGF0aC5zdWJzdHJpbmcoJ2h0dHA6Ly8nLmxlbmd0aCk7XG4gICAgcG9zID0gcC5pbmRleE9mKCcvJyk7XG4gICAgaWYgKHBvcyA+IDApIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHAuc3Vic3RyaW5nKDAsIHBvcyk7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gcC5zdWJzdHJpbmcocG9zKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzd2FnZ2VyLmhvc3QgPSBwO1xuICAgICAgc3dhZ2dlci5iYXNlUGF0aCA9ICcvJztcbiAgICB9XG4gIH0gZWxzZSBpZiAob2JqLmJhc2VQYXRoLmluZGV4T2YoJ2h0dHBzOi8vJykgPT09IDApIHtcbiAgICBwID0gb2JqLmJhc2VQYXRoLnN1YnN0cmluZygnaHR0cHM6Ly8nLmxlbmd0aCk7XG4gICAgcG9zID0gcC5pbmRleE9mKCcvJyk7XG4gICAgaWYgKHBvcyA+IDApIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHAuc3Vic3RyaW5nKDAsIHBvcyk7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gcC5zdWJzdHJpbmcocG9zKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzd2FnZ2VyLmhvc3QgPSBwO1xuICAgICAgc3dhZ2dlci5iYXNlUGF0aCA9ICcvJztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc3dhZ2dlci5iYXNlUGF0aCA9IG9iai5iYXNlUGF0aDtcbiAgfVxuXG4gIHZhciByZXNvdXJjZUxldmVsQXV0aDtcbiAgaWYob2JqLmF1dGhvcml6YXRpb25zKSB7XG4gICAgcmVzb3VyY2VMZXZlbEF1dGggPSBvYmouYXV0aG9yaXphdGlvbnM7XG4gIH1cbiAgaWYob2JqLmNvbnN1bWVzKSB7XG4gICAgc3dhZ2dlci5jb25zdW1lcyA9IG9iai5jb25zdW1lcztcbiAgfVxuICBpZihvYmoucHJvZHVjZXMpIHtcbiAgICBzd2FnZ2VyLnByb2R1Y2VzID0gb2JqLnByb2R1Y2VzO1xuICB9XG5cbiAgLy8gYnVpbGQgYSBtYXBwaW5nIG9mIGlkIHRvIG5hbWUgZm9yIDEuMCBtb2RlbCByZXNvbHV0aW9uc1xuICBpZihfLmlzT2JqZWN0KG9iaikpIHtcbiAgICBmb3IobmFtZSBpbiBvYmoubW9kZWxzKSB7XG4gICAgICB2YXIgZXhpc3RpbmdNb2RlbCA9IG9iai5tb2RlbHNbbmFtZV07XG4gICAgICB2YXIga2V5ID0gKGV4aXN0aW5nTW9kZWwuaWQgfHwgbmFtZSk7XG4gICAgICB0aGlzLm1vZGVsTWFwW2tleV0gPSBuYW1lO1xuICAgIH1cbiAgfVxuXG4gIGZvcihpID0gMDsgaSA8IG9iai5hcGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGFwaSA9IG9iai5hcGlzW2ldO1xuICAgIHZhciBwYXRoID0gYXBpLnBhdGg7XG4gICAgdmFyIG9wZXJhdGlvbnMgPSBhcGkub3BlcmF0aW9ucztcbiAgICB0aGlzLm9wZXJhdGlvbnMocGF0aCwgb2JqLnJlc291cmNlUGF0aCwgb3BlcmF0aW9ucywgcmVzb3VyY2VMZXZlbEF1dGgsIHN3YWdnZXIpO1xuICB9XG5cbiAgdmFyIG1vZGVscyA9IG9iai5tb2RlbHMgfHwge307XG4gIHRoaXMubW9kZWxzKG1vZGVscywgc3dhZ2dlcik7XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUubW9kZWxzID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIGlmKCFfLmlzT2JqZWN0KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIG5hbWU7XG5cbiAgc3dhZ2dlci5kZWZpbml0aW9ucyA9IHN3YWdnZXIuZGVmaW5pdGlvbnMgfHwge307XG4gIGZvcihuYW1lIGluIG9iaikge1xuICAgIHZhciBleGlzdGluZ01vZGVsID0gb2JqW25hbWVdO1xuICAgIHZhciBfcmVxdWlyZWQgPSBbXTtcbiAgICB2YXIgc2NoZW1hID0geyBwcm9wZXJ0aWVzOiB7fX07XG4gICAgdmFyIHByb3BlcnR5TmFtZTtcbiAgICBmb3IocHJvcGVydHlOYW1lIGluIGV4aXN0aW5nTW9kZWwucHJvcGVydGllcykge1xuICAgICAgdmFyIGV4aXN0aW5nUHJvcGVydHkgPSBleGlzdGluZ01vZGVsLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcbiAgICAgIHZhciBwcm9wZXJ0eSA9IHt9O1xuICAgICAgdGhpcy5kYXRhVHlwZShleGlzdGluZ1Byb3BlcnR5LCBwcm9wZXJ0eSk7XG4gICAgICBpZihleGlzdGluZ1Byb3BlcnR5LmRlc2NyaXB0aW9uKSB7XG4gICAgICAgIHByb3BlcnR5LmRlc2NyaXB0aW9uID0gZXhpc3RpbmdQcm9wZXJ0eS5kZXNjcmlwdGlvbjtcbiAgICAgIH1cbiAgICAgIGlmKGV4aXN0aW5nUHJvcGVydHlbJ2VudW0nXSkge1xuICAgICAgICBwcm9wZXJ0eVsnZW51bSddID0gZXhpc3RpbmdQcm9wZXJ0eVsnZW51bSddO1xuICAgICAgfVxuICAgICAgaWYodHlwZW9mIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09ICdib29sZWFuJyAmJiBleGlzdGluZ1Byb3BlcnR5LnJlcXVpcmVkID09PSB0cnVlKSB7XG4gICAgICAgIF9yZXF1aXJlZC5wdXNoKHByb3BlcnR5TmFtZSk7XG4gICAgICB9XG4gICAgICBpZih0eXBlb2YgZXhpc3RpbmdQcm9wZXJ0eS5yZXF1aXJlZCA9PT0gJ3N0cmluZycgJiYgZXhpc3RpbmdQcm9wZXJ0eS5yZXF1aXJlZCA9PT0gJ3RydWUnKSB7XG4gICAgICAgIF9yZXF1aXJlZC5wdXNoKHByb3BlcnR5TmFtZSk7XG4gICAgICB9XG4gICAgICBzY2hlbWEucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdID0gcHJvcGVydHk7XG4gICAgfVxuICAgIGlmKF9yZXF1aXJlZC5sZW5ndGggPiAwKSB7XG4gICAgICBzY2hlbWEucmVxdWlyZWQgPSBfcmVxdWlyZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjaGVtYS5yZXF1aXJlZCA9IGV4aXN0aW5nTW9kZWwucmVxdWlyZWQ7XG4gICAgfVxuICAgIHN3YWdnZXIuZGVmaW5pdGlvbnNbbmFtZV0gPSBzY2hlbWE7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5leHRyYWN0VGFnID0gZnVuY3Rpb24ocmVzb3VyY2VQYXRoKSB7XG4gIHZhciBwYXRoU3RyaW5nID0gcmVzb3VyY2VQYXRoIHx8ICdkZWZhdWx0JztcbiAgaWYocGF0aFN0cmluZy5pbmRleE9mKCdodHRwOicpID09PSAwIHx8IHBhdGhTdHJpbmcuaW5kZXhPZignaHR0cHM6JykgPT09IDApIHtcbiAgICBwYXRoU3RyaW5nID0gcGF0aFN0cmluZy5zcGxpdChbJy8nXSk7XG4gICAgcGF0aFN0cmluZyA9IHBhdGhTdHJpbmdbcGF0aFN0cmluZy5sZW5ndGggLTFdLnN1YnN0cmluZygpO1xuICB9XG4gIGlmKHBhdGhTdHJpbmcuZW5kc1dpdGgoJy5qc29uJykpIHtcbiAgICBwYXRoU3RyaW5nID0gcGF0aFN0cmluZy5zdWJzdHJpbmcoMCwgcGF0aFN0cmluZy5sZW5ndGggLSAnLmpzb24nLmxlbmd0aCk7XG4gIH1cbiAgcmV0dXJuIHBhdGhTdHJpbmcucmVwbGFjZSgnLycsJycpO1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLm9wZXJhdGlvbnMgPSBmdW5jdGlvbihwYXRoLCByZXNvdXJjZVBhdGgsIG9iaiwgcmVzb3VyY2VMZXZlbEF1dGgsIHN3YWdnZXIpIHtcbiAgaWYoIUFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgaTtcblxuICBpZighc3dhZ2dlci5wYXRocykge1xuICAgIHN3YWdnZXIucGF0aHMgPSB7fTtcbiAgfVxuXG4gIHZhciBwYXRoT2JqID0gc3dhZ2dlci5wYXRoc1twYXRoXSB8fCB7fTtcbiAgdmFyIHRhZyA9IHRoaXMuZXh0cmFjdFRhZyhyZXNvdXJjZVBhdGgpO1xuICBzd2FnZ2VyLnRhZ3MgPSBzd2FnZ2VyLnRhZ3MgfHwgW107XG4gIHZhciBtYXRjaGVkID0gZmFsc2U7XG4gIGZvcihpID0gMDsgaSA8IHN3YWdnZXIudGFncy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB0YWdPYmplY3QgPSBzd2FnZ2VyLnRhZ3NbaV07XG4gICAgaWYodGFnT2JqZWN0Lm5hbWUgPT09IHRhZykge1xuICAgICAgbWF0Y2hlZCA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmKCFtYXRjaGVkKSB7XG4gICAgc3dhZ2dlci50YWdzLnB1c2goe25hbWU6IHRhZ30pO1xuICB9XG5cbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGV4aXN0aW5nT3BlcmF0aW9uID0gb2JqW2ldO1xuICAgIHZhciBtZXRob2QgPSAoZXhpc3RpbmdPcGVyYXRpb24ubWV0aG9kIHx8IGV4aXN0aW5nT3BlcmF0aW9uLmh0dHBNZXRob2QpLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFyIG9wZXJhdGlvbiA9IHt0YWdzOiBbdGFnXX07XG4gICAgdmFyIGV4aXN0aW5nQXV0aG9yaXphdGlvbnMgPSBleGlzdGluZ09wZXJhdGlvbi5hdXRob3JpemF0aW9ucztcblxuICAgIGlmKGV4aXN0aW5nQXV0aG9yaXphdGlvbnMgJiYgT2JqZWN0LmtleXMoZXhpc3RpbmdBdXRob3JpemF0aW9ucykubGVuZ3RoID09PSAwKSB7XG4gICAgICBleGlzdGluZ0F1dGhvcml6YXRpb25zID0gcmVzb3VyY2VMZXZlbEF1dGg7XG4gICAgfVxuXG4gICAgaWYodHlwZW9mIGV4aXN0aW5nQXV0aG9yaXphdGlvbnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgc2NvcGVzT2JqZWN0O1xuICAgICAgZm9yKHZhciBrZXkgaW4gZXhpc3RpbmdBdXRob3JpemF0aW9ucykge1xuICAgICAgICBvcGVyYXRpb24uc2VjdXJpdHkgPSBvcGVyYXRpb24uc2VjdXJpdHkgfHwgW107XG4gICAgICAgIHZhciBzY29wZXMgPSBleGlzdGluZ0F1dGhvcml6YXRpb25zW2tleV07XG4gICAgICAgIGlmKHNjb3Blcykge1xuICAgICAgICAgIHZhciBzZWN1cml0eVNjb3BlcyA9IFtdO1xuICAgICAgICAgIGZvcih2YXIgaiBpbiBzY29wZXMpIHtcbiAgICAgICAgICAgIHNlY3VyaXR5U2NvcGVzLnB1c2goc2NvcGVzW2pdLnNjb3BlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2NvcGVzT2JqZWN0ID0ge307XG4gICAgICAgICAgc2NvcGVzT2JqZWN0W2tleV0gPSBzZWN1cml0eVNjb3BlcztcbiAgICAgICAgICBvcGVyYXRpb24uc2VjdXJpdHkucHVzaChzY29wZXNPYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHNjb3Blc09iamVjdCA9IHt9O1xuICAgICAgICAgIHNjb3Blc09iamVjdFtrZXldID0gW107XG4gICAgICAgICAgb3BlcmF0aW9uLnNlY3VyaXR5LnB1c2goc2NvcGVzT2JqZWN0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLmNvbnN1bWVzKSB7XG4gICAgICBvcGVyYXRpb24uY29uc3VtZXMgPSBleGlzdGluZ09wZXJhdGlvbi5jb25zdW1lcztcbiAgICB9XG4gICAgZWxzZSBpZihzd2FnZ2VyLmNvbnN1bWVzKSB7XG4gICAgICBvcGVyYXRpb24uY29uc3VtZXMgPSBzd2FnZ2VyLmNvbnN1bWVzO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5wcm9kdWNlcykge1xuICAgICAgb3BlcmF0aW9uLnByb2R1Y2VzID0gZXhpc3RpbmdPcGVyYXRpb24ucHJvZHVjZXM7XG4gICAgfVxuICAgIGVsc2UgaWYoc3dhZ2dlci5wcm9kdWNlcykge1xuICAgICAgb3BlcmF0aW9uLnByb2R1Y2VzID0gc3dhZ2dlci5wcm9kdWNlcztcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24uc3VtbWFyeSkge1xuICAgICAgb3BlcmF0aW9uLnN1bW1hcnkgPSBleGlzdGluZ09wZXJhdGlvbi5zdW1tYXJ5O1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5ub3Rlcykge1xuICAgICAgb3BlcmF0aW9uLmRlc2NyaXB0aW9uID0gZXhpc3RpbmdPcGVyYXRpb24ubm90ZXM7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLm5pY2tuYW1lKSB7XG4gICAgICBvcGVyYXRpb24ub3BlcmF0aW9uSWQgPSBleGlzdGluZ09wZXJhdGlvbi5uaWNrbmFtZTtcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24uZGVwcmVjYXRlZCkge1xuICAgICAgb3BlcmF0aW9uLmRlcHJlY2F0ZWQgPSBleGlzdGluZ09wZXJhdGlvbi5kZXByZWNhdGVkO1xuICAgIH1cblxuICAgIHRoaXMuYXV0aG9yaXphdGlvbnMoZXhpc3RpbmdBdXRob3JpemF0aW9ucywgc3dhZ2dlcik7XG4gICAgdGhpcy5wYXJhbWV0ZXJzKG9wZXJhdGlvbiwgZXhpc3RpbmdPcGVyYXRpb24ucGFyYW1ldGVycywgc3dhZ2dlcik7XG4gICAgdGhpcy5yZXNwb25zZU1lc3NhZ2VzKG9wZXJhdGlvbiwgZXhpc3RpbmdPcGVyYXRpb24sIHN3YWdnZXIpO1xuXG4gICAgcGF0aE9ialttZXRob2RdID0gb3BlcmF0aW9uO1xuICB9XG5cbiAgc3dhZ2dlci5wYXRoc1twYXRoXSA9IHBhdGhPYmo7XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUucmVzcG9uc2VNZXNzYWdlcyA9IGZ1bmN0aW9uKG9wZXJhdGlvbiwgZXhpc3RpbmdPcGVyYXRpb24pIHtcbiAgaWYoIV8uaXNPYmplY3QoZXhpc3RpbmdPcGVyYXRpb24pKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIGJ1aWxkIGRlZmF1bHQgcmVzcG9uc2UgZnJvbSB0aGUgb3BlcmF0aW9uICgxLngpXG4gIHZhciBkZWZhdWx0UmVzcG9uc2UgPSB7fTtcbiAgdGhpcy5kYXRhVHlwZShleGlzdGluZ09wZXJhdGlvbiwgZGVmYXVsdFJlc3BvbnNlKTtcbiAgLy8gVE9ETzogbG9vayBpbnRvIHRoZSByZWFsIHByb2JsZW0gb2YgcmVuZGVyaW5nIHJlc3BvbnNlcyBpbiBzd2FnZ2VyLXVpXG4gIC8vIC4uLi5zaG91bGQgcmVwb25zZVR5cGUgaGF2ZSBhbiBpbXBsaWNpdCBzY2hlbWE/XG4gIGlmKCFkZWZhdWx0UmVzcG9uc2Uuc2NoZW1hICYmIGRlZmF1bHRSZXNwb25zZS50eXBlKSB7XG4gICAgZGVmYXVsdFJlc3BvbnNlID0ge3NjaGVtYTogZGVmYXVsdFJlc3BvbnNlfTtcbiAgfVxuXG4gIG9wZXJhdGlvbi5yZXNwb25zZXMgPSBvcGVyYXRpb24ucmVzcG9uc2VzIHx8IHt9O1xuXG4gIC8vIGdyYWIgZnJvbSByZXNwb25zZU1lc3NhZ2VzICgxLjIpXG4gIHZhciBoYXMyMDAgPSBmYWxzZTtcbiAgaWYoQXJyYXkuaXNBcnJheShleGlzdGluZ09wZXJhdGlvbi5yZXNwb25zZU1lc3NhZ2VzKSkge1xuICAgIHZhciBpO1xuICAgIHZhciBleGlzdGluZ1Jlc3BvbnNlcyA9IGV4aXN0aW5nT3BlcmF0aW9uLnJlc3BvbnNlTWVzc2FnZXM7XG4gICAgZm9yKGkgPSAwOyBpIDwgZXhpc3RpbmdSZXNwb25zZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBleGlzdGluZ1Jlc3BvbnNlID0gZXhpc3RpbmdSZXNwb25zZXNbaV07XG4gICAgICB2YXIgcmVzcG9uc2UgPSB7IGRlc2NyaXB0aW9uOiBleGlzdGluZ1Jlc3BvbnNlLm1lc3NhZ2UgfTtcbiAgICAgIGlmKGV4aXN0aW5nUmVzcG9uc2UuY29kZSA9PT0gMjAwKSB7XG4gICAgICAgIGhhczIwMCA9IHRydWU7XG4gICAgICB9XG4gICAgICAvLyBDb252ZXJ0IHJlc3BvbnNlTW9kZWwgLT4gc2NoZW1heyRyZWY6IHJlc3BvbnNlTW9kZWx9XG4gICAgICBpZihleGlzdGluZ1Jlc3BvbnNlLnJlc3BvbnNlTW9kZWwpIHtcbiAgICAgICAgcmVzcG9uc2Uuc2NoZW1hID0geyckcmVmJzogJyMvZGVmaW5pdGlvbnMvJyArIGV4aXN0aW5nUmVzcG9uc2UucmVzcG9uc2VNb2RlbH07XG4gICAgICB9XG4gICAgICBvcGVyYXRpb24ucmVzcG9uc2VzWycnICsgZXhpc3RpbmdSZXNwb25zZS5jb2RlXSA9IHJlc3BvbnNlO1xuICAgIH1cbiAgfVxuXG4gIGlmKGhhczIwMCkge1xuICAgIG9wZXJhdGlvbi5yZXNwb25zZXNbJ2RlZmF1bHQnXSA9IGRlZmF1bHRSZXNwb25zZTtcbiAgfVxuICBlbHNlIHtcbiAgICBvcGVyYXRpb24ucmVzcG9uc2VzWycyMDAnXSA9IGRlZmF1bHRSZXNwb25zZTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmF1dGhvcml6YXRpb25zID0gZnVuY3Rpb24ob2JqKSB7XG4gIC8vIFRPRE9cbiAgaWYoIV8uaXNPYmplY3Qob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnBhcmFtZXRlcnMgPSBmdW5jdGlvbihvcGVyYXRpb24sIG9iaikge1xuICBpZighQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBpO1xuICBmb3IoaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZXhpc3RpbmdQYXJhbWV0ZXIgPSBvYmpbaV07XG4gICAgdmFyIHBhcmFtZXRlciA9IHt9O1xuICAgIHBhcmFtZXRlci5uYW1lID0gZXhpc3RpbmdQYXJhbWV0ZXIubmFtZTtcbiAgICBwYXJhbWV0ZXIuZGVzY3JpcHRpb24gPSBleGlzdGluZ1BhcmFtZXRlci5kZXNjcmlwdGlvbjtcbiAgICBwYXJhbWV0ZXIucmVxdWlyZWQgPSBleGlzdGluZ1BhcmFtZXRlci5yZXF1aXJlZDtcbiAgICBwYXJhbWV0ZXIuaW4gPSBleGlzdGluZ1BhcmFtZXRlci5wYXJhbVR5cGU7XG5cbiAgICAvLyBwZXIgIzE2OFxuICAgIGlmKHBhcmFtZXRlci5pbiA9PT0gJ2JvZHknKSB7XG4gICAgICBwYXJhbWV0ZXIubmFtZSA9ICdib2R5JztcbiAgICB9XG4gICAgaWYocGFyYW1ldGVyLmluID09PSAnZm9ybScpIHtcbiAgICAgIHBhcmFtZXRlci5pbiA9ICdmb3JtRGF0YSc7XG4gICAgfVxuXG4gICAgaWYoZXhpc3RpbmdQYXJhbWV0ZXIuZW51bSkge1xuICAgICAgcGFyYW1ldGVyLmVudW0gPSBleGlzdGluZ1BhcmFtZXRlci5lbnVtO1xuICAgIH1cblxuICAgIGlmKGV4aXN0aW5nUGFyYW1ldGVyLmFsbG93TXVsdGlwbGUgPT09IHRydWUgfHwgZXhpc3RpbmdQYXJhbWV0ZXIuYWxsb3dNdWx0aXBsZSA9PT0gJ3RydWUnKSB7XG4gICAgICB2YXIgaW5uZXJUeXBlID0ge307XG4gICAgICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nUGFyYW1ldGVyLCBpbm5lclR5cGUpO1xuICAgICAgcGFyYW1ldGVyLnR5cGUgPSAnYXJyYXknO1xuICAgICAgcGFyYW1ldGVyLml0ZW1zID0gaW5uZXJUeXBlO1xuXG4gICAgICBpZihleGlzdGluZ1BhcmFtZXRlci5hbGxvd2FibGVWYWx1ZXMpIHtcbiAgICAgICAgdmFyIGF2ID0gZXhpc3RpbmdQYXJhbWV0ZXIuYWxsb3dhYmxlVmFsdWVzO1xuICAgICAgICBpZihhdi52YWx1ZVR5cGUgPT09ICdMSVNUJykge1xuICAgICAgICAgIHBhcmFtZXRlclsnZW51bSddID0gYXYudmFsdWVzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy5kYXRhVHlwZShleGlzdGluZ1BhcmFtZXRlciwgcGFyYW1ldGVyKTtcbiAgICB9XG4gICAgaWYodHlwZW9mIGV4aXN0aW5nUGFyYW1ldGVyLmRlZmF1bHRWYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHBhcmFtZXRlci5kZWZhdWx0ID0gZXhpc3RpbmdQYXJhbWV0ZXIuZGVmYXVsdFZhbHVlO1xuICAgIH1cblxuICAgIG9wZXJhdGlvbi5wYXJhbWV0ZXJzID0gb3BlcmF0aW9uLnBhcmFtZXRlcnMgfHwgW107XG4gICAgb3BlcmF0aW9uLnBhcmFtZXRlcnMucHVzaChwYXJhbWV0ZXIpO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZGF0YVR5cGUgPSBmdW5jdGlvbihzb3VyY2UsIHRhcmdldCkge1xuICBpZighXy5pc09iamVjdChzb3VyY2UpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYoc291cmNlLm1pbmltdW0pIHtcbiAgICB0YXJnZXQubWluaW11bSA9IHNvdXJjZS5taW5pbXVtO1xuICB9XG4gIGlmKHNvdXJjZS5tYXhpbXVtKSB7XG4gICAgdGFyZ2V0Lm1heGltdW0gPSBzb3VyY2UubWF4aW11bTtcbiAgfVxuICBpZiAoc291cmNlLmZvcm1hdCkge1xuICAgIHRhcmdldC5mb3JtYXQgPSBzb3VyY2UuZm9ybWF0O1xuICB9XG5cbiAgLy8gZGVmYXVsdCBjYW4gYmUgJ2ZhbHNlJ1xuICBpZih0eXBlb2Ygc291cmNlLmRlZmF1bHRWYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0YXJnZXQuZGVmYXVsdCA9IHNvdXJjZS5kZWZhdWx0VmFsdWU7XG4gIH1cblxuICB2YXIganNvblNjaGVtYVR5cGUgPSB0aGlzLnRvSnNvblNjaGVtYShzb3VyY2UpO1xuICBpZihqc29uU2NoZW1hVHlwZSkge1xuICAgIHRhcmdldCA9IHRhcmdldCB8fCB7fTtcbiAgICBpZihqc29uU2NoZW1hVHlwZS50eXBlKSB7XG4gICAgICB0YXJnZXQudHlwZSA9IGpzb25TY2hlbWFUeXBlLnR5cGU7XG4gICAgfVxuICAgIGlmKGpzb25TY2hlbWFUeXBlLmZvcm1hdCkge1xuICAgICAgdGFyZ2V0LmZvcm1hdCA9IGpzb25TY2hlbWFUeXBlLmZvcm1hdDtcbiAgICB9XG4gICAgaWYoanNvblNjaGVtYVR5cGUuJHJlZikge1xuICAgICAgdGFyZ2V0LnNjaGVtYSA9IHskcmVmOiBqc29uU2NoZW1hVHlwZS4kcmVmfTtcbiAgICB9XG4gICAgaWYoanNvblNjaGVtYVR5cGUuaXRlbXMpIHtcbiAgICAgIHRhcmdldC5pdGVtcyA9IGpzb25TY2hlbWFUeXBlLml0ZW1zO1xuICAgIH1cbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnRvSnNvblNjaGVtYSA9IGZ1bmN0aW9uKHNvdXJjZSkge1xuICBpZighc291cmNlKSB7XG4gICAgcmV0dXJuICdvYmplY3QnO1xuICB9XG4gIHZhciBkZXRlY3RlZFR5cGUgPSAoc291cmNlLnR5cGUgfHwgc291cmNlLmRhdGFUeXBlIHx8IHNvdXJjZS5yZXNwb25zZUNsYXNzIHx8ICcnKTtcbiAgdmFyIGxjVHlwZSA9IGRldGVjdGVkVHlwZS50b0xvd2VyQ2FzZSgpO1xuICB2YXIgZm9ybWF0ID0gKHNvdXJjZS5mb3JtYXQgfHwgJycpLnRvTG93ZXJDYXNlKCk7XG5cbiAgaWYobGNUeXBlLmluZGV4T2YoJ2xpc3RbJykgPT09IDApIHtcbiAgICB2YXIgaW5uZXJUeXBlID0gZGV0ZWN0ZWRUeXBlLnN1YnN0cmluZyg1LCBkZXRlY3RlZFR5cGUubGVuZ3RoIC0gMSk7XG4gICAgdmFyIGpzb25UeXBlID0gdGhpcy50b0pzb25TY2hlbWEoe3R5cGU6IGlubmVyVHlwZX0pO1xuICAgIHJldHVybiB7dHlwZTogJ2FycmF5JywgaXRlbXM6IGpzb25UeXBlfTtcbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2ludCcgfHwgKGxjVHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDMyJykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnaW50ZWdlcicsIGZvcm1hdDogJ2ludDMyJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnbG9uZycgfHwgKGxjVHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDY0JykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnaW50ZWdlcicsIGZvcm1hdDogJ2ludDY0J307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnaW50ZWdlcicpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnaW50ZWdlcicsIGZvcm1hdDogJ2ludDY0J307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnZmxvYXQnIHx8IChsY1R5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2Zsb2F0JykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnbnVtYmVyJywgZm9ybWF0OiAnZmxvYXQnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdkb3VibGUnIHx8IChsY1R5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2RvdWJsZScpKSB7XG4gICAge3JldHVybiB7dHlwZTogJ251bWJlcicsIGZvcm1hdDogJ2RvdWJsZSd9O31cbiAgfSBlbHNlIGlmKChsY1R5cGUgPT09ICdzdHJpbmcnICYmIGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHx8IChsY1R5cGUgPT09ICdkYXRlJykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnc3RyaW5nJywgZm9ybWF0OiAnZGF0ZS10aW1lJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnc3RyaW5nJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdzdHJpbmcnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdmaWxlJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdmaWxlJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnYm9vbGVhbid9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2Jvb2xlYW4nfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdhcnJheScgfHwgbGNUeXBlID09PSAnbGlzdCcpIHtcbiAgICBpZihzb3VyY2UuaXRlbXMpIHtcbiAgICAgIHZhciBpdCA9IHRoaXMudG9Kc29uU2NoZW1hKHNvdXJjZS5pdGVtcyk7XG4gICAgICByZXR1cm4ge3R5cGU6ICdhcnJheScsIGl0ZW1zOiBpdH07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuIHt0eXBlOiAnYXJyYXknLCBpdGVtczoge3R5cGU6ICdvYmplY3QnfX07XG4gICAgfVxuICB9IGVsc2UgaWYoc291cmNlLiRyZWYpIHtcbiAgICByZXR1cm4geyRyZWY6IHRoaXMubW9kZWxNYXBbc291cmNlLiRyZWZdID8gJyMvZGVmaW5pdGlvbnMvJyArIHRoaXMubW9kZWxNYXBbc291cmNlLiRyZWZdIDogc291cmNlLiRyZWZ9O1xuICB9IGVsc2UgaWYobGNUeXBlID09PSAndm9pZCcgfHwgbGNUeXBlID09PSAnJykge1xuICAgIHtyZXR1cm4ge307fVxuICB9IGVsc2UgaWYgKHRoaXMubW9kZWxNYXBbc291cmNlLnR5cGVdKSB7XG4gICAgLy8gSWYgdGhpcyBhIG1vZGVsIHVzaW5nIGB0eXBlYCBpbnN0ZWFkIG9mIGAkcmVmYCwgdGhhdCdzIGZpbmUuXG4gICAgcmV0dXJuIHskcmVmOiAnIy9kZWZpbml0aW9ucy8nICsgdGhpcy5tb2RlbE1hcFtzb3VyY2UudHlwZV19O1xuICB9IGVsc2Uge1xuICAgIC8vIFVua25vd24gbW9kZWwgdHlwZSBvciAnb2JqZWN0JywgcGFzcyBpdCBhbG9uZy5cbiAgICByZXR1cm4ge3R5cGU6IHNvdXJjZS50eXBlfTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnJlc291cmNlTGlzdGluZyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlciwgb3B0cywgY2FsbGJhY2spIHtcbiAgdmFyIGk7XG4gIHZhciBwcm9jZXNzZWRDb3VudCA9IDA7ICAgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gIHZhciBzZWxmID0gdGhpczsgICAgICAgICAgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gIHZhciBleHBlY3RlZENvdW50ID0gb2JqLmFwaXMubGVuZ3RoO1xuICB2YXIgX3N3YWdnZXIgPSBzd2FnZ2VyOyAgIC8vIGpzaGludCBpZ25vcmU6bGluZVxuICB2YXIgX29wdHMgPSB7fTtcblxuICBpZihvcHRzICYmIG9wdHMucmVxdWVzdEludGVyY2VwdG9yKXtcbiAgICBfb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgPSBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIGlmKG9wdHMgJiYgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yKXtcbiAgICBfb3B0cy5yZXNwb25zZUludGVyY2VwdG9yID0gb3B0cy5yZXNwb25zZUludGVyY2VwdG9yO1xuICB9XG5cbiAgdmFyIHN3YWdnZXJSZXF1ZXN0SGVhZGVycyA9ICdhcHBsaWNhdGlvbi9qc29uJztcblxuICBpZihvcHRzICYmIG9wdHMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzKSB7XG4gICAgc3dhZ2dlclJlcXVlc3RIZWFkZXJzID0gb3B0cy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnM7XG4gIH1cblxuICBpZihleHBlY3RlZENvdW50ID09PSAwKSB7XG4gICAgdGhpcy5maW5pc2goY2FsbGJhY2ssIHN3YWdnZXIpO1xuICB9XG5cbiAgZm9yKGkgPSAwOyBpIDwgZXhwZWN0ZWRDb3VudDsgaSsrKSB7XG4gICAgdmFyIGFwaSA9IG9iai5hcGlzW2ldO1xuICAgIHZhciBwYXRoID0gYXBpLnBhdGg7XG4gICAgdmFyIGFic29sdXRlUGF0aCA9IHRoaXMuZ2V0QWJzb2x1dGVQYXRoKG9iai5zd2FnZ2VyVmVyc2lvbiwgdGhpcy5kb2NMb2NhdGlvbiwgcGF0aCk7XG5cbiAgICBpZihhcGkuZGVzY3JpcHRpb24pIHtcbiAgICAgIHN3YWdnZXIudGFncyA9IHN3YWdnZXIudGFncyB8fCBbXTtcbiAgICAgIHN3YWdnZXIudGFncy5wdXNoKHtcbiAgICAgICAgbmFtZSA6IHRoaXMuZXh0cmFjdFRhZyhhcGkucGF0aCksXG4gICAgICAgIGRlc2NyaXB0aW9uIDogYXBpLmRlc2NyaXB0aW9uIHx8ICcnXG4gICAgICB9KTtcbiAgICB9XG4gICAgdmFyIGh0dHAgPSB7XG4gICAgICB1cmw6IGFic29sdXRlUGF0aCxcbiAgICAgIGhlYWRlcnM6IHsgYWNjZXB0OiBzd2FnZ2VyUmVxdWVzdEhlYWRlcnMgfSxcbiAgICAgIG9uOiB7fSxcbiAgICAgIG1ldGhvZDogJ2dldCdcbiAgICB9O1xuICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICBodHRwLm9uLnJlc3BvbnNlID0gZnVuY3Rpb24oZGF0YSkge1xuICAgICAgcHJvY2Vzc2VkQ291bnQgKz0gMTtcbiAgICAgIHZhciBvYmogPSBkYXRhLm9iajtcbiAgICAgIGlmKG9iaikge1xuICAgICAgICBzZWxmLmRlY2xhcmF0aW9uKG9iaiwgX3N3YWdnZXIpO1xuICAgICAgfVxuICAgICAgaWYocHJvY2Vzc2VkQ291bnQgPT09IGV4cGVjdGVkQ291bnQpIHtcbiAgICAgICAgc2VsZi5maW5pc2goY2FsbGJhY2ssIF9zd2FnZ2VyKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGh0dHAub24uZXJyb3IgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGRhdGEpO1xuICAgICAgcHJvY2Vzc2VkQ291bnQgKz0gMTtcbiAgICAgIGlmKHByb2Nlc3NlZENvdW50ID09PSBleHBlY3RlZENvdW50KSB7XG4gICAgICAgIHNlbGYuZmluaXNoKGNhbGxiYWNrLCBfc3dhZ2dlcik7XG4gICAgICB9XG4gICAgfTtcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG4gICAgaWYodGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyAmJiB0eXBlb2YgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShodHRwKTtcbiAgICB9XG5cbiAgICBuZXcgU3dhZ2dlckh0dHAoKS5leGVjdXRlKGh0dHAsIF9vcHRzKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmdldEFic29sdXRlUGF0aCA9IGZ1bmN0aW9uKHZlcnNpb24sIGRvY0xvY2F0aW9uLCBwYXRoKSAge1xuICBpZih2ZXJzaW9uID09PSAnMS4wJykge1xuICAgIGlmKGRvY0xvY2F0aW9uLmVuZHNXaXRoKCcuanNvbicpKSB7XG4gICAgICAvLyBnZXQgcm9vdCBwYXRoXG4gICAgICB2YXIgcG9zID0gZG9jTG9jYXRpb24ubGFzdEluZGV4T2YoJy8nKTtcbiAgICAgIGlmKHBvcyA+IDApIHtcbiAgICAgICAgZG9jTG9jYXRpb24gPSBkb2NMb2NhdGlvbi5zdWJzdHJpbmcoMCwgcG9zKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgbG9jYXRpb24gPSBkb2NMb2NhdGlvbjtcbiAgaWYocGF0aC5pbmRleE9mKCdodHRwOicpID09PSAwIHx8IHBhdGguaW5kZXhPZignaHR0cHM6JykgPT09IDApIHtcbiAgICBsb2NhdGlvbiA9IHBhdGg7XG4gIH1cbiAgZWxzZSB7XG4gICAgaWYoZG9jTG9jYXRpb24uZW5kc1dpdGgoJy8nKSkge1xuICAgICAgbG9jYXRpb24gPSBkb2NMb2NhdGlvbi5zdWJzdHJpbmcoMCwgZG9jTG9jYXRpb24ubGVuZ3RoIC0gMSk7XG4gICAgfVxuICAgIGxvY2F0aW9uICs9IHBhdGg7XG4gIH1cbiAgbG9jYXRpb24gPSBsb2NhdGlvbi5yZXBsYWNlKCd7Zm9ybWF0fScsICdqc29uJyk7XG4gIHJldHVybiBsb2NhdGlvbjtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5zZWN1cml0eURlZmluaXRpb25zID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIGlmKG9iai5hdXRob3JpemF0aW9ucykge1xuICAgIHZhciBuYW1lO1xuICAgIGZvcihuYW1lIGluIG9iai5hdXRob3JpemF0aW9ucykge1xuICAgICAgdmFyIGlzVmFsaWQgPSBmYWxzZTtcbiAgICAgIHZhciBzZWN1cml0eURlZmluaXRpb24gPSB7fTtcbiAgICAgIHZhciBkZWZpbml0aW9uID0gb2JqLmF1dGhvcml6YXRpb25zW25hbWVdO1xuICAgICAgaWYoZGVmaW5pdGlvbi50eXBlID09PSAnYXBpS2V5Jykge1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24udHlwZSA9ICdhcGlLZXknO1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24uaW4gPSBkZWZpbml0aW9uLnBhc3NBcztcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLm5hbWUgPSBkZWZpbml0aW9uLmtleW5hbWUgfHwgbmFtZTtcbiAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ2Jhc2ljQXV0aCcpIHtcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnR5cGUgPSAnYmFzaWNBdXRoJztcbiAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgdmFyIGV4aXN0aW5nU2NvcGVzID0gZGVmaW5pdGlvbi5zY29wZXMgfHwgW107XG4gICAgICAgIHZhciBzY29wZXMgPSB7fTtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIGZvcihpIGluIGV4aXN0aW5nU2NvcGVzKSB7XG4gICAgICAgICAgdmFyIHNjb3BlID0gZXhpc3RpbmdTY29wZXNbaV07XG4gICAgICAgICAgc2NvcGVzW3Njb3BlLnNjb3BlXSA9IHNjb3BlLmRlc2NyaXB0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi50eXBlID0gJ29hdXRoMic7XG4gICAgICAgIGlmKGkgPiAwKSB7XG4gICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnNjb3BlcyA9IHNjb3BlcztcbiAgICAgICAgfVxuICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXMpIHtcbiAgICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXMuaW1wbGljaXQpIHtcbiAgICAgICAgICAgIHZhciBpbXBsaWNpdCA9IGRlZmluaXRpb24uZ3JhbnRUeXBlcy5pbXBsaWNpdDtcbiAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5mbG93ID0gJ2ltcGxpY2l0JztcbiAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5hdXRob3JpemF0aW9uVXJsID0gaW1wbGljaXQubG9naW5FbmRwb2ludDtcbiAgICAgICAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgICAgICAgaWYoZGVmaW5pdGlvbi5ncmFudFR5cGVzWydhdXRob3JpemF0aW9uX2NvZGUnXSkge1xuICAgICAgICAgICAgaWYoIXNlY3VyaXR5RGVmaW5pdGlvbi5mbG93KSB7XG4gICAgICAgICAgICAgIC8vIGNhbm5vdCBzZXQgaWYgZmxvdyBpcyBhbHJlYWR5IGRlZmluZWRcbiAgICAgICAgICAgICAgdmFyIGF1dGhDb2RlID0gZGVmaW5pdGlvbi5ncmFudFR5cGVzWydhdXRob3JpemF0aW9uX2NvZGUnXTtcbiAgICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmZsb3cgPSAnYWNjZXNzQ29kZSc7XG4gICAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5hdXRob3JpemF0aW9uVXJsID0gYXV0aENvZGUudG9rZW5SZXF1ZXN0RW5kcG9pbnQudXJsO1xuICAgICAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24udG9rZW5VcmwgPSBhdXRoQ29kZS50b2tlbkVuZHBvaW50LnVybDtcbiAgICAgICAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGlzVmFsaWQpIHtcbiAgICAgICAgc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zID0gc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zIHx8IHt9O1xuICAgICAgICBzd2FnZ2VyLnNlY3VyaXR5RGVmaW5pdGlvbnNbbmFtZV0gPSBzZWN1cml0eURlZmluaXRpb247XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuYXBpSW5mbyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICAvLyBpbmZvIHNlY3Rpb25cbiAgaWYob2JqLmluZm8pIHtcbiAgICB2YXIgaW5mbyA9IG9iai5pbmZvO1xuICAgIHN3YWdnZXIuaW5mbyA9IHt9O1xuXG4gICAgaWYoaW5mby5jb250YWN0KSB7XG4gICAgICBzd2FnZ2VyLmluZm8uY29udGFjdCA9IHt9O1xuICAgICAgc3dhZ2dlci5pbmZvLmNvbnRhY3QuZW1haWwgPSBpbmZvLmNvbnRhY3Q7XG4gICAgfVxuICAgIGlmKGluZm8uZGVzY3JpcHRpb24pIHtcbiAgICAgIHN3YWdnZXIuaW5mby5kZXNjcmlwdGlvbiA9IGluZm8uZGVzY3JpcHRpb247XG4gICAgfVxuICAgIGlmKGluZm8udGl0bGUpIHtcbiAgICAgIHN3YWdnZXIuaW5mby50aXRsZSA9IGluZm8udGl0bGU7XG4gICAgfVxuICAgIGlmKGluZm8udGVybXNPZlNlcnZpY2VVcmwpIHtcbiAgICAgIHN3YWdnZXIuaW5mby50ZXJtc09mU2VydmljZSA9IGluZm8udGVybXNPZlNlcnZpY2VVcmw7XG4gICAgfVxuICAgIGlmKGluZm8ubGljZW5zZSB8fCBpbmZvLmxpY2Vuc2VVcmwpIHtcbiAgICAgIHN3YWdnZXIubGljZW5zZSA9IHt9O1xuICAgICAgaWYoaW5mby5saWNlbnNlKSB7XG4gICAgICAgIHN3YWdnZXIubGljZW5zZS5uYW1lID0gaW5mby5saWNlbnNlO1xuICAgICAgfVxuICAgICAgaWYoaW5mby5saWNlbnNlVXJsKSB7XG4gICAgICAgIHN3YWdnZXIubGljZW5zZS51cmwgPSBpbmZvLmxpY2Vuc2VVcmw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMud2FybmluZ3MucHVzaCgnbWlzc2luZyBpbmZvIHNlY3Rpb24nKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIChjYWxsYmFjaywgb2JqKSB7XG4gIGNhbGxiYWNrKG9iaik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgbG9nID0gcmVxdWlyZSgnLi4vaGVscGVycycpLmxvZztcbnZhciBfID0ge1xuICBpc1BsYWluT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdCcpLFxuICBpc1N0cmluZzogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzU3RyaW5nJyksXG59O1xuXG52YXIgU2NoZW1hTWFya3VwID0gcmVxdWlyZSgnLi4vc2NoZW1hLW1hcmt1cC5qcycpO1xudmFyIGpzeWFtbCA9IHJlcXVpcmUoJ2pzLXlhbWwnKTtcblxudmFyIE1vZGVsID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgdGhpcy5kZWZpbml0aW9uID0gZGVmaW5pdGlvbiB8fCB7fTtcbiAgdGhpcy5pc0FycmF5ID0gZGVmaW5pdGlvbi50eXBlID09PSAnYXJyYXknO1xuICB0aGlzLm1vZGVscyA9IG1vZGVscyB8fCB7fTtcbiAgdGhpcy5uYW1lID0gbmFtZSB8fCBkZWZpbml0aW9uLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyA9IG1vZGVsUHJvcGVydHlNYWNybyB8fCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICByZXR1cm4gcHJvcGVydHkuZGVmYXVsdDtcbiAgfTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIE5vdGUhICBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgcmVtb3ZlZCBpbiAyLjIueCFcbk1vZGVsLnByb3RvdHlwZS5jcmVhdGVKU09OU2FtcGxlID0gTW9kZWwucHJvdG90eXBlLmdldFNhbXBsZVZhbHVlID0gZnVuY3Rpb24gKG1vZGVsc1RvSWdub3JlKSB7XG4gIG1vZGVsc1RvSWdub3JlID0gbW9kZWxzVG9JZ25vcmUgfHwge307XG5cbiAgbW9kZWxzVG9JZ25vcmVbdGhpcy5uYW1lXSA9IHRoaXM7XG5cbiAgLy8gUmVzcG9uc2Ugc3VwcG9ydFxuICBpZiAodGhpcy5leGFtcGxlcyAmJiBfLmlzUGxhaW5PYmplY3QodGhpcy5leGFtcGxlcykgJiYgdGhpcy5leGFtcGxlc1snYXBwbGljYXRpb24vanNvbiddKSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSB0aGlzLmV4YW1wbGVzWydhcHBsaWNhdGlvbi9qc29uJ107XG5cbiAgICBpZiAoXy5pc1N0cmluZyh0aGlzLmRlZmluaXRpb24uZXhhbXBsZSkpIHtcbiAgICAgIHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlID0ganN5YW1sLnNhZmVMb2FkKHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIXRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSB0aGlzLmV4YW1wbGVzO1xuICB9XG5cbiAgcmV0dXJuIFNjaGVtYU1hcmt1cC5zY2hlbWFUb0pTT04odGhpcy5kZWZpbml0aW9uLCB0aGlzLm1vZGVscywgbW9kZWxzVG9JZ25vcmUsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG5cbk1vZGVsLnByb3RvdHlwZS5nZXRNb2NrU2lnbmF0dXJlID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gU2NoZW1hTWFya3VwLnNjaGVtYVRvSFRNTCh0aGlzLm5hbWUsIHRoaXMuZGVmaW5pdGlvbiwgdGhpcy5tb2RlbHMsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBjbG9uZURlZXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpLFxuICBpc0VtcHR5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0Jylcbn07XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMnKTtcbnZhciBNb2RlbCA9IHJlcXVpcmUoJy4vbW9kZWwnKTtcbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4uL2h0dHAnKTtcbnZhciBRID0gcmVxdWlyZSgncScpO1xuXG52YXIgT3BlcmF0aW9uID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAocGFyZW50LCBzY2hlbWUsIG9wZXJhdGlvbklkLCBodHRwTWV0aG9kLCBwYXRoLCBhcmdzLCBkZWZpbml0aW9ucywgbW9kZWxzLCBjbGllbnRBdXRob3JpemF0aW9ucykge1xuICB2YXIgZXJyb3JzID0gW107XG5cbiAgcGFyZW50ID0gcGFyZW50IHx8IHt9O1xuICBhcmdzID0gYXJncyB8fCB7fTtcblxuICBpZihwYXJlbnQgJiYgcGFyZW50Lm9wdGlvbnMpIHtcbiAgICB0aGlzLmNsaWVudCA9IHBhcmVudC5vcHRpb25zLmNsaWVudCB8fCBudWxsO1xuICAgIHRoaXMucmVxdWVzdEludGVyY2VwdG9yID0gcGFyZW50Lm9wdGlvbnMucmVxdWVzdEludGVyY2VwdG9yIHx8IG51bGw7XG4gICAgdGhpcy5yZXNwb25zZUludGVyY2VwdG9yID0gcGFyZW50Lm9wdGlvbnMucmVzcG9uc2VJbnRlcmNlcHRvciB8fCBudWxsO1xuICB9XG4gIHRoaXMuYXV0aG9yaXphdGlvbnMgPSBhcmdzLnNlY3VyaXR5O1xuICB0aGlzLmJhc2VQYXRoID0gcGFyZW50LmJhc2VQYXRoIHx8ICcvJztcbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IGNsaWVudEF1dGhvcml6YXRpb25zO1xuICB0aGlzLmNvbnN1bWVzID0gYXJncy5jb25zdW1lcyB8fCBwYXJlbnQuY29uc3VtZXMgfHwgWydhcHBsaWNhdGlvbi9qc29uJ107XG4gIHRoaXMucHJvZHVjZXMgPSBhcmdzLnByb2R1Y2VzIHx8IHBhcmVudC5wcm9kdWNlcyB8fCBbJ2FwcGxpY2F0aW9uL2pzb24nXTtcbiAgdGhpcy5kZXByZWNhdGVkID0gYXJncy5kZXByZWNhdGVkO1xuICB0aGlzLmRlc2NyaXB0aW9uID0gYXJncy5kZXNjcmlwdGlvbjtcbiAgdGhpcy5ob3N0ID0gcGFyZW50Lmhvc3QgfHwgJ2xvY2FsaG9zdCc7XG4gIHRoaXMubWV0aG9kID0gKGh0dHBNZXRob2QgfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbiAnICsgb3BlcmF0aW9uSWQgKyAnIGlzIG1pc3NpbmcgbWV0aG9kLicpKTtcbiAgdGhpcy5tb2RlbHMgPSBtb2RlbHMgfHwge307XG4gIHRoaXMubmlja25hbWUgPSAob3BlcmF0aW9uSWQgfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbnMgbXVzdCBoYXZlIGEgbmlja25hbWUuJykpO1xuICB0aGlzLm9wZXJhdGlvbiA9IGFyZ3M7XG4gIHRoaXMub3BlcmF0aW9ucyA9IHt9O1xuICB0aGlzLnBhcmFtZXRlcnMgPSBhcmdzICE9PSBudWxsID8gKGFyZ3MucGFyYW1ldGVycyB8fCBbXSkgOiB7fTtcbiAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gIHRoaXMucGF0aCA9IChwYXRoIHx8IGVycm9ycy5wdXNoKCdPcGVyYXRpb24gJyArIHRoaXMubmlja25hbWUgKyAnIGlzIG1pc3NpbmcgcGF0aC4nKSk7XG4gIHRoaXMucmVzcG9uc2VzID0gKGFyZ3MucmVzcG9uc2VzIHx8IHt9KTtcbiAgdGhpcy5zY2hlbWUgPSBzY2hlbWUgfHwgcGFyZW50LnNjaGVtZSB8fCAnaHR0cCc7XG4gIHRoaXMuc2NoZW1lcyA9IGFyZ3Muc2NoZW1lcyB8fCBwYXJlbnQuc2NoZW1lcztcbiAgdGhpcy5zZWN1cml0eSA9IGFyZ3Muc2VjdXJpdHkgfHwgcGFyZW50LnNlY3VyaXR5O1xuICB0aGlzLnN1bW1hcnkgPSBhcmdzLnN1bW1hcnkgfHwgJyc7XG4gIHRoaXMudHlwZSA9IG51bGw7XG4gIHRoaXMudXNlSlF1ZXJ5ID0gcGFyZW50LnVzZUpRdWVyeTtcbiAgdGhpcy5qcXVlcnlBamF4Q2FjaGUgPSBwYXJlbnQuanF1ZXJ5QWpheENhY2hlO1xuICB0aGlzLmVuYWJsZUNvb2tpZXMgPSBwYXJlbnQuZW5hYmxlQ29va2llcztcbiAgdGhpcy5wYXJhbWV0ZXJNYWNybyA9IHBhcmVudC5wYXJhbWV0ZXJNYWNybyB8fCBmdW5jdGlvbiAob3BlcmF0aW9uLCBwYXJhbWV0ZXIpIHtcbiAgICByZXR1cm4gcGFyYW1ldGVyLmRlZmF1bHQ7XG4gIH07XG5cbiAgdGhpcy5pbmxpbmVNb2RlbHMgPSBbXTtcblxuICBpZih0aGlzLmJhc2VQYXRoICE9PSAnLycgJiYgdGhpcy5iYXNlUGF0aC5zbGljZSgtMSkgPT09ICcvJykge1xuICAgIHRoaXMuYmFzZVBhdGggPSB0aGlzLmJhc2VQYXRoLnNsaWNlKDAsIC0xKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdGhpcy5kZXByZWNhdGVkID09PSAnc3RyaW5nJykge1xuICAgIHN3aXRjaCh0aGlzLmRlcHJlY2F0ZWQudG9Mb3dlckNhc2UoKSkge1xuICAgICAgY2FzZSAndHJ1ZSc6IGNhc2UgJ3llcyc6IGNhc2UgJzEnOiB7XG4gICAgICAgIHRoaXMuZGVwcmVjYXRlZCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdmYWxzZSc6IGNhc2UgJ25vJzogY2FzZSAnMCc6IGNhc2UgbnVsbDoge1xuICAgICAgICB0aGlzLmRlcHJlY2F0ZWQgPSBmYWxzZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGRlZmF1bHQ6IHRoaXMuZGVwcmVjYXRlZCA9IEJvb2xlYW4odGhpcy5kZXByZWNhdGVkKTtcbiAgICB9XG4gIH1cblxuICB2YXIgaSwgbW9kZWw7XG5cbiAgaWYgKGRlZmluaXRpb25zKSB7XG4gICAgLy8gYWRkIHRvIGdsb2JhbCBtb2RlbHNcbiAgICB2YXIga2V5O1xuXG4gICAgZm9yIChrZXkgaW4gZGVmaW5pdGlvbnMpIHtcbiAgICAgIG1vZGVsID0gbmV3IE1vZGVsKGtleSwgZGVmaW5pdGlvbnNba2V5XSwgdGhpcy5tb2RlbHMsIHBhcmVudC5tb2RlbFByb3BlcnR5TWFjcm8pO1xuXG4gICAgICBpZiAobW9kZWwpIHtcbiAgICAgICAgdGhpcy5tb2RlbHNba2V5XSA9IG1vZGVsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBkZWZpbml0aW9ucyA9IHt9O1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgIHBhcmFtLmRlZmF1bHQgPSB0aGlzLnBhcmFtZXRlck1hY3JvKHRoaXMsIHBhcmFtKTtcblxuICAgIGlmIChwYXJhbS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBwYXJhbS5pc0xpc3QgPSB0cnVlO1xuICAgICAgcGFyYW0uYWxsb3dNdWx0aXBsZSA9IHRydWU7XG4gICAgICAvLyB0aGUgZW51bSBjYW4gYmUgZGVmaW5lZCBhdCB0aGUgaXRlbXMgbGV2ZWxcbiAgICAgIC8vaWYgKHBhcmFtLml0ZW1zICYmIHBhcmFtLml0ZW1zLmVudW0pIHtcbiAgICAgIC8vICBwYXJhbVsnZW51bSddID0gcGFyYW0uaXRlbXMuZW51bTtcbiAgICAgIC8vfVxuICAgIH1cblxuICAgIHZhciBpbm5lclR5cGUgPSB0aGlzLmdldFR5cGUocGFyYW0pO1xuXG4gICAgaWYgKGlubmVyVHlwZSAmJiBpbm5lclR5cGUudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpID09PSAnYm9vbGVhbicpIHtcbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcyA9IHt9O1xuICAgICAgcGFyYW0uaXNMaXN0ID0gdHJ1ZTtcbiAgICAgIHBhcmFtWydlbnVtJ10gPSBbdHJ1ZSwgZmFsc2VdOyAvLyB1c2UgYWN0dWFsIHByaW1pdGl2ZXNcbiAgICB9XG5cbiAgICBpZih0eXBlb2YgcGFyYW1bJ3gtZXhhbXBsZSddICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIGQgPSBwYXJhbVsneC1leGFtcGxlJ107XG4gICAgICBwYXJhbS5kZWZhdWx0ID0gZDtcbiAgICB9XG4gICAgaWYocGFyYW1bJ3gtZXhhbXBsZXMnXSkge1xuICAgICAgdmFyIGQgPSBwYXJhbVsneC1leGFtcGxlcyddLmRlZmF1bHQ7XG4gICAgICBpZih0eXBlb2YgZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcGFyYW0uZGVmYXVsdCA9IGQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGVudW1WYWx1ZXMgPSBwYXJhbVsnZW51bSddIHx8IChwYXJhbS5pdGVtcyAmJiBwYXJhbS5pdGVtc1snZW51bSddKTtcblxuICAgIGlmICh0eXBlb2YgZW51bVZhbHVlcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBpZDtcblxuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzID0ge307XG4gICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMudmFsdWVzID0gW107XG4gICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMuZGVzY3JpcHRpdmVWYWx1ZXMgPSBbXTtcblxuICAgICAgZm9yIChpZCA9IDA7IGlkIDwgZW51bVZhbHVlcy5sZW5ndGg7IGlkKyspIHtcbiAgICAgICAgdmFyIHZhbHVlID0gZW51bVZhbHVlc1tpZF07XG4gICAgICAgIHZhciBpc0RlZmF1bHQgPSAodmFsdWUgPT09IHBhcmFtLmRlZmF1bHQgfHwgdmFsdWUrJycgPT09IHBhcmFtLmRlZmF1bHQpO1xuXG4gICAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy52YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgICAgIC8vIEFsd2F5cyBoYXZlIHN0cmluZyBmb3IgZGVzY3JpcHRpdmUgdmFsdWVzLi4uLlxuICAgICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMuZGVzY3JpcHRpdmVWYWx1ZXMucHVzaCh7dmFsdWUgOiB2YWx1ZSsnJywgaXNEZWZhdWx0OiBpc0RlZmF1bHR9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGFyYW0udHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgaW5uZXJUeXBlID0gW2lubmVyVHlwZV07XG5cbiAgICAgIGlmICh0eXBlb2YgcGFyYW0uYWxsb3dhYmxlVmFsdWVzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAvLyBjYW4ndCBzaG93IGFzIGEgbGlzdCBpZiBubyB2YWx1ZXMgdG8gc2VsZWN0IGZyb21cbiAgICAgICAgZGVsZXRlIHBhcmFtLmlzTGlzdDtcbiAgICAgICAgZGVsZXRlIHBhcmFtLmFsbG93TXVsdGlwbGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcGFyYW0ubW9kZWxTaWduYXR1cmUgPSB7dHlwZTogaW5uZXJUeXBlLCBkZWZpbml0aW9uczogdGhpcy5tb2RlbHN9O1xuICAgIHBhcmFtLnNpZ25hdHVyZSA9IHRoaXMuZ2V0TW9kZWxTaWduYXR1cmUoaW5uZXJUeXBlLCB0aGlzLm1vZGVscykudG9TdHJpbmcoKTtcbiAgICBwYXJhbS5zYW1wbGVKU09OID0gdGhpcy5nZXRNb2RlbFNhbXBsZUpTT04oaW5uZXJUeXBlLCB0aGlzLm1vZGVscyk7XG4gICAgcGFyYW0ucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSA9IHBhcmFtLnNpZ25hdHVyZTtcbiAgfVxuXG4gIHZhciBkZWZhdWx0UmVzcG9uc2VDb2RlLCByZXNwb25zZSwgcmVzcG9uc2VzID0gdGhpcy5yZXNwb25zZXM7XG5cbiAgaWYgKHJlc3BvbnNlc1snMjAwJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAwJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDAnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjAxJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAxJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDEnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjAyJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAyJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDInO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjAzJ10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjAzJ107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDMnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjA0J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjA0J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDQnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjA1J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjA1J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDUnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snMjA2J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snMjA2J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICcyMDYnO1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlc1snZGVmYXVsdCddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJ2RlZmF1bHQnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJ2RlZmF1bHQnO1xuICB9XG5cbiAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLnNjaGVtYSkge1xuICAgIHZhciByZXNvbHZlZE1vZGVsID0gdGhpcy5yZXNvbHZlTW9kZWwocmVzcG9uc2Uuc2NoZW1hLCBkZWZpbml0aW9ucyk7XG4gICAgdmFyIHN1Y2Nlc3NSZXNwb25zZTtcblxuICAgIGRlbGV0ZSByZXNwb25zZXNbZGVmYXVsdFJlc3BvbnNlQ29kZV07XG5cbiAgICBpZiAocmVzb2x2ZWRNb2RlbCkge1xuICAgICAgdGhpcy5zdWNjZXNzUmVzcG9uc2UgPSB7fTtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMuc3VjY2Vzc1Jlc3BvbnNlW2RlZmF1bHRSZXNwb25zZUNvZGVdID0gcmVzb2x2ZWRNb2RlbDtcbiAgICB9IGVsc2UgaWYgKCFyZXNwb25zZS5zY2hlbWEudHlwZSB8fCByZXNwb25zZS5zY2hlbWEudHlwZSA9PT0gJ29iamVjdCcgfHwgcmVzcG9uc2Uuc2NoZW1hLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIC8vIElubGluZSBtb2RlbFxuICAgICAgdGhpcy5zdWNjZXNzUmVzcG9uc2UgPSB7fTtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMuc3VjY2Vzc1Jlc3BvbnNlW2RlZmF1bHRSZXNwb25zZUNvZGVdID0gbmV3IE1vZGVsKHVuZGVmaW5lZCwgcmVzcG9uc2Uuc2NoZW1hIHx8IHt9LCB0aGlzLm1vZGVscywgcGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFByaW1pdGl2ZVxuICAgICAgdGhpcy5zdWNjZXNzUmVzcG9uc2UgPSB7fTtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMuc3VjY2Vzc1Jlc3BvbnNlW2RlZmF1bHRSZXNwb25zZUNvZGVdID0gcmVzcG9uc2Uuc2NoZW1hO1xuICAgIH1cblxuICAgIGlmIChzdWNjZXNzUmVzcG9uc2UpIHtcbiAgICAgIC8vIEF0dGFjaCByZXNwb25zZSBwcm9wZXJ0aWVzXG4gICAgICBpZiAocmVzcG9uc2UuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgc3VjY2Vzc1Jlc3BvbnNlLmRlc2NyaXB0aW9uID0gcmVzcG9uc2UuZGVzY3JpcHRpb247XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZS5leGFtcGxlcykge1xuICAgICAgICBzdWNjZXNzUmVzcG9uc2UuZXhhbXBsZXMgPSByZXNwb25zZS5leGFtcGxlcztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMpIHtcbiAgICAgICAgc3VjY2Vzc1Jlc3BvbnNlLmhlYWRlcnMgPSByZXNwb25zZS5oZWFkZXJzO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudHlwZSA9IHJlc3BvbnNlO1xuICB9XG5cbiAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgaWYgKHRoaXMucmVzb3VyY2UgJiYgdGhpcy5yZXNvdXJjZS5hcGkgJiYgdGhpcy5yZXNvdXJjZS5hcGkuZmFpbCkge1xuICAgICAgdGhpcy5yZXNvdXJjZS5hcGkuZmFpbChlcnJvcnMpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5pc0RlZmF1bHRBcnJheUl0ZW1WYWx1ZSA9IGZ1bmN0aW9uKHZhbHVlLCBwYXJhbSkge1xuICBpZiAocGFyYW0uZGVmYXVsdCAmJiBBcnJheS5pc0FycmF5KHBhcmFtLmRlZmF1bHQpKSB7XG4gICAgcmV0dXJuIHBhcmFtLmRlZmF1bHQuaW5kZXhPZih2YWx1ZSkgIT09IC0xO1xuICB9XG4gIHJldHVybiB2YWx1ZSA9PT0gcGFyYW0uZGVmYXVsdDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uIChwYXJhbSkge1xuICB2YXIgdHlwZSA9IHBhcmFtLnR5cGU7XG4gIHZhciBmb3JtYXQgPSBwYXJhbS5mb3JtYXQ7XG4gIHZhciBpc0FycmF5ID0gZmFsc2U7XG4gIHZhciBzdHI7XG5cbiAgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQzMicpIHtcbiAgICBzdHIgPSAnaW50ZWdlcic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDY0Jykge1xuICAgIHN0ciA9ICdsb25nJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicpIHtcbiAgICBzdHIgPSAnaW50ZWdlcic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoZm9ybWF0ID09PSAnZGF0ZS10aW1lJykge1xuICAgICAgc3RyID0gJ2RhdGUtdGltZSc7XG4gICAgfSBlbHNlIGlmIChmb3JtYXQgPT09ICdkYXRlJykge1xuICAgICAgc3RyID0gJ2RhdGUnO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSAnc3RyaW5nJztcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSB7XG4gICAgc3RyID0gJ2Zsb2F0JztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdkb3VibGUnKSB7XG4gICAgc3RyID0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgPSAnYm9vbGVhbic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIGlzQXJyYXkgPSB0cnVlO1xuXG4gICAgaWYgKHBhcmFtLml0ZW1zKSB7XG4gICAgICBzdHIgPSB0aGlzLmdldFR5cGUocGFyYW0uaXRlbXMpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlID09PSAnZmlsZScpIHtcbiAgICBzdHIgPSAnZmlsZSc7XG4gIH1cblxuICBpZiAocGFyYW0uJHJlZikge1xuICAgIHN0ciA9IGhlbHBlcnMuc2ltcGxlUmVmKHBhcmFtLiRyZWYpO1xuICB9XG5cbiAgdmFyIHNjaGVtYSA9IHBhcmFtLnNjaGVtYTtcblxuICBpZiAoc2NoZW1hKSB7XG4gICAgdmFyIHJlZiA9IHNjaGVtYS4kcmVmO1xuXG4gICAgaWYgKHJlZikge1xuICAgICAgcmVmID0gaGVscGVycy5zaW1wbGVSZWYocmVmKTtcblxuICAgICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIFsgcmVmIF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gcmVmO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiBpbmxpbmUgc2NoZW1hLCB3ZSBhZGQgaXQgb3VyIGludGVyYWwgaGFzaCAtPiB3aGljaCBnaXZlcyB1cyBpdCdzIElEIChpbnQpXG4gICAgICBpZihzY2hlbWEudHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkSW5saW5lTW9kZWwoc2NoZW1hKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmdldFR5cGUoc2NoZW1hKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzQXJyYXkpIHtcbiAgICByZXR1cm4gWyBzdHIgXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59O1xuXG4vKipcbiAqIGFkZHMgYW4gaW5saW5lIHNjaGVtYSAobW9kZWwpIHRvIGEgaGFzaCwgd2hlcmUgd2UgY2FuIHJlZiBpdCBsYXRlclxuICogQHBhcmFtIHtvYmplY3R9IHNjaGVtYSBhIHNjaGVtYVxuICogQHJldHVybiB7bnVtYmVyfSB0aGUgSUQgb2YgdGhlIHNjaGVtYSBiZWluZyBhZGRlZCwgb3IgbnVsbFxuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5hZGRJbmxpbmVNb2RlbCA9IGZ1bmN0aW9uIChzY2hlbWEpIHtcbiAgdmFyIGxlbiA9IHRoaXMuaW5saW5lTW9kZWxzLmxlbmd0aDtcbiAgdmFyIG1vZGVsID0gdGhpcy5yZXNvbHZlTW9kZWwoc2NoZW1hLCB7fSk7XG4gIGlmKG1vZGVsKSB7XG4gICAgdGhpcy5pbmxpbmVNb2RlbHMucHVzaChtb2RlbCk7XG4gICAgcmV0dXJuICdJbmxpbmUgTW9kZWwgJytsZW47IC8vIHJldHVybiBzdHJpbmcgcmVmIG9mIHRoZSBpbmxpbmUgbW9kZWwgKHVzZWQgd2l0aCAjZ2V0SW5saW5lTW9kZWwpXG4gIH1cbiAgcmV0dXJuIG51bGw7IC8vIHJlcG9ydCBlcnJvcnM/XG59O1xuXG4vKipcbiAqIGdldHMgdGhlIGludGVybmFsIHJlZiB0byBhbiBpbmxpbmUgbW9kZWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbmxpbmVfc3RyIGEgc3RyaW5nIHJlZmVyZW5jZSB0byBhbiBpbmxpbmUgbW9kZWxcbiAqIEByZXR1cm4ge01vZGVsfSB0aGUgbW9kZWwgYmVpbmcgcmVmZXJlbmNlZC4gT3IgbnVsbFxuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRJbmxpbmVNb2RlbCA9IGZ1bmN0aW9uKGlubGluZVN0cikge1xuICBpZigvXklubGluZSBNb2RlbCBcXGQrJC8udGVzdChpbmxpbmVTdHIpKSB7XG4gICAgdmFyIGlkID0gcGFyc2VJbnQoaW5saW5lU3RyLnN1YnN0cignSW5saW5lIE1vZGVsJy5sZW5ndGgpLnRyaW0oKSwxMCk7IC8vXG4gICAgdmFyIG1vZGVsID0gdGhpcy5pbmxpbmVNb2RlbHNbaWRdO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuICAvLyBJJ20gcmV0dXJuaW5nIG51bGwgaGVyZSwgc2hvdWxkIEkgcmF0aGVyIHRocm93IGFuIGVycm9yP1xuICByZXR1cm4gbnVsbDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUucmVzb2x2ZU1vZGVsID0gZnVuY3Rpb24gKHNjaGVtYSwgZGVmaW5pdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiBzY2hlbWEuJHJlZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIgcmVmID0gc2NoZW1hLiRyZWY7XG5cbiAgICBpZiAocmVmLmluZGV4T2YoJyMvZGVmaW5pdGlvbnMvJykgPT09IDApIHtcbiAgICAgIHJlZiA9IHJlZi5zdWJzdHJpbmcoJyMvZGVmaW5pdGlvbnMvJy5sZW5ndGgpO1xuICAgIH1cblxuICAgIGlmIChkZWZpbml0aW9uc1tyZWZdKSB7XG4gICAgICByZXR1cm4gbmV3IE1vZGVsKHJlZiwgZGVmaW5pdGlvbnNbcmVmXSwgdGhpcy5tb2RlbHMsIHRoaXMucGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgfVxuICAvLyBzY2hlbWEgbXVzdCBhdCBsZWFzdCBiZSBhbiBvYmplY3QgdG8gZ2V0IHJlc29sdmVkIHRvIGFuIGlubGluZSBNb2RlbFxuICB9IGVsc2UgaWYgKHNjaGVtYSAmJiB0eXBlb2Ygc2NoZW1hID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgICAgKHNjaGVtYS50eXBlID09PSAnb2JqZWN0JyB8fCBfLmlzVW5kZWZpbmVkKHNjaGVtYS50eXBlKSkpIHtcbiAgICByZXR1cm4gbmV3IE1vZGVsKHVuZGVmaW5lZCwgc2NoZW1hLCB0aGlzLm1vZGVscywgdGhpcy5wYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5oZWxwID0gZnVuY3Rpb24gKGRvbnRQcmludCkge1xuICB2YXIgb3V0ID0gdGhpcy5uaWNrbmFtZSArICc6ICcgKyB0aGlzLnN1bW1hcnkgKyAnXFxuJztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcbiAgICB2YXIgdHlwZUluZm8gPSBwYXJhbS5zaWduYXR1cmU7XG5cbiAgICBvdXQgKz0gJ1xcbiAgKiAnICsgcGFyYW0ubmFtZSArICcgKCcgKyB0eXBlSW5mbyArICcpOiAnICsgcGFyYW0uZGVzY3JpcHRpb247XG4gIH1cblxuICBpZiAodHlwZW9mIGRvbnRQcmludCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBoZWxwZXJzLmxvZyhvdXQpO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0TW9kZWxTaWduYXR1cmUgPSBmdW5jdGlvbiAodHlwZSwgZGVmaW5pdGlvbnMpIHtcbiAgdmFyIGlzUHJpbWl0aXZlLCBsaXN0VHlwZTtcblxuICBpZiAodHlwZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgbGlzdFR5cGUgPSB0cnVlO1xuICAgIHR5cGUgPSB0eXBlWzBdO1xuICB9XG5cbiAgLy8gQ29udmVydCB1bmRlZmluZWQgdG8gc3RyaW5nIG9mICd1bmRlZmluZWQnXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0eXBlID0gJ3VuZGVmaW5lZCc7XG4gICAgaXNQcmltaXRpdmUgPSB0cnVlO1xuXG4gIH0gZWxzZSBpZiAoZGVmaW5pdGlvbnNbdHlwZV0pe1xuICAgIC8vIGEgbW9kZWwgZGVmIGV4aXN0cz9cbiAgICB0eXBlID0gZGVmaW5pdGlvbnNbdHlwZV07IC8qIE1vZGVsICovXG4gICAgaXNQcmltaXRpdmUgPSBmYWxzZTtcblxuICB9IGVsc2UgaWYgKHRoaXMuZ2V0SW5saW5lTW9kZWwodHlwZSkpIHtcbiAgICB0eXBlID0gdGhpcy5nZXRJbmxpbmVNb2RlbCh0eXBlKTsgLyogTW9kZWwgKi9cbiAgICBpc1ByaW1pdGl2ZSA9IGZhbHNlO1xuXG4gIH0gZWxzZSB7XG4gICAgLy8gV2UgZGVmYXVsdCB0byBwcmltaXRpdmVcbiAgICBpc1ByaW1pdGl2ZSA9IHRydWU7XG4gIH1cblxuICBpZiAoaXNQcmltaXRpdmUpIHtcbiAgICBpZiAobGlzdFR5cGUpIHtcbiAgICAgIHJldHVybiAnQXJyYXlbJyArIHR5cGUgKyAnXSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0eXBlLnRvU3RyaW5nKCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChsaXN0VHlwZSkge1xuICAgICAgcmV0dXJuICdBcnJheVsnICsgdHlwZS5nZXRNb2NrU2lnbmF0dXJlKCkgKyAnXSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0eXBlLmdldE1vY2tTaWduYXR1cmUoKTtcbiAgICB9XG4gIH1cbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc3VwcG9ydEhlYWRlclBhcmFtcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRydWU7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLnBhcmVudC5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRIZWFkZXJQYXJhbXMgPSBmdW5jdGlvbiAoYXJncykge1xuICB2YXIgaGVhZGVycyA9IHRoaXMuc2V0Q29udGVudFR5cGVzKGFyZ3MsIHt9KTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmIChwYXJhbS5pbiA9PT0gJ2hlYWRlcicpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJnc1twYXJhbS5uYW1lXTtcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICBoZWFkZXJzW3BhcmFtLm5hbWVdID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGhlYWRlcnM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLnVybGlmeSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gIHZhciBmb3JtUGFyYW1zID0ge307XG4gIHZhciByZXF1ZXN0VXJsID0gdGhpcy5wYXRoLnJlcGxhY2UoLyMuKi8sICcnKTsgLy8gcmVtb3ZlIFVSTCBmcmFnbWVudFxuICB2YXIgcXVlcnlzdHJpbmcgPSAnJzsgLy8gZ3JhYiBwYXJhbXMgZnJvbSB0aGUgYXJncywgYnVpbGQgdGhlIHF1ZXJ5c3RyaW5nIGFsb25nIHRoZSB3YXlcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmIChwYXJhbS5pbiA9PT0gJ3BhdGgnKSB7XG4gICAgICAgIHZhciByZWcgPSBuZXcgUmVnRXhwKCdcXHsnICsgcGFyYW0ubmFtZSArICdcXH0nLCAnZ2knKTtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJnc1twYXJhbS5uYW1lXTtcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICB2YWx1ZSA9IHRoaXMuZW5jb2RlUGF0aENvbGxlY3Rpb24ocGFyYW0uY29sbGVjdGlvbkZvcm1hdCwgcGFyYW0ubmFtZSwgdmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlID0gdGhpcy5lbmNvZGVQYXRoUGFyYW0odmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVxdWVzdFVybCA9IHJlcXVlc3RVcmwucmVwbGFjZShyZWcsIHZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAocGFyYW0uaW4gPT09ICdxdWVyeScgJiYgdHlwZW9mIGFyZ3NbcGFyYW0ubmFtZV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmIChxdWVyeXN0cmluZyA9PT0gJycgJiYgcmVxdWVzdFVybC5pbmRleE9mKCc/JykgPCAwKSB7XG4gICAgICAgICAgcXVlcnlzdHJpbmcgKz0gJz8nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9ICcmJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgcGFyYW0uY29sbGVjdGlvbkZvcm1hdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB2YXIgcXAgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocXApKSB7XG4gICAgICAgICAgICBxdWVyeXN0cmluZyArPSB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBwYXJhbS5uYW1lLCBxcCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW0ubmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0oYXJnc1twYXJhbS5uYW1lXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW0ubmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0oYXJnc1twYXJhbS5uYW1lXSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAocGFyYW0uaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgICAgZm9ybVBhcmFtc1twYXJhbS5uYW1lXSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHZhciB1cmwgPSB0aGlzLnNjaGVtZSArICc6Ly8nICsgdGhpcy5ob3N0O1xuXG4gIGlmICh0aGlzLmJhc2VQYXRoICE9PSAnLycpIHtcbiAgICB1cmwgKz0gdGhpcy5iYXNlUGF0aDtcbiAgfVxuICByZXR1cm4gdXJsICsgcmVxdWVzdFVybCArIHF1ZXJ5c3RyaW5nO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNaXNzaW5nUGFyYW1zID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgdmFyIG1pc3NpbmdQYXJhbXMgPSBbXTsgLy8gY2hlY2sgcmVxdWlyZWQgcGFyYW1zLCB0cmFjayB0aGUgb25lcyB0aGF0IGFyZSBtaXNzaW5nXG4gIHZhciBpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG5cbiAgICBpZiAocGFyYW0ucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgbWlzc2luZ1BhcmFtcyA9IHBhcmFtLm5hbWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1pc3NpbmdQYXJhbXM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldEJvZHkgPSBmdW5jdGlvbiAoaGVhZGVycywgYXJncywgb3B0cykge1xuICB2YXIgZm9ybVBhcmFtcyA9IHt9LCBoYXNGb3JtUGFyYW1zLCBib2R5LCBrZXksIHZhbHVlLCBoYXNCb2R5ID0gZmFsc2U7XG5cbiAgLy8gbG9vayBhdCBlYWNoIHBhcmFtIGFuZCBwdXQgZm9ybSBwYXJhbXMgaW4gYW4gb2JqZWN0XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmIChwYXJhbS5pbiA9PT0gJ2JvZHknKSB7XG4gICAgICAgIGJvZHkgPSBhcmdzW3BhcmFtLm5hbWVdO1xuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgICBmb3JtUGFyYW1zW3BhcmFtLm5hbWVdID0ge1xuICAgICAgICAgIHBhcmFtOiBwYXJhbSxcbiAgICAgICAgICB2YWx1ZTogYXJnc1twYXJhbS5uYW1lXVxuICAgICAgICB9O1xuICAgICAgICBoYXNGb3JtUGFyYW1zID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBpZihwYXJhbS5pbiA9PT0gJ2JvZHknKSB7XG4gICAgICAgIGhhc0JvZHkgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGlmIGJvZHkgaXMgbnVsbCBhbmQgaGFzQm9keSBpcyB0cnVlLCBBTkQgYSBKU09OIGJvZHkgaXMgcmVxdWVzdGVkLCBzZW5kIGVtcHR5IHt9XG4gIGlmKGhhc0JvZHkgJiYgdHlwZW9mIGJvZHkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIGNvbnRlbnRUeXBlID0gaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gICAgaWYoY29udGVudFR5cGUgJiYgY29udGVudFR5cGUuaW5kZXhPZignYXBwbGljYXRpb24vanNvbicpID09PSAwKSB7XG4gICAgICBib2R5ID0gJ3t9JztcbiAgICB9XG4gIH1cblxuICB2YXIgaXNNdWx0aVBhcnQgPSBmYWxzZTtcbiAgaWYoaGVhZGVyc1snQ29udGVudC1UeXBlJ10gJiYgaGVhZGVyc1snQ29udGVudC1UeXBlJ10uaW5kZXhPZignbXVsdGlwYXJ0L2Zvcm0tZGF0YScpID49IDApIHtcbiAgICBpc011bHRpUGFydCA9IHRydWU7XG4gIH1cblxuICAvLyBoYW5kbGUgZm9ybSBwYXJhbXNcbiAgaWYgKGhhc0Zvcm1QYXJhbXMgJiYgIWlzTXVsdGlQYXJ0KSB7XG4gICAgdmFyIGVuY29kZWQgPSAnJztcblxuICAgIGZvciAoa2V5IGluIGZvcm1QYXJhbXMpIHtcbiAgICAgIHZhciBwYXJhbSA9IGZvcm1QYXJhbXNba2V5XS5wYXJhbTtcbiAgICAgIHZhbHVlID0gZm9ybVBhcmFtc1trZXldLnZhbHVlO1xuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICBpZiAoZW5jb2RlZCAhPT0gJycpIHtcbiAgICAgICAgICAgIGVuY29kZWQgKz0gJyYnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbmNvZGVkICs9IHRoaXMuZW5jb2RlUXVlcnlDb2xsZWN0aW9uKHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQsIGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGlmIChlbmNvZGVkICE9PSAnJykge1xuICAgICAgICAgICAgZW5jb2RlZCArPSAnJic7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZW5jb2RlZCArPSBlbmNvZGVVUklDb21wb25lbnQoa2V5KSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBib2R5ID0gZW5jb2RlZDtcbiAgfSBlbHNlIGlmIChpc011bHRpUGFydCkge1xuICAgIGlmICh0eXBlb2YgRm9ybURhdGEgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciBib2R5UGFyYW0gPSBuZXcgRm9ybURhdGEoKTtcblxuICAgICAgYm9keVBhcmFtLnR5cGUgPSAnZm9ybURhdGEnO1xuXG4gICAgICBmb3IgKGtleSBpbiBmb3JtUGFyYW1zKSB7XG4gICAgICAgIHZhbHVlID0gYXJnc1trZXldO1xuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgaWYoe30udG9TdHJpbmcuYXBwbHkodmFsdWUpID09PSAnW29iamVjdCBGaWxlXScpIHtcbiAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLnR5cGUgPT09ICdmaWxlJyAmJiB2YWx1ZS52YWx1ZSkge1xuICAgICAgICAgICAgYm9keVBhcmFtLmFwcGVuZChrZXksIHZhbHVlLnZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBrZXksIHZhbHVlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgYm9keVBhcmFtLmFwcGVuZChrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJvZHkgPSBib2R5UGFyYW07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgYm9keVBhcmFtID0ge307XG4gICAgICBmb3IgKGtleSBpbiBmb3JtUGFyYW1zKSB7XG4gICAgICAgIHZhbHVlID0gYXJnc1trZXldO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICB2YXIgZGVsaW1ldGVyO1xuICAgICAgICAgIHZhciBmb3JtYXQgPSBwYXJhbS5jb2xsZWN0aW9uRm9ybWF0IHx8ICdtdWx0aSc7XG4gICAgICAgICAgaWYoZm9ybWF0ID09PSAnc3N2Jykge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJyAnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKGZvcm1hdCA9PT0gJ3BpcGVzJykge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJ3wnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKGZvcm1hdCA9PT0gJ3RzdicpIHtcbiAgICAgICAgICAgIGRlbGltZXRlciA9ICdcXHQnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlbGltZXRlciA9ICcsJztcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGRhdGE7XG4gICAgICAgICAgdmFsdWUuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICBpZihkYXRhKSB7XG4gICAgICAgICAgICAgIGRhdGEgKz0gZGVsaW1ldGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIGRhdGEgPSAnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRhdGEgKz0gdjtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBib2R5UGFyYW1ba2V5XSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYm9keVBhcmFtW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYm9keSA9IGJvZHlQYXJhbTtcbiAgICB9XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnbXVsdGlwYXJ0L2Zvcm0tZGF0YSc7XG4gIH1cblxuICByZXR1cm4gYm9keTtcbn07XG5cbi8qKlxuICogZ2V0cyBzYW1wbGUgcmVzcG9uc2UgZm9yIGEgc2luZ2xlIG9wZXJhdGlvblxuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNb2RlbFNhbXBsZUpTT04gPSBmdW5jdGlvbiAodHlwZSwgbW9kZWxzKSB7XG4gIHZhciBsaXN0VHlwZSwgc2FtcGxlSnNvbiwgaW5uZXJUeXBlO1xuICBtb2RlbHMgPSBtb2RlbHMgfHwge307XG5cbiAgbGlzdFR5cGUgPSAodHlwZSBpbnN0YW5jZW9mIEFycmF5KTtcbiAgaW5uZXJUeXBlID0gbGlzdFR5cGUgPyB0eXBlWzBdIDogdHlwZTtcblxuICBpZihtb2RlbHNbaW5uZXJUeXBlXSkge1xuICAgIHNhbXBsZUpzb24gPSBtb2RlbHNbaW5uZXJUeXBlXS5jcmVhdGVKU09OU2FtcGxlKCk7XG4gIH0gZWxzZSBpZiAodGhpcy5nZXRJbmxpbmVNb2RlbChpbm5lclR5cGUpKXtcbiAgICBzYW1wbGVKc29uID0gdGhpcy5nZXRJbmxpbmVNb2RlbChpbm5lclR5cGUpLmNyZWF0ZUpTT05TYW1wbGUoKTsgLy8gbWF5IHJldHVybiBudWxsLCBpZiB0eXBlIGlzbid0IGNvcnJlY3RcbiAgfVxuXG5cbiAgaWYgKHNhbXBsZUpzb24pIHtcbiAgICBzYW1wbGVKc29uID0gbGlzdFR5cGUgPyBbc2FtcGxlSnNvbl0gOiBzYW1wbGVKc29uO1xuXG4gICAgaWYgKHR5cGVvZiBzYW1wbGVKc29uID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHNhbXBsZUpzb247XG4gICAgfSBlbHNlIGlmIChfLmlzT2JqZWN0KHNhbXBsZUpzb24pKSB7XG4gICAgICB2YXIgdCA9IHNhbXBsZUpzb247XG5cbiAgICAgIGlmIChzYW1wbGVKc29uIGluc3RhbmNlb2YgQXJyYXkgJiYgc2FtcGxlSnNvbi5sZW5ndGggPiAwKSB7XG4gICAgICAgIHQgPSBzYW1wbGVKc29uWzBdO1xuICAgICAgfVxuXG4gICAgICBpZiAodC5ub2RlTmFtZSAmJiB0eXBlb2YgdCA9PT0gJ05vZGUnKSB7XG4gICAgICAgIHZhciB4bWxTdHJpbmcgPSBuZXcgWE1MU2VyaWFsaXplcigpLnNlcmlhbGl6ZVRvU3RyaW5nKHQpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1hdFhtbCh4bWxTdHJpbmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHNhbXBsZUpzb24sIG51bGwsIDIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogbGVnYWN5IGJpbmRpbmdcbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZG8gPSBmdW5jdGlvbiAoYXJncywgb3B0cywgY2FsbGJhY2ssIGVycm9yLCBwYXJlbnQpIHtcbiAgcmV0dXJuIHRoaXMuZXhlY3V0ZShhcmdzLCBvcHRzLCBjYWxsYmFjaywgZXJyb3IsIHBhcmVudCk7XG59O1xuXG4vKipcbiAqIGV4ZWN1dGVzIGFuIG9wZXJhdGlvblxuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKGFyZzEsIGFyZzIsIGFyZzMsIGFyZzQsIHBhcmVudCkge1xuICB2YXIgYXJncyA9IGFyZzEgfHwge307XG4gIHZhciBvcHRzID0ge30sIHN1Y2Nlc3MsIGVycm9yLCBkZWZlcnJlZDtcblxuICBpZiAoXy5pc09iamVjdChhcmcyKSkge1xuICAgIG9wdHMgPSBhcmcyO1xuICAgIHN1Y2Nlc3MgPSBhcmczO1xuICAgIGVycm9yID0gYXJnNDtcbiAgfVxuXG4gIGlmKHRoaXMuY2xpZW50KSB7XG4gICAgb3B0cy5jbGllbnQgPSB0aGlzLmNsaWVudDtcbiAgfVxuXG4gIC8vIGFkZCB0aGUgcmVxdWVzdCBpbnRlcmNlcHRvciBmcm9tIHBhcmVudCwgaWYgbm9uZSBzZW50IGZyb20gY2xpZW50XG4gIGlmKCFvcHRzLnJlcXVlc3RJbnRlcmNlcHRvciAmJiB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvciApIHtcbiAgICBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvciA9IHRoaXMucmVxdWVzdEludGVyY2VwdG9yIDtcbiAgfVxuXG4gIGlmKCFvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IgJiYgdGhpcy5yZXNwb25zZUludGVyY2VwdG9yKSB7XG4gICAgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yID0gdGhpcy5yZXNwb25zZUludGVyY2VwdG9yO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBhcmcyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgc3VjY2VzcyA9IGFyZzI7XG4gICAgZXJyb3IgPSBhcmczO1xuICB9XG5cbiAgaWYgKHRoaXMucGFyZW50LnVzZVByb21pc2UpIHtcbiAgICBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgfSBlbHNlIHtcbiAgICBzdWNjZXNzID0gKHN1Y2Nlc3MgfHwgdGhpcy5wYXJlbnQuZGVmYXVsdFN1Y2Nlc3NDYWxsYmFjayB8fCBoZWxwZXJzLmxvZyk7XG4gICAgZXJyb3IgPSAoZXJyb3IgfHwgdGhpcy5wYXJlbnQuZGVmYXVsdEVycm9yQ2FsbGJhY2sgfHwgaGVscGVycy5sb2cpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLnVzZUpRdWVyeSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLnVzZUpRdWVyeSA9IHRoaXMudXNlSlF1ZXJ5O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLmpxdWVyeUFqYXhDYWNoZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLmpxdWVyeUFqYXhDYWNoZSA9IHRoaXMuanF1ZXJ5QWpheENhY2hlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLmVuYWJsZUNvb2tpZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0cy5lbmFibGVDb29raWVzID0gdGhpcy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdmFyIG1pc3NpbmdQYXJhbXMgPSB0aGlzLmdldE1pc3NpbmdQYXJhbXMoYXJncyk7XG5cbiAgaWYgKG1pc3NpbmdQYXJhbXMubGVuZ3RoID4gMCkge1xuICAgIHZhciBtZXNzYWdlID0gJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW1zOiAnICsgbWlzc2luZ1BhcmFtcztcblxuICAgIGhlbHBlcnMuZmFpbChtZXNzYWdlKTtcblxuICAgIGlmICh0aGlzLnBhcmVudC51c2VQcm9taXNlKSB7XG4gICAgICBkZWZlcnJlZC5yZWplY3QobWVzc2FnZSk7XG4gICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3IobWVzc2FnZSwgcGFyZW50KTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cblxuICB2YXIgYWxsSGVhZGVycyA9IHRoaXMuZ2V0SGVhZGVyUGFyYW1zKGFyZ3MpO1xuICB2YXIgY29udGVudFR5cGVIZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywgb3B0cyk7XG4gIHZhciBoZWFkZXJzID0ge30sIGF0dHJuYW1lO1xuXG4gIGZvciAoYXR0cm5hbWUgaW4gYWxsSGVhZGVycykgeyBoZWFkZXJzW2F0dHJuYW1lXSA9IGFsbEhlYWRlcnNbYXR0cm5hbWVdOyB9XG4gIGZvciAoYXR0cm5hbWUgaW4gY29udGVudFR5cGVIZWFkZXJzKSB7IGhlYWRlcnNbYXR0cm5hbWVdID0gY29udGVudFR5cGVIZWFkZXJzW2F0dHJuYW1lXTsgfVxuXG4gIHZhciBib2R5ID0gdGhpcy5nZXRCb2R5KGNvbnRlbnRUeXBlSGVhZGVycywgYXJncywgb3B0cyk7XG4gIHZhciB1cmwgPSB0aGlzLnVybGlmeShhcmdzKTtcblxuICBpZih1cmwuaW5kZXhPZignLntmb3JtYXR9JykgPiAwKSB7XG4gICAgaWYoaGVhZGVycykge1xuICAgICAgdmFyIGZvcm1hdCA9IGhlYWRlcnMuQWNjZXB0IHx8IGhlYWRlcnMuYWNjZXB0O1xuICAgICAgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCdqc29uJykgPiAwKSB7XG4gICAgICAgIHVybCA9IHVybC5yZXBsYWNlKCcue2Zvcm1hdH0nLCAnLmpzb24nKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCd4bWwnKSA+IDApIHtcbiAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoJy57Zm9ybWF0fScsICcueG1sJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1cmw6IHVybCxcbiAgICBtZXRob2Q6IHRoaXMubWV0aG9kLnRvVXBwZXJDYXNlKCksXG4gICAgYm9keTogYm9keSxcbiAgICBlbmFibGVDb29raWVzOiBvcHRzLmVuYWJsZUNvb2tpZXMsXG4gICAgdXNlSlF1ZXJ5OiBvcHRzLnVzZUpRdWVyeSxcbiAgICBqcXVlcnlBamF4Q2FjaGU6IG9wdHMuanF1ZXJ5QWpheENhY2hlLFxuICAgIGRlZmVycmVkOiBkZWZlcnJlZCxcbiAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgIGNsaWVudEF1dGhvcml6YXRpb25zOiBvcHRzLmNsaWVudEF1dGhvcml6YXRpb25zLFxuICAgIG9uOiB7XG4gICAgICByZXNwb25zZTogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChkZWZlcnJlZCkge1xuICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBzdWNjZXNzKHJlc3BvbnNlLCBwYXJlbnQpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICBpZiAoZGVmZXJyZWQpIHtcbiAgICAgICAgICBkZWZlcnJlZC5yZWplY3QocmVzcG9uc2UpO1xuICAgICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBlcnJvcihyZXNwb25zZSwgcGFyZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaiwgdGhpcy5vcGVyYXRpb24uc2VjdXJpdHkpO1xuICBpZiAob3B0cy5tb2NrID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IFN3YWdnZXJIdHRwKCkuZXhlY3V0ZShvYmosIG9wdHMpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBpdGVtQnlQcmlvcml0eShjb2wsIGl0ZW1Qcmlvcml0eSkge1xuXG4gIC8vIE5vIHByaW9yaXRpZXM/IHJldHVybiBmaXJzdC4uLlxuICBpZihfLmlzRW1wdHkoaXRlbVByaW9yaXR5KSkge1xuICAgIHJldHVybiBjb2xbMF07XG4gIH1cblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gaXRlbVByaW9yaXR5Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYoY29sLmluZGV4T2YoaXRlbVByaW9yaXR5W2ldKSA+IC0xKSB7XG4gICAgICByZXR1cm4gaXRlbVByaW9yaXR5W2ldO1xuICAgIH1cbiAgfVxuXG4gIC8vIE90aGVyd2lzZSByZXR1cm4gZmlyc3RcbiAgcmV0dXJuIGNvbFswXTtcbn1cblxuT3BlcmF0aW9uLnByb3RvdHlwZS5zZXRDb250ZW50VHlwZXMgPSBmdW5jdGlvbiAoYXJncywgb3B0cykge1xuICAvLyBkZWZhdWx0IHR5cGVcbiAgdmFyIGFsbERlZmluZWRQYXJhbXMgPSB0aGlzLnBhcmFtZXRlcnM7XG4gIHZhciBib2R5O1xuICB2YXIgY29uc3VtZXMgPSBhcmdzLnBhcmFtZXRlckNvbnRlbnRUeXBlIHx8IGl0ZW1CeVByaW9yaXR5KHRoaXMuY29uc3VtZXMsIFsnYXBwbGljYXRpb24vanNvbicsICdhcHBsaWNhdGlvbi95YW1sJ10pO1xuICB2YXIgYWNjZXB0cyA9IG9wdHMucmVzcG9uc2VDb250ZW50VHlwZSB8fCBpdGVtQnlQcmlvcml0eSh0aGlzLnByb2R1Y2VzLCBbJ2FwcGxpY2F0aW9uL2pzb24nLCAnYXBwbGljYXRpb24veWFtbCddKTtcbiAgdmFyIGRlZmluZWRGaWxlUGFyYW1zID0gW107XG4gIHZhciBkZWZpbmVkRm9ybVBhcmFtcyA9IFtdO1xuICB2YXIgaGVhZGVycyA9IHt9O1xuICB2YXIgaTtcblxuICAvLyBnZXQgcGFyYW1zIGZyb20gdGhlIG9wZXJhdGlvbiBhbmQgc2V0IHRoZW0gaW4gZGVmaW5lZEZpbGVQYXJhbXMsIGRlZmluZWRGb3JtUGFyYW1zLCBoZWFkZXJzXG4gIGZvciAoaSA9IDA7IGkgPCBhbGxEZWZpbmVkUGFyYW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gYWxsRGVmaW5lZFBhcmFtc1tpXTtcblxuICAgIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgaWYgKHBhcmFtLnR5cGUgPT09ICdmaWxlJykge1xuICAgICAgICBkZWZpbmVkRmlsZVBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlZmluZWRGb3JtUGFyYW1zLnB1c2gocGFyYW0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocGFyYW0uaW4gPT09ICdoZWFkZXInICYmIG9wdHMpIHtcbiAgICAgIHZhciBrZXkgPSBwYXJhbS5uYW1lO1xuICAgICAgdmFyIGhlYWRlclZhbHVlID0gb3B0c1twYXJhbS5uYW1lXTtcblxuICAgICAgaWYgKHR5cGVvZiBvcHRzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBoZWFkZXJzW2tleV0gPSBoZWFkZXJWYWx1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnYm9keScgJiYgdHlwZW9mIGFyZ3NbcGFyYW0ubmFtZV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBib2R5ID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGVyZSdzIGEgYm9keSwgbmVlZCB0byBzZXQgdGhlIGNvbnN1bWVzIGhlYWRlciB2aWEgcmVxdWVzdENvbnRlbnRUeXBlXG4gIHZhciBoYXNCb2R5ID0gYm9keSB8fCBkZWZpbmVkRmlsZVBhcmFtcy5sZW5ndGggfHwgZGVmaW5lZEZvcm1QYXJhbXMubGVuZ3RoO1xuICBpZiAodGhpcy5tZXRob2QgPT09ICdwb3N0JyB8fCB0aGlzLm1ldGhvZCA9PT0gJ3B1dCcgfHwgdGhpcy5tZXRob2QgPT09ICdwYXRjaCcgfHxcbiAgICAgICgodGhpcy5tZXRob2QgPT09ICdkZWxldGUnIHx8IHRoaXMubWV0aG9kID09PSAnZ2V0JykgJiYgaGFzQm9keSkpIHtcbiAgICBpZiAob3B0cy5yZXF1ZXN0Q29udGVudFR5cGUpIHtcbiAgICAgIGNvbnN1bWVzID0gb3B0cy5yZXF1ZXN0Q29udGVudFR5cGU7XG4gICAgfVxuICAgIC8vIGlmIGFueSBmb3JtIHBhcmFtcywgY29udGVudCB0eXBlIG11c3QgYmUgc2V0XG4gICAgaWYgKGRlZmluZWRGb3JtUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN1bWVzID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKG9wdHMucmVxdWVzdENvbnRlbnRUeXBlKSB7ICAgICAgICAgICAgIC8vIG92ZXJyaWRlIGlmIHNldFxuICAgICAgICBjb25zdW1lcyA9IG9wdHMucmVxdWVzdENvbnRlbnRUeXBlO1xuICAgICAgfSBlbHNlIGlmIChkZWZpbmVkRmlsZVBhcmFtcy5sZW5ndGggPiAwKSB7IC8vIGlmIGEgZmlsZSwgbXVzdCBiZSBtdWx0aXBhcnQvZm9ybS1kYXRhXG4gICAgICAgIGNvbnN1bWVzID0gJ211bHRpcGFydC9mb3JtLWRhdGEnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuY29uc3VtZXMgJiYgdGhpcy5jb25zdW1lcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgLy8gdXNlIHRoZSBjb25zdW1lcyBzZXR0aW5nXG4gICAgICAgICAgZm9yKHZhciBjIGluIHRoaXMuY29uc3VtZXMpIHtcbiAgICAgICAgICAgIHZhciBjaGsgPSB0aGlzLmNvbnN1bWVzW2NdO1xuICAgICAgICAgICAgaWYoY2hrLmluZGV4T2YoJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpID09PSAwIHx8IGNoay5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPT09IDApIHtcbiAgICAgICAgICAgICAgY29uc3VtZXMgPSBjaGs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZih0eXBlb2YgY29uc3VtZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIGRlZmF1bHQgdG8geC13d3ctZnJvbS11cmxlbmNvZGVkXG4gICAgICAgIGNvbnN1bWVzID0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCc7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGNvbnN1bWVzID0gbnVsbDtcbiAgfVxuXG4gIGlmIChjb25zdW1lcyAmJiB0aGlzLmNvbnN1bWVzKSB7XG4gICAgaWYgKHRoaXMuY29uc3VtZXMuaW5kZXhPZihjb25zdW1lcykgPT09IC0xKSB7XG4gICAgICBoZWxwZXJzLmxvZygnc2VydmVyIGRvZXNuXFwndCBjb25zdW1lICcgKyBjb25zdW1lcyArICcsIHRyeSAnICsgSlNPTi5zdHJpbmdpZnkodGhpcy5jb25zdW1lcykpO1xuICAgIH1cbiAgfVxuXG4gIGlmICghdGhpcy5tYXRjaGVzQWNjZXB0KGFjY2VwdHMpKSB7XG4gICAgaGVscGVycy5sb2coJ3NlcnZlciBjYW5cXCd0IHByb2R1Y2UgJyArIGFjY2VwdHMpO1xuICB9XG5cbiAgaWYgKChjb25zdW1lcyAmJiBib2R5ICE9PSAnJykgfHwgKGNvbnN1bWVzID09PSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJykpIHtcbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IGNvbnN1bWVzO1xuICB9XG4gIGVsc2UgaWYodGhpcy5jb25zdW1lcyAmJiB0aGlzLmNvbnN1bWVzLmxlbmd0aCA+IDAgJiYgdGhpcy5jb25zdW1lc1swXSA9PT0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpIHtcbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IHRoaXMuY29uc3VtZXNbMF07XG4gIH1cblxuICBpZiAoYWNjZXB0cykge1xuICAgIGhlYWRlcnMuQWNjZXB0ID0gYWNjZXB0cztcbiAgfVxuXG4gIHJldHVybiBoZWFkZXJzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHJlcXVlc3QgYWNjZXB0cyBoZWFkZXIgbWF0Y2hlcyBhbnl0aGluZyBpbiB0aGlzLnByb2R1Y2VzLlxuICogIElmIHRoaXMucHJvZHVjZXMgY29udGFpbnMgKiAvICosIGlnbm9yZSB0aGUgYWNjZXB0IGhlYWRlci5cbiAqIEBwYXJhbSB7c3RyaW5nPX0gYWNjZXB0cyBUaGUgY2xpZW50IHJlcXVlc3QgYWNjZXB0IGhlYWRlci5cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUubWF0Y2hlc0FjY2VwdCA9IGZ1bmN0aW9uKGFjY2VwdHMpIHtcbiAgLy8gbm8gYWNjZXB0cyBvciBwcm9kdWNlcywgbm8gcHJvYmxlbSFcbiAgaWYgKCFhY2NlcHRzIHx8ICF0aGlzLnByb2R1Y2VzKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIHRoaXMucHJvZHVjZXMuaW5kZXhPZihhY2NlcHRzKSAhPT0gLTEgfHwgdGhpcy5wcm9kdWNlcy5pbmRleE9mKCcqLyonKSAhPT0gLTE7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmFzQ3VybCA9IGZ1bmN0aW9uIChhcmdzMSwgYXJnczIpIHtcbiAgdmFyIG9wdHMgPSB7bW9jazogdHJ1ZX07XG4gIGlmICh0eXBlb2YgYXJnczIgPT09ICdvYmplY3QnKSB7XG4gICAgZm9yICh2YXIgYXJnS2V5IGluIGFyZ3MyKSB7XG4gICAgICBvcHRzW2FyZ0tleV0gPSBhcmdzMlthcmdLZXldO1xuICAgIH1cbiAgfVxuICB2YXIgb2JqID0gdGhpcy5leGVjdXRlKGFyZ3MxLCBvcHRzKTtcblxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaiwgdGhpcy5vcGVyYXRpb24uc2VjdXJpdHkpO1xuXG4gIHZhciByZXN1bHRzID0gW107XG5cbiAgcmVzdWx0cy5wdXNoKCctWCAnICsgdGhpcy5tZXRob2QudG9VcHBlckNhc2UoKSk7XG5cbiAgaWYgKHR5cGVvZiBvYmouaGVhZGVycyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIga2V5O1xuXG4gICAgZm9yIChrZXkgaW4gb2JqLmhlYWRlcnMpIHtcbiAgICAgIHZhciB2YWx1ZSA9IG9iai5oZWFkZXJzW2tleV07XG4gICAgICBpZih0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKXtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXCcvZywgJ1xcXFx1MDAyNycpO1xuICAgICAgfVxuICAgICAgcmVzdWx0cy5wdXNoKCctLWhlYWRlciBcXCcnICsga2V5ICsgJzogJyArIHZhbHVlICsgJ1xcJycpO1xuICAgIH1cbiAgfVxuICB2YXIgaXNGb3JtRGF0YSA9IGZhbHNlO1xuICB2YXIgaXNNdWx0aXBhcnQgPSBmYWxzZTtcblxuICB2YXIgdHlwZSA9IG9iai5oZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgaWYodHlwZSAmJiB0eXBlLmluZGV4T2YoJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpID09PSAwKSB7XG4gICAgaXNGb3JtRGF0YSA9IHRydWU7XG4gIH1cbiAgZWxzZSBpZiAodHlwZSAmJiB0eXBlLmluZGV4T2YoJ211bHRpcGFydC9mb3JtLWRhdGEnKSA9PT0gMCkge1xuICAgIGlzRm9ybURhdGEgPSB0cnVlO1xuICAgIGlzTXVsdGlwYXJ0ID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChvYmouYm9keSkge1xuICAgIHZhciBib2R5O1xuICAgIGlmIChfLmlzT2JqZWN0KG9iai5ib2R5KSkge1xuICAgICAgaWYoaXNNdWx0aXBhcnQpIHtcbiAgICAgICAgaXNNdWx0aXBhcnQgPSB0cnVlO1xuICAgICAgICAvLyBhZGQgdGhlIGZvcm0gZGF0YVxuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIHBhcmFtZXRlciA9IHRoaXMucGFyYW1ldGVyc1tpXTtcbiAgICAgICAgICBpZihwYXJhbWV0ZXIuaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgICAgICAgIGlmICghYm9keSkge1xuICAgICAgICAgICAgICBib2R5ID0gJyc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBwYXJhbVZhbHVlO1xuICAgICAgICAgICAgaWYodHlwZW9mIEZvcm1EYXRhID09PSAnZnVuY3Rpb24nICYmIG9iai5ib2R5IGluc3RhbmNlb2YgRm9ybURhdGEpIHtcbiAgICAgICAgICAgICAgcGFyYW1WYWx1ZSA9IG9iai5ib2R5LmdldChwYXJhbWV0ZXIubmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgcGFyYW1WYWx1ZSA9IG9iai5ib2R5W3BhcmFtZXRlci5uYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYXJhbVZhbHVlKSB7XG4gICAgICAgICAgICAgIGlmIChwYXJhbWV0ZXIudHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAgICAgICAgICAgICAgaWYocGFyYW1WYWx1ZS5uYW1lKSB7XG4gICAgICAgICAgICAgICAgICBib2R5ICs9ICctRiAnICsgcGFyYW1ldGVyLm5hbWUgKyAnPUBcIicgKyBwYXJhbVZhbHVlLm5hbWUgKyAnXCIgJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYm9keSArPSAnLUYgJztcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwYXJhbVZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgYm9keSArPSB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbWV0ZXIuY29sbGVjdGlvbkZvcm1hdCwgcGFyYW1ldGVyLm5hbWUsIHBhcmFtVmFsdWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBib2R5ICs9IHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW1ldGVyLm5hbWUpICsgJz0nICsgcGFyYW1WYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYm9keSArPSAnICc7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYoIWJvZHkpIHtcbiAgICAgICAgYm9keSA9IEpTT04uc3RyaW5naWZ5KG9iai5ib2R5KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYm9keSA9IG9iai5ib2R5O1xuICAgIH1cbiAgICAvLyBlc2NhcGUgQCA9PiAlNDAsICcgPT4gJTI3XG4gICAgYm9keSA9IGJvZHkucmVwbGFjZSgvXFwnL2csICclMjcnKS5yZXBsYWNlKC9cXG4vZywgJyBcXFxcIFxcbiAnKTtcblxuICAgIGlmKCFpc0Zvcm1EYXRhKSB7XG4gICAgICAvLyBlc2NhcGUgJiA9PiAlMjZcbiAgICAgIGJvZHkgPSBib2R5LnJlcGxhY2UoLyYvZywgJyUyNicpO1xuICAgIH1cbiAgICBpZihpc011bHRpcGFydCkge1xuICAgICAgcmVzdWx0cy5wdXNoKGJvZHkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJlc3VsdHMucHVzaCgnLWQgXFwnJyArIGJvZHkucmVwbGFjZSgvQC9nLCAnJTQwJykgKyAnXFwnJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICdjdXJsICcgKyAocmVzdWx0cy5qb2luKCcgJykpICsgJyBcXCcnICsgb2JqLnVybCArICdcXCcnO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVQYXRoQ29sbGVjdGlvbiA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCB2YWx1ZSkge1xuICB2YXIgZW5jb2RlZCA9ICcnO1xuICB2YXIgaTtcbiAgdmFyIHNlcGFyYXRvciA9ICcnO1xuXG4gIGlmICh0eXBlID09PSAnc3N2Jykge1xuICAgIHNlcGFyYXRvciA9ICclMjAnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICd0c3YnKSB7XG4gICAgc2VwYXJhdG9yID0gJyUwOSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3BpcGVzJykge1xuICAgIHNlcGFyYXRvciA9ICd8JztcbiAgfSBlbHNlIHtcbiAgICBzZXBhcmF0b3IgPSAnLCc7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgZW5jb2RlZCA9IHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kZWQgKz0gc2VwYXJhdG9yICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZW5jb2RlZDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUXVlcnlDb2xsZWN0aW9uID0gZnVuY3Rpb24gKHR5cGUsIG5hbWUsIHZhbHVlKSB7XG4gIHZhciBlbmNvZGVkID0gJyc7XG4gIHZhciBpO1xuXG4gIHR5cGUgPSB0eXBlIHx8ICdkZWZhdWx0JztcbiAgaWYgKHR5cGUgPT09ICdkZWZhdWx0JyB8fCB0eXBlID09PSAnbXVsdGknKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoaSA+IDApIHtlbmNvZGVkICs9ICcmJzt9XG5cbiAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShuYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBzZXBhcmF0b3IgPSAnJztcblxuICAgIGlmICh0eXBlID09PSAnY3N2Jykge1xuICAgICAgc2VwYXJhdG9yID0gJywnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3NzdicpIHtcbiAgICAgIHNlcGFyYXRvciA9ICclMjAnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3RzdicpIHtcbiAgICAgIHNlcGFyYXRvciA9ICclMDknO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3BpcGVzJykge1xuICAgICAgc2VwYXJhdG9yID0gJ3wnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2JyYWNrZXRzJykge1xuICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpICE9PSAwKSB7XG4gICAgICAgICAgZW5jb2RlZCArPSAnJic7XG4gICAgICAgIH1cblxuICAgICAgICBlbmNvZGVkICs9IHRoaXMuZW5jb2RlUXVlcnlLZXkobmFtZSkgKyAnW109JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNlcGFyYXRvciAhPT0gJycpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgIGVuY29kZWQgPSB0aGlzLmVuY29kZVF1ZXJ5S2V5KG5hbWUpICsgJz0nICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbmNvZGVkICs9IHNlcGFyYXRvciArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZW5jb2RlZDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUXVlcnlLZXkgPSBmdW5jdGlvbiAoYXJnKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoYXJnKVxuICAgICAgLnJlcGxhY2UoJyU1QicsJ1snKS5yZXBsYWNlKCclNUQnLCAnXScpLnJlcGxhY2UoJyUyNCcsICckJyk7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmVuY29kZVF1ZXJ5UGFyYW0gPSBmdW5jdGlvbiAoYXJnKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoYXJnKTtcbn07XG5cbi8qKlxuICogVE9ETyByZXZpc2l0LCBtaWdodCBub3Qgd2FudCB0byBsZWF2ZSAnLydcbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUGF0aFBhcmFtID0gZnVuY3Rpb24gKHBhdGhQYXJhbSkge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHBhdGhQYXJhbSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgT3BlcmF0aW9uR3JvdXAgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YWcsIGRlc2NyaXB0aW9uLCBleHRlcm5hbERvY3MsIG9wZXJhdGlvbikge1xuICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247XG4gIHRoaXMuZXh0ZXJuYWxEb2NzID0gZXh0ZXJuYWxEb2NzO1xuICB0aGlzLm5hbWUgPSB0YWc7XG4gIHRoaXMub3BlcmF0aW9uID0gb3BlcmF0aW9uO1xuICB0aGlzLm9wZXJhdGlvbnNBcnJheSA9IFtdO1xuICB0aGlzLnBhdGggPSB0YWc7XG4gIHRoaXMudGFnID0gdGFnO1xufTtcblxuT3BlcmF0aW9uR3JvdXAucHJvdG90eXBlLnNvcnQgPSBmdW5jdGlvbiAoKSB7XG5cbn07XG5cbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gdHJ1ZTtcbiAgICB2YXIgY3VycmVudFF1ZXVlO1xuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgICAgICAgICBjdXJyZW50UXVldWVbaV0oKTtcbiAgICAgICAgfVxuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG59XG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHF1ZXVlLnB1c2goZnVuKTtcbiAgICBpZiAoIWRyYWluaW5nKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZHJhaW5RdWV1ZSwgMCk7XG4gICAgfVxufTtcblxucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCIoZnVuY3Rpb24gKEJ1ZmZlcil7XG4oZnVuY3Rpb24gKCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBmdW5jdGlvbiBidG9hKHN0cikge1xuICAgIHZhciBidWZmZXJcbiAgICAgIDtcblxuICAgIGlmIChzdHIgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIGJ1ZmZlciA9IHN0cjtcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmZmVyID0gbmV3IEJ1ZmZlcihzdHIudG9TdHJpbmcoKSwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICB9XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBidG9hO1xufSgpKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OWlkRzloTDJsdVpHVjRMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpS0daMWJtTjBhVzl1SUNncElIdGNiaUFnWENKMWMyVWdjM1J5YVdOMFhDSTdYRzVjYmlBZ1puVnVZM1JwYjI0Z1luUnZZU2h6ZEhJcElIdGNiaUFnSUNCMllYSWdZblZtWm1WeVhHNGdJQ0FnSUNBN1hHNWNiaUFnSUNCcFppQW9jM1J5SUdsdWMzUmhibU5sYjJZZ1FuVm1abVZ5S1NCN1hHNGdJQ0FnSUNCaWRXWm1aWElnUFNCemRISTdYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUdKMVptWmxjaUE5SUc1bGR5QkNkV1ptWlhJb2MzUnlMblJ2VTNSeWFXNW5LQ2tzSUNkaWFXNWhjbmtuS1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0J5WlhSMWNtNGdZblZtWm1WeUxuUnZVM1J5YVc1bktDZGlZWE5sTmpRbktUdGNiaUFnZlZ4dVhHNGdJRzF2WkhWc1pTNWxlSEJ2Y25SeklEMGdZblJ2WVR0Y2JuMG9LU2s3WEc0aVhYMD0iLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXMtYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxudmFyIHJvb3RQYXJlbnQgPSB7fVxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIFNhZmFyaSA1LTcgbGFja3Mgc3VwcG9ydCBmb3IgY2hhbmdpbmcgdGhlIGBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yYCBwcm9wZXJ0eVxuICogICAgIG9uIG9iamVjdHMuXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IChmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEJhciAoKSB7fVxuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5mb28gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gICAgYXJyLmNvbnN0cnVjdG9yID0gQmFyXG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgYXJyLmNvbnN0cnVjdG9yID09PSBCYXIgJiYgLy8gY29uc3RydWN0b3IgY2FuIGJlIHNldFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn0pKClcblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG4vKipcbiAqIENsYXNzOiBCdWZmZXJcbiAqID09PT09PT09PT09PT1cbiAqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGFyZSBhdWdtZW50ZWRcbiAqIHdpdGggZnVuY3Rpb24gcHJvcGVydGllcyBmb3IgYWxsIHRoZSBub2RlIGBCdWZmZXJgIEFQSSBmdW5jdGlvbnMuIFdlIHVzZVxuICogYFVpbnQ4QXJyYXlgIHNvIHRoYXQgc3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXQgcmV0dXJuc1xuICogYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogQnkgYXVnbWVudGluZyB0aGUgaW5zdGFuY2VzLCB3ZSBjYW4gYXZvaWQgbW9kaWZ5aW5nIHRoZSBgVWludDhBcnJheWBcbiAqIHByb3RvdHlwZS5cbiAqL1xuZnVuY3Rpb24gQnVmZmVyIChhcmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICAvLyBBdm9pZCBnb2luZyB0aHJvdWdoIGFuIEFyZ3VtZW50c0FkYXB0b3JUcmFtcG9saW5lIGluIHRoZSBjb21tb24gY2FzZS5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHJldHVybiBuZXcgQnVmZmVyKGFyZywgYXJndW1lbnRzWzFdKVxuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZylcbiAgfVxuXG4gIHRoaXMubGVuZ3RoID0gMFxuICB0aGlzLnBhcmVudCA9IHVuZGVmaW5lZFxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLCBhcmcpXG4gIH1cblxuICAvLyBTbGlnaHRseSBsZXNzIGNvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGlzLCBhcmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogJ3V0ZjgnKVxuICB9XG5cbiAgLy8gVW51c3VhbC5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhpcywgYXJnKVxufVxuXG5mdW5jdGlvbiBmcm9tTnVtYmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChsZW5ndGgpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIC8vIEFzc3VtcHRpb246IGJ5dGVMZW5ndGgoKSByZXR1cm4gdmFsdWUgaXMgYWx3YXlzIDwga01heExlbmd0aC5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG5cbiAgdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpKSByZXR1cm4gZnJvbUJ1ZmZlcih0aGF0LCBvYmplY3QpXG5cbiAgaWYgKGlzQXJyYXkob2JqZWN0KSkgcmV0dXJuIGZyb21BcnJheSh0aGF0LCBvYmplY3QpXG5cbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbXVzdCBzdGFydCB3aXRoIG51bWJlciwgYnVmZmVyLCBhcnJheSBvciBzdHJpbmcnKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAob2JqZWN0LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICByZXR1cm4gZnJvbVR5cGVkQXJyYXkodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgfVxuXG4gIGlmIChvYmplY3QubGVuZ3RoKSByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmplY3QpXG5cbiAgcmV0dXJuIGZyb21Kc29uT2JqZWN0KHRoYXQsIG9iamVjdClcbn1cblxuZnVuY3Rpb24gZnJvbUJ1ZmZlciAodGhhdCwgYnVmZmVyKSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGJ1ZmZlci5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBidWZmZXIuY29weSh0aGF0LCAwLCAwLCBsZW5ndGgpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIER1cGxpY2F0ZSBvZiBmcm9tQXJyYXkoKSB0byBrZWVwIGZyb21BcnJheSgpIG1vbm9tb3JwaGljLlxuZnVuY3Rpb24gZnJvbVR5cGVkQXJyYXkgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIC8vIFRydW5jYXRpbmcgdGhlIGVsZW1lbnRzIGlzIHByb2JhYmx5IG5vdCB3aGF0IHBlb3BsZSBleHBlY3QgZnJvbSB0eXBlZFxuICAvLyBhcnJheXMgd2l0aCBCWVRFU19QRVJfRUxFTUVOVCA+IDEgYnV0IGl0J3MgY29tcGF0aWJsZSB3aXRoIHRoZSBiZWhhdmlvclxuICAvLyBvZiB0aGUgb2xkIEJ1ZmZlciBjb25zdHJ1Y3Rvci5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXkpIHtcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgYXJyYXkuYnl0ZUxlbmd0aFxuICAgIHRoYXQgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbVR5cGVkQXJyYXkodGhhdCwgbmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vLyBEZXNlcmlhbGl6ZSB7IHR5cGU6ICdCdWZmZXInLCBkYXRhOiBbMSwyLDMsLi4uXSB9IGludG8gYSBCdWZmZXIgb2JqZWN0LlxuLy8gUmV0dXJucyBhIHplcm8tbGVuZ3RoIGJ1ZmZlciBmb3IgaW5wdXRzIHRoYXQgZG9uJ3QgY29uZm9ybSB0byB0aGUgc3BlYy5cbmZ1bmN0aW9uIGZyb21Kc29uT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgdmFyIGFycmF5XG4gIHZhciBsZW5ndGggPSAwXG5cbiAgaWYgKG9iamVjdC50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iamVjdC5kYXRhKSkge1xuICAgIGFycmF5ID0gb2JqZWN0LmRhdGFcbiAgICBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIH1cbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gYWxsb2NhdGUgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gQnVmZmVyLl9hdWdtZW50KG5ldyBVaW50OEFycmF5KGxlbmd0aCkpXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gICAgdGhhdC5faXNCdWZmZXIgPSB0cnVlXG4gIH1cblxuICB2YXIgZnJvbVBvb2wgPSBsZW5ndGggIT09IDAgJiYgbGVuZ3RoIDw9IEJ1ZmZlci5wb29sU2l6ZSA+Pj4gMVxuICBpZiAoZnJvbVBvb2wpIHRoYXQucGFyZW50ID0gcm9vdFBhcmVudFxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IGtNYXhMZW5ndGgoKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAoc3ViamVjdCwgZW5jb2RpbmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNsb3dCdWZmZXIpKSByZXR1cm4gbmV3IFNsb3dCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG4gIGRlbGV0ZSBidWYucGFyZW50XG4gIHJldHVybiBidWZcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIHZhciBpID0gMFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkgYnJlYWtcblxuICAgICsraVxuICB9XG5cbiAgaWYgKGkgIT09IGxlbikge1xuICAgIHggPSBhW2ldXG4gICAgeSA9IGJbaV1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAncmF3JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdCBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMuJylcblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcigwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGl0ZW0gPSBsaXN0W2ldXG4gICAgaXRlbS5jb3B5KGJ1ZiwgcG9zKVxuICAgIHBvcyArPSBpdGVtLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHN0cmluZyA9ICcnICsgc3RyaW5nXG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAvLyBEZXByZWNhdGVkXG4gICAgICBjYXNlICdyYXcnOlxuICAgICAgY2FzZSAncmF3cyc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG4vLyBwcmUtc2V0IGZvciB2YWx1ZXMgdGhhdCBtYXkgZXhpc3QgaW4gdGhlIGZ1dHVyZVxuQnVmZmVyLnByb3RvdHlwZS5sZW5ndGggPSB1bmRlZmluZWRcbkJ1ZmZlci5wcm90b3R5cGUucGFyZW50ID0gdW5kZWZpbmVkXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICBzdGFydCA9IHN0YXJ0IHwgMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPT09IEluZmluaXR5ID8gdGhpcy5sZW5ndGggOiBlbmQgfCAwXG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcbiAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKGVuZCA8PSBzdGFydCkgcmV0dXJuICcnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiAwXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICBieXRlT2Zmc2V0ID4+PSAwXG5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gdGhpcy5sZW5ndGgpIHJldHVybiAtMVxuXG4gIC8vIE5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy5sZW5ndGggKyBieXRlT2Zmc2V0LCAwKVxuXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSByZXR1cm4gLTEgLy8gc3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcgYWx3YXlzIGZhaWxzXG4gICAgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbCh0aGlzLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgWyB2YWwgXSwgYnl0ZU9mZnNldClcbiAgfVxuXG4gIGZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yICh2YXIgaSA9IDA7IGJ5dGVPZmZzZXQgKyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJyW2J5dGVPZmZzZXQgKyBpXSA9PT0gdmFsW2ZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4XSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbC5sZW5ndGgpIHJldHVybiBieXRlT2Zmc2V0ICsgZm91bmRJbmRleFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuLy8gYGdldGAgaXMgZGVwcmVjYXRlZFxuQnVmZmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQgKG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLmdldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMucmVhZFVJbnQ4KG9mZnNldClcbn1cblxuLy8gYHNldGAgaXMgZGVwcmVjYXRlZFxuQnVmZmVyLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiBzZXQgKHYsIG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLnNldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMud3JpdGVVSW50OCh2LCBvZmZzZXQpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmluYXJ5V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggfCAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgLy8gbGVnYWN5IHdyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKSAtIHJlbW92ZSBpbiB2MC4xM1xuICB9IGVsc2Uge1xuICAgIHZhciBzd2FwID0gZW5jb2RpbmdcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIG9mZnNldCA9IGxlbmd0aCB8IDBcbiAgICBsZW5ndGggPSBzd2FwXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignYXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGJpbmFyeVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gYmluYXJ5U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IEJ1ZmZlci5fYXVnbWVudCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpKVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47IGkrKykge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgaWYgKG5ld0J1Zi5sZW5ndGgpIG5ld0J1Zi5wYXJlbnQgPSB0aGlzLnBhcmVudCB8fCB0aGlzXG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdidWZmZXIgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gdmFsdWUgPCAwID8gMSA6IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCd2YWx1ZSBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdpbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0Ll9zZXQodGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLCB0YXJnZXRTdGFydClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gZmlsbCh2YWx1ZSwgc3RhcnQ9MCwgZW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXZhbHVlKSB2YWx1ZSA9IDBcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kKSBlbmQgPSB0aGlzLmxlbmd0aFxuXG4gIGlmIChlbmQgPCBzdGFydCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCA8IHN0YXJ0JylcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDAgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdlbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gdmFsdWVcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gdXRmOFRvQnl0ZXModmFsdWUudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGBBcnJheUJ1ZmZlcmAgd2l0aCB0aGUgKmNvcGllZCogbWVtb3J5IG9mIHRoZSBidWZmZXIgaW5zdGFuY2UuXG4gKiBBZGRlZCBpbiBOb2RlIDAuMTIuIE9ubHkgYXZhaWxhYmxlIGluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBBcnJheUJ1ZmZlci5cbiAqL1xuQnVmZmVyLnByb3RvdHlwZS50b0FycmF5QnVmZmVyID0gZnVuY3Rpb24gdG9BcnJheUJ1ZmZlciAoKSB7XG4gIGlmICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAgIHJldHVybiAobmV3IEJ1ZmZlcih0aGlzKSkuYnVmZmVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheSh0aGlzLmxlbmd0aClcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBidWYubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgYnVmW2ldID0gdGhpc1tpXVxuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1Zi5idWZmZXJcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQnVmZmVyLnRvQXJyYXlCdWZmZXIgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKVxuICB9XG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIEJQID0gQnVmZmVyLnByb3RvdHlwZVxuXG4vKipcbiAqIEF1Z21lbnQgYSBVaW50OEFycmF5ICppbnN0YW5jZSogKG5vdCB0aGUgVWludDhBcnJheSBjbGFzcyEpIHdpdGggQnVmZmVyIG1ldGhvZHNcbiAqL1xuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gX2F1Z21lbnQgKGFycikge1xuICBhcnIuY29uc3RydWN0b3IgPSBCdWZmZXJcbiAgYXJyLl9pc0J1ZmZlciA9IHRydWVcblxuICAvLyBzYXZlIHJlZmVyZW5jZSB0byBvcmlnaW5hbCBVaW50OEFycmF5IHNldCBtZXRob2QgYmVmb3JlIG92ZXJ3cml0aW5nXG4gIGFyci5fc2V0ID0gYXJyLnNldFxuXG4gIC8vIGRlcHJlY2F0ZWRcbiAgYXJyLmdldCA9IEJQLmdldFxuICBhcnIuc2V0ID0gQlAuc2V0XG5cbiAgYXJyLndyaXRlID0gQlAud3JpdGVcbiAgYXJyLnRvU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvTG9jYWxlU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvSlNPTiA9IEJQLnRvSlNPTlxuICBhcnIuZXF1YWxzID0gQlAuZXF1YWxzXG4gIGFyci5jb21wYXJlID0gQlAuY29tcGFyZVxuICBhcnIuaW5kZXhPZiA9IEJQLmluZGV4T2ZcbiAgYXJyLmNvcHkgPSBCUC5jb3B5XG4gIGFyci5zbGljZSA9IEJQLnNsaWNlXG4gIGFyci5yZWFkVUludExFID0gQlAucmVhZFVJbnRMRVxuICBhcnIucmVhZFVJbnRCRSA9IEJQLnJlYWRVSW50QkVcbiAgYXJyLnJlYWRVSW50OCA9IEJQLnJlYWRVSW50OFxuICBhcnIucmVhZFVJbnQxNkxFID0gQlAucmVhZFVJbnQxNkxFXG4gIGFyci5yZWFkVUludDE2QkUgPSBCUC5yZWFkVUludDE2QkVcbiAgYXJyLnJlYWRVSW50MzJMRSA9IEJQLnJlYWRVSW50MzJMRVxuICBhcnIucmVhZFVJbnQzMkJFID0gQlAucmVhZFVJbnQzMkJFXG4gIGFyci5yZWFkSW50TEUgPSBCUC5yZWFkSW50TEVcbiAgYXJyLnJlYWRJbnRCRSA9IEJQLnJlYWRJbnRCRVxuICBhcnIucmVhZEludDggPSBCUC5yZWFkSW50OFxuICBhcnIucmVhZEludDE2TEUgPSBCUC5yZWFkSW50MTZMRVxuICBhcnIucmVhZEludDE2QkUgPSBCUC5yZWFkSW50MTZCRVxuICBhcnIucmVhZEludDMyTEUgPSBCUC5yZWFkSW50MzJMRVxuICBhcnIucmVhZEludDMyQkUgPSBCUC5yZWFkSW50MzJCRVxuICBhcnIucmVhZEZsb2F0TEUgPSBCUC5yZWFkRmxvYXRMRVxuICBhcnIucmVhZEZsb2F0QkUgPSBCUC5yZWFkRmxvYXRCRVxuICBhcnIucmVhZERvdWJsZUxFID0gQlAucmVhZERvdWJsZUxFXG4gIGFyci5yZWFkRG91YmxlQkUgPSBCUC5yZWFkRG91YmxlQkVcbiAgYXJyLndyaXRlVUludDggPSBCUC53cml0ZVVJbnQ4XG4gIGFyci53cml0ZVVJbnRMRSA9IEJQLndyaXRlVUludExFXG4gIGFyci53cml0ZVVJbnRCRSA9IEJQLndyaXRlVUludEJFXG4gIGFyci53cml0ZVVJbnQxNkxFID0gQlAud3JpdGVVSW50MTZMRVxuICBhcnIud3JpdGVVSW50MTZCRSA9IEJQLndyaXRlVUludDE2QkVcbiAgYXJyLndyaXRlVUludDMyTEUgPSBCUC53cml0ZVVJbnQzMkxFXG4gIGFyci53cml0ZVVJbnQzMkJFID0gQlAud3JpdGVVSW50MzJCRVxuICBhcnIud3JpdGVJbnRMRSA9IEJQLndyaXRlSW50TEVcbiAgYXJyLndyaXRlSW50QkUgPSBCUC53cml0ZUludEJFXG4gIGFyci53cml0ZUludDggPSBCUC53cml0ZUludDhcbiAgYXJyLndyaXRlSW50MTZMRSA9IEJQLndyaXRlSW50MTZMRVxuICBhcnIud3JpdGVJbnQxNkJFID0gQlAud3JpdGVJbnQxNkJFXG4gIGFyci53cml0ZUludDMyTEUgPSBCUC53cml0ZUludDMyTEVcbiAgYXJyLndyaXRlSW50MzJCRSA9IEJQLndyaXRlSW50MzJCRVxuICBhcnIud3JpdGVGbG9hdExFID0gQlAud3JpdGVGbG9hdExFXG4gIGFyci53cml0ZUZsb2F0QkUgPSBCUC53cml0ZUZsb2F0QkVcbiAgYXJyLndyaXRlRG91YmxlTEUgPSBCUC53cml0ZURvdWJsZUxFXG4gIGFyci53cml0ZURvdWJsZUJFID0gQlAud3JpdGVEb3VibGVCRVxuICBhcnIuZmlsbCA9IEJQLmZpbGxcbiAgYXJyLmluc3BlY3QgPSBCUC5pbnNwZWN0XG4gIGFyci50b0FycmF5QnVmZmVyID0gQlAudG9BcnJheUJ1ZmZlclxuXG4gIHJldHVybiBhcnJcbn1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gbGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCB8IDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuIiwidmFyIGxvb2t1cCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQndXNlIHN0cmljdCc7XG5cbiAgdmFyIEFyciA9ICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpXG4gICAgPyBVaW50OEFycmF5XG4gICAgOiBBcnJheVxuXG5cdHZhciBQTFVTICAgPSAnKycuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0ggID0gJy8nLmNoYXJDb2RlQXQoMClcblx0dmFyIE5VTUJFUiA9ICcwJy5jaGFyQ29kZUF0KDApXG5cdHZhciBMT1dFUiAgPSAnYScuY2hhckNvZGVBdCgwKVxuXHR2YXIgVVBQRVIgID0gJ0EnLmNoYXJDb2RlQXQoMClcblx0dmFyIFBMVVNfVVJMX1NBRkUgPSAnLScuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0hfVVJMX1NBRkUgPSAnXycuY2hhckNvZGVBdCgwKVxuXG5cdGZ1bmN0aW9uIGRlY29kZSAoZWx0KSB7XG5cdFx0dmFyIGNvZGUgPSBlbHQuY2hhckNvZGVBdCgwKVxuXHRcdGlmIChjb2RlID09PSBQTFVTIHx8XG5cdFx0ICAgIGNvZGUgPT09IFBMVVNfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjIgLy8gJysnXG5cdFx0aWYgKGNvZGUgPT09IFNMQVNIIHx8XG5cdFx0ICAgIGNvZGUgPT09IFNMQVNIX1VSTF9TQUZFKVxuXHRcdFx0cmV0dXJuIDYzIC8vICcvJ1xuXHRcdGlmIChjb2RlIDwgTlVNQkVSKVxuXHRcdFx0cmV0dXJuIC0xIC8vbm8gbWF0Y2hcblx0XHRpZiAoY29kZSA8IE5VTUJFUiArIDEwKVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBOVU1CRVIgKyAyNiArIDI2XG5cdFx0aWYgKGNvZGUgPCBVUFBFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBVUFBFUlxuXHRcdGlmIChjb2RlIDwgTE9XRVIgKyAyNilcblx0XHRcdHJldHVybiBjb2RlIC0gTE9XRVIgKyAyNlxuXHR9XG5cblx0ZnVuY3Rpb24gYjY0VG9CeXRlQXJyYXkgKGI2NCkge1xuXHRcdHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG5cblx0XHRpZiAoYjY0Lmxlbmd0aCAlIDQgPiAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuXHRcdH1cblxuXHRcdC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuXHRcdC8vIHJlcHJlc2VudCBvbmUgYnl0ZVxuXHRcdC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuXHRcdC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2Vcblx0XHR2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXHRcdHBsYWNlSG9sZGVycyA9ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAyKSA/IDIgOiAnPScgPT09IGI2NC5jaGFyQXQobGVuIC0gMSkgPyAxIDogMFxuXG5cdFx0Ly8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5cdFx0YXJyID0gbmV3IEFycihiNjQubGVuZ3RoICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpXG5cblx0XHQvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG5cdFx0bCA9IHBsYWNlSG9sZGVycyA+IDAgPyBiNjQubGVuZ3RoIC0gNCA6IGI2NC5sZW5ndGhcblxuXHRcdHZhciBMID0gMFxuXG5cdFx0ZnVuY3Rpb24gcHVzaCAodikge1xuXHRcdFx0YXJyW0wrK10gPSB2XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxOCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCAxMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA8PCA2KSB8IGRlY29kZShiNjQuY2hhckF0KGkgKyAzKSlcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMDAwKSA+PiAxNilcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMCkgPj4gOClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9XG5cblx0XHRpZiAocGxhY2VIb2xkZXJzID09PSAyKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPj4gNClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxMCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCA0KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpID4+IDIpXG5cdFx0XHRwdXNoKCh0bXAgPj4gOCkgJiAweEZGKVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdHJldHVybiBhcnJcblx0fVxuXG5cdGZ1bmN0aW9uIHVpbnQ4VG9CYXNlNjQgKHVpbnQ4KSB7XG5cdFx0dmFyIGksXG5cdFx0XHRleHRyYUJ5dGVzID0gdWludDgubGVuZ3RoICUgMywgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcblx0XHRcdG91dHB1dCA9IFwiXCIsXG5cdFx0XHR0ZW1wLCBsZW5ndGhcblxuXHRcdGZ1bmN0aW9uIGVuY29kZSAobnVtKSB7XG5cdFx0XHRyZXR1cm4gbG9va3VwLmNoYXJBdChudW0pXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcblx0XHRcdHJldHVybiBlbmNvZGUobnVtID4+IDE4ICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDEyICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDYgJiAweDNGKSArIGVuY29kZShudW0gJiAweDNGKVxuXHRcdH1cblxuXHRcdC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcblx0XHRmb3IgKGkgPSAwLCBsZW5ndGggPSB1aW50OC5sZW5ndGggLSBleHRyYUJ5dGVzOyBpIDwgbGVuZ3RoOyBpICs9IDMpIHtcblx0XHRcdHRlbXAgPSAodWludDhbaV0gPDwgMTYpICsgKHVpbnQ4W2kgKyAxXSA8PCA4KSArICh1aW50OFtpICsgMl0pXG5cdFx0XHRvdXRwdXQgKz0gdHJpcGxldFRvQmFzZTY0KHRlbXApXG5cdFx0fVxuXG5cdFx0Ly8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuXHRcdHN3aXRjaCAoZXh0cmFCeXRlcykge1xuXHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHR0ZW1wID0gdWludDhbdWludDgubGVuZ3RoIC0gMV1cblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDIpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz09J1xuXHRcdFx0XHRicmVha1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHR0ZW1wID0gKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDJdIDw8IDgpICsgKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMTApXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPj4gNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDIpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9ICc9J1xuXHRcdFx0XHRicmVha1xuXHRcdH1cblxuXHRcdHJldHVybiBvdXRwdXRcblx0fVxuXG5cdGV4cG9ydHMudG9CeXRlQXJyYXkgPSBiNjRUb0J5dGVBcnJheVxuXHRleHBvcnRzLmZyb21CeXRlQXJyYXkgPSB1aW50OFRvQmFzZTY0XG59KHR5cGVvZiBleHBvcnRzID09PSAndW5kZWZpbmVkJyA/ICh0aGlzLmJhc2U2NGpzID0ge30pIDogZXhwb3J0cykpXG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsIlxuLyoqXG4gKiBpc0FycmF5XG4gKi9cblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG4vKipcbiAqIHRvU3RyaW5nXG4gKi9cblxudmFyIHN0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKlxuICogV2hldGhlciBvciBub3QgdGhlIGdpdmVuIGB2YWxgXG4gKiBpcyBhbiBhcnJheS5cbiAqXG4gKiBleGFtcGxlOlxuICpcbiAqICAgICAgICBpc0FycmF5KFtdKTtcbiAqICAgICAgICAvLyA+IHRydWVcbiAqICAgICAgICBpc0FycmF5KGFyZ3VtZW50cyk7XG4gKiAgICAgICAgLy8gPiBmYWxzZVxuICogICAgICAgIGlzQXJyYXkoJycpO1xuICogICAgICAgIC8vID4gZmFsc2VcbiAqXG4gKiBAcGFyYW0ge21peGVkfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2x9XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5IHx8IGZ1bmN0aW9uICh2YWwpIHtcbiAgcmV0dXJuICEhIHZhbCAmJiAnW29iamVjdCBBcnJheV0nID09IHN0ci5jYWxsKHZhbCk7XG59O1xuIiwiLyoganNoaW50IG5vZGU6IHRydWUgKi9cbihmdW5jdGlvbiAoKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBmdW5jdGlvbiBDb29raWVBY2Nlc3NJbmZvKGRvbWFpbiwgcGF0aCwgc2VjdXJlLCBzY3JpcHQpIHtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWVBY2Nlc3NJbmZvKSB7XG4gICAgICAgICAgICB0aGlzLmRvbWFpbiA9IGRvbWFpbiB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBwYXRoIHx8IFwiL1wiO1xuICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSAhIXNlY3VyZTtcbiAgICAgICAgICAgIHRoaXMuc2NyaXB0ID0gISFzY3JpcHQ7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUFjY2Vzc0luZm8oZG9tYWluLCBwYXRoLCBzZWN1cmUsIHNjcmlwdCk7XG4gICAgfVxuICAgIGV4cG9ydHMuQ29va2llQWNjZXNzSW5mbyA9IENvb2tpZUFjY2Vzc0luZm87XG5cbiAgICBmdW5jdGlvbiBDb29raWUoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGlmIChjb29raWVzdHIgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHJldHVybiBjb29raWVzdHI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuZXhwaXJhdGlvbl9kYXRlID0gSW5maW5pdHk7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBTdHJpbmcocmVxdWVzdF9wYXRoIHx8IFwiL1wiKTtcbiAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfcGF0aCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5kb21haW4gPSByZXF1ZXN0X2RvbWFpbiB8fCBudWxsO1xuICAgICAgICAgICAgdGhpcy5leHBsaWNpdF9kb21haW4gPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2VjdXJlID0gZmFsc2U7IC8vaG93IHRvIGRlZmluZSBkZWZhdWx0P1xuICAgICAgICAgICAgdGhpcy5ub3NjcmlwdCA9IGZhbHNlOyAvL2h0dHBvbmx5XG4gICAgICAgICAgICBpZiAoY29va2llc3RyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wYXJzZShjb29raWVzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBDb29raWUoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICB9XG4gICAgZXhwb3J0cy5Db29raWUgPSBDb29raWU7XG5cbiAgICBDb29raWUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgIHZhciBzdHIgPSBbdGhpcy5uYW1lICsgXCI9XCIgKyB0aGlzLnZhbHVlXTtcbiAgICAgICAgaWYgKHRoaXMuZXhwaXJhdGlvbl9kYXRlICE9PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJleHBpcmVzPVwiICsgKG5ldyBEYXRlKHRoaXMuZXhwaXJhdGlvbl9kYXRlKSkudG9HTVRTdHJpbmcoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZG9tYWluKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcImRvbWFpbj1cIiArIHRoaXMuZG9tYWluKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYXRoKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcInBhdGg9XCIgKyB0aGlzLnBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNlY3VyZSkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJzZWN1cmVcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubm9zY3JpcHQpIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwiaHR0cG9ubHlcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0ci5qb2luKFwiOyBcIik7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUudG9WYWx1ZVN0cmluZyA9IGZ1bmN0aW9uIHRvVmFsdWVTdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWUgKyBcIj1cIiArIHRoaXMudmFsdWU7XG4gICAgfTtcblxuICAgIHZhciBjb29raWVfc3RyX3NwbGl0dGVyID0gL1s6XSg/PVxccypbYS16QS1aMC05X1xcLV0rXFxzKls9XSkvZztcbiAgICBDb29raWUucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gcGFyc2Uoc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llKSB7XG4gICAgICAgICAgICB2YXIgcGFydHMgPSBzdHIuc3BsaXQoXCI7XCIpLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEhdmFsdWU7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgcGFpciA9IHBhcnRzWzBdLm1hdGNoKC8oW149XSspPShbXFxzXFxTXSopLyksXG4gICAgICAgICAgICAgICAga2V5ID0gcGFpclsxXSxcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhaXJbMl0sXG4gICAgICAgICAgICAgICAgaTtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IGtleTtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgcGFpciA9IHBhcnRzW2ldLm1hdGNoKC8oW149XSspKD86PShbXFxzXFxTXSopKT8vKTtcbiAgICAgICAgICAgICAgICBrZXkgPSBwYWlyWzFdLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIHZhbHVlID0gcGFpclsyXTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJodHRwb25seVwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLm5vc2NyaXB0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImV4cGlyZXNcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBpcmF0aW9uX2RhdGUgPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtYmVyKERhdGUucGFyc2UodmFsdWUpKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5maW5pdHk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJwYXRoXCI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGF0aCA9IHZhbHVlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS50cmltKCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXCI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfcGF0aCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJkb21haW5cIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21haW4gPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUudHJpbSgpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlwiO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cGxpY2l0X2RvbWFpbiA9ICEhdGhpcy5kb21haW47XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzZWN1cmVcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5leHBsaWNpdF9wYXRoKSB7XG4gICAgICAgICAgICAgICB0aGlzLnBhdGggPSByZXF1ZXN0X3BhdGggfHwgXCIvXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfZG9tYWluKSB7XG4gICAgICAgICAgICAgICB0aGlzLmRvbWFpbiA9IHJlcXVlc3RfZG9tYWluO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZSgpLnBhcnNlKHN0ciwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCk7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUubWF0Y2hlcyA9IGZ1bmN0aW9uIG1hdGNoZXMoYWNjZXNzX2luZm8pIHtcbiAgICAgICAgaWYgKHRoaXMubm9zY3JpcHQgJiYgYWNjZXNzX2luZm8uc2NyaXB0IHx8XG4gICAgICAgICAgICAgICAgdGhpcy5zZWN1cmUgJiYgIWFjY2Vzc19pbmZvLnNlY3VyZSB8fFxuICAgICAgICAgICAgICAgICF0aGlzLmNvbGxpZGVzV2l0aChhY2Nlc3NfaW5mbykpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgQ29va2llLnByb3RvdHlwZS5jb2xsaWRlc1dpdGggPSBmdW5jdGlvbiBjb2xsaWRlc1dpdGgoYWNjZXNzX2luZm8pIHtcbiAgICAgICAgaWYgKCh0aGlzLnBhdGggJiYgIWFjY2Vzc19pbmZvLnBhdGgpIHx8ICh0aGlzLmRvbWFpbiAmJiAhYWNjZXNzX2luZm8uZG9tYWluKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnBhdGggJiYgYWNjZXNzX2luZm8ucGF0aC5pbmRleE9mKHRoaXMucGF0aCkgIT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5leHBsaWNpdF9wYXRoICYmIGFjY2Vzc19pbmZvLnBhdGguaW5kZXhPZiggdGhpcy5wYXRoICkgIT09IDApIHtcbiAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhY2Nlc3NfZG9tYWluID0gYWNjZXNzX2luZm8uZG9tYWluICYmIGFjY2Vzc19pbmZvLmRvbWFpbi5yZXBsYWNlKC9eW1xcLl0vLCcnKTtcbiAgICAgICAgdmFyIGNvb2tpZV9kb21haW4gPSB0aGlzLmRvbWFpbiAmJiB0aGlzLmRvbWFpbi5yZXBsYWNlKC9eW1xcLl0vLCcnKTtcbiAgICAgICAgaWYgKGNvb2tpZV9kb21haW4gPT09IGFjY2Vzc19kb21haW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb29raWVfZG9tYWluKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfZG9tYWluKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyB3ZSBhbHJlYWR5IGNoZWNrZWQgaWYgdGhlIGRvbWFpbnMgd2VyZSBleGFjdGx5IHRoZSBzYW1lXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgd2lsZGNhcmQgPSBhY2Nlc3NfZG9tYWluLmluZGV4T2YoY29va2llX2RvbWFpbik7XG4gICAgICAgICAgICBpZiAod2lsZGNhcmQgPT09IC0xIHx8IHdpbGRjYXJkICE9PSBhY2Nlc3NfZG9tYWluLmxlbmd0aCAtIGNvb2tpZV9kb21haW4ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIENvb2tpZUphcigpIHtcbiAgICAgICAgdmFyIGNvb2tpZXMsIGNvb2tpZXNfbGlzdCwgY29sbGlkYWJsZV9jb29raWU7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llSmFyKSB7XG4gICAgICAgICAgICBjb29raWVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTsgLy9uYW1lOiBbQ29va2llXVxuXG4gICAgICAgICAgICB0aGlzLnNldENvb2tpZSA9IGZ1bmN0aW9uIHNldENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVtb3ZlLCBpO1xuICAgICAgICAgICAgICAgIGNvb2tpZSA9IG5ldyBDb29raWUoY29va2llLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICAgICAgICAgICAgICAvL0RlbGV0ZSB0aGUgY29va2llIGlmIHRoZSBzZXQgaXMgcGFzdCB0aGUgY3VycmVudCB0aW1lXG4gICAgICAgICAgICAgICAgcmVtb3ZlID0gY29va2llLmV4cGlyYXRpb25fZGF0ZSA8PSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgIGlmIChjb29raWVzW2Nvb2tpZS5uYW1lXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdCA9IGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llc19saXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xsaWRhYmxlX2Nvb2tpZSA9IGNvb2tpZXNfbGlzdFtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2xsaWRhYmxlX2Nvb2tpZS5jb2xsaWRlc1dpdGgoY29va2llKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0LnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNfbGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjb29raWVzW2Nvb2tpZS5uYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdFtpXSA9IGNvb2tpZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb29raWVzX2xpc3QucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVtb3ZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29va2llc1tjb29raWUubmFtZV0gPSBbY29va2llXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy9yZXR1cm5zIGEgY29va2llXG4gICAgICAgICAgICB0aGlzLmdldENvb2tpZSA9IGZ1bmN0aW9uIGdldENvb2tpZShjb29raWVfbmFtZSwgYWNjZXNzX2luZm8pIHtcbiAgICAgICAgICAgICAgICB2YXIgY29va2llLCBpO1xuICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdCA9IGNvb2tpZXNbY29va2llX25hbWVdO1xuICAgICAgICAgICAgICAgIGlmICghY29va2llc19saXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZXNfbGlzdC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb29raWUgPSBjb29raWVzX2xpc3RbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUuZXhwaXJhdGlvbl9kYXRlIDw9IERhdGUubm93KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb29raWVzX2xpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llLm1hdGNoZXMoYWNjZXNzX2luZm8pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vcmV0dXJucyBhIGxpc3Qgb2YgY29va2llc1xuICAgICAgICAgICAgdGhpcy5nZXRDb29raWVzID0gZnVuY3Rpb24gZ2V0Q29va2llcyhhY2Nlc3NfaW5mbykge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaGVzID0gW10sIGNvb2tpZV9uYW1lLCBjb29raWU7XG4gICAgICAgICAgICAgICAgZm9yIChjb29raWVfbmFtZSBpbiBjb29raWVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZSA9IHRoaXMuZ2V0Q29va2llKGNvb2tpZV9uYW1lLCBhY2Nlc3NfaW5mbyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZXMucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1hdGNoZXMudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXMuam9pbihcIjpcIik7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBtYXRjaGVzLnRvVmFsdWVTdHJpbmcgPSBmdW5jdGlvbiB0b1ZhbHVlU3RyaW5nKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjLnRvVmFsdWVTdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgfSkuam9pbignOycpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXM7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUphcigpO1xuICAgIH1cbiAgICBleHBvcnRzLkNvb2tpZUphciA9IENvb2tpZUphcjtcblxuICAgIC8vcmV0dXJucyBsaXN0IG9mIGNvb2tpZXMgdGhhdCB3ZXJlIHNldCBjb3JyZWN0bHkuIENvb2tpZXMgdGhhdCBhcmUgZXhwaXJlZCBhbmQgcmVtb3ZlZCBhcmUgbm90IHJldHVybmVkLlxuICAgIENvb2tpZUphci5wcm90b3R5cGUuc2V0Q29va2llcyA9IGZ1bmN0aW9uIHNldENvb2tpZXMoY29va2llcywgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICBjb29raWVzID0gQXJyYXkuaXNBcnJheShjb29raWVzKSA/XG4gICAgICAgICAgICAgICAgY29va2llcyA6XG4gICAgICAgICAgICAgICAgY29va2llcy5zcGxpdChjb29raWVfc3RyX3NwbGl0dGVyKTtcbiAgICAgICAgdmFyIHN1Y2Nlc3NmdWwgPSBbXSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjb29raWU7XG4gICAgICAgIGNvb2tpZXMgPSBjb29raWVzLm1hcChmdW5jdGlvbihpdGVtKXtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29va2llKGl0ZW0sIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICB9KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvb2tpZSA9IGNvb2tpZXNbaV07XG4gICAgICAgICAgICBpZiAodGhpcy5zZXRDb29raWUoY29va2llLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSkge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NmdWwucHVzaChjb29raWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdWNjZXNzZnVsO1xuICAgIH07XG59KCkpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB5YW1sID0gcmVxdWlyZSgnLi9saWIvanMteWFtbC5qcycpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0geWFtbDtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgbG9hZGVyID0gcmVxdWlyZSgnLi9qcy15YW1sL2xvYWRlcicpO1xudmFyIGR1bXBlciA9IHJlcXVpcmUoJy4vanMteWFtbC9kdW1wZXInKTtcblxuXG5mdW5jdGlvbiBkZXByZWNhdGVkKG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Z1bmN0aW9uICcgKyBuYW1lICsgJyBpcyBkZXByZWNhdGVkIGFuZCBjYW5ub3QgYmUgdXNlZC4nKTtcbiAgfTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5UeXBlICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3R5cGUnKTtcbm1vZHVsZS5leHBvcnRzLlNjaGVtYSAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hJyk7XG5tb2R1bGUuZXhwb3J0cy5GQUlMU0FGRV9TQ0hFTUEgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9mYWlsc2FmZScpO1xubW9kdWxlLmV4cG9ydHMuSlNPTl9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvanNvbicpO1xubW9kdWxlLmV4cG9ydHMuQ09SRV9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvY29yZScpO1xubW9kdWxlLmV4cG9ydHMuREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTtcbm1vZHVsZS5leHBvcnRzLmxvYWQgICAgICAgICAgICAgICAgPSBsb2FkZXIubG9hZDtcbm1vZHVsZS5leHBvcnRzLmxvYWRBbGwgICAgICAgICAgICAgPSBsb2FkZXIubG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgICAgICAgICAgPSBsb2FkZXIuc2FmZUxvYWQ7XG5tb2R1bGUuZXhwb3J0cy5zYWZlTG9hZEFsbCAgICAgICAgID0gbG9hZGVyLnNhZmVMb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMuZHVtcCAgICAgICAgICAgICAgICA9IGR1bXBlci5kdW1wO1xubW9kdWxlLmV4cG9ydHMuc2FmZUR1bXAgICAgICAgICAgICA9IGR1bXBlci5zYWZlRHVtcDtcbm1vZHVsZS5leHBvcnRzLllBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvZXhjZXB0aW9uJyk7XG5cbi8vIERlcHJlY2F0ZWQgc2NoZW1hIG5hbWVzIGZyb20gSlMtWUFNTCAyLjAueFxubW9kdWxlLmV4cG9ydHMuTUlOSU1BTF9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2ZhaWxzYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5TQUZFX1NDSEVNQSAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG5cbi8vIERlcHJlY2F0ZWQgZnVuY3Rpb25zIGZyb20gSlMtWUFNTCAxLngueFxubW9kdWxlLmV4cG9ydHMuc2NhbiAgICAgICAgICAgPSBkZXByZWNhdGVkKCdzY2FuJyk7XG5tb2R1bGUuZXhwb3J0cy5wYXJzZSAgICAgICAgICA9IGRlcHJlY2F0ZWQoJ3BhcnNlJyk7XG5tb2R1bGUuZXhwb3J0cy5jb21wb3NlICAgICAgICA9IGRlcHJlY2F0ZWQoJ2NvbXBvc2UnKTtcbm1vZHVsZS5leHBvcnRzLmFkZENvbnN0cnVjdG9yID0gZGVwcmVjYXRlZCgnYWRkQ29uc3RydWN0b3InKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG5mdW5jdGlvbiBpc05vdGhpbmcoc3ViamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBzdWJqZWN0ID09PSAndW5kZWZpbmVkJykgfHwgKHN1YmplY3QgPT09IG51bGwpO1xufVxuXG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHN1YmplY3QpIHtcbiAgcmV0dXJuICh0eXBlb2Ygc3ViamVjdCA9PT0gJ29iamVjdCcpICYmIChzdWJqZWN0ICE9PSBudWxsKTtcbn1cblxuXG5mdW5jdGlvbiB0b0FycmF5KHNlcXVlbmNlKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHNlcXVlbmNlKSkgcmV0dXJuIHNlcXVlbmNlO1xuICBlbHNlIGlmIChpc05vdGhpbmcoc2VxdWVuY2UpKSByZXR1cm4gW107XG5cbiAgcmV0dXJuIFsgc2VxdWVuY2UgXTtcbn1cblxuXG5mdW5jdGlvbiBleHRlbmQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgdmFyIGluZGV4LCBsZW5ndGgsIGtleSwgc291cmNlS2V5cztcblxuICBpZiAoc291cmNlKSB7XG4gICAgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG5cbiAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gc291cmNlS2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICBrZXkgPSBzb3VyY2VLZXlzW2luZGV4XTtcbiAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuXG5mdW5jdGlvbiByZXBlYXQoc3RyaW5nLCBjb3VudCkge1xuICB2YXIgcmVzdWx0ID0gJycsIGN5Y2xlO1xuXG4gIGZvciAoY3ljbGUgPSAwOyBjeWNsZSA8IGNvdW50OyBjeWNsZSArPSAxKSB7XG4gICAgcmVzdWx0ICs9IHN0cmluZztcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gaXNOZWdhdGl2ZVplcm8obnVtYmVyKSB7XG4gIHJldHVybiAobnVtYmVyID09PSAwKSAmJiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSAxIC8gbnVtYmVyKTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5pc05vdGhpbmcgICAgICA9IGlzTm90aGluZztcbm1vZHVsZS5leHBvcnRzLmlzT2JqZWN0ICAgICAgID0gaXNPYmplY3Q7XG5tb2R1bGUuZXhwb3J0cy50b0FycmF5ICAgICAgICA9IHRvQXJyYXk7XG5tb2R1bGUuZXhwb3J0cy5yZXBlYXQgICAgICAgICA9IHJlcGVhdDtcbm1vZHVsZS5leHBvcnRzLmlzTmVnYXRpdmVaZXJvID0gaXNOZWdhdGl2ZVplcm87XG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgICAgICAgICA9IGV4dGVuZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBuby11c2UtYmVmb3JlLWRlZmluZSovXG5cbnZhciBjb21tb24gICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBZQU1MRXhjZXB0aW9uICAgICAgID0gcmVxdWlyZSgnLi9leGNlcHRpb24nKTtcbnZhciBERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG52YXIgREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfc2FmZScpO1xuXG52YXIgX3RvU3RyaW5nICAgICAgID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgQ0hBUl9UQUIgICAgICAgICAgICAgICAgICA9IDB4MDk7IC8qIFRhYiAqL1xudmFyIENIQVJfTElORV9GRUVEICAgICAgICAgICAgPSAweDBBOyAvKiBMRiAqL1xudmFyIENIQVJfU1BBQ0UgICAgICAgICAgICAgICAgPSAweDIwOyAvKiBTcGFjZSAqL1xudmFyIENIQVJfRVhDTEFNQVRJT04gICAgICAgICAgPSAweDIxOyAvKiAhICovXG52YXIgQ0hBUl9ET1VCTEVfUVVPVEUgICAgICAgICA9IDB4MjI7IC8qIFwiICovXG52YXIgQ0hBUl9TSEFSUCAgICAgICAgICAgICAgICA9IDB4MjM7IC8qICMgKi9cbnZhciBDSEFSX1BFUkNFTlQgICAgICAgICAgICAgID0gMHgyNTsgLyogJSAqL1xudmFyIENIQVJfQU1QRVJTQU5EICAgICAgICAgICAgPSAweDI2OyAvKiAmICovXG52YXIgQ0hBUl9TSU5HTEVfUVVPVEUgICAgICAgICA9IDB4Mjc7IC8qICcgKi9cbnZhciBDSEFSX0FTVEVSSVNLICAgICAgICAgICAgID0gMHgyQTsgLyogKiAqL1xudmFyIENIQVJfQ09NTUEgICAgICAgICAgICAgICAgPSAweDJDOyAvKiAsICovXG52YXIgQ0hBUl9NSU5VUyAgICAgICAgICAgICAgICA9IDB4MkQ7IC8qIC0gKi9cbnZhciBDSEFSX0NPTE9OICAgICAgICAgICAgICAgID0gMHgzQTsgLyogOiAqL1xudmFyIENIQVJfR1JFQVRFUl9USEFOICAgICAgICAgPSAweDNFOyAvKiA+ICovXG52YXIgQ0hBUl9RVUVTVElPTiAgICAgICAgICAgICA9IDB4M0Y7IC8qID8gKi9cbnZhciBDSEFSX0NPTU1FUkNJQUxfQVQgICAgICAgID0gMHg0MDsgLyogQCAqL1xudmFyIENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVCAgPSAweDVCOyAvKiBbICovXG52YXIgQ0hBUl9SSUdIVF9TUVVBUkVfQlJBQ0tFVCA9IDB4NUQ7IC8qIF0gKi9cbnZhciBDSEFSX0dSQVZFX0FDQ0VOVCAgICAgICAgID0gMHg2MDsgLyogYCAqL1xudmFyIENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUICAgPSAweDdCOyAvKiB7ICovXG52YXIgQ0hBUl9WRVJUSUNBTF9MSU5FICAgICAgICA9IDB4N0M7IC8qIHwgKi9cbnZhciBDSEFSX1JJR0hUX0NVUkxZX0JSQUNLRVQgID0gMHg3RDsgLyogfSAqL1xuXG52YXIgRVNDQVBFX1NFUVVFTkNFUyA9IHt9O1xuXG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDBdICAgPSAnXFxcXDAnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDA3XSAgID0gJ1xcXFxhJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwOF0gICA9ICdcXFxcYic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDldICAgPSAnXFxcXHQnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBBXSAgID0gJ1xcXFxuJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwQl0gICA9ICdcXFxcdic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MENdICAgPSAnXFxcXGYnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBEXSAgID0gJ1xcXFxyJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgxQl0gICA9ICdcXFxcZSc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjJdICAgPSAnXFxcXFwiJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHg1Q10gICA9ICdcXFxcXFxcXCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4ODVdICAgPSAnXFxcXE4nO1xuRVNDQVBFX1NFUVVFTkNFU1sweEEwXSAgID0gJ1xcXFxfJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgyMDI4XSA9ICdcXFxcTCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjAyOV0gPSAnXFxcXFAnO1xuXG52YXIgREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVggPSBbXG4gICd5JywgJ1knLCAneWVzJywgJ1llcycsICdZRVMnLCAnb24nLCAnT24nLCAnT04nLFxuICAnbicsICdOJywgJ25vJywgJ05vJywgJ05PJywgJ29mZicsICdPZmYnLCAnT0ZGJ1xuXTtcblxuZnVuY3Rpb24gY29tcGlsZVN0eWxlTWFwKHNjaGVtYSwgbWFwKSB7XG4gIHZhciByZXN1bHQsIGtleXMsIGluZGV4LCBsZW5ndGgsIHRhZywgc3R5bGUsIHR5cGU7XG5cbiAgaWYgKG1hcCA9PT0gbnVsbCkgcmV0dXJuIHt9O1xuXG4gIHJlc3VsdCA9IHt9O1xuICBrZXlzID0gT2JqZWN0LmtleXMobWFwKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdGFnID0ga2V5c1tpbmRleF07XG4gICAgc3R5bGUgPSBTdHJpbmcobWFwW3RhZ10pO1xuXG4gICAgaWYgKHRhZy5zbGljZSgwLCAyKSA9PT0gJyEhJykge1xuICAgICAgdGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWcuc2xpY2UoMik7XG4gICAgfVxuXG4gICAgdHlwZSA9IHNjaGVtYS5jb21waWxlZFR5cGVNYXBbdGFnXTtcblxuICAgIGlmICh0eXBlICYmIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHR5cGUuc3R5bGVBbGlhc2VzLCBzdHlsZSkpIHtcbiAgICAgIHN0eWxlID0gdHlwZS5zdHlsZUFsaWFzZXNbc3R5bGVdO1xuICAgIH1cblxuICAgIHJlc3VsdFt0YWddID0gc3R5bGU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBlbmNvZGVIZXgoY2hhcmFjdGVyKSB7XG4gIHZhciBzdHJpbmcsIGhhbmRsZSwgbGVuZ3RoO1xuXG4gIHN0cmluZyA9IGNoYXJhY3Rlci50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcblxuICBpZiAoY2hhcmFjdGVyIDw9IDB4RkYpIHtcbiAgICBoYW5kbGUgPSAneCc7XG4gICAgbGVuZ3RoID0gMjtcbiAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPD0gMHhGRkZGKSB7XG4gICAgaGFuZGxlID0gJ3UnO1xuICAgIGxlbmd0aCA9IDQ7XG4gIH0gZWxzZSBpZiAoY2hhcmFjdGVyIDw9IDB4RkZGRkZGRkYpIHtcbiAgICBoYW5kbGUgPSAnVSc7XG4gICAgbGVuZ3RoID0gODtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignY29kZSBwb2ludCB3aXRoaW4gYSBzdHJpbmcgbWF5IG5vdCBiZSBncmVhdGVyIHRoYW4gMHhGRkZGRkZGRicpO1xuICB9XG5cbiAgcmV0dXJuICdcXFxcJyArIGhhbmRsZSArIGNvbW1vbi5yZXBlYXQoJzAnLCBsZW5ndGggLSBzdHJpbmcubGVuZ3RoKSArIHN0cmluZztcbn1cblxuZnVuY3Rpb24gU3RhdGUob3B0aW9ucykge1xuICB0aGlzLnNjaGVtYSAgICAgICA9IG9wdGlvbnNbJ3NjaGVtYSddIHx8IERFRkFVTFRfRlVMTF9TQ0hFTUE7XG4gIHRoaXMuaW5kZW50ICAgICAgID0gTWF0aC5tYXgoMSwgKG9wdGlvbnNbJ2luZGVudCddIHx8IDIpKTtcbiAgdGhpcy5za2lwSW52YWxpZCAgPSBvcHRpb25zWydza2lwSW52YWxpZCddIHx8IGZhbHNlO1xuICB0aGlzLmZsb3dMZXZlbCAgICA9IChjb21tb24uaXNOb3RoaW5nKG9wdGlvbnNbJ2Zsb3dMZXZlbCddKSA/IC0xIDogb3B0aW9uc1snZmxvd0xldmVsJ10pO1xuICB0aGlzLnN0eWxlTWFwICAgICA9IGNvbXBpbGVTdHlsZU1hcCh0aGlzLnNjaGVtYSwgb3B0aW9uc1snc3R5bGVzJ10gfHwgbnVsbCk7XG4gIHRoaXMuc29ydEtleXMgICAgID0gb3B0aW9uc1snc29ydEtleXMnXSB8fCBmYWxzZTtcbiAgdGhpcy5saW5lV2lkdGggICAgPSBvcHRpb25zWydsaW5lV2lkdGgnXSB8fCA4MDtcbiAgdGhpcy5ub1JlZnMgICAgICAgPSBvcHRpb25zWydub1JlZnMnXSB8fCBmYWxzZTtcbiAgdGhpcy5ub0NvbXBhdE1vZGUgPSBvcHRpb25zWydub0NvbXBhdE1vZGUnXSB8fCBmYWxzZTtcblxuICB0aGlzLmltcGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEltcGxpY2l0O1xuICB0aGlzLmV4cGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEV4cGxpY2l0O1xuXG4gIHRoaXMudGFnID0gbnVsbDtcbiAgdGhpcy5yZXN1bHQgPSAnJztcblxuICB0aGlzLmR1cGxpY2F0ZXMgPSBbXTtcbiAgdGhpcy51c2VkRHVwbGljYXRlcyA9IG51bGw7XG59XG5cbi8vIEluZGVudHMgZXZlcnkgbGluZSBpbiBhIHN0cmluZy4gRW1wdHkgbGluZXMgKFxcbiBvbmx5KSBhcmUgbm90IGluZGVudGVkLlxuZnVuY3Rpb24gaW5kZW50U3RyaW5nKHN0cmluZywgc3BhY2VzKSB7XG4gIHZhciBpbmQgPSBjb21tb24ucmVwZWF0KCcgJywgc3BhY2VzKSxcbiAgICAgIHBvc2l0aW9uID0gMCxcbiAgICAgIG5leHQgPSAtMSxcbiAgICAgIHJlc3VsdCA9ICcnLFxuICAgICAgbGluZSxcbiAgICAgIGxlbmd0aCA9IHN0cmluZy5sZW5ndGg7XG5cbiAgd2hpbGUgKHBvc2l0aW9uIDwgbGVuZ3RoKSB7XG4gICAgbmV4dCA9IHN0cmluZy5pbmRleE9mKCdcXG4nLCBwb3NpdGlvbik7XG4gICAgaWYgKG5leHQgPT09IC0xKSB7XG4gICAgICBsaW5lID0gc3RyaW5nLnNsaWNlKHBvc2l0aW9uKTtcbiAgICAgIHBvc2l0aW9uID0gbGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaW5lID0gc3RyaW5nLnNsaWNlKHBvc2l0aW9uLCBuZXh0ICsgMSk7XG4gICAgICBwb3NpdGlvbiA9IG5leHQgKyAxO1xuICAgIH1cblxuICAgIGlmIChsaW5lLmxlbmd0aCAmJiBsaW5lICE9PSAnXFxuJykgcmVzdWx0ICs9IGluZDtcblxuICAgIHJlc3VsdCArPSBsaW5lO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpIHtcbiAgcmV0dXJuICdcXG4nICsgY29tbW9uLnJlcGVhdCgnICcsIHN0YXRlLmluZGVudCAqIGxldmVsKTtcbn1cblxuZnVuY3Rpb24gdGVzdEltcGxpY2l0UmVzb2x2aW5nKHN0YXRlLCBzdHIpIHtcbiAgdmFyIGluZGV4LCBsZW5ndGgsIHR5cGU7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IHN0YXRlLmltcGxpY2l0VHlwZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHR5cGUgPSBzdGF0ZS5pbXBsaWNpdFR5cGVzW2luZGV4XTtcblxuICAgIGlmICh0eXBlLnJlc29sdmUoc3RyKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vLyBbMzNdIHMtd2hpdGUgOjo9IHMtc3BhY2UgfCBzLXRhYlxuZnVuY3Rpb24gaXNXaGl0ZXNwYWNlKGMpIHtcbiAgcmV0dXJuIGMgPT09IENIQVJfU1BBQ0UgfHwgYyA9PT0gQ0hBUl9UQUI7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIGNhbiBiZSBwcmludGVkIHdpdGhvdXQgZXNjYXBpbmcuXG4vLyBGcm9tIFlBTUwgMS4yOiBcImFueSBhbGxvd2VkIGNoYXJhY3RlcnMga25vd24gdG8gYmUgbm9uLXByaW50YWJsZVxuLy8gc2hvdWxkIGFsc28gYmUgZXNjYXBlZC4gW0hvd2V2ZXIsXSBUaGlzIGlzbuKAmXQgbWFuZGF0b3J5XCJcbi8vIERlcml2ZWQgZnJvbSBuYi1jaGFyIC0gXFx0IC0gI3g4NSAtICN4QTAgLSAjeDIwMjggLSAjeDIwMjkuXG5mdW5jdGlvbiBpc1ByaW50YWJsZShjKSB7XG4gIHJldHVybiAgKDB4MDAwMjAgPD0gYyAmJiBjIDw9IDB4MDAwMDdFKVxuICAgICAgfHwgKCgweDAwMEExIDw9IGMgJiYgYyA8PSAweDAwRDdGRikgJiYgYyAhPT0gMHgyMDI4ICYmIGMgIT09IDB4MjAyOSlcbiAgICAgIHx8ICgoMHgwRTAwMCA8PSBjICYmIGMgPD0gMHgwMEZGRkQpICYmIGMgIT09IDB4RkVGRiAvKiBCT00gKi8pXG4gICAgICB8fCAgKDB4MTAwMDAgPD0gYyAmJiBjIDw9IDB4MTBGRkZGKTtcbn1cblxuLy8gU2ltcGxpZmllZCB0ZXN0IGZvciB2YWx1ZXMgYWxsb3dlZCBhZnRlciB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHBsYWluIHN0eWxlLlxuZnVuY3Rpb24gaXNQbGFpblNhZmUoYykge1xuICAvLyBVc2VzIGEgc3Vic2V0IG9mIG5iLWNoYXIgLSBjLWZsb3ctaW5kaWNhdG9yIC0gXCI6XCIgLSBcIiNcIlxuICAvLyB3aGVyZSBuYi1jaGFyIDo6PSBjLXByaW50YWJsZSAtIGItY2hhciAtIGMtYnl0ZS1vcmRlci1tYXJrLlxuICByZXR1cm4gaXNQcmludGFibGUoYykgJiYgYyAhPT0gMHhGRUZGXG4gICAgLy8gLSBjLWZsb3ctaW5kaWNhdG9yXG4gICAgJiYgYyAhPT0gQ0hBUl9DT01NQVxuICAgICYmIGMgIT09IENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfUklHSFRfU1FVQVJFX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX0xFRlRfQ1VSTFlfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfUklHSFRfQ1VSTFlfQlJBQ0tFVFxuICAgIC8vIC0gXCI6XCIgLSBcIiNcIlxuICAgICYmIGMgIT09IENIQVJfQ09MT05cbiAgICAmJiBjICE9PSBDSEFSX1NIQVJQO1xufVxuXG4vLyBTaW1wbGlmaWVkIHRlc3QgZm9yIHZhbHVlcyBhbGxvd2VkIGFzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gcGxhaW4gc3R5bGUuXG5mdW5jdGlvbiBpc1BsYWluU2FmZUZpcnN0KGMpIHtcbiAgLy8gVXNlcyBhIHN1YnNldCBvZiBucy1jaGFyIC0gYy1pbmRpY2F0b3JcbiAgLy8gd2hlcmUgbnMtY2hhciA9IG5iLWNoYXIgLSBzLXdoaXRlLlxuICByZXR1cm4gaXNQcmludGFibGUoYykgJiYgYyAhPT0gMHhGRUZGXG4gICAgJiYgIWlzV2hpdGVzcGFjZShjKSAvLyAtIHMtd2hpdGVcbiAgICAvLyAtIChjLWluZGljYXRvciA6Oj1cbiAgICAvLyDigJwt4oCdIHwg4oCcP+KAnSB8IOKAnDrigJ0gfCDigJws4oCdIHwg4oCcW+KAnSB8IOKAnF3igJ0gfCDigJx74oCdIHwg4oCcfeKAnVxuICAgICYmIGMgIT09IENIQVJfTUlOVVNcbiAgICAmJiBjICE9PSBDSEFSX1FVRVNUSU9OXG4gICAgJiYgYyAhPT0gQ0hBUl9DT0xPTlxuICAgICYmIGMgIT09IENIQVJfQ09NTUFcbiAgICAmJiBjICE9PSBDSEFSX0xFRlRfU1FVQVJFX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUXG4gICAgJiYgYyAhPT0gQ0hBUl9MRUZUX0NVUkxZX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX1JJR0hUX0NVUkxZX0JSQUNLRVRcbiAgICAvLyB8IOKAnCPigJ0gfCDigJwm4oCdIHwg4oCcKuKAnSB8IOKAnCHigJ0gfCDigJx84oCdIHwg4oCcPuKAnSB8IOKAnCfigJ0gfCDigJxcIuKAnVxuICAgICYmIGMgIT09IENIQVJfU0hBUlBcbiAgICAmJiBjICE9PSBDSEFSX0FNUEVSU0FORFxuICAgICYmIGMgIT09IENIQVJfQVNURVJJU0tcbiAgICAmJiBjICE9PSBDSEFSX0VYQ0xBTUFUSU9OXG4gICAgJiYgYyAhPT0gQ0hBUl9WRVJUSUNBTF9MSU5FXG4gICAgJiYgYyAhPT0gQ0hBUl9HUkVBVEVSX1RIQU5cbiAgICAmJiBjICE9PSBDSEFSX1NJTkdMRV9RVU9URVxuICAgICYmIGMgIT09IENIQVJfRE9VQkxFX1FVT1RFXG4gICAgLy8gfCDigJwl4oCdIHwg4oCcQOKAnSB8IOKAnGDigJ0pXG4gICAgJiYgYyAhPT0gQ0hBUl9QRVJDRU5UXG4gICAgJiYgYyAhPT0gQ0hBUl9DT01NRVJDSUFMX0FUXG4gICAgJiYgYyAhPT0gQ0hBUl9HUkFWRV9BQ0NFTlQ7XG59XG5cbnZhciBTVFlMRV9QTEFJTiAgID0gMSxcbiAgICBTVFlMRV9TSU5HTEUgID0gMixcbiAgICBTVFlMRV9MSVRFUkFMID0gMyxcbiAgICBTVFlMRV9GT0xERUQgID0gNCxcbiAgICBTVFlMRV9ET1VCTEUgID0gNTtcblxuLy8gRGV0ZXJtaW5lcyB3aGljaCBzY2FsYXIgc3R5bGVzIGFyZSBwb3NzaWJsZSBhbmQgcmV0dXJucyB0aGUgcHJlZmVycmVkIHN0eWxlLlxuLy8gbGluZVdpZHRoID0gLTEgPT4gbm8gbGltaXQuXG4vLyBQcmUtY29uZGl0aW9uczogc3RyLmxlbmd0aCA+IDAuXG4vLyBQb3N0LWNvbmRpdGlvbnM6XG4vLyAgICBTVFlMRV9QTEFJTiBvciBTVFlMRV9TSU5HTEUgPT4gbm8gXFxuIGFyZSBpbiB0aGUgc3RyaW5nLlxuLy8gICAgU1RZTEVfTElURVJBTCA9PiBubyBsaW5lcyBhcmUgc3VpdGFibGUgZm9yIGZvbGRpbmcgKG9yIGxpbmVXaWR0aCBpcyAtMSkuXG4vLyAgICBTVFlMRV9GT0xERUQgPT4gYSBsaW5lID4gbGluZVdpZHRoIGFuZCBjYW4gYmUgZm9sZGVkIChhbmQgbGluZVdpZHRoICE9IC0xKS5cbmZ1bmN0aW9uIGNob29zZVNjYWxhclN0eWxlKHN0cmluZywgc2luZ2xlTGluZU9ubHksIGluZGVudFBlckxldmVsLCBsaW5lV2lkdGgsIHRlc3RBbWJpZ3VvdXNUeXBlKSB7XG4gIHZhciBpO1xuICB2YXIgY2hhcjtcbiAgdmFyIGhhc0xpbmVCcmVhayA9IGZhbHNlO1xuICB2YXIgaGFzRm9sZGFibGVMaW5lID0gZmFsc2U7IC8vIG9ubHkgY2hlY2tlZCBpZiBzaG91bGRUcmFja1dpZHRoXG4gIHZhciBzaG91bGRUcmFja1dpZHRoID0gbGluZVdpZHRoICE9PSAtMTtcbiAgdmFyIHByZXZpb3VzTGluZUJyZWFrID0gLTE7IC8vIGNvdW50IHRoZSBmaXJzdCBsaW5lIGNvcnJlY3RseVxuICB2YXIgcGxhaW4gPSBpc1BsYWluU2FmZUZpcnN0KHN0cmluZy5jaGFyQ29kZUF0KDApKVxuICAgICAgICAgICYmICFpc1doaXRlc3BhY2Uoc3RyaW5nLmNoYXJDb2RlQXQoc3RyaW5nLmxlbmd0aCAtIDEpKTtcblxuICBpZiAoc2luZ2xlTGluZU9ubHkpIHtcbiAgICAvLyBDYXNlOiBubyBibG9jayBzdHlsZXMuXG4gICAgLy8gQ2hlY2sgZm9yIGRpc2FsbG93ZWQgY2hhcmFjdGVycyB0byBydWxlIG91dCBwbGFpbiBhbmQgc2luZ2xlLlxuICAgIGZvciAoaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoYXIgPSBzdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICAgIGlmICghaXNQcmludGFibGUoY2hhcikpIHtcbiAgICAgICAgcmV0dXJuIFNUWUxFX0RPVUJMRTtcbiAgICAgIH1cbiAgICAgIHBsYWluID0gcGxhaW4gJiYgaXNQbGFpblNhZmUoY2hhcik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIENhc2U6IGJsb2NrIHN0eWxlcyBwZXJtaXR0ZWQuXG4gICAgZm9yIChpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgY2hhciA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWYgKGNoYXIgPT09IENIQVJfTElORV9GRUVEKSB7XG4gICAgICAgIGhhc0xpbmVCcmVhayA9IHRydWU7XG4gICAgICAgIC8vIENoZWNrIGlmIGFueSBsaW5lIGNhbiBiZSBmb2xkZWQuXG4gICAgICAgIGlmIChzaG91bGRUcmFja1dpZHRoKSB7XG4gICAgICAgICAgaGFzRm9sZGFibGVMaW5lID0gaGFzRm9sZGFibGVMaW5lIHx8XG4gICAgICAgICAgICAvLyBGb2xkYWJsZSBsaW5lID0gdG9vIGxvbmcsIGFuZCBub3QgbW9yZS1pbmRlbnRlZC5cbiAgICAgICAgICAgIChpIC0gcHJldmlvdXNMaW5lQnJlYWsgLSAxID4gbGluZVdpZHRoICYmXG4gICAgICAgICAgICAgc3RyaW5nW3ByZXZpb3VzTGluZUJyZWFrICsgMV0gIT09ICcgJyk7XG4gICAgICAgICAgcHJldmlvdXNMaW5lQnJlYWsgPSBpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCFpc1ByaW50YWJsZShjaGFyKSkge1xuICAgICAgICByZXR1cm4gU1RZTEVfRE9VQkxFO1xuICAgICAgfVxuICAgICAgcGxhaW4gPSBwbGFpbiAmJiBpc1BsYWluU2FmZShjaGFyKTtcbiAgICB9XG4gICAgLy8gaW4gY2FzZSB0aGUgZW5kIGlzIG1pc3NpbmcgYSBcXG5cbiAgICBoYXNGb2xkYWJsZUxpbmUgPSBoYXNGb2xkYWJsZUxpbmUgfHwgKHNob3VsZFRyYWNrV2lkdGggJiZcbiAgICAgIChpIC0gcHJldmlvdXNMaW5lQnJlYWsgLSAxID4gbGluZVdpZHRoICYmXG4gICAgICAgc3RyaW5nW3ByZXZpb3VzTGluZUJyZWFrICsgMV0gIT09ICcgJykpO1xuICB9XG4gIC8vIEFsdGhvdWdoIGV2ZXJ5IHN0eWxlIGNhbiByZXByZXNlbnQgXFxuIHdpdGhvdXQgZXNjYXBpbmcsIHByZWZlciBibG9jayBzdHlsZXNcbiAgLy8gZm9yIG11bHRpbGluZSwgc2luY2UgdGhleSdyZSBtb3JlIHJlYWRhYmxlIGFuZCB0aGV5IGRvbid0IGFkZCBlbXB0eSBsaW5lcy5cbiAgLy8gQWxzbyBwcmVmZXIgZm9sZGluZyBhIHN1cGVyLWxvbmcgbGluZS5cbiAgaWYgKCFoYXNMaW5lQnJlYWsgJiYgIWhhc0ZvbGRhYmxlTGluZSkge1xuICAgIC8vIFN0cmluZ3MgaW50ZXJwcmV0YWJsZSBhcyBhbm90aGVyIHR5cGUgaGF2ZSB0byBiZSBxdW90ZWQ7XG4gICAgLy8gZS5nLiB0aGUgc3RyaW5nICd0cnVlJyB2cy4gdGhlIGJvb2xlYW4gdHJ1ZS5cbiAgICByZXR1cm4gcGxhaW4gJiYgIXRlc3RBbWJpZ3VvdXNUeXBlKHN0cmluZylcbiAgICAgID8gU1RZTEVfUExBSU4gOiBTVFlMRV9TSU5HTEU7XG4gIH1cbiAgLy8gRWRnZSBjYXNlOiBibG9jayBpbmRlbnRhdGlvbiBpbmRpY2F0b3IgY2FuIG9ubHkgaGF2ZSBvbmUgZGlnaXQuXG4gIGlmIChzdHJpbmdbMF0gPT09ICcgJyAmJiBpbmRlbnRQZXJMZXZlbCA+IDkpIHtcbiAgICByZXR1cm4gU1RZTEVfRE9VQkxFO1xuICB9XG4gIC8vIEF0IHRoaXMgcG9pbnQgd2Uga25vdyBibG9jayBzdHlsZXMgYXJlIHZhbGlkLlxuICAvLyBQcmVmZXIgbGl0ZXJhbCBzdHlsZSB1bmxlc3Mgd2Ugd2FudCB0byBmb2xkLlxuICByZXR1cm4gaGFzRm9sZGFibGVMaW5lID8gU1RZTEVfRk9MREVEIDogU1RZTEVfTElURVJBTDtcbn1cblxuLy8gTm90ZTogbGluZSBicmVha2luZy9mb2xkaW5nIGlzIGltcGxlbWVudGVkIGZvciBvbmx5IHRoZSBmb2xkZWQgc3R5bGUuXG4vLyBOQi4gV2UgZHJvcCB0aGUgbGFzdCB0cmFpbGluZyBuZXdsaW5lIChpZiBhbnkpIG9mIGEgcmV0dXJuZWQgYmxvY2sgc2NhbGFyXG4vLyAgc2luY2UgdGhlIGR1bXBlciBhZGRzIGl0cyBvd24gbmV3bGluZS4gVGhpcyBhbHdheXMgd29ya3M6XG4vLyAgICDigKIgTm8gZW5kaW5nIG5ld2xpbmUgPT4gdW5hZmZlY3RlZDsgYWxyZWFkeSB1c2luZyBzdHJpcCBcIi1cIiBjaG9tcGluZy5cbi8vICAgIOKAoiBFbmRpbmcgbmV3bGluZSAgICA9PiByZW1vdmVkIHRoZW4gcmVzdG9yZWQuXG4vLyAgSW1wb3J0YW50bHksIHRoaXMga2VlcHMgdGhlIFwiK1wiIGNob21wIGluZGljYXRvciBmcm9tIGdhaW5pbmcgYW4gZXh0cmEgbGluZS5cbmZ1bmN0aW9uIHdyaXRlU2NhbGFyKHN0YXRlLCBzdHJpbmcsIGxldmVsLCBpc2tleSkge1xuICBzdGF0ZS5kdW1wID0gKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc3RyaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFwiJydcIjtcbiAgICB9XG4gICAgaWYgKCFzdGF0ZS5ub0NvbXBhdE1vZGUgJiZcbiAgICAgICAgREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVguaW5kZXhPZihzdHJpbmcpICE9PSAtMSkge1xuICAgICAgcmV0dXJuIFwiJ1wiICsgc3RyaW5nICsgXCInXCI7XG4gICAgfVxuXG4gICAgdmFyIGluZGVudCA9IHN0YXRlLmluZGVudCAqIE1hdGgubWF4KDEsIGxldmVsKTsgLy8gbm8gMC1pbmRlbnQgc2NhbGFyc1xuICAgIC8vIEFzIGluZGVudGF0aW9uIGdldHMgZGVlcGVyLCBsZXQgdGhlIHdpZHRoIGRlY3JlYXNlIG1vbm90b25pY2FsbHlcbiAgICAvLyB0byB0aGUgbG93ZXIgYm91bmQgbWluKHN0YXRlLmxpbmVXaWR0aCwgNDApLlxuICAgIC8vIE5vdGUgdGhhdCB0aGlzIGltcGxpZXNcbiAgICAvLyAgc3RhdGUubGluZVdpZHRoIOKJpCA0MCArIHN0YXRlLmluZGVudDogd2lkdGggaXMgZml4ZWQgYXQgdGhlIGxvd2VyIGJvdW5kLlxuICAgIC8vICBzdGF0ZS5saW5lV2lkdGggPiA0MCArIHN0YXRlLmluZGVudDogd2lkdGggZGVjcmVhc2VzIHVudGlsIHRoZSBsb3dlciBib3VuZC5cbiAgICAvLyBUaGlzIGJlaGF2ZXMgYmV0dGVyIHRoYW4gYSBjb25zdGFudCBtaW5pbXVtIHdpZHRoIHdoaWNoIGRpc2FsbG93cyBuYXJyb3dlciBvcHRpb25zLFxuICAgIC8vIG9yIGFuIGluZGVudCB0aHJlc2hvbGQgd2hpY2ggY2F1c2VzIHRoZSB3aWR0aCB0byBzdWRkZW5seSBpbmNyZWFzZS5cbiAgICB2YXIgbGluZVdpZHRoID0gc3RhdGUubGluZVdpZHRoID09PSAtMVxuICAgICAgPyAtMSA6IE1hdGgubWF4KE1hdGgubWluKHN0YXRlLmxpbmVXaWR0aCwgNDApLCBzdGF0ZS5saW5lV2lkdGggLSBpbmRlbnQpO1xuXG4gICAgLy8gV2l0aG91dCBrbm93aW5nIGlmIGtleXMgYXJlIGltcGxpY2l0L2V4cGxpY2l0LCBhc3N1bWUgaW1wbGljaXQgZm9yIHNhZmV0eS5cbiAgICB2YXIgc2luZ2xlTGluZU9ubHkgPSBpc2tleVxuICAgICAgLy8gTm8gYmxvY2sgc3R5bGVzIGluIGZsb3cgbW9kZS5cbiAgICAgIHx8IChzdGF0ZS5mbG93TGV2ZWwgPiAtMSAmJiBsZXZlbCA+PSBzdGF0ZS5mbG93TGV2ZWwpO1xuICAgIGZ1bmN0aW9uIHRlc3RBbWJpZ3VpdHkoc3RyaW5nKSB7XG4gICAgICByZXR1cm4gdGVzdEltcGxpY2l0UmVzb2x2aW5nKHN0YXRlLCBzdHJpbmcpO1xuICAgIH1cblxuICAgIHN3aXRjaCAoY2hvb3NlU2NhbGFyU3R5bGUoc3RyaW5nLCBzaW5nbGVMaW5lT25seSwgc3RhdGUuaW5kZW50LCBsaW5lV2lkdGgsIHRlc3RBbWJpZ3VpdHkpKSB7XG4gICAgICBjYXNlIFNUWUxFX1BMQUlOOlxuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgY2FzZSBTVFlMRV9TSU5HTEU6XG4gICAgICAgIHJldHVybiBcIidcIiArIHN0cmluZy5yZXBsYWNlKC8nL2csIFwiJydcIikgKyBcIidcIjtcbiAgICAgIGNhc2UgU1RZTEVfTElURVJBTDpcbiAgICAgICAgcmV0dXJuICd8JyArIGJsb2NrSGVhZGVyKHN0cmluZywgc3RhdGUuaW5kZW50KVxuICAgICAgICAgICsgZHJvcEVuZGluZ05ld2xpbmUoaW5kZW50U3RyaW5nKHN0cmluZywgaW5kZW50KSk7XG4gICAgICBjYXNlIFNUWUxFX0ZPTERFRDpcbiAgICAgICAgcmV0dXJuICc+JyArIGJsb2NrSGVhZGVyKHN0cmluZywgc3RhdGUuaW5kZW50KVxuICAgICAgICAgICsgZHJvcEVuZGluZ05ld2xpbmUoaW5kZW50U3RyaW5nKGZvbGRTdHJpbmcoc3RyaW5nLCBsaW5lV2lkdGgpLCBpbmRlbnQpKTtcbiAgICAgIGNhc2UgU1RZTEVfRE9VQkxFOlxuICAgICAgICByZXR1cm4gJ1wiJyArIGVzY2FwZVN0cmluZyhzdHJpbmcsIGxpbmVXaWR0aCkgKyAnXCInO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ2ltcG9zc2libGUgZXJyb3I6IGludmFsaWQgc2NhbGFyIHN0eWxlJyk7XG4gICAgfVxuICB9KCkpO1xufVxuXG4vLyBQcmUtY29uZGl0aW9uczogc3RyaW5nIGlzIHZhbGlkIGZvciBhIGJsb2NrIHNjYWxhciwgMSA8PSBpbmRlbnRQZXJMZXZlbCA8PSA5LlxuZnVuY3Rpb24gYmxvY2tIZWFkZXIoc3RyaW5nLCBpbmRlbnRQZXJMZXZlbCkge1xuICB2YXIgaW5kZW50SW5kaWNhdG9yID0gKHN0cmluZ1swXSA9PT0gJyAnKSA/IFN0cmluZyhpbmRlbnRQZXJMZXZlbCkgOiAnJztcblxuICAvLyBub3RlIHRoZSBzcGVjaWFsIGNhc2U6IHRoZSBzdHJpbmcgJ1xcbicgY291bnRzIGFzIGEgXCJ0cmFpbGluZ1wiIGVtcHR5IGxpbmUuXG4gIHZhciBjbGlwID0gICAgICAgICAgc3RyaW5nW3N0cmluZy5sZW5ndGggLSAxXSA9PT0gJ1xcbic7XG4gIHZhciBrZWVwID0gY2xpcCAmJiAoc3RyaW5nW3N0cmluZy5sZW5ndGggLSAyXSA9PT0gJ1xcbicgfHwgc3RyaW5nID09PSAnXFxuJyk7XG4gIHZhciBjaG9tcCA9IGtlZXAgPyAnKycgOiAoY2xpcCA/ICcnIDogJy0nKTtcblxuICByZXR1cm4gaW5kZW50SW5kaWNhdG9yICsgY2hvbXAgKyAnXFxuJztcbn1cblxuLy8gKFNlZSB0aGUgbm90ZSBmb3Igd3JpdGVTY2FsYXIuKVxuZnVuY3Rpb24gZHJvcEVuZGluZ05ld2xpbmUoc3RyaW5nKSB7XG4gIHJldHVybiBzdHJpbmdbc3RyaW5nLmxlbmd0aCAtIDFdID09PSAnXFxuJyA/IHN0cmluZy5zbGljZSgwLCAtMSkgOiBzdHJpbmc7XG59XG5cbi8vIE5vdGU6IGEgbG9uZyBsaW5lIHdpdGhvdXQgYSBzdWl0YWJsZSBicmVhayBwb2ludCB3aWxsIGV4Y2VlZCB0aGUgd2lkdGggbGltaXQuXG4vLyBQcmUtY29uZGl0aW9uczogZXZlcnkgY2hhciBpbiBzdHIgaXNQcmludGFibGUsIHN0ci5sZW5ndGggPiAwLCB3aWR0aCA+IDAuXG5mdW5jdGlvbiBmb2xkU3RyaW5nKHN0cmluZywgd2lkdGgpIHtcbiAgLy8gSW4gZm9sZGVkIHN0eWxlLCAkayQgY29uc2VjdXRpdmUgbmV3bGluZXMgb3V0cHV0IGFzICRrKzEkIG5ld2xpbmVz4oCUXG4gIC8vIHVubGVzcyB0aGV5J3JlIGJlZm9yZSBvciBhZnRlciBhIG1vcmUtaW5kZW50ZWQgbGluZSwgb3IgYXQgdGhlIHZlcnlcbiAgLy8gYmVnaW5uaW5nIG9yIGVuZCwgaW4gd2hpY2ggY2FzZSAkayQgbWFwcyB0byAkayQuXG4gIC8vIFRoZXJlZm9yZSwgcGFyc2UgZWFjaCBjaHVuayBhcyBuZXdsaW5lKHMpIGZvbGxvd2VkIGJ5IGEgY29udGVudCBsaW5lLlxuICB2YXIgbGluZVJlID0gLyhcXG4rKShbXlxcbl0qKS9nO1xuXG4gIC8vIGZpcnN0IGxpbmUgKHBvc3NpYmx5IGFuIGVtcHR5IGxpbmUpXG4gIHZhciByZXN1bHQgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBuZXh0TEYgPSBzdHJpbmcuaW5kZXhPZignXFxuJyk7XG4gICAgbmV4dExGID0gbmV4dExGICE9PSAtMSA/IG5leHRMRiA6IHN0cmluZy5sZW5ndGg7XG4gICAgbGluZVJlLmxhc3RJbmRleCA9IG5leHRMRjtcbiAgICByZXR1cm4gZm9sZExpbmUoc3RyaW5nLnNsaWNlKDAsIG5leHRMRiksIHdpZHRoKTtcbiAgfSgpKTtcbiAgLy8gSWYgd2UgaGF2ZW4ndCByZWFjaGVkIHRoZSBmaXJzdCBjb250ZW50IGxpbmUgeWV0LCBkb24ndCBhZGQgYW4gZXh0cmEgXFxuLlxuICB2YXIgcHJldk1vcmVJbmRlbnRlZCA9IHN0cmluZ1swXSA9PT0gJ1xcbicgfHwgc3RyaW5nWzBdID09PSAnICc7XG4gIHZhciBtb3JlSW5kZW50ZWQ7XG5cbiAgLy8gcmVzdCBvZiB0aGUgbGluZXNcbiAgdmFyIG1hdGNoO1xuICB3aGlsZSAoKG1hdGNoID0gbGluZVJlLmV4ZWMoc3RyaW5nKSkpIHtcbiAgICB2YXIgcHJlZml4ID0gbWF0Y2hbMV0sIGxpbmUgPSBtYXRjaFsyXTtcbiAgICBtb3JlSW5kZW50ZWQgPSAobGluZVswXSA9PT0gJyAnKTtcbiAgICByZXN1bHQgKz0gcHJlZml4XG4gICAgICArICghcHJldk1vcmVJbmRlbnRlZCAmJiAhbW9yZUluZGVudGVkICYmIGxpbmUgIT09ICcnXG4gICAgICAgID8gJ1xcbicgOiAnJylcbiAgICAgICsgZm9sZExpbmUobGluZSwgd2lkdGgpO1xuICAgIHByZXZNb3JlSW5kZW50ZWQgPSBtb3JlSW5kZW50ZWQ7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vLyBHcmVlZHkgbGluZSBicmVha2luZy5cbi8vIFBpY2tzIHRoZSBsb25nZXN0IGxpbmUgdW5kZXIgdGhlIGxpbWl0IGVhY2ggdGltZSxcbi8vIG90aGVyd2lzZSBzZXR0bGVzIGZvciB0aGUgc2hvcnRlc3QgbGluZSBvdmVyIHRoZSBsaW1pdC5cbi8vIE5CLiBNb3JlLWluZGVudGVkIGxpbmVzICpjYW5ub3QqIGJlIGZvbGRlZCwgYXMgdGhhdCB3b3VsZCBhZGQgYW4gZXh0cmEgXFxuLlxuZnVuY3Rpb24gZm9sZExpbmUobGluZSwgd2lkdGgpIHtcbiAgaWYgKGxpbmUgPT09ICcnIHx8IGxpbmVbMF0gPT09ICcgJykgcmV0dXJuIGxpbmU7XG5cbiAgLy8gU2luY2UgYSBtb3JlLWluZGVudGVkIGxpbmUgYWRkcyBhIFxcbiwgYnJlYWtzIGNhbid0IGJlIGZvbGxvd2VkIGJ5IGEgc3BhY2UuXG4gIHZhciBicmVha1JlID0gLyBbXiBdL2c7IC8vIG5vdGU6IHRoZSBtYXRjaCBpbmRleCB3aWxsIGFsd2F5cyBiZSA8PSBsZW5ndGgtMi5cbiAgdmFyIG1hdGNoO1xuICAvLyBzdGFydCBpcyBhbiBpbmNsdXNpdmUgaW5kZXguIGVuZCwgY3VyciwgYW5kIG5leHQgYXJlIGV4Y2x1c2l2ZS5cbiAgdmFyIHN0YXJ0ID0gMCwgZW5kLCBjdXJyID0gMCwgbmV4dCA9IDA7XG4gIHZhciByZXN1bHQgPSAnJztcblxuICAvLyBJbnZhcmlhbnRzOiAwIDw9IHN0YXJ0IDw9IGxlbmd0aC0xLlxuICAvLyAgIDAgPD0gY3VyciA8PSBuZXh0IDw9IG1heCgwLCBsZW5ndGgtMikuIGN1cnIgLSBzdGFydCA8PSB3aWR0aC5cbiAgLy8gSW5zaWRlIHRoZSBsb29wOlxuICAvLyAgIEEgbWF0Y2ggaW1wbGllcyBsZW5ndGggPj0gMiwgc28gY3VyciBhbmQgbmV4dCBhcmUgPD0gbGVuZ3RoLTIuXG4gIHdoaWxlICgobWF0Y2ggPSBicmVha1JlLmV4ZWMobGluZSkpKSB7XG4gICAgbmV4dCA9IG1hdGNoLmluZGV4O1xuICAgIC8vIG1haW50YWluIGludmFyaWFudDogY3VyciAtIHN0YXJ0IDw9IHdpZHRoXG4gICAgaWYgKG5leHQgLSBzdGFydCA+IHdpZHRoKSB7XG4gICAgICBlbmQgPSAoY3VyciA+IHN0YXJ0KSA/IGN1cnIgOiBuZXh0OyAvLyBkZXJpdmUgZW5kIDw9IGxlbmd0aC0yXG4gICAgICByZXN1bHQgKz0gJ1xcbicgKyBsaW5lLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICAgICAgLy8gc2tpcCB0aGUgc3BhY2UgdGhhdCB3YXMgb3V0cHV0IGFzIFxcblxuICAgICAgc3RhcnQgPSBlbmQgKyAxOyAgICAgICAgICAgICAgICAgICAgLy8gZGVyaXZlIHN0YXJ0IDw9IGxlbmd0aC0xXG4gICAgfVxuICAgIGN1cnIgPSBuZXh0O1xuICB9XG5cbiAgLy8gQnkgdGhlIGludmFyaWFudHMsIHN0YXJ0IDw9IGxlbmd0aC0xLCBzbyB0aGVyZSBpcyBzb21ldGhpbmcgbGVmdCBvdmVyLlxuICAvLyBJdCBpcyBlaXRoZXIgdGhlIHdob2xlIHN0cmluZyBvciBhIHBhcnQgc3RhcnRpbmcgZnJvbSBub24td2hpdGVzcGFjZS5cbiAgcmVzdWx0ICs9ICdcXG4nO1xuICAvLyBJbnNlcnQgYSBicmVhayBpZiB0aGUgcmVtYWluZGVyIGlzIHRvbyBsb25nIGFuZCB0aGVyZSBpcyBhIGJyZWFrIGF2YWlsYWJsZS5cbiAgaWYgKGxpbmUubGVuZ3RoIC0gc3RhcnQgPiB3aWR0aCAmJiBjdXJyID4gc3RhcnQpIHtcbiAgICByZXN1bHQgKz0gbGluZS5zbGljZShzdGFydCwgY3VycikgKyAnXFxuJyArIGxpbmUuc2xpY2UoY3VyciArIDEpO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdCArPSBsaW5lLnNsaWNlKHN0YXJ0KTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQuc2xpY2UoMSk7IC8vIGRyb3AgZXh0cmEgXFxuIGpvaW5lclxufVxuXG4vLyBFc2NhcGVzIGEgZG91YmxlLXF1b3RlZCBzdHJpbmcuXG5mdW5jdGlvbiBlc2NhcGVTdHJpbmcoc3RyaW5nKSB7XG4gIHZhciByZXN1bHQgPSAnJztcbiAgdmFyIGNoYXI7XG4gIHZhciBlc2NhcGVTZXE7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyBpKyspIHtcbiAgICBjaGFyID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gICAgZXNjYXBlU2VxID0gRVNDQVBFX1NFUVVFTkNFU1tjaGFyXTtcbiAgICByZXN1bHQgKz0gIWVzY2FwZVNlcSAmJiBpc1ByaW50YWJsZShjaGFyKVxuICAgICAgPyBzdHJpbmdbaV1cbiAgICAgIDogZXNjYXBlU2VxIHx8IGVuY29kZUhleChjaGFyKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgb2JqZWN0KSB7XG4gIHZhciBfcmVzdWx0ID0gJycsXG4gICAgICBfdGFnICAgID0gc3RhdGUudGFnLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgLy8gV3JpdGUgb25seSB2YWxpZCBlbGVtZW50cy5cbiAgICBpZiAod3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0W2luZGV4XSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgaWYgKGluZGV4ICE9PSAwKSBfcmVzdWx0ICs9ICcsICc7XG4gICAgICBfcmVzdWx0ICs9IHN0YXRlLmR1bXA7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9ICdbJyArIF9yZXN1bHQgKyAnXSc7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgY29tcGFjdCkge1xuICB2YXIgX3Jlc3VsdCA9ICcnLFxuICAgICAgX3RhZyAgICA9IHN0YXRlLnRhZyxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIC8vIFdyaXRlIG9ubHkgdmFsaWQgZWxlbWVudHMuXG4gICAgaWYgKHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RbaW5kZXhdLCB0cnVlLCB0cnVlKSkge1xuICAgICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7XG4gICAgICAgIF9yZXN1bHQgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpO1xuICAgICAgfVxuICAgICAgX3Jlc3VsdCArPSAnLSAnICsgc3RhdGUuZHVtcDtcbiAgICB9XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gX3Jlc3VsdCB8fCAnW10nOyAvLyBFbXB0eSBzZXF1ZW5jZSBpZiBubyB2YWxpZCB2YWx1ZXMuXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QpIHtcbiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJyxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoLFxuICAgICAgb2JqZWN0S2V5LFxuICAgICAgb2JqZWN0VmFsdWUsXG4gICAgICBwYWlyQnVmZmVyO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyQnVmZmVyID0gJyc7XG5cbiAgICBpZiAoaW5kZXggIT09IDApIHBhaXJCdWZmZXIgKz0gJywgJztcblxuICAgIG9iamVjdEtleSA9IG9iamVjdEtleUxpc3RbaW5kZXhdO1xuICAgIG9iamVjdFZhbHVlID0gb2JqZWN0W29iamVjdEtleV07XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdEtleSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXk7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLmR1bXAubGVuZ3RoID4gMTAyNCkgcGFpckJ1ZmZlciArPSAnPyAnO1xuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wICsgJzogJztcblxuICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0VmFsdWUsIGZhbHNlLCBmYWxzZSkpIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIHRoaXMgcGFpciBiZWNhdXNlIG9mIGludmFsaWQgdmFsdWUuXG4gICAgfVxuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wO1xuXG4gICAgLy8gQm90aCBrZXkgYW5kIHZhbHVlIGFyZSB2YWxpZC5cbiAgICBfcmVzdWx0ICs9IHBhaXJCdWZmZXI7XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gJ3snICsgX3Jlc3VsdCArICd9Jztcbn1cblxuZnVuY3Rpb24gd3JpdGVCbG9ja01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QsIGNvbXBhY3QpIHtcbiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJyxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoLFxuICAgICAgb2JqZWN0S2V5LFxuICAgICAgb2JqZWN0VmFsdWUsXG4gICAgICBleHBsaWNpdFBhaXIsXG4gICAgICBwYWlyQnVmZmVyO1xuXG4gIC8vIEFsbG93IHNvcnRpbmcga2V5cyBzbyB0aGF0IHRoZSBvdXRwdXQgZmlsZSBpcyBkZXRlcm1pbmlzdGljXG4gIGlmIChzdGF0ZS5zb3J0S2V5cyA9PT0gdHJ1ZSkge1xuICAgIC8vIERlZmF1bHQgc29ydGluZ1xuICAgIG9iamVjdEtleUxpc3Quc29ydCgpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBzdGF0ZS5zb3J0S2V5cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIEN1c3RvbSBzb3J0IGZ1bmN0aW9uXG4gICAgb2JqZWN0S2V5TGlzdC5zb3J0KHN0YXRlLnNvcnRLZXlzKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5zb3J0S2V5cykge1xuICAgIC8vIFNvbWV0aGluZyBpcyB3cm9uZ1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdzb3J0S2V5cyBtdXN0IGJlIGEgYm9vbGVhbiBvciBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0S2V5TGlzdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpckJ1ZmZlciA9ICcnO1xuXG4gICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7XG4gICAgICBwYWlyQnVmZmVyICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBvYmplY3RLZXkgPSBvYmplY3RLZXlMaXN0W2luZGV4XTtcbiAgICBvYmplY3RWYWx1ZSA9IG9iamVjdFtvYmplY3RLZXldO1xuXG4gICAgaWYgKCF3cml0ZU5vZGUoc3RhdGUsIGxldmVsICsgMSwgb2JqZWN0S2V5LCB0cnVlLCB0cnVlLCB0cnVlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXkuXG4gICAgfVxuXG4gICAgZXhwbGljaXRQYWlyID0gKHN0YXRlLnRhZyAhPT0gbnVsbCAmJiBzdGF0ZS50YWcgIT09ICc/JykgfHxcbiAgICAgICAgICAgICAgICAgICAoc3RhdGUuZHVtcCAmJiBzdGF0ZS5kdW1wLmxlbmd0aCA+IDEwMjQpO1xuXG4gICAgaWYgKGV4cGxpY2l0UGFpcikge1xuICAgICAgaWYgKHN0YXRlLmR1bXAgJiYgQ0hBUl9MSU5FX0ZFRUQgPT09IHN0YXRlLmR1bXAuY2hhckNvZGVBdCgwKSkge1xuICAgICAgICBwYWlyQnVmZmVyICs9ICc/JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhaXJCdWZmZXIgKz0gJz8gJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXA7XG5cbiAgICBpZiAoZXhwbGljaXRQYWlyKSB7XG4gICAgICBwYWlyQnVmZmVyICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RWYWx1ZSwgdHJ1ZSwgZXhwbGljaXRQYWlyKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCB2YWx1ZS5cbiAgICB9XG5cbiAgICBpZiAoc3RhdGUuZHVtcCAmJiBDSEFSX0xJTkVfRkVFRCA9PT0gc3RhdGUuZHVtcC5jaGFyQ29kZUF0KDApKSB7XG4gICAgICBwYWlyQnVmZmVyICs9ICc6JztcbiAgICB9IGVsc2Uge1xuICAgICAgcGFpckJ1ZmZlciArPSAnOiAnO1xuICAgIH1cblxuICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcDtcblxuICAgIC8vIEJvdGgga2V5IGFuZCB2YWx1ZSBhcmUgdmFsaWQuXG4gICAgX3Jlc3VsdCArPSBwYWlyQnVmZmVyO1xuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9IF9yZXN1bHQgfHwgJ3t9JzsgLy8gRW1wdHkgbWFwcGluZyBpZiBubyB2YWxpZCBwYWlycy5cbn1cblxuZnVuY3Rpb24gZGV0ZWN0VHlwZShzdGF0ZSwgb2JqZWN0LCBleHBsaWNpdCkge1xuICB2YXIgX3Jlc3VsdCwgdHlwZUxpc3QsIGluZGV4LCBsZW5ndGgsIHR5cGUsIHN0eWxlO1xuXG4gIHR5cGVMaXN0ID0gZXhwbGljaXQgPyBzdGF0ZS5leHBsaWNpdFR5cGVzIDogc3RhdGUuaW1wbGljaXRUeXBlcztcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gdHlwZUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHR5cGUgPSB0eXBlTGlzdFtpbmRleF07XG5cbiAgICBpZiAoKHR5cGUuaW5zdGFuY2VPZiAgfHwgdHlwZS5wcmVkaWNhdGUpICYmXG4gICAgICAgICghdHlwZS5pbnN0YW5jZU9mIHx8ICgodHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcpICYmIChvYmplY3QgaW5zdGFuY2VvZiB0eXBlLmluc3RhbmNlT2YpKSkgJiZcbiAgICAgICAgKCF0eXBlLnByZWRpY2F0ZSAgfHwgdHlwZS5wcmVkaWNhdGUob2JqZWN0KSkpIHtcblxuICAgICAgc3RhdGUudGFnID0gZXhwbGljaXQgPyB0eXBlLnRhZyA6ICc/JztcblxuICAgICAgaWYgKHR5cGUucmVwcmVzZW50KSB7XG4gICAgICAgIHN0eWxlID0gc3RhdGUuc3R5bGVNYXBbdHlwZS50YWddIHx8IHR5cGUuZGVmYXVsdFN0eWxlO1xuXG4gICAgICAgIGlmIChfdG9TdHJpbmcuY2FsbCh0eXBlLnJlcHJlc2VudCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScpIHtcbiAgICAgICAgICBfcmVzdWx0ID0gdHlwZS5yZXByZXNlbnQob2JqZWN0LCBzdHlsZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwodHlwZS5yZXByZXNlbnQsIHN0eWxlKSkge1xuICAgICAgICAgIF9yZXN1bHQgPSB0eXBlLnJlcHJlc2VudFtzdHlsZV0ob2JqZWN0LCBzdHlsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJyE8JyArIHR5cGUudGFnICsgJz4gdGFnIHJlc29sdmVyIGFjY2VwdHMgbm90IFwiJyArIHN0eWxlICsgJ1wiIHN0eWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5kdW1wID0gX3Jlc3VsdDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vLyBTZXJpYWxpemVzIGBvYmplY3RgIGFuZCB3cml0ZXMgaXQgdG8gZ2xvYmFsIGByZXN1bHRgLlxuLy8gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MsIG9yIGZhbHNlIG9uIGludmFsaWQgb2JqZWN0LlxuLy9cbmZ1bmN0aW9uIHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgYmxvY2ssIGNvbXBhY3QsIGlza2V5KSB7XG4gIHN0YXRlLnRhZyA9IG51bGw7XG4gIHN0YXRlLmR1bXAgPSBvYmplY3Q7XG5cbiAgaWYgKCFkZXRlY3RUeXBlKHN0YXRlLCBvYmplY3QsIGZhbHNlKSkge1xuICAgIGRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgdHJ1ZSk7XG4gIH1cblxuICB2YXIgdHlwZSA9IF90b1N0cmluZy5jYWxsKHN0YXRlLmR1bXApO1xuXG4gIGlmIChibG9jaykge1xuICAgIGJsb2NrID0gKHN0YXRlLmZsb3dMZXZlbCA8IDAgfHwgc3RhdGUuZmxvd0xldmVsID4gbGV2ZWwpO1xuICB9XG5cbiAgdmFyIG9iamVjdE9yQXJyYXkgPSB0eXBlID09PSAnW29iamVjdCBPYmplY3RdJyB8fCB0eXBlID09PSAnW29iamVjdCBBcnJheV0nLFxuICAgICAgZHVwbGljYXRlSW5kZXgsXG4gICAgICBkdXBsaWNhdGU7XG5cbiAgaWYgKG9iamVjdE9yQXJyYXkpIHtcbiAgICBkdXBsaWNhdGVJbmRleCA9IHN0YXRlLmR1cGxpY2F0ZXMuaW5kZXhPZihvYmplY3QpO1xuICAgIGR1cGxpY2F0ZSA9IGR1cGxpY2F0ZUluZGV4ICE9PSAtMTtcbiAgfVxuXG4gIGlmICgoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB8fCBkdXBsaWNhdGUgfHwgKHN0YXRlLmluZGVudCAhPT0gMiAmJiBsZXZlbCA+IDApKSB7XG4gICAgY29tcGFjdCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKGR1cGxpY2F0ZSAmJiBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0pIHtcbiAgICBzdGF0ZS5kdW1wID0gJypyZWZfJyArIGR1cGxpY2F0ZUluZGV4O1xuICB9IGVsc2Uge1xuICAgIGlmIChvYmplY3RPckFycmF5ICYmIGR1cGxpY2F0ZSAmJiAhc3RhdGUudXNlZER1cGxpY2F0ZXNbZHVwbGljYXRlSW5kZXhdKSB7XG4gICAgICBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0gPSB0cnVlO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgIGlmIChibG9jayAmJiAoT2JqZWN0LmtleXMoc3RhdGUuZHVtcCkubGVuZ3RoICE9PSAwKSkge1xuICAgICAgICB3cml0ZUJsb2NrTWFwcGluZyhzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXAsIGNvbXBhY3QpO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wKTtcbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyAnICcgKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICBpZiAoYmxvY2sgJiYgKHN0YXRlLmR1bXAubGVuZ3RoICE9PSAwKSkge1xuICAgICAgICB3cml0ZUJsb2NrU2VxdWVuY2Uoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wLCBjb21wYWN0KTtcbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3cml0ZUZsb3dTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXApO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArICcgJyArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IFN0cmluZ10nKSB7XG4gICAgICBpZiAoc3RhdGUudGFnICE9PSAnPycpIHtcbiAgICAgICAgd3JpdGVTY2FsYXIoc3RhdGUsIHN0YXRlLmR1bXAsIGxldmVsLCBpc2tleSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzdGF0ZS5za2lwSW52YWxpZCkgcmV0dXJuIGZhbHNlO1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ3VuYWNjZXB0YWJsZSBraW5kIG9mIGFuIG9iamVjdCB0byBkdW1wICcgKyB0eXBlKTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB7XG4gICAgICBzdGF0ZS5kdW1wID0gJyE8JyArIHN0YXRlLnRhZyArICc+ICcgKyBzdGF0ZS5kdW1wO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBnZXREdXBsaWNhdGVSZWZlcmVuY2VzKG9iamVjdCwgc3RhdGUpIHtcbiAgdmFyIG9iamVjdHMgPSBbXSxcbiAgICAgIGR1cGxpY2F0ZXNJbmRleGVzID0gW10sXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpbnNwZWN0Tm9kZShvYmplY3QsIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gZHVwbGljYXRlc0luZGV4ZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHN0YXRlLmR1cGxpY2F0ZXMucHVzaChvYmplY3RzW2R1cGxpY2F0ZXNJbmRleGVzW2luZGV4XV0pO1xuICB9XG4gIHN0YXRlLnVzZWREdXBsaWNhdGVzID0gbmV3IEFycmF5KGxlbmd0aCk7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3ROb2RlKG9iamVjdCwgb2JqZWN0cywgZHVwbGljYXRlc0luZGV4ZXMpIHtcbiAgdmFyIG9iamVjdEtleUxpc3QsXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpZiAob2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnKSB7XG4gICAgaW5kZXggPSBvYmplY3RzLmluZGV4T2Yob2JqZWN0KTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBpZiAoZHVwbGljYXRlc0luZGV4ZXMuaW5kZXhPZihpbmRleCkgPT09IC0xKSB7XG4gICAgICAgIGR1cGxpY2F0ZXNJbmRleGVzLnB1c2goaW5kZXgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvYmplY3RzLnB1c2gob2JqZWN0KTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3RbaW5kZXhdLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuXG4gICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3Rbb2JqZWN0S2V5TGlzdFtpbmRleF1dLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZHVtcChpbnB1dCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUob3B0aW9ucyk7XG5cbiAgaWYgKCFzdGF0ZS5ub1JlZnMpIGdldER1cGxpY2F0ZVJlZmVyZW5jZXMoaW5wdXQsIHN0YXRlKTtcblxuICBpZiAod3JpdGVOb2RlKHN0YXRlLCAwLCBpbnB1dCwgdHJ1ZSwgdHJ1ZSkpIHJldHVybiBzdGF0ZS5kdW1wICsgJ1xcbic7XG5cbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBzYWZlRHVtcChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gZHVtcChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzLmR1bXAgICAgID0gZHVtcDtcbm1vZHVsZS5leHBvcnRzLnNhZmVEdW1wID0gc2FmZUR1bXA7XG4iLCIvLyBZQU1MIGVycm9yIGNsYXNzLiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzg0NTg5ODRcbi8vXG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIFlBTUxFeGNlcHRpb24ocmVhc29uLCBtYXJrKSB7XG4gIC8vIFN1cGVyIGNvbnN0cnVjdG9yXG4gIEVycm9yLmNhbGwodGhpcyk7XG5cbiAgLy8gSW5jbHVkZSBzdGFjayB0cmFjZSBpbiBlcnJvciBvYmplY3RcbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgLy8gQ2hyb21lIGFuZCBOb2RlSlNcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBGRiwgSUUgMTArIGFuZCBTYWZhcmkgNisuIEZhbGxiYWNrIGZvciBvdGhlcnNcbiAgICB0aGlzLnN0YWNrID0gKG5ldyBFcnJvcigpKS5zdGFjayB8fCAnJztcbiAgfVxuXG4gIHRoaXMubmFtZSA9ICdZQU1MRXhjZXB0aW9uJztcbiAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gIHRoaXMubWFyayA9IG1hcms7XG4gIHRoaXMubWVzc2FnZSA9ICh0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKScpICsgKHRoaXMubWFyayA/ICcgJyArIHRoaXMubWFyay50b1N0cmluZygpIDogJycpO1xufVxuXG5cbi8vIEluaGVyaXQgZnJvbSBFcnJvclxuWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSk7XG5ZQU1MRXhjZXB0aW9uLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFlBTUxFeGNlcHRpb247XG5cblxuWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyhjb21wYWN0KSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLm5hbWUgKyAnOiAnO1xuXG4gIHJlc3VsdCArPSB0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKSc7XG5cbiAgaWYgKCFjb21wYWN0ICYmIHRoaXMubWFyaykge1xuICAgIHJlc3VsdCArPSAnICcgKyB0aGlzLm1hcmsudG9TdHJpbmcoKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gWUFNTEV4Y2VwdGlvbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBtYXgtbGVuLG5vLXVzZS1iZWZvcmUtZGVmaW5lKi9cblxudmFyIGNvbW1vbiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIFlBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xudmFyIE1hcmsgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL21hcmsnKTtcbnZhciBERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG52YXIgREVGQVVMVF9GVUxMX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfZnVsbCcpO1xuXG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5cbnZhciBDT05URVhUX0ZMT1dfSU4gICA9IDE7XG52YXIgQ09OVEVYVF9GTE9XX09VVCAgPSAyO1xudmFyIENPTlRFWFRfQkxPQ0tfSU4gID0gMztcbnZhciBDT05URVhUX0JMT0NLX09VVCA9IDQ7XG5cblxudmFyIENIT01QSU5HX0NMSVAgID0gMTtcbnZhciBDSE9NUElOR19TVFJJUCA9IDI7XG52YXIgQ0hPTVBJTkdfS0VFUCAgPSAzO1xuXG5cbnZhciBQQVRURVJOX05PTl9QUklOVEFCTEUgICAgICAgICA9IC9bXFx4MDAtXFx4MDhcXHgwQlxceDBDXFx4MEUtXFx4MUZcXHg3Ri1cXHg4NFxceDg2LVxceDlGXFx1RkZGRVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdLztcbnZhciBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUyA9IC9bXFx4ODVcXHUyMDI4XFx1MjAyOV0vO1xudmFyIFBBVFRFUk5fRkxPV19JTkRJQ0FUT1JTICAgICAgID0gL1ssXFxbXFxdXFx7XFx9XS87XG52YXIgUEFUVEVSTl9UQUdfSEFORExFICAgICAgICAgICAgPSAvXig/OiF8ISF8IVthLXpcXC1dKyEpJC9pO1xudmFyIFBBVFRFUk5fVEFHX1VSSSAgICAgICAgICAgICAgID0gL14oPzohfFteLFxcW1xcXVxce1xcfV0pKD86JVswLTlhLWZdezJ9fFswLTlhLXpcXC0jO1xcL1xcPzpAJj1cXCtcXCQsX1xcLiF+XFwqJ1xcKFxcKVxcW1xcXV0pKiQvaTtcblxuXG5mdW5jdGlvbiBpc19FT0woYykge1xuICByZXR1cm4gKGMgPT09IDB4MEEvKiBMRiAqLykgfHwgKGMgPT09IDB4MEQvKiBDUiAqLyk7XG59XG5cbmZ1bmN0aW9uIGlzX1dISVRFX1NQQUNFKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fCAoYyA9PT0gMHgyMC8qIFNwYWNlICovKTtcbn1cblxuZnVuY3Rpb24gaXNfV1NfT1JfRU9MKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fFxuICAgICAgICAgKGMgPT09IDB4MjAvKiBTcGFjZSAqLykgfHxcbiAgICAgICAgIChjID09PSAweDBBLyogTEYgKi8pIHx8XG4gICAgICAgICAoYyA9PT0gMHgwRC8qIENSICovKTtcbn1cblxuZnVuY3Rpb24gaXNfRkxPV19JTkRJQ0FUT1IoYykge1xuICByZXR1cm4gYyA9PT0gMHgyQy8qICwgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4NUIvKiBbICovIHx8XG4gICAgICAgICBjID09PSAweDVELyogXSAqLyB8fFxuICAgICAgICAgYyA9PT0gMHg3Qi8qIHsgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4N0QvKiB9ICovO1xufVxuXG5mdW5jdGlvbiBmcm9tSGV4Q29kZShjKSB7XG4gIHZhciBsYztcblxuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIC8qZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSovXG4gIGxjID0gYyB8IDB4MjA7XG5cbiAgaWYgKCgweDYxLyogYSAqLyA8PSBsYykgJiYgKGxjIDw9IDB4NjYvKiBmICovKSkge1xuICAgIHJldHVybiBsYyAtIDB4NjEgKyAxMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlZEhleExlbihjKSB7XG4gIGlmIChjID09PSAweDc4LyogeCAqLykgeyByZXR1cm4gMjsgfVxuICBpZiAoYyA9PT0gMHg3NS8qIHUgKi8pIHsgcmV0dXJuIDQ7IH1cbiAgaWYgKGMgPT09IDB4NTUvKiBVICovKSB7IHJldHVybiA4OyB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBmcm9tRGVjaW1hbENvZGUoYykge1xuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gc2ltcGxlRXNjYXBlU2VxdWVuY2UoYykge1xuICByZXR1cm4gKGMgPT09IDB4MzAvKiAwICovKSA/ICdcXHgwMCcgOlxuICAgICAgICAoYyA9PT0gMHg2MS8qIGEgKi8pID8gJ1xceDA3JyA6XG4gICAgICAgIChjID09PSAweDYyLyogYiAqLykgPyAnXFx4MDgnIDpcbiAgICAgICAgKGMgPT09IDB4NzQvKiB0ICovKSA/ICdcXHgwOScgOlxuICAgICAgICAoYyA9PT0gMHgwOS8qIFRhYiAqLykgPyAnXFx4MDknIDpcbiAgICAgICAgKGMgPT09IDB4NkUvKiBuICovKSA/ICdcXHgwQScgOlxuICAgICAgICAoYyA9PT0gMHg3Ni8qIHYgKi8pID8gJ1xceDBCJyA6XG4gICAgICAgIChjID09PSAweDY2LyogZiAqLykgPyAnXFx4MEMnIDpcbiAgICAgICAgKGMgPT09IDB4NzIvKiByICovKSA/ICdcXHgwRCcgOlxuICAgICAgICAoYyA9PT0gMHg2NS8qIGUgKi8pID8gJ1xceDFCJyA6XG4gICAgICAgIChjID09PSAweDIwLyogU3BhY2UgKi8pID8gJyAnIDpcbiAgICAgICAgKGMgPT09IDB4MjIvKiBcIiAqLykgPyAnXFx4MjInIDpcbiAgICAgICAgKGMgPT09IDB4MkYvKiAvICovKSA/ICcvJyA6XG4gICAgICAgIChjID09PSAweDVDLyogXFwgKi8pID8gJ1xceDVDJyA6XG4gICAgICAgIChjID09PSAweDRFLyogTiAqLykgPyAnXFx4ODUnIDpcbiAgICAgICAgKGMgPT09IDB4NUYvKiBfICovKSA/ICdcXHhBMCcgOlxuICAgICAgICAoYyA9PT0gMHg0Qy8qIEwgKi8pID8gJ1xcdTIwMjgnIDpcbiAgICAgICAgKGMgPT09IDB4NTAvKiBQICovKSA/ICdcXHUyMDI5JyA6ICcnO1xufVxuXG5mdW5jdGlvbiBjaGFyRnJvbUNvZGVwb2ludChjKSB7XG4gIGlmIChjIDw9IDB4RkZGRikge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICB9XG4gIC8vIEVuY29kZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXJcbiAgLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTE2I0NvZGVfcG9pbnRzX1UuMkIwMTAwMDBfdG9fVS4yQjEwRkZGRlxuICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgLSAweDAxMDAwMCkgPj4gMTApICsgMHhEODAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGMgLSAweDAxMDAwMCkgJiAweDAzRkYpICsgMHhEQzAwKTtcbn1cblxudmFyIHNpbXBsZUVzY2FwZUNoZWNrID0gbmV3IEFycmF5KDI1Nik7IC8vIGludGVnZXIsIGZvciBmYXN0IGFjY2Vzc1xudmFyIHNpbXBsZUVzY2FwZU1hcCA9IG5ldyBBcnJheSgyNTYpO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICBzaW1wbGVFc2NhcGVDaGVja1tpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpID8gMSA6IDA7XG4gIHNpbXBsZUVzY2FwZU1hcFtpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpO1xufVxuXG5cbmZ1bmN0aW9uIFN0YXRlKGlucHV0LCBvcHRpb25zKSB7XG4gIHRoaXMuaW5wdXQgPSBpbnB1dDtcblxuICB0aGlzLmZpbGVuYW1lICA9IG9wdGlvbnNbJ2ZpbGVuYW1lJ10gIHx8IG51bGw7XG4gIHRoaXMuc2NoZW1hICAgID0gb3B0aW9uc1snc2NoZW1hJ10gICAgfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5vbldhcm5pbmcgPSBvcHRpb25zWydvbldhcm5pbmcnXSB8fCBudWxsO1xuICB0aGlzLmxlZ2FjeSAgICA9IG9wdGlvbnNbJ2xlZ2FjeSddICAgIHx8IGZhbHNlO1xuICB0aGlzLmpzb24gICAgICA9IG9wdGlvbnNbJ2pzb24nXSAgICAgIHx8IGZhbHNlO1xuICB0aGlzLmxpc3RlbmVyICA9IG9wdGlvbnNbJ2xpc3RlbmVyJ10gIHx8IG51bGw7XG5cbiAgdGhpcy5pbXBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRJbXBsaWNpdDtcbiAgdGhpcy50eXBlTWFwICAgICAgID0gdGhpcy5zY2hlbWEuY29tcGlsZWRUeXBlTWFwO1xuXG4gIHRoaXMubGVuZ3RoICAgICA9IGlucHV0Lmxlbmd0aDtcbiAgdGhpcy5wb3NpdGlvbiAgID0gMDtcbiAgdGhpcy5saW5lICAgICAgID0gMDtcbiAgdGhpcy5saW5lU3RhcnQgID0gMDtcbiAgdGhpcy5saW5lSW5kZW50ID0gMDtcblxuICB0aGlzLmRvY3VtZW50cyA9IFtdO1xuXG4gIC8qXG4gIHRoaXMudmVyc2lvbjtcbiAgdGhpcy5jaGVja0xpbmVCcmVha3M7XG4gIHRoaXMudGFnTWFwO1xuICB0aGlzLmFuY2hvck1hcDtcbiAgdGhpcy50YWc7XG4gIHRoaXMuYW5jaG9yO1xuICB0aGlzLmtpbmQ7XG4gIHRoaXMucmVzdWx0OyovXG5cbn1cblxuXG5mdW5jdGlvbiBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKSB7XG4gIHJldHVybiBuZXcgWUFNTEV4Y2VwdGlvbihcbiAgICBtZXNzYWdlLFxuICAgIG5ldyBNYXJrKHN0YXRlLmZpbGVuYW1lLCBzdGF0ZS5pbnB1dCwgc3RhdGUucG9zaXRpb24sIHN0YXRlLmxpbmUsIChzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydCkpKTtcbn1cblxuZnVuY3Rpb24gdGhyb3dFcnJvcihzdGF0ZSwgbWVzc2FnZSkge1xuICB0aHJvdyBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gdGhyb3dXYXJuaW5nKHN0YXRlLCBtZXNzYWdlKSB7XG4gIGlmIChzdGF0ZS5vbldhcm5pbmcpIHtcbiAgICBzdGF0ZS5vbldhcm5pbmcuY2FsbChudWxsLCBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKSk7XG4gIH1cbn1cblxuXG52YXIgZGlyZWN0aXZlSGFuZGxlcnMgPSB7XG5cbiAgWUFNTDogZnVuY3Rpb24gaGFuZGxlWWFtbERpcmVjdGl2ZShzdGF0ZSwgbmFtZSwgYXJncykge1xuXG4gICAgdmFyIG1hdGNoLCBtYWpvciwgbWlub3I7XG5cbiAgICBpZiAoc3RhdGUudmVyc2lvbiAhPT0gbnVsbCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2R1cGxpY2F0aW9uIG9mICVZQU1MIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ1lBTUwgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSBvbmUgYXJndW1lbnQnKTtcbiAgICB9XG5cbiAgICBtYXRjaCA9IC9eKFswLTldKylcXC4oWzAtOV0rKSQvLmV4ZWMoYXJnc1swXSk7XG5cbiAgICBpZiAobWF0Y2ggPT09IG51bGwpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIGFyZ3VtZW50IG9mIHRoZSBZQU1MIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIG1ham9yID0gcGFyc2VJbnQobWF0Y2hbMV0sIDEwKTtcbiAgICBtaW5vciA9IHBhcnNlSW50KG1hdGNoWzJdLCAxMCk7XG5cbiAgICBpZiAobWFqb3IgIT09IDEpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmFjY2VwdGFibGUgWUFNTCB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCcpO1xuICAgIH1cblxuICAgIHN0YXRlLnZlcnNpb24gPSBhcmdzWzBdO1xuICAgIHN0YXRlLmNoZWNrTGluZUJyZWFrcyA9IChtaW5vciA8IDIpO1xuXG4gICAgaWYgKG1pbm9yICE9PSAxICYmIG1pbm9yICE9PSAyKSB7XG4gICAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICd1bnN1cHBvcnRlZCBZQU1MIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50Jyk7XG4gICAgfVxuICB9LFxuXG4gIFRBRzogZnVuY3Rpb24gaGFuZGxlVGFnRGlyZWN0aXZlKHN0YXRlLCBuYW1lLCBhcmdzKSB7XG5cbiAgICB2YXIgaGFuZGxlLCBwcmVmaXg7XG5cbiAgICBpZiAoYXJncy5sZW5ndGggIT09IDIpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdUQUcgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSB0d28gYXJndW1lbnRzJyk7XG4gICAgfVxuXG4gICAgaGFuZGxlID0gYXJnc1swXTtcbiAgICBwcmVmaXggPSBhcmdzWzFdO1xuXG4gICAgaWYgKCFQQVRURVJOX1RBR19IQU5ETEUudGVzdChoYW5kbGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnaWxsLWZvcm1lZCB0YWcgaGFuZGxlIChmaXJzdCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTtcbiAgICB9XG5cbiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCBoYW5kbGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGhlcmUgaXMgYSBwcmV2aW91c2x5IGRlY2xhcmVkIHN1ZmZpeCBmb3IgXCInICsgaGFuZGxlICsgJ1wiIHRhZyBoYW5kbGUnKTtcbiAgICB9XG5cbiAgICBpZiAoIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHByZWZpeCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIHRhZyBwcmVmaXggKHNlY29uZCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTtcbiAgICB9XG5cbiAgICBzdGF0ZS50YWdNYXBbaGFuZGxlXSA9IHByZWZpeDtcbiAgfVxufTtcblxuXG5mdW5jdGlvbiBjYXB0dXJlU2VnbWVudChzdGF0ZSwgc3RhcnQsIGVuZCwgY2hlY2tKc29uKSB7XG4gIHZhciBfcG9zaXRpb24sIF9sZW5ndGgsIF9jaGFyYWN0ZXIsIF9yZXN1bHQ7XG5cbiAgaWYgKHN0YXJ0IDwgZW5kKSB7XG4gICAgX3Jlc3VsdCA9IHN0YXRlLmlucHV0LnNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgaWYgKGNoZWNrSnNvbikge1xuICAgICAgZm9yIChfcG9zaXRpb24gPSAwLCBfbGVuZ3RoID0gX3Jlc3VsdC5sZW5ndGg7XG4gICAgICAgICAgIF9wb3NpdGlvbiA8IF9sZW5ndGg7XG4gICAgICAgICAgIF9wb3NpdGlvbiArPSAxKSB7XG4gICAgICAgIF9jaGFyYWN0ZXIgPSBfcmVzdWx0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uKTtcbiAgICAgICAgaWYgKCEoX2NoYXJhY3RlciA9PT0gMHgwOSB8fFxuICAgICAgICAgICAgICAoMHgyMCA8PSBfY2hhcmFjdGVyICYmIF9jaGFyYWN0ZXIgPD0gMHgxMEZGRkYpKSkge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdleHBlY3RlZCB2YWxpZCBKU09OIGNoYXJhY3RlcicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChQQVRURVJOX05PTl9QUklOVEFCTEUudGVzdChfcmVzdWx0KSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RoZSBzdHJlYW0gY29udGFpbnMgbm9uLXByaW50YWJsZSBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuXG4gICAgc3RhdGUucmVzdWx0ICs9IF9yZXN1bHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWVyZ2VNYXBwaW5ncyhzdGF0ZSwgZGVzdGluYXRpb24sIHNvdXJjZSwgb3ZlcnJpZGFibGVLZXlzKSB7XG4gIHZhciBzb3VyY2VLZXlzLCBrZXksIGluZGV4LCBxdWFudGl0eTtcblxuICBpZiAoIWNvbW1vbi5pc09iamVjdChzb3VyY2UpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Nhbm5vdCBtZXJnZSBtYXBwaW5nczsgdGhlIHByb3ZpZGVkIHNvdXJjZSBvYmplY3QgaXMgdW5hY2NlcHRhYmxlJyk7XG4gIH1cblxuICBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSBzb3VyY2VLZXlzLmxlbmd0aDsgaW5kZXggPCBxdWFudGl0eTsgaW5kZXggKz0gMSkge1xuICAgIGtleSA9IHNvdXJjZUtleXNbaW5kZXhdO1xuXG4gICAgaWYgKCFfaGFzT3duUHJvcGVydHkuY2FsbChkZXN0aW5hdGlvbiwga2V5KSkge1xuICAgICAgZGVzdGluYXRpb25ba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgb3ZlcnJpZGFibGVLZXlzW2tleV0gPSB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKSB7XG4gIHZhciBpbmRleCwgcXVhbnRpdHk7XG5cbiAga2V5Tm9kZSA9IFN0cmluZyhrZXlOb2RlKTtcblxuICBpZiAoX3Jlc3VsdCA9PT0gbnVsbCkge1xuICAgIF9yZXN1bHQgPSB7fTtcbiAgfVxuXG4gIGlmIChrZXlUYWcgPT09ICd0YWc6eWFtbC5vcmcsMjAwMjptZXJnZScpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZU5vZGUpKSB7XG4gICAgICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSB2YWx1ZU5vZGUubGVuZ3RoOyBpbmRleCA8IHF1YW50aXR5OyBpbmRleCArPSAxKSB7XG4gICAgICAgIG1lcmdlTWFwcGluZ3Moc3RhdGUsIF9yZXN1bHQsIHZhbHVlTm9kZVtpbmRleF0sIG92ZXJyaWRhYmxlS2V5cyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG1lcmdlTWFwcGluZ3Moc3RhdGUsIF9yZXN1bHQsIHZhbHVlTm9kZSwgb3ZlcnJpZGFibGVLZXlzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFzdGF0ZS5qc29uICYmXG4gICAgICAgICFfaGFzT3duUHJvcGVydHkuY2FsbChvdmVycmlkYWJsZUtleXMsIGtleU5vZGUpICYmXG4gICAgICAgIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKF9yZXN1bHQsIGtleU5vZGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRlZCBtYXBwaW5nIGtleScpO1xuICAgIH1cbiAgICBfcmVzdWx0W2tleU5vZGVdID0gdmFsdWVOb2RlO1xuICAgIGRlbGV0ZSBvdmVycmlkYWJsZUtleXNba2V5Tm9kZV07XG4gIH1cblxuICByZXR1cm4gX3Jlc3VsdDtcbn1cblxuZnVuY3Rpb24gcmVhZExpbmVCcmVhayhzdGF0ZSkge1xuICB2YXIgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggPT09IDB4MEEvKiBMRiAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4MEQvKiBDUiAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDBBLyogTEYgKi8pIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdhIGxpbmUgYnJlYWsgaXMgZXhwZWN0ZWQnKTtcbiAgfVxuXG4gIHN0YXRlLmxpbmUgKz0gMTtcbiAgc3RhdGUubGluZVN0YXJ0ID0gc3RhdGUucG9zaXRpb247XG59XG5cbmZ1bmN0aW9uIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGFsbG93Q29tbWVudHMsIGNoZWNrSW5kZW50KSB7XG4gIHZhciBsaW5lQnJlYWtzID0gMCxcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmIChhbGxvd0NvbW1lbnRzICYmIGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgZG8ge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9IHdoaWxlIChjaCAhPT0gMHgwQS8qIExGICovICYmIGNoICE9PSAweDBELyogQ1IgKi8gJiYgY2ggIT09IDApO1xuICAgIH1cblxuICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICByZWFkTGluZUJyZWFrKHN0YXRlKTtcblxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgIGxpbmVCcmVha3MrKztcbiAgICAgIHN0YXRlLmxpbmVJbmRlbnQgPSAwO1xuXG4gICAgICB3aGlsZSAoY2ggPT09IDB4MjAvKiBTcGFjZSAqLykge1xuICAgICAgICBzdGF0ZS5saW5lSW5kZW50Kys7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNoZWNrSW5kZW50ICE9PSAtMSAmJiBsaW5lQnJlYWtzICE9PSAwICYmIHN0YXRlLmxpbmVJbmRlbnQgPCBjaGVja0luZGVudCkge1xuICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ2RlZmljaWVudCBpbmRlbnRhdGlvbicpO1xuICB9XG5cbiAgcmV0dXJuIGxpbmVCcmVha3M7XG59XG5cbmZ1bmN0aW9uIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb24sXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uKTtcblxuICAvLyBDb25kaXRpb24gc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCBpcyB0ZXN0ZWRcbiAgLy8gaW4gcGFyZW50IG9uIGVhY2ggY2FsbCwgZm9yIGVmZmljaWVuY3kuIE5vIG5lZWRzIHRvIHRlc3QgaGVyZSBhZ2Fpbi5cbiAgaWYgKChjaCA9PT0gMHgyRC8qIC0gKi8gfHwgY2ggPT09IDB4MkUvKiAuICovKSAmJlxuICAgICAgY2ggPT09IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uICsgMSkgJiZcbiAgICAgIGNoID09PSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KF9wb3NpdGlvbiArIDIpKSB7XG5cbiAgICBfcG9zaXRpb24gKz0gMztcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSAwIHx8IGlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgY291bnQpIHtcbiAgaWYgKGNvdW50ID09PSAxKSB7XG4gICAgc3RhdGUucmVzdWx0ICs9ICcgJztcbiAgfSBlbHNlIGlmIChjb3VudCA+IDEpIHtcbiAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgY291bnQgLSAxKTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCwgd2l0aGluRmxvd0NvbGxlY3Rpb24pIHtcbiAgdmFyIHByZWNlZGluZyxcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIGNhcHR1cmVTdGFydCxcbiAgICAgIGNhcHR1cmVFbmQsXG4gICAgICBoYXNQZW5kaW5nQ29udGVudCxcbiAgICAgIF9saW5lLFxuICAgICAgX2xpbmVTdGFydCxcbiAgICAgIF9saW5lSW5kZW50LFxuICAgICAgX2tpbmQgPSBzdGF0ZS5raW5kLFxuICAgICAgX3Jlc3VsdCA9IHN0YXRlLnJlc3VsdCxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGlzX1dTX09SX0VPTChjaCkgICAgICB8fFxuICAgICAgaXNfRkxPV19JTkRJQ0FUT1IoY2gpIHx8XG4gICAgICBjaCA9PT0gMHgyMy8qICMgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI2LyogJiAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MkEvKiAqICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyMS8qICEgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDdDLyogfCAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4M0UvKiA+ICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyNy8qICcgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDIyLyogXCIgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI1LyogJSAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4NDAvKiBAICovICAgIHx8XG4gICAgICBjaCA9PT0gMHg2MC8qIGAgKi8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoY2ggPT09IDB4M0YvKiA/ICovIHx8IGNoID09PSAweDJELyogLSAqLykge1xuICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgIGlmIChpc19XU19PUl9FT0woZm9sbG93aW5nKSB8fFxuICAgICAgICB3aXRoaW5GbG93Q29sbGVjdGlvbiAmJiBpc19GTE9XX0lORElDQVRPUihmb2xsb3dpbmcpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuXG4gIHdoaWxlIChjaCAhPT0gMCkge1xuICAgIGlmIChjaCA9PT0gMHgzQS8qIDogKi8pIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpIHx8XG4gICAgICAgICAgd2l0aGluRmxvd0NvbGxlY3Rpb24gJiYgaXNfRkxPV19JTkRJQ0FUT1IoZm9sbG93aW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4MjMvKiAjICovKSB7XG4gICAgICBwcmVjZWRpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uIC0gMSk7XG5cbiAgICAgIGlmIChpc19XU19PUl9FT0wocHJlY2VkaW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkgfHxcbiAgICAgICAgICAgICAgIHdpdGhpbkZsb3dDb2xsZWN0aW9uICYmIGlzX0ZMT1dfSU5ESUNBVE9SKGNoKSkge1xuICAgICAgYnJlYWs7XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIF9saW5lID0gc3RhdGUubGluZTtcbiAgICAgIF9saW5lU3RhcnQgPSBzdGF0ZS5saW5lU3RhcnQ7XG4gICAgICBfbGluZUluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgLTEpO1xuXG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+PSBub2RlSW5kZW50KSB7XG4gICAgICAgIGhhc1BlbmRpbmdDb250ZW50ID0gdHJ1ZTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbiA9IGNhcHR1cmVFbmQ7XG4gICAgICAgIHN0YXRlLmxpbmUgPSBfbGluZTtcbiAgICAgICAgc3RhdGUubGluZVN0YXJ0ID0gX2xpbmVTdGFydDtcbiAgICAgICAgc3RhdGUubGluZUluZGVudCA9IF9saW5lSW5kZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGFzUGVuZGluZ0NvbnRlbnQpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcbiAgICAgIHdyaXRlRm9sZGVkTGluZXMoc3RhdGUsIHN0YXRlLmxpbmUgLSBfbGluZSk7XG4gICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgIH1cblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgfVxuXG4gIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcblxuICBpZiAoc3RhdGUucmVzdWx0KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzdGF0ZS5raW5kID0gX2tpbmQ7XG4gIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZFNpbmdsZVF1b3RlZFNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgY2gsXG4gICAgICBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQ7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjcvKiAnICovKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgc3RhdGUucG9zaXRpb24rKztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlICgoY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkgIT09IDApIHtcbiAgICBpZiAoY2ggPT09IDB4MjcvKiAnICovKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyNy8qICcgKi8pIHtcbiAgICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIHRydWUpO1xuICAgICAgd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgZmFsc2UsIG5vZGVJbmRlbnQpKTtcbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIGRvY3VtZW50IHdpdGhpbiBhIHNpbmdsZSBxdW90ZWQgc2NhbGFyJyk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgIGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBzaW5nbGUgcXVvdGVkIHNjYWxhcicpO1xufVxuXG5mdW5jdGlvbiByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBjYXB0dXJlRW5kLFxuICAgICAgaGV4TGVuZ3RoLFxuICAgICAgaGV4UmVzdWx0LFxuICAgICAgdG1wLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjIvKiBcIiAqLykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN0YXRlLmtpbmQgPSAnc2NhbGFyJztcbiAgc3RhdGUucmVzdWx0ID0gJyc7XG4gIHN0YXRlLnBvc2l0aW9uKys7XG4gIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICB3aGlsZSAoKGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikpICE9PSAwKSB7XG4gICAgaWYgKGNoID09PSAweDIyLyogXCIgKi8pIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCB0cnVlKTtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4NUMvKiBcXCAqLykge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIHRydWUpO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCk7XG5cbiAgICAgICAgLy8gVE9ETzogcmV3b3JrIHRvIGlubGluZSBmbiB3aXRoIG5vIHR5cGUgY2FzdD9cbiAgICAgIH0gZWxzZSBpZiAoY2ggPCAyNTYgJiYgc2ltcGxlRXNjYXBlQ2hlY2tbY2hdKSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBzaW1wbGVFc2NhcGVNYXBbY2hdO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuXG4gICAgICB9IGVsc2UgaWYgKCh0bXAgPSBlc2NhcGVkSGV4TGVuKGNoKSkgPiAwKSB7XG4gICAgICAgIGhleExlbmd0aCA9IHRtcDtcbiAgICAgICAgaGV4UmVzdWx0ID0gMDtcblxuICAgICAgICBmb3IgKDsgaGV4TGVuZ3RoID4gMDsgaGV4TGVuZ3RoLS0pIHtcbiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgICAgICBpZiAoKHRtcCA9IGZyb21IZXhDb2RlKGNoKSkgPj0gMCkge1xuICAgICAgICAgICAgaGV4UmVzdWx0ID0gKGhleFJlc3VsdCA8PCA0KSArIHRtcDtcblxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZXhwZWN0ZWQgaGV4YWRlY2ltYWwgY2hhcmFjdGVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNoYXJGcm9tQ29kZXBvaW50KGhleFJlc3VsdCk7XG5cbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3Vua25vd24gZXNjYXBlIHNlcXVlbmNlJyk7XG4gICAgICB9XG5cbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgdHJ1ZSk7XG4gICAgICB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCkpO1xuICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgfSBlbHNlIGlmIChzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0ICYmIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgZG9jdW1lbnQgd2l0aGluIGEgZG91YmxlIHF1b3RlZCBzY2FsYXInKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgIH1cbiAgfVxuXG4gIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIGRvdWJsZSBxdW90ZWQgc2NhbGFyJyk7XG59XG5cbmZ1bmN0aW9uIHJlYWRGbG93Q29sbGVjdGlvbihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgcmVhZE5leHQgPSB0cnVlLFxuICAgICAgX2xpbmUsXG4gICAgICBfdGFnICAgICA9IHN0YXRlLnRhZyxcbiAgICAgIF9yZXN1bHQsXG4gICAgICBfYW5jaG9yICA9IHN0YXRlLmFuY2hvcixcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIHRlcm1pbmF0b3IsXG4gICAgICBpc1BhaXIsXG4gICAgICBpc0V4cGxpY2l0UGFpcixcbiAgICAgIGlzTWFwcGluZyxcbiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LFxuICAgICAga2V5Tm9kZSxcbiAgICAgIGtleVRhZyxcbiAgICAgIHZhbHVlTm9kZSxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoID09PSAweDVCLyogWyAqLykge1xuICAgIHRlcm1pbmF0b3IgPSAweDVEOy8qIF0gKi9cbiAgICBpc01hcHBpbmcgPSBmYWxzZTtcbiAgICBfcmVzdWx0ID0gW107XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4N0IvKiB7ICovKSB7XG4gICAgdGVybWluYXRvciA9IDB4N0Q7LyogfSAqL1xuICAgIGlzTWFwcGluZyA9IHRydWU7XG4gICAgX3Jlc3VsdCA9IHt9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSB0ZXJtaW5hdG9yKSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgc3RhdGUudGFnID0gX3RhZztcbiAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICBzdGF0ZS5raW5kID0gaXNNYXBwaW5nID8gJ21hcHBpbmcnIDogJ3NlcXVlbmNlJztcbiAgICAgIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCFyZWFkTmV4dCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ21pc3NlZCBjb21tYSBiZXR3ZWVuIGZsb3cgY29sbGVjdGlvbiBlbnRyaWVzJyk7XG4gICAgfVxuXG4gICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgaXNQYWlyID0gaXNFeHBsaWNpdFBhaXIgPSBmYWxzZTtcblxuICAgIGlmIChjaCA9PT0gMHgzRi8qID8gKi8pIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG4gICAgICAgIGlzUGFpciA9IGlzRXhwbGljaXRQYWlyID0gdHJ1ZTtcbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICBrZXlUYWcgPSBzdGF0ZS50YWc7XG4gICAga2V5Tm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoKGlzRXhwbGljaXRQYWlyIHx8IHN0YXRlLmxpbmUgPT09IF9saW5lKSAmJiBjaCA9PT0gMHgzQS8qIDogKi8pIHtcbiAgICAgIGlzUGFpciA9IHRydWU7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcbiAgICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICB9XG5cbiAgICBpZiAoaXNNYXBwaW5nKSB7XG4gICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKTtcbiAgICB9IGVsc2UgaWYgKGlzUGFpcikge1xuICAgICAgX3Jlc3VsdC5wdXNoKHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIG51bGwsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCB2YWx1ZU5vZGUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3Jlc3VsdC5wdXNoKGtleU5vZGUpO1xuICAgIH1cblxuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChjaCA9PT0gMHgyQy8qICwgKi8pIHtcbiAgICAgIHJlYWROZXh0ID0gdHJ1ZTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVhZE5leHQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBmbG93IGNvbGxlY3Rpb24nKTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBmb2xkaW5nLFxuICAgICAgY2hvbXBpbmcgICAgICAgPSBDSE9NUElOR19DTElQLFxuICAgICAgZGlkUmVhZENvbnRlbnQgPSBmYWxzZSxcbiAgICAgIGRldGVjdGVkSW5kZW50ID0gZmFsc2UsXG4gICAgICB0ZXh0SW5kZW50ICAgICA9IG5vZGVJbmRlbnQsXG4gICAgICBlbXB0eUxpbmVzICAgICA9IDAsXG4gICAgICBhdE1vcmVJbmRlbnRlZCA9IGZhbHNlLFxuICAgICAgdG1wLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggPT09IDB4N0MvKiB8ICovKSB7XG4gICAgZm9sZGluZyA9IGZhbHNlO1xuICB9IGVsc2UgaWYgKGNoID09PSAweDNFLyogPiAqLykge1xuICAgIGZvbGRpbmcgPSB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN0YXRlLmtpbmQgPSAnc2NhbGFyJztcbiAgc3RhdGUucmVzdWx0ID0gJyc7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSAweDJCLyogKyAqLyB8fCBjaCA9PT0gMHgyRC8qIC0gKi8pIHtcbiAgICAgIGlmIChDSE9NUElOR19DTElQID09PSBjaG9tcGluZykge1xuICAgICAgICBjaG9tcGluZyA9IChjaCA9PT0gMHgyQi8qICsgKi8pID8gQ0hPTVBJTkdfS0VFUCA6IENIT01QSU5HX1NUUklQO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3JlcGVhdCBvZiBhIGNob21waW5nIG1vZGUgaWRlbnRpZmllcicpO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIGlmICgodG1wID0gZnJvbURlY2ltYWxDb2RlKGNoKSkgPj0gMCkge1xuICAgICAgaWYgKHRtcCA9PT0gMCkge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYmFkIGV4cGxpY2l0IGluZGVudGF0aW9uIHdpZHRoIG9mIGEgYmxvY2sgc2NhbGFyOyBpdCBjYW5ub3QgYmUgbGVzcyB0aGFuIG9uZScpO1xuICAgICAgfSBlbHNlIGlmICghZGV0ZWN0ZWRJbmRlbnQpIHtcbiAgICAgICAgdGV4dEluZGVudCA9IG5vZGVJbmRlbnQgKyB0bXAgLSAxO1xuICAgICAgICBkZXRlY3RlZEluZGVudCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAncmVwZWF0IG9mIGFuIGluZGVudGF0aW9uIHdpZHRoIGlkZW50aWZpZXInKTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKTtcblxuICAgIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHtcbiAgICAgIGRvIHsgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOyB9XG4gICAgICB3aGlsZSAoIWlzX0VPTChjaCkgJiYgKGNoICE9PSAwKSk7XG4gICAgfVxuICB9XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgcmVhZExpbmVCcmVhayhzdGF0ZSk7XG4gICAgc3RhdGUubGluZUluZGVudCA9IDA7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgd2hpbGUgKCghZGV0ZWN0ZWRJbmRlbnQgfHwgc3RhdGUubGluZUluZGVudCA8IHRleHRJbmRlbnQpICYmXG4gICAgICAgICAgIChjaCA9PT0gMHgyMC8qIFNwYWNlICovKSkge1xuICAgICAgc3RhdGUubGluZUluZGVudCsrO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmICghZGV0ZWN0ZWRJbmRlbnQgJiYgc3RhdGUubGluZUluZGVudCA+IHRleHRJbmRlbnQpIHtcbiAgICAgIHRleHRJbmRlbnQgPSBzdGF0ZS5saW5lSW5kZW50O1xuICAgIH1cblxuICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICBlbXB0eUxpbmVzKys7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBFbmQgb2YgdGhlIHNjYWxhci5cbiAgICBpZiAoc3RhdGUubGluZUluZGVudCA8IHRleHRJbmRlbnQpIHtcblxuICAgICAgLy8gUGVyZm9ybSB0aGUgY2hvbXBpbmcuXG4gICAgICBpZiAoY2hvbXBpbmcgPT09IENIT01QSU5HX0tFRVApIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGRpZFJlYWRDb250ZW50ID8gMSArIGVtcHR5TGluZXMgOiBlbXB0eUxpbmVzKTtcbiAgICAgIH0gZWxzZSBpZiAoY2hvbXBpbmcgPT09IENIT01QSU5HX0NMSVApIHtcbiAgICAgICAgaWYgKGRpZFJlYWRDb250ZW50KSB7IC8vIGkuZS4gb25seSBpZiB0aGUgc2NhbGFyIGlzIG5vdCBlbXB0eS5cbiAgICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gJ1xcbic7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQnJlYWsgdGhpcyBgd2hpbGVgIGN5Y2xlIGFuZCBnbyB0byB0aGUgZnVuY2l0b24ncyBlcGlsb2d1ZS5cbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIEZvbGRlZCBzdHlsZTogdXNlIGZhbmN5IHJ1bGVzIHRvIGhhbmRsZSBsaW5lIGJyZWFrcy5cbiAgICBpZiAoZm9sZGluZykge1xuXG4gICAgICAvLyBMaW5lcyBzdGFydGluZyB3aXRoIHdoaXRlIHNwYWNlIGNoYXJhY3RlcnMgKG1vcmUtaW5kZW50ZWQgbGluZXMpIGFyZSBub3QgZm9sZGVkLlxuICAgICAgaWYgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgICBhdE1vcmVJbmRlbnRlZCA9IHRydWU7XG4gICAgICAgIC8vIGV4Y2VwdCBmb3IgdGhlIGZpcnN0IGNvbnRlbnQgbGluZSAoY2YuIEV4YW1wbGUgOC4xKVxuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZGlkUmVhZENvbnRlbnQgPyAxICsgZW1wdHlMaW5lcyA6IGVtcHR5TGluZXMpO1xuXG4gICAgICAvLyBFbmQgb2YgbW9yZS1pbmRlbnRlZCBibG9jay5cbiAgICAgIH0gZWxzZSBpZiAoYXRNb3JlSW5kZW50ZWQpIHtcbiAgICAgICAgYXRNb3JlSW5kZW50ZWQgPSBmYWxzZTtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGVtcHR5TGluZXMgKyAxKTtcblxuICAgICAgLy8gSnVzdCBvbmUgbGluZSBicmVhayAtIHBlcmNlaXZlIGFzIHRoZSBzYW1lIGxpbmUuXG4gICAgICB9IGVsc2UgaWYgKGVtcHR5TGluZXMgPT09IDApIHtcbiAgICAgICAgaWYgKGRpZFJlYWRDb250ZW50KSB7IC8vIGkuZS4gb25seSBpZiB3ZSBoYXZlIGFscmVhZHkgcmVhZCBzb21lIHNjYWxhciBjb250ZW50LlxuICAgICAgICAgIHN0YXRlLnJlc3VsdCArPSAnICc7XG4gICAgICAgIH1cblxuICAgICAgLy8gU2V2ZXJhbCBsaW5lIGJyZWFrcyAtIHBlcmNlaXZlIGFzIGRpZmZlcmVudCBsaW5lcy5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBlbXB0eUxpbmVzKTtcbiAgICAgIH1cblxuICAgIC8vIExpdGVyYWwgc3R5bGU6IGp1c3QgYWRkIGV4YWN0IG51bWJlciBvZiBsaW5lIGJyZWFrcyBiZXR3ZWVuIGNvbnRlbnQgbGluZXMuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEtlZXAgYWxsIGxpbmUgYnJlYWtzIGV4Y2VwdCB0aGUgaGVhZGVyIGxpbmUgYnJlYWsuXG4gICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZGlkUmVhZENvbnRlbnQgPyAxICsgZW1wdHlMaW5lcyA6IGVtcHR5TGluZXMpO1xuICAgIH1cblxuICAgIGRpZFJlYWRDb250ZW50ID0gdHJ1ZTtcbiAgICBkZXRlY3RlZEluZGVudCA9IHRydWU7XG4gICAgZW1wdHlMaW5lcyA9IDA7XG4gICAgY2FwdHVyZVN0YXJ0ID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB3aGlsZSAoIWlzX0VPTChjaCkgJiYgKGNoICE9PSAwKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCBmYWxzZSk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIG5vZGVJbmRlbnQpIHtcbiAgdmFyIF9saW5lLFxuICAgICAgX3RhZyAgICAgID0gc3RhdGUudGFnLFxuICAgICAgX2FuY2hvciAgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgX3Jlc3VsdCAgID0gW10sXG4gICAgICBmb2xsb3dpbmcsXG4gICAgICBkZXRlY3RlZCAgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIHdoaWxlIChjaCAhPT0gMCkge1xuXG4gICAgaWYgKGNoICE9PSAweDJELyogLSAqLykge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgaWYgKCFpc19XU19PUl9FT0woZm9sbG93aW5nKSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZGV0ZWN0ZWQgPSB0cnVlO1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG5cbiAgICBpZiAoc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpKSB7XG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA8PSBub2RlSW5kZW50KSB7XG4gICAgICAgIF9yZXN1bHQucHVzaChudWxsKTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0JMT0NLX0lOLCBmYWxzZSwgdHJ1ZSk7XG4gICAgX3Jlc3VsdC5wdXNoKHN0YXRlLnJlc3VsdCk7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmICgoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpICYmIChjaCAhPT0gMCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgaW5kZW50YXRpb24gb2YgYSBzZXF1ZW5jZSBlbnRyeScpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChkZXRlY3RlZCkge1xuICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICBzdGF0ZS5raW5kID0gJ3NlcXVlbmNlJztcbiAgICBzdGF0ZS5yZXN1bHQgPSBfcmVzdWx0O1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrTWFwcGluZyhzdGF0ZSwgbm9kZUluZGVudCwgZmxvd0luZGVudCkge1xuICB2YXIgZm9sbG93aW5nLFxuICAgICAgYWxsb3dDb21wYWN0LFxuICAgICAgX2xpbmUsXG4gICAgICBfdGFnICAgICAgICAgID0gc3RhdGUudGFnLFxuICAgICAgX2FuY2hvciAgICAgICA9IHN0YXRlLmFuY2hvcixcbiAgICAgIF9yZXN1bHQgICAgICAgPSB7fSxcbiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LFxuICAgICAga2V5VGFnICAgICAgICA9IG51bGwsXG4gICAgICBrZXlOb2RlICAgICAgID0gbnVsbCxcbiAgICAgIHZhbHVlTm9kZSAgICAgPSBudWxsLFxuICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlLFxuICAgICAgZGV0ZWN0ZWQgICAgICA9IGZhbHNlLFxuICAgICAgY2g7XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuICAgIF9saW5lID0gc3RhdGUubGluZTsgLy8gU2F2ZSB0aGUgY3VycmVudCBsaW5lLlxuXG4gICAgLy9cbiAgICAvLyBFeHBsaWNpdCBub3RhdGlvbiBjYXNlLiBUaGVyZSBhcmUgdHdvIHNlcGFyYXRlIGJsb2NrczpcbiAgICAvLyBmaXJzdCBmb3IgdGhlIGtleSAoZGVub3RlZCBieSBcIj9cIikgYW5kIHNlY29uZCBmb3IgdGhlIHZhbHVlIChkZW5vdGVkIGJ5IFwiOlwiKVxuICAgIC8vXG4gICAgaWYgKChjaCA9PT0gMHgzRi8qID8gKi8gfHwgY2ggPT09IDB4M0EvKiA6ICovKSAmJiBpc19XU19PUl9FT0woZm9sbG93aW5nKSkge1xuXG4gICAgICBpZiAoY2ggPT09IDB4M0YvKiA/ICovKSB7XG4gICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIG51bGwpO1xuICAgICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgZGV0ZWN0ZWQgPSB0cnVlO1xuICAgICAgICBhdEV4cGxpY2l0S2V5ID0gdHJ1ZTtcbiAgICAgICAgYWxsb3dDb21wYWN0ID0gdHJ1ZTtcblxuICAgICAgfSBlbHNlIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgIC8vIGkuZS4gMHgzQS8qIDogKi8gPT09IGNoYXJhY3RlciBhZnRlciB0aGUgZXhwbGljaXQga2V5LlxuICAgICAgICBhdEV4cGxpY2l0S2V5ID0gZmFsc2U7XG4gICAgICAgIGFsbG93Q29tcGFjdCA9IHRydWU7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbmNvbXBsZXRlIGV4cGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBrZXkgbm9kZSBpcyBtaXNzZWQnKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGUucG9zaXRpb24gKz0gMTtcbiAgICAgIGNoID0gZm9sbG93aW5nO1xuXG4gICAgLy9cbiAgICAvLyBJbXBsaWNpdCBub3RhdGlvbiBjYXNlLiBGbG93LXN0eWxlIG5vZGUgYXMgdGhlIGtleSBmaXJzdCwgdGhlbiBcIjpcIiwgYW5kIHRoZSB2YWx1ZS5cbiAgICAvL1xuICAgIH0gZWxzZSBpZiAoY29tcG9zZU5vZGUoc3RhdGUsIGZsb3dJbmRlbnQsIENPTlRFWFRfRkxPV19PVVQsIGZhbHNlLCB0cnVlKSkge1xuXG4gICAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUpIHtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoID09PSAweDNBLyogOiAqLykge1xuICAgICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICAgIGlmICghaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Egd2hpdGVzcGFjZSBjaGFyYWN0ZXIgaXMgZXhwZWN0ZWQgYWZ0ZXIgdGhlIGtleS12YWx1ZSBzZXBhcmF0b3Igd2l0aGluIGEgYmxvY2sgbWFwcGluZycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gICAgICAgICAgICBrZXlUYWcgPSBrZXlOb2RlID0gdmFsdWVOb2RlID0gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlO1xuICAgICAgICAgIGFsbG93Q29tcGFjdCA9IGZhbHNlO1xuICAgICAgICAgIGtleVRhZyA9IHN0YXRlLnRhZztcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZGV0ZWN0ZWQpIHtcbiAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGFuIGltcGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBjb2xvbiBpcyBtaXNzZWQnKTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gS2VlcCB0aGUgcmVzdWx0IG9mIGBjb21wb3NlTm9kZWAuXG4gICAgICAgIH1cblxuICAgICAgfSBlbHNlIGlmIChkZXRlY3RlZCkge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGEgYmxvY2sgbWFwcGluZyBlbnRyeTsgYSBtdWx0aWxpbmUga2V5IG1heSBub3QgYmUgYW4gaW1wbGljaXQga2V5Jyk7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIHRoZSByZXN1bHQgb2YgYGNvbXBvc2VOb2RlYC5cbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhazsgLy8gUmVhZGluZyBpcyBkb25lLiBHbyB0byB0aGUgZXBpbG9ndWUuXG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBDb21tb24gcmVhZGluZyBjb2RlIGZvciBib3RoIGV4cGxpY2l0IGFuZCBpbXBsaWNpdCBub3RhdGlvbnMuXG4gICAgLy9cbiAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpIHtcbiAgICAgIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgbm9kZUluZGVudCwgQ09OVEVYVF9CTE9DS19PVVQsIHRydWUsIGFsbG93Q29tcGFjdCkpIHtcbiAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSk7XG4gICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gbm9kZUluZGVudCAmJiAoY2ggIT09IDApKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYmFkIGluZGVudGF0aW9uIG9mIGEgbWFwcGluZyBlbnRyeScpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vXG4gIC8vIEVwaWxvZ3VlLlxuICAvL1xuXG4gIC8vIFNwZWNpYWwgY2FzZTogbGFzdCBtYXBwaW5nJ3Mgbm9kZSBjb250YWlucyBvbmx5IHRoZSBrZXkgaW4gZXhwbGljaXQgbm90YXRpb24uXG4gIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIG51bGwpO1xuICB9XG5cbiAgLy8gRXhwb3NlIHRoZSByZXN1bHRpbmcgbWFwcGluZy5cbiAgaWYgKGRldGVjdGVkKSB7XG4gICAgc3RhdGUudGFnID0gX3RhZztcbiAgICBzdGF0ZS5hbmNob3IgPSBfYW5jaG9yO1xuICAgIHN0YXRlLmtpbmQgPSAnbWFwcGluZyc7XG4gICAgc3RhdGUucmVzdWx0ID0gX3Jlc3VsdDtcbiAgfVxuXG4gIHJldHVybiBkZXRlY3RlZDtcbn1cblxuZnVuY3Rpb24gcmVhZFRhZ1Byb3BlcnR5KHN0YXRlKSB7XG4gIHZhciBfcG9zaXRpb24sXG4gICAgICBpc1ZlcmJhdGltID0gZmFsc2UsXG4gICAgICBpc05hbWVkICAgID0gZmFsc2UsXG4gICAgICB0YWdIYW5kbGUsXG4gICAgICB0YWdOYW1lLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjEvKiAhICovKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGlvbiBvZiBhIHRhZyBwcm9wZXJ0eScpO1xuICB9XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHgzQy8qIDwgKi8pIHtcbiAgICBpc1ZlcmJhdGltID0gdHJ1ZTtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgfSBlbHNlIGlmIChjaCA9PT0gMHgyMS8qICEgKi8pIHtcbiAgICBpc05hbWVkID0gdHJ1ZTtcbiAgICB0YWdIYW5kbGUgPSAnISEnO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICB9IGVsc2Uge1xuICAgIHRhZ0hhbmRsZSA9ICchJztcbiAgfVxuXG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIGlmIChpc1ZlcmJhdGltKSB7XG4gICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgY2ggIT09IDB4M0UvKiA+ICovKTtcblxuICAgIGlmIChzdGF0ZS5wb3NpdGlvbiA8IHN0YXRlLmxlbmd0aCkge1xuICAgICAgdGFnTmFtZSA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSB2ZXJiYXRpbSB0YWcnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpKSB7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyMS8qICEgKi8pIHtcbiAgICAgICAgaWYgKCFpc05hbWVkKSB7XG4gICAgICAgICAgdGFnSGFuZGxlID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uIC0gMSwgc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgICAgIGlmICghUEFUVEVSTl9UQUdfSEFORExFLnRlc3QodGFnSGFuZGxlKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ25hbWVkIHRhZyBoYW5kbGUgY2Fubm90IGNvbnRhaW4gc3VjaCBjaGFyYWN0ZXJzJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaXNOYW1lZCA9IHRydWU7XG4gICAgICAgICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0YWcgc3VmZml4IGNhbm5vdCBjb250YWluIGV4Y2xhbWF0aW9uIG1hcmtzJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIHRhZ05hbWUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChQQVRURVJOX0ZMT1dfSU5ESUNBVE9SUy50ZXN0KHRhZ05hbWUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGFnIHN1ZmZpeCBjYW5ub3QgY29udGFpbiBmbG93IGluZGljYXRvciBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRhZ05hbWUgJiYgIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHRhZ05hbWUpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RhZyBuYW1lIGNhbm5vdCBjb250YWluIHN1Y2ggY2hhcmFjdGVyczogJyArIHRhZ05hbWUpO1xuICB9XG5cbiAgaWYgKGlzVmVyYmF0aW0pIHtcbiAgICBzdGF0ZS50YWcgPSB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCB0YWdIYW5kbGUpKSB7XG4gICAgc3RhdGUudGFnID0gc3RhdGUudGFnTWFwW3RhZ0hhbmRsZV0gKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnIScpIHtcbiAgICBzdGF0ZS50YWcgPSAnIScgKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnISEnKSB7XG4gICAgc3RhdGUudGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZGVjbGFyZWQgdGFnIGhhbmRsZSBcIicgKyB0YWdIYW5kbGUgKyAnXCInKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQW5jaG9yUHJvcGVydHkoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbixcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoICE9PSAweDI2LyogJiAqLykgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRpb24gb2YgYW4gYW5jaG9yIHByb3BlcnR5Jyk7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbmNob3Igbm9kZSBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIGNoYXJhY3RlcicpO1xuICB9XG5cbiAgc3RhdGUuYW5jaG9yID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQWxpYXMoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbiwgYWxpYXMsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyQS8qICogKi8pIHJldHVybiBmYWxzZTtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbGlhcyBub2RlIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyJyk7XG4gIH1cblxuICBhbGlhcyA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmICghc3RhdGUuYW5jaG9yTWFwLmhhc093blByb3BlcnR5KGFsaWFzKSkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmlkZW50aWZpZWQgYWxpYXMgXCInICsgYWxpYXMgKyAnXCInKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VsdCA9IHN0YXRlLmFuY2hvck1hcFthbGlhc107XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbXBvc2VOb2RlKHN0YXRlLCBwYXJlbnRJbmRlbnQsIG5vZGVDb250ZXh0LCBhbGxvd1RvU2VlaywgYWxsb3dDb21wYWN0KSB7XG4gIHZhciBhbGxvd0Jsb2NrU3R5bGVzLFxuICAgICAgYWxsb3dCbG9ja1NjYWxhcnMsXG4gICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMsXG4gICAgICBpbmRlbnRTdGF0dXMgPSAxLCAvLyAxOiB0aGlzPnBhcmVudCwgMDogdGhpcz1wYXJlbnQsIC0xOiB0aGlzPHBhcmVudFxuICAgICAgYXROZXdMaW5lICA9IGZhbHNlLFxuICAgICAgaGFzQ29udGVudCA9IGZhbHNlLFxuICAgICAgdHlwZUluZGV4LFxuICAgICAgdHlwZVF1YW50aXR5LFxuICAgICAgdHlwZSxcbiAgICAgIGZsb3dJbmRlbnQsXG4gICAgICBibG9ja0luZGVudDtcblxuICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5saXN0ZW5lcignb3BlbicsIHN0YXRlKTtcbiAgfVxuXG4gIHN0YXRlLnRhZyAgICA9IG51bGw7XG4gIHN0YXRlLmFuY2hvciA9IG51bGw7XG4gIHN0YXRlLmtpbmQgICA9IG51bGw7XG4gIHN0YXRlLnJlc3VsdCA9IG51bGw7XG5cbiAgYWxsb3dCbG9ja1N0eWxlcyA9IGFsbG93QmxvY2tTY2FsYXJzID0gYWxsb3dCbG9ja0NvbGxlY3Rpb25zID1cbiAgICBDT05URVhUX0JMT0NLX09VVCA9PT0gbm9kZUNvbnRleHQgfHxcbiAgICBDT05URVhUX0JMT0NLX0lOICA9PT0gbm9kZUNvbnRleHQ7XG5cbiAgaWYgKGFsbG93VG9TZWVrKSB7XG4gICAgaWYgKHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKSkge1xuICAgICAgYXROZXdMaW5lID0gdHJ1ZTtcblxuICAgICAgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPiBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gMTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gcGFyZW50SW5kZW50KSB7XG4gICAgICAgIGluZGVudFN0YXR1cyA9IDA7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gLTE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSkge1xuICAgIHdoaWxlIChyZWFkVGFnUHJvcGVydHkoc3RhdGUpIHx8IHJlYWRBbmNob3JQcm9wZXJ0eShzdGF0ZSkpIHtcbiAgICAgIGlmIChza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSkpIHtcbiAgICAgICAgYXROZXdMaW5lID0gdHJ1ZTtcbiAgICAgICAgYWxsb3dCbG9ja0NvbGxlY3Rpb25zID0gYWxsb3dCbG9ja1N0eWxlcztcblxuICAgICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IHBhcmVudEluZGVudCkge1xuICAgICAgICAgIGluZGVudFN0YXR1cyA9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gLTE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFsbG93QmxvY2tDb2xsZWN0aW9ucyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMpIHtcbiAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPSBhdE5ld0xpbmUgfHwgYWxsb3dDb21wYWN0O1xuICB9XG5cbiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSB8fCBDT05URVhUX0JMT0NLX09VVCA9PT0gbm9kZUNvbnRleHQpIHtcbiAgICBpZiAoQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCB8fCBDT05URVhUX0ZMT1dfT1VUID09PSBub2RlQ29udGV4dCkge1xuICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudCArIDE7XG4gICAgfVxuXG4gICAgYmxvY2tJbmRlbnQgPSBzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydDtcblxuICAgIGlmIChpbmRlbnRTdGF0dXMgPT09IDEpIHtcbiAgICAgIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiZcbiAgICAgICAgICAocmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIGJsb2NrSW5kZW50KSB8fFxuICAgICAgICAgICByZWFkQmxvY2tNYXBwaW5nKHN0YXRlLCBibG9ja0luZGVudCwgZmxvd0luZGVudCkpIHx8XG4gICAgICAgICAgcmVhZEZsb3dDb2xsZWN0aW9uKHN0YXRlLCBmbG93SW5kZW50KSkge1xuICAgICAgICBoYXNDb250ZW50ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICgoYWxsb3dCbG9ja1NjYWxhcnMgJiYgcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkgfHxcbiAgICAgICAgICAgIHJlYWRTaW5nbGVRdW90ZWRTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpIHx8XG4gICAgICAgICAgICByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgIH0gZWxzZSBpZiAocmVhZEFsaWFzKHN0YXRlKSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgICAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCB8fCBzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdhbGlhcyBub2RlIHNob3VsZCBub3QgaGF2ZSBhbnkgcHJvcGVydGllcycpO1xuICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2UgaWYgKHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCwgQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCkpIHtcbiAgICAgICAgICBoYXNDb250ZW50ID0gdHJ1ZTtcblxuICAgICAgICAgIGlmIChzdGF0ZS50YWcgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHN0YXRlLnRhZyA9ICc/JztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yTWFwW3N0YXRlLmFuY2hvcl0gPSBzdGF0ZS5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGluZGVudFN0YXR1cyA9PT0gMCkge1xuICAgICAgLy8gU3BlY2lhbCBjYXNlOiBibG9jayBzZXF1ZW5jZXMgYXJlIGFsbG93ZWQgdG8gaGF2ZSBzYW1lIGluZGVudGF0aW9uIGxldmVsIGFzIHRoZSBwYXJlbnQuXG4gICAgICAvLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI3OTk3ODRcbiAgICAgIGhhc0NvbnRlbnQgPSBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiYgcmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIGJsb2NrSW5kZW50KTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJyEnKSB7XG4gICAgaWYgKHN0YXRlLnRhZyA9PT0gJz8nKSB7XG4gICAgICBmb3IgKHR5cGVJbmRleCA9IDAsIHR5cGVRdWFudGl0eSA9IHN0YXRlLmltcGxpY2l0VHlwZXMubGVuZ3RoO1xuICAgICAgICAgICB0eXBlSW5kZXggPCB0eXBlUXVhbnRpdHk7XG4gICAgICAgICAgIHR5cGVJbmRleCArPSAxKSB7XG4gICAgICAgIHR5cGUgPSBzdGF0ZS5pbXBsaWNpdFR5cGVzW3R5cGVJbmRleF07XG5cbiAgICAgICAgLy8gSW1wbGljaXQgcmVzb2x2aW5nIGlzIG5vdCBhbGxvd2VkIGZvciBub24tc2NhbGFyIHR5cGVzLCBhbmQgJz8nXG4gICAgICAgIC8vIG5vbi1zcGVjaWZpYyB0YWcgaXMgb25seSBhc3NpZ25lZCB0byBwbGFpbiBzY2FsYXJzLiBTbywgaXQgaXNuJ3RcbiAgICAgICAgLy8gbmVlZGVkIHRvIGNoZWNrIGZvciAna2luZCcgY29uZm9ybWl0eS5cblxuICAgICAgICBpZiAodHlwZS5yZXNvbHZlKHN0YXRlLnJlc3VsdCkpIHsgLy8gYHN0YXRlLnJlc3VsdGAgdXBkYXRlZCBpbiByZXNvbHZlciBpZiBtYXRjaGVkXG4gICAgICAgICAgc3RhdGUucmVzdWx0ID0gdHlwZS5jb25zdHJ1Y3Qoc3RhdGUucmVzdWx0KTtcbiAgICAgICAgICBzdGF0ZS50YWcgPSB0eXBlLnRhZztcbiAgICAgICAgICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YXRlLnR5cGVNYXAsIHN0YXRlLnRhZykpIHtcbiAgICAgIHR5cGUgPSBzdGF0ZS50eXBlTWFwW3N0YXRlLnRhZ107XG5cbiAgICAgIGlmIChzdGF0ZS5yZXN1bHQgIT09IG51bGwgJiYgdHlwZS5raW5kICE9PSBzdGF0ZS5raW5kKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmFjY2VwdGFibGUgbm9kZSBraW5kIGZvciAhPCcgKyBzdGF0ZS50YWcgKyAnPiB0YWc7IGl0IHNob3VsZCBiZSBcIicgKyB0eXBlLmtpbmQgKyAnXCIsIG5vdCBcIicgKyBzdGF0ZS5raW5kICsgJ1wiJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdHlwZS5yZXNvbHZlKHN0YXRlLnJlc3VsdCkpIHsgLy8gYHN0YXRlLnJlc3VsdGAgdXBkYXRlZCBpbiByZXNvbHZlciBpZiBtYXRjaGVkXG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW5ub3QgcmVzb2x2ZSBhIG5vZGUgd2l0aCAhPCcgKyBzdGF0ZS50YWcgKyAnPiBleHBsaWNpdCB0YWcnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCA9IHR5cGUuY29uc3RydWN0KHN0YXRlLnJlc3VsdCk7XG4gICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5rbm93biB0YWcgITwnICsgc3RhdGUudGFnICsgJz4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5saXN0ZW5lcignY2xvc2UnLCBzdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLnRhZyAhPT0gbnVsbCB8fCAgc3RhdGUuYW5jaG9yICE9PSBudWxsIHx8IGhhc0NvbnRlbnQ7XG59XG5cbmZ1bmN0aW9uIHJlYWREb2N1bWVudChzdGF0ZSkge1xuICB2YXIgZG9jdW1lbnRTdGFydCA9IHN0YXRlLnBvc2l0aW9uLFxuICAgICAgX3Bvc2l0aW9uLFxuICAgICAgZGlyZWN0aXZlTmFtZSxcbiAgICAgIGRpcmVjdGl2ZUFyZ3MsXG4gICAgICBoYXNEaXJlY3RpdmVzID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBzdGF0ZS52ZXJzaW9uID0gbnVsbDtcbiAgc3RhdGUuY2hlY2tMaW5lQnJlYWtzID0gc3RhdGUubGVnYWN5O1xuICBzdGF0ZS50YWdNYXAgPSB7fTtcbiAgc3RhdGUuYW5jaG9yTWFwID0ge307XG5cbiAgd2hpbGUgKChjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pKSAhPT0gMCkge1xuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IDAgfHwgY2ggIT09IDB4MjUvKiAlICovKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBoYXNEaXJlY3RpdmVzID0gdHJ1ZTtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgIWlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICBkaXJlY3RpdmVOYW1lID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gICAgZGlyZWN0aXZlQXJncyA9IFtdO1xuXG4gICAgaWYgKGRpcmVjdGl2ZU5hbWUubGVuZ3RoIDwgMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2RpcmVjdGl2ZSBuYW1lIG11c3Qgbm90IGJlIGxlc3MgdGhhbiBvbmUgY2hhcmFjdGVyIGluIGxlbmd0aCcpO1xuICAgIH1cblxuICAgIHdoaWxlIChjaCAhPT0gMCkge1xuICAgICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHtcbiAgICAgICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICAgICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19FT0woY2gpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc19FT0woY2gpKSBicmVhaztcblxuICAgICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgICAgIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGRpcmVjdGl2ZUFyZ3MucHVzaChzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKSk7XG4gICAgfVxuXG4gICAgaWYgKGNoICE9PSAwKSByZWFkTGluZUJyZWFrKHN0YXRlKTtcblxuICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChkaXJlY3RpdmVIYW5kbGVycywgZGlyZWN0aXZlTmFtZSkpIHtcbiAgICAgIGRpcmVjdGl2ZUhhbmRsZXJzW2RpcmVjdGl2ZU5hbWVdKHN0YXRlLCBkaXJlY3RpdmVOYW1lLCBkaXJlY3RpdmVBcmdzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAndW5rbm93biBkb2N1bWVudCBkaXJlY3RpdmUgXCInICsgZGlyZWN0aXZlTmFtZSArICdcIicpO1xuICAgIH1cbiAgfVxuXG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gMCAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikgICAgID09PSAweDJELyogLSAqLyAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpID09PSAweDJELyogLSAqLyAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDIpID09PSAweDJELyogLSAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uICs9IDM7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gIH0gZWxzZSBpZiAoaGFzRGlyZWN0aXZlcykge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkaXJlY3RpdmVzIGVuZCBtYXJrIGlzIGV4cGVjdGVkJyk7XG4gIH1cblxuICBjb21wb3NlTm9kZShzdGF0ZSwgc3RhdGUubGluZUluZGVudCAtIDEsIENPTlRFWFRfQkxPQ0tfT1VULCBmYWxzZSwgdHJ1ZSk7XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICBpZiAoc3RhdGUuY2hlY2tMaW5lQnJlYWtzICYmXG4gICAgICBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUy50ZXN0KHN0YXRlLmlucHV0LnNsaWNlKGRvY3VtZW50U3RhcnQsIHN0YXRlLnBvc2l0aW9uKSkpIHtcbiAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICdub24tQVNDSUkgbGluZSBicmVha3MgYXJlIGludGVycHJldGVkIGFzIGNvbnRlbnQnKTtcbiAgfVxuXG4gIHN0YXRlLmRvY3VtZW50cy5wdXNoKHN0YXRlLnJlc3VsdCk7XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkge1xuXG4gICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDJFLyogLiAqLykge1xuICAgICAgc3RhdGUucG9zaXRpb24gKz0gMztcbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uIDwgKHN0YXRlLmxlbmd0aCAtIDEpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2VuZCBvZiB0aGUgc3RyZWFtIG9yIGEgZG9jdW1lbnQgc2VwYXJhdG9yIGlzIGV4cGVjdGVkJyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuO1xuICB9XG59XG5cblxuZnVuY3Rpb24gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucykge1xuICBpbnB1dCA9IFN0cmluZyhpbnB1dCk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIGlmIChpbnB1dC5sZW5ndGggIT09IDApIHtcblxuICAgIC8vIEFkZCB0YWlsaW5nIGBcXG5gIGlmIG5vdCBleGlzdHNcbiAgICBpZiAoaW5wdXQuY2hhckNvZGVBdChpbnB1dC5sZW5ndGggLSAxKSAhPT0gMHgwQS8qIExGICovICYmXG4gICAgICAgIGlucHV0LmNoYXJDb2RlQXQoaW5wdXQubGVuZ3RoIC0gMSkgIT09IDB4MEQvKiBDUiAqLykge1xuICAgICAgaW5wdXQgKz0gJ1xcbic7XG4gICAgfVxuXG4gICAgLy8gU3RyaXAgQk9NXG4gICAgaWYgKGlucHV0LmNoYXJDb2RlQXQoMCkgPT09IDB4RkVGRikge1xuICAgICAgaW5wdXQgPSBpbnB1dC5zbGljZSgxKTtcbiAgICB9XG4gIH1cblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUoaW5wdXQsIG9wdGlvbnMpO1xuXG4gIC8vIFVzZSAwIGFzIHN0cmluZyB0ZXJtaW5hdG9yLiBUaGF0IHNpZ25pZmljYW50bHkgc2ltcGxpZmllcyBib3VuZHMgY2hlY2suXG4gIHN0YXRlLmlucHV0ICs9ICdcXDAnO1xuXG4gIHdoaWxlIChzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSA9PT0gMHgyMC8qIFNwYWNlICovKSB7XG4gICAgc3RhdGUubGluZUluZGVudCArPSAxO1xuICAgIHN0YXRlLnBvc2l0aW9uICs9IDE7XG4gIH1cblxuICB3aGlsZSAoc3RhdGUucG9zaXRpb24gPCAoc3RhdGUubGVuZ3RoIC0gMSkpIHtcbiAgICByZWFkRG9jdW1lbnQoc3RhdGUpO1xuICB9XG5cbiAgcmV0dXJuIHN0YXRlLmRvY3VtZW50cztcbn1cblxuXG5mdW5jdGlvbiBsb2FkQWxsKGlucHV0LCBpdGVyYXRvciwgb3B0aW9ucykge1xuICB2YXIgZG9jdW1lbnRzID0gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucyksIGluZGV4LCBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGRvY3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgaXRlcmF0b3IoZG9jdW1lbnRzW2luZGV4XSk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBsb2FkKGlucHV0LCBvcHRpb25zKSB7XG4gIHZhciBkb2N1bWVudHMgPSBsb2FkRG9jdW1lbnRzKGlucHV0LCBvcHRpb25zKTtcblxuICBpZiAoZG9jdW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIC8qZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkKi9cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9IGVsc2UgaWYgKGRvY3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gZG9jdW1lbnRzWzBdO1xuICB9XG4gIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdleHBlY3RlZCBhIHNpbmdsZSBkb2N1bWVudCBpbiB0aGUgc3RyZWFtLCBidXQgZm91bmQgbW9yZScpO1xufVxuXG5cbmZ1bmN0aW9uIHNhZmVMb2FkQWxsKGlucHV0LCBvdXRwdXQsIG9wdGlvbnMpIHtcbiAgbG9hZEFsbChpbnB1dCwgb3V0cHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTtcbn1cblxuXG5mdW5jdGlvbiBzYWZlTG9hZChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gbG9hZChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cblxubW9kdWxlLmV4cG9ydHMubG9hZEFsbCAgICAgPSBsb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMubG9hZCAgICAgICAgPSBsb2FkO1xubW9kdWxlLmV4cG9ydHMuc2FmZUxvYWRBbGwgPSBzYWZlTG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgID0gc2FmZUxvYWQ7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cblxuZnVuY3Rpb24gTWFyayhuYW1lLCBidWZmZXIsIHBvc2l0aW9uLCBsaW5lLCBjb2x1bW4pIHtcbiAgdGhpcy5uYW1lICAgICA9IG5hbWU7XG4gIHRoaXMuYnVmZmVyICAgPSBidWZmZXI7XG4gIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjtcbiAgdGhpcy5saW5lICAgICA9IGxpbmU7XG4gIHRoaXMuY29sdW1uICAgPSBjb2x1bW47XG59XG5cblxuTWFyay5wcm90b3R5cGUuZ2V0U25pcHBldCA9IGZ1bmN0aW9uIGdldFNuaXBwZXQoaW5kZW50LCBtYXhMZW5ndGgpIHtcbiAgdmFyIGhlYWQsIHN0YXJ0LCB0YWlsLCBlbmQsIHNuaXBwZXQ7XG5cbiAgaWYgKCF0aGlzLmJ1ZmZlcikgcmV0dXJuIG51bGw7XG5cbiAgaW5kZW50ID0gaW5kZW50IHx8IDQ7XG4gIG1heExlbmd0aCA9IG1heExlbmd0aCB8fCA3NTtcblxuICBoZWFkID0gJyc7XG4gIHN0YXJ0ID0gdGhpcy5wb3NpdGlvbjtcblxuICB3aGlsZSAoc3RhcnQgPiAwICYmICdcXHgwMFxcclxcblxceDg1XFx1MjAyOFxcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KHN0YXJ0IC0gMSkpID09PSAtMSkge1xuICAgIHN0YXJ0IC09IDE7XG4gICAgaWYgKHRoaXMucG9zaXRpb24gLSBzdGFydCA+IChtYXhMZW5ndGggLyAyIC0gMSkpIHtcbiAgICAgIGhlYWQgPSAnIC4uLiAnO1xuICAgICAgc3RhcnQgKz0gNTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHRhaWwgPSAnJztcbiAgZW5kID0gdGhpcy5wb3NpdGlvbjtcblxuICB3aGlsZSAoZW5kIDwgdGhpcy5idWZmZXIubGVuZ3RoICYmICdcXHgwMFxcclxcblxceDg1XFx1MjAyOFxcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KGVuZCkpID09PSAtMSkge1xuICAgIGVuZCArPSAxO1xuICAgIGlmIChlbmQgLSB0aGlzLnBvc2l0aW9uID4gKG1heExlbmd0aCAvIDIgLSAxKSkge1xuICAgICAgdGFpbCA9ICcgLi4uICc7XG4gICAgICBlbmQgLT0gNTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHNuaXBwZXQgPSB0aGlzLmJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTtcblxuICByZXR1cm4gY29tbW9uLnJlcGVhdCgnICcsIGluZGVudCkgKyBoZWFkICsgc25pcHBldCArIHRhaWwgKyAnXFxuJyArXG4gICAgICAgICBjb21tb24ucmVwZWF0KCcgJywgaW5kZW50ICsgdGhpcy5wb3NpdGlvbiAtIHN0YXJ0ICsgaGVhZC5sZW5ndGgpICsgJ14nO1xufTtcblxuXG5NYXJrLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKGNvbXBhY3QpIHtcbiAgdmFyIHNuaXBwZXQsIHdoZXJlID0gJyc7XG5cbiAgaWYgKHRoaXMubmFtZSkge1xuICAgIHdoZXJlICs9ICdpbiBcIicgKyB0aGlzLm5hbWUgKyAnXCIgJztcbiAgfVxuXG4gIHdoZXJlICs9ICdhdCBsaW5lICcgKyAodGhpcy5saW5lICsgMSkgKyAnLCBjb2x1bW4gJyArICh0aGlzLmNvbHVtbiArIDEpO1xuXG4gIGlmICghY29tcGFjdCkge1xuICAgIHNuaXBwZXQgPSB0aGlzLmdldFNuaXBwZXQoKTtcblxuICAgIGlmIChzbmlwcGV0KSB7XG4gICAgICB3aGVyZSArPSAnOlxcbicgKyBzbmlwcGV0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB3aGVyZTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNYXJrO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG1heC1sZW4qL1xuXG52YXIgY29tbW9uICAgICAgICA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgWUFNTEV4Y2VwdGlvbiA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7XG52YXIgVHlwZSAgICAgICAgICA9IHJlcXVpcmUoJy4vdHlwZScpO1xuXG5cbmZ1bmN0aW9uIGNvbXBpbGVMaXN0KHNjaGVtYSwgbmFtZSwgcmVzdWx0KSB7XG4gIHZhciBleGNsdWRlID0gW107XG5cbiAgc2NoZW1hLmluY2x1ZGUuZm9yRWFjaChmdW5jdGlvbiAoaW5jbHVkZWRTY2hlbWEpIHtcbiAgICByZXN1bHQgPSBjb21waWxlTGlzdChpbmNsdWRlZFNjaGVtYSwgbmFtZSwgcmVzdWx0KTtcbiAgfSk7XG5cbiAgc2NoZW1hW25hbWVdLmZvckVhY2goZnVuY3Rpb24gKGN1cnJlbnRUeXBlKSB7XG4gICAgcmVzdWx0LmZvckVhY2goZnVuY3Rpb24gKHByZXZpb3VzVHlwZSwgcHJldmlvdXNJbmRleCkge1xuICAgICAgaWYgKHByZXZpb3VzVHlwZS50YWcgPT09IGN1cnJlbnRUeXBlLnRhZykge1xuICAgICAgICBleGNsdWRlLnB1c2gocHJldmlvdXNJbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXN1bHQucHVzaChjdXJyZW50VHlwZSk7XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHQuZmlsdGVyKGZ1bmN0aW9uICh0eXBlLCBpbmRleCkge1xuICAgIHJldHVybiBleGNsdWRlLmluZGV4T2YoaW5kZXgpID09PSAtMTtcbiAgfSk7XG59XG5cblxuZnVuY3Rpb24gY29tcGlsZU1hcCgvKiBsaXN0cy4uLiAqLykge1xuICB2YXIgcmVzdWx0ID0ge30sIGluZGV4LCBsZW5ndGg7XG5cbiAgZnVuY3Rpb24gY29sbGVjdFR5cGUodHlwZSkge1xuICAgIHJlc3VsdFt0eXBlLnRhZ10gPSB0eXBlO1xuICB9XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgYXJndW1lbnRzW2luZGV4XS5mb3JFYWNoKGNvbGxlY3RUeXBlKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gU2NoZW1hKGRlZmluaXRpb24pIHtcbiAgdGhpcy5pbmNsdWRlICA9IGRlZmluaXRpb24uaW5jbHVkZSAgfHwgW107XG4gIHRoaXMuaW1wbGljaXQgPSBkZWZpbml0aW9uLmltcGxpY2l0IHx8IFtdO1xuICB0aGlzLmV4cGxpY2l0ID0gZGVmaW5pdGlvbi5leHBsaWNpdCB8fCBbXTtcblxuICB0aGlzLmltcGxpY2l0LmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICBpZiAodHlwZS5sb2FkS2luZCAmJiB0eXBlLmxvYWRLaW5kICE9PSAnc2NhbGFyJykge1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1RoZXJlIGlzIGEgbm9uLXNjYWxhciB0eXBlIGluIHRoZSBpbXBsaWNpdCBsaXN0IG9mIGEgc2NoZW1hLiBJbXBsaWNpdCByZXNvbHZpbmcgb2Ygc3VjaCB0eXBlcyBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5jb21waWxlZEltcGxpY2l0ID0gY29tcGlsZUxpc3QodGhpcywgJ2ltcGxpY2l0JywgW10pO1xuICB0aGlzLmNvbXBpbGVkRXhwbGljaXQgPSBjb21waWxlTGlzdCh0aGlzLCAnZXhwbGljaXQnLCBbXSk7XG4gIHRoaXMuY29tcGlsZWRUeXBlTWFwICA9IGNvbXBpbGVNYXAodGhpcy5jb21waWxlZEltcGxpY2l0LCB0aGlzLmNvbXBpbGVkRXhwbGljaXQpO1xufVxuXG5cblNjaGVtYS5ERUZBVUxUID0gbnVsbDtcblxuXG5TY2hlbWEuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlU2NoZW1hKCkge1xuICB2YXIgc2NoZW1hcywgdHlwZXM7XG5cbiAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgY2FzZSAxOlxuICAgICAgc2NoZW1hcyA9IFNjaGVtYS5ERUZBVUxUO1xuICAgICAgdHlwZXMgPSBhcmd1bWVudHNbMF07XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgMjpcbiAgICAgIHNjaGVtYXMgPSBhcmd1bWVudHNbMF07XG4gICAgICB0eXBlcyA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdXcm9uZyBudW1iZXIgb2YgYXJndW1lbnRzIGZvciBTY2hlbWEuY3JlYXRlIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBzY2hlbWFzID0gY29tbW9uLnRvQXJyYXkoc2NoZW1hcyk7XG4gIHR5cGVzID0gY29tbW9uLnRvQXJyYXkodHlwZXMpO1xuXG4gIGlmICghc2NoZW1hcy5ldmVyeShmdW5jdGlvbiAoc2NoZW1hKSB7IHJldHVybiBzY2hlbWEgaW5zdGFuY2VvZiBTY2hlbWE7IH0pKSB7XG4gICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1NwZWNpZmllZCBsaXN0IG9mIHN1cGVyIHNjaGVtYXMgKG9yIGEgc2luZ2xlIFNjaGVtYSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVNjaGVtYSBvYmplY3QuJyk7XG4gIH1cblxuICBpZiAoIXR5cGVzLmV2ZXJ5KGZ1bmN0aW9uICh0eXBlKSB7IHJldHVybiB0eXBlIGluc3RhbmNlb2YgVHlwZTsgfSkpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignU3BlY2lmaWVkIGxpc3Qgb2YgWUFNTCB0eXBlcyAob3IgYSBzaW5nbGUgVHlwZSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVR5cGUgb2JqZWN0LicpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBTY2hlbWEoe1xuICAgIGluY2x1ZGU6IHNjaGVtYXMsXG4gICAgZXhwbGljaXQ6IHR5cGVzXG4gIH0pO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNjaGVtYTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBDb3JlIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwNDkyM1xuLy9cbi8vIE5PVEU6IEpTLVlBTUwgZG9lcyBub3Qgc3VwcG9ydCBzY2hlbWEtc3BlY2lmaWMgdGFnIHJlc29sdXRpb24gcmVzdHJpY3Rpb25zLlxuLy8gU28sIENvcmUgc2NoZW1hIGhhcyBubyBkaXN0aW5jdGlvbnMgZnJvbSBKU09OIHNjaGVtYSBpcyBKUy1ZQU1MLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vanNvbicpXG4gIF1cbn0pO1xuIiwiLy8gSlMtWUFNTCdzIGRlZmF1bHQgc2NoZW1hIGZvciBgbG9hZGAgZnVuY3Rpb24uXG4vLyBJdCBpcyBub3QgZGVzY3JpYmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vL1xuLy8gVGhpcyBzY2hlbWEgaXMgYmFzZWQgb24gSlMtWUFNTCdzIGRlZmF1bHQgc2FmZSBzY2hlbWEgYW5kIGluY2x1ZGVzXG4vLyBKYXZhU2NyaXB0LXNwZWNpZmljIHR5cGVzOiAhIWpzL3VuZGVmaW5lZCwgISFqcy9yZWdleHAgYW5kICEhanMvZnVuY3Rpb24uXG4vL1xuLy8gQWxzbyB0aGlzIHNjaGVtYSBpcyB1c2VkIGFzIGRlZmF1bHQgYmFzZSBzY2hlbWEgYXQgYFNjaGVtYS5jcmVhdGVgIGZ1bmN0aW9uLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBTY2hlbWEuREVGQVVMVCA9IG5ldyBTY2hlbWEoe1xuICBpbmNsdWRlOiBbXG4gICAgcmVxdWlyZSgnLi9kZWZhdWx0X3NhZmUnKVxuICBdLFxuICBleHBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvanMvdW5kZWZpbmVkJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9qcy9yZWdleHAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2pzL2Z1bmN0aW9uJylcbiAgXVxufSk7XG4iLCIvLyBKUy1ZQU1MJ3MgZGVmYXVsdCBzY2hlbWEgZm9yIGBzYWZlTG9hZGAgZnVuY3Rpb24uXG4vLyBJdCBpcyBub3QgZGVzY3JpYmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vL1xuLy8gVGhpcyBzY2hlbWEgaXMgYmFzZWQgb24gc3RhbmRhcmQgWUFNTCdzIENvcmUgc2NoZW1hIGFuZCBpbmNsdWRlcyBtb3N0IG9mXG4vLyBleHRyYSB0eXBlcyBkZXNjcmliZWQgYXQgWUFNTCB0YWcgcmVwb3NpdG9yeS4gKGh0dHA6Ly95YW1sLm9yZy90eXBlLylcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2NvcmUnKVxuICBdLFxuICBpbXBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvdGltZXN0YW1wJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9tZXJnZScpXG4gIF0sXG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9iaW5hcnknKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL29tYXAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3BhaXJzJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zZXQnKVxuICBdXG59KTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBGYWlsc2FmZSBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDIzNDZcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zdHInKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3NlcScpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvbWFwJylcbiAgXVxufSk7XG4iLCIvLyBTdGFuZGFyZCBZQU1MJ3MgSlNPTiBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDMyMzFcbi8vXG4vLyBOT1RFOiBKUy1ZQU1MIGRvZXMgbm90IHN1cHBvcnQgc2NoZW1hLXNwZWNpZmljIHRhZyByZXNvbHV0aW9uIHJlc3RyaWN0aW9ucy5cbi8vIFNvLCB0aGlzIHNjaGVtYSBpcyBub3Qgc3VjaCBzdHJpY3QgYXMgZGVmaW5lZCBpbiB0aGUgWUFNTCBzcGVjaWZpY2F0aW9uLlxuLy8gSXQgYWxsb3dzIG51bWJlcnMgaW4gYmluYXJ5IG5vdGFpb24sIHVzZSBgTnVsbGAgYW5kIGBOVUxMYCBhcyBgbnVsbGAsIGV0Yy5cblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2ZhaWxzYWZlJylcbiAgXSxcbiAgaW1wbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL251bGwnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2Jvb2wnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2ludCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvZmxvYXQnKVxuICBdXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFlBTUxFeGNlcHRpb24gPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xuXG52YXIgVFlQRV9DT05TVFJVQ1RPUl9PUFRJT05TID0gW1xuICAna2luZCcsXG4gICdyZXNvbHZlJyxcbiAgJ2NvbnN0cnVjdCcsXG4gICdpbnN0YW5jZU9mJyxcbiAgJ3ByZWRpY2F0ZScsXG4gICdyZXByZXNlbnQnLFxuICAnZGVmYXVsdFN0eWxlJyxcbiAgJ3N0eWxlQWxpYXNlcydcbl07XG5cbnZhciBZQU1MX05PREVfS0lORFMgPSBbXG4gICdzY2FsYXInLFxuICAnc2VxdWVuY2UnLFxuICAnbWFwcGluZydcbl07XG5cbmZ1bmN0aW9uIGNvbXBpbGVTdHlsZUFsaWFzZXMobWFwKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcblxuICBpZiAobWFwICE9PSBudWxsKSB7XG4gICAgT2JqZWN0LmtleXMobWFwKS5mb3JFYWNoKGZ1bmN0aW9uIChzdHlsZSkge1xuICAgICAgbWFwW3N0eWxlXS5mb3JFYWNoKGZ1bmN0aW9uIChhbGlhcykge1xuICAgICAgICByZXN1bHRbU3RyaW5nKGFsaWFzKV0gPSBzdHlsZTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gVHlwZSh0YWcsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgIGlmIChUWVBFX0NPTlNUUlVDVE9SX09QVElPTlMuaW5kZXhPZihuYW1lKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdVbmtub3duIG9wdGlvbiBcIicgKyBuYW1lICsgJ1wiIGlzIG1ldCBpbiBkZWZpbml0aW9uIG9mIFwiJyArIHRhZyArICdcIiBZQU1MIHR5cGUuJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBUT0RPOiBBZGQgdGFnIGZvcm1hdCBjaGVjay5cbiAgdGhpcy50YWcgICAgICAgICAgPSB0YWc7XG4gIHRoaXMua2luZCAgICAgICAgID0gb3B0aW9uc1sna2luZCddICAgICAgICAgfHwgbnVsbDtcbiAgdGhpcy5yZXNvbHZlICAgICAgPSBvcHRpb25zWydyZXNvbHZlJ10gICAgICB8fCBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9O1xuICB0aGlzLmNvbnN0cnVjdCAgICA9IG9wdGlvbnNbJ2NvbnN0cnVjdCddICAgIHx8IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhOyB9O1xuICB0aGlzLmluc3RhbmNlT2YgICA9IG9wdGlvbnNbJ2luc3RhbmNlT2YnXSAgIHx8IG51bGw7XG4gIHRoaXMucHJlZGljYXRlICAgID0gb3B0aW9uc1sncHJlZGljYXRlJ10gICAgfHwgbnVsbDtcbiAgdGhpcy5yZXByZXNlbnQgICAgPSBvcHRpb25zWydyZXByZXNlbnQnXSAgICB8fCBudWxsO1xuICB0aGlzLmRlZmF1bHRTdHlsZSA9IG9wdGlvbnNbJ2RlZmF1bHRTdHlsZSddIHx8IG51bGw7XG4gIHRoaXMuc3R5bGVBbGlhc2VzID0gY29tcGlsZVN0eWxlQWxpYXNlcyhvcHRpb25zWydzdHlsZUFsaWFzZXMnXSB8fCBudWxsKTtcblxuICBpZiAoWUFNTF9OT0RFX0tJTkRTLmluZGV4T2YodGhpcy5raW5kKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignVW5rbm93biBraW5kIFwiJyArIHRoaXMua2luZCArICdcIiBpcyBzcGVjaWZpZWQgZm9yIFwiJyArIHRhZyArICdcIiBZQU1MIHR5cGUuJyk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBUeXBlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG5vLWJpdHdpc2UqL1xuXG52YXIgTm9kZUJ1ZmZlcjtcblxudHJ5IHtcbiAgLy8gQSB0cmljayBmb3IgYnJvd3NlcmlmaWVkIHZlcnNpb24sIHRvIG5vdCBpbmNsdWRlIGBCdWZmZXJgIHNoaW1cbiAgdmFyIF9yZXF1aXJlID0gcmVxdWlyZTtcbiAgTm9kZUJ1ZmZlciA9IF9yZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG59IGNhdGNoIChfXykge31cblxudmFyIFR5cGUgICAgICAgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cblxuLy8gWyA2NCwgNjUsIDY2IF0gLT4gWyBwYWRkaW5nLCBDUiwgTEYgXVxudmFyIEJBU0U2NF9NQVAgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz1cXG5cXHInO1xuXG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sQmluYXJ5KGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgY29kZSwgaWR4LCBiaXRsZW4gPSAwLCBtYXggPSBkYXRhLmxlbmd0aCwgbWFwID0gQkFTRTY0X01BUDtcblxuICAvLyBDb252ZXJ0IG9uZSBieSBvbmUuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGNvZGUgPSBtYXAuaW5kZXhPZihkYXRhLmNoYXJBdChpZHgpKTtcblxuICAgIC8vIFNraXAgQ1IvTEZcbiAgICBpZiAoY29kZSA+IDY0KSBjb250aW51ZTtcblxuICAgIC8vIEZhaWwgb24gaWxsZWdhbCBjaGFyYWN0ZXJzXG4gICAgaWYgKGNvZGUgPCAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICBiaXRsZW4gKz0gNjtcbiAgfVxuXG4gIC8vIElmIHRoZXJlIGFyZSBhbnkgYml0cyBsZWZ0LCBzb3VyY2Ugd2FzIGNvcnJ1cHRlZFxuICByZXR1cm4gKGJpdGxlbiAlIDgpID09PSAwO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sQmluYXJ5KGRhdGEpIHtcbiAgdmFyIGlkeCwgdGFpbGJpdHMsXG4gICAgICBpbnB1dCA9IGRhdGEucmVwbGFjZSgvW1xcclxcbj1dL2csICcnKSwgLy8gcmVtb3ZlIENSL0xGICYgcGFkZGluZyB0byBzaW1wbGlmeSBzY2FuXG4gICAgICBtYXggPSBpbnB1dC5sZW5ndGgsXG4gICAgICBtYXAgPSBCQVNFNjRfTUFQLFxuICAgICAgYml0cyA9IDAsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICAvLyBDb2xsZWN0IGJ5IDYqNCBiaXRzICgzIGJ5dGVzKVxuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGlmICgoaWR4ICUgNCA9PT0gMCkgJiYgaWR4KSB7XG4gICAgICByZXN1bHQucHVzaCgoYml0cyA+PiAxNikgJiAweEZGKTtcbiAgICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7XG4gICAgICByZXN1bHQucHVzaChiaXRzICYgMHhGRik7XG4gICAgfVxuXG4gICAgYml0cyA9IChiaXRzIDw8IDYpIHwgbWFwLmluZGV4T2YoaW5wdXQuY2hhckF0KGlkeCkpO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdGFpbGJpdHMgPSAobWF4ICUgNCkgKiA2O1xuXG4gIGlmICh0YWlsYml0cyA9PT0gMCkge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDE2KSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7XG4gICAgcmVzdWx0LnB1c2goYml0cyAmIDB4RkYpO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxOCkge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDEwKSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDIpICYgMHhGRik7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDEyKSB7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gNCkgJiAweEZGKTtcbiAgfVxuXG4gIC8vIFdyYXAgaW50byBCdWZmZXIgZm9yIE5vZGVKUyBhbmQgbGVhdmUgQXJyYXkgZm9yIGJyb3dzZXJcbiAgaWYgKE5vZGVCdWZmZXIpIHJldHVybiBuZXcgTm9kZUJ1ZmZlcihyZXN1bHQpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxCaW5hcnkob2JqZWN0IC8qLCBzdHlsZSovKSB7XG4gIHZhciByZXN1bHQgPSAnJywgYml0cyA9IDAsIGlkeCwgdGFpbCxcbiAgICAgIG1heCA9IG9iamVjdC5sZW5ndGgsXG4gICAgICBtYXAgPSBCQVNFNjRfTUFQO1xuXG4gIC8vIENvbnZlcnQgZXZlcnkgdGhyZWUgYnl0ZXMgdG8gNCBBU0NJSSBjaGFyYWN0ZXJzLlxuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGlmICgoaWR4ICUgMyA9PT0gMCkgJiYgaWR4KSB7XG4gICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdO1xuICAgICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxMikgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNikgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdO1xuICAgIH1cblxuICAgIGJpdHMgPSAoYml0cyA8PCA4KSArIG9iamVjdFtpZHhdO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdGFpbCA9IG1heCAlIDM7XG5cbiAgaWYgKHRhaWwgPT09IDApIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiA2KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdO1xuICB9IGVsc2UgaWYgKHRhaWwgPT09IDIpIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDEwKSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNCkgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzIDw8IDIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gIH0gZWxzZSBpZiAodGFpbCA9PT0gMSkge1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMikgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzIDw8IDQpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpc0JpbmFyeShvYmplY3QpIHtcbiAgcmV0dXJuIE5vZGVCdWZmZXIgJiYgTm9kZUJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpiaW5hcnknLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEJpbmFyeSxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sQmluYXJ5LFxuICBwcmVkaWNhdGU6IGlzQmluYXJ5LFxuICByZXByZXNlbnQ6IHJlcHJlc2VudFlhbWxCaW5hcnlcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxCb29sZWFuKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGg7XG5cbiAgcmV0dXJuIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICd0cnVlJyB8fCBkYXRhID09PSAnVHJ1ZScgfHwgZGF0YSA9PT0gJ1RSVUUnKSkgfHxcbiAgICAgICAgIChtYXggPT09IDUgJiYgKGRhdGEgPT09ICdmYWxzZScgfHwgZGF0YSA9PT0gJ0ZhbHNlJyB8fCBkYXRhID09PSAnRkFMU0UnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxCb29sZWFuKGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEgPT09ICd0cnVlJyB8fFxuICAgICAgICAgZGF0YSA9PT0gJ1RydWUnIHx8XG4gICAgICAgICBkYXRhID09PSAnVFJVRSc7XG59XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBCb29sZWFuXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmJvb2wnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEJvb2xlYW4sXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEJvb2xlYW4sXG4gIHByZWRpY2F0ZTogaXNCb29sZWFuLFxuICByZXByZXNlbnQ6IHtcbiAgICBsb3dlcmNhc2U6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuIG9iamVjdCA/ICd0cnVlJyA6ICdmYWxzZSc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAnVFJVRScgOiAnRkFMU0UnOyB9LFxuICAgIGNhbWVsY2FzZTogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gb2JqZWN0ID8gJ1RydWUnIDogJ0ZhbHNlJzsgfVxuICB9LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIFR5cGUgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIFlBTUxfRkxPQVRfUEFUVEVSTiA9IG5ldyBSZWdFeHAoXG4gICdeKD86Wy0rXT8oPzpbMC05XVswLTlfXSopXFxcXC5bMC05X10qKD86W2VFXVstK11bMC05XSspPycgK1xuICAnfFxcXFwuWzAtOV9dKyg/OltlRV1bLStdWzAtOV0rKT8nICtcbiAgJ3xbLStdP1swLTldWzAtOV9dKig/OjpbMC01XT9bMC05XSkrXFxcXC5bMC05X10qJyArXG4gICd8Wy0rXT9cXFxcLig/OmluZnxJbmZ8SU5GKScgK1xuICAnfFxcXFwuKD86bmFufE5hTnxOQU4pKSQnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxGbG9hdChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKCFZQU1MX0ZMT0FUX1BBVFRFUk4udGVzdChkYXRhKSkgcmV0dXJuIGZhbHNlO1xuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sRmxvYXQoZGF0YSkge1xuICB2YXIgdmFsdWUsIHNpZ24sIGJhc2UsIGRpZ2l0cztcblxuICB2YWx1ZSAgPSBkYXRhLnJlcGxhY2UoL18vZywgJycpLnRvTG93ZXJDYXNlKCk7XG4gIHNpZ24gICA9IHZhbHVlWzBdID09PSAnLScgPyAtMSA6IDE7XG4gIGRpZ2l0cyA9IFtdO1xuXG4gIGlmICgnKy0nLmluZGV4T2YodmFsdWVbMF0pID49IDApIHtcbiAgICB2YWx1ZSA9IHZhbHVlLnNsaWNlKDEpO1xuICB9XG5cbiAgaWYgKHZhbHVlID09PSAnLmluZicpIHtcbiAgICByZXR1cm4gKHNpZ24gPT09IDEpID8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZIDogTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO1xuXG4gIH0gZWxzZSBpZiAodmFsdWUgPT09ICcubmFuJykge1xuICAgIHJldHVybiBOYU47XG5cbiAgfSBlbHNlIGlmICh2YWx1ZS5pbmRleE9mKCc6JykgPj0gMCkge1xuICAgIHZhbHVlLnNwbGl0KCc6JykuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgICAgZGlnaXRzLnVuc2hpZnQocGFyc2VGbG9hdCh2LCAxMCkpO1xuICAgIH0pO1xuXG4gICAgdmFsdWUgPSAwLjA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gZCAqIGJhc2U7XG4gICAgICBiYXNlICo9IDYwO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNpZ24gKiB2YWx1ZTtcblxuICB9XG4gIHJldHVybiBzaWduICogcGFyc2VGbG9hdCh2YWx1ZSwgMTApO1xufVxuXG5cbnZhciBTQ0lFTlRJRklDX1dJVEhPVVRfRE9UID0gL15bLStdP1swLTldK2UvO1xuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sRmxvYXQob2JqZWN0LCBzdHlsZSkge1xuICB2YXIgcmVzO1xuXG4gIGlmIChpc05hTihvYmplY3QpKSB7XG4gICAgc3dpdGNoIChzdHlsZSkge1xuICAgICAgY2FzZSAnbG93ZXJjYXNlJzogcmV0dXJuICcubmFuJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLk5BTic7XG4gICAgICBjYXNlICdjYW1lbGNhc2UnOiByZXR1cm4gJy5OYU4nO1xuICAgIH1cbiAgfSBlbHNlIGlmIChOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgPT09IG9iamVjdCkge1xuICAgIHN3aXRjaCAoc3R5bGUpIHtcbiAgICAgIGNhc2UgJ2xvd2VyY2FzZSc6IHJldHVybiAnLmluZic7XG4gICAgICBjYXNlICd1cHBlcmNhc2UnOiByZXR1cm4gJy5JTkYnO1xuICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICcuSW5mJztcbiAgICB9XG4gIH0gZWxzZSBpZiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSBvYmplY3QpIHtcbiAgICBzd2l0Y2ggKHN0eWxlKSB7XG4gICAgICBjYXNlICdsb3dlcmNhc2UnOiByZXR1cm4gJy0uaW5mJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLS5JTkYnO1xuICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICctLkluZic7XG4gICAgfVxuICB9IGVsc2UgaWYgKGNvbW1vbi5pc05lZ2F0aXZlWmVybyhvYmplY3QpKSB7XG4gICAgcmV0dXJuICctMC4wJztcbiAgfVxuXG4gIHJlcyA9IG9iamVjdC50b1N0cmluZygxMCk7XG5cbiAgLy8gSlMgc3RyaW5naWZpZXIgY2FuIGJ1aWxkIHNjaWVudGlmaWMgZm9ybWF0IHdpdGhvdXQgZG90czogNWUtMTAwLFxuICAvLyB3aGlsZSBZQU1MIHJlcXVyZXMgZG90OiA1LmUtMTAwLiBGaXggaXQgd2l0aCBzaW1wbGUgaGFja1xuXG4gIHJldHVybiBTQ0lFTlRJRklDX1dJVEhPVVRfRE9ULnRlc3QocmVzKSA/IHJlcy5yZXBsYWNlKCdlJywgJy5lJykgOiByZXM7XG59XG5cbmZ1bmN0aW9uIGlzRmxvYXQob2JqZWN0KSB7XG4gIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IE51bWJlcl0nKSAmJlxuICAgICAgICAgKG9iamVjdCAlIDEgIT09IDAgfHwgY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpmbG9hdCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sRmxvYXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEZsb2F0LFxuICBwcmVkaWNhdGU6IGlzRmxvYXQsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbEZsb2F0LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIFR5cGUgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gaXNIZXhDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKSB8fFxuICAgICAgICAgKCgweDQxLyogQSAqLyA8PSBjKSAmJiAoYyA8PSAweDQ2LyogRiAqLykpIHx8XG4gICAgICAgICAoKDB4NjEvKiBhICovIDw9IGMpICYmIChjIDw9IDB4NjYvKiBmICovKSk7XG59XG5cbmZ1bmN0aW9uIGlzT2N0Q29kZShjKSB7XG4gIHJldHVybiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzcvKiA3ICovKSk7XG59XG5cbmZ1bmN0aW9uIGlzRGVjQ29kZShjKSB7XG4gIHJldHVybiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSk7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sSW50ZWdlcihkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoLFxuICAgICAgaW5kZXggPSAwLFxuICAgICAgaGFzRGlnaXRzID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBpZiAoIW1heCkgcmV0dXJuIGZhbHNlO1xuXG4gIGNoID0gZGF0YVtpbmRleF07XG5cbiAgLy8gc2lnblxuICBpZiAoY2ggPT09ICctJyB8fCBjaCA9PT0gJysnKSB7XG4gICAgY2ggPSBkYXRhWysraW5kZXhdO1xuICB9XG5cbiAgaWYgKGNoID09PSAnMCcpIHtcbiAgICAvLyAwXG4gICAgaWYgKGluZGV4ICsgMSA9PT0gbWF4KSByZXR1cm4gdHJ1ZTtcbiAgICBjaCA9IGRhdGFbKytpbmRleF07XG5cbiAgICAvLyBiYXNlIDIsIGJhc2UgOCwgYmFzZSAxNlxuXG4gICAgaWYgKGNoID09PSAnYicpIHtcbiAgICAgIC8vIGJhc2UgMlxuICAgICAgaW5kZXgrKztcblxuICAgICAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICAgIGlmIChjaCA9PT0gJ18nKSBjb250aW51ZTtcbiAgICAgICAgaWYgKGNoICE9PSAnMCcgJiYgY2ggIT09ICcxJykgcmV0dXJuIGZhbHNlO1xuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cblxuICAgIGlmIChjaCA9PT0gJ3gnKSB7XG4gICAgICAvLyBiYXNlIDE2XG4gICAgICBpbmRleCsrO1xuXG4gICAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICAgICAgaWYgKGNoID09PSAnXycpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIWlzSGV4Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cbiAgICAvLyBiYXNlIDhcbiAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgICBpZiAoIWlzT2N0Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaGFzRGlnaXRzID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgfVxuXG4gIC8vIGJhc2UgMTAgKGV4Y2VwdCAwKSBvciBiYXNlIDYwXG5cbiAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgaWYgKGNoID09PSAnOicpIGJyZWFrO1xuICAgIGlmICghaXNEZWNDb2RlKGRhdGEuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGhhc0RpZ2l0cyA9IHRydWU7XG4gIH1cblxuICBpZiAoIWhhc0RpZ2l0cykgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIGlmICFiYXNlNjAgLSBkb25lO1xuICBpZiAoY2ggIT09ICc6JykgcmV0dXJuIHRydWU7XG5cbiAgLy8gYmFzZTYwIGFsbW9zdCBub3QgdXNlZCwgbm8gbmVlZHMgdG8gb3B0aW1pemVcbiAgcmV0dXJuIC9eKDpbMC01XT9bMC05XSkrJC8udGVzdChkYXRhLnNsaWNlKGluZGV4KSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxJbnRlZ2VyKGRhdGEpIHtcbiAgdmFyIHZhbHVlID0gZGF0YSwgc2lnbiA9IDEsIGNoLCBiYXNlLCBkaWdpdHMgPSBbXTtcblxuICBpZiAodmFsdWUuaW5kZXhPZignXycpICE9PSAtMSkge1xuICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXy9nLCAnJyk7XG4gIH1cblxuICBjaCA9IHZhbHVlWzBdO1xuXG4gIGlmIChjaCA9PT0gJy0nIHx8IGNoID09PSAnKycpIHtcbiAgICBpZiAoY2ggPT09ICctJykgc2lnbiA9IC0xO1xuICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMSk7XG4gICAgY2ggPSB2YWx1ZVswXTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gJzAnKSByZXR1cm4gMDtcblxuICBpZiAoY2ggPT09ICcwJykge1xuICAgIGlmICh2YWx1ZVsxXSA9PT0gJ2InKSByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCAyKTtcbiAgICBpZiAodmFsdWVbMV0gPT09ICd4JykgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZSwgMTYpO1xuICAgIHJldHVybiBzaWduICogcGFyc2VJbnQodmFsdWUsIDgpO1xuICB9XG5cbiAgaWYgKHZhbHVlLmluZGV4T2YoJzonKSAhPT0gLTEpIHtcbiAgICB2YWx1ZS5zcGxpdCgnOicpLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICAgIGRpZ2l0cy51bnNoaWZ0KHBhcnNlSW50KHYsIDEwKSk7XG4gICAgfSk7XG5cbiAgICB2YWx1ZSA9IDA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gKGQgKiBiYXNlKTtcbiAgICAgIGJhc2UgKj0gNjA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2lnbiAqIHZhbHVlO1xuXG4gIH1cblxuICByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLCAxMCk7XG59XG5cbmZ1bmN0aW9uIGlzSW50ZWdlcihvYmplY3QpIHtcbiAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSkgPT09ICdbb2JqZWN0IE51bWJlcl0nICYmXG4gICAgICAgICAob2JqZWN0ICUgMSA9PT0gMCAmJiAhY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjppbnQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEludGVnZXIsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEludGVnZXIsXG4gIHByZWRpY2F0ZTogaXNJbnRlZ2VyLFxuICByZXByZXNlbnQ6IHtcbiAgICBiaW5hcnk6ICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzBiJyArIG9iamVjdC50b1N0cmluZygyKTsgfSxcbiAgICBvY3RhbDogICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzAnICArIG9iamVjdC50b1N0cmluZyg4KTsgfSxcbiAgICBkZWNpbWFsOiAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gICAgICAgIG9iamVjdC50b1N0cmluZygxMCk7IH0sXG4gICAgaGV4YWRlY2ltYWw6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuICcweCcgKyBvYmplY3QudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnZGVjaW1hbCcsXG4gIHN0eWxlQWxpYXNlczoge1xuICAgIGJpbmFyeTogICAgICBbIDIsICAnYmluJyBdLFxuICAgIG9jdGFsOiAgICAgICBbIDgsICAnb2N0JyBdLFxuICAgIGRlY2ltYWw6ICAgICBbIDEwLCAnZGVjJyBdLFxuICAgIGhleGFkZWNpbWFsOiBbIDE2LCAnaGV4JyBdXG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXNwcmltYTtcblxuLy8gQnJvd3NlcmlmaWVkIHZlcnNpb24gZG9lcyBub3QgaGF2ZSBlc3ByaW1hXG4vL1xuLy8gMS4gRm9yIG5vZGUuanMganVzdCByZXF1aXJlIG1vZHVsZSBhcyBkZXBzXG4vLyAyLiBGb3IgYnJvd3NlciB0cnkgdG8gcmVxdWlyZSBtdWR1bGUgdmlhIGV4dGVybmFsIEFNRCBzeXN0ZW0uXG4vLyAgICBJZiBub3QgZm91bmQgLSB0cnkgdG8gZmFsbGJhY2sgdG8gd2luZG93LmVzcHJpbWEuIElmIG5vdFxuLy8gICAgZm91bmQgdG9vIC0gdGhlbiBmYWlsIHRvIHBhcnNlLlxuLy9cbnRyeSB7XG4gIC8vIHdvcmthcm91bmQgdG8gZXhjbHVkZSBwYWNrYWdlIGZyb20gYnJvd3NlcmlmeSBsaXN0LlxuICB2YXIgX3JlcXVpcmUgPSByZXF1aXJlO1xuICBlc3ByaW1hID0gX3JlcXVpcmUoJ2VzcHJpbWEnKTtcbn0gY2F0Y2ggKF8pIHtcbiAgLypnbG9iYWwgd2luZG93ICovXG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgZXNwcmltYSA9IHdpbmRvdy5lc3ByaW1hO1xufVxuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbihkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgc291cmNlID0gJygnICsgZGF0YSArICcpJyxcbiAgICAgICAgYXN0ICAgID0gZXNwcmltYS5wYXJzZShzb3VyY2UsIHsgcmFuZ2U6IHRydWUgfSk7XG5cbiAgICBpZiAoYXN0LnR5cGUgICAgICAgICAgICAgICAgICAgICE9PSAnUHJvZ3JhbScgICAgICAgICAgICAgfHxcbiAgICAgICAgYXN0LmJvZHkubGVuZ3RoICAgICAgICAgICAgICE9PSAxICAgICAgICAgICAgICAgICAgICAgfHxcbiAgICAgICAgYXN0LmJvZHlbMF0udHlwZSAgICAgICAgICAgICE9PSAnRXhwcmVzc2lvblN0YXRlbWVudCcgfHxcbiAgICAgICAgYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi50eXBlICE9PSAnRnVuY3Rpb25FeHByZXNzaW9uJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29uc3RydWN0SmF2YXNjcmlwdEZ1bmN0aW9uKGRhdGEpIHtcbiAgLypqc2xpbnQgZXZpbDp0cnVlKi9cblxuICB2YXIgc291cmNlID0gJygnICsgZGF0YSArICcpJyxcbiAgICAgIGFzdCAgICA9IGVzcHJpbWEucGFyc2Uoc291cmNlLCB7IHJhbmdlOiB0cnVlIH0pLFxuICAgICAgcGFyYW1zID0gW10sXG4gICAgICBib2R5O1xuXG4gIGlmIChhc3QudHlwZSAgICAgICAgICAgICAgICAgICAgIT09ICdQcm9ncmFtJyAgICAgICAgICAgICB8fFxuICAgICAgYXN0LmJvZHkubGVuZ3RoICAgICAgICAgICAgICE9PSAxICAgICAgICAgICAgICAgICAgICAgfHxcbiAgICAgIGFzdC5ib2R5WzBdLnR5cGUgICAgICAgICAgICAhPT0gJ0V4cHJlc3Npb25TdGF0ZW1lbnQnIHx8XG4gICAgICBhc3QuYm9keVswXS5leHByZXNzaW9uLnR5cGUgIT09ICdGdW5jdGlvbkV4cHJlc3Npb24nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcmVzb2x2ZSBmdW5jdGlvbicpO1xuICB9XG5cbiAgYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi5wYXJhbXMuZm9yRWFjaChmdW5jdGlvbiAocGFyYW0pIHtcbiAgICBwYXJhbXMucHVzaChwYXJhbS5uYW1lKTtcbiAgfSk7XG5cbiAgYm9keSA9IGFzdC5ib2R5WzBdLmV4cHJlc3Npb24uYm9keS5yYW5nZTtcblxuICAvLyBFc3ByaW1hJ3MgcmFuZ2VzIGluY2x1ZGUgdGhlIGZpcnN0ICd7JyBhbmQgdGhlIGxhc3QgJ30nIGNoYXJhY3RlcnMgb25cbiAgLy8gZnVuY3Rpb24gZXhwcmVzc2lvbnMuIFNvIGN1dCB0aGVtIG91dC5cbiAgLyplc2xpbnQtZGlzYWJsZSBuby1uZXctZnVuYyovXG4gIHJldHVybiBuZXcgRnVuY3Rpb24ocGFyYW1zLCBzb3VyY2Uuc2xpY2UoYm9keVswXSArIDEsIGJvZHlbMV0gLSAxKSk7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudEphdmFzY3JpcHRGdW5jdGlvbihvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgcmV0dXJuIG9iamVjdC50b1N0cmluZygpO1xufVxuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL2Z1bmN0aW9uJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbixcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0RnVuY3Rpb24sXG4gIHByZWRpY2F0ZTogaXNGdW5jdGlvbixcbiAgcmVwcmVzZW50OiByZXByZXNlbnRKYXZhc2NyaXB0RnVuY3Rpb25cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRSZWdFeHAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICB2YXIgcmVnZXhwID0gZGF0YSxcbiAgICAgIHRhaWwgICA9IC9cXC8oW2dpbV0qKSQvLmV4ZWMoZGF0YSksXG4gICAgICBtb2RpZmllcnMgPSAnJztcblxuICAvLyBpZiByZWdleHAgc3RhcnRzIHdpdGggJy8nIGl0IGNhbiBoYXZlIG1vZGlmaWVycyBhbmQgbXVzdCBiZSBwcm9wZXJseSBjbG9zZWRcbiAgLy8gYC9mb28vZ2ltYCAtIG1vZGlmaWVycyB0YWlsIGNhbiBiZSBtYXhpbXVtIDMgY2hhcnNcbiAgaWYgKHJlZ2V4cFswXSA9PT0gJy8nKSB7XG4gICAgaWYgKHRhaWwpIG1vZGlmaWVycyA9IHRhaWxbMV07XG5cbiAgICBpZiAobW9kaWZpZXJzLmxlbmd0aCA+IDMpIHJldHVybiBmYWxzZTtcbiAgICAvLyBpZiBleHByZXNzaW9uIHN0YXJ0cyB3aXRoIC8sIGlzIHNob3VsZCBiZSBwcm9wZXJseSB0ZXJtaW5hdGVkXG4gICAgaWYgKHJlZ2V4cFtyZWdleHAubGVuZ3RoIC0gbW9kaWZpZXJzLmxlbmd0aCAtIDFdICE9PSAnLycpIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RKYXZhc2NyaXB0UmVnRXhwKGRhdGEpIHtcbiAgdmFyIHJlZ2V4cCA9IGRhdGEsXG4gICAgICB0YWlsICAgPSAvXFwvKFtnaW1dKikkLy5leGVjKGRhdGEpLFxuICAgICAgbW9kaWZpZXJzID0gJyc7XG5cbiAgLy8gYC9mb28vZ2ltYCAtIHRhaWwgY2FuIGJlIG1heGltdW0gNCBjaGFyc1xuICBpZiAocmVnZXhwWzBdID09PSAnLycpIHtcbiAgICBpZiAodGFpbCkgbW9kaWZpZXJzID0gdGFpbFsxXTtcbiAgICByZWdleHAgPSByZWdleHAuc2xpY2UoMSwgcmVnZXhwLmxlbmd0aCAtIG1vZGlmaWVycy5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVnRXhwKHJlZ2V4cCwgbW9kaWZpZXJzKTtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cChvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgdmFyIHJlc3VsdCA9ICcvJyArIG9iamVjdC5zb3VyY2UgKyAnLyc7XG5cbiAgaWYgKG9iamVjdC5nbG9iYWwpIHJlc3VsdCArPSAnZyc7XG4gIGlmIChvYmplY3QubXVsdGlsaW5lKSByZXN1bHQgKz0gJ20nO1xuICBpZiAob2JqZWN0Lmlnbm9yZUNhc2UpIHJlc3VsdCArPSAnaSc7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gaXNSZWdFeHAob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL3JlZ2V4cCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVKYXZhc2NyaXB0UmVnRXhwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRSZWdFeHAsXG4gIHByZWRpY2F0ZTogaXNSZWdFeHAsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdEphdmFzY3JpcHRVbmRlZmluZWQoKSB7XG4gIC8qZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkKi9cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChvYmplY3QpIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICd1bmRlZmluZWQnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpqcy91bmRlZmluZWQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0VW5kZWZpbmVkLFxuICBwcmVkaWNhdGU6IGlzVW5kZWZpbmVkLFxuICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRVbmRlZmluZWRcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6bWFwJywge1xuICBraW5kOiAnbWFwcGluZycsXG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGEgIT09IG51bGwgPyBkYXRhIDoge307IH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxNZXJnZShkYXRhKSB7XG4gIHJldHVybiBkYXRhID09PSAnPDwnIHx8IGRhdGEgPT09IG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOm1lcmdlJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxNZXJnZVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE51bGwoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoO1xuXG4gIHJldHVybiAobWF4ID09PSAxICYmIGRhdGEgPT09ICd+JykgfHxcbiAgICAgICAgIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICdudWxsJyB8fCBkYXRhID09PSAnTnVsbCcgfHwgZGF0YSA9PT0gJ05VTEwnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxOdWxsKCkge1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNOdWxsKG9iamVjdCkge1xuICByZXR1cm4gb2JqZWN0ID09PSBudWxsO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpudWxsJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxOdWxsLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxOdWxsLFxuICBwcmVkaWNhdGU6IGlzTnVsbCxcbiAgcmVwcmVzZW50OiB7XG4gICAgY2Fub25pY2FsOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnfic7ICAgIH0sXG4gICAgbG93ZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnbnVsbCc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTlVMTCc7IH0sXG4gICAgY2FtZWxjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTnVsbCc7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnbG93ZXJjYXNlJ1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBfdG9TdHJpbmcgICAgICAgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE9tYXAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIG9iamVjdEtleXMgPSBbXSwgaW5kZXgsIGxlbmd0aCwgcGFpciwgcGFpcktleSwgcGFpckhhc0tleSxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpciA9IG9iamVjdFtpbmRleF07XG4gICAgcGFpckhhc0tleSA9IGZhbHNlO1xuXG4gICAgaWYgKF90b1N0cmluZy5jYWxsKHBhaXIpICE9PSAnW29iamVjdCBPYmplY3RdJykgcmV0dXJuIGZhbHNlO1xuXG4gICAgZm9yIChwYWlyS2V5IGluIHBhaXIpIHtcbiAgICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChwYWlyLCBwYWlyS2V5KSkge1xuICAgICAgICBpZiAoIXBhaXJIYXNLZXkpIHBhaXJIYXNLZXkgPSB0cnVlO1xuICAgICAgICBlbHNlIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXBhaXJIYXNLZXkpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChvYmplY3RLZXlzLmluZGV4T2YocGFpcktleSkgPT09IC0xKSBvYmplY3RLZXlzLnB1c2gocGFpcktleSk7XG4gICAgZWxzZSByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbE9tYXAoZGF0YSkge1xuICByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6b21hcCcsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxPbWFwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxPbWFwXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFBhaXJzKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiB0cnVlO1xuXG4gIHZhciBpbmRleCwgbGVuZ3RoLCBwYWlyLCBrZXlzLCByZXN1bHQsXG4gICAgICBvYmplY3QgPSBkYXRhO1xuXG4gIHJlc3VsdCA9IG5ldyBBcnJheShvYmplY3QubGVuZ3RoKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyID0gb2JqZWN0W2luZGV4XTtcblxuICAgIGlmIChfdG9TdHJpbmcuY2FsbChwYWlyKSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHJldHVybiBmYWxzZTtcblxuICAgIGtleXMgPSBPYmplY3Qua2V5cyhwYWlyKTtcblxuICAgIGlmIChrZXlzLmxlbmd0aCAhPT0gMSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgcmVzdWx0W2luZGV4XSA9IFsga2V5c1swXSwgcGFpcltrZXlzWzBdXSBdO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxQYWlycyhkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gW107XG5cbiAgdmFyIGluZGV4LCBsZW5ndGgsIHBhaXIsIGtleXMsIHJlc3VsdCxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgcmVzdWx0ID0gbmV3IEFycmF5KG9iamVjdC5sZW5ndGgpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXIgPSBvYmplY3RbaW5kZXhdO1xuXG4gICAga2V5cyA9IE9iamVjdC5rZXlzKHBhaXIpO1xuXG4gICAgcmVzdWx0W2luZGV4XSA9IFsga2V5c1swXSwgcGFpcltrZXlzWzBdXSBdO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6cGFpcnMnLCB7XG4gIGtpbmQ6ICdzZXF1ZW5jZScsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sUGFpcnMsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFBhaXJzXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnNlcScsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTsgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxTZXQoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIGtleSwgb2JqZWN0ID0gZGF0YTtcblxuICBmb3IgKGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICBpZiAob2JqZWN0W2tleV0gIT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFNldChkYXRhKSB7XG4gIHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IHt9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzZXQnLCB7XG4gIGtpbmQ6ICdtYXBwaW5nJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxTZXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFNldFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzdHInLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6ICcnOyB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBZQU1MX0RBVEVfUkVHRVhQID0gbmV3IFJlZ0V4cChcbiAgJ14oWzAtOV1bMC05XVswLTldWzAtOV0pJyAgICAgICAgICArIC8vIFsxXSB5ZWFyXG4gICctKFswLTldWzAtOV0pJyAgICAgICAgICAgICAgICAgICAgKyAvLyBbMl0gbW9udGhcbiAgJy0oWzAtOV1bMC05XSkkJyk7ICAgICAgICAgICAgICAgICAgIC8vIFszXSBkYXlcblxudmFyIFlBTUxfVElNRVNUQU1QX1JFR0VYUCA9IG5ldyBSZWdFeHAoXG4gICdeKFswLTldWzAtOV1bMC05XVswLTldKScgICAgICAgICAgKyAvLyBbMV0geWVhclxuICAnLShbMC05XVswLTldPyknICAgICAgICAgICAgICAgICAgICsgLy8gWzJdIG1vbnRoXG4gICctKFswLTldWzAtOV0/KScgICAgICAgICAgICAgICAgICAgKyAvLyBbM10gZGF5XG4gICcoPzpbVHRdfFsgXFxcXHRdKyknICAgICAgICAgICAgICAgICArIC8vIC4uLlxuICAnKFswLTldWzAtOV0/KScgICAgICAgICAgICAgICAgICAgICsgLy8gWzRdIGhvdXJcbiAgJzooWzAtOV1bMC05XSknICAgICAgICAgICAgICAgICAgICArIC8vIFs1XSBtaW51dGVcbiAgJzooWzAtOV1bMC05XSknICAgICAgICAgICAgICAgICAgICArIC8vIFs2XSBzZWNvbmRcbiAgJyg/OlxcXFwuKFswLTldKikpPycgICAgICAgICAgICAgICAgICsgLy8gWzddIGZyYWN0aW9uXG4gICcoPzpbIFxcXFx0XSooWnwoWy0rXSkoWzAtOV1bMC05XT8pJyArIC8vIFs4XSB0eiBbOV0gdHpfc2lnbiBbMTBdIHR6X2hvdXJcbiAgJyg/OjooWzAtOV1bMC05XSkpPykpPyQnKTsgICAgICAgICAgIC8vIFsxMV0gdHpfbWludXRlXG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sVGltZXN0YW1wKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgaWYgKFlBTUxfREFURV9SRUdFWFAuZXhlYyhkYXRhKSAhPT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gIGlmIChZQU1MX1RJTUVTVEFNUF9SRUdFWFAuZXhlYyhkYXRhKSAhPT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFRpbWVzdGFtcChkYXRhKSB7XG4gIHZhciBtYXRjaCwgeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIGZyYWN0aW9uID0gMCxcbiAgICAgIGRlbHRhID0gbnVsbCwgdHpfaG91ciwgdHpfbWludXRlLCBkYXRlO1xuXG4gIG1hdGNoID0gWUFNTF9EQVRFX1JFR0VYUC5leGVjKGRhdGEpO1xuICBpZiAobWF0Y2ggPT09IG51bGwpIG1hdGNoID0gWUFNTF9USU1FU1RBTVBfUkVHRVhQLmV4ZWMoZGF0YSk7XG5cbiAgaWYgKG1hdGNoID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ0RhdGUgcmVzb2x2ZSBlcnJvcicpO1xuXG4gIC8vIG1hdGNoOiBbMV0geWVhciBbMl0gbW9udGggWzNdIGRheVxuXG4gIHllYXIgPSArKG1hdGNoWzFdKTtcbiAgbW9udGggPSArKG1hdGNoWzJdKSAtIDE7IC8vIEpTIG1vbnRoIHN0YXJ0cyB3aXRoIDBcbiAgZGF5ID0gKyhtYXRjaFszXSk7XG5cbiAgaWYgKCFtYXRjaFs0XSkgeyAvLyBubyBob3VyXG4gICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXkpKTtcbiAgfVxuXG4gIC8vIG1hdGNoOiBbNF0gaG91ciBbNV0gbWludXRlIFs2XSBzZWNvbmQgWzddIGZyYWN0aW9uXG5cbiAgaG91ciA9ICsobWF0Y2hbNF0pO1xuICBtaW51dGUgPSArKG1hdGNoWzVdKTtcbiAgc2Vjb25kID0gKyhtYXRjaFs2XSk7XG5cbiAgaWYgKG1hdGNoWzddKSB7XG4gICAgZnJhY3Rpb24gPSBtYXRjaFs3XS5zbGljZSgwLCAzKTtcbiAgICB3aGlsZSAoZnJhY3Rpb24ubGVuZ3RoIDwgMykgeyAvLyBtaWxsaS1zZWNvbmRzXG4gICAgICBmcmFjdGlvbiArPSAnMCc7XG4gICAgfVxuICAgIGZyYWN0aW9uID0gK2ZyYWN0aW9uO1xuICB9XG5cbiAgLy8gbWF0Y2g6IFs4XSB0eiBbOV0gdHpfc2lnbiBbMTBdIHR6X2hvdXIgWzExXSB0el9taW51dGVcblxuICBpZiAobWF0Y2hbOV0pIHtcbiAgICB0el9ob3VyID0gKyhtYXRjaFsxMF0pO1xuICAgIHR6X21pbnV0ZSA9ICsobWF0Y2hbMTFdIHx8IDApO1xuICAgIGRlbHRhID0gKHR6X2hvdXIgKiA2MCArIHR6X21pbnV0ZSkgKiA2MDAwMDsgLy8gZGVsdGEgaW4gbWlsaS1zZWNvbmRzXG4gICAgaWYgKG1hdGNoWzldID09PSAnLScpIGRlbHRhID0gLWRlbHRhO1xuICB9XG5cbiAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBmcmFjdGlvbikpO1xuXG4gIGlmIChkZWx0YSkgZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpIC0gZGVsdGEpO1xuXG4gIHJldHVybiBkYXRlO1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sVGltZXN0YW1wKG9iamVjdCAvKiwgc3R5bGUqLykge1xuICByZXR1cm4gb2JqZWN0LnRvSVNPU3RyaW5nKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnRpbWVzdGFtcCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sVGltZXN0YW1wLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxUaW1lc3RhbXAsXG4gIGluc3RhbmNlT2Y6IERhdGUsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbFRpbWVzdGFtcFxufSk7XG4iLCJ2YXIgYmFzZUluZGV4T2YgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlSW5kZXhPZicpLFxuICAgIGJpbmFyeUluZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmluYXJ5SW5kZXgnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgdmFsdWVgIGlzIGZvdW5kIGluIGBhcnJheWBcbiAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIElmIGBmcm9tSW5kZXhgIGlzIG5lZ2F0aXZlLCBpdCdzIHVzZWQgYXMgdGhlIG9mZnNldFxuICogZnJvbSB0aGUgZW5kIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgc29ydGVkIHByb3ZpZGluZyBgdHJ1ZWAgZm9yIGBmcm9tSW5kZXhgXG4gKiBwZXJmb3JtcyBhIGZhc3RlciBiaW5hcnkgc2VhcmNoLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtib29sZWFufG51bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20gb3IgYHRydWVgXG4gKiAgdG8gcGVyZm9ybSBhIGJpbmFyeSBzZWFyY2ggb24gYSBzb3J0ZWQgYXJyYXkuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAqIC8vID0+IDFcbiAqXG4gKiAvLyB1c2luZyBgZnJvbUluZGV4YFxuICogXy5pbmRleE9mKFsxLCAyLCAxLCAyXSwgMiwgMik7XG4gKiAvLyA9PiAzXG4gKlxuICogLy8gcGVyZm9ybWluZyBhIGJpbmFyeSBzZWFyY2hcbiAqIF8uaW5kZXhPZihbMSwgMSwgMiwgMl0sIDIsIHRydWUpO1xuICogLy8gPT4gMlxuICovXG5mdW5jdGlvbiBpbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDA7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIGlmICh0eXBlb2YgZnJvbUluZGV4ID09ICdudW1iZXInKSB7XG4gICAgZnJvbUluZGV4ID0gZnJvbUluZGV4IDwgMCA/IG5hdGl2ZU1heChsZW5ndGggKyBmcm9tSW5kZXgsIDApIDogZnJvbUluZGV4O1xuICB9IGVsc2UgaWYgKGZyb21JbmRleCkge1xuICAgIHZhciBpbmRleCA9IGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgaWYgKGluZGV4IDwgbGVuZ3RoICYmXG4gICAgICAgICh2YWx1ZSA9PT0gdmFsdWUgPyAodmFsdWUgPT09IGFycmF5W2luZGV4XSkgOiAoYXJyYXlbaW5kZXhdICE9PSBhcnJheVtpbmRleF0pKSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgcmV0dXJuIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4IHx8IDApO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluZGV4T2Y7XG4iLCIvKipcbiAqIEdldHMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5sYXN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiAzXG4gKi9cbmZ1bmN0aW9uIGxhc3QoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgcmV0dXJuIGxlbmd0aCA/IGFycmF5W2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxhc3Q7XG4iLCJ2YXIgTGF6eVdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9MYXp5V3JhcHBlcicpLFxuICAgIExvZGFzaFdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYmFzZUxvZGFzaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VMb2Rhc2gnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgd3JhcHBlckNsb25lID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvd3JhcHBlckNsb25lJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgbG9kYXNoYCBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgaW1wbGljaXQgY2hhaW5pbmcuXG4gKiBNZXRob2RzIHRoYXQgb3BlcmF0ZSBvbiBhbmQgcmV0dXJuIGFycmF5cywgY29sbGVjdGlvbnMsIGFuZCBmdW5jdGlvbnMgY2FuXG4gKiBiZSBjaGFpbmVkIHRvZ2V0aGVyLiBNZXRob2RzIHRoYXQgcmV0cmlldmUgYSBzaW5nbGUgdmFsdWUgb3IgbWF5IHJldHVybiBhXG4gKiBwcmltaXRpdmUgdmFsdWUgd2lsbCBhdXRvbWF0aWNhbGx5IGVuZCB0aGUgY2hhaW4gcmV0dXJuaW5nIHRoZSB1bndyYXBwZWRcbiAqIHZhbHVlLiBFeHBsaWNpdCBjaGFpbmluZyBtYXkgYmUgZW5hYmxlZCB1c2luZyBgXy5jaGFpbmAuIFRoZSBleGVjdXRpb24gb2ZcbiAqIGNoYWluZWQgbWV0aG9kcyBpcyBsYXp5LCB0aGF0IGlzLCBleGVjdXRpb24gaXMgZGVmZXJyZWQgdW50aWwgYF8jdmFsdWVgXG4gKiBpcyBpbXBsaWNpdGx5IG9yIGV4cGxpY2l0bHkgY2FsbGVkLlxuICpcbiAqIExhenkgZXZhbHVhdGlvbiBhbGxvd3Mgc2V2ZXJhbCBtZXRob2RzIHRvIHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uLiBTaG9ydGN1dFxuICogZnVzaW9uIGlzIGFuIG9wdGltaXphdGlvbiBzdHJhdGVneSB3aGljaCBtZXJnZSBpdGVyYXRlZSBjYWxsczsgdGhpcyBjYW4gaGVscFxuICogdG8gYXZvaWQgdGhlIGNyZWF0aW9uIG9mIGludGVybWVkaWF0ZSBkYXRhIHN0cnVjdHVyZXMgYW5kIGdyZWF0bHkgcmVkdWNlIHRoZVxuICogbnVtYmVyIG9mIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuXG4gKlxuICogQ2hhaW5pbmcgaXMgc3VwcG9ydGVkIGluIGN1c3RvbSBidWlsZHMgYXMgbG9uZyBhcyB0aGUgYF8jdmFsdWVgIG1ldGhvZCBpc1xuICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gKlxuICogSW4gYWRkaXRpb24gdG8gbG9kYXNoIG1ldGhvZHMsIHdyYXBwZXJzIGhhdmUgYEFycmF5YCBhbmQgYFN0cmluZ2AgbWV0aG9kcy5cbiAqXG4gKiBUaGUgd3JhcHBlciBgQXJyYXlgIG1ldGhvZHMgYXJlOlxuICogYGNvbmNhdGAsIGBqb2luYCwgYHBvcGAsIGBwdXNoYCwgYHJldmVyc2VgLCBgc2hpZnRgLCBgc2xpY2VgLCBgc29ydGAsXG4gKiBgc3BsaWNlYCwgYW5kIGB1bnNoaWZ0YFxuICpcbiAqIFRoZSB3cmFwcGVyIGBTdHJpbmdgIG1ldGhvZHMgYXJlOlxuICogYHJlcGxhY2VgIGFuZCBgc3BsaXRgXG4gKlxuICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uIGFyZTpcbiAqIGBjb21wYWN0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCwgYGRyb3BXaGlsZWAsIGBmaWx0ZXJgLFxuICogYGZpcnN0YCwgYGluaXRpYWxgLCBgbGFzdGAsIGBtYXBgLCBgcGx1Y2tgLCBgcmVqZWN0YCwgYHJlc3RgLCBgcmV2ZXJzZWAsXG4gKiBgc2xpY2VgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGFrZVJpZ2h0V2hpbGVgLCBgdGFrZVdoaWxlYCwgYHRvQXJyYXlgLFxuICogYW5kIGB3aGVyZWBcbiAqXG4gKiBUaGUgY2hhaW5hYmxlIHdyYXBwZXIgbWV0aG9kcyBhcmU6XG4gKiBgYWZ0ZXJgLCBgYXJ5YCwgYGFzc2lnbmAsIGBhdGAsIGBiZWZvcmVgLCBgYmluZGAsIGBiaW5kQWxsYCwgYGJpbmRLZXlgLFxuICogYGNhbGxiYWNrYCwgYGNoYWluYCwgYGNodW5rYCwgYGNvbW1pdGAsIGBjb21wYWN0YCwgYGNvbmNhdGAsIGBjb25zdGFudGAsXG4gKiBgY291bnRCeWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCxcbiAqIGBkZWZlcmAsIGBkZWxheWAsIGBkaWZmZXJlbmNlYCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCxcbiAqIGBkcm9wV2hpbGVgLCBgZmlsbGAsIGBmaWx0ZXJgLCBgZmxhdHRlbmAsIGBmbGF0dGVuRGVlcGAsIGBmbG93YCwgYGZsb3dSaWdodGAsXG4gKiBgZm9yRWFjaGAsIGBmb3JFYWNoUmlnaHRgLCBgZm9ySW5gLCBgZm9ySW5SaWdodGAsIGBmb3JPd25gLCBgZm9yT3duUmlnaHRgLFxuICogYGZ1bmN0aW9uc2AsIGBncm91cEJ5YCwgYGluZGV4QnlgLCBgaW5pdGlhbGAsIGBpbnRlcnNlY3Rpb25gLCBgaW52ZXJ0YCxcbiAqIGBpbnZva2VgLCBga2V5c2AsIGBrZXlzSW5gLCBgbWFwYCwgYG1hcEtleXNgLCBgbWFwVmFsdWVzYCwgYG1hdGNoZXNgLFxuICogYG1hdGNoZXNQcm9wZXJ0eWAsIGBtZW1vaXplYCwgYG1lcmdlYCwgYG1ldGhvZGAsIGBtZXRob2RPZmAsIGBtaXhpbmAsXG4gKiBgbW9kQXJnc2AsIGBuZWdhdGVgLCBgb21pdGAsIGBvbmNlYCwgYHBhaXJzYCwgYHBhcnRpYWxgLCBgcGFydGlhbFJpZ2h0YCxcbiAqIGBwYXJ0aXRpb25gLCBgcGlja2AsIGBwbGFudGAsIGBwbHVja2AsIGBwcm9wZXJ0eWAsIGBwcm9wZXJ0eU9mYCwgYHB1bGxgLFxuICogYHB1bGxBdGAsIGBwdXNoYCwgYHJhbmdlYCwgYHJlYXJnYCwgYHJlamVjdGAsIGByZW1vdmVgLCBgcmVzdGAsIGByZXN0UGFyYW1gLFxuICogYHJldmVyc2VgLCBgc2V0YCwgYHNodWZmbGVgLCBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc29ydEJ5QWxsYCxcbiAqIGBzb3J0QnlPcmRlcmAsIGBzcGxpY2VgLCBgc3ByZWFkYCwgYHRha2VgLCBgdGFrZVJpZ2h0YCwgYHRha2VSaWdodFdoaWxlYCxcbiAqIGB0YWtlV2hpbGVgLCBgdGFwYCwgYHRocm90dGxlYCwgYHRocnVgLCBgdGltZXNgLCBgdG9BcnJheWAsIGB0b1BsYWluT2JqZWN0YCxcbiAqIGB0cmFuc2Zvcm1gLCBgdW5pb25gLCBgdW5pcWAsIGB1bnNoaWZ0YCwgYHVuemlwYCwgYHVuemlwV2l0aGAsIGB2YWx1ZXNgLFxuICogYHZhbHVlc0luYCwgYHdoZXJlYCwgYHdpdGhvdXRgLCBgd3JhcGAsIGB4b3JgLCBgemlwYCwgYHppcE9iamVjdGAsIGB6aXBXaXRoYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBhcmUgKipub3QqKiBjaGFpbmFibGUgYnkgZGVmYXVsdCBhcmU6XG4gKiBgYWRkYCwgYGF0dGVtcHRgLCBgY2FtZWxDYXNlYCwgYGNhcGl0YWxpemVgLCBgY2VpbGAsIGBjbG9uZWAsIGBjbG9uZURlZXBgLFxuICogYGRlYnVycmAsIGBlbmRzV2l0aGAsIGBlc2NhcGVgLCBgZXNjYXBlUmVnRXhwYCwgYGV2ZXJ5YCwgYGZpbmRgLCBgZmluZEluZGV4YCxcbiAqIGBmaW5kS2V5YCwgYGZpbmRMYXN0YCwgYGZpbmRMYXN0SW5kZXhgLCBgZmluZExhc3RLZXlgLCBgZmluZFdoZXJlYCwgYGZpcnN0YCxcbiAqIGBmbG9vcmAsIGBnZXRgLCBgZ3RgLCBgZ3RlYCwgYGhhc2AsIGBpZGVudGl0eWAsIGBpbmNsdWRlc2AsIGBpbmRleE9mYCxcbiAqIGBpblJhbmdlYCwgYGlzQXJndW1lbnRzYCwgYGlzQXJyYXlgLCBgaXNCb29sZWFuYCwgYGlzRGF0ZWAsIGBpc0VsZW1lbnRgLFxuICogYGlzRW1wdHlgLCBgaXNFcXVhbGAsIGBpc0Vycm9yYCwgYGlzRmluaXRlYCBgaXNGdW5jdGlvbmAsIGBpc01hdGNoYCxcbiAqIGBpc05hdGl2ZWAsIGBpc05hTmAsIGBpc051bGxgLCBgaXNOdW1iZXJgLCBgaXNPYmplY3RgLCBgaXNQbGFpbk9iamVjdGAsXG4gKiBgaXNSZWdFeHBgLCBgaXNTdHJpbmdgLCBgaXNVbmRlZmluZWRgLCBgaXNUeXBlZEFycmF5YCwgYGpvaW5gLCBga2ViYWJDYXNlYCxcbiAqIGBsYXN0YCwgYGxhc3RJbmRleE9mYCwgYGx0YCwgYGx0ZWAsIGBtYXhgLCBgbWluYCwgYG5vQ29uZmxpY3RgLCBgbm9vcGAsXG4gKiBgbm93YCwgYHBhZGAsIGBwYWRMZWZ0YCwgYHBhZFJpZ2h0YCwgYHBhcnNlSW50YCwgYHBvcGAsIGByYW5kb21gLCBgcmVkdWNlYCxcbiAqIGByZWR1Y2VSaWdodGAsIGByZXBlYXRgLCBgcmVzdWx0YCwgYHJvdW5kYCwgYHJ1bkluQ29udGV4dGAsIGBzaGlmdGAsIGBzaXplYCxcbiAqIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsIGBzb3J0ZWRMYXN0SW5kZXhgLCBgc3RhcnRDYXNlYCxcbiAqIGBzdGFydHNXaXRoYCwgYHN1bWAsIGB0ZW1wbGF0ZWAsIGB0cmltYCwgYHRyaW1MZWZ0YCwgYHRyaW1SaWdodGAsIGB0cnVuY2AsXG4gKiBgdW5lc2NhcGVgLCBgdW5pcXVlSWRgLCBgdmFsdWVgLCBhbmQgYHdvcmRzYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZCBgc2FtcGxlYCB3aWxsIHJldHVybiBhIHdyYXBwZWQgdmFsdWUgd2hlbiBgbmAgaXMgcHJvdmlkZWQsXG4gKiBvdGhlcndpc2UgYW4gdW53cmFwcGVkIHZhbHVlIGlzIHJldHVybmVkLlxuICpcbiAqIEBuYW1lIF9cbiAqIEBjb25zdHJ1Y3RvclxuICogQGNhdGVnb3J5IENoYWluXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwIGluIGEgYGxvZGFzaGAgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gKlxuICogLy8gcmV0dXJucyBhbiB1bndyYXBwZWQgdmFsdWVcbiAqIHdyYXBwZWQucmVkdWNlKGZ1bmN0aW9uKHRvdGFsLCBuKSB7XG4gKiAgIHJldHVybiB0b3RhbCArIG47XG4gKiB9KTtcbiAqIC8vID0+IDZcbiAqXG4gKiAvLyByZXR1cm5zIGEgd3JhcHBlZCB2YWx1ZVxuICogdmFyIHNxdWFyZXMgPSB3cmFwcGVkLm1hcChmdW5jdGlvbihuKSB7XG4gKiAgIHJldHVybiBuICogbjtcbiAqIH0pO1xuICpcbiAqIF8uaXNBcnJheShzcXVhcmVzKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KHNxdWFyZXMudmFsdWUoKSk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGxvZGFzaCh2YWx1ZSkge1xuICBpZiAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNBcnJheSh2YWx1ZSkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSkge1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExvZGFzaFdyYXBwZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdfX2NoYWluX18nKSAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnX193cmFwcGVkX18nKSkge1xuICAgICAgcmV0dXJuIHdyYXBwZXJDbG9uZSh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih2YWx1ZSk7XG59XG5cbi8vIEVuc3VyZSB3cmFwcGVycyBhcmUgaW5zdGFuY2VzIG9mIGBiYXNlTG9kYXNoYC5cbmxvZGFzaC5wcm90b3R5cGUgPSBiYXNlTG9kYXNoLnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2Rhc2g7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZm9yRWFjaCcpO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUVhY2gnKSxcbiAgICBjcmVhdGVGaW5kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlRmluZCcpO1xuXG4vKipcbiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgdGhlIGZpcnN0IGVsZW1lbnRcbiAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kXG4gKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gKlxuICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBkZXRlY3RcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gKiAgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAqIF07XG4gKlxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCBmdW5jdGlvbihjaHIpIHtcbiAqICAgcmV0dXJuIGNoci5hZ2UgPCA0MDtcbiAqIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ2Jhcm5leSdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiB0cnVlIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ3BlYmJsZXMnXG4gKlxuICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gKiAvLyA9PiAnZnJlZCdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCAnYWN0aXZlJyksICd1c2VyJyk7XG4gKiAvLyA9PiAnYmFybmV5J1xuICovXG52YXIgZmluZCA9IGNyZWF0ZUZpbmQoYmFzZUVhY2gpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmQ7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlFYWNoJyksXG4gICAgYmFzZUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRWFjaCcpLFxuICAgIGNyZWF0ZUZvckVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoJyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICogVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5XG4gKiBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICpcbiAqICoqTm90ZToqKiBBcyB3aXRoIG90aGVyIFwiQ29sbGVjdGlvbnNcIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSBcImxlbmd0aFwiIHByb3BlcnR5XG4gKiBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYF8uZm9ySW5gIG9yIGBfLmZvck93bmBcbiAqIG1heSBiZSB1c2VkIGZvciBvYmplY3QgaXRlcmF0aW9uLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgZWFjaFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICogQHJldHVybnMge0FycmF5fE9iamVjdHxzdHJpbmd9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfKFsxLCAyXSkuZm9yRWFjaChmdW5jdGlvbihuKSB7XG4gKiAgIGNvbnNvbGUubG9nKG4pO1xuICogfSkudmFsdWUoKTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZSBmcm9tIGxlZnQgdG8gcmlnaHQgYW5kIHJldHVybnMgdGhlIGFycmF5XG4gKlxuICogXy5mb3JFYWNoKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24obiwga2V5KSB7XG4gKiAgIGNvbnNvbGUubG9nKG4sIGtleSk7XG4gKiB9KTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZS1rZXkgcGFpciBhbmQgcmV0dXJucyB0aGUgb2JqZWN0IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbnZhciBmb3JFYWNoID0gY3JlYXRlRm9yRWFjaChhcnJheUVhY2gsIGJhc2VFYWNoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmb3JFYWNoO1xuIiwidmFyIGJhc2VJbmRleE9mID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUluZGV4T2YnKSxcbiAgICBnZXRMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXRMZW5ndGgnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNJdGVyYXRlZUNhbGwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0l0ZXJhdGVlQ2FsbCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICB2YWx1ZXMgPSByZXF1aXJlKCcuLi9vYmplY3QvdmFsdWVzJyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB0YXJnZXRgIGlzIGluIGBjb2xsZWN0aW9uYCB1c2luZ1xuICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhcyB0aGUgb2Zmc2V0XG4gKiBmcm9tIHRoZSBlbmQgb2YgYGNvbGxlY3Rpb25gLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29udGFpbnMsIGluY2x1ZGVcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ucmVkdWNlYC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIG1hdGNoaW5nIGVsZW1lbnQgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxLCAyKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pbmNsdWRlcyh7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfSwgJ2ZyZWQnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmluY2x1ZGVzKCdwZWJibGVzJywgJ2ViJyk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGluY2x1ZGVzKGNvbGxlY3Rpb24sIHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkge1xuICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbiA/IGdldExlbmd0aChjb2xsZWN0aW9uKSA6IDA7XG4gIGlmICghaXNMZW5ndGgobGVuZ3RoKSkge1xuICAgIGNvbGxlY3Rpb24gPSB2YWx1ZXMoY29sbGVjdGlvbik7XG4gICAgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG4gIH1cbiAgaWYgKHR5cGVvZiBmcm9tSW5kZXggIT0gJ251bWJlcicgfHwgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkpKSB7XG4gICAgZnJvbUluZGV4ID0gMDtcbiAgfSBlbHNlIHtcbiAgICBmcm9tSW5kZXggPSBmcm9tSW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGZyb21JbmRleCwgMCkgOiAoZnJvbUluZGV4IHx8IDApO1xuICB9XG4gIHJldHVybiAodHlwZW9mIGNvbGxlY3Rpb24gPT0gJ3N0cmluZycgfHwgIWlzQXJyYXkoY29sbGVjdGlvbikgJiYgaXNTdHJpbmcoY29sbGVjdGlvbikpXG4gICAgPyAoZnJvbUluZGV4IDw9IGxlbmd0aCAmJiBjb2xsZWN0aW9uLmluZGV4T2YodGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpXG4gICAgOiAoISFsZW5ndGggJiYgYmFzZUluZGV4T2YoY29sbGVjdGlvbiwgdGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluY2x1ZGVzO1xuIiwidmFyIGFycmF5TWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlNYXAnKSxcbiAgICBiYXNlQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2FsbGJhY2snKSxcbiAgICBiYXNlTWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZU1hcCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhyb3VnaFxuICogYGl0ZXJhdGVlYC4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWVcbiAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICpcbiAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAqIGBfLmV2ZXJ5YCwgYF8uZmlsdGVyYCwgYF8ubWFwYCwgYF8ubWFwVmFsdWVzYCwgYF8ucmVqZWN0YCwgYW5kIGBfLnNvbWVgLlxuICpcbiAqIFRoZSBndWFyZGVkIG1ldGhvZHMgYXJlOlxuICogYGFyeWAsIGBjYWxsYmFja2AsIGBjaHVua2AsIGBjbG9uZWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgY3VycnlSaWdodGAsXG4gKiBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLCBgZmlsbGAsIGBmbGF0dGVuYCwgYGludmVydGAsIGBtYXhgLCBgbWluYCxcbiAqIGBwYXJzZUludGAsIGBzbGljZWAsIGBzb3J0QnlgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGVtcGxhdGVgLCBgdHJpbWAsXG4gKiBgdHJpbUxlZnRgLCBgdHJpbVJpZ2h0YCwgYHRydW5jYCwgYHJhbmRvbWAsIGByYW5nZWAsIGBzYW1wbGVgLCBgc29tZWAsXG4gKiBgc3VtYCwgYHVuaXFgLCBhbmQgYHdvcmRzYFxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29sbGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICogIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gdGltZXNUaHJlZShuKSB7XG4gKiAgIHJldHVybiBuICogMztcbiAqIH1cbiAqXG4gKiBfLm1hcChbMSwgMl0sIHRpbWVzVGhyZWUpO1xuICogLy8gPT4gWzMsIDZdXG4gKlxuICogXy5tYXAoeyAnYSc6IDEsICdiJzogMiB9LCB0aW1lc1RocmVlKTtcbiAqIC8vID0+IFszLCA2XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5tYXAodXNlcnMsICd1c2VyJyk7XG4gKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJ11cbiAqL1xuZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5TWFwIDogYmFzZU1hcDtcbiAgaXRlcmF0ZWUgPSBiYXNlQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU5vdyA9IGdldE5hdGl2ZShEYXRlLCAnbm93Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgVW5peCBlcG9jaFxuICogKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBEYXRlXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTtcbiAqIH0sIF8ubm93KCkpO1xuICogLy8gPT4gbG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgZnVuY3Rpb24gdG8gYmUgaW52b2tlZFxuICovXG52YXIgbm93ID0gbmF0aXZlTm93IHx8IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5vdztcbiIsInZhciBjcmVhdGVXcmFwcGVyID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlV3JhcHBlcicpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMnKSxcbiAgICByZXN0UGFyYW0gPSByZXF1aXJlKCcuL3Jlc3RQYXJhbScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgUEFSVElBTF9GTEFHID0gMzI7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgXG4gKiBhbmQgcHJlcGVuZHMgYW55IGFkZGl0aW9uYWwgYF8uYmluZGAgYXJndW1lbnRzIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZVxuICogYm91bmQgZnVuY3Rpb24uXG4gKlxuICogVGhlIGBfLmJpbmQucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpYyBidWlsZHMsXG4gKiBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogKipOb3RlOioqIFVubGlrZSBuYXRpdmUgYEZ1bmN0aW9uI2JpbmRgIHRoaXMgbWV0aG9kIGRvZXMgbm90IHNldCB0aGUgXCJsZW5ndGhcIlxuICogcHJvcGVydHkgb2YgYm91bmQgZnVuY3Rpb25zLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBncmVldCA9IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICogICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAqIH07XG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gKiBib3VuZCgnIScpO1xuICogLy8gPT4gJ2hpIGZyZWQhJ1xuICpcbiAqIC8vIHVzaW5nIHBsYWNlaG9sZGVyc1xuICogdmFyIGJvdW5kID0gXy5iaW5kKGdyZWV0LCBvYmplY3QsIF8sICchJyk7XG4gKiBib3VuZCgnaGknKTtcbiAqIC8vID0+ICdoaSBmcmVkISdcbiAqL1xudmFyIGJpbmQgPSByZXN0UGFyYW0oZnVuY3Rpb24oZnVuYywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGJpdG1hc2sgPSBCSU5EX0ZMQUc7XG4gIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBiaW5kLnBsYWNlaG9sZGVyKTtcbiAgICBiaXRtYXNrIHw9IFBBUlRJQUxfRkxBRztcbiAgfVxuICByZXR1cm4gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycyk7XG59KTtcblxuLy8gQXNzaWduIGRlZmF1bHQgcGxhY2Vob2xkZXJzLlxuYmluZC5wbGFjZWhvbGRlciA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQ7XG4iLCIvKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAqIGNyZWF0ZWQgZnVuY3Rpb24gYW5kIGFyZ3VtZW50cyBmcm9tIGBzdGFydGAgYW5kIGJleW9uZCBwcm92aWRlZCBhcyBhbiBhcnJheS5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb24gdGhlIFtyZXN0IHBhcmFtZXRlcl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0Z1bmN0aW9ucy9yZXN0X3BhcmFtZXRlcnMpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHNheSA9IF8ucmVzdFBhcmFtKGZ1bmN0aW9uKHdoYXQsIG5hbWVzKSB7XG4gKiAgIHJldHVybiB3aGF0ICsgJyAnICsgXy5pbml0aWFsKG5hbWVzKS5qb2luKCcsICcpICtcbiAqICAgICAoXy5zaXplKG5hbWVzKSA+IDEgPyAnLCAmICcgOiAnJykgKyBfLmxhc3QobmFtZXMpO1xuICogfSk7XG4gKlxuICogc2F5KCdoZWxsbycsICdmcmVkJywgJ2Jhcm5leScsICdwZWJibGVzJyk7XG4gKiAvLyA9PiAnaGVsbG8gZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnXG4gKi9cbmZ1bmN0aW9uIHJlc3RQYXJhbShmdW5jLCBzdGFydCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICBzdGFydCA9IG5hdGl2ZU1heChzdGFydCA9PT0gdW5kZWZpbmVkID8gKGZ1bmMubGVuZ3RoIC0gMSkgOiAoK3N0YXJ0IHx8IDApLCAwKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBzdGFydCwgMCksXG4gICAgICAgIHJlc3QgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHJlc3RbaW5kZXhdID0gYXJnc1tzdGFydCArIGluZGV4XTtcbiAgICB9XG4gICAgc3dpdGNoIChzdGFydCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIHJlc3QpO1xuICAgICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIHJlc3QpO1xuICAgICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIHJlc3QpO1xuICAgIH1cbiAgICB2YXIgb3RoZXJBcmdzID0gQXJyYXkoc3RhcnQgKyAxKTtcbiAgICBpbmRleCA9IC0xO1xuICAgIHdoaWxlICgrK2luZGV4IDwgc3RhcnQpIHtcbiAgICAgIG90aGVyQXJnc1tpbmRleF0gPSBhcmdzW2luZGV4XTtcbiAgICB9XG4gICAgb3RoZXJBcmdzW3N0YXJ0XSA9IHJlc3Q7XG4gICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgb3RoZXJBcmdzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXN0UGFyYW07XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vYmFzZUNyZWF0ZScpLFxuICAgIGJhc2VMb2Rhc2ggPSByZXF1aXJlKCcuL2Jhc2VMb2Rhc2gnKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgYC1JbmZpbml0eWAgYW5kIGBJbmZpbml0eWAuICovXG52YXIgUE9TSVRJVkVfSU5GSU5JVFkgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxhenkgd3JhcHBlciBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgbGF6eSBldmFsdWF0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICovXG5mdW5jdGlvbiBMYXp5V3JhcHBlcih2YWx1ZSkge1xuICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gIHRoaXMuX19hY3Rpb25zX18gPSBbXTtcbiAgdGhpcy5fX2Rpcl9fID0gMTtcbiAgdGhpcy5fX2ZpbHRlcmVkX18gPSBmYWxzZTtcbiAgdGhpcy5fX2l0ZXJhdGVlc19fID0gW107XG4gIHRoaXMuX190YWtlQ291bnRfXyA9IFBPU0lUSVZFX0lORklOSVRZO1xuICB0aGlzLl9fdmlld3NfXyA9IFtdO1xufVxuXG5MYXp5V3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbkxhenlXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExhenlXcmFwcGVyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IExhenlXcmFwcGVyO1xuIiwidmFyIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL2Jhc2VDcmVhdGUnKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi9iYXNlTG9kYXNoJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgY29uc3RydWN0b3IgZm9yIGNyZWF0aW5nIGBsb2Rhc2hgIHdyYXBwZXIgb2JqZWN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NoYWluQWxsXSBFbmFibGUgY2hhaW5pbmcgZm9yIGFsbCB3cmFwcGVyIG1ldGhvZHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYWN0aW9ucz1bXV0gQWN0aW9ucyB0byBwZWZvcm0gdG8gcmVzb2x2ZSB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBMb2Rhc2hXcmFwcGVyKHZhbHVlLCBjaGFpbkFsbCwgYWN0aW9ucykge1xuICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gIHRoaXMuX19hY3Rpb25zX18gPSBhY3Rpb25zIHx8IFtdO1xuICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG59XG5cbkxvZGFzaFdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG5Mb2Rhc2hXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExvZGFzaFdyYXBwZXI7XG5cbm1vZHVsZS5leHBvcnRzID0gTG9kYXNoV3JhcHBlcjtcbiIsIi8qKlxuICogQ29waWVzIHRoZSB2YWx1ZXMgb2YgYHNvdXJjZWAgdG8gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyBmcm9tLlxuICogQHBhcmFtIHtBcnJheX0gW2FycmF5PVtdXSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgdG8uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlDb3B5KHNvdXJjZSwgYXJyYXkpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuXG4gIGFycmF5IHx8IChhcnJheSA9IEFycmF5KGxlbmd0aCkpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGFycmF5W2luZGV4XSA9IHNvdXJjZVtpbmRleF07XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5Q29weTtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUVhY2g7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tYXBgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5TWFwO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheVNvbWU7XG4iLCJ2YXIgYmFzZUNvcHkgPSByZXF1aXJlKCcuL2Jhc2VDb3B5JyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nLFxuICogbXVsdGlwbGUgc291cmNlcywgYW5kIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBzb3VyY2UgPT0gbnVsbFxuICAgID8gb2JqZWN0XG4gICAgOiBiYXNlQ29weShzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQXNzaWduO1xuIiwidmFyIGJhc2VNYXRjaGVzID0gcmVxdWlyZSgnLi9iYXNlTWF0Y2hlcycpLFxuICAgIGJhc2VNYXRjaGVzUHJvcGVydHkgPSByZXF1aXJlKCcuL2Jhc2VNYXRjaGVzUHJvcGVydHknKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlkZW50aXR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9pZGVudGl0eScpLFxuICAgIHByb3BlcnR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9wcm9wZXJ0eScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNhbGxiYWNrYCB3aGljaCBzdXBwb3J0cyBzcGVjaWZ5aW5nIHRoZVxuICogbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSBbZnVuYz1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhIGNhbGxiYWNrLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJnQ291bnRdIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAqL1xuZnVuY3Rpb24gYmFzZUNhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIGZ1bmM7XG4gIGlmICh0eXBlID09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdGhpc0FyZyA9PT0gdW5kZWZpbmVkXG4gICAgICA/IGZ1bmNcbiAgICAgIDogYmluZENhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KTtcbiAgfVxuICBpZiAoZnVuYyA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGlkZW50aXR5O1xuICB9XG4gIGlmICh0eXBlID09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGJhc2VNYXRjaGVzKGZ1bmMpO1xuICB9XG4gIHJldHVybiB0aGlzQXJnID09PSB1bmRlZmluZWRcbiAgICA/IHByb3BlcnR5KGZ1bmMpXG4gICAgOiBiYXNlTWF0Y2hlc1Byb3BlcnR5KGZ1bmMsIHRoaXNBcmcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDYWxsYmFjaztcbiIsInZhciBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpLFxuICAgIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vYXJyYXlFYWNoJyksXG4gICAgYmFzZUFzc2lnbiA9IHJlcXVpcmUoJy4vYmFzZUFzc2lnbicpLFxuICAgIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBpbml0Q2xvbmVBcnJheSA9IHJlcXVpcmUoJy4vaW5pdENsb25lQXJyYXknKSxcbiAgICBpbml0Q2xvbmVCeVRhZyA9IHJlcXVpcmUoJy4vaW5pdENsb25lQnlUYWcnKSxcbiAgICBpbml0Q2xvbmVPYmplY3QgPSByZXF1aXJlKCcuL2luaXRDbG9uZU9iamVjdCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuL2lzSG9zdE9iamVjdCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIHN1cHBvcnRlZCBieSBgXy5jbG9uZWAuICovXG52YXIgY2xvbmVhYmxlVGFncyA9IHt9O1xuY2xvbmVhYmxlVGFnc1thcmdzVGFnXSA9IGNsb25lYWJsZVRhZ3NbYXJyYXlUYWddID1cbmNsb25lYWJsZVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gY2xvbmVhYmxlVGFnc1tib29sVGFnXSA9XG5jbG9uZWFibGVUYWdzW2RhdGVUYWddID0gY2xvbmVhYmxlVGFnc1tmbG9hdDMyVGFnXSA9XG5jbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQ4VGFnXSA9XG5jbG9uZWFibGVUYWdzW2ludDE2VGFnXSA9IGNsb25lYWJsZVRhZ3NbaW50MzJUYWddID1cbmNsb25lYWJsZVRhZ3NbbnVtYmVyVGFnXSA9IGNsb25lYWJsZVRhZ3Nbb2JqZWN0VGFnXSA9XG5jbG9uZWFibGVUYWdzW3JlZ2V4cFRhZ10gPSBjbG9uZWFibGVUYWdzW3N0cmluZ1RhZ10gPVxuY2xvbmVhYmxlVGFnc1t1aW50OFRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPVxuY2xvbmVhYmxlVGFnc1t1aW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbmNsb25lYWJsZVRhZ3NbZXJyb3JUYWddID0gY2xvbmVhYmxlVGFnc1tmdW5jVGFnXSA9XG5jbG9uZWFibGVUYWdzW21hcFRhZ10gPSBjbG9uZWFibGVUYWdzW3NldFRhZ10gPVxuY2xvbmVhYmxlVGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhcmd1bWVudCBqdWdnbGluZ1xuICogYW5kIGB0aGlzYCBiaW5kaW5nIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcgdmFsdWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IGB2YWx1ZWAgYmVsb25ncyB0by5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBBc3NvY2lhdGVzIGNsb25lcyB3aXRoIHNvdXJjZSBjb3VudGVycGFydHMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGlzRGVlcCwgY3VzdG9taXplciwga2V5LCBvYmplY3QsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciByZXN1bHQ7XG4gIGlmIChjdXN0b21pemVyKSB7XG4gICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QpIDogY3VzdG9taXplcih2YWx1ZSk7XG4gIH1cbiAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKTtcbiAgaWYgKGlzQXJyKSB7XG4gICAgcmVzdWx0ID0gaW5pdENsb25lQXJyYXkodmFsdWUpO1xuICAgIGlmICghaXNEZWVwKSB7XG4gICAgICByZXR1cm4gYXJyYXlDb3B5KHZhbHVlLCByZXN1bHQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgdGFnID0gb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSksXG4gICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcgfHwgdGFnID09IGFyZ3NUYWcgfHwgKGlzRnVuYyAmJiAhb2JqZWN0KSkge1xuICAgICAgaWYgKGlzSG9zdE9iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA/IHZhbHVlIDoge307XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBpbml0Q2xvbmVPYmplY3QoaXNGdW5jID8ge30gOiB2YWx1ZSk7XG4gICAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgICByZXR1cm4gYmFzZUFzc2lnbihyZXN1bHQsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNsb25lYWJsZVRhZ3NbdGFnXVxuICAgICAgICA/IGluaXRDbG9uZUJ5VGFnKHZhbHVlLCB0YWcsIGlzRGVlcClcbiAgICAgICAgOiAob2JqZWN0ID8gdmFsdWUgOiB7fSk7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIGFuZCByZXR1cm4gaXRzIGNvcnJlc3BvbmRpbmcgY2xvbmUuXG4gIHN0YWNrQSB8fCAoc3RhY2tBID0gW10pO1xuICBzdGFja0IgfHwgKHN0YWNrQiA9IFtdKTtcblxuICB2YXIgbGVuZ3RoID0gc3RhY2tBLmxlbmd0aDtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKHN0YWNrQVtsZW5ndGhdID09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gc3RhY2tCW2xlbmd0aF07XG4gICAgfVxuICB9XG4gIC8vIEFkZCB0aGUgc291cmNlIHZhbHVlIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cyBhbmQgYXNzb2NpYXRlIGl0IHdpdGggaXRzIGNsb25lLlxuICBzdGFja0EucHVzaCh2YWx1ZSk7XG4gIHN0YWNrQi5wdXNoKHJlc3VsdCk7XG5cbiAgLy8gUmVjdXJzaXZlbHkgcG9wdWxhdGUgY2xvbmUgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgKGlzQXJyID8gYXJyYXlFYWNoIDogYmFzZUZvck93bikodmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRba2V5XSA9IGJhc2VDbG9uZShzdWJWYWx1ZSwgaXNEZWVwLCBjdXN0b21pemVyLCBrZXksIHZhbHVlLCBzdGFja0EsIHN0YWNrQik7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDbG9uZTtcbiIsIi8qKlxuICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBjb3B5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIHRvLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUNvcHkoc291cmNlLCBwcm9wcywgb2JqZWN0KSB7XG4gIG9iamVjdCB8fCAob2JqZWN0ID0ge30pO1xuXG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBvYmplY3Rba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNvcHk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY3JlYXRlYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFzc2lnbmluZ1xuICogcHJvcGVydGllcyB0byB0aGUgY3JlYXRlZCBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90b3R5cGUgVGhlIG9iamVjdCB0byBpbmhlcml0IGZyb20uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICovXG52YXIgYmFzZUNyZWF0ZSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvdHlwZSkge1xuICAgIGlmIChpc09iamVjdChwcm90b3R5cGUpKSB7XG4gICAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBvYmplY3Q7XG4gICAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0IHx8IHt9O1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ3JlYXRlO1xuIiwidmFyIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBjcmVhdGVCYXNlRWFjaCA9IHJlcXVpcmUoJy4vY3JlYXRlQmFzZUVhY2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fHN0cmluZ30gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gKi9cbnZhciBiYXNlRWFjaCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd24pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VFYWNoO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kYCwgYF8uZmluZExhc3RgLCBgXy5maW5kS2V5YCwgYW5kIGBfLmZpbmRMYXN0S2V5YCxcbiAqIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcsIHdoaWNoIGl0ZXJhdGVzXG4gKiBvdmVyIGBjb2xsZWN0aW9uYCB1c2luZyB0aGUgcHJvdmlkZWQgYGVhY2hGdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBgY29sbGVjdGlvbmAuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRLZXldIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBrZXkgb2YgdGhlIGZvdW5kIGVsZW1lbnRcbiAqICBpbnN0ZWFkIG9mIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmb3VuZCBlbGVtZW50IG9yIGl0cyBrZXksIGVsc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VGaW5kKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZWFjaEZ1bmMsIHJldEtleSkge1xuICB2YXIgcmVzdWx0O1xuICBlYWNoRnVuYyhjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSkge1xuICAgICAgcmVzdWx0ID0gcmV0S2V5ID8ga2V5IDogdmFsdWU7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRmluZDtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmluZEluZGV4YCBhbmQgYF8uZmluZExhc3RJbmRleGAgd2l0aG91dFxuICogc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZpbmRJbmRleChhcnJheSwgcHJlZGljYXRlLCBmcm9tUmlnaHQpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZpbmRJbmRleDtcbiIsInZhciBjcmVhdGVCYXNlRm9yID0gcmVxdWlyZSgnLi9jcmVhdGVCYXNlRm9yJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JJbmAgYW5kIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlc1xuICogb3ZlciBgb2JqZWN0YCBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3JcbiAqIGVhY2ggcHJvcGVydHkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseVxuICogcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3I7XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXNJbiA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzSW4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvckluKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgcmV0dXJuIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5c0luKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9ySW47XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93bmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gIHJldHVybiBiYXNlRm9yKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3JPd247XG4iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBzdHJpbmcgcGF0aHNcbiAqIGFuZCBkZWZhdWx0IHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoS2V5XSBUaGUga2V5IHJlcHJlc2VudGF0aW9uIG9mIHBhdGguXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoLCBwYXRoS2V5KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICBpZiAocGF0aEtleSAhPT0gdW5kZWZpbmVkICYmIHBhdGhLZXkgaW4gb2JqZWN0KSB7XG4gICAgcGF0aCA9IFtwYXRoS2V5XTtcbiAgfVxuICB2YXIgaW5kZXggPSAwLFxuICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgd2hpbGUgKG9iamVjdCAhPSBudWxsICYmIGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KVtwYXRoW2luZGV4KytdXTtcbiAgfVxuICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldDtcbiIsInZhciBpbmRleE9mTmFOID0gcmVxdWlyZSgnLi9pbmRleE9mTmFOJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5kZXhPZmAgd2l0aG91dCBzdXBwb3J0IGZvciBiaW5hcnkgc2VhcmNoZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICBpZiAodmFsdWUgIT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIGluZGV4T2ZOYU4oYXJyYXksIGZyb21JbmRleCk7XG4gIH1cbiAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSW5kZXhPZjtcbiIsInZhciBiYXNlSXNFcXVhbERlZXAgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsRGVlcCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNFcXVhbGAgd2l0aG91dCBzdXBwb3J0IGZvciBgdGhpc2AgYmluZGluZ1xuICogYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgdmFsdWVzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0KHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjtcbiAgfVxuICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYmFzZUlzRXF1YWwsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbDtcbiIsInZhciBlcXVhbEFycmF5cyA9IHJlcXVpcmUoJy4vZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9lcXVhbEJ5VGFnJyksXG4gICAgZXF1YWxPYmplY3RzID0gcmVxdWlyZSgnLi9lcXVhbE9iamVjdHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi9pc0hvc3RPYmplY3QnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzVHlwZWRBcnJheScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbGAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICogZGVlcCBjb21wYXJpc29ucyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhclxuICogcmVmZXJlbmNlcyB0byBiZSBjb21wYXJlZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQj1bXV0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWxEZWVwKG9iamVjdCwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIG9iaklzQXJyID0gaXNBcnJheShvYmplY3QpLFxuICAgICAgb3RoSXNBcnIgPSBpc0FycmF5KG90aGVyKSxcbiAgICAgIG9ialRhZyA9IGFycmF5VGFnLFxuICAgICAgb3RoVGFnID0gYXJyYXlUYWc7XG5cbiAgaWYgKCFvYmpJc0Fycikge1xuICAgIG9ialRhZyA9IG9ialRvU3RyaW5nLmNhbGwob2JqZWN0KTtcbiAgICBpZiAob2JqVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgIG9ialRhZyA9IG9iamVjdFRhZztcbiAgICB9IGVsc2UgaWYgKG9ialRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgIG9iaklzQXJyID0gaXNUeXBlZEFycmF5KG9iamVjdCk7XG4gICAgfVxuICB9XG4gIGlmICghb3RoSXNBcnIpIHtcbiAgICBvdGhUYWcgPSBvYmpUb1N0cmluZy5jYWxsKG90aGVyKTtcbiAgICBpZiAob3RoVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgIG90aFRhZyA9IG9iamVjdFRhZztcbiAgICB9IGVsc2UgaWYgKG90aFRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgIG90aElzQXJyID0gaXNUeXBlZEFycmF5KG90aGVyKTtcbiAgICB9XG4gIH1cbiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KG9iamVjdCksXG4gICAgICBvdGhJc09iaiA9IG90aFRhZyA9PSBvYmplY3RUYWcgJiYgIWlzSG9zdE9iamVjdChvdGhlciksXG4gICAgICBpc1NhbWVUYWcgPSBvYmpUYWcgPT0gb3RoVGFnO1xuXG4gIGlmIChpc1NhbWVUYWcgJiYgIShvYmpJc0FyciB8fCBvYmpJc09iaikpIHtcbiAgICByZXR1cm4gZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCBvYmpUYWcpO1xuICB9XG4gIGlmICghaXNMb29zZSkge1xuICAgIHZhciBvYmpJc1dyYXBwZWQgPSBvYmpJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ19fd3JhcHBlZF9fJyksXG4gICAgICAgIG90aElzV3JhcHBlZCA9IG90aElzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsICdfX3dyYXBwZWRfXycpO1xuXG4gICAgaWYgKG9iaklzV3JhcHBlZCB8fCBvdGhJc1dyYXBwZWQpIHtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsIG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlciwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuICAgIH1cbiAgfVxuICBpZiAoIWlzU2FtZVRhZykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGRldGVjdGluZyBjaXJjdWxhciByZWZlcmVuY2VzIHNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI0pPLlxuICBzdGFja0EgfHwgKHN0YWNrQSA9IFtdKTtcbiAgc3RhY2tCIHx8IChzdGFja0IgPSBbXSk7XG5cbiAgdmFyIGxlbmd0aCA9IHN0YWNrQS5sZW5ndGg7XG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIGlmIChzdGFja0FbbGVuZ3RoXSA9PSBvYmplY3QpIHtcbiAgICAgIHJldHVybiBzdGFja0JbbGVuZ3RoXSA9PSBvdGhlcjtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIGBvYmplY3RgIGFuZCBgb3RoZXJgIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgc3RhY2tBLnB1c2gob2JqZWN0KTtcbiAgc3RhY2tCLnB1c2gob3RoZXIpO1xuXG4gIHZhciByZXN1bHQgPSAob2JqSXNBcnIgPyBlcXVhbEFycmF5cyA6IGVxdWFsT2JqZWN0cykob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG5cbiAgc3RhY2tBLnBvcCgpO1xuICBzdGFja0IucG9wKCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIHRvIG1hdGNoLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSwgY3VzdG9taXplcikge1xuICB2YXIgaW5kZXggPSBtYXRjaERhdGEubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gaW5kZXgsXG4gICAgICBub0N1c3RvbWl6ZXIgPSAhY3VzdG9taXplcjtcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gIWxlbmd0aDtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICB3aGlsZSAoaW5kZXgtLSkge1xuICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICBpZiAoKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKVxuICAgICAgICAgID8gZGF0YVsxXSAhPT0gb2JqZWN0W2RhdGFbMF1dXG4gICAgICAgICAgOiAhKGRhdGFbMF0gaW4gb2JqZWN0KVxuICAgICAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICB2YXIga2V5ID0gZGF0YVswXSxcbiAgICAgICAgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgc3JjVmFsdWUgPSBkYXRhWzFdO1xuXG4gICAgaWYgKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKSB7XG4gICAgICBpZiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcbiAgICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBjdXN0b21pemVyLCB0cnVlKSA6IHJlc3VsdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNNYXRjaDtcbiIsIi8qKlxuICogVGhlIGZ1bmN0aW9uIHdob3NlIHByb3RvdHlwZSBhbGwgY2hhaW5pbmcgd3JhcHBlcnMgaW5oZXJpdCBmcm9tLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGJhc2VMb2Rhc2goKSB7XG4gIC8vIE5vIG9wZXJhdGlvbiBwZXJmb3JtZWQuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUxvZGFzaDtcbiIsInZhciBiYXNlRWFjaCA9IHJlcXVpcmUoJy4vYmFzZUVhY2gnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXBgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kc1xuICogYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107XG5cbiAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgIHJlc3VsdFsrK2luZGV4XSA9IGl0ZXJhdGVlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWFwO1xuIiwidmFyIGJhc2VJc01hdGNoID0gcmVxdWlyZSgnLi9iYXNlSXNNYXRjaCcpLFxuICAgIGdldE1hdGNoRGF0YSA9IHJlcXVpcmUoJy4vZ2V0TWF0Y2hEYXRhJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc2Agd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNvdXJjZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXMoc291cmNlKSB7XG4gIHZhciBtYXRjaERhdGEgPSBnZXRNYXRjaERhdGEoc291cmNlKTtcbiAgaWYgKG1hdGNoRGF0YS5sZW5ndGggPT0gMSAmJiBtYXRjaERhdGFbMF1bMl0pIHtcbiAgICB2YXIga2V5ID0gbWF0Y2hEYXRhWzBdWzBdLFxuICAgICAgICB2YWx1ZSA9IG1hdGNoRGF0YVswXVsxXTtcblxuICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICAgICAgcmV0dXJuIG9iamVjdFtrZXldID09PSB2YWx1ZSAmJiAodmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1hdGNoZXM7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIGJhc2VJc0VxdWFsID0gcmVxdWlyZSgnLi9iYXNlSXNFcXVhbCcpLFxuICAgIGJhc2VTbGljZSA9IHJlcXVpcmUoJy4vYmFzZVNsaWNlJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzS2V5ID0gcmVxdWlyZSgnLi9pc0tleScpLFxuICAgIGlzU3RyaWN0Q29tcGFyYWJsZSA9IHJlcXVpcmUoJy4vaXNTdHJpY3RDb21wYXJhYmxlJyksXG4gICAgbGFzdCA9IHJlcXVpcmUoJy4uL2FycmF5L2xhc3QnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKSxcbiAgICB0b1BhdGggPSByZXF1aXJlKCcuL3RvUGF0aCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNyY1ZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBzcmNWYWx1ZSkge1xuICB2YXIgaXNBcnIgPSBpc0FycmF5KHBhdGgpLFxuICAgICAgaXNDb21tb24gPSBpc0tleShwYXRoKSAmJiBpc1N0cmljdENvbXBhcmFibGUoc3JjVmFsdWUpLFxuICAgICAgcGF0aEtleSA9IChwYXRoICsgJycpO1xuXG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIGtleSA9IHBhdGhLZXk7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICBpZiAoKGlzQXJyIHx8ICFpc0NvbW1vbikgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgb2JqZWN0ID0gcGF0aC5sZW5ndGggPT0gMSA/IG9iamVjdCA6IGJhc2VHZXQob2JqZWN0LCBiYXNlU2xpY2UocGF0aCwgMCwgLTEpKTtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBrZXkgPSBsYXN0KHBhdGgpO1xuICAgICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBzcmNWYWx1ZVxuICAgICAgPyAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpXG4gICAgICA6IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmplY3Rba2V5XSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWF0Y2hlc1Byb3BlcnR5O1xuIiwidmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHRvT2JqZWN0KG9iamVjdClba2V5XTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlUHJvcGVydHk7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIHRvUGF0aCA9IHJlcXVpcmUoJy4vdG9QYXRoJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUHJvcGVydHlgIHdoaWNoIHN1cHBvcnRzIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZVByb3BlcnR5RGVlcChwYXRoKSB7XG4gIHZhciBwYXRoS2V5ID0gKHBhdGggKyAnJyk7XG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gYmFzZUdldChvYmplY3QsIHBhdGgsIHBhdGhLZXkpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eURlZXA7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5JyksXG4gICAgbWV0YU1hcCA9IHJlcXVpcmUoJy4vbWV0YU1hcCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXREYXRhYCB3aXRob3V0IHN1cHBvcnQgZm9yIGhvdCBsb29wIGRldGVjdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAqL1xudmFyIGJhc2VTZXREYXRhID0gIW1ldGFNYXAgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIGRhdGEpIHtcbiAgbWV0YU1hcC5zZXQoZnVuYywgZGF0YSk7XG4gIHJldHVybiBmdW5jO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlU2V0RGF0YTtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2xpY2VgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICBzdGFydCA9IHN0YXJ0ID09IG51bGwgPyAwIDogKCtzdGFydCB8fCAwKTtcbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gLXN0YXJ0ID4gbGVuZ3RoID8gMCA6IChsZW5ndGggKyBzdGFydCk7XG4gIH1cbiAgZW5kID0gKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IGxlbmd0aCkgPyBsZW5ndGggOiAoK2VuZCB8fCAwKTtcbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuZ3RoO1xuICB9XG4gIGxlbmd0aCA9IHN0YXJ0ID4gZW5kID8gMCA6ICgoZW5kIC0gc3RhcnQpID4+PiAwKTtcbiAgc3RhcnQgPj4+PSAwO1xuXG4gIHZhciByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSBhcnJheVtpbmRleCArIHN0YXJ0XTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VTbGljZTtcbiIsIi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBpZiBpdCdzIG5vdCBvbmUuIEFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZFxuICogZm9yIGBudWxsYCBvciBgdW5kZWZpbmVkYCB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGJhc2VUb1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogKHZhbHVlICsgJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUb1N0cmluZztcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udmFsdWVzYCBhbmQgYF8udmFsdWVzSW5gIHdoaWNoIGNyZWF0ZXMgYW5cbiAqIGFycmF5IG9mIGBvYmplY3RgIHByb3BlcnR5IHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lc1xuICogb2YgYHByb3BzYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGdldCB2YWx1ZXMgZm9yLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBiYXNlVmFsdWVzKG9iamVjdCwgcHJvcHMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IG9iamVjdFtwcm9wc1tpbmRleF1dO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVZhbHVlcztcbiIsInZhciBiaW5hcnlJbmRleEJ5ID0gcmVxdWlyZSgnLi9iaW5hcnlJbmRleEJ5JyksXG4gICAgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgSEFMRl9NQVhfQVJSQVlfTEVOR1RIID0gTUFYX0FSUkFZX0xFTkdUSCA+Pj4gMTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgYGFycmF5YCB0byBkZXRlcm1pbmUgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAqIHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvIGBhcnJheWAgaW4gb3JkZXIgdG8gbWFpbnRhaW4gaXRzIHNvcnQgb3JkZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSwgcmV0SGlnaGVzdCkge1xuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IGxvdztcblxuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID09PSB2YWx1ZSAmJiBoaWdoIDw9IEhBTEZfTUFYX0FSUkFZX0xFTkdUSCkge1xuICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxLFxuICAgICAgICAgIGNvbXB1dGVkID0gYXJyYXlbbWlkXTtcblxuICAgICAgaWYgKChyZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKSkgJiYgY29tcHV0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBoaWdoO1xuICB9XG4gIHJldHVybiBiaW5hcnlJbmRleEJ5KGFycmF5LCB2YWx1ZSwgaWRlbnRpdHksIHJldEhpZ2hlc3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4O1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVGbG9vciA9IE1hdGguZmxvb3IsXG4gICAgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgTUFYX0FSUkFZX0lOREVYID0gTUFYX0FSUkFZX0xFTkdUSCAtIDE7XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBiaW5hcnlJbmRleGAgZXhjZXB0IHRoYXQgaXQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvclxuICogYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpciBzb3J0IHJhbmtpbmcuIFRoZVxuICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSwgcmV0SGlnaGVzdCkge1xuICB2YWx1ZSA9IGl0ZXJhdGVlKHZhbHVlKTtcblxuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDAsXG4gICAgICB2YWxJc05hTiA9IHZhbHVlICE9PSB2YWx1ZSxcbiAgICAgIHZhbElzTnVsbCA9IHZhbHVlID09PSBudWxsLFxuICAgICAgdmFsSXNVbmRlZiA9IHZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICB2YXIgbWlkID0gbmF0aXZlRmxvb3IoKGxvdyArIGhpZ2gpIC8gMiksXG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUoYXJyYXlbbWlkXSksXG4gICAgICAgIGlzRGVmID0gY29tcHV0ZWQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgaXNSZWZsZXhpdmUgPSBjb21wdXRlZCA9PT0gY29tcHV0ZWQ7XG5cbiAgICBpZiAodmFsSXNOYU4pIHtcbiAgICAgIHZhciBzZXRMb3cgPSBpc1JlZmxleGl2ZSB8fCByZXRIaWdoZXN0O1xuICAgIH0gZWxzZSBpZiAodmFsSXNOdWxsKSB7XG4gICAgICBzZXRMb3cgPSBpc1JlZmxleGl2ZSAmJiBpc0RlZiAmJiAocmV0SGlnaGVzdCB8fCBjb21wdXRlZCAhPSBudWxsKTtcbiAgICB9IGVsc2UgaWYgKHZhbElzVW5kZWYpIHtcbiAgICAgIHNldExvdyA9IGlzUmVmbGV4aXZlICYmIChyZXRIaWdoZXN0IHx8IGlzRGVmKTtcbiAgICB9IGVsc2UgaWYgKGNvbXB1dGVkID09IG51bGwpIHtcbiAgICAgIHNldExvdyA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRMb3cgPSByZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHNldExvdykge1xuICAgICAgbG93ID0gbWlkICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlnaCA9IG1pZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5hdGl2ZU1pbihoaWdoLCBNQVhfQVJSQVlfSU5ERVgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4Qnk7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlQ2FsbGJhY2tgIHdoaWNoIG9ubHkgc3VwcG9ydHMgYHRoaXNgIGJpbmRpbmdcbiAqIGFuZCBzcGVjaWZ5aW5nIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyZ0NvdW50XSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gKi9cbmZ1bmN0aW9uIGJpbmRDYWxsYmFjayhmdW5jLCB0aGlzQXJnLCBhcmdDb3VudCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBpZGVudGl0eTtcbiAgfVxuICBpZiAodGhpc0FyZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZ1bmM7XG4gIH1cbiAgc3dpdGNoIChhcmdDb3VudCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH07XG4gICAgY2FzZSA0OiByZXR1cm4gZnVuY3Rpb24oYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgb3RoZXIsIGtleSwgb2JqZWN0LCBzb3VyY2UpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZENhbGxiYWNrO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBBcnJheUJ1ZmZlciA9IGdsb2JhbC5BcnJheUJ1ZmZlcixcbiAgICBVaW50OEFycmF5ID0gZ2xvYmFsLlVpbnQ4QXJyYXk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBnaXZlbiBhcnJheSBidWZmZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGJ1ZmZlciBUaGUgYXJyYXkgYnVmZmVyIHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5QnVmZmVyfSBSZXR1cm5zIHRoZSBjbG9uZWQgYXJyYXkgYnVmZmVyLlxuICovXG5mdW5jdGlvbiBidWZmZXJDbG9uZShidWZmZXIpIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheUJ1ZmZlcihidWZmZXIuYnl0ZUxlbmd0aCksXG4gICAgICB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkocmVzdWx0KTtcblxuICB2aWV3LnNldChuZXcgVWludDhBcnJheShidWZmZXIpKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBidWZmZXJDbG9uZTtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMkoxWm1abGNrTnNiMjVsTG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEVpTENKbWFXeGxJam9pWjJWdVpYSmhkR1ZrTG1weklpd2ljMjkxY21ObFVtOXZkQ0k2SWlJc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYklpOHFLaUJPWVhScGRtVWdiV1YwYUc5a0lISmxabVZ5Wlc1alpYTXVJQ292WEc1MllYSWdRWEp5WVhsQ2RXWm1aWElnUFNCbmJHOWlZV3d1UVhKeVlYbENkV1ptWlhJc1hHNGdJQ0FnVldsdWREaEJjbkpoZVNBOUlHZHNiMkpoYkM1VmFXNTBPRUZ5Y21GNU8xeHVYRzR2S2lwY2JpQXFJRU55WldGMFpYTWdZU0JqYkc5dVpTQnZaaUIwYUdVZ1oybDJaVzRnWVhKeVlYa2dZblZtWm1WeUxseHVJQ3BjYmlBcUlFQndjbWwyWVhSbFhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNVFuVm1abVZ5ZlNCaWRXWm1aWElnVkdobElHRnljbUY1SUdKMVptWmxjaUIwYnlCamJHOXVaUzVjYmlBcUlFQnlaWFIxY201eklIdEJjbkpoZVVKMVptWmxjbjBnVW1WMGRYSnVjeUIwYUdVZ1kyeHZibVZrSUdGeWNtRjVJR0oxWm1abGNpNWNiaUFxTDF4dVpuVnVZM1JwYjI0Z1luVm1abVZ5UTJ4dmJtVW9ZblZtWm1WeUtTQjdYRzRnSUhaaGNpQnlaWE4xYkhRZ1BTQnVaWGNnUVhKeVlYbENkV1ptWlhJb1luVm1abVZ5TG1KNWRHVk1aVzVuZEdncExGeHVJQ0FnSUNBZ2RtbGxkeUE5SUc1bGR5QlZhVzUwT0VGeWNtRjVLSEpsYzNWc2RDazdYRzVjYmlBZ2RtbGxkeTV6WlhRb2JtVjNJRlZwYm5RNFFYSnlZWGtvWW5WbVptVnlLU2s3WEc0Z0lISmxkSFZ5YmlCeVpYTjFiSFE3WEc1OVhHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdZblZtWm1WeVEyeHZibVU3WEc0aVhYMD0iLCIvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgdGhhdCBpcyB0aGUgY29tcG9zaXRpb24gb2YgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLFxuICogcGxhY2Vob2xkZXJzLCBhbmQgcHJvdmlkZWQgYXJndW1lbnRzIGludG8gYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycykge1xuICB2YXIgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgYXJnc0luZGV4ID0gLTEsXG4gICAgICBhcmdzTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKythcmdzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W2hvbGRlcnNbYXJnc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleF07XG4gIH1cbiAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXgrK10gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzO1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gKiBpcyB0YWlsb3JlZCBmb3IgYF8ucGFydGlhbFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnRpYWxzIFRoZSBhcmd1bWVudHMgdG8gYXBwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKSB7XG4gIHZhciBob2xkZXJzSW5kZXggPSAtMSxcbiAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgYXJnc0xlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgcmlnaHRJbmRleCA9IC0xLFxuICAgICAgcmlnaHRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShhcmdzTGVuZ3RoICsgcmlnaHRMZW5ndGgpO1xuXG4gIHdoaWxlICgrK2FyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICByZXN1bHRbYXJnc0luZGV4XSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgfVxuICB2YXIgb2Zmc2V0ID0gYXJnc0luZGV4O1xuICB3aGlsZSAoKytyaWdodEluZGV4IDwgcmlnaHRMZW5ndGgpIHtcbiAgICByZXN1bHRbb2Zmc2V0ICsgcmlnaHRJbmRleF0gPSBwYXJ0aWFsc1tyaWdodEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKytob2xkZXJzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W29mZnNldCArIGhvbGRlcnNbaG9sZGVyc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzUmlnaHQ7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYGJhc2VFYWNoYCBvciBgYmFzZUVhY2hSaWdodGAgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uID8gZ2V0TGVuZ3RoKGNvbGxlY3Rpb24pIDogMDtcbiAgICBpZiAoIWlzTGVuZ3RoKGxlbmd0aCkpIHtcbiAgICAgIHJldHVybiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG4gICAgfVxuICAgIHZhciBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xLFxuICAgICAgICBpdGVyYWJsZSA9IHRvT2JqZWN0KGNvbGxlY3Rpb24pO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCYXNlRWFjaDtcbiIsInZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgYF8uZm9ySW5gIG9yIGBfLmZvckluUmlnaHRgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzRnVuYykge1xuICAgIHZhciBpdGVyYWJsZSA9IHRvT2JqZWN0KG9iamVjdCksXG4gICAgICAgIHByb3BzID0ga2V5c0Z1bmMob2JqZWN0KSxcbiAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJhc2VGb3I7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmRXcmFwcGVyKGZ1bmMsIHRoaXNBcmcpIHtcbiAgdmFyIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kV3JhcHBlcjtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMk55WldGMFpVSnBibVJYY21Gd2NHVnlMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZM0psWVhSbFEzUnZjbGR5WVhCd1pYSWdQU0J5WlhGMWFYSmxLQ2N1TDJOeVpXRjBaVU4wYjNKWGNtRndjR1Z5SnlrN1hHNWNiaThxS2x4dUlDb2dRM0psWVhSbGN5QmhJR1oxYm1OMGFXOXVJSFJvWVhRZ2QzSmhjSE1nWUdaMWJtTmdJR0Z1WkNCcGJuWnZhMlZ6SUdsMElIZHBkR2dnZEdobElHQjBhR2x6WUZ4dUlDb2dZbWx1WkdsdVp5QnZaaUJnZEdocGMwRnlaMkF1WEc0Z0tseHVJQ29nUUhCeWFYWmhkR1ZjYmlBcUlFQndZWEpoYlNCN1JuVnVZM1JwYjI1OUlHWjFibU1nVkdobElHWjFibU4wYVc5dUlIUnZJR0pwYm1RdVhHNGdLaUJBY0dGeVlXMGdleXA5SUZ0MGFHbHpRWEpuWFNCVWFHVWdZSFJvYVhOZ0lHSnBibVJwYm1jZ2IyWWdZR1oxYm1OZ0xseHVJQ29nUUhKbGRIVnlibk1nZTBaMWJtTjBhVzl1ZlNCU1pYUjFjbTV6SUhSb1pTQnVaWGNnWW05MWJtUWdablZ1WTNScGIyNHVYRzRnS2k5Y2JtWjFibU4wYVc5dUlHTnlaV0YwWlVKcGJtUlhjbUZ3Y0dWeUtHWjFibU1zSUhSb2FYTkJjbWNwSUh0Y2JpQWdkbUZ5SUVOMGIzSWdQU0JqY21WaGRHVkRkRzl5VjNKaGNIQmxjaWhtZFc1aktUdGNibHh1SUNCbWRXNWpkR2x2YmlCM2NtRndjR1Z5S0NrZ2UxeHVJQ0FnSUhaaGNpQm1iaUE5SUNoMGFHbHpJQ1ltSUhSb2FYTWdJVDA5SUdkc2IySmhiQ0FtSmlCMGFHbHpJR2x1YzNSaGJtTmxiMllnZDNKaGNIQmxjaWtnUHlCRGRHOXlJRG9nWm5WdVl6dGNiaUFnSUNCeVpYUjFjbTRnWm00dVlYQndiSGtvZEdocGMwRnlaeXdnWVhKbmRXMWxiblJ6S1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnZDNKaGNIQmxjanRjYm4xY2JseHViVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQmpjbVZoZEdWQ2FXNWtWM0poY0hCbGNqdGNiaUpkZlE9PSIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9iYXNlQ3JlYXRlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDdG9yV3JhcHBlcihDdG9yKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAvLyBVc2UgYSBgc3dpdGNoYCBzdGF0ZW1lbnQgdG8gd29yayB3aXRoIGNsYXNzIGNvbnN0cnVjdG9ycy5cbiAgICAvLyBTZWUgaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZWNtYXNjcmlwdC1mdW5jdGlvbi1vYmplY3RzLWNhbGwtdGhpc2FyZ3VtZW50LWFyZ3VtZW50c2xpc3RcbiAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBDdG9yO1xuICAgICAgY2FzZSAxOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSk7XG4gICAgICBjYXNlIDI6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgIGNhc2UgMzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgY2FzZSA0OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gICAgICBjYXNlIDU6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdKTtcbiAgICAgIGNhc2UgNjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0pO1xuICAgICAgY2FzZSA3OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSwgYXJnc1s2XSk7XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGJhc2VDcmVhdGUoQ3Rvci5wcm90b3R5cGUpLFxuICAgICAgICByZXN1bHQgPSBDdG9yLmFwcGx5KHRoaXNCaW5kaW5nLCBhcmdzKTtcblxuICAgIC8vIE1pbWljIHRoZSBjb25zdHJ1Y3RvcidzIGByZXR1cm5gIGJlaGF2aW9yLlxuICAgIC8vIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxMy4yLjIgZm9yIG1vcmUgZGV0YWlscy5cbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IHRoaXNCaW5kaW5nO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUN0b3JXcmFwcGVyO1xuIiwidmFyIGJhc2VDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmFzZUNhbGxiYWNrJyksXG4gICAgYmFzZUZpbmQgPSByZXF1aXJlKCcuL2Jhc2VGaW5kJyksXG4gICAgYmFzZUZpbmRJbmRleCA9IHJlcXVpcmUoJy4vYmFzZUZpbmRJbmRleCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYF8uZmluZGAgb3IgYF8uZmluZExhc3RgIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRmluZChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICBwcmVkaWNhdGUgPSBiYXNlQ2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKTtcbiAgICBpZiAoaXNBcnJheShjb2xsZWN0aW9uKSkge1xuICAgICAgdmFyIGluZGV4ID0gYmFzZUZpbmRJbmRleChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21SaWdodCk7XG4gICAgICByZXR1cm4gaW5kZXggPiAtMSA/IGNvbGxlY3Rpb25baW5kZXhdIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZUZpbmQoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBlYWNoRnVuYyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlRmluZDtcbiIsInZhciBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gZm9yIGBfLmZvckVhY2hgIG9yIGBfLmZvckVhY2hSaWdodGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFycmF5RnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGFuIGFycmF5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBlYWNoIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVGb3JFYWNoKGFycmF5RnVuYywgZWFjaEZ1bmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJyAmJiB0aGlzQXJnID09PSB1bmRlZmluZWQgJiYgaXNBcnJheShjb2xsZWN0aW9uKSlcbiAgICAgID8gYXJyYXlGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKVxuICAgICAgOiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBiaW5kQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVGb3JFYWNoO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xudmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIGNyZWF0ZUN0b3JXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVDdG9yV3JhcHBlcicpLFxuICAgIGlzTGF6aWFibGUgPSByZXF1aXJlKCcuL2lzTGF6aWFibGUnKSxcbiAgICByZW9yZGVyID0gcmVxdWlyZSgnLi9yZW9yZGVyJyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL3JlcGxhY2VIb2xkZXJzJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vc2V0RGF0YScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQklORF9LRVlfRkxBRyA9IDIsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQ1VSUllfUklHSFRfRkxBRyA9IDE2LFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0LFxuICAgIEFSWV9GTEFHID0gMTI4O1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIG9wdGlvbmFsIGB0aGlzYFxuICogYmluZGluZyBvZiwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7QXJyYXl9IFtob2xkZXJzUmlnaHRdIFRoZSBgcGFydGlhbHNSaWdodGAgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVIeWJyaWRXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eSkge1xuICB2YXIgaXNBcnkgPSBiaXRtYXNrICYgQVJZX0ZMQUcsXG4gICAgICBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgaXNCaW5kS2V5ID0gYml0bWFzayAmIEJJTkRfS0VZX0ZMQUcsXG4gICAgICBpc0N1cnJ5ID0gYml0bWFzayAmIENVUlJZX0ZMQUcsXG4gICAgICBpc0N1cnJ5Qm91bmQgPSBiaXRtYXNrICYgQ1VSUllfQk9VTkRfRkxBRyxcbiAgICAgIGlzQ3VycnlSaWdodCA9IGJpdG1hc2sgJiBDVVJSWV9SSUdIVF9GTEFHLFxuICAgICAgQ3RvciA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgLy8gQXZvaWQgYGFyZ3VtZW50c2Agb2JqZWN0IHVzZSBkaXNxdWFsaWZ5aW5nIG9wdGltaXphdGlvbnMgYnlcbiAgICAvLyBjb252ZXJ0aW5nIGl0IHRvIGFuIGFycmF5IGJlZm9yZSBwcm92aWRpbmcgaXQgdG8gb3RoZXIgZnVuY3Rpb25zLlxuICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgIH1cbiAgICBpZiAocGFydGlhbHMpIHtcbiAgICAgIGFyZ3MgPSBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfVxuICAgIGlmIChwYXJ0aWFsc1JpZ2h0KSB7XG4gICAgICBhcmdzID0gY29tcG9zZUFyZ3NSaWdodChhcmdzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQpO1xuICAgIH1cbiAgICBpZiAoaXNDdXJyeSB8fCBpc0N1cnJ5UmlnaHQpIHtcbiAgICAgIHZhciBwbGFjZWhvbGRlciA9IHdyYXBwZXIucGxhY2Vob2xkZXIsXG4gICAgICAgICAgYXJnc0hvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG5cbiAgICAgIGxlbmd0aCAtPSBhcmdzSG9sZGVycy5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgdmFyIG5ld0FyZ1BvcyA9IGFyZ1BvcyA/IGFycmF5Q29weShhcmdQb3MpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbmV3QXJpdHkgPSBuYXRpdmVNYXgoYXJpdHkgLSBsZW5ndGgsIDApLFxuICAgICAgICAgICAgbmV3c0hvbGRlcnMgPSBpc0N1cnJ5ID8gYXJnc0hvbGRlcnMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdIb2xkZXJzUmlnaHQgPSBpc0N1cnJ5ID8gdW5kZWZpbmVkIDogYXJnc0hvbGRlcnMsXG4gICAgICAgICAgICBuZXdQYXJ0aWFscyA9IGlzQ3VycnkgPyBhcmdzIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbmV3UGFydGlhbHNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBhcmdzO1xuXG4gICAgICAgIGJpdG1hc2sgfD0gKGlzQ3VycnkgPyBQQVJUSUFMX0ZMQUcgOiBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgICBiaXRtYXNrICY9IH4oaXNDdXJyeSA/IFBBUlRJQUxfUklHSFRfRkxBRyA6IFBBUlRJQUxfRkxBRyk7XG5cbiAgICAgICAgaWYgKCFpc0N1cnJ5Qm91bmQpIHtcbiAgICAgICAgICBiaXRtYXNrICY9IH4oQklORF9GTEFHIHwgQklORF9LRVlfRkxBRyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5ld0RhdGEgPSBbZnVuYywgYml0bWFzaywgdGhpc0FyZywgbmV3UGFydGlhbHMsIG5ld3NIb2xkZXJzLCBuZXdQYXJ0aWFsc1JpZ2h0LCBuZXdIb2xkZXJzUmlnaHQsIG5ld0FyZ1BvcywgYXJ5LCBuZXdBcml0eV0sXG4gICAgICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG5cbiAgICAgICAgaWYgKGlzTGF6aWFibGUoZnVuYykpIHtcbiAgICAgICAgICBzZXREYXRhKHJlc3VsdCwgbmV3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gcGxhY2Vob2xkZXI7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLFxuICAgICAgICBmbiA9IGlzQmluZEtleSA/IHRoaXNCaW5kaW5nW2Z1bmNdIDogZnVuYztcblxuICAgIGlmIChhcmdQb3MpIHtcbiAgICAgIGFyZ3MgPSByZW9yZGVyKGFyZ3MsIGFyZ1Bvcyk7XG4gICAgfVxuICAgIGlmIChpc0FyeSAmJiBhcnkgPCBhcmdzLmxlbmd0aCkge1xuICAgICAgYXJncy5sZW5ndGggPSBhcnk7XG4gICAgfVxuICAgIGlmICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgZm4gPSBDdG9yIHx8IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUh5YnJpZFdyYXBwZXI7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJOeVpXRjBaVWg1WW5KcFpGZHlZWEJ3WlhJdWFuTWlYU3dpYm1GdFpYTWlPbHRkTENKdFlYQndhVzVuY3lJNklqdEJRVUZCTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZWEp5WVhsRGIzQjVJRDBnY21WeGRXbHlaU2duTGk5aGNuSmhlVU52Y0hrbktTeGNiaUFnSUNCamIyMXdiM05sUVhKbmN5QTlJSEpsY1hWcGNtVW9KeTR2WTI5dGNHOXpaVUZ5WjNNbktTeGNiaUFnSUNCamIyMXdiM05sUVhKbmMxSnBaMmgwSUQwZ2NtVnhkV2x5WlNnbkxpOWpiMjF3YjNObFFYSm5jMUpwWjJoMEp5a3NYRzRnSUNBZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWtzWEc0Z0lDQWdhWE5NWVhwcFlXSnNaU0E5SUhKbGNYVnBjbVVvSnk0dmFYTk1ZWHBwWVdKc1pTY3BMRnh1SUNBZ0lISmxiM0prWlhJZ1BTQnlaWEYxYVhKbEtDY3VMM0psYjNKa1pYSW5LU3hjYmlBZ0lDQnlaWEJzWVdObFNHOXNaR1Z5Y3lBOUlISmxjWFZwY21Vb0p5NHZjbVZ3YkdGalpVaHZiR1JsY25NbktTeGNiaUFnSUNCelpYUkVZWFJoSUQwZ2NtVnhkV2x5WlNnbkxpOXpaWFJFWVhSaEp5azdYRzVjYmk4cUtpQlZjMlZrSUhSdklHTnZiWEJ2YzJVZ1ltbDBiV0Z6YTNNZ1ptOXlJSGR5WVhCd1pYSWdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdRa2xPUkY5R1RFRkhJRDBnTVN4Y2JpQWdJQ0JDU1U1RVgwdEZXVjlHVEVGSElEMGdNaXhjYmlBZ0lDQkRWVkpTV1Y5Q1QxVk9SRjlHVEVGSElEMGdOQ3hjYmlBZ0lDQkRWVkpTV1Y5R1RFRkhJRDBnT0N4Y2JpQWdJQ0JEVlZKU1dWOVNTVWRJVkY5R1RFRkhJRDBnTVRZc1hHNGdJQ0FnVUVGU1ZFbEJURjlHVEVGSElEMGdNeklzWEc0Z0lDQWdVRUZTVkVsQlRGOVNTVWRJVkY5R1RFRkhJRDBnTmpRc1hHNGdJQ0FnUVZKWlgwWk1RVWNnUFNBeE1qZzdYRzVjYmk4cUlFNWhkR2wyWlNCdFpYUm9iMlFnY21WbVpYSmxibU5sY3lCbWIzSWdkR2h2YzJVZ2QybDBhQ0IwYUdVZ2MyRnRaU0J1WVcxbElHRnpJRzkwYUdWeUlHQnNiMlJoYzJoZ0lHMWxkR2h2WkhNdUlDb3ZYRzUyWVhJZ2JtRjBhWFpsVFdGNElEMGdUV0YwYUM1dFlYZzdYRzVjYmk4cUtseHVJQ29nUTNKbFlYUmxjeUJoSUdaMWJtTjBhVzl1SUhSb1lYUWdkM0poY0hNZ1lHWjFibU5nSUdGdVpDQnBiblp2YTJWeklHbDBJSGRwZEdnZ2IzQjBhVzl1WVd3Z1lIUm9hWE5nWEc0Z0tpQmlhVzVrYVc1bklHOW1MQ0J3WVhKMGFXRnNJR0Z3Y0d4cFkyRjBhVzl1TENCaGJtUWdZM1Z5Y25scGJtY3VYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU4YzNSeWFXNW5mU0JtZFc1aklGUm9aU0JtZFc1amRHbHZiaUJ2Y2lCdFpYUm9iMlFnYm1GdFpTQjBieUJ5WldabGNtVnVZMlV1WEc0Z0tpQkFjR0Z5WVcwZ2UyNTFiV0psY24wZ1ltbDBiV0Z6YXlCVWFHVWdZbWwwYldGemF5QnZaaUJtYkdGbmN5NGdVMlZsSUdCamNtVmhkR1ZYY21Gd2NHVnlZQ0JtYjNJZ2JXOXlaU0JrWlhSaGFXeHpMbHh1SUNvZ1FIQmhjbUZ0SUhzcWZTQmJkR2hwYzBGeVoxMGdWR2hsSUdCMGFHbHpZQ0JpYVc1a2FXNW5JRzltSUdCbWRXNWpZQzVjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUZ0d1lYSjBhV0ZzYzEwZ1ZHaGxJR0Z5WjNWdFpXNTBjeUIwYnlCd2NtVndaVzVrSUhSdklIUm9iM05sSUhCeWIzWnBaR1ZrSUhSdklIUm9aU0J1WlhjZ1puVnVZM1JwYjI0dVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNWZTQmJhRzlzWkdWeWMxMGdWR2hsSUdCd1lYSjBhV0ZzYzJBZ2NHeGhZMlZvYjJ4a1pYSWdhVzVrWlhobGN5NWNiaUFxSUVCd1lYSmhiU0I3UVhKeVlYbDlJRnR3WVhKMGFXRnNjMUpwWjJoMFhTQlVhR1VnWVhKbmRXMWxiblJ6SUhSdklHRndjR1Z1WkNCMGJ5QjBhRzl6WlNCd2NtOTJhV1JsWkNCMGJ5QjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhCaGNtRnRJSHRCY25KaGVYMGdXMmh2YkdSbGNuTlNhV2RvZEYwZ1ZHaGxJR0J3WVhKMGFXRnNjMUpwWjJoMFlDQndiR0ZqWldodmJHUmxjaUJwYm1SbGVHVnpMbHh1SUNvZ1FIQmhjbUZ0SUh0QmNuSmhlWDBnVzJGeVoxQnZjMTBnVkdobElHRnlaM1Z0Wlc1MElIQnZjMmwwYVc5dWN5QnZaaUIwYUdVZ2JtVjNJR1oxYm1OMGFXOXVMbHh1SUNvZ1FIQmhjbUZ0SUh0dWRXMWlaWEo5SUZ0aGNubGRJRlJvWlNCaGNtbDBlU0JqWVhBZ2IyWWdZR1oxYm1OZ0xseHVJQ29nUUhCaGNtRnRJSHR1ZFcxaVpYSjlJRnRoY21sMGVWMGdWR2hsSUdGeWFYUjVJRzltSUdCbWRXNWpZQzVjYmlBcUlFQnlaWFIxY201eklIdEdkVzVqZEdsdmJuMGdVbVYwZFhKdWN5QjBhR1VnYm1WM0lIZHlZWEJ3WldRZ1puVnVZM1JwYjI0dVhHNGdLaTljYm1aMWJtTjBhVzl1SUdOeVpXRjBaVWg1WW5KcFpGZHlZWEJ3WlhJb1puVnVZeXdnWW1sMGJXRnpheXdnZEdocGMwRnlaeXdnY0dGeWRHbGhiSE1zSUdodmJHUmxjbk1zSUhCaGNuUnBZV3h6VW1sbmFIUXNJR2h2YkdSbGNuTlNhV2RvZEN3Z1lYSm5VRzl6TENCaGNua3NJR0Z5YVhSNUtTQjdYRzRnSUhaaGNpQnBjMEZ5ZVNBOUlHSnBkRzFoYzJzZ0ppQkJVbGxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRbWx1WkNBOUlHSnBkRzFoYzJzZ0ppQkNTVTVFWDBaTVFVY3NYRzRnSUNBZ0lDQnBjMEpwYm1STFpYa2dQU0JpYVhSdFlYTnJJQ1lnUWtsT1JGOUxSVmxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRM1Z5Y25rZ1BTQmlhWFJ0WVhOcklDWWdRMVZTVWxsZlJreEJSeXhjYmlBZ0lDQWdJR2x6UTNWeWNubENiM1Z1WkNBOUlHSnBkRzFoYzJzZ0ppQkRWVkpTV1Y5Q1QxVk9SRjlHVEVGSExGeHVJQ0FnSUNBZ2FYTkRkWEp5ZVZKcFoyaDBJRDBnWW1sMGJXRnpheUFtSUVOVlVsSlpYMUpKUjBoVVgwWk1RVWNzWEc0Z0lDQWdJQ0JEZEc5eUlEMGdhWE5DYVc1a1MyVjVJRDhnZFc1a1pXWnBibVZrSURvZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJb1puVnVZeWs3WEc1Y2JpQWdablZ1WTNScGIyNGdkM0poY0hCbGNpZ3BJSHRjYmlBZ0lDQXZMeUJCZG05cFpDQmdZWEpuZFcxbGJuUnpZQ0J2WW1wbFkzUWdkWE5sSUdScGMzRjFZV3hwWm5scGJtY2diM0IwYVcxcGVtRjBhVzl1Y3lCaWVWeHVJQ0FnSUM4dklHTnZiblpsY25ScGJtY2dhWFFnZEc4Z1lXNGdZWEp5WVhrZ1ltVm1iM0psSUhCeWIzWnBaR2x1WnlCcGRDQjBieUJ2ZEdobGNpQm1kVzVqZEdsdmJuTXVYRzRnSUNBZ2RtRnlJR3hsYm1kMGFDQTlJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ3NYRzRnSUNBZ0lDQWdJR2x1WkdWNElEMGdiR1Z1WjNSb0xGeHVJQ0FnSUNBZ0lDQmhjbWR6SUQwZ1FYSnlZWGtvYkdWdVozUm9LVHRjYmx4dUlDQWdJSGRvYVd4bElDaHBibVJsZUMwdEtTQjdYRzRnSUNBZ0lDQmhjbWR6VzJsdVpHVjRYU0E5SUdGeVozVnRaVzUwYzF0cGJtUmxlRjA3WEc0Z0lDQWdmVnh1SUNBZ0lHbG1JQ2h3WVhKMGFXRnNjeWtnZTF4dUlDQWdJQ0FnWVhKbmN5QTlJR052YlhCdmMyVkJjbWR6S0dGeVozTXNJSEJoY25ScFlXeHpMQ0JvYjJ4a1pYSnpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSEJoY25ScFlXeHpVbWxuYUhRcElIdGNiaUFnSUNBZ0lHRnlaM01nUFNCamIyMXdiM05sUVhKbmMxSnBaMmgwS0dGeVozTXNJSEJoY25ScFlXeHpVbWxuYUhRc0lHaHZiR1JsY25OU2FXZG9kQ2s3WEc0Z0lDQWdmVnh1SUNBZ0lHbG1JQ2hwYzBOMWNuSjVJSHg4SUdselEzVnljbmxTYVdkb2RDa2dlMXh1SUNBZ0lDQWdkbUZ5SUhCc1lXTmxhRzlzWkdWeUlEMGdkM0poY0hCbGNpNXdiR0ZqWldodmJHUmxjaXhjYmlBZ0lDQWdJQ0FnSUNCaGNtZHpTRzlzWkdWeWN5QTlJSEpsY0d4aFkyVkliMnhrWlhKektHRnlaM01zSUhCc1lXTmxhRzlzWkdWeUtUdGNibHh1SUNBZ0lDQWdiR1Z1WjNSb0lDMDlJR0Z5WjNOSWIyeGtaWEp6TG14bGJtZDBhRHRjYmlBZ0lDQWdJR2xtSUNoc1pXNW5kR2dnUENCaGNtbDBlU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdibVYzUVhKblVHOXpJRDBnWVhKblVHOXpJRDhnWVhKeVlYbERiM0I1S0dGeVoxQnZjeWtnT2lCMWJtUmxabWx1WldRc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkQmNtbDBlU0E5SUc1aGRHbDJaVTFoZUNoaGNtbDBlU0F0SUd4bGJtZDBhQ3dnTUNrc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkelNHOXNaR1Z5Y3lBOUlHbHpRM1Z5Y25rZ1B5QmhjbWR6U0c5c1pHVnljeUE2SUhWdVpHVm1hVzVsWkN4Y2JpQWdJQ0FnSUNBZ0lDQWdJRzVsZDBodmJHUmxjbk5TYVdkb2RDQTlJR2x6UTNWeWNua2dQeUIxYm1SbFptbHVaV1FnT2lCaGNtZHpTRzlzWkdWeWN5eGNiaUFnSUNBZ0lDQWdJQ0FnSUc1bGQxQmhjblJwWVd4eklEMGdhWE5EZFhKeWVTQS9JR0Z5WjNNZ09pQjFibVJsWm1sdVpXUXNYRzRnSUNBZ0lDQWdJQ0FnSUNCdVpYZFFZWEowYVdGc2MxSnBaMmgwSUQwZ2FYTkRkWEp5ZVNBL0lIVnVaR1ZtYVc1bFpDQTZJR0Z5WjNNN1hHNWNiaUFnSUNBZ0lDQWdZbWwwYldGemF5QjhQU0FvYVhORGRYSnllU0EvSUZCQlVsUkpRVXhmUmt4QlJ5QTZJRkJCVWxSSlFVeGZVa2xIU0ZSZlJreEJSeWs3WEc0Z0lDQWdJQ0FnSUdKcGRHMWhjMnNnSmowZ2ZpaHBjME4xY25KNUlEOGdVRUZTVkVsQlRGOVNTVWRJVkY5R1RFRkhJRG9nVUVGU1ZFbEJURjlHVEVGSEtUdGNibHh1SUNBZ0lDQWdJQ0JwWmlBb0lXbHpRM1Z5Y25sQ2IzVnVaQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lHSnBkRzFoYzJzZ0pqMGdmaWhDU1U1RVgwWk1RVWNnZkNCQ1NVNUVYMHRGV1Y5R1RFRkhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMllYSWdibVYzUkdGMFlTQTlJRnRtZFc1akxDQmlhWFJ0WVhOckxDQjBhR2x6UVhKbkxDQnVaWGRRWVhKMGFXRnNjeXdnYm1WM2MwaHZiR1JsY25Nc0lHNWxkMUJoY25ScFlXeHpVbWxuYUhRc0lHNWxkMGh2YkdSbGNuTlNhV2RvZEN3Z2JtVjNRWEpuVUc5ekxDQmhjbmtzSUc1bGQwRnlhWFI1WFN4Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzNWc2RDQTlJR055WldGMFpVaDVZbkpwWkZkeVlYQndaWEl1WVhCd2JIa29kVzVrWldacGJtVmtMQ0J1WlhkRVlYUmhLVHRjYmx4dUlDQWdJQ0FnSUNCcFppQW9hWE5NWVhwcFlXSnNaU2htZFc1aktTa2dlMXh1SUNBZ0lDQWdJQ0FnSUhObGRFUmhkR0VvY21WemRXeDBMQ0J1WlhkRVlYUmhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCeVpYTjFiSFF1Y0d4aFkyVm9iMnhrWlhJZ1BTQndiR0ZqWldodmJHUmxjanRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYzNWc2REdGNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnZG1GeUlIUm9hWE5DYVc1a2FXNW5JRDBnYVhOQ2FXNWtJRDhnZEdocGMwRnlaeUE2SUhSb2FYTXNYRzRnSUNBZ0lDQWdJR1p1SUQwZ2FYTkNhVzVrUzJWNUlEOGdkR2hwYzBKcGJtUnBibWRiWm5WdVkxMGdPaUJtZFc1ak8xeHVYRzRnSUNBZ2FXWWdLR0Z5WjFCdmN5a2dlMXh1SUNBZ0lDQWdZWEpuY3lBOUlISmxiM0prWlhJb1lYSm5jeXdnWVhKblVHOXpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLR2x6UVhKNUlDWW1JR0Z5ZVNBOElHRnlaM011YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0JoY21kekxteGxibWQwYUNBOUlHRnllVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFJvYVhNZ0ppWWdkR2hwY3lBaFBUMGdaMnh2WW1Gc0lDWW1JSFJvYVhNZ2FXNXpkR0Z1WTJWdlppQjNjbUZ3Y0dWeUtTQjdYRzRnSUNBZ0lDQm1iaUE5SUVOMGIzSWdmSHdnWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElvWm5WdVl5azdYRzRnSUNBZ2ZWeHVJQ0FnSUhKbGRIVnliaUJtYmk1aGNIQnNlU2gwYUdselFtbHVaR2x1Wnl3Z1lYSm5jeWs3WEc0Z0lIMWNiaUFnY21WMGRYSnVJSGR5WVhCd1pYSTdYRzU5WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ1kzSmxZWFJsU0hsaWNtbGtWM0poY0hCbGNqdGNiaUpkZlE9PSIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBjcmVhdGVDdG9yV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlQ3RvcldyYXBwZXInKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3Igd3JhcHBlciBtZXRhZGF0YS4gKi9cbnZhciBCSU5EX0ZMQUcgPSAxO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIHRoZSBvcHRpb25hbCBgdGhpc2BcbiAqIGJpbmRpbmcgb2YgYHRoaXNBcmdgIGFuZCB0aGUgYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAqIHRoZSB3cmFwcGVyLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUGFydGlhbFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGlzQmluZCA9IGJpdG1hc2sgJiBCSU5EX0ZMQUcsXG4gICAgICBDdG9yID0gY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgIC8vIGNvbnZlcnRpbmcgaXQgdG8gYW4gYXJyYXkgYmVmb3JlIHByb3ZpZGluZyBpdCBgZnVuY2AuXG4gICAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgIGFyZ3MgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICBhcmdzW2xlZnRJbmRleF0gPSBwYXJ0aWFsc1tsZWZ0SW5kZXhdO1xuICAgIH1cbiAgICB3aGlsZSAoYXJnc0xlbmd0aC0tKSB7XG4gICAgICBhcmdzW2xlZnRJbmRleCsrXSA9IGFyZ3VtZW50c1srK2FyZ3NJbmRleF07XG4gICAgfVxuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkoaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVBhcnRpYWxXcmFwcGVyO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wyTnlaV0YwWlZCaGNuUnBZV3hYY21Gd2NHVnlMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWs3WEc1Y2JpOHFLaUJWYzJWa0lIUnZJR052YlhCdmMyVWdZbWwwYldGemEzTWdabTl5SUhkeVlYQndaWElnYldWMFlXUmhkR0V1SUNvdlhHNTJZWElnUWtsT1JGOUdURUZISUQwZ01UdGNibHh1THlvcVhHNGdLaUJEY21WaGRHVnpJR0VnWm5WdVkzUnBiMjRnZEdoaGRDQjNjbUZ3Y3lCZ1puVnVZMkFnWVc1a0lHbHVkbTlyWlhNZ2FYUWdkMmwwYUNCMGFHVWdiM0IwYVc5dVlXd2dZSFJvYVhOZ1hHNGdLaUJpYVc1a2FXNW5JRzltSUdCMGFHbHpRWEpuWUNCaGJtUWdkR2hsSUdCd1lYSjBhV0ZzYzJBZ2NISmxjR1Z1WkdWa0lIUnZJSFJvYjNObElIQnliM1pwWkdWa0lIUnZYRzRnS2lCMGFHVWdkM0poY0hCbGNpNWNiaUFxWEc0Z0tpQkFjSEpwZG1GMFpWeHVJQ29nUUhCaGNtRnRJSHRHZFc1amRHbHZibjBnWm5WdVl5QlVhR1VnWm5WdVkzUnBiMjRnZEc4Z2NHRnlkR2xoYkd4NUlHRndjR3g1SUdGeVozVnRaVzUwY3lCMGJ5NWNiaUFxSUVCd1lYSmhiU0I3Ym5WdFltVnlmU0JpYVhSdFlYTnJJRlJvWlNCaWFYUnRZWE5ySUc5bUlHWnNZV2R6TGlCVFpXVWdZR055WldGMFpWZHlZWEJ3WlhKZ0lHWnZjaUJ0YjNKbElHUmxkR0ZwYkhNdVhHNGdLaUJBY0dGeVlXMGdleXA5SUhSb2FYTkJjbWNnVkdobElHQjBhR2x6WUNCaWFXNWthVzVuSUc5bUlHQm1kVzVqWUM1Y2JpQXFJRUJ3WVhKaGJTQjdRWEp5WVhsOUlIQmhjblJwWVd4eklGUm9aU0JoY21kMWJXVnVkSE1nZEc4Z2NISmxjR1Z1WkNCMGJ5QjBhRzl6WlNCd2NtOTJhV1JsWkNCMGJ5QjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhKbGRIVnlibk1nZTBaMWJtTjBhVzl1ZlNCU1pYUjFjbTV6SUhSb1pTQnVaWGNnWW05MWJtUWdablZ1WTNScGIyNHVYRzRnS2k5Y2JtWjFibU4wYVc5dUlHTnlaV0YwWlZCaGNuUnBZV3hYY21Gd2NHVnlLR1oxYm1Nc0lHSnBkRzFoYzJzc0lIUm9hWE5CY21jc0lIQmhjblJwWVd4ektTQjdYRzRnSUhaaGNpQnBjMEpwYm1RZ1BTQmlhWFJ0WVhOcklDWWdRa2xPUkY5R1RFRkhMRnh1SUNBZ0lDQWdRM1J2Y2lBOUlHTnlaV0YwWlVOMGIzSlhjbUZ3Y0dWeUtHWjFibU1wTzF4dVhHNGdJR1oxYm1OMGFXOXVJSGR5WVhCd1pYSW9LU0I3WEc0Z0lDQWdMeThnUVhadmFXUWdZR0Z5WjNWdFpXNTBjMkFnYjJKcVpXTjBJSFZ6WlNCa2FYTnhkV0ZzYVdaNWFXNW5JRzl3ZEdsdGFYcGhkR2x2Ym5NZ1lubGNiaUFnSUNBdkx5QmpiMjUyWlhKMGFXNW5JR2wwSUhSdklHRnVJR0Z5Y21GNUlHSmxabTl5WlNCd2NtOTJhV1JwYm1jZ2FYUWdZR1oxYm1OZ0xseHVJQ0FnSUhaaGNpQmhjbWR6U1c1a1pYZ2dQU0F0TVN4Y2JpQWdJQ0FnSUNBZ1lYSm5jMHhsYm1kMGFDQTlJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ3NYRzRnSUNBZ0lDQWdJR3hsWm5SSmJtUmxlQ0E5SUMweExGeHVJQ0FnSUNBZ0lDQnNaV1owVEdWdVozUm9JRDBnY0dGeWRHbGhiSE11YkdWdVozUm9MRnh1SUNBZ0lDQWdJQ0JoY21keklEMGdRWEp5WVhrb2JHVm1kRXhsYm1kMGFDQXJJR0Z5WjNOTVpXNW5kR2dwTzF4dVhHNGdJQ0FnZDJocGJHVWdLQ3NyYkdWbWRFbHVaR1Y0SUR3Z2JHVm1kRXhsYm1kMGFDa2dlMXh1SUNBZ0lDQWdZWEpuYzF0c1pXWjBTVzVrWlhoZElEMGdjR0Z5ZEdsaGJITmJiR1ZtZEVsdVpHVjRYVHRjYmlBZ0lDQjlYRzRnSUNBZ2QyaHBiR1VnS0dGeVozTk1aVzVuZEdndExTa2dlMXh1SUNBZ0lDQWdZWEpuYzF0c1pXWjBTVzVrWlhncksxMGdQU0JoY21kMWJXVnVkSE5iS3l0aGNtZHpTVzVrWlhoZE8xeHVJQ0FnSUgxY2JpQWdJQ0IyWVhJZ1ptNGdQU0FvZEdocGN5QW1KaUIwYUdseklDRTlQU0JuYkc5aVlXd2dKaVlnZEdocGN5QnBibk4wWVc1alpXOW1JSGR5WVhCd1pYSXBJRDhnUTNSdmNpQTZJR1oxYm1NN1hHNGdJQ0FnY21WMGRYSnVJR1p1TG1Gd2NHeDVLR2x6UW1sdVpDQS9JSFJvYVhOQmNtY2dPaUIwYUdsekxDQmhjbWR6S1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnZDNKaGNIQmxjanRjYm4xY2JseHViVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQmpjbVZoZEdWUVlYSjBhV0ZzVjNKaGNIQmxjanRjYmlKZGZRPT0iLCJ2YXIgYmFzZVNldERhdGEgPSByZXF1aXJlKCcuL2Jhc2VTZXREYXRhJyksXG4gICAgY3JlYXRlQmluZFdyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUJpbmRXcmFwcGVyJyksXG4gICAgY3JlYXRlSHlicmlkV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlSHlicmlkV3JhcHBlcicpLFxuICAgIGNyZWF0ZVBhcnRpYWxXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVQYXJ0aWFsV3JhcHBlcicpLFxuICAgIGdldERhdGEgPSByZXF1aXJlKCcuL2dldERhdGEnKSxcbiAgICBtZXJnZURhdGEgPSByZXF1aXJlKCcuL21lcmdlRGF0YScpLFxuICAgIHNldERhdGEgPSByZXF1aXJlKCcuL3NldERhdGEnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3Igd3JhcHBlciBtZXRhZGF0YS4gKi9cbnZhciBCSU5EX0ZMQUcgPSAxLFxuICAgIEJJTkRfS0VZX0ZMQUcgPSAyLFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0O1xuXG4vKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBlaXRoZXIgY3VycmllcyBvciBpbnZva2VzIGBmdW5jYCB3aXRoIG9wdGlvbmFsXG4gKiBgdGhpc2AgYmluZGluZyBhbmQgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuXG4gKiAgVGhlIGJpdG1hc2sgbWF5IGJlIGNvbXBvc2VkIG9mIHRoZSBmb2xsb3dpbmcgZmxhZ3M6XG4gKiAgICAgMSAtIGBfLmJpbmRgXG4gKiAgICAgMiAtIGBfLmJpbmRLZXlgXG4gKiAgICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gKiAgICAgOCAtIGBfLmN1cnJ5YFxuICogICAgMTYgLSBgXy5jdXJyeVJpZ2h0YFxuICogICAgMzIgLSBgXy5wYXJ0aWFsYFxuICogICAgNjQgLSBgXy5wYXJ0aWFsUmlnaHRgXG4gKiAgIDEyOCAtIGBfLnJlYXJnYFxuICogICAyNTYgLSBgXy5hcnlgXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJnUG9zXSBUaGUgYXJndW1lbnQgcG9zaXRpb25zIG9mIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gIHZhciBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRztcbiAgaWYgKCFpc0JpbmRLZXkgJiYgdHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB2YXIgbGVuZ3RoID0gcGFydGlhbHMgPyBwYXJ0aWFscy5sZW5ndGggOiAwO1xuICBpZiAoIWxlbmd0aCkge1xuICAgIGJpdG1hc2sgJj0gfihQQVJUSUFMX0ZMQUcgfCBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgIHBhcnRpYWxzID0gaG9sZGVycyA9IHVuZGVmaW5lZDtcbiAgfVxuICBsZW5ndGggLT0gKGhvbGRlcnMgPyBob2xkZXJzLmxlbmd0aCA6IDApO1xuICBpZiAoYml0bWFzayAmIFBBUlRJQUxfUklHSFRfRkxBRykge1xuICAgIHZhciBwYXJ0aWFsc1JpZ2h0ID0gcGFydGlhbHMsXG4gICAgICAgIGhvbGRlcnNSaWdodCA9IGhvbGRlcnM7XG5cbiAgICBwYXJ0aWFscyA9IGhvbGRlcnMgPSB1bmRlZmluZWQ7XG4gIH1cbiAgdmFyIGRhdGEgPSBpc0JpbmRLZXkgPyB1bmRlZmluZWQgOiBnZXREYXRhKGZ1bmMpLFxuICAgICAgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHldO1xuXG4gIGlmIChkYXRhKSB7XG4gICAgbWVyZ2VEYXRhKG5ld0RhdGEsIGRhdGEpO1xuICAgIGJpdG1hc2sgPSBuZXdEYXRhWzFdO1xuICAgIGFyaXR5ID0gbmV3RGF0YVs5XTtcbiAgfVxuICBuZXdEYXRhWzldID0gYXJpdHkgPT0gbnVsbFxuICAgID8gKGlzQmluZEtleSA/IDAgOiBmdW5jLmxlbmd0aClcbiAgICA6IChuYXRpdmVNYXgoYXJpdHkgLSBsZW5ndGgsIDApIHx8IDApO1xuXG4gIGlmIChiaXRtYXNrID09IEJJTkRfRkxBRykge1xuICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kV3JhcHBlcihuZXdEYXRhWzBdLCBuZXdEYXRhWzJdKTtcbiAgfSBlbHNlIGlmICgoYml0bWFzayA9PSBQQVJUSUFMX0ZMQUcgfHwgYml0bWFzayA9PSAoQklORF9GTEFHIHwgUEFSVElBTF9GTEFHKSkgJiYgIW5ld0RhdGFbNF0ubGVuZ3RoKSB7XG4gICAgcmVzdWx0ID0gY3JlYXRlUGFydGlhbFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG4gIH1cbiAgdmFyIHNldHRlciA9IGRhdGEgPyBiYXNlU2V0RGF0YSA6IHNldERhdGE7XG4gIHJldHVybiBzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVXcmFwcGVyO1xuIiwidmFyIGFycmF5U29tZSA9IHJlcXVpcmUoJy4vYXJyYXlTb21lJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBhcnJheXMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7QXJyYXl9IG90aGVyIFRoZSBvdGhlciBhcnJheSB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIGFycmF5cy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJyYXlzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIG90aExlbmd0aCA9IG90aGVyLmxlbmd0aDtcblxuICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzTG9vc2UgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuXG4gIHdoaWxlICgrK2luZGV4IDwgYXJyTGVuZ3RoKSB7XG4gICAgdmFyIGFyclZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2luZGV4XSxcbiAgICAgICAgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIoaXNMb29zZSA/IG90aFZhbHVlIDogYXJyVmFsdWUsIGlzTG9vc2UgPyBhcnJWYWx1ZSA6IG90aFZhbHVlLCBpbmRleCkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgaWYgKGlzTG9vc2UpIHtcbiAgICAgIGlmICghYXJyYXlTb21lKG90aGVyLCBmdW5jdGlvbihvdGhWYWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fCBlcXVhbEZ1bmMoYXJyVmFsdWUsIG90aFZhbHVlLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIShhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEFycmF5cztcbiIsIi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2ZcbiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgYm9vbFRhZzpcbiAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWJlcnMsIGRhdGVzIHRvIG1pbGxpc2Vjb25kcyBhbmQgYm9vbGVhbnNcbiAgICAgIC8vIHRvIGAxYCBvciBgMGAgdHJlYXRpbmcgaW52YWxpZCBkYXRlcyBjb2VyY2VkIHRvIGBOYU5gIGFzIG5vdCBlcXVhbC5cbiAgICAgIHJldHVybiArb2JqZWN0ID09ICtvdGhlcjtcblxuICAgIGNhc2UgZXJyb3JUYWc6XG4gICAgICByZXR1cm4gb2JqZWN0Lm5hbWUgPT0gb3RoZXIubmFtZSAmJiBvYmplY3QubWVzc2FnZSA9PSBvdGhlci5tZXNzYWdlO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgICAvLyBUcmVhdCBgTmFOYCB2cy4gYE5hTmAgYXMgZXF1YWwuXG4gICAgICByZXR1cm4gKG9iamVjdCAhPSArb2JqZWN0KVxuICAgICAgICA/IG90aGVyICE9ICtvdGhlclxuICAgICAgICA6IG9iamVjdCA9PSArb3RoZXI7XG5cbiAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICBjYXNlIHN0cmluZ1RhZzpcbiAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MgcHJpbWl0aXZlcyBhbmQgc3RyaW5nXG4gICAgICAvLyBvYmplY3RzIGFzIGVxdWFsLiBTZWUgaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4MTUuMTAuNi40IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxCeVRhZztcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBvYmplY3RzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIHZhbHVlcy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgb2JqUHJvcHMgPSBrZXlzKG9iamVjdCksXG4gICAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsXG4gICAgICBvdGhQcm9wcyA9IGtleXMob3RoZXIpLFxuICAgICAgb3RoTGVuZ3RoID0gb3RoUHJvcHMubGVuZ3RoO1xuXG4gIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc0xvb3NlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBpbmRleCA9IG9iakxlbmd0aDtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIGlmICghKGlzTG9vc2UgPyBrZXkgaW4gb3RoZXIgOiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCBrZXkpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICB2YXIgc2tpcEN0b3IgPSBpc0xvb3NlO1xuICB3aGlsZSAoKytpbmRleCA8IG9iakxlbmd0aCkge1xuICAgIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICB2YXIgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgb3RoVmFsdWUgPSBvdGhlcltrZXldLFxuICAgICAgICByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcihpc0xvb3NlID8gb3RoVmFsdWUgOiBvYmpWYWx1ZSwgaXNMb29zZT8gb2JqVmFsdWUgOiBvdGhWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcblxuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIDogcmVzdWx0KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBza2lwQ3RvciB8fCAoc2tpcEN0b3IgPSBrZXkgPT0gJ2NvbnN0cnVjdG9yJyk7XG4gIH1cbiAgaWYgKCFza2lwQ3Rvcikge1xuICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAvLyBOb24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbC5cbiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAhKHR5cGVvZiBvYmpDdG9yID09ICdmdW5jdGlvbicgJiYgb2JqQ3RvciBpbnN0YW5jZW9mIG9iakN0b3IgJiZcbiAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbE9iamVjdHM7XG4iLCJ2YXIgbWV0YU1hcCA9IHJlcXVpcmUoJy4vbWV0YU1hcCcpLFxuICAgIG5vb3AgPSByZXF1aXJlKCcuLi91dGlsaXR5L25vb3AnKTtcblxuLyoqXG4gKiBHZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKi9cbnZhciBnZXREYXRhID0gIW1ldGFNYXAgPyBub29wIDogZnVuY3Rpb24oZnVuYykge1xuICByZXR1cm4gbWV0YU1hcC5nZXQoZnVuYyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGdldERhdGE7XG4iLCJ2YXIgcmVhbE5hbWVzID0gcmVxdWlyZSgnLi9yZWFsTmFtZXMnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYW1lIG9mIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lLlxuICovXG5mdW5jdGlvbiBnZXRGdW5jTmFtZShmdW5jKSB7XG4gIHZhciByZXN1bHQgPSAoZnVuYy5uYW1lICsgJycpLFxuICAgICAgYXJyYXkgPSByZWFsTmFtZXNbcmVzdWx0XSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgZGF0YSA9IGFycmF5W2xlbmd0aF0sXG4gICAgICAgIG90aGVyRnVuYyA9IGRhdGEuZnVuYztcbiAgICBpZiAob3RoZXJGdW5jID09IG51bGwgfHwgb3RoZXJGdW5jID09IGZ1bmMpIHtcbiAgICAgIHJldHVybiBkYXRhLm5hbWU7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RnVuY05hbWU7XG4iLCJ2YXIgYmFzZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9iYXNlUHJvcGVydHknKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IHZhbHVlIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYXZvaWQgYSBbSklUIGJ1Z10oaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE0Mjc5MilcbiAqIHRoYXQgYWZmZWN0cyBTYWZhcmkgb24gYXQgbGVhc3QgaU9TIDguMS04LjMgQVJNNjQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBcImxlbmd0aFwiIHZhbHVlLlxuICovXG52YXIgZ2V0TGVuZ3RoID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBnZXRMZW5ndGg7XG4iLCJ2YXIgaXNTdHJpY3RDb21wYXJhYmxlID0gcmVxdWlyZSgnLi9pc1N0cmljdENvbXBhcmFibGUnKSxcbiAgICBwYWlycyA9IHJlcXVpcmUoJy4uL29iamVjdC9wYWlycycpO1xuXG4vKipcbiAqIEdldHMgdGhlIHByb3BlcnkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbWF0Y2ggZGF0YSBvZiBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gcGFpcnMob2JqZWN0KSxcbiAgICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgcmVzdWx0W2xlbmd0aF1bMl0gPSBpc1N0cmljdENvbXBhcmFibGUocmVzdWx0W2xlbmd0aF1bMV0pO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWF0Y2hEYXRhO1xuIiwidmFyIGlzTmF0aXZlID0gcmVxdWlyZSgnLi4vbGFuZy9pc05hdGl2ZScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZ1bmN0aW9uIGlmIGl0J3MgbmF0aXZlLCBlbHNlIGB1bmRlZmluZWRgLlxuICovXG5mdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgdmFyIHZhbHVlID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgcmV0dXJuIGlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldE5hdGl2ZTtcbiIsIi8qKlxuICogR2V0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYE5hTmAgaXMgZm91bmQgaW4gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCBgTmFOYCwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBpbmRleE9mTmFOKGFycmF5LCBmcm9tSW5kZXgsIGZyb21SaWdodCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaW5kZXggPSBmcm9tSW5kZXggKyAoZnJvbVJpZ2h0ID8gMCA6IC0xKTtcblxuICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgIHZhciBvdGhlciA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAob3RoZXIgIT09IG90aGVyKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbmRleE9mTmFOO1xuIiwiLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gYXJyYXkgY2xvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gKi9cbmZ1bmN0aW9uIGluaXRDbG9uZUFycmF5KGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBuZXcgYXJyYXkuY29uc3RydWN0b3IobGVuZ3RoKTtcblxuICAvLyBBZGQgYXJyYXkgcHJvcGVydGllcyBhc3NpZ25lZCBieSBgUmVnRXhwI2V4ZWNgLlxuICBpZiAobGVuZ3RoICYmIHR5cGVvZiBhcnJheVswXSA9PSAnc3RyaW5nJyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGFycmF5LCAnaW5kZXgnKSkge1xuICAgIHJlc3VsdC5pbmRleCA9IGFycmF5LmluZGV4O1xuICAgIHJlc3VsdC5pbnB1dCA9IGFycmF5LmlucHV0O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQXJyYXk7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgYnVmZmVyQ2xvbmUgPSByZXF1aXJlKCcuL2J1ZmZlckNsb25lJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheTtcblxuLyoqIFVzZWQgdG8gbG9va3VwIGEgdHlwZSBhcnJheSBjb25zdHJ1Y3RvcnMgYnkgYHRvU3RyaW5nVGFnYC4gKi9cbnZhciBjdG9yQnlUYWcgPSB7fTtcbmN0b3JCeVRhZ1tmbG9hdDMyVGFnXSA9IGdsb2JhbC5GbG9hdDMyQXJyYXk7XG5jdG9yQnlUYWdbZmxvYXQ2NFRhZ10gPSBnbG9iYWwuRmxvYXQ2NEFycmF5O1xuY3RvckJ5VGFnW2ludDhUYWddID0gZ2xvYmFsLkludDhBcnJheTtcbmN0b3JCeVRhZ1tpbnQxNlRhZ10gPSBnbG9iYWwuSW50MTZBcnJheTtcbmN0b3JCeVRhZ1tpbnQzMlRhZ10gPSBnbG9iYWwuSW50MzJBcnJheTtcbmN0b3JCeVRhZ1t1aW50OFRhZ10gPSBVaW50OEFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4Q2xhbXBlZFRhZ10gPSBnbG9iYWwuVWludDhDbGFtcGVkQXJyYXk7XG5jdG9yQnlUYWdbdWludDE2VGFnXSA9IGdsb2JhbC5VaW50MTZBcnJheTtcbmN0b3JCeVRhZ1t1aW50MzJUYWddID0gZ2xvYmFsLlVpbnQzMkFycmF5O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgcmV0dXJuIGJ1ZmZlckNsb25lKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAvLyBTYWZhcmkgNSBtb2JpbGUgaW5jb3JyZWN0bHkgaGFzIGBPYmplY3RgIGFzIHRoZSBjb25zdHJ1Y3RvciBvZiB0eXBlZCBhcnJheXMuXG4gICAgICBpZiAoQ3RvciBpbnN0YW5jZW9mIEN0b3IpIHtcbiAgICAgICAgQ3RvciA9IGN0b3JCeVRhZ1t0YWddO1xuICAgICAgfVxuICAgICAgdmFyIGJ1ZmZlciA9IG9iamVjdC5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IEN0b3IoaXNEZWVwID8gYnVmZmVyQ2xvbmUoYnVmZmVyKSA6IGJ1ZmZlciwgb2JqZWN0LmJ5dGVPZmZzZXQsIG9iamVjdC5sZW5ndGgpO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBDdG9yKG9iamVjdC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhvYmplY3QpKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSBvYmplY3QubGFzdEluZGV4O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJsdWFYUkRiRzl1WlVKNVZHRm5MbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SjJZWElnWW5WbVptVnlRMnh2Ym1VZ1BTQnlaWEYxYVhKbEtDY3VMMkoxWm1abGNrTnNiMjVsSnlrN1hHNWNiaThxS2lCZ1QySnFaV04wSTNSdlUzUnlhVzVuWUNCeVpYTjFiSFFnY21WbVpYSmxibU5sY3k0Z0tpOWNiblpoY2lCaWIyOXNWR0ZuSUQwZ0oxdHZZbXBsWTNRZ1FtOXZiR1ZoYmwwbkxGeHVJQ0FnSUdSaGRHVlVZV2NnUFNBblcyOWlhbVZqZENCRVlYUmxYU2NzWEc0Z0lDQWdiblZ0WW1WeVZHRm5JRDBnSjF0dlltcGxZM1FnVG5WdFltVnlYU2NzWEc0Z0lDQWdjbVZuWlhod1ZHRm5JRDBnSjF0dlltcGxZM1FnVW1WblJYaHdYU2NzWEc0Z0lDQWdjM1J5YVc1blZHRm5JRDBnSjF0dlltcGxZM1FnVTNSeWFXNW5YU2M3WEc1Y2JuWmhjaUJoY25KaGVVSjFabVpsY2xSaFp5QTlJQ2RiYjJKcVpXTjBJRUZ5Y21GNVFuVm1abVZ5WFNjc1hHNGdJQ0FnWm14dllYUXpNbFJoWnlBOUlDZGJiMkpxWldOMElFWnNiMkYwTXpKQmNuSmhlVjBuTEZ4dUlDQWdJR1pzYjJGME5qUlVZV2NnUFNBblcyOWlhbVZqZENCR2JHOWhkRFkwUVhKeVlYbGRKeXhjYmlBZ0lDQnBiblE0VkdGbklEMGdKMXR2WW1wbFkzUWdTVzUwT0VGeWNtRjVYU2NzWEc0Z0lDQWdhVzUwTVRaVVlXY2dQU0FuVzI5aWFtVmpkQ0JKYm5ReE5rRnljbUY1WFNjc1hHNGdJQ0FnYVc1ME16SlVZV2NnUFNBblcyOWlhbVZqZENCSmJuUXpNa0Z5Y21GNVhTY3NYRzRnSUNBZ2RXbHVkRGhVWVdjZ1BTQW5XMjlpYW1WamRDQlZhVzUwT0VGeWNtRjVYU2NzWEc0Z0lDQWdkV2x1ZERoRGJHRnRjR1ZrVkdGbklEMGdKMXR2WW1wbFkzUWdWV2x1ZERoRGJHRnRjR1ZrUVhKeVlYbGRKeXhjYmlBZ0lDQjFhVzUwTVRaVVlXY2dQU0FuVzI5aWFtVmpkQ0JWYVc1ME1UWkJjbkpoZVYwbkxGeHVJQ0FnSUhWcGJuUXpNbFJoWnlBOUlDZGJiMkpxWldOMElGVnBiblF6TWtGeWNtRjVYU2M3WEc1Y2JpOHFLaUJWYzJWa0lIUnZJRzFoZEdOb0lHQlNaV2RGZUhCZ0lHWnNZV2R6SUdaeWIyMGdkR2hsYVhJZ1kyOWxjbU5sWkNCemRISnBibWNnZG1Gc2RXVnpMaUFxTDF4dWRtRnlJSEpsUm14aFozTWdQU0F2WEZ4M0tpUXZPMXh1WEc0dktpb2dUbUYwYVhabElHMWxkR2h2WkNCeVpXWmxjbVZ1WTJWekxpQXFMMXh1ZG1GeUlGVnBiblE0UVhKeVlYa2dQU0JuYkc5aVlXd3VWV2x1ZERoQmNuSmhlVHRjYmx4dUx5b3FJRlZ6WldRZ2RHOGdiRzl2YTNWd0lHRWdkSGx3WlNCaGNuSmhlU0JqYjI1emRISjFZM1J2Y25NZ1lua2dZSFJ2VTNSeWFXNW5WR0ZuWUM0Z0tpOWNiblpoY2lCamRHOXlRbmxVWVdjZ1BTQjdmVHRjYm1OMGIzSkNlVlJoWjF0bWJHOWhkRE15VkdGblhTQTlJR2RzYjJKaGJDNUdiRzloZERNeVFYSnlZWGs3WEc1amRHOXlRbmxVWVdkYlpteHZZWFEyTkZSaFoxMGdQU0JuYkc5aVlXd3VSbXh2WVhRMk5FRnljbUY1TzF4dVkzUnZja0o1VkdGblcybHVkRGhVWVdkZElEMGdaMnh2WW1Gc0xrbHVkRGhCY25KaGVUdGNibU4wYjNKQ2VWUmhaMXRwYm5ReE5sUmhaMTBnUFNCbmJHOWlZV3d1U1c1ME1UWkJjbkpoZVR0Y2JtTjBiM0pDZVZSaFoxdHBiblF6TWxSaFoxMGdQU0JuYkc5aVlXd3VTVzUwTXpKQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0MWFXNTBPRlJoWjEwZ1BTQlZhVzUwT0VGeWNtRjVPMXh1WTNSdmNrSjVWR0ZuVzNWcGJuUTRRMnhoYlhCbFpGUmhaMTBnUFNCbmJHOWlZV3d1VldsdWREaERiR0Z0Y0dWa1FYSnlZWGs3WEc1amRHOXlRbmxVWVdkYmRXbHVkREUyVkdGblhTQTlJR2RzYjJKaGJDNVZhVzUwTVRaQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0MWFXNTBNekpVWVdkZElEMGdaMnh2WW1Gc0xsVnBiblF6TWtGeWNtRjVPMXh1WEc0dktpcGNiaUFxSUVsdWFYUnBZV3hwZW1WeklHRnVJRzlpYW1WamRDQmpiRzl1WlNCaVlYTmxaQ0J2YmlCcGRITWdZSFJ2VTNSeWFXNW5WR0ZuWUM1Y2JpQXFYRzRnS2lBcUtrNXZkR1U2S2lvZ1ZHaHBjeUJtZFc1amRHbHZiaUJ2Ym14NUlITjFjSEJ2Y25SeklHTnNiMjVwYm1jZ2RtRnNkV1Z6SUhkcGRHZ2dkR0ZuY3lCdlpseHVJQ29nWUVKdmIyeGxZVzVnTENCZ1JHRjBaV0FzSUdCRmNuSnZjbUFzSUdCT2RXMWlaWEpnTENCZ1VtVm5SWGh3WUN3Z2IzSWdZRk4wY21sdVoyQXVYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3VDJKcVpXTjBmU0J2WW1wbFkzUWdWR2hsSUc5aWFtVmpkQ0IwYnlCamJHOXVaUzVjYmlBcUlFQndZWEpoYlNCN2MzUnlhVzVuZlNCMFlXY2dWR2hsSUdCMGIxTjBjbWx1WjFSaFoyQWdiMllnZEdobElHOWlhbVZqZENCMGJ5QmpiRzl1WlM1Y2JpQXFJRUJ3WVhKaGJTQjdZbTl2YkdWaGJuMGdXMmx6UkdWbGNGMGdVM0JsWTJsbWVTQmhJR1JsWlhBZ1kyeHZibVV1WEc0Z0tpQkFjbVYwZFhKdWN5QjdUMkpxWldOMGZTQlNaWFIxY201eklIUm9aU0JwYm1sMGFXRnNhWHBsWkNCamJHOXVaUzVjYmlBcUwxeHVablZ1WTNScGIyNGdhVzVwZEVOc2IyNWxRbmxVWVdjb2IySnFaV04wTENCMFlXY3NJR2x6UkdWbGNDa2dlMXh1SUNCMllYSWdRM1J2Y2lBOUlHOWlhbVZqZEM1amIyNXpkSEoxWTNSdmNqdGNiaUFnYzNkcGRHTm9JQ2gwWVdjcElIdGNiaUFnSUNCallYTmxJR0Z5Y21GNVFuVm1abVZ5VkdGbk9seHVJQ0FnSUNBZ2NtVjBkWEp1SUdKMVptWmxja05zYjI1bEtHOWlhbVZqZENrN1hHNWNiaUFnSUNCallYTmxJR0p2YjJ4VVlXYzZYRzRnSUNBZ1kyRnpaU0JrWVhSbFZHRm5PbHh1SUNBZ0lDQWdjbVYwZFhKdUlHNWxkeUJEZEc5eUtDdHZZbXBsWTNRcE8xeHVYRzRnSUNBZ1kyRnpaU0JtYkc5aGRETXlWR0ZuT2lCallYTmxJR1pzYjJGME5qUlVZV2M2WEc0Z0lDQWdZMkZ6WlNCcGJuUTRWR0ZuT2lCallYTmxJR2x1ZERFMlZHRm5PaUJqWVhObElHbHVkRE15VkdGbk9seHVJQ0FnSUdOaGMyVWdkV2x1ZERoVVlXYzZJR05oYzJVZ2RXbHVkRGhEYkdGdGNHVmtWR0ZuT2lCallYTmxJSFZwYm5ReE5sUmhaem9nWTJGelpTQjFhVzUwTXpKVVlXYzZYRzRnSUNBZ0lDQXZMeUJUWVdaaGNta2dOU0J0YjJKcGJHVWdhVzVqYjNKeVpXTjBiSGtnYUdGeklHQlBZbXBsWTNSZ0lHRnpJSFJvWlNCamIyNXpkSEoxWTNSdmNpQnZaaUIwZVhCbFpDQmhjbkpoZVhNdVhHNGdJQ0FnSUNCcFppQW9RM1J2Y2lCcGJuTjBZVzVqWlc5bUlFTjBiM0lwSUh0Y2JpQWdJQ0FnSUNBZ1EzUnZjaUE5SUdOMGIzSkNlVlJoWjF0MFlXZGRPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdkbUZ5SUdKMVptWmxjaUE5SUc5aWFtVmpkQzVpZFdabVpYSTdYRzRnSUNBZ0lDQnlaWFIxY200Z2JtVjNJRU4wYjNJb2FYTkVaV1Z3SUQ4Z1luVm1abVZ5UTJ4dmJtVW9ZblZtWm1WeUtTQTZJR0oxWm1abGNpd2diMkpxWldOMExtSjVkR1ZQWm1aelpYUXNJRzlpYW1WamRDNXNaVzVuZEdncE8xeHVYRzRnSUNBZ1kyRnpaU0J1ZFcxaVpYSlVZV2M2WEc0Z0lDQWdZMkZ6WlNCemRISnBibWRVWVdjNlhHNGdJQ0FnSUNCeVpYUjFjbTRnYm1WM0lFTjBiM0lvYjJKcVpXTjBLVHRjYmx4dUlDQWdJR05oYzJVZ2NtVm5aWGh3VkdGbk9seHVJQ0FnSUNBZ2RtRnlJSEpsYzNWc2RDQTlJRzVsZHlCRGRHOXlLRzlpYW1WamRDNXpiM1Z5WTJVc0lISmxSbXhoWjNNdVpYaGxZeWh2WW1wbFkzUXBLVHRjYmlBZ0lDQWdJSEpsYzNWc2RDNXNZWE4wU1c1a1pYZ2dQU0J2WW1wbFkzUXViR0Z6ZEVsdVpHVjRPMXh1SUNCOVhHNGdJSEpsZEhWeWJpQnlaWE4xYkhRN1hHNTlYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpJRDBnYVc1cGRFTnNiMjVsUW5sVVlXYzdYRzRpWFgwPSIsIi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgaWYgKCEodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yIGluc3RhbmNlb2YgQ3RvcikpIHtcbiAgICBDdG9yID0gT2JqZWN0O1xuICB9XG4gIHJldHVybiBuZXcgQ3Rvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVPYmplY3Q7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgoZ2V0TGVuZ3RoKHZhbHVlKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2U7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QgaW4gSUUgPCA5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqL1xudmFyIGlzSG9zdE9iamVjdCA9IChmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QoeyAndG9TdHJpbmcnOiAwIH0gKyAnJyk7XG4gIH0gY2F0Y2goZSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIC8vIElFIDwgOSBwcmVzZW50cyBtYW55IGhvc3Qgb2JqZWN0cyBhcyBgT2JqZWN0YCBvYmplY3RzIHRoYXQgY2FuIGNvZXJjZVxuICAgIC8vIHRvIHN0cmluZ3MgZGVzcGl0ZSBoYXZpbmcgaW1wcm9wZXJseSBkZWZpbmVkIGB0b1N0cmluZ2AgbWV0aG9kcy5cbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlLnRvU3RyaW5nICE9ICdmdW5jdGlvbicgJiYgdHlwZW9mICh2YWx1ZSArICcnKSA9PSAnc3RyaW5nJztcbiAgfTtcbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNIb3N0T2JqZWN0O1xuIiwiLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xudmFyIHJlSXNVaW50ID0gL15cXGQrJC87XG5cbi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgdmFsdWUgPSAodHlwZW9mIHZhbHVlID09ICdudW1iZXInIHx8IHJlSXNVaW50LnRlc3QodmFsdWUpKSA/ICt2YWx1ZSA6IC0xO1xuICBsZW5ndGggPSBsZW5ndGggPT0gbnVsbCA/IE1BWF9TQUZFX0lOVEVHRVIgOiBsZW5ndGg7XG4gIHJldHVybiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDwgbGVuZ3RoO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSW5kZXg7XG4iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vaXNJbmRleCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgcHJvdmlkZWQgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB0eXBlID0gdHlwZW9mIGluZGV4O1xuICBpZiAodHlwZSA9PSAnbnVtYmVyJ1xuICAgICAgPyAoaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSlcbiAgICAgIDogKHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KSkge1xuICAgIHZhciBvdGhlciA9IG9iamVjdFtpbmRleF07XG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/ICh2YWx1ZSA9PT0gb3RoZXIpIDogKG90aGVyICE9PSBvdGhlcik7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSXRlcmF0ZWVDYWxsO1xuIiwidmFyIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlSXNEZWVwUHJvcCA9IC9cXC58XFxbKD86W15bXFxdXSp8KFtcIiddKSg/Oig/IVxcMSlbXlxcblxcXFxdfFxcXFwuKSo/XFwxKVxcXS8sXG4gICAgcmVJc1BsYWluUHJvcCA9IC9eXFx3KiQvO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcHJvcGVydHkgbmFtZSBhbmQgbm90IGEgcHJvcGVydHkgcGF0aC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzS2V5KHZhbHVlLCBvYmplY3QpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGlmICgodHlwZSA9PSAnc3RyaW5nJyAmJiByZUlzUGxhaW5Qcm9wLnRlc3QodmFsdWUpKSB8fCB0eXBlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciByZXN1bHQgPSAhcmVJc0RlZXBQcm9wLnRlc3QodmFsdWUpO1xuICByZXR1cm4gcmVzdWx0IHx8IChvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiB0b09iamVjdChvYmplY3QpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0tleTtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBnZXREYXRhID0gcmVxdWlyZSgnLi9nZXREYXRhJyksXG4gICAgZ2V0RnVuY05hbWUgPSByZXF1aXJlKCcuL2dldEZ1bmNOYW1lJyksXG4gICAgbG9kYXNoID0gcmVxdWlyZSgnLi4vY2hhaW4vbG9kYXNoJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaGFzIGEgbGF6eSBjb3VudGVycGFydCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xhemlhYmxlKGZ1bmMpIHtcbiAgdmFyIGZ1bmNOYW1lID0gZ2V0RnVuY05hbWUoZnVuYyksXG4gICAgICBvdGhlciA9IGxvZGFzaFtmdW5jTmFtZV07XG5cbiAgaWYgKHR5cGVvZiBvdGhlciAhPSAnZnVuY3Rpb24nIHx8ICEoZnVuY05hbWUgaW4gTGF6eVdyYXBwZXIucHJvdG90eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZnVuYyA9PT0gb3RoZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICB2YXIgZGF0YSA9IGdldERhdGEob3RoZXIpO1xuICByZXR1cm4gISFkYXRhICYmIGZ1bmMgPT09IGRhdGFbMF07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMYXppYWJsZTtcbiIsIi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIGJhc2VkIG9uIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBsZW5ndGgsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMZW5ndGg7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3RMaWtlO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaWYgc3VpdGFibGUgZm9yIHN0cmljdFxuICogIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IHZhbHVlICYmICFpc09iamVjdCh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTdHJpY3RDb21wYXJhYmxlO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi9yZXBsYWNlSG9sZGVycycpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQVJZX0ZMQUcgPSAxMjgsXG4gICAgUkVBUkdfRkxBRyA9IDI1NjtcblxuLyoqIFVzZWQgYXMgdGhlIGludGVybmFsIGFyZ3VtZW50IHBsYWNlaG9sZGVyLiAqL1xudmFyIFBMQUNFSE9MREVSID0gJ19fbG9kYXNoX3BsYWNlaG9sZGVyX18nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1pbiA9IE1hdGgubWluO1xuXG4vKipcbiAqIE1lcmdlcyB0aGUgZnVuY3Rpb24gbWV0YWRhdGEgb2YgYHNvdXJjZWAgaW50byBgZGF0YWAuXG4gKlxuICogTWVyZ2luZyBtZXRhZGF0YSByZWR1Y2VzIHRoZSBudW1iZXIgb2Ygd3JhcHBlcnMgcmVxdWlyZWQgdG8gaW52b2tlIGEgZnVuY3Rpb24uXG4gKiBUaGlzIGlzIHBvc3NpYmxlIGJlY2F1c2UgbWV0aG9kcyBsaWtlIGBfLmJpbmRgLCBgXy5jdXJyeWAsIGFuZCBgXy5wYXJ0aWFsYFxuICogbWF5IGJlIGFwcGxpZWQgcmVnYXJkbGVzcyBvZiBleGVjdXRpb24gb3JkZXIuIE1ldGhvZHMgbGlrZSBgXy5hcnlgIGFuZCBgXy5yZWFyZ2BcbiAqIGF1Z21lbnQgZnVuY3Rpb24gYXJndW1lbnRzLCBtYWtpbmcgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGV4ZWN1dGVkIGltcG9ydGFudCxcbiAqIHByZXZlbnRpbmcgdGhlIG1lcmdpbmcgb2YgbWV0YWRhdGEuIEhvd2V2ZXIsIHdlIG1ha2UgYW4gZXhjZXB0aW9uIGZvciBhIHNhZmVcbiAqIGNvbW1vbiBjYXNlIHdoZXJlIGN1cnJpZWQgZnVuY3Rpb25zIGhhdmUgYF8uYXJ5YCBhbmQgb3IgYF8ucmVhcmdgIGFwcGxpZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgVGhlIGRlc3RpbmF0aW9uIG1ldGFkYXRhLlxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBzb3VyY2UgbWV0YWRhdGEuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGRhdGFgLlxuICovXG5mdW5jdGlvbiBtZXJnZURhdGEoZGF0YSwgc291cmNlKSB7XG4gIHZhciBiaXRtYXNrID0gZGF0YVsxXSxcbiAgICAgIHNyY0JpdG1hc2sgPSBzb3VyY2VbMV0sXG4gICAgICBuZXdCaXRtYXNrID0gYml0bWFzayB8IHNyY0JpdG1hc2ssXG4gICAgICBpc0NvbW1vbiA9IG5ld0JpdG1hc2sgPCBBUllfRkxBRztcblxuICB2YXIgaXNDb21ibyA9XG4gICAgKHNyY0JpdG1hc2sgPT0gQVJZX0ZMQUcgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKSB8fFxuICAgIChzcmNCaXRtYXNrID09IEFSWV9GTEFHICYmIGJpdG1hc2sgPT0gUkVBUkdfRkxBRyAmJiBkYXRhWzddLmxlbmd0aCA8PSBzb3VyY2VbOF0pIHx8XG4gICAgKHNyY0JpdG1hc2sgPT0gKEFSWV9GTEFHIHwgUkVBUkdfRkxBRykgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKTtcblxuICAvLyBFeGl0IGVhcmx5IGlmIG1ldGFkYXRhIGNhbid0IGJlIG1lcmdlZC5cbiAgaWYgKCEoaXNDb21tb24gfHwgaXNDb21ibykpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGB0aGlzQXJnYCBpZiBhdmFpbGFibGUuXG4gIGlmIChzcmNCaXRtYXNrICYgQklORF9GTEFHKSB7XG4gICAgZGF0YVsyXSA9IHNvdXJjZVsyXTtcbiAgICAvLyBTZXQgd2hlbiBjdXJyeWluZyBhIGJvdW5kIGZ1bmN0aW9uLlxuICAgIG5ld0JpdG1hc2sgfD0gKGJpdG1hc2sgJiBCSU5EX0ZMQUcpID8gMCA6IENVUlJZX0JPVU5EX0ZMQUc7XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIGFyZ3VtZW50cy5cbiAgdmFyIHZhbHVlID0gc291cmNlWzNdO1xuICBpZiAodmFsdWUpIHtcbiAgICB2YXIgcGFydGlhbHMgPSBkYXRhWzNdO1xuICAgIGRhdGFbM10gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzKHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzRdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgZGF0YVs0XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVszXSwgUExBQ0VIT0xERVIpIDogYXJyYXlDb3B5KHNvdXJjZVs0XSk7XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIHJpZ2h0IGFyZ3VtZW50cy5cbiAgdmFsdWUgPSBzb3VyY2VbNV07XG4gIGlmICh2YWx1ZSkge1xuICAgIHBhcnRpYWxzID0gZGF0YVs1XTtcbiAgICBkYXRhWzVdID0gcGFydGlhbHMgPyBjb21wb3NlQXJnc1JpZ2h0KHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzZdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgZGF0YVs2XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVs1XSwgUExBQ0VIT0xERVIpIDogYXJyYXlDb3B5KHNvdXJjZVs2XSk7XG4gIH1cbiAgLy8gVXNlIHNvdXJjZSBgYXJnUG9zYCBpZiBhdmFpbGFibGUuXG4gIHZhbHVlID0gc291cmNlWzddO1xuICBpZiAodmFsdWUpIHtcbiAgICBkYXRhWzddID0gYXJyYXlDb3B5KHZhbHVlKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcnlgIGlmIGl0J3Mgc21hbGxlci5cbiAgaWYgKHNyY0JpdG1hc2sgJiBBUllfRkxBRykge1xuICAgIGRhdGFbOF0gPSBkYXRhWzhdID09IG51bGwgPyBzb3VyY2VbOF0gOiBuYXRpdmVNaW4oZGF0YVs4XSwgc291cmNlWzhdKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcml0eWAgaWYgb25lIGlzIG5vdCBwcm92aWRlZC5cbiAgaWYgKGRhdGFbOV0gPT0gbnVsbCkge1xuICAgIGRhdGFbOV0gPSBzb3VyY2VbOV07XG4gIH1cbiAgLy8gVXNlIHNvdXJjZSBgZnVuY2AgYW5kIG1lcmdlIGJpdG1hc2tzLlxuICBkYXRhWzBdID0gc291cmNlWzBdO1xuICBkYXRhWzFdID0gbmV3Qml0bWFzaztcblxuICByZXR1cm4gZGF0YTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtZXJnZURhdGE7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9nZXROYXRpdmUnKTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKGdsb2JhbCwgJ1dlYWtNYXAnKTtcblxuLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgbWV0YU1hcCA9IFdlYWtNYXAgJiYgbmV3IFdlYWtNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gbWV0YU1hcDtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMjFsZEdGTllYQXVhbk1pWFN3aWJtRnRaWE1pT2x0ZExDSnRZWEJ3YVc1bmN5STZJanRCUVVGQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1oyVjBUbUYwYVhabElEMGdjbVZ4ZFdseVpTZ25MaTluWlhST1lYUnBkbVVuS1R0Y2JseHVMeW9xSUU1aGRHbDJaU0J0WlhSb2IyUWdjbVZtWlhKbGJtTmxjeTRnS2k5Y2JuWmhjaUJYWldGclRXRndJRDBnWjJWMFRtRjBhWFpsS0dkc2IySmhiQ3dnSjFkbFlXdE5ZWEFuS1R0Y2JseHVMeW9xSUZWelpXUWdkRzhnYzNSdmNtVWdablZ1WTNScGIyNGdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdiV1YwWVUxaGNDQTlJRmRsWVd0TllYQWdKaVlnYm1WM0lGZGxZV3ROWVhBN1hHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdiV1YwWVUxaGNEdGNiaUpkZlE9PSIsIi8qKiBVc2VkIHRvIGxvb2t1cCB1bm1pbmlmaWVkIGZ1bmN0aW9uIG5hbWVzLiAqL1xudmFyIHJlYWxOYW1lcyA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlYWxOYW1lcztcbiIsInZhciBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpLFxuICAgIGlzSW5kZXggPSByZXF1aXJlKCcuL2lzSW5kZXgnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBSZW9yZGVyIGBhcnJheWAgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgaW5kZXhlcyB3aGVyZSB0aGUgZWxlbWVudCBhdFxuICogdGhlIGZpcnN0IGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBmaXJzdCBlbGVtZW50LCB0aGUgZWxlbWVudCBhdFxuICogdGhlIHNlY29uZCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgc2Vjb25kIGVsZW1lbnQsIGFuZCBzbyBvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHJlb3JkZXIuXG4gKiBAcGFyYW0ge0FycmF5fSBpbmRleGVzIFRoZSBhcnJhbmdlZCBhcnJheSBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIHJlb3JkZXIoYXJyYXksIGluZGV4ZXMpIHtcbiAgdmFyIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihpbmRleGVzLmxlbmd0aCwgYXJyTGVuZ3RoKSxcbiAgICAgIG9sZEFycmF5ID0gYXJyYXlDb3B5KGFycmF5KTtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgaW5kZXggPSBpbmRleGVzW2xlbmd0aF07XG4gICAgYXJyYXlbbGVuZ3RoXSA9IGlzSW5kZXgoaW5kZXgsIGFyckxlbmd0aCkgPyBvbGRBcnJheVtpbmRleF0gOiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlb3JkZXI7XG4iLCIvKiogVXNlZCBhcyB0aGUgaW50ZXJuYWwgYXJndW1lbnQgcGxhY2Vob2xkZXIuICovXG52YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbi8qKlxuICogUmVwbGFjZXMgYWxsIGBwbGFjZWhvbGRlcmAgZWxlbWVudHMgaW4gYGFycmF5YCB3aXRoIGFuIGludGVybmFsIHBsYWNlaG9sZGVyXG4gKiBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiB0aGVpciBpbmRleGVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHsqfSBwbGFjZWhvbGRlciBUaGUgcGxhY2Vob2xkZXIgdG8gcmVwbGFjZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKi9cbmZ1bmN0aW9uIHJlcGxhY2VIb2xkZXJzKGFycmF5LCBwbGFjZWhvbGRlcikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc0luZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHBsYWNlaG9sZGVyKSB7XG4gICAgICBhcnJheVtpbmRleF0gPSBQTEFDRUhPTERFUjtcbiAgICAgIHJlc3VsdFsrK3Jlc0luZGV4XSA9IGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcGxhY2VIb2xkZXJzO1xuIiwidmFyIGJhc2VTZXREYXRhID0gcmVxdWlyZSgnLi9iYXNlU2V0RGF0YScpLFxuICAgIG5vdyA9IHJlcXVpcmUoJy4uL2RhdGUvbm93Jyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCB3aGVuIGEgZnVuY3Rpb24gYmVjb21lcyBob3QuICovXG52YXIgSE9UX0NPVU5UID0gMTUwLFxuICAgIEhPVF9TUEFOID0gMTY7XG5cbi8qKlxuICogU2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICpcbiAqICoqTm90ZToqKiBJZiB0aGlzIGZ1bmN0aW9uIGJlY29tZXMgaG90LCBpLmUuIGlzIGludm9rZWQgYSBsb3QgaW4gYSBzaG9ydFxuICogcGVyaW9kIG9mIHRpbWUsIGl0IHdpbGwgdHJpcCBpdHMgYnJlYWtlciBhbmQgdHJhbnNpdGlvbiB0byBhbiBpZGVudGl0eSBmdW5jdGlvblxuICogdG8gYXZvaWQgZ2FyYmFnZSBjb2xsZWN0aW9uIHBhdXNlcyBpbiBWOC4gU2VlIFtWOCBpc3N1ZSAyMDcwXShodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjA3MClcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBzZXREYXRhID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgY291bnQgPSAwLFxuICAgICAgbGFzdENhbGxlZCA9IDA7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICB2YXIgc3RhbXAgPSBub3coKSxcbiAgICAgICAgcmVtYWluaW5nID0gSE9UX1NQQU4gLSAoc3RhbXAgLSBsYXN0Q2FsbGVkKTtcblxuICAgIGxhc3RDYWxsZWQgPSBzdGFtcDtcbiAgICBpZiAocmVtYWluaW5nID4gMCkge1xuICAgICAgaWYgKCsrY291bnQgPj0gSE9UX0NPVU5UKSB7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvdW50ID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIGJhc2VTZXREYXRhKGtleSwgdmFsdWUpO1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBzZXREYXRhO1xuIiwidmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9pc0luZGV4JyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuL2lzTGVuZ3RoJyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXNJbicpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIGZhbGxiYWNrIGltcGxlbWVudGF0aW9uIG9mIGBPYmplY3Qua2V5c2Agd2hpY2ggY3JlYXRlcyBhbiBhcnJheSBvZiB0aGVcbiAqIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBzaGltS2V5cyhvYmplY3QpIHtcbiAgdmFyIHByb3BzID0ga2V5c0luKG9iamVjdCksXG4gICAgICBwcm9wc0xlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IHByb3BzTGVuZ3RoICYmIG9iamVjdC5sZW5ndGg7XG5cbiAgdmFyIGFsbG93SW5kZXhlcyA9ICEhbGVuZ3RoICYmIGlzTGVuZ3RoKGxlbmd0aCkgJiZcbiAgICAoaXNBcnJheShvYmplY3QpIHx8IGlzQXJndW1lbnRzKG9iamVjdCkgfHwgaXNTdHJpbmcob2JqZWN0KSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBpZiAoKGFsbG93SW5kZXhlcyAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSkgfHwgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hpbUtleXM7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIG9iamVjdCBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIHRvT2JqZWN0KHZhbHVlKSB7XG4gIGlmIChzdXBwb3J0LnVuaW5kZXhlZENoYXJzICYmIGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSB2YWx1ZS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IE9iamVjdCh2YWx1ZSk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdWx0W2luZGV4XSA9IHZhbHVlLmNoYXJBdChpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b09iamVjdDtcbiIsInZhciBiYXNlVG9TdHJpbmcgPSByZXF1aXJlKCcuL2Jhc2VUb1N0cmluZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxuXFxcXF18XFxcXC4pKj8pXFwyKVxcXS9nO1xuXG4vKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi9cbnZhciByZUVzY2FwZUNoYXIgPSAvXFxcXChcXFxcKT8vZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIHByb3BlcnR5IHBhdGggYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICovXG5mdW5jdGlvbiB0b1BhdGgodmFsdWUpIHtcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgYmFzZVRvU3RyaW5nKHZhbHVlKS5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdHJpbmcpIHtcbiAgICByZXN1bHQucHVzaChxdW90ZSA/IHN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiAobnVtYmVyIHx8IG1hdGNoKSk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvUGF0aDtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBMb2Rhc2hXcmFwcGVyID0gcmVxdWlyZSgnLi9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHdyYXBwZXJgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gd3JhcHBlciBUaGUgd3JhcHBlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCB3cmFwcGVyLlxuICovXG5mdW5jdGlvbiB3cmFwcGVyQ2xvbmUod3JhcHBlcikge1xuICByZXR1cm4gd3JhcHBlciBpbnN0YW5jZW9mIExhenlXcmFwcGVyXG4gICAgPyB3cmFwcGVyLmNsb25lKClcbiAgICA6IG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZXIuX193cmFwcGVkX18sIHdyYXBwZXIuX19jaGFpbl9fLCBhcnJheUNvcHkod3JhcHBlci5fX2FjdGlvbnNfXykpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHdyYXBwZXJDbG9uZTtcbiIsInZhciBiYXNlQ2xvbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2xvbmUnKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iaW5kQ2FsbGJhY2snKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVlcCBjbG9uZSBvZiBgdmFsdWVgLiBJZiBgY3VzdG9taXplcmAgaXMgcHJvdmlkZWQgaXQncyBpbnZva2VkXG4gKiB0byBwcm9kdWNlIHRoZSBjbG9uZWQgdmFsdWVzLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCBjbG9uaW5nXG4gKiBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBib3VuZCB0byBgdGhpc0FyZ2BcbiAqIGFuZCBpbnZva2VkIHdpdGggdXAgdG8gdGhyZWUgYXJndW1lbnQ7ICh2YWx1ZSBbLCBpbmRleHxrZXksIG9iamVjdF0pLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uIHRoZVxuICogW3N0cnVjdHVyZWQgY2xvbmUgYWxnb3JpdGhtXShodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNS9pbmZyYXN0cnVjdHVyZS5odG1sI2ludGVybmFsLXN0cnVjdHVyZWQtY2xvbmluZy1hbGdvcml0aG0pLlxuICogVGhlIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFuZCBvYmplY3RzIGNyZWF0ZWQgYnlcbiAqIGNvbnN0cnVjdG9ycyBvdGhlciB0aGFuIGBPYmplY3RgIGFyZSBjbG9uZWQgdG8gcGxhaW4gYE9iamVjdGAgb2JqZWN0cy4gQW5cbiAqIGVtcHR5IG9iamVjdCBpcyByZXR1cm5lZCBmb3IgdW5jbG9uZWFibGUgdmFsdWVzIHN1Y2ggYXMgZnVuY3Rpb25zLCBET00gbm9kZXMsXG4gKiBNYXBzLCBTZXRzLCBhbmQgV2Vha01hcHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBkZWVwIGNsb25lLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGN1c3RvbWl6ZXJgLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGRlZXAgY2xvbmVkIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgdXNlcnMgPSBbXG4gKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnIH1cbiAqIF07XG4gKlxuICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcCh1c2Vycyk7XG4gKiBkZWVwWzBdID09PSB1c2Vyc1swXTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogLy8gdXNpbmcgYSBjdXN0b21pemVyIGNhbGxiYWNrXG4gKiB2YXIgZWwgPSBfLmNsb25lRGVlcChkb2N1bWVudC5ib2R5LCBmdW5jdGlvbih2YWx1ZSkge1xuICogICBpZiAoXy5pc0VsZW1lbnQodmFsdWUpKSB7XG4gKiAgICAgcmV0dXJuIHZhbHVlLmNsb25lTm9kZSh0cnVlKTtcbiAqICAgfVxuICogfSk7XG4gKlxuICogZWwgPT09IGRvY3VtZW50LmJvZHlcbiAqIC8vID0+IGZhbHNlXG4gKiBlbC5ub2RlTmFtZVxuICogLy8gPT4gQk9EWVxuICogZWwuY2hpbGROb2Rlcy5sZW5ndGg7XG4gKiAvLyA9PiAyMFxuICovXG5mdW5jdGlvbiBjbG9uZURlZXAodmFsdWUsIGN1c3RvbWl6ZXIsIHRoaXNBcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbidcbiAgICA/IGJhc2VDbG9uZSh2YWx1ZSwgdHJ1ZSwgYmluZENhbGxiYWNrKGN1c3RvbWl6ZXIsIHRoaXNBcmcsIDMpKVxuICAgIDogYmFzZUNsb25lKHZhbHVlLCB0cnVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZURlZXA7XG4iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKSAmJlxuICAgIGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdjYWxsZWUnKSAmJiAhcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJndW1lbnRzO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlSXNBcnJheSA9IGdldE5hdGl2ZShBcnJheSwgJ2lzQXJyYXknKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJyYXkoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXkoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNBcnJheSA9IG5hdGl2ZUlzQXJyYXkgfHwgZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBhcnJheVRhZztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheTtcbiIsInZhciBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4vaXNTdHJpbmcnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBlbXB0eS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGVtcHR5IHVubGVzcyBpdCdzIGFuXG4gKiBgYXJndW1lbnRzYCBvYmplY3QsIGFycmF5LCBzdHJpbmcsIG9yIGpRdWVyeS1saWtlIGNvbGxlY3Rpb24gd2l0aCBhIGxlbmd0aFxuICogZ3JlYXRlciB0aGFuIGAwYCBvciBhbiBvYmplY3Qgd2l0aCBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGVtcHR5LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNFbXB0eShudWxsKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRW1wdHkodHJ1ZSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0VtcHR5KDEpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNFbXB0eShbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzRW1wdHkoeyAnYSc6IDEgfSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0VtcHR5KHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQXJyYXlMaWtlKHZhbHVlKSAmJiAoaXNBcnJheSh2YWx1ZSkgfHwgaXNTdHJpbmcodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSB8fFxuICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNGdW5jdGlvbih2YWx1ZS5zcGxpY2UpKSkpIHtcbiAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gIWtleXModmFsdWUpLmxlbmd0aDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0VtcHR5O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0Z1bmN0aW9uKF8pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNGdW5jdGlvbigvYWJjLyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gIC8vIFRoZSB1c2Ugb2YgYE9iamVjdCN0b1N0cmluZ2AgYXZvaWRzIGlzc3VlcyB3aXRoIHRoZSBgdHlwZW9mYCBvcGVyYXRvclxuICAvLyBpbiBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaSB3aGljaCByZXR1cm4gJ2Z1bmN0aW9uJyBmb3IgcmVnZXhlc1xuICAvLyBhbmQgU2FmYXJpIDggd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXkgY29uc3RydWN0b3JzLlxuICByZXR1cm4gaXNPYmplY3QodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IGZ1bmNUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGdW5jdGlvbjtcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBob3N0IGNvbnN0cnVjdG9ycyAoU2FmYXJpID4gNSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbnZhciBmblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaWYgYSBtZXRob2QgaXMgbmF0aXZlLiAqL1xudmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICtcbiAgZm5Ub1N0cmluZy5jYWxsKGhhc093blByb3BlcnR5KS5yZXBsYWNlKC9bXFxcXF4kLiorPygpW1xcXXt9fF0vZywgJ1xcXFwkJicpXG4gIC5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcXFxcKCl8IGZvciAuKz8oPz1cXFxcXFxdKS9nLCAnJDEuKj8nKSArICckJ1xuKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc05hdGl2ZShfKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHJldHVybiByZUlzTmF0aXZlLnRlc3QoZm5Ub1N0cmluZy5jYWxsKHZhbHVlKSk7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgKGlzSG9zdE9iamVjdCh2YWx1ZSkgPyByZUlzTmF0aXZlIDogcmVJc0hvc3RDdG9yKS50ZXN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc05hdGl2ZTtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlIFtsYW5ndWFnZSB0eXBlXShodHRwczovL2VzNS5naXRodWIuaW8vI3g4KSBvZiBgT2JqZWN0YC5cbiAqIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoMSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAvLyBBdm9pZCBhIFY4IEpJVCBidWcgaW4gQ2hyb21lIDE5LTIwLlxuICAvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTIyOTEgZm9yIG1vcmUgZGV0YWlscy5cbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3Q7XG4iLCJ2YXIgYmFzZUZvckluID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUZvckluJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgdGhhdCBpcywgYW4gb2JqZWN0IGNyZWF0ZWQgYnkgdGhlXG4gKiBgT2JqZWN0YCBjb25zdHJ1Y3RvciBvciBvbmUgd2l0aCBhIGBbW1Byb3RvdHlwZV1dYCBvZiBgbnVsbGAuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGFzc3VtZXMgb2JqZWN0cyBjcmVhdGVkIGJ5IHRoZSBgT2JqZWN0YCBjb25zdHJ1Y3RvclxuICogaGF2ZSBubyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiB9XG4gKlxuICogXy5pc1BsYWluT2JqZWN0KG5ldyBGb28pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KHsgJ3gnOiAwLCAneSc6IDAgfSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KE9iamVjdC5jcmVhdGUobnVsbCkpO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KHZhbHVlKSB7XG4gIHZhciBDdG9yO1xuXG4gIC8vIEV4aXQgZWFybHkgZm9yIG5vbiBgT2JqZWN0YCBvYmplY3RzLlxuICBpZiAoIShpc09iamVjdExpa2UodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KHZhbHVlKSAmJiAhaXNBcmd1bWVudHModmFsdWUpKSB8fFxuICAgICAgKCFoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnY29uc3RydWN0b3InKSAmJiAoQ3RvciA9IHZhbHVlLmNvbnN0cnVjdG9yLCB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmICEoQ3RvciBpbnN0YW5jZW9mIEN0b3IpKSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gSUUgPCA5IGl0ZXJhdGVzIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGJlZm9yZSBvd24gcHJvcGVydGllcy4gSWYgdGhlIGZpcnN0XG4gIC8vIGl0ZXJhdGVkIHByb3BlcnR5IGlzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0eSB0aGVuIHRoZXJlIGFyZSBubyBpbmhlcml0ZWRcbiAgLy8gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICB2YXIgcmVzdWx0O1xuICBpZiAoc3VwcG9ydC5vd25MYXN0KSB7XG4gICAgYmFzZUZvckluKHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgIHJlc3VsdCA9IGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQgIT09IGZhbHNlO1xuICB9XG4gIC8vIEluIG1vc3QgZW52aXJvbm1lbnRzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0aWVzIGFyZSBpdGVyYXRlZCBiZWZvcmVcbiAgLy8gaXRzIGluaGVyaXRlZCBwcm9wZXJ0aWVzLiBJZiB0aGUgbGFzdCBpdGVyYXRlZCBwcm9wZXJ0eSBpcyBhbiBvYmplY3Qnc1xuICAvLyBvd24gcHJvcGVydHkgdGhlbiB0aGVyZSBhcmUgbm8gaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgYmFzZUZvckluKHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5KSB7XG4gICAgcmVzdWx0ID0ga2V5O1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHJlc3VsdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNQbGFpbk9iamVjdDtcbiIsInZhciBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN0cmluZ2AgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N0cmluZygnYWJjJyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N0cmluZygxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gc3RyaW5nVGFnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N0cmluZztcbiIsInZhciBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgb2YgdHlwZWQgYXJyYXlzLiAqL1xudmFyIHR5cGVkQXJyYXlUYWdzID0ge307XG50eXBlZEFycmF5VGFnc1tmbG9hdDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Zsb2F0NjRUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQ4VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50OENsYW1wZWRUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDE2VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbnR5cGVkQXJyYXlUYWdzW2FyZ3NUYWddID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlUYWddID1cbnR5cGVkQXJyYXlUYWdzW2FycmF5QnVmZmVyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Jvb2xUYWddID1cbnR5cGVkQXJyYXlUYWdzW2RhdGVUYWddID0gdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID1cbnR5cGVkQXJyYXlUYWdzW2Z1bmNUYWddID0gdHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9XG50eXBlZEFycmF5VGFnc1tudW1iZXJUYWddID0gdHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tyZWdleHBUYWddID0gdHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tzdHJpbmdUYWddID0gdHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIHR5cGVkIGFycmF5LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNUeXBlZEFycmF5KHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tvYmpUb1N0cmluZy5jYWxsKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUeXBlZEFycmF5O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYHVuZGVmaW5lZGAsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1VuZGVmaW5lZCh2b2lkIDApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNVbmRlZmluZWQobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1VuZGVmaW5lZDtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXROYXRpdmUnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgc2hpbUtleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9zaGltS2V5cycpLFxuICAgIHN1cHBvcnQgPSByZXF1aXJlKCcuLi9zdXBwb3J0Jyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlS2V5cyA9IGdldE5hdGl2ZShPYmplY3QsICdrZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuIFNlZSB0aGVcbiAqIFtFUyBzcGVjXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3Qua2V5cylcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5cyhuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLmtleXMoJ2hpJyk7XG4gKiAvLyA9PiBbJzAnLCAnMSddXG4gKi9cbnZhciBrZXlzID0gIW5hdGl2ZUtleXMgPyBzaGltS2V5cyA6IGZ1bmN0aW9uKG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBpZiAoKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgPT09IG9iamVjdCkgfHxcbiAgICAgICh0eXBlb2Ygb2JqZWN0ID09ICdmdW5jdGlvbicgPyBzdXBwb3J0LmVudW1Qcm90b3R5cGVzIDogaXNBcnJheUxpa2Uob2JqZWN0KSkpIHtcbiAgICByZXR1cm4gc2hpbUtleXMob2JqZWN0KTtcbiAgfVxuICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSA/IG5hdGl2ZUtleXMob2JqZWN0KSA6IFtdO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBrZXlzO1xuIiwidmFyIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2FycmF5RWFjaCcpLFxuICAgIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi4vbGFuZy9pc0Z1bmN0aW9uJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzSW5kZXgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCB0byBmaXggdGhlIEpTY3JpcHQgYFtbRG9udEVudW1dXWAgYnVnLiAqL1xudmFyIHNoYWRvd1Byb3BzID0gW1xuICAnY29uc3RydWN0b3InLCAnaGFzT3duUHJvcGVydHknLCAnaXNQcm90b3R5cGVPZicsICdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG4gICd0b0xvY2FsZVN0cmluZycsICd0b1N0cmluZycsICd2YWx1ZU9mJ1xuXTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxuICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZSxcbiAgICBzdHJpbmdQcm90byA9IFN0cmluZy5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGF2b2lkIGl0ZXJhdGluZyBvdmVyIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgaW4gSUUgPCA5LiAqL1xudmFyIG5vbkVudW1Qcm9wcyA9IHt9O1xubm9uRW51bVByb3BzW2FycmF5VGFnXSA9IG5vbkVudW1Qcm9wc1tkYXRlVGFnXSA9IG5vbkVudW1Qcm9wc1tudW1iZXJUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9Mb2NhbGVTdHJpbmcnOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcbm5vbkVudW1Qcm9wc1tib29sVGFnXSA9IG5vbkVudW1Qcm9wc1tzdHJpbmdUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcbm5vbkVudW1Qcm9wc1tlcnJvclRhZ10gPSBub25FbnVtUHJvcHNbZnVuY1RhZ10gPSBub25FbnVtUHJvcHNbcmVnZXhwVGFnXSA9IHsgJ2NvbnN0cnVjdG9yJzogdHJ1ZSwgJ3RvU3RyaW5nJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW29iamVjdFRhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUgfTtcblxuYXJyYXlFYWNoKHNoYWRvd1Byb3BzLCBmdW5jdGlvbihrZXkpIHtcbiAgZm9yICh2YXIgdGFnIGluIG5vbkVudW1Qcm9wcykge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG5vbkVudW1Qcm9wcywgdGFnKSkge1xuICAgICAgdmFyIHByb3BzID0gbm9uRW51bVByb3BzW3RhZ107XG4gICAgICBwcm9wc1trZXldID0gaGFzT3duUHJvcGVydHkuY2FsbChwcm9wcywga2V5KTtcbiAgICB9XG4gIH1cbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5c0luKG5ldyBGb28pO1xuICogLy8gPT4gWydhJywgJ2InLCAnYyddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbmZ1bmN0aW9uIGtleXNJbihvYmplY3QpIHtcbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICB9XG4gIHZhciBsZW5ndGggPSBvYmplY3QubGVuZ3RoO1xuXG4gIGxlbmd0aCA9IChsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSB8fCBpc1N0cmluZyhvYmplY3QpKSAmJiBsZW5ndGgpIHx8IDA7XG5cbiAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICBpbmRleCA9IC0xLFxuICAgICAgcHJvdG8gPSAoaXNGdW5jdGlvbihDdG9yKSAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG8sXG4gICAgICBpc1Byb3RvID0gcHJvdG8gPT09IG9iamVjdCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCksXG4gICAgICBza2lwSW5kZXhlcyA9IGxlbmd0aCA+IDAsXG4gICAgICBza2lwRXJyb3JQcm9wcyA9IHN1cHBvcnQuZW51bUVycm9yUHJvcHMgJiYgKG9iamVjdCA9PT0gZXJyb3JQcm90byB8fCBvYmplY3QgaW5zdGFuY2VvZiBFcnJvciksXG4gICAgICBza2lwUHJvdG8gPSBzdXBwb3J0LmVudW1Qcm90b3R5cGVzICYmIGlzRnVuY3Rpb24ob2JqZWN0KTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSAoaW5kZXggKyAnJyk7XG4gIH1cbiAgLy8gbG9kYXNoIHNraXBzIHRoZSBgY29uc3RydWN0b3JgIHByb3BlcnR5IHdoZW4gaXQgaW5mZXJzIGl0J3MgaXRlcmF0aW5nXG4gIC8vIG92ZXIgYSBgcHJvdG90eXBlYCBvYmplY3QgYmVjYXVzZSBJRSA8IDkgY2FuJ3Qgc2V0IHRoZSBgW1tFbnVtZXJhYmxlXV1gXG4gIC8vIGF0dHJpYnV0ZSBvZiBhbiBleGlzdGluZyBwcm9wZXJ0eSBhbmQgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgb2YgYVxuICAvLyBwcm90b3R5cGUgZGVmYXVsdHMgdG8gbm9uLWVudW1lcmFibGUuXG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoIShza2lwUHJvdG8gJiYga2V5ID09ICdwcm90b3R5cGUnKSAmJlxuICAgICAgICAhKHNraXBFcnJvclByb3BzICYmIChrZXkgPT0gJ21lc3NhZ2UnIHx8IGtleSA9PSAnbmFtZScpKSAmJlxuICAgICAgICAhKHNraXBJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSAmJlxuICAgICAgICAhKGtleSA9PSAnY29uc3RydWN0b3InICYmIChpc1Byb3RvIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICBpZiAoc3VwcG9ydC5ub25FbnVtU2hhZG93cyAmJiBvYmplY3QgIT09IG9iamVjdFByb3RvKSB7XG4gICAgdmFyIHRhZyA9IG9iamVjdCA9PT0gc3RyaW5nUHJvdG8gPyBzdHJpbmdUYWcgOiAob2JqZWN0ID09PSBlcnJvclByb3RvID8gZXJyb3JUYWcgOiBvYmpUb1N0cmluZy5jYWxsKG9iamVjdCkpLFxuICAgICAgICBub25FbnVtcyA9IG5vbkVudW1Qcm9wc1t0YWddIHx8IG5vbkVudW1Qcm9wc1tvYmplY3RUYWddO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcpIHtcbiAgICAgIHByb3RvID0gb2JqZWN0UHJvdG87XG4gICAgfVxuICAgIGxlbmd0aCA9IHNoYWRvd1Byb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGtleSA9IHNoYWRvd1Byb3BzW2xlbmd0aF07XG4gICAgICB2YXIgbm9uRW51bSA9IG5vbkVudW1zW2tleV07XG4gICAgICBpZiAoIShpc1Byb3RvICYmIG5vbkVudW0pICYmXG4gICAgICAgICAgKG5vbkVudW0gPyBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSA6IG9iamVjdFtrZXldICE9PSBwcm90b1trZXldKSkge1xuICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNJbjtcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgdGhlIGtleS12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGAsXG4gKiBlLmcuIGBbW2tleTEsIHZhbHVlMV0sIFtrZXkyLCB2YWx1ZTJdXWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGtleS12YWx1ZSBwYWlycy5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5wYWlycyh7ICdiYXJuZXknOiAzNiwgJ2ZyZWQnOiA0MCB9KTtcbiAqIC8vID0+IFtbJ2Jhcm5leScsIDM2XSwgWydmcmVkJywgNDBdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBwYWlycyhvYmplY3QpIHtcbiAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHByb3BzID0ga2V5cyhvYmplY3QpLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgcmVzdWx0W2luZGV4XSA9IFtrZXksIG9iamVjdFtrZXldXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhaXJzO1xuIiwidmFyIGJhc2VWYWx1ZXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlVmFsdWVzJyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8udmFsdWVzKG5ldyBGb28pO1xuICogLy8gPT4gWzEsIDJdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy52YWx1ZXMoJ2hpJyk7XG4gKiAvLyA9PiBbJ2gnLCAnaSddXG4gKi9cbmZ1bmN0aW9uIHZhbHVlcyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHZhbHVlcztcbiIsIi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSxcbiAgICBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxuICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlLFxuICAgIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIEFuIG9iamVjdCBlbnZpcm9ubWVudCBmZWF0dXJlIGZsYWdzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAdHlwZSBPYmplY3RcbiAqL1xudmFyIHN1cHBvcnQgPSB7fTtcblxuKGZ1bmN0aW9uKHgpIHtcbiAgdmFyIEN0b3IgPSBmdW5jdGlvbigpIHsgdGhpcy54ID0geDsgfSxcbiAgICAgIG9iamVjdCA9IHsgJzAnOiB4LCAnbGVuZ3RoJzogeCB9LFxuICAgICAgcHJvcHMgPSBbXTtcblxuICBDdG9yLnByb3RvdHlwZSA9IHsgJ3ZhbHVlT2YnOiB4LCAneSc6IHggfTtcbiAgZm9yICh2YXIga2V5IGluIG5ldyBDdG9yKSB7IHByb3BzLnB1c2goa2V5KTsgfVxuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYG5hbWVgIG9yIGBtZXNzYWdlYCBwcm9wZXJ0aWVzIG9mIGBFcnJvci5wcm90b3R5cGVgIGFyZVxuICAgKiBlbnVtZXJhYmxlIGJ5IGRlZmF1bHQgKElFIDwgOSwgU2FmYXJpIDwgNS4xKS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LmVudW1FcnJvclByb3BzID0gcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChlcnJvclByb3RvLCAnbWVzc2FnZScpIHx8XG4gICAgcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChlcnJvclByb3RvLCAnbmFtZScpO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYHByb3RvdHlwZWAgcHJvcGVydGllcyBhcmUgZW51bWVyYWJsZSBieSBkZWZhdWx0LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMy42LCBPcGVyYSA+IDkuNTAgLSBPcGVyYSA8IDExLjYwLCBhbmQgU2FmYXJpIDwgNS4xXG4gICAqIChpZiB0aGUgcHJvdG90eXBlIG9yIGEgcHJvcGVydHkgb24gdGhlIHByb3RvdHlwZSBoYXMgYmVlbiBzZXQpXG4gICAqIGluY29ycmVjdGx5IHNldCB0aGUgYFtbRW51bWVyYWJsZV1dYCB2YWx1ZSBvZiBhIGZ1bmN0aW9uJ3MgYHByb3RvdHlwZWBcbiAgICogcHJvcGVydHkgdG8gYHRydWVgLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgXy5zdXBwb3J0XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICovXG4gIHN1cHBvcnQuZW51bVByb3RvdHlwZXMgPSBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKEN0b3IsICdwcm90b3R5cGUnKTtcblxuICAvKipcbiAgICogRGV0ZWN0IGlmIHByb3BlcnRpZXMgc2hhZG93aW5nIHRob3NlIG9uIGBPYmplY3QucHJvdG90eXBlYCBhcmUgbm9uLWVudW1lcmFibGUuXG4gICAqXG4gICAqIEluIElFIDwgOSBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgc2hhZG93aW5nIG5vbi1lbnVtZXJhYmxlIG9uZXMsXG4gICAqIGFyZSBtYWRlIG5vbi1lbnVtZXJhYmxlIGFzIHdlbGwgKGEuay5hIHRoZSBKU2NyaXB0IGBbW0RvbnRFbnVtXV1gIGJ1ZykuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5ub25FbnVtU2hhZG93cyA9ICEvdmFsdWVPZi8udGVzdChwcm9wcyk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBvd24gcHJvcGVydGllcyBhcmUgaXRlcmF0ZWQgYWZ0ZXIgaW5oZXJpdGVkIHByb3BlcnRpZXMgKElFIDwgOSkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5vd25MYXN0ID0gcHJvcHNbMF0gIT0gJ3gnO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYEFycmF5I3NoaWZ0YCBhbmQgYEFycmF5I3NwbGljZWAgYXVnbWVudCBhcnJheS1saWtlIG9iamVjdHNcbiAgICogY29ycmVjdGx5LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMTAsIGNvbXBhdGliaWxpdHkgbW9kZXMgb2YgSUUgOCwgYW5kIElFIDwgOSBoYXZlIGJ1Z2d5IEFycmF5XG4gICAqIGBzaGlmdCgpYCBhbmQgYHNwbGljZSgpYCBmdW5jdGlvbnMgdGhhdCBmYWlsIHRvIHJlbW92ZSB0aGUgbGFzdCBlbGVtZW50LFxuICAgKiBgdmFsdWVbMF1gLCBvZiBhcnJheS1saWtlIG9iamVjdHMgZXZlbiB0aG91Z2ggdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgaXNcbiAgICogc2V0IHRvIGAwYC4gVGhlIGBzaGlmdCgpYCBtZXRob2QgaXMgYnVnZ3kgaW4gY29tcGF0aWJpbGl0eSBtb2RlcyBvZiBJRSA4LFxuICAgKiB3aGlsZSBgc3BsaWNlKClgIGlzIGJ1Z2d5IHJlZ2FyZGxlc3Mgb2YgbW9kZSBpbiBJRSA8IDkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5zcGxpY2VPYmplY3RzID0gKHNwbGljZS5jYWxsKG9iamVjdCwgMCwgMSksICFvYmplY3RbMF0pO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgbGFjayBvZiBzdXBwb3J0IGZvciBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgYnkgaW5kZXguXG4gICAqXG4gICAqIElFIDwgOCBjYW4ndCBhY2Nlc3MgY2hhcmFjdGVycyBieSBpbmRleC4gSUUgOCBjYW4gb25seSBhY2Nlc3MgY2hhcmFjdGVyc1xuICAgKiBieSBpbmRleCBvbiBzdHJpbmcgbGl0ZXJhbHMsIG5vdCBzdHJpbmcgb2JqZWN0cy5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LnVuaW5kZXhlZENoYXJzID0gKCd4J1swXSArIE9iamVjdCgneCcpWzBdKSAhPSAneHgnO1xufSgxLCAwKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gc3VwcG9ydDtcbiIsIi8qKlxuICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgcHJvdmlkZWQgdG8gaXQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5pZGVudGl0eShvYmplY3QpID09PSBvYmplY3Q7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlkZW50aXR5KHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpZGVudGl0eTtcbiIsIi8qKlxuICogQSBuby1vcGVyYXRpb24gZnVuY3Rpb24gdGhhdCByZXR1cm5zIGB1bmRlZmluZWRgIHJlZ2FyZGxlc3Mgb2YgdGhlXG4gKiBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5ub29wKG9iamVjdCkgPT09IHVuZGVmaW5lZDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gbm9vcCgpIHtcbiAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBub29wO1xuIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VQcm9wZXJ0eScpLFxuICAgIGJhc2VQcm9wZXJ0eURlZXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlUHJvcGVydHlEZWVwJyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0tleScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIGF0IGBwYXRoYCBvbiBhXG4gKiBnaXZlbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3RzID0gW1xuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAyIH0gfSB9LFxuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAxIH0gfSB9XG4gKiBdO1xuICpcbiAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYi5jJykpO1xuICogLy8gPT4gWzIsIDFdXG4gKlxuICogXy5wbHVjayhfLnNvcnRCeShvYmplY3RzLCBfLnByb3BlcnR5KFsnYScsICdiJywgJ2MnXSkpLCAnYS5iLmMnKTtcbiAqIC8vID0+IFsxLCAyXVxuICovXG5mdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eShwYXRoKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcHJvcGVydHk7XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuLy8gdmltOnRzPTQ6c3RzPTQ6c3c9NDpcbi8qIVxuICpcbiAqIENvcHlyaWdodCAyMDA5LTIwMTIgS3JpcyBLb3dhbCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVFxuICogbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9yYXcvbWFzdGVyL0xJQ0VOU0VcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IFR5bGVyIENsb3NlXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDA5IFR5bGVyIENsb3NlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUIFggbGljZW5zZSBmb3VuZFxuICogYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5odG1sXG4gKiBGb3JrZWQgYXQgcmVmX3NlbmQuanMgdmVyc2lvbjogMjAwOS0wNS0xMVxuICpcbiAqIFdpdGggcGFydHMgYnkgTWFyayBNaWxsZXJcbiAqIENvcHlyaWdodCAoQykgMjAxMSBHb29nbGUgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4oZnVuY3Rpb24gKGRlZmluaXRpb24pIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIC8vIFRoaXMgZmlsZSB3aWxsIGZ1bmN0aW9uIHByb3Blcmx5IGFzIGEgPHNjcmlwdD4gdGFnLCBvciBhIG1vZHVsZVxuICAgIC8vIHVzaW5nIENvbW1vbkpTIGFuZCBOb2RlSlMgb3IgUmVxdWlyZUpTIG1vZHVsZSBmb3JtYXRzLiAgSW5cbiAgICAvLyBDb21tb24vTm9kZS9SZXF1aXJlSlMsIHRoZSBtb2R1bGUgZXhwb3J0cyB0aGUgUSBBUEkgYW5kIHdoZW5cbiAgICAvLyBleGVjdXRlZCBhcyBhIHNpbXBsZSA8c2NyaXB0PiwgaXQgY3JlYXRlcyBhIFEgZ2xvYmFsIGluc3RlYWQuXG5cbiAgICAvLyBNb250YWdlIFJlcXVpcmVcbiAgICBpZiAodHlwZW9mIGJvb3RzdHJhcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGJvb3RzdHJhcChcInByb21pc2VcIiwgZGVmaW5pdGlvbik7XG5cbiAgICAvLyBDb21tb25KU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcblxuICAgIC8vIFJlcXVpcmVKU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGRlZmluaXRpb24pO1xuXG4gICAgLy8gU0VTIChTZWN1cmUgRWNtYVNjcmlwdClcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKCFzZXMub2soKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VzLm1ha2VRID0gZGVmaW5pdGlvbjtcbiAgICAgICAgfVxuXG4gICAgLy8gPHNjcmlwdD5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgLy8gUHJlZmVyIHdpbmRvdyBvdmVyIHNlbGYgZm9yIGFkZC1vbiBzY3JpcHRzLiBVc2Ugc2VsZiBmb3JcbiAgICAgICAgLy8gbm9uLXdpbmRvd2VkIGNvbnRleHRzLlxuICAgICAgICB2YXIgZ2xvYmFsID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHNlbGY7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBgd2luZG93YCBvYmplY3QsIHNhdmUgdGhlIHByZXZpb3VzIFEgZ2xvYmFsXG4gICAgICAgIC8vIGFuZCBpbml0aWFsaXplIFEgYXMgYSBnbG9iYWwuXG4gICAgICAgIHZhciBwcmV2aW91c1EgPSBnbG9iYWwuUTtcbiAgICAgICAgZ2xvYmFsLlEgPSBkZWZpbml0aW9uKCk7XG5cbiAgICAgICAgLy8gQWRkIGEgbm9Db25mbGljdCBmdW5jdGlvbiBzbyBRIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlXG4gICAgICAgIC8vIGdsb2JhbCBuYW1lc3BhY2UuXG4gICAgICAgIGdsb2JhbC5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnbG9iYWwuUSA9IHByZXZpb3VzUTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnZpcm9ubWVudCB3YXMgbm90IGFudGljaXBhdGVkIGJ5IFEuIFBsZWFzZSBmaWxlIGEgYnVnLlwiKTtcbiAgICB9XG5cbn0pKGZ1bmN0aW9uICgpIHtcblwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzU3RhY2tzID0gZmFsc2U7XG50cnkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufSBjYXRjaCAoZSkge1xuICAgIGhhc1N0YWNrcyA9ICEhZS5zdGFjaztcbn1cblxuLy8gQWxsIGNvZGUgYWZ0ZXIgdGhpcyBwb2ludCB3aWxsIGJlIGZpbHRlcmVkIGZyb20gc3RhY2sgdHJhY2VzIHJlcG9ydGVkXG4vLyBieSBRLlxudmFyIHFTdGFydGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xudmFyIHFGaWxlTmFtZTtcblxuLy8gc2hpbXNcblxuLy8gdXNlZCBmb3IgZmFsbGJhY2sgaW4gXCJhbGxSZXNvbHZlZFwiXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgcG9zc2libGUgbWVhbnMgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gYSBmdXR1cmUgdHVyblxuLy8gb2YgdGhlIGV2ZW50IGxvb3AuXG52YXIgbmV4dFRpY2sgPShmdW5jdGlvbiAoKSB7XG4gICAgLy8gbGlua2VkIGxpc3Qgb2YgdGFza3MgKHNpbmdsZSwgd2l0aCBoZWFkIG5vZGUpXG4gICAgdmFyIGhlYWQgPSB7dGFzazogdm9pZCAwLCBuZXh0OiBudWxsfTtcbiAgICB2YXIgdGFpbCA9IGhlYWQ7XG4gICAgdmFyIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlcXVlc3RUaWNrID0gdm9pZCAwO1xuICAgIHZhciBpc05vZGVKUyA9IGZhbHNlO1xuICAgIC8vIHF1ZXVlIGZvciBsYXRlIHRhc2tzLCB1c2VkIGJ5IHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmdcbiAgICB2YXIgbGF0ZXJRdWV1ZSA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgICAgIC8qIGpzaGludCBsb29wZnVuYzogdHJ1ZSAqL1xuICAgICAgICB2YXIgdGFzaywgZG9tYWluO1xuXG4gICAgICAgIHdoaWxlIChoZWFkLm5leHQpIHtcbiAgICAgICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICAgICAgICB0YXNrID0gaGVhZC50YXNrO1xuICAgICAgICAgICAgaGVhZC50YXNrID0gdm9pZCAwO1xuICAgICAgICAgICAgZG9tYWluID0gaGVhZC5kb21haW47XG5cbiAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICBoZWFkLmRvbWFpbiA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pO1xuXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGxhdGVyUXVldWUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXNrID0gbGF0ZXJRdWV1ZS5wb3AoKTtcbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrKTtcbiAgICAgICAgfVxuICAgICAgICBmbHVzaGluZyA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBydW5zIGEgc2luZ2xlIGZ1bmN0aW9uIGluIHRoZSBhc3luYyBxdWV1ZVxuICAgIGZ1bmN0aW9uIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRhc2soKTtcblxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNOb2RlSlMpIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBub2RlLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBjb25zaWRlcmVkIGZhdGFsIGVycm9ycy5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIHN5bmNocm9ub3VzbHkgdG8gaW50ZXJydXB0IGZsdXNoaW5nIVxuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIGNvbnRpbnVhdGlvbiBpZiB0aGUgdW5jYXVnaHQgZXhjZXB0aW9uIGlzIHN1cHByZXNzZWRcbiAgICAgICAgICAgICAgICAvLyBsaXN0ZW5pbmcgXCJ1bmNhdWdodEV4Y2VwdGlvblwiIGV2ZW50cyAoYXMgZG9tYWlucyBkb2VzKS5cbiAgICAgICAgICAgICAgICAvLyBDb250aW51ZSBpbiBuZXh0IGV2ZW50IHRvIGF2b2lkIHRpY2sgcmVjdXJzaW9uLlxuICAgICAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEluIGJyb3dzZXJzLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBub3QgZmF0YWwuXG4gICAgICAgICAgICAgICAgLy8gUmUtdGhyb3cgdGhlbSBhc3luY2hyb25vdXNseSB0byBhdm9pZCBzbG93LWRvd25zLlxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5leHRUaWNrID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgdGFpbCA9IHRhaWwubmV4dCA9IHtcbiAgICAgICAgICAgIHRhc2s6IHRhc2ssXG4gICAgICAgICAgICBkb21haW46IGlzTm9kZUpTICYmIHByb2Nlc3MuZG9tYWluLFxuICAgICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghZmx1c2hpbmcpIHtcbiAgICAgICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHByb2Nlc3MudG9TdHJpbmcoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIgJiYgcHJvY2Vzcy5uZXh0VGljaykge1xuICAgICAgICAvLyBFbnN1cmUgUSBpcyBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudCwgd2l0aCBhIGBwcm9jZXNzLm5leHRUaWNrYC5cbiAgICAgICAgLy8gVG8gc2VlIHRocm91Z2ggZmFrZSBOb2RlIGVudmlyb25tZW50czpcbiAgICAgICAgLy8gKiBNb2NoYSB0ZXN0IHJ1bm5lciAtIGV4cG9zZXMgYSBgcHJvY2Vzc2AgZ2xvYmFsIHdpdGhvdXQgYSBgbmV4dFRpY2tgXG4gICAgICAgIC8vICogQnJvd3NlcmlmeSAtIGV4cG9zZXMgYSBgcHJvY2Vzcy5uZXhUaWNrYCBmdW5jdGlvbiB0aGF0IHVzZXNcbiAgICAgICAgLy8gICBgc2V0VGltZW91dGAuIEluIHRoaXMgY2FzZSBgc2V0SW1tZWRpYXRlYCBpcyBwcmVmZXJyZWQgYmVjYXVzZVxuICAgICAgICAvLyAgICBpdCBpcyBmYXN0ZXIuIEJyb3dzZXJpZnkncyBgcHJvY2Vzcy50b1N0cmluZygpYCB5aWVsZHNcbiAgICAgICAgLy8gICBcIltvYmplY3QgT2JqZWN0XVwiLCB3aGlsZSBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudFxuICAgICAgICAvLyAgIGBwcm9jZXNzLm5leHRUaWNrKClgIHlpZWxkcyBcIltvYmplY3QgcHJvY2Vzc11cIi5cbiAgICAgICAgaXNOb2RlSlMgPSB0cnVlO1xuXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBJbiBJRTEwLCBOb2RlLmpzIDAuOSssIG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9Ob2JsZUpTL3NldEltbWVkaWF0ZVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBzZXRJbW1lZGlhdGUuYmluZCh3aW5kb3csIGZsdXNoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbHVzaCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgLy8gQXQgbGVhc3QgU2FmYXJpIFZlcnNpb24gNi4wLjUgKDg1MzYuMzAuMSkgaW50ZXJtaXR0ZW50bHkgY2Fubm90IGNyZWF0ZVxuICAgICAgICAvLyB3b3JraW5nIG1lc3NhZ2UgcG9ydHMgdGhlIGZpcnN0IHRpbWUgYSBwYWdlIGxvYWRzLlxuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gcmVxdWVzdFBvcnRUaWNrO1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmbHVzaDtcbiAgICAgICAgICAgIGZsdXNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciByZXF1ZXN0UG9ydFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBPcGVyYSByZXF1aXJlcyB1cyB0byBwcm92aWRlIGEgbWVzc2FnZSBwYXlsb2FkLCByZWdhcmRsZXNzIG9mXG4gICAgICAgICAgICAvLyB3aGV0aGVyIHdlIHVzZSBpdC5cbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgICAgIH07XG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICByZXF1ZXN0UG9ydFRpY2soKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9sZCBicm93c2Vyc1xuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBydW5zIGEgdGFzayBhZnRlciBhbGwgb3RoZXIgdGFza3MgaGF2ZSBiZWVuIHJ1blxuICAgIC8vIHRoaXMgaXMgdXNlZnVsIGZvciB1bmhhbmRsZWQgcmVqZWN0aW9uIHRyYWNraW5nIHRoYXQgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgYWxsIGB0aGVuYGQgdGFza3MgaGF2ZSBiZWVuIHJ1bi5cbiAgICBuZXh0VGljay5ydW5BZnRlciA9IGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgIGxhdGVyUXVldWUucHVzaCh0YXNrKTtcbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIG5leHRUaWNrO1xufSkoKTtcblxuLy8gQXR0ZW1wdCB0byBtYWtlIGdlbmVyaWNzIHNhZmUgaW4gdGhlIGZhY2Ugb2YgZG93bnN0cmVhbVxuLy8gbW9kaWZpY2F0aW9ucy5cbi8vIFRoZXJlIGlzIG5vIHNpdHVhdGlvbiB3aGVyZSB0aGlzIGlzIG5lY2Vzc2FyeS5cbi8vIElmIHlvdSBuZWVkIGEgc2VjdXJpdHkgZ3VhcmFudGVlLCB0aGVzZSBwcmltb3JkaWFscyBuZWVkIHRvIGJlXG4vLyBkZWVwbHkgZnJvemVuIGFueXdheSwgYW5kIGlmIHlvdSBkb27igJl0IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsXG4vLyB0aGlzIGlzIGp1c3QgcGxhaW4gcGFyYW5vaWQuXG4vLyBIb3dldmVyLCB0aGlzICoqbWlnaHQqKiBoYXZlIHRoZSBuaWNlIHNpZGUtZWZmZWN0IG9mIHJlZHVjaW5nIHRoZSBzaXplIG9mXG4vLyB0aGUgbWluaWZpZWQgY29kZSBieSByZWR1Y2luZyB4LmNhbGwoKSB0byBtZXJlbHkgeCgpXG4vLyBTZWUgTWFyayBNaWxsZXLigJlzIGV4cGxhbmF0aW9uIG9mIHdoYXQgdGhpcyBkb2VzLlxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9Y29udmVudGlvbnM6c2FmZV9tZXRhX3Byb2dyYW1taW5nXG52YXIgY2FsbCA9IEZ1bmN0aW9uLmNhbGw7XG5mdW5jdGlvbiB1bmN1cnJ5VGhpcyhmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNhbGwuYXBwbHkoZiwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuLy8gVGhpcyBpcyBlcXVpdmFsZW50LCBidXQgc2xvd2VyOlxuLy8gdW5jdXJyeVRoaXMgPSBGdW5jdGlvbl9iaW5kLmJpbmQoRnVuY3Rpb25fYmluZC5jYWxsKTtcbi8vIGh0dHA6Ly9qc3BlcmYuY29tL3VuY3Vycnl0aGlzXG5cbnZhciBhcnJheV9zbGljZSA9IHVuY3VycnlUaGlzKEFycmF5LnByb3RvdHlwZS5zbGljZSk7XG5cbnZhciBhcnJheV9yZWR1Y2UgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUucmVkdWNlIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgYmFzaXMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgICAgICAvLyBjb25jZXJuaW5nIHRoZSBpbml0aWFsIHZhbHVlLCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyBzZWVrIHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXksIGFjY291bnRpbmdcbiAgICAgICAgICAgIC8vIGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCBpcyBpcyBhIHNwYXJzZSBhcnJheVxuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGJhc2lzID0gdGhpc1tpbmRleCsrXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgrK2luZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAoMSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVkdWNlXG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhlIGFycmF5IGlzIHNwYXJzZVxuICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICBiYXNpcyA9IGNhbGxiYWNrKGJhc2lzLCB0aGlzW2luZGV4XSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNpcztcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfaW5kZXhPZiA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIHx8IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBub3QgYSB2ZXJ5IGdvb2Qgc2hpbSwgYnV0IGdvb2QgZW5vdWdoIGZvciBvdXIgb25lIHVzZSBvZiBpdFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfbWFwID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLm1hcCB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGNvbGxlY3QgPSBbXTtcbiAgICAgICAgYXJyYXlfcmVkdWNlKHNlbGYsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgY29sbGVjdC5wdXNoKGNhbGxiYWNrLmNhbGwodGhpc3AsIHZhbHVlLCBpbmRleCwgc2VsZikpO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICByZXR1cm4gY29sbGVjdDtcbiAgICB9XG4pO1xuXG52YXIgb2JqZWN0X2NyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gKHByb3RvdHlwZSkge1xuICAgIGZ1bmN0aW9uIFR5cGUoKSB7IH1cbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3IFR5cGUoKTtcbn07XG5cbnZhciBvYmplY3RfaGFzT3duUHJvcGVydHkgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcblxudmFyIG9iamVjdF9rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0X2hhc093blByb3BlcnR5KG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgb2JqZWN0X3RvU3RyaW5nID0gdW5jdXJyeVRoaXMoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBPYmplY3QodmFsdWUpO1xufVxuXG4vLyBnZW5lcmF0b3IgcmVsYXRlZCBzaGltc1xuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgZnVuY3Rpb24gb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuZnVuY3Rpb24gaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikge1xuICAgIHJldHVybiAoXG4gICAgICAgIG9iamVjdF90b1N0cmluZyhleGNlcHRpb24pID09PSBcIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIiB8fFxuICAgICAgICBleGNlcHRpb24gaW5zdGFuY2VvZiBRUmV0dXJuVmFsdWVcbiAgICApO1xufVxuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgaGVscGVyIGFuZCBRLnJldHVybiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpblxuLy8gU3BpZGVyTW9ua2V5LlxudmFyIFFSZXR1cm5WYWx1ZTtcbmlmICh0eXBlb2YgUmV0dXJuVmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBSZXR1cm5WYWx1ZTtcbn0gZWxzZSB7XG4gICAgUVJldHVyblZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9O1xufVxuXG4vLyBsb25nIHN0YWNrIHRyYWNlc1xuXG52YXIgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgPSBcIkZyb20gcHJldmlvdXMgZXZlbnQ6XCI7XG5cbmZ1bmN0aW9uIG1ha2VTdGFja1RyYWNlTG9uZyhlcnJvciwgcHJvbWlzZSkge1xuICAgIC8vIElmIHBvc3NpYmxlLCB0cmFuc2Zvcm0gdGhlIGVycm9yIHN0YWNrIHRyYWNlIGJ5IHJlbW92aW5nIE5vZGUgYW5kIFFcbiAgICAvLyBjcnVmdCwgdGhlbiBjb25jYXRlbmF0aW5nIHdpdGggdGhlIHN0YWNrIHRyYWNlIG9mIGBwcm9taXNlYC4gU2VlICM1Ny5cbiAgICBpZiAoaGFzU3RhY2tzICYmXG4gICAgICAgIHByb21pc2Uuc3RhY2sgJiZcbiAgICAgICAgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIGVycm9yICE9PSBudWxsICYmXG4gICAgICAgIGVycm9yLnN0YWNrICYmXG4gICAgICAgIGVycm9yLnN0YWNrLmluZGV4T2YoU1RBQ0tfSlVNUF9TRVBBUkFUT1IpID09PSAtMVxuICAgICkge1xuICAgICAgICB2YXIgc3RhY2tzID0gW107XG4gICAgICAgIGZvciAodmFyIHAgPSBwcm9taXNlOyAhIXA7IHAgPSBwLnNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKHAuc3RhY2spIHtcbiAgICAgICAgICAgICAgICBzdGFja3MudW5zaGlmdChwLnN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFja3MudW5zaGlmdChlcnJvci5zdGFjayk7XG5cbiAgICAgICAgdmFyIGNvbmNhdGVkU3RhY2tzID0gc3RhY2tzLmpvaW4oXCJcXG5cIiArIFNUQUNLX0pVTVBfU0VQQVJBVE9SICsgXCJcXG5cIik7XG4gICAgICAgIGVycm9yLnN0YWNrID0gZmlsdGVyU3RhY2tTdHJpbmcoY29uY2F0ZWRTdGFja3MpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZmlsdGVyU3RhY2tTdHJpbmcoc3RhY2tTdHJpbmcpIHtcbiAgICB2YXIgbGluZXMgPSBzdGFja1N0cmluZy5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgZGVzaXJlZExpbmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuXG4gICAgICAgIGlmICghaXNJbnRlcm5hbEZyYW1lKGxpbmUpICYmICFpc05vZGVGcmFtZShsaW5lKSAmJiBsaW5lKSB7XG4gICAgICAgICAgICBkZXNpcmVkTGluZXMucHVzaChsaW5lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzaXJlZExpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIGlzTm9kZUZyYW1lKHN0YWNrTGluZSkge1xuICAgIHJldHVybiBzdGFja0xpbmUuaW5kZXhPZihcIihtb2R1bGUuanM6XCIpICE9PSAtMSB8fFxuICAgICAgICAgICBzdGFja0xpbmUuaW5kZXhPZihcIihub2RlLmpzOlwiKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpIHtcbiAgICAvLyBOYW1lZCBmdW5jdGlvbnM6IFwiYXQgZnVuY3Rpb25OYW1lIChmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlcilcIlxuICAgIC8vIEluIElFMTAgZnVuY3Rpb24gbmFtZSBjYW4gaGF2ZSBzcGFjZXMgKFwiQW5vbnltb3VzIGZ1bmN0aW9uXCIpIE9fb1xuICAgIHZhciBhdHRlbXB0MSA9IC9hdCAuKyBcXCgoLispOihcXGQrKTooPzpcXGQrKVxcKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDEpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0MVsxXSwgTnVtYmVyKGF0dGVtcHQxWzJdKV07XG4gICAgfVxuXG4gICAgLy8gQW5vbnltb3VzIGZ1bmN0aW9uczogXCJhdCBmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQyID0gL2F0IChbXiBdKyk6KFxcZCspOig/OlxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mikge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQyWzFdLCBOdW1iZXIoYXR0ZW1wdDJbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBGaXJlZm94IHN0eWxlOiBcImZ1bmN0aW9uQGZpbGVuYW1lOmxpbmVOdW1iZXIgb3IgQGZpbGVuYW1lOmxpbmVOdW1iZXJcIlxuICAgIHZhciBhdHRlbXB0MyA9IC8uKkAoLispOihcXGQrKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDMpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0M1sxXSwgTnVtYmVyKGF0dGVtcHQzWzJdKV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0ludGVybmFsRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgdmFyIGZpbGVOYW1lQW5kTGluZU51bWJlciA9IGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpO1xuXG4gICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBmaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICB2YXIgbGluZU51bWJlciA9IGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcblxuICAgIHJldHVybiBmaWxlTmFtZSA9PT0gcUZpbGVOYW1lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPj0gcVN0YXJ0aW5nTGluZSAmJlxuICAgICAgICBsaW5lTnVtYmVyIDw9IHFFbmRpbmdMaW5lO1xufVxuXG4vLyBkaXNjb3ZlciBvd24gZmlsZSBuYW1lIGFuZCBsaW5lIG51bWJlciByYW5nZSBmb3IgZmlsdGVyaW5nIHN0YWNrXG4vLyB0cmFjZXNcbmZ1bmN0aW9uIGNhcHR1cmVMaW5lKCkge1xuICAgIGlmICghaGFzU3RhY2tzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZhciBsaW5lcyA9IGUuc3RhY2suc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIHZhciBmaXJzdExpbmUgPSBsaW5lc1swXS5pbmRleE9mKFwiQFwiKSA+IDAgPyBsaW5lc1sxXSA6IGxpbmVzWzJdO1xuICAgICAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKGZpcnN0TGluZSk7XG4gICAgICAgIGlmICghZmlsZU5hbWVBbmRMaW5lTnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBxRmlsZU5hbWUgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMF07XG4gICAgICAgIHJldHVybiBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGUoY2FsbGJhY2ssIG5hbWUsIGFsdGVybmF0aXZlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS53YXJuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihuYW1lICsgXCIgaXMgZGVwcmVjYXRlZCwgdXNlIFwiICsgYWx0ZXJuYXRpdmUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgIFwiIGluc3RlYWQuXCIsIG5ldyBFcnJvcihcIlwiKS5zdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGNhbGxiYWNrLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG5cbi8vIGVuZCBvZiBzaGltc1xuLy8gYmVnaW5uaW5nIG9mIHJlYWwgd29ya1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLCBwYXNzZXMgcHJvbWlzZXMgdGhyb3VnaCwgb3JcbiAqIGNvZXJjZXMgcHJvbWlzZXMgZnJvbSBkaWZmZXJlbnQgc3lzdGVtcy5cbiAqIEBwYXJhbSB2YWx1ZSBpbW1lZGlhdGUgcmVmZXJlbmNlIG9yIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gUSh2YWx1ZSkge1xuICAgIC8vIElmIHRoZSBvYmplY3QgaXMgYWxyZWFkeSBhIFByb21pc2UsIHJldHVybiBpdCBkaXJlY3RseS4gIFRoaXMgZW5hYmxlc1xuICAgIC8vIHRoZSByZXNvbHZlIGZ1bmN0aW9uIHRvIGJvdGggYmUgdXNlZCB0byBjcmVhdGVkIHJlZmVyZW5jZXMgZnJvbSBvYmplY3RzLFxuICAgIC8vIGJ1dCB0byB0b2xlcmFibHkgY29lcmNlIG5vbi1wcm9taXNlcyB0byBwcm9taXNlcy5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBhc3NpbWlsYXRlIHRoZW5hYmxlc1xuICAgIGlmIChpc1Byb21pc2VBbGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGNvZXJjZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGwodmFsdWUpO1xuICAgIH1cbn1cblEucmVzb2x2ZSA9IFE7XG5cbi8qKlxuICogUGVyZm9ybXMgYSB0YXNrIGluIGEgZnV0dXJlIHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0YXNrXG4gKi9cblEubmV4dFRpY2sgPSBuZXh0VGljaztcblxuLyoqXG4gKiBDb250cm9scyB3aGV0aGVyIG9yIG5vdCBsb25nIHN0YWNrIHRyYWNlcyB3aWxsIGJlIG9uXG4gKi9cblEubG9uZ1N0YWNrU3VwcG9ydCA9IGZhbHNlO1xuXG4vLyBlbmFibGUgbG9uZyBzdGFja3MgaWYgUV9ERUJVRyBpcyBzZXRcbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzICYmIHByb2Nlc3MuZW52ICYmIHByb2Nlc3MuZW52LlFfREVCVUcpIHtcbiAgICBRLmxvbmdTdGFja1N1cHBvcnQgPSB0cnVlO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSB7cHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0fSBvYmplY3QuXG4gKlxuICogYHJlc29sdmVgIGlzIGEgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggYSBtb3JlIHJlc29sdmVkIHZhbHVlIGZvciB0aGVcbiAqIHByb21pc2UuIFRvIGZ1bGZpbGwgdGhlIHByb21pc2UsIGludm9rZSBgcmVzb2x2ZWAgd2l0aCBhbnkgdmFsdWUgdGhhdCBpc1xuICogbm90IGEgdGhlbmFibGUuIFRvIHJlamVjdCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGEgcmVqZWN0ZWRcbiAqIHRoZW5hYmxlLCBvciBpbnZva2UgYHJlamVjdGAgd2l0aCB0aGUgcmVhc29uIGRpcmVjdGx5LiBUbyByZXNvbHZlIHRoZVxuICogcHJvbWlzZSB0byBhbm90aGVyIHRoZW5hYmxlLCB0aHVzIHB1dHRpbmcgaXQgaW4gdGhlIHNhbWUgc3RhdGUsIGludm9rZVxuICogYHJlc29sdmVgIHdpdGggdGhhdCBvdGhlciB0aGVuYWJsZS5cbiAqL1xuUS5kZWZlciA9IGRlZmVyO1xuZnVuY3Rpb24gZGVmZXIoKSB7XG4gICAgLy8gaWYgXCJtZXNzYWdlc1wiIGlzIGFuIFwiQXJyYXlcIiwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvbWlzZSBoYXMgbm90IHlldFxuICAgIC8vIGJlZW4gcmVzb2x2ZWQuICBJZiBpdCBpcyBcInVuZGVmaW5lZFwiLCBpdCBoYXMgYmVlbiByZXNvbHZlZC4gIEVhY2hcbiAgICAvLyBlbGVtZW50IG9mIHRoZSBtZXNzYWdlcyBhcnJheSBpcyBpdHNlbGYgYW4gYXJyYXkgb2YgY29tcGxldGUgYXJndW1lbnRzIHRvXG4gICAgLy8gZm9yd2FyZCB0byB0aGUgcmVzb2x2ZWQgcHJvbWlzZS4gIFdlIGNvZXJjZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSB0byBhXG4gICAgLy8gcHJvbWlzZSB1c2luZyB0aGUgYHJlc29sdmVgIGZ1bmN0aW9uIGJlY2F1c2UgaXQgaGFuZGxlcyBib3RoIGZ1bGx5XG4gICAgLy8gbm9uLXRoZW5hYmxlIHZhbHVlcyBhbmQgb3RoZXIgdGhlbmFibGVzIGdyYWNlZnVsbHkuXG4gICAgdmFyIG1lc3NhZ2VzID0gW10sIHByb2dyZXNzTGlzdGVuZXJzID0gW10sIHJlc29sdmVkUHJvbWlzZTtcblxuICAgIHZhciBkZWZlcnJlZCA9IG9iamVjdF9jcmVhdGUoZGVmZXIucHJvdG90eXBlKTtcbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIG9wZXJhbmRzKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICBtZXNzYWdlcy5wdXNoKGFyZ3MpO1xuICAgICAgICAgICAgaWYgKG9wID09PSBcIndoZW5cIiAmJiBvcGVyYW5kc1sxXSkgeyAvLyBwcm9ncmVzcyBvcGVyYW5kXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChvcGVyYW5kc1sxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFByb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KHJlc29sdmVkUHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZFxuICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmVhcmVyVmFsdWUgPSBuZWFyZXIocmVzb2x2ZWRQcm9taXNlKTtcbiAgICAgICAgaWYgKGlzUHJvbWlzZShuZWFyZXJWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5lYXJlclZhbHVlOyAvLyBzaG9ydGVuIGNoYWluXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5lYXJlclZhbHVlO1xuICAgIH07XG5cbiAgICBwcm9taXNlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghcmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJwZW5kaW5nXCIgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZWRQcm9taXNlLmluc3BlY3QoKTtcbiAgICB9O1xuXG4gICAgaWYgKFEubG9uZ1N0YWNrU3VwcG9ydCAmJiBoYXNTdGFja3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBkb24ndCB0cnkgdG8gdXNlIGBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZWAgb3IgdHJhbnNmZXIgdGhlXG4gICAgICAgICAgICAvLyBhY2Nlc3NvciBhcm91bmQ7IHRoYXQgY2F1c2VzIG1lbW9yeSBsZWFrcyBhcyBwZXIgR0gtMTExLiBKdXN0XG4gICAgICAgICAgICAvLyByZWlmeSB0aGUgc3RhY2sgdHJhY2UgYXMgYSBzdHJpbmcgQVNBUC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lLCBjdXQgb2ZmIHRoZSBmaXJzdCBsaW5lOyBpdCdzIGFsd2F5cyBqdXN0XG4gICAgICAgICAgICAvLyBcIltvYmplY3QgUHJvbWlzZV1cXG5cIiwgYXMgcGVyIHRoZSBgdG9TdHJpbmdgLlxuICAgICAgICAgICAgcHJvbWlzZS5zdGFjayA9IGUuc3RhY2suc3Vic3RyaW5nKGUuc3RhY2suaW5kZXhPZihcIlxcblwiKSArIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTk9URTogd2UgZG8gdGhlIGNoZWNrcyBmb3IgYHJlc29sdmVkUHJvbWlzZWAgaW4gZWFjaCBtZXRob2QsIGluc3RlYWQgb2ZcbiAgICAvLyBjb25zb2xpZGF0aW5nIHRoZW0gaW50byBgYmVjb21lYCwgc2luY2Ugb3RoZXJ3aXNlIHdlJ2QgY3JlYXRlIG5ld1xuICAgIC8vIHByb21pc2VzIHdpdGggdGhlIGxpbmVzIGBiZWNvbWUod2hhdGV2ZXIodmFsdWUpKWAuIFNlZSBlLmcuIEdILTI1Mi5cblxuICAgIGZ1bmN0aW9uIGJlY29tZShuZXdQcm9taXNlKSB7XG4gICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5ld1Byb21pc2U7XG4gICAgICAgIHByb21pc2Uuc291cmNlID0gbmV3UHJvbWlzZTtcblxuICAgICAgICBhcnJheV9yZWR1Y2UobWVzc2FnZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5ld1Byb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KG5ld1Byb21pc2UsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG5cbiAgICAgICAgbWVzc2FnZXMgPSB2b2lkIDA7XG4gICAgICAgIHByb2dyZXNzTGlzdGVuZXJzID0gdm9pZCAwO1xuICAgIH1cblxuICAgIGRlZmVycmVkLnByb21pc2UgPSBwcm9taXNlO1xuICAgIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKFEodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgZGVmZXJyZWQuZnVsZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoZnVsZmlsbCh2YWx1ZSkpO1xuICAgIH07XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUocmVqZWN0KHJlYXNvbikpO1xuICAgIH07XG4gICAgZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9ncmVzc0xpc3RlbmVycywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvZ3Jlc3NMaXN0ZW5lcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcihwcm9ncmVzcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlZmVycmVkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBOb2RlLXN0eWxlIGNhbGxiYWNrIHRoYXQgd2lsbCByZXNvbHZlIG9yIHJlamVjdCB0aGUgZGVmZXJyZWRcbiAqIHByb21pc2UuXG4gKiBAcmV0dXJucyBhIG5vZGViYWNrXG4gKi9cbmRlZmVyLnByb3RvdHlwZS5tYWtlTm9kZVJlc29sdmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVycm9yLCB2YWx1ZSkge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHNlbGYucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKipcbiAqIEBwYXJhbSByZXNvbHZlciB7RnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG5vdGhpbmcgYW5kIGFjY2VwdHNcbiAqIHRoZSByZXNvbHZlLCByZWplY3QsIGFuZCBub3RpZnkgZnVuY3Rpb25zIGZvciBhIGRlZmVycmVkLlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgbWF5IGJlIHJlc29sdmVkIHdpdGggdGhlIGdpdmVuIHJlc29sdmUgYW5kIHJlamVjdFxuICogZnVuY3Rpb25zLCBvciByZWplY3RlZCBieSBhIHRocm93biBleGNlcHRpb24gaW4gcmVzb2x2ZXJcbiAqL1xuUS5Qcm9taXNlID0gcHJvbWlzZTsgLy8gRVM2XG5RLnByb21pc2UgPSBwcm9taXNlO1xuZnVuY3Rpb24gcHJvbWlzZShyZXNvbHZlcikge1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVzb2x2ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB0cnkge1xuICAgICAgICByZXNvbHZlcihkZWZlcnJlZC5yZXNvbHZlLCBkZWZlcnJlZC5yZWplY3QsIGRlZmVycmVkLm5vdGlmeSk7XG4gICAgfSBjYXRjaCAocmVhc29uKSB7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChyZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxucHJvbWlzZS5yYWNlID0gcmFjZTsgLy8gRVM2XG5wcm9taXNlLmFsbCA9IGFsbDsgLy8gRVM2XG5wcm9taXNlLnJlamVjdCA9IHJlamVjdDsgLy8gRVM2XG5wcm9taXNlLnJlc29sdmUgPSBROyAvLyBFUzZcblxuLy8gWFhYIGV4cGVyaW1lbnRhbC4gIFRoaXMgbWV0aG9kIGlzIGEgd2F5IHRvIGRlbm90ZSB0aGF0IGEgbG9jYWwgdmFsdWUgaXNcbi8vIHNlcmlhbGl6YWJsZSBhbmQgc2hvdWxkIGJlIGltbWVkaWF0ZWx5IGRpc3BhdGNoZWQgdG8gYSByZW1vdGUgdXBvbiByZXF1ZXN0LFxuLy8gaW5zdGVhZCBvZiBwYXNzaW5nIGEgcmVmZXJlbmNlLlxuUS5wYXNzQnlDb3B5ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIC8vZnJlZXplKG9iamVjdCk7XG4gICAgLy9wYXNzQnlDb3BpZXMuc2V0KG9iamVjdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIG9iamVjdDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSWYgdHdvIHByb21pc2VzIGV2ZW50dWFsbHkgZnVsZmlsbCB0byB0aGUgc2FtZSB2YWx1ZSwgcHJvbWlzZXMgdGhhdCB2YWx1ZSxcbiAqIGJ1dCBvdGhlcndpc2UgcmVqZWN0cy5cbiAqIEBwYXJhbSB4IHtBbnkqfVxuICogQHBhcmFtIHkge0FueSp9XG4gKiBAcmV0dXJucyB7QW55Kn0gYSBwcm9taXNlIGZvciB4IGFuZCB5IGlmIHRoZXkgYXJlIHRoZSBzYW1lLCBidXQgYSByZWplY3Rpb25cbiAqIG90aGVyd2lzZS5cbiAqXG4gKi9cblEuam9pbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIFEoeCkuam9pbih5KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAodGhhdCkge1xuICAgIHJldHVybiBRKFt0aGlzLCB0aGF0XSkuc3ByZWFkKGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIGlmICh4ID09PSB5KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBcIj09PVwiIHNob3VsZCBiZSBPYmplY3QuaXMgb3IgZXF1aXZcbiAgICAgICAgICAgIHJldHVybiB4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3Qgam9pbjogbm90IHRoZSBzYW1lOiBcIiArIHggKyBcIiBcIiArIHkpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZmlyc3Qgb2YgYW4gYXJyYXkgb2YgcHJvbWlzZXMgdG8gYmVjb21lIHNldHRsZWQuXG4gKiBAcGFyYW0gYW5zd2VycyB7QXJyYXlbQW55Kl19IHByb21pc2VzIHRvIHJhY2VcbiAqIEByZXR1cm5zIHtBbnkqfSB0aGUgZmlyc3QgcHJvbWlzZSB0byBiZSBzZXR0bGVkXG4gKi9cblEucmFjZSA9IHJhY2U7XG5mdW5jdGlvbiByYWNlKGFuc3dlclBzKSB7XG4gICAgcmV0dXJuIHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdGhpcyBvbmNlIHdlIGNhbiBhc3N1bWUgYXQgbGVhc3QgRVM1XG4gICAgICAgIC8vIGFuc3dlclBzLmZvckVhY2goZnVuY3Rpb24gKGFuc3dlclApIHtcbiAgICAgICAgLy8gICAgIFEoYW5zd2VyUCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAvLyB9KTtcbiAgICAgICAgLy8gVXNlIHRoaXMgaW4gdGhlIG1lYW50aW1lXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhbnN3ZXJQcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgUShhbnN3ZXJQc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnJhY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihRLnJhY2UpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgUHJvbWlzZSB3aXRoIGEgcHJvbWlzZSBkZXNjcmlwdG9yIG9iamVjdCBhbmQgb3B0aW9uYWwgZmFsbGJhY2tcbiAqIGZ1bmN0aW9uLiAgVGhlIGRlc2NyaXB0b3IgY29udGFpbnMgbWV0aG9kcyBsaWtlIHdoZW4ocmVqZWN0ZWQpLCBnZXQobmFtZSksXG4gKiBzZXQobmFtZSwgdmFsdWUpLCBwb3N0KG5hbWUsIGFyZ3MpLCBhbmQgZGVsZXRlKG5hbWUpLCB3aGljaCBhbGxcbiAqIHJldHVybiBlaXRoZXIgYSB2YWx1ZSwgYSBwcm9taXNlIGZvciBhIHZhbHVlLCBvciBhIHJlamVjdGlvbi4gIFRoZSBmYWxsYmFja1xuICogYWNjZXB0cyB0aGUgb3BlcmF0aW9uIG5hbWUsIGEgcmVzb2x2ZXIsIGFuZCBhbnkgZnVydGhlciBhcmd1bWVudHMgdGhhdCB3b3VsZFxuICogaGF2ZSBiZWVuIGZvcndhcmRlZCB0byB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kIGFib3ZlIGhhZCBhIG1ldGhvZCBiZWVuXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBwcm9wZXIgbmFtZS4gIFRoZSBBUEkgbWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCB0aGUgbmF0dXJlXG4gKiBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LCBhcGFydCBmcm9tIHRoYXQgaXQgaXMgdXNhYmxlIHdoZXJlZXZlciBwcm9taXNlcyBhcmVcbiAqIGJvdWdodCBhbmQgc29sZC5cbiAqL1xuUS5tYWtlUHJvbWlzZSA9IFByb21pc2U7XG5mdW5jdGlvbiBQcm9taXNlKGRlc2NyaXB0b3IsIGZhbGxiYWNrLCBpbnNwZWN0KSB7XG4gICAgaWYgKGZhbGxiYWNrID09PSB2b2lkIDApIHtcbiAgICAgICAgZmFsbGJhY2sgPSBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiUHJvbWlzZSBkb2VzIG5vdCBzdXBwb3J0IG9wZXJhdGlvbjogXCIgKyBvcFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChpbnNwZWN0ID09PSB2b2lkIDApIHtcbiAgICAgICAgaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGU6IFwidW5rbm93blwifTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIGFyZ3MpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yW29wXSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlc2NyaXB0b3Jbb3BdLmFwcGx5KHByb21pc2UsIGFyZ3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxsYmFjay5jYWxsKHByb21pc2UsIG9wLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXN1bHQgPSByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGluc3BlY3Q7XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZCBgdmFsdWVPZmAgYW5kIGBleGNlcHRpb25gIHN1cHBvcnRcbiAgICBpZiAoaW5zcGVjdCkge1xuICAgICAgICB2YXIgaW5zcGVjdGVkID0gaW5zcGVjdCgpO1xuICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgIHByb21pc2UuZXhjZXB0aW9uID0gaW5zcGVjdGVkLnJlYXNvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInBlbmRpbmdcIiB8fFxuICAgICAgICAgICAgICAgIGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdGVkLnZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgZG9uZSA9IGZhbHNlOyAgIC8vIGVuc3VyZSB0aGUgdW50cnVzdGVkIHByb21pc2UgbWFrZXMgYXQgbW9zdCBhXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5nbGUgY2FsbCB0byBvbmUgb2YgdGhlIGNhbGxiYWNrc1xuXG4gICAgZnVuY3Rpb24gX2Z1bGZpbGxlZCh2YWx1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBmdWxmaWxsZWQgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bGZpbGxlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcmVqZWN0ZWQoZXhjZXB0aW9uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGV4Y2VwdGlvbiwgc2VsZik7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3RlZChleGNlcHRpb24pO1xuICAgICAgICAgICAgfSBjYXRjaCAobmV3RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXdFeGNlcHRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHJvZ3Jlc3NlZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHByb2dyZXNzZWQgPT09IFwiZnVuY3Rpb25cIiA/IHByb2dyZXNzZWQodmFsdWUpIDogdmFsdWU7XG4gICAgfVxuXG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfZnVsZmlsbGVkKHZhbHVlKSk7XG4gICAgICAgIH0sIFwid2hlblwiLCBbZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfcmVqZWN0ZWQoZXhjZXB0aW9uKSk7XG4gICAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIC8vIFByb2dyZXNzIHByb3BhZ2F0b3IgbmVlZCB0byBiZSBhdHRhY2hlZCBpbiB0aGUgY3VycmVudCB0aWNrLlxuICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKHZvaWQgMCwgXCJ3aGVuXCIsIFt2b2lkIDAsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG4gICAgICAgIHZhciB0aHJldyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBfcHJvZ3Jlc3NlZCh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocmV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRocmV3KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkobmV3VmFsdWUpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5RLnRhcCA9IGZ1bmN0aW9uIChwcm9taXNlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRhcChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFdvcmtzIGFsbW9zdCBsaWtlIFwiZmluYWxseVwiLCBidXQgbm90IGNhbGxlZCBmb3IgcmVqZWN0aW9ucy5cbiAqIE9yaWdpbmFsIHJlc29sdXRpb24gdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggY2FsbGJhY2sgdW5hZmZlY3RlZC5cbiAqIENhbGxiYWNrIG1heSByZXR1cm4gYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBhd2FpdGVkIGZvci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7US5Qcm9taXNlfVxuICogQGV4YW1wbGVcbiAqIGRvU29tZXRoaW5nKClcbiAqICAgLnRoZW4oLi4uKVxuICogICAudGFwKGNvbnNvbGUubG9nKVxuICogICAudGhlbiguLi4pO1xuICovXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IFEoY2FsbGJhY2spO1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKHZhbHVlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBvbiBhIHByb21pc2UuXG4gKlxuICogR3VhcmFudGVlczpcbiAqXG4gKiAxLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLlxuICogMi4gdGhhdCBlaXRoZXIgdGhlIGZ1bGZpbGxlZCBjYWxsYmFjayBvciB0aGUgcmVqZWN0ZWQgY2FsbGJhY2sgd2lsbCBiZVxuICogICAgY2FsbGVkLCBidXQgbm90IGJvdGguXG4gKiAzLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoaXMgdHVybi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgICAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgdG8gb2JzZXJ2ZVxuICogQHBhcmFtIGZ1bGZpbGxlZCAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogQHBhcmFtIHJlamVjdGVkICAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIHJlamVjdGlvbiBleGNlcHRpb25cbiAqIEBwYXJhbSBwcm9ncmVzc2VkIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIGludm9rZWQgY2FsbGJhY2tcbiAqL1xuUS53aGVuID0gd2hlbjtcbmZ1bmN0aW9uIHdoZW4odmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUSh2YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGhlblJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9KTtcbn07XG5cblEudGhlblJlc29sdmUgPSBmdW5jdGlvbiAocHJvbWlzZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyByZWFzb247IH0pO1xufTtcblxuUS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHByb21pc2UsIHJlYXNvbikge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZWplY3QocmVhc29uKTtcbn07XG5cbi8qKlxuICogSWYgYW4gb2JqZWN0IGlzIG5vdCBhIHByb21pc2UsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlLlxuICogSWYgYSBwcm9taXNlIGlzIHJlamVjdGVkLCBpdCBpcyBhcyBcIm5lYXJcIiBhcyBwb3NzaWJsZSB0b28uXG4gKiBJZiBpdOKAmXMgYSBmdWxmaWxsZWQgcHJvbWlzZSwgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5lYXJlci5cbiAqIElmIGl04oCZcyBhIGRlZmVycmVkIHByb21pc2UgYW5kIHRoZSBkZWZlcnJlZCBoYXMgYmVlbiByZXNvbHZlZCwgdGhlXG4gKiByZXNvbHV0aW9uIGlzIFwibmVhcmVyXCIuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBtb3N0IHJlc29sdmVkIChuZWFyZXN0KSBmb3JtIG9mIHRoZSBvYmplY3RcbiAqL1xuXG4vLyBYWFggc2hvdWxkIHdlIHJlLWRvIHRoaXM/XG5RLm5lYXJlciA9IG5lYXJlcjtcbmZ1bmN0aW9uIG5lYXJlcih2YWx1ZSkge1xuICAgIGlmIChpc1Byb21pc2UodmFsdWUpKSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSB2YWx1ZS5pbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHByb21pc2UuXG4gKiBPdGhlcndpc2UgaXQgaXMgYSBmdWxmaWxsZWQgdmFsdWUuXG4gKi9cblEuaXNQcm9taXNlID0gaXNQcm9taXNlO1xuZnVuY3Rpb24gaXNQcm9taXNlKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBQcm9taXNlO1xufVxuXG5RLmlzUHJvbWlzZUFsaWtlID0gaXNQcm9taXNlQWxpa2U7XG5mdW5jdGlvbiBpc1Byb21pc2VBbGlrZShvYmplY3QpIHtcbiAgICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSAmJiB0eXBlb2Ygb2JqZWN0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBwZW5kaW5nIHByb21pc2UsIG1lYW5pbmcgbm90XG4gKiBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG4gKi9cblEuaXNQZW5kaW5nID0gaXNQZW5kaW5nO1xuZnVuY3Rpb24gaXNQZW5kaW5nKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJwZW5kaW5nXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHZhbHVlIG9yIGZ1bGZpbGxlZFxuICogcHJvbWlzZS5cbiAqL1xuUS5pc0Z1bGZpbGxlZCA9IGlzRnVsZmlsbGVkO1xuZnVuY3Rpb24gaXNGdWxmaWxsZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuICFpc1Byb21pc2Uob2JqZWN0KSB8fCBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0Z1bGZpbGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHJlamVjdGVkIHByb21pc2UuXG4gKi9cblEuaXNSZWplY3RlZCA9IGlzUmVqZWN0ZWQ7XG5mdW5jdGlvbiBpc1JlamVjdGVkKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzUmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59O1xuXG4vLy8vIEJFR0lOIFVOSEFORExFRCBSRUpFQ1RJT04gVFJBQ0tJTkdcblxuLy8gVGhpcyBwcm9taXNlIGxpYnJhcnkgY29uc3VtZXMgZXhjZXB0aW9ucyB0aHJvd24gaW4gaGFuZGxlcnMgc28gdGhleSBjYW4gYmVcbi8vIGhhbmRsZWQgYnkgYSBzdWJzZXF1ZW50IHByb21pc2UuICBUaGUgZXhjZXB0aW9ucyBnZXQgYWRkZWQgdG8gdGhpcyBhcnJheSB3aGVuXG4vLyB0aGV5IGFyZSBjcmVhdGVkLCBhbmQgcmVtb3ZlZCB3aGVuIHRoZXkgYXJlIGhhbmRsZWQuICBOb3RlIHRoYXQgaW4gRVM2IG9yXG4vLyBzaGltbWVkIGVudmlyb25tZW50cywgdGhpcyB3b3VsZCBuYXR1cmFsbHkgYmUgYSBgU2V0YC5cbnZhciB1bmhhbmRsZWRSZWFzb25zID0gW107XG52YXIgdW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IHRydWU7XG5cbmZ1bmN0aW9uIHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpIHtcbiAgICB1bmhhbmRsZWRSZWFzb25zLmxlbmd0aCA9IDA7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyYWNrUmVqZWN0aW9uKHByb21pc2UsIHJlYXNvbikge1xuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBwcm9jZXNzLmVtaXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChhcnJheV9pbmRleE9mKHVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInVuaGFuZGxlZFJlamVjdGlvblwiLCByZWFzb24sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucy5wdXNoKHByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgaWYgKHJlYXNvbiAmJiB0eXBlb2YgcmVhc29uLnN0YWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChyZWFzb24uc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChcIihubyBzdGFjaykgXCIgKyByZWFzb24pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdW50cmFja1JlamVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhdCA9IGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgaWYgKGF0ICE9PSAtMSkge1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXRSZXBvcnQgPSBhcnJheV9pbmRleE9mKHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgaWYgKGF0UmVwb3J0ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmVtaXQoXCJyZWplY3Rpb25IYW5kbGVkXCIsIHVuaGFuZGxlZFJlYXNvbnNbYXRdLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdFJlcG9ydCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5zcGxpY2UoYXQsIDEpO1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnNwbGljZShhdCwgMSk7XG4gICAgfVxufVxuXG5RLnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucyA9IHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucztcblxuUS5nZXRVbmhhbmRsZWRSZWFzb25zID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIE1ha2UgYSBjb3B5IHNvIHRoYXQgY29uc3VtZXJzIGNhbid0IGludGVyZmVyZSB3aXRoIG91ciBpbnRlcm5hbCBzdGF0ZS5cbiAgICByZXR1cm4gdW5oYW5kbGVkUmVhc29ucy5zbGljZSgpO1xufTtcblxuUS5zdG9wVW5oYW5kbGVkUmVqZWN0aW9uVHJhY2tpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCk7XG4gICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gZmFsc2U7XG59O1xuXG5yZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcblxuLy8vLyBFTkQgVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSByZWplY3RlZCBwcm9taXNlLlxuICogQHBhcmFtIHJlYXNvbiB2YWx1ZSBkZXNjcmliaW5nIHRoZSBmYWlsdXJlXG4gKi9cblEucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgIHZhciByZWplY3Rpb24gPSBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uIChyZWplY3RlZCkge1xuICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoZSBlcnJvciBoYXMgYmVlbiBoYW5kbGVkXG4gICAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICB1bnRyYWNrUmVqZWN0aW9uKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkID8gcmVqZWN0ZWQocmVhc29uKSA6IHRoaXM7XG4gICAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwicmVqZWN0ZWRcIiwgcmVhc29uOiByZWFzb24gfTtcbiAgICB9KTtcblxuICAgIC8vIE5vdGUgdGhhdCB0aGUgcmVhc29uIGhhcyBub3QgYmVlbiBoYW5kbGVkLlxuICAgIHRyYWNrUmVqZWN0aW9uKHJlamVjdGlvbiwgcmVhc29uKTtcblxuICAgIHJldHVybiByZWplY3Rpb247XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIGZ1bGZpbGxlZCBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2VcbiAqL1xuUS5mdWxmaWxsID0gZnVsZmlsbDtcbmZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHtcbiAgICByZXR1cm4gUHJvbWlzZSh7XG4gICAgICAgIFwid2hlblwiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZ2V0XCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwic2V0XCI6IGZ1bmN0aW9uIChuYW1lLCByaHMpIHtcbiAgICAgICAgICAgIHZhbHVlW25hbWVdID0gcmhzO1xuICAgICAgICB9LFxuICAgICAgICBcImRlbGV0ZVwiOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgZGVsZXRlIHZhbHVlW25hbWVdO1xuICAgICAgICB9LFxuICAgICAgICBcInBvc3RcIjogZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICAgICAgICAgIC8vIE1hcmsgTWlsbGVyIHByb3Bvc2VzIHRoYXQgcG9zdCB3aXRoIG5vIG5hbWUgc2hvdWxkIGFwcGx5IGFcbiAgICAgICAgICAgIC8vIHByb21pc2VkIGZ1bmN0aW9uLlxuICAgICAgICAgICAgaWYgKG5hbWUgPT09IG51bGwgfHwgbmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHZvaWQgMCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXS5hcHBseSh2YWx1ZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFwiYXBwbHlcIjogZnVuY3Rpb24gKHRoaXNwLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodGhpc3AsIGFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBcImtleXNcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdF9rZXlzKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0sIHZvaWQgMCwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwiZnVsZmlsbGVkXCIsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZW5hYmxlcyB0byBRIHByb21pc2VzLlxuICogQHBhcmFtIHByb21pc2UgdGhlbmFibGUgcHJvbWlzZVxuICogQHJldHVybnMgYSBRIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gY29lcmNlKHByb21pc2UpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvbWlzZS50aGVuKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG4vKipcbiAqIEFubm90YXRlcyBhbiBvYmplY3Qgc3VjaCB0aGF0IGl0IHdpbGwgbmV2ZXIgYmVcbiAqIHRyYW5zZmVycmVkIGF3YXkgZnJvbSB0aGlzIHByb2Nlc3Mgb3ZlciBhbnkgcHJvbWlzZVxuICogY29tbXVuaWNhdGlvbiBjaGFubmVsLlxuICogQHBhcmFtIG9iamVjdFxuICogQHJldHVybnMgcHJvbWlzZSBhIHdyYXBwaW5nIG9mIHRoYXQgb2JqZWN0IHRoYXRcbiAqIGFkZGl0aW9uYWxseSByZXNwb25kcyB0byB0aGUgXCJpc0RlZlwiIG1lc3NhZ2VcbiAqIHdpdGhvdXQgYSByZWplY3Rpb24uXG4gKi9cblEubWFzdGVyID0gbWFzdGVyO1xuZnVuY3Rpb24gbWFzdGVyKG9iamVjdCkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJpc0RlZlwiOiBmdW5jdGlvbiAoKSB7fVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKG9wLCBhcmdzKSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKTtcbiAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBRKG9iamVjdCkuaW5zcGVjdCgpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFNwcmVhZHMgdGhlIHZhbHVlcyBvZiBhIHByb21pc2VkIGFycmF5IG9mIGFyZ3VtZW50cyBpbnRvIHRoZVxuICogZnVsZmlsbG1lbnQgY2FsbGJhY2suXG4gKiBAcGFyYW0gZnVsZmlsbGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdmFyaWFkaWMgYXJndW1lbnRzIGZyb20gdGhlXG4gKiBwcm9taXNlZCBhcnJheVxuICogQHBhcmFtIHJlamVjdGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgcHJvbWlzZVxuICogaXMgcmVqZWN0ZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb3IgdGhyb3duIGV4Y2VwdGlvbiBvZlxuICogZWl0aGVyIGNhbGxiYWNrLlxuICovXG5RLnNwcmVhZCA9IHNwcmVhZDtcbmZ1bmN0aW9uIHNwcmVhZCh2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS5zcHJlYWQoZnVsZmlsbGVkLCByZWplY3RlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkudGhlbihmdW5jdGlvbiAoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGxlZC5hcHBseSh2b2lkIDAsIGFycmF5KTtcbiAgICB9LCByZWplY3RlZCk7XG59O1xuXG4vKipcbiAqIFRoZSBhc3luYyBmdW5jdGlvbiBpcyBhIGRlY29yYXRvciBmb3IgZ2VuZXJhdG9yIGZ1bmN0aW9ucywgdHVybmluZ1xuICogdGhlbSBpbnRvIGFzeW5jaHJvbm91cyBnZW5lcmF0b3JzLiAgQWx0aG91Z2ggZ2VuZXJhdG9ycyBhcmUgb25seSBwYXJ0XG4gKiBvZiB0aGUgbmV3ZXN0IEVDTUFTY3JpcHQgNiBkcmFmdHMsIHRoaXMgY29kZSBkb2VzIG5vdCBjYXVzZSBzeW50YXhcbiAqIGVycm9ycyBpbiBvbGRlciBlbmdpbmVzLiAgVGhpcyBjb2RlIHNob3VsZCBjb250aW51ZSB0byB3b3JrIGFuZCB3aWxsXG4gKiBpbiBmYWN0IGltcHJvdmUgb3ZlciB0aW1lIGFzIHRoZSBsYW5ndWFnZSBpbXByb3Zlcy5cbiAqXG4gKiBFUzYgZ2VuZXJhdG9ycyBhcmUgY3VycmVudGx5IHBhcnQgb2YgVjggdmVyc2lvbiAzLjE5IHdpdGggdGhlXG4gKiAtLWhhcm1vbnktZ2VuZXJhdG9ycyBydW50aW1lIGZsYWcgZW5hYmxlZC4gIFNwaWRlck1vbmtleSBoYXMgaGFkIHRoZW1cbiAqIGZvciBsb25nZXIsIGJ1dCB1bmRlciBhbiBvbGRlciBQeXRob24taW5zcGlyZWQgZm9ybS4gIFRoaXMgZnVuY3Rpb25cbiAqIHdvcmtzIG9uIGJvdGgga2luZHMgb2YgZ2VuZXJhdG9ycy5cbiAqXG4gKiBEZWNvcmF0ZXMgYSBnZW5lcmF0b3IgZnVuY3Rpb24gc3VjaCB0aGF0OlxuICogIC0gaXQgbWF5IHlpZWxkIHByb21pc2VzXG4gKiAgLSBleGVjdXRpb24gd2lsbCBjb250aW51ZSB3aGVuIHRoYXQgcHJvbWlzZSBpcyBmdWxmaWxsZWRcbiAqICAtIHRoZSB2YWx1ZSBvZiB0aGUgeWllbGQgZXhwcmVzc2lvbiB3aWxsIGJlIHRoZSBmdWxmaWxsZWQgdmFsdWVcbiAqICAtIGl0IHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlICh3aGVuIHRoZSBnZW5lcmF0b3JcbiAqICAgIHN0b3BzIGl0ZXJhdGluZylcbiAqICAtIHRoZSBkZWNvcmF0ZWQgZnVuY3Rpb24gcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqICAgIG9mIHRoZSBnZW5lcmF0b3Igb3IgdGhlIGZpcnN0IHJlamVjdGVkIHByb21pc2UgYW1vbmcgdGhvc2VcbiAqICAgIHlpZWxkZWQuXG4gKiAgLSBpZiBhbiBlcnJvciBpcyB0aHJvd24gaW4gdGhlIGdlbmVyYXRvciwgaXQgcHJvcGFnYXRlcyB0aHJvdWdoXG4gKiAgICBldmVyeSBmb2xsb3dpbmcgeWllbGQgdW50aWwgaXQgaXMgY2F1Z2h0LCBvciB1bnRpbCBpdCBlc2NhcGVzXG4gKiAgICB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGFsdG9nZXRoZXIsIGFuZCBpcyB0cmFuc2xhdGVkIGludG8gYVxuICogICAgcmVqZWN0aW9uIGZvciB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZGVjb3JhdGVkIGdlbmVyYXRvci5cbiAqL1xuUS5hc3luYyA9IGFzeW5jO1xuZnVuY3Rpb24gYXN5bmMobWFrZUdlbmVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHdoZW4gdmVyYiBpcyBcInNlbmRcIiwgYXJnIGlzIGEgdmFsdWVcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwidGhyb3dcIiwgYXJnIGlzIGFuIGV4Y2VwdGlvblxuICAgICAgICBmdW5jdGlvbiBjb250aW51ZXIodmVyYiwgYXJnKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICAgICAgICAvLyBVbnRpbCBWOCAzLjE5IC8gQ2hyb21pdW0gMjkgaXMgcmVsZWFzZWQsIFNwaWRlck1vbmtleSBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gZW5naW5lIHRoYXQgaGFzIGEgZGVwbG95ZWQgYmFzZSBvZiBicm93c2VycyB0aGF0IHN1cHBvcnQgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgIC8vIEhvd2V2ZXIsIFNNJ3MgZ2VuZXJhdG9ycyB1c2UgdGhlIFB5dGhvbi1pbnNwaXJlZCBzZW1hbnRpY3Mgb2ZcbiAgICAgICAgICAgIC8vIG91dGRhdGVkIEVTNiBkcmFmdHMuICBXZSB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgRVM2LCBidXQgd2UnZCBhbHNvXG4gICAgICAgICAgICAvLyBsaWtlIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gdXNlIGdlbmVyYXRvcnMgaW4gZGVwbG95ZWQgYnJvd3NlcnMsIHNvXG4gICAgICAgICAgICAvLyB3ZSBhbHNvIHN1cHBvcnQgUHl0aG9uLXN0eWxlIGdlbmVyYXRvcnMuICBBdCBzb21lIHBvaW50IHdlIGNhbiByZW1vdmVcbiAgICAgICAgICAgIC8vIHRoaXMgYmxvY2suXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgU3RvcEl0ZXJhdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIC8vIEVTNiBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdG9yW3ZlcmJdKGFyZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBRKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LnZhbHVlLCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTcGlkZXJNb25rZXkgR2VuZXJhdG9yc1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBSZW1vdmUgdGhpcyBjYXNlIHdoZW4gU00gZG9lcyBFUzYgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RvcEl0ZXJhdGlvbihleGNlcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUShleGNlcHRpb24udmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB3aGVuKHJlc3VsdCwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBnZW5lcmF0b3IgPSBtYWtlR2VuZXJhdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJuZXh0XCIpO1xuICAgICAgICB2YXIgZXJyYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJ0aHJvd1wiKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBUaGUgc3Bhd24gZnVuY3Rpb24gaXMgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZCBhc3luYyB0aGF0IGltbWVkaWF0ZWx5XG4gKiBjYWxscyB0aGUgZ2VuZXJhdG9yIGFuZCBhbHNvIGVuZHMgdGhlIHByb21pc2UgY2hhaW4sIHNvIHRoYXQgYW55XG4gKiB1bmhhbmRsZWQgZXJyb3JzIGFyZSB0aHJvd24gaW5zdGVhZCBvZiBmb3J3YXJkZWQgdG8gdGhlIGVycm9yXG4gKiBoYW5kbGVyLiBUaGlzIGlzIHVzZWZ1bCBiZWNhdXNlIGl0J3MgZXh0cmVtZWx5IGNvbW1vbiB0byBydW5cbiAqIGdlbmVyYXRvcnMgYXQgdGhlIHRvcC1sZXZlbCB0byB3b3JrIHdpdGggbGlicmFyaWVzLlxuICovXG5RLnNwYXduID0gc3Bhd247XG5mdW5jdGlvbiBzcGF3bihtYWtlR2VuZXJhdG9yKSB7XG4gICAgUS5kb25lKFEuYXN5bmMobWFrZUdlbmVyYXRvcikoKSk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBpbnRlcmZhY2Ugb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuLyoqXG4gKiBUaHJvd3MgYSBSZXR1cm5WYWx1ZSBleGNlcHRpb24gdG8gc3RvcCBhbiBhc3luY2hyb25vdXMgZ2VuZXJhdG9yLlxuICpcbiAqIFRoaXMgaW50ZXJmYWNlIGlzIGEgc3RvcC1nYXAgbWVhc3VyZSB0byBzdXBwb3J0IGdlbmVyYXRvciByZXR1cm5cbiAqIHZhbHVlcyBpbiBvbGRlciBGaXJlZm94L1NwaWRlck1vbmtleS4gIEluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBFUzZcbiAqIGdlbmVyYXRvcnMgbGlrZSBDaHJvbWl1bSAyOSwganVzdCB1c2UgXCJyZXR1cm5cIiBpbiB5b3VyIGdlbmVyYXRvclxuICogZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSB0aGUgcmV0dXJuIHZhbHVlIGZvciB0aGUgc3Vycm91bmRpbmcgZ2VuZXJhdG9yXG4gKiBAdGhyb3dzIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB3aXRoIHRoZSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBFUzYgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24qICgpIHtcbiAqICAgICAgdmFyIGZvbyA9IHlpZWxkIGdldEZvb1Byb21pc2UoKTtcbiAqICAgICAgdmFyIGJhciA9IHlpZWxkIGdldEJhclByb21pc2UoKTtcbiAqICAgICAgcmV0dXJuIGZvbyArIGJhcjtcbiAqIH0pXG4gKiAvLyBPbGRlciBTcGlkZXJNb25rZXkgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24gKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICBRLnJldHVybihmb28gKyBiYXIpO1xuICogfSlcbiAqL1xuUVtcInJldHVyblwiXSA9IF9yZXR1cm47XG5mdW5jdGlvbiBfcmV0dXJuKHZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IFFSZXR1cm5WYWx1ZSh2YWx1ZSk7XG59XG5cbi8qKlxuICogVGhlIHByb21pc2VkIGZ1bmN0aW9uIGRlY29yYXRvciBlbnN1cmVzIHRoYXQgYW55IHByb21pc2UgYXJndW1lbnRzXG4gKiBhcmUgc2V0dGxlZCBhbmQgcGFzc2VkIGFzIHZhbHVlcyAoYHRoaXNgIGlzIGFsc28gc2V0dGxlZCBhbmQgcGFzc2VkXG4gKiBhcyBhIHZhbHVlKS4gIEl0IHdpbGwgYWxzbyBlbnN1cmUgdGhhdCB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb24gaXNcbiAqIGFsd2F5cyBhIHByb21pc2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBRLnByb21pc2VkKGZ1bmN0aW9uIChhLCBiKSB7XG4gKiAgICAgcmV0dXJuIGEgKyBiO1xuICogfSk7XG4gKiBhZGQoUShhKSwgUShCKSk7XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGRlY29yYXRlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBoYXMgYmVlbiBkZWNvcmF0ZWQuXG4gKi9cblEucHJvbWlzZWQgPSBwcm9taXNlZDtcbmZ1bmN0aW9uIHByb21pc2VkKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNwcmVhZChbdGhpcywgYWxsKGFyZ3VtZW50cyldLCBmdW5jdGlvbiAoc2VsZiwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vKipcbiAqIHNlbmRzIGEgbWVzc2FnZSB0byBhIHZhbHVlIGluIGEgZnV0dXJlIHR1cm5cbiAqIEBwYXJhbSBvYmplY3QqIHRoZSByZWNpcGllbnRcbiAqIEBwYXJhbSBvcCB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBvcGVyYXRpb24sIGUuZy4sIFwid2hlblwiLFxuICogQHBhcmFtIGFyZ3MgZnVydGhlciBhcmd1bWVudHMgdG8gYmUgZm9yd2FyZGVkIHRvIHRoZSBvcGVyYXRpb25cbiAqIEByZXR1cm5zIHJlc3VsdCB7UHJvbWlzZX0gYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb25cbiAqL1xuUS5kaXNwYXRjaCA9IGRpc3BhdGNoO1xuZnVuY3Rpb24gZGlzcGF0Y2gob2JqZWN0LCBvcCwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2gob3AsIGFyZ3MpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uIChvcCwgYXJncykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnByb21pc2VEaXNwYXRjaChkZWZlcnJlZC5yZXNvbHZlLCBvcCwgYXJncyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZ2V0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBwcm9wZXJ0eSB2YWx1ZVxuICovXG5RLmdldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZ2V0XCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIG9iamVjdCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBzZXRcbiAqIEBwYXJhbSB2YWx1ZSAgICAgbmV3IHZhbHVlIG9mIHByb3BlcnR5XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5zZXQgPSBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBEZWxldGVzIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5kZWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kZWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImRlbGV0ZVwiXSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIHZhbHVlICAgICBhIHZhbHVlIHRvIHBvc3QsIHR5cGljYWxseSBhbiBhcnJheSBvZlxuICogICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uIGFyZ3VtZW50cyBmb3IgcHJvbWlzZXMgdGhhdFxuICogICAgICAgICAgICAgICAgICBhcmUgdWx0aW1hdGVseSBiYWNrZWQgd2l0aCBgcmVzb2x2ZWAgdmFsdWVzLFxuICogICAgICAgICAgICAgICAgICBhcyBvcHBvc2VkIHRvIHRob3NlIGJhY2tlZCB3aXRoIFVSTHNcbiAqICAgICAgICAgICAgICAgICAgd2hlcmVpbiB0aGUgcG9zdGVkIHZhbHVlIGNhbiBiZSBhbnlcbiAqICAgICAgICAgICAgICAgICAgSlNPTiBzZXJpYWxpemFibGUgb2JqZWN0LlxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cbi8vIGJvdW5kIGxvY2FsbHkgYmVjYXVzZSBpdCBpcyB1c2VkIGJ5IG90aGVyIG1ldGhvZHNcblEubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEucG9zdCA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuLyoqXG4gKiBJbnZva2VzIGEgbWV0aG9kIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIG1ldGhvZCB0byBpbnZva2VcbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgaW52b2NhdGlvbiBhcmd1bWVudHNcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNlbmQgPSAvLyBYWFggTWFyayBNaWxsZXIncyBwcm9wb3NlZCBwYXJsYW5jZVxuUS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLmludm9rZSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5Qcm9taXNlLnByb3RvdHlwZS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIGFyZ3MgICAgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUS5mYXBwbHkgPSBmdW5jdGlvbiAob2JqZWN0LCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIENhbGxzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUVtcInRyeVwiXSA9XG5RLmZjYWxsID0gZnVuY3Rpb24gKG9iamVjdCAvKiAuLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFycmF5X3NsaWNlKGFyZ3VtZW50cyldKTtcbn07XG5cbi8qKlxuICogQmluZHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uLCB0cmFuc2Zvcm1pbmcgcmV0dXJuIHZhbHVlcyBpbnRvIGEgZnVsZmlsbGVkXG4gKiBwcm9taXNlIGFuZCB0aHJvd24gZXJyb3JzIGludG8gYSByZWplY3RlZCBvbmUuXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZiaW5kID0gZnVuY3Rpb24gKG9iamVjdCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBwcm9taXNlID0gUShvYmplY3QpO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblByb21pc2UucHJvdG90eXBlLmZiaW5kID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBSZXF1ZXN0cyB0aGUgbmFtZXMgb2YgdGhlIG93bmVkIHByb3BlcnRpZXMgb2YgYSBwcm9taXNlZFxuICogb2JqZWN0IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUga2V5cyBvZiB0aGUgZXZlbnR1YWxseSBzZXR0bGVkIG9iamVjdFxuICovXG5RLmtleXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkuICBJZiBhbnkgb2ZcbiAqIHRoZSBwcm9taXNlcyBnZXRzIHJlamVjdGVkLCB0aGUgd2hvbGUgYXJyYXkgaXMgcmVqZWN0ZWQgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXNcbiAqL1xuLy8gQnkgTWFyayBNaWxsZXJcbi8vIGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPXN0cmF3bWFuOmNvbmN1cnJlbmN5JnJldj0xMzA4Nzc2NTIxI2FsbGZ1bGZpbGxlZFxuUS5hbGwgPSBhbGw7XG5mdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gd2hlbihwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHByb21pc2UsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc25hcHNob3Q7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgaXNQcm9taXNlKHByb21pc2UpICYmXG4gICAgICAgICAgICAgICAgKHNuYXBzaG90ID0gcHJvbWlzZS5pbnNwZWN0KCkpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSBzbmFwc2hvdC52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgKytwZW5kaW5nQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hlbihcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtLXBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChwcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHsgaW5kZXg6IGluZGV4LCB2YWx1ZTogcHJvZ3Jlc3MgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHByb21pc2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2Ugb2YgYW4gYXJyYXkuIFByaW9yIHJlamVjdGVkIHByb21pc2VzIGFyZVxuICogaWdub3JlZC4gIFJlamVjdHMgb25seSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICogQHBhcmFtIHtBcnJheSp9IGFuIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIG9yIHByb21pc2VzIGZvciB2YWx1ZXNcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmdWxmaWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2UsXG4gKiBvciBhIHJlamVjdGVkIHByb21pc2UgaWYgYWxsIHByb21pc2VzIGFyZSByZWplY3RlZC5cbiAqL1xuUS5hbnkgPSBhbnk7XG5cbmZ1bmN0aW9uIGFueShwcm9taXNlcykge1xuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHZhciBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgICB2YXIgcGVuZGluZ0NvdW50ID0gMDtcbiAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uIChwcmV2LCBjdXJyZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHByb21pc2VzW2luZGV4XTtcblxuICAgICAgICBwZW5kaW5nQ291bnQrKztcblxuICAgICAgICB3aGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBvblByb2dyZXNzKTtcbiAgICAgICAgZnVuY3Rpb24gb25GdWxmaWxsZWQocmVzdWx0KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25SZWplY3RlZCgpIHtcbiAgICAgICAgICAgIHBlbmRpbmdDb3VudC0tO1xuICAgICAgICAgICAgaWYgKHBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiQ2FuJ3QgZ2V0IGZ1bGZpbGxtZW50IHZhbHVlIGZyb20gYW55IHByb21pc2UsIGFsbCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwicHJvbWlzZXMgd2VyZSByZWplY3RlZC5cIlxuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeSh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBwcm9ncmVzc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB1bmRlZmluZWQpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxuLyoqXG4gKiBXYWl0cyBmb3IgYWxsIHByb21pc2VzIHRvIGJlIHNldHRsZWQsIGVpdGhlciBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLiAgVGhpcyBpcyBkaXN0aW5jdCBmcm9tIGBhbGxgIHNpbmNlIHRoYXQgd291bGQgc3RvcFxuICogd2FpdGluZyBhdCB0aGUgZmlyc3QgcmVqZWN0aW9uLiAgVGhlIHByb21pc2UgcmV0dXJuZWQgYnlcbiAqIGBhbGxSZXNvbHZlZGAgd2lsbCBuZXZlciBiZSByZWplY3RlZC5cbiAqIEBwYXJhbSBwcm9taXNlcyBhIHByb21pc2UgZm9yIGFuIGFycmF5IChvciBhbiBhcnJheSkgb2YgcHJvbWlzZXNcbiAqIChvciB2YWx1ZXMpXG4gKiBAcmV0dXJuIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgcHJvbWlzZXNcbiAqL1xuUS5hbGxSZXNvbHZlZCA9IGRlcHJlY2F0ZShhbGxSZXNvbHZlZCwgXCJhbGxSZXNvbHZlZFwiLCBcImFsbFNldHRsZWRcIik7XG5mdW5jdGlvbiBhbGxSZXNvbHZlZChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcHJvbWlzZXMgPSBhcnJheV9tYXAocHJvbWlzZXMsIFEpO1xuICAgICAgICByZXR1cm4gd2hlbihhbGwoYXJyYXlfbWFwKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHdoZW4ocHJvbWlzZSwgbm9vcCwgbm9vcCk7XG4gICAgICAgIH0pKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbFJlc29sdmVkKHRoaXMpO1xufTtcblxuLyoqXG4gKiBAc2VlIFByb21pc2UjYWxsU2V0dGxlZFxuICovXG5RLmFsbFNldHRsZWQgPSBhbGxTZXR0bGVkO1xuZnVuY3Rpb24gYWxsU2V0dGxlZChwcm9taXNlcykge1xuICAgIHJldHVybiBRKHByb21pc2VzKS5hbGxTZXR0bGVkKCk7XG59XG5cbi8qKlxuICogVHVybnMgYW4gYXJyYXkgb2YgcHJvbWlzZXMgaW50byBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZWlyIHN0YXRlcyAoYXNcbiAqIHJldHVybmVkIGJ5IGBpbnNwZWN0YCkgd2hlbiB0aGV5IGhhdmUgYWxsIHNldHRsZWQuXG4gKiBAcGFyYW0ge0FycmF5W0FueSpdfSB2YWx1ZXMgYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMge0FycmF5W1N0YXRlXX0gYW4gYXJyYXkgb2Ygc3RhdGVzIGZvciB0aGUgcmVzcGVjdGl2ZSB2YWx1ZXMuXG4gKi9cblByb21pc2UucHJvdG90eXBlLmFsbFNldHRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcmV0dXJuIGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlID0gUShwcm9taXNlKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJlZ2FyZGxlc3MoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuaW5zcGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihyZWdhcmRsZXNzLCByZWdhcmRsZXNzKTtcbiAgICAgICAgfSkpO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBDYXB0dXJlcyB0aGUgZmFpbHVyZSBvZiBhIHByb21pc2UsIGdpdmluZyBhbiBvcG9ydHVuaXR5IHRvIHJlY292ZXJcbiAqIHdpdGggYSBjYWxsYmFjay4gIElmIHRoZSBnaXZlbiBwcm9taXNlIGlzIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gKiBwcm9taXNlIGlzIGZ1bGZpbGxlZC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBmdWxmaWxsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlmIHRoZVxuICogZ2l2ZW4gcHJvbWlzZSBpcyByZWplY3RlZFxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFja1xuICovXG5RLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogQXR0YWNoZXMgYSBsaXN0ZW5lciB0aGF0IGNhbiByZXNwb25kIHRvIHByb2dyZXNzIG5vdGlmaWNhdGlvbnMgZnJvbSBhXG4gKiBwcm9taXNlJ3Mgb3JpZ2luYXRpbmcgZGVmZXJyZWQuIFRoaXMgbGlzdGVuZXIgcmVjZWl2ZXMgdGhlIGV4YWN0IGFyZ3VtZW50c1xuICogcGFzc2VkIHRvIGBgZGVmZXJyZWQubm90aWZ5YGAuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgZm9yIHNvbWV0aGluZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gcmVjZWl2ZSBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybnMgdGhlIGdpdmVuIHByb21pc2UsIHVuY2hhbmdlZFxuICovXG5RLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG5mdW5jdGlvbiBwcm9ncmVzcyhvYmplY3QsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRoZW4odm9pZCAwLCB2b2lkIDAsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5wcm9ncmVzcyA9IGZ1bmN0aW9uIChwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIG9wcG9ydHVuaXR5IHRvIG9ic2VydmUgdGhlIHNldHRsaW5nIG9mIGEgcHJvbWlzZSxcbiAqIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcHJvbWlzZSBpcyBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuICBGb3J3YXJkc1xuICogdGhlIHJlc29sdXRpb24gdG8gdGhlIHJldHVybmVkIHByb21pc2Ugd2hlbiB0aGUgY2FsbGJhY2sgaXMgZG9uZS5cbiAqIFRoZSBjYWxsYmFjayBjYW4gcmV0dXJuIGEgcHJvbWlzZSB0byBkZWZlciBjb21wbGV0aW9uLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBvYnNlcnZlIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlblxuICogcHJvbWlzZSwgdGFrZXMgbm8gYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSB3aGVuXG4gKiBgYGZpbmBgIGlzIGRvbmUuXG4gKi9cblEuZmluID0gLy8gWFhYIGxlZ2FjeVxuUVtcImZpbmFsbHlcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdClbXCJmaW5hbGx5XCJdKGNhbGxiYWNrKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZpbiA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gVE9ETyBhdHRlbXB0IHRvIHJlY3ljbGUgdGhlIHJlamVjdGlvbiB3aXRoIFwidGhpc1wiLlxuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFRlcm1pbmF0ZXMgYSBjaGFpbiBvZiBwcm9taXNlcywgZm9yY2luZyByZWplY3Rpb25zIHRvIGJlXG4gKiB0aHJvd24gYXMgZXhjZXB0aW9ucy5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBhdCB0aGUgZW5kIG9mIGEgY2hhaW4gb2YgcHJvbWlzZXNcbiAqIEByZXR1cm5zIG5vdGhpbmdcbiAqL1xuUS5kb25lID0gZnVuY3Rpb24gKG9iamVjdCwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRvbmUoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHZhciBvblVuaGFuZGxlZEVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIC8vIGZvcndhcmQgdG8gYSBmdXR1cmUgdHVybiBzbyB0aGF0IGBgd2hlbmBgXG4gICAgICAgIC8vIGRvZXMgbm90IGNhdGNoIGl0IGFuZCB0dXJuIGl0IGludG8gYSByZWplY3Rpb24uXG4gICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIEF2b2lkIHVubmVjZXNzYXJ5IGBuZXh0VGlja2BpbmcgdmlhIGFuIHVubmVjZXNzYXJ5IGB3aGVuYC5cbiAgICB2YXIgcHJvbWlzZSA9IGZ1bGZpbGxlZCB8fCByZWplY3RlZCB8fCBwcm9ncmVzcyA/XG4gICAgICAgIHRoaXMudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykgOlxuICAgICAgICB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5kb21haW4pIHtcbiAgICAgICAgb25VbmhhbmRsZWRFcnJvciA9IHByb2Nlc3MuZG9tYWluLmJpbmQob25VbmhhbmRsZWRFcnJvcik7XG4gICAgfVxuXG4gICAgcHJvbWlzZS50aGVuKHZvaWQgMCwgb25VbmhhbmRsZWRFcnJvcik7XG59O1xuXG4vKipcbiAqIENhdXNlcyBhIHByb21pc2UgdG8gYmUgcmVqZWN0ZWQgaWYgaXQgZG9lcyBub3QgZ2V0IGZ1bGZpbGxlZCBiZWZvcmVcbiAqIHNvbWUgbWlsbGlzZWNvbmRzIHRpbWUgb3V0LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzIHRpbWVvdXRcbiAqIEBwYXJhbSB7QW55Kn0gY3VzdG9tIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0IChvcHRpb25hbClcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UgaWYgaXQgaXNcbiAqIGZ1bGZpbGxlZCBiZWZvcmUgdGhlIHRpbWVvdXQsIG90aGVyd2lzZSByZWplY3RlZC5cbiAqL1xuUS50aW1lb3V0ID0gZnVuY3Rpb24gKG9iamVjdCwgbXMsIGVycm9yKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aW1lb3V0KG1zLCBlcnJvcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24gKG1zLCBlcnJvcikge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWVycm9yIHx8IFwic3RyaW5nXCIgPT09IHR5cGVvZiBlcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IgfHwgXCJUaW1lZCBvdXQgYWZ0ZXIgXCIgKyBtcyArIFwiIG1zXCIpO1xuICAgICAgICAgICAgZXJyb3IuY29kZSA9IFwiRVRJTUVET1VUXCI7XG4gICAgICAgIH1cbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycm9yKTtcbiAgICB9LCBtcyk7XG5cbiAgICB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9LCBkZWZlcnJlZC5ub3RpZnkpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZ2l2ZW4gdmFsdWUgKG9yIHByb21pc2VkIHZhbHVlKSwgc29tZVxuICogbWlsbGlzZWNvbmRzIGFmdGVyIGl0IHJlc29sdmVkLiBQYXNzZXMgcmVqZWN0aW9ucyBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbGxpc2Vjb25kc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBhZnRlciBtaWxsaXNlY29uZHNcbiAqIHRpbWUgaGFzIGVsYXBzZWQgc2luY2UgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UuXG4gKiBJZiB0aGUgZ2l2ZW4gcHJvbWlzZSByZWplY3RzLCB0aGF0IGlzIHBhc3NlZCBpbW1lZGlhdGVseS5cbiAqL1xuUS5kZWxheSA9IGZ1bmN0aW9uIChvYmplY3QsIHRpbWVvdXQpIHtcbiAgICBpZiAodGltZW91dCA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBvYmplY3Q7XG4gICAgICAgIG9iamVjdCA9IHZvaWQgMDtcbiAgICB9XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kZWxheSh0aW1lb3V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3NlcyBhIGNvbnRpbnVhdGlvbiB0byBhIE5vZGUgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCB3aXRoIHRoZSBnaXZlblxuICogYXJndW1lbnRzIHByb3ZpZGVkIGFzIGFuIGFycmF5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKlxuICogICAgICBRLm5mYXBwbHkoRlMucmVhZEZpbGUsIFtfX2ZpbGVuYW1lXSlcbiAqICAgICAgLnRoZW4oZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAqICAgICAgfSlcbiAqXG4gKi9cblEubmZhcHBseSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgYXJncykge1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgaW5kaXZpZHVhbGx5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmNhbGwoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpXG4gKiAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogfSlcbiAqXG4gKi9cblEubmZjYWxsID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZjYWxsID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBXcmFwcyBhIE5vZGVKUyBjb250aW51YXRpb24gcGFzc2luZyBmdW5jdGlvbiBhbmQgcmV0dXJucyBhbiBlcXVpdmFsZW50XG4gKiB2ZXJzaW9uIHRoYXQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmJpbmQoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpKFwidXRmLThcIilcbiAqIC50aGVuKGNvbnNvbGUubG9nKVxuICogLmRvbmUoKVxuICovXG5RLm5mYmluZCA9XG5RLmRlbm9kZWlmeSA9IGZ1bmN0aW9uIChjYWxsYmFjayAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIFEoY2FsbGJhY2spLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZiaW5kID1cblByb21pc2UucHJvdG90eXBlLmRlbm9kZWlmeSA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgcmV0dXJuIFEuZGVub2RlaWZ5LmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG5RLm5iaW5kID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzcCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIGZ1bmN0aW9uIGJvdW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXNwLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIFEoYm91bmQpLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmJpbmQgPSBmdW5jdGlvbiAoLyp0aGlzcCwgLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDApO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5uYmluZC5hcHBseSh2b2lkIDAsIGFyZ3MpO1xufTtcblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvZiBhIE5vZGUtc3R5bGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIE5vZGUtc3R5bGVcbiAqIGNhbGxiYWNrIHdpdGggYSBnaXZlbiBhcnJheSBvZiBhcmd1bWVudHMsIHBsdXMgYSBwcm92aWRlZCBjYWxsYmFjay5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrXG4gKiB3aWxsIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLm5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkubnBvc3QobmFtZSwgYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLm5wb3N0ID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzIHx8IFtdKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2ssIGZvcndhcmRpbmcgdGhlIGdpdmVuIHZhcmlhZGljIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkXG4gKiBjYWxsYmFjayBhcmd1bWVudC5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSAuLi5hcmdzIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2Q7IHRoZSBjYWxsYmFjayB3aWxsXG4gKiBiZSBwcm92aWRlZCBieSBRIGFuZCBhcHBlbmRlZCB0byB0aGVzZSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSB2YWx1ZSBvciBlcnJvclxuICovXG5RLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblEubm1jYWxsID0gLy8gWFhYIEJhc2VkIG9uIFwiUmVkc2FuZHJvJ3NcIiBwcm9wb3NhbFxuUS5uaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uc2VuZCA9IC8vIFhYWCBCYXNlZCBvbiBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIFwic2VuZFwiXG5Qcm9taXNlLnByb3RvdHlwZS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5Qcm9taXNlLnByb3RvdHlwZS5uaW52b2tlID0gZnVuY3Rpb24gKG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogSWYgYSBmdW5jdGlvbiB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgYm90aCBOb2RlIGNvbnRpbnVhdGlvbi1wYXNzaW5nLXN0eWxlIGFuZFxuICogcHJvbWlzZS1yZXR1cm5pbmctc3R5bGUsIGl0IGNhbiBlbmQgaXRzIGludGVybmFsIHByb21pc2UgY2hhaW4gd2l0aFxuICogYG5vZGVpZnkobm9kZWJhY2spYCwgZm9yd2FyZGluZyB0aGUgb3B0aW9uYWwgbm9kZWJhY2sgYXJndW1lbnQuICBJZiB0aGUgdXNlclxuICogZWxlY3RzIHRvIHVzZSBhIG5vZGViYWNrLCB0aGUgcmVzdWx0IHdpbGwgYmUgc2VudCB0aGVyZS4gIElmIHRoZXkgZG8gbm90XG4gKiBwYXNzIGEgbm9kZWJhY2ssIHRoZXkgd2lsbCByZWNlaXZlIHRoZSByZXN1bHQgcHJvbWlzZS5cbiAqIEBwYXJhbSBvYmplY3QgYSByZXN1bHQgKG9yIGEgcHJvbWlzZSBmb3IgYSByZXN1bHQpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBub2RlYmFjayBhIE5vZGUuanMtc3R5bGUgY2FsbGJhY2tcbiAqIEByZXR1cm5zIGVpdGhlciB0aGUgcHJvbWlzZSBvciBub3RoaW5nXG4gKi9cblEubm9kZWlmeSA9IG5vZGVpZnk7XG5mdW5jdGlvbiBub2RlaWZ5KG9iamVjdCwgbm9kZWJhY2spIHtcbiAgICByZXR1cm4gUShvYmplY3QpLm5vZGVpZnkobm9kZWJhY2spO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrKSB7XG4gICAgaWYgKG5vZGViYWNrKSB7XG4gICAgICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKG51bGwsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuXG5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJRLm5vQ29uZmxpY3Qgb25seSB3b3JrcyB3aGVuIFEgaXMgdXNlZCBhcyBhIGdsb2JhbFwiKTtcbn07XG5cbi8vIEFsbCBjb2RlIGJlZm9yZSB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMuXG52YXIgcUVuZGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xuXG5yZXR1cm4gUTtcblxufSk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKCdfcHJvY2VzcycpKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXhMM0V1YW5NaVhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWp0QlFVRkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpTHk4Z2RtbHRPblJ6UFRRNmMzUnpQVFE2YzNjOU5EcGNiaThxSVZ4dUlDcGNiaUFxSUVOdmNIbHlhV2RvZENBeU1EQTVMVEl3TVRJZ1MzSnBjeUJMYjNkaGJDQjFibVJsY2lCMGFHVWdkR1Z5YlhNZ2IyWWdkR2hsSUUxSlZGeHVJQ29nYkdsalpXNXpaU0JtYjNWdVpDQmhkQ0JvZEhSd09pOHZaMmwwYUhWaUxtTnZiUzlyY21semEyOTNZV3d2Y1M5eVlYY3ZiV0Z6ZEdWeUwweEpRMFZPVTBWY2JpQXFYRzRnS2lCWGFYUm9JSEJoY25SeklHSjVJRlI1YkdWeUlFTnNiM05sWEc0Z0tpQkRiM0I1Y21sbmFIUWdNakF3TnkweU1EQTVJRlI1YkdWeUlFTnNiM05sSUhWdVpHVnlJSFJvWlNCMFpYSnRjeUJ2WmlCMGFHVWdUVWxVSUZnZ2JHbGpaVzV6WlNCbWIzVnVaRnh1SUNvZ1lYUWdhSFIwY0RvdkwzZDNkeTV2Y0dWdWMyOTFjbU5sTG05eVp5OXNhV05sYm5ObGN5OXRhWFF0YkdsalpXNXpaUzVvZEcxc1hHNGdLaUJHYjNKclpXUWdZWFFnY21WbVgzTmxibVF1YW5NZ2RtVnljMmx2YmpvZ01qQXdPUzB3TlMweE1WeHVJQ3BjYmlBcUlGZHBkR2dnY0dGeWRITWdZbmtnVFdGeWF5Qk5hV3hzWlhKY2JpQXFJRU52Y0hseWFXZG9kQ0FvUXlrZ01qQXhNU0JIYjI5bmJHVWdTVzVqTGx4dUlDcGNiaUFxSUV4cFkyVnVjMlZrSUhWdVpHVnlJSFJvWlNCQmNHRmphR1VnVEdsalpXNXpaU3dnVm1WeWMybHZiaUF5TGpBZ0tIUm9aU0JjSWt4cFkyVnVjMlZjSWlrN1hHNGdLaUI1YjNVZ2JXRjVJRzV2ZENCMWMyVWdkR2hwY3lCbWFXeGxJR1Y0WTJWd2RDQnBiaUJqYjIxd2JHbGhibU5sSUhkcGRHZ2dkR2hsSUV4cFkyVnVjMlV1WEc0Z0tpQlpiM1VnYldGNUlHOWlkR0ZwYmlCaElHTnZjSGtnYjJZZ2RHaGxJRXhwWTJWdWMyVWdZWFJjYmlBcVhHNGdLaUJvZEhSd09pOHZkM2QzTG1Gd1lXTm9aUzV2Y21jdmJHbGpaVzV6WlhNdlRFbERSVTVUUlMweUxqQmNiaUFxWEc0Z0tpQlZibXhsYzNNZ2NtVnhkV2x5WldRZ1lua2dZWEJ3YkdsallXSnNaU0JzWVhjZ2IzSWdZV2R5WldWa0lIUnZJR2x1SUhkeWFYUnBibWNzSUhOdlpuUjNZWEpsWEc0Z0tpQmthWE4wY21saWRYUmxaQ0IxYm1SbGNpQjBhR1VnVEdsalpXNXpaU0JwY3lCa2FYTjBjbWxpZFhSbFpDQnZiaUJoYmlCY0lrRlRJRWxUWENJZ1FrRlRTVk1zWEc0Z0tpQlhTVlJJVDFWVUlGZEJVbEpCVGxSSlJWTWdUMUlnUTA5T1JFbFVTVTlPVXlCUFJpQkJUbGtnUzBsT1JDd2daV2wwYUdWeUlHVjRjSEpsYzNNZ2IzSWdhVzF3YkdsbFpDNWNiaUFxSUZObFpTQjBhR1VnVEdsalpXNXpaU0JtYjNJZ2RHaGxJSE53WldOcFptbGpJR3hoYm1kMVlXZGxJR2R2ZG1WeWJtbHVaeUJ3WlhKdGFYTnphVzl1Y3lCaGJtUmNiaUFxSUd4cGJXbDBZWFJwYjI1eklIVnVaR1Z5SUhSb1pTQk1hV05sYm5ObExseHVJQ3BjYmlBcUwxeHVYRzRvWm5WdVkzUnBiMjRnS0dSbFptbHVhWFJwYjI0cElIdGNiaUFnSUNCY0luVnpaU0J6ZEhKcFkzUmNJanRjYmx4dUlDQWdJQzh2SUZSb2FYTWdabWxzWlNCM2FXeHNJR1oxYm1OMGFXOXVJSEJ5YjNCbGNteDVJR0Z6SUdFZ1BITmpjbWx3ZEQ0Z2RHRm5MQ0J2Y2lCaElHMXZaSFZzWlZ4dUlDQWdJQzh2SUhWemFXNW5JRU52YlcxdmJrcFRJR0Z1WkNCT2IyUmxTbE1nYjNJZ1VtVnhkV2x5WlVwVElHMXZaSFZzWlNCbWIzSnRZWFJ6TGlBZ1NXNWNiaUFnSUNBdkx5QkRiMjF0YjI0dlRtOWtaUzlTWlhGMWFYSmxTbE1zSUhSb1pTQnRiMlIxYkdVZ1pYaHdiM0owY3lCMGFHVWdVU0JCVUVrZ1lXNWtJSGRvWlc1Y2JpQWdJQ0F2THlCbGVHVmpkWFJsWkNCaGN5QmhJSE5wYlhCc1pTQThjMk55YVhCMFBpd2dhWFFnWTNKbFlYUmxjeUJoSUZFZ1oyeHZZbUZzSUdsdWMzUmxZV1F1WEc1Y2JpQWdJQ0F2THlCTmIyNTBZV2RsSUZKbGNYVnBjbVZjYmlBZ0lDQnBaaUFvZEhsd1pXOW1JR0p2YjNSemRISmhjQ0E5UFQwZ1hDSm1kVzVqZEdsdmJsd2lLU0I3WEc0Z0lDQWdJQ0FnSUdKdmIzUnpkSEpoY0NoY0luQnliMjFwYzJWY0lpd2daR1ZtYVc1cGRHbHZiaWs3WEc1Y2JpQWdJQ0F2THlCRGIyMXRiMjVLVTF4dUlDQWdJSDBnWld4elpTQnBaaUFvZEhsd1pXOW1JR1Y0Y0c5eWRITWdQVDA5SUZ3aWIySnFaV04wWENJZ0ppWWdkSGx3Wlc5bUlHMXZaSFZzWlNBOVBUMGdYQ0p2WW1wbFkzUmNJaWtnZTF4dUlDQWdJQ0FnSUNCdGIyUjFiR1V1Wlhod2IzSjBjeUE5SUdSbFptbHVhWFJwYjI0b0tUdGNibHh1SUNBZ0lDOHZJRkpsY1hWcGNtVktVMXh1SUNBZ0lIMGdaV3h6WlNCcFppQW9kSGx3Wlc5bUlHUmxabWx1WlNBOVBUMGdYQ0ptZFc1amRHbHZibHdpSUNZbUlHUmxabWx1WlM1aGJXUXBJSHRjYmlBZ0lDQWdJQ0FnWkdWbWFXNWxLR1JsWm1sdWFYUnBiMjRwTzF4dVhHNGdJQ0FnTHk4Z1UwVlRJQ2hUWldOMWNtVWdSV050WVZOamNtbHdkQ2xjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWE1nSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ2FXWWdLQ0Z6WlhNdWIyc29LU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdU8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWekxtMWhhMlZSSUQwZ1pHVm1hVzVwZEdsdmJqdGNiaUFnSUNBZ0lDQWdmVnh1WEc0Z0lDQWdMeThnUEhOamNtbHdkRDVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQjNhVzVrYjNjZ0lUMDlJRndpZFc1a1pXWnBibVZrWENJZ2ZId2dkSGx3Wlc5bUlITmxiR1lnSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0x5OGdVSEpsWm1WeUlIZHBibVJ2ZHlCdmRtVnlJSE5sYkdZZ1ptOXlJR0ZrWkMxdmJpQnpZM0pwY0hSekxpQlZjMlVnYzJWc1ppQm1iM0pjYmlBZ0lDQWdJQ0FnTHk4Z2JtOXVMWGRwYm1SdmQyVmtJR052Ym5SbGVIUnpMbHh1SUNBZ0lDQWdJQ0IyWVhJZ1oyeHZZbUZzSUQwZ2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaUEvSUhkcGJtUnZkeUE2SUhObGJHWTdYRzVjYmlBZ0lDQWdJQ0FnTHk4Z1IyVjBJSFJvWlNCZ2QybHVaRzkzWUNCdlltcGxZM1FzSUhOaGRtVWdkR2hsSUhCeVpYWnBiM1Z6SUZFZ1oyeHZZbUZzWEc0Z0lDQWdJQ0FnSUM4dklHRnVaQ0JwYm1sMGFXRnNhWHBsSUZFZ1lYTWdZU0JuYkc5aVlXd3VYRzRnSUNBZ0lDQWdJSFpoY2lCd2NtVjJhVzkxYzFFZ1BTQm5iRzlpWVd3dVVUdGNiaUFnSUNBZ0lDQWdaMnh2WW1Gc0xsRWdQU0JrWldacGJtbDBhVzl1S0NrN1hHNWNiaUFnSUNBZ0lDQWdMeThnUVdSa0lHRWdibTlEYjI1bWJHbGpkQ0JtZFc1amRHbHZiaUJ6YnlCUklHTmhiaUJpWlNCeVpXMXZkbVZrSUdaeWIyMGdkR2hsWEc0Z0lDQWdJQ0FnSUM4dklHZHNiMkpoYkNCdVlXMWxjM0JoWTJVdVhHNGdJQ0FnSUNBZ0lHZHNiMkpoYkM1UkxtNXZRMjl1Wm14cFkzUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JuYkc5aVlXd3VVU0E5SUhCeVpYWnBiM1Z6VVR0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQWdJQ0FnSUNCOU8xeHVYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Z3aVZHaHBjeUJsYm5acGNtOXViV1Z1ZENCM1lYTWdibTkwSUdGdWRHbGphWEJoZEdWa0lHSjVJRkV1SUZCc1pXRnpaU0JtYVd4bElHRWdZblZuTGx3aUtUdGNiaUFnSUNCOVhHNWNibjBwS0daMWJtTjBhVzl1SUNncElIdGNibHdpZFhObElITjBjbWxqZEZ3aU8xeHVYRzUyWVhJZ2FHRnpVM1JoWTJ0eklEMGdabUZzYzJVN1hHNTBjbmtnZTF4dUlDQWdJSFJvY205M0lHNWxkeUJGY25KdmNpZ3BPMXh1ZlNCallYUmphQ0FvWlNrZ2UxeHVJQ0FnSUdoaGMxTjBZV05yY3lBOUlDRWhaUzV6ZEdGamF6dGNibjFjYmx4dUx5OGdRV3hzSUdOdlpHVWdZV1owWlhJZ2RHaHBjeUJ3YjJsdWRDQjNhV3hzSUdKbElHWnBiSFJsY21Wa0lHWnliMjBnYzNSaFkyc2dkSEpoWTJWeklISmxjRzl5ZEdWa1hHNHZMeUJpZVNCUkxseHVkbUZ5SUhGVGRHRnlkR2x1WjB4cGJtVWdQU0JqWVhCMGRYSmxUR2x1WlNncE8xeHVkbUZ5SUhGR2FXeGxUbUZ0WlR0Y2JseHVMeThnYzJocGJYTmNibHh1THk4Z2RYTmxaQ0JtYjNJZ1ptRnNiR0poWTJzZ2FXNGdYQ0poYkd4U1pYTnZiSFpsWkZ3aVhHNTJZWElnYm05dmNDQTlJR1oxYm1OMGFXOXVJQ2dwSUh0OU8xeHVYRzR2THlCVmMyVWdkR2hsSUdaaGMzUmxjM1FnY0c5emMybGliR1VnYldWaGJuTWdkRzhnWlhobFkzVjBaU0JoSUhSaGMyc2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJseHVMeThnYjJZZ2RHaGxJR1YyWlc1MElHeHZiM0F1WEc1MllYSWdibVY0ZEZScFkyc2dQU2htZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnTHk4Z2JHbHVhMlZrSUd4cGMzUWdiMllnZEdGemEzTWdLSE5wYm1kc1pTd2dkMmwwYUNCb1pXRmtJRzV2WkdVcFhHNGdJQ0FnZG1GeUlHaGxZV1FnUFNCN2RHRnphem9nZG05cFpDQXdMQ0J1WlhoME9pQnVkV3hzZlR0Y2JpQWdJQ0IyWVhJZ2RHRnBiQ0E5SUdobFlXUTdYRzRnSUNBZ2RtRnlJR1pzZFhOb2FXNW5JRDBnWm1Gc2MyVTdYRzRnSUNBZ2RtRnlJSEpsY1hWbGMzUlVhV05ySUQwZ2RtOXBaQ0F3TzF4dUlDQWdJSFpoY2lCcGMwNXZaR1ZLVXlBOUlHWmhiSE5sTzF4dUlDQWdJQzh2SUhGMVpYVmxJR1p2Y2lCc1lYUmxJSFJoYzJ0ekxDQjFjMlZrSUdKNUlIVnVhR0Z1Wkd4bFpDQnlaV3BsWTNScGIyNGdkSEpoWTJ0cGJtZGNiaUFnSUNCMllYSWdiR0YwWlhKUmRXVjFaU0E5SUZ0ZE8xeHVYRzRnSUNBZ1puVnVZM1JwYjI0Z1pteDFjMmdvS1NCN1hHNGdJQ0FnSUNBZ0lDOHFJR3B6YUdsdWRDQnNiMjl3Wm5WdVl6b2dkSEoxWlNBcUwxeHVJQ0FnSUNBZ0lDQjJZWElnZEdGemF5d2daRzl0WVdsdU8xeHVYRzRnSUNBZ0lDQWdJSGRvYVd4bElDaG9aV0ZrTG01bGVIUXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHaGxZV1FnUFNCb1pXRmtMbTVsZUhRN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IwWVhOcklEMGdhR1ZoWkM1MFlYTnJPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FHVmhaQzUwWVhOcklEMGdkbTlwWkNBd08xeHVJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVJRDBnYUdWaFpDNWtiMjFoYVc0N1hHNWNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQm9aV0ZrTG1SdmJXRnBiaUE5SUhadmFXUWdNRHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrYjIxaGFXNHVaVzUwWlhJb0tUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0lDQWdJSEoxYmxOcGJtZHNaU2gwWVhOckxDQmtiMjFoYVc0cE8xeHVYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZDJocGJHVWdLR3hoZEdWeVVYVmxkV1V1YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBZWE5ySUQwZ2JHRjBaWEpSZFdWMVpTNXdiM0FvS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEoxYmxOcGJtZHNaU2gwWVhOcktUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0JtYkhWemFHbHVaeUE5SUdaaGJITmxPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnlkVzV6SUdFZ2MybHVaMnhsSUdaMWJtTjBhVzl1SUdsdUlIUm9aU0JoYzNsdVl5QnhkV1YxWlZ4dUlDQWdJR1oxYm1OMGFXOXVJSEoxYmxOcGJtZHNaU2gwWVhOckxDQmtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJoYzJzb0tUdGNibHh1SUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2FYTk9iMlJsU2xNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJKYmlCdWIyUmxMQ0IxYm1OaGRXZG9kQ0JsZUdObGNIUnBiMjV6SUdGeVpTQmpiMjV6YVdSbGNtVmtJR1poZEdGc0lHVnljbTl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QlNaUzEwYUhKdmR5QjBhR1Z0SUhONWJtTm9jbTl1YjNWemJIa2dkRzhnYVc1MFpYSnlkWEIwSUdac2RYTm9hVzVuSVZ4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0x5OGdSVzV6ZFhKbElHTnZiblJwYm5WaGRHbHZiaUJwWmlCMGFHVWdkVzVqWVhWbmFIUWdaWGhqWlhCMGFXOXVJR2x6SUhOMWNIQnlaWE56WldSY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QnNhWE4wWlc1cGJtY2dYQ0oxYm1OaGRXZG9kRVY0WTJWd2RHbHZibHdpSUdWMlpXNTBjeUFvWVhNZ1pHOXRZV2x1Y3lCa2IyVnpLUzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCRGIyNTBhVzUxWlNCcGJpQnVaWGgwSUdWMlpXNTBJSFJ2SUdGMmIybGtJSFJwWTJzZ2NtVmpkWEp6YVc5dUxseHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2hrYjIxaGFXNHBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1pHOXRZV2x1TG1WNGFYUW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYzJWMFZHbHRaVzkxZENobWJIVnphQ3dnTUNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2YldGcGJpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCa2IyMWhhVzR1Wlc1MFpYSW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsTzF4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQzh2SUVsdUlHSnliM2R6WlhKekxDQjFibU5oZFdkb2RDQmxlR05sY0hScGIyNXpJR0Z5WlNCdWIzUWdabUYwWVd3dVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0x5OGdVbVV0ZEdoeWIzY2dkR2hsYlNCaGMzbHVZMmh5YjI1dmRYTnNlU0IwYnlCaGRtOXBaQ0J6Ykc5M0xXUnZkMjV6TGx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhObGRGUnBiV1Z2ZFhRb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUgwc0lEQXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnYVdZZ0tHUnZiV0ZwYmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVMbVY0YVhRb0tUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMWNibHh1SUNBZ0lHNWxlSFJVYVdOcklEMGdablZ1WTNScGIyNGdLSFJoYzJzcElIdGNiaUFnSUNBZ0lDQWdkR0ZwYkNBOUlIUmhhV3d1Ym1WNGRDQTlJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUmhjMnM2SUhSaGMyc3NYRzRnSUNBZ0lDQWdJQ0FnSUNCa2IyMWhhVzQ2SUdselRtOWtaVXBUSUNZbUlIQnliMk5sYzNNdVpHOXRZV2x1TEZ4dUlDQWdJQ0FnSUNBZ0lDQWdibVY0ZERvZ2JuVnNiRnh1SUNBZ0lDQWdJQ0I5TzF4dVhHNGdJQ0FnSUNBZ0lHbG1JQ2doWm14MWMyaHBibWNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR1pzZFhOb2FXNW5JRDBnZEhKMVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcktDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJ3Y205alpYTnpJRDA5UFNCY0ltOWlhbVZqZEZ3aUlDWW1YRzRnSUNBZ0lDQWdJSEJ5YjJObGMzTXVkRzlUZEhKcGJtY29LU0E5UFQwZ1hDSmJiMkpxWldOMElIQnliMk5sYzNOZFhDSWdKaVlnY0hKdlkyVnpjeTV1WlhoMFZHbGpheWtnZTF4dUlDQWdJQ0FnSUNBdkx5QkZibk4xY21VZ1VTQnBjeUJwYmlCaElISmxZV3dnVG05a1pTQmxiblpwY205dWJXVnVkQ3dnZDJsMGFDQmhJR0J3Y205alpYTnpMbTVsZUhSVWFXTnJZQzVjYmlBZ0lDQWdJQ0FnTHk4Z1ZHOGdjMlZsSUhSb2NtOTFaMmdnWm1GclpTQk9iMlJsSUdWdWRtbHliMjV0Wlc1MGN6cGNiaUFnSUNBZ0lDQWdMeThnS2lCTmIyTm9ZU0IwWlhOMElISjFibTVsY2lBdElHVjRjRzl6WlhNZ1lTQmdjSEp2WTJWemMyQWdaMnh2WW1Gc0lIZHBkR2h2ZFhRZ1lTQmdibVY0ZEZScFkydGdYRzRnSUNBZ0lDQWdJQzh2SUNvZ1FuSnZkM05sY21sbWVTQXRJR1Y0Y0c5elpYTWdZU0JnY0hKdlkyVnpjeTV1WlhoVWFXTnJZQ0JtZFc1amRHbHZiaUIwYUdGMElIVnpaWE5jYmlBZ0lDQWdJQ0FnTHk4Z0lDQmdjMlYwVkdsdFpXOTFkR0F1SUVsdUlIUm9hWE1nWTJGelpTQmdjMlYwU1cxdFpXUnBZWFJsWUNCcGN5QndjbVZtWlhKeVpXUWdZbVZqWVhWelpWeHVJQ0FnSUNBZ0lDQXZMeUFnSUNCcGRDQnBjeUJtWVhOMFpYSXVJRUp5YjNkelpYSnBabmtuY3lCZ2NISnZZMlZ6Y3k1MGIxTjBjbWx1WnlncFlDQjVhV1ZzWkhOY2JpQWdJQ0FnSUNBZ0x5OGdJQ0JjSWx0dlltcGxZM1FnVDJKcVpXTjBYVndpTENCM2FHbHNaU0JwYmlCaElISmxZV3dnVG05a1pTQmxiblpwY205dWJXVnVkRnh1SUNBZ0lDQWdJQ0F2THlBZ0lHQndjbTlqWlhOekxtNWxlSFJVYVdOcktDbGdJSGxwWld4a2N5QmNJbHR2WW1wbFkzUWdjSEp2WTJWemMxMWNJaTVjYmlBZ0lDQWdJQ0FnYVhOT2IyUmxTbE1nUFNCMGNuVmxPMXh1WEc0Z0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2WTJWemN5NXVaWGgwVkdsamF5aG1iSFZ6YUNrN1hHNGdJQ0FnSUNBZ0lIMDdYRzVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWFJKYlcxbFpHbGhkR1VnUFQwOUlGd2lablZ1WTNScGIyNWNJaWtnZTF4dUlDQWdJQ0FnSUNBdkx5QkpiaUJKUlRFd0xDQk9iMlJsTG1weklEQXVPU3NzSUc5eUlHaDBkSEJ6T2k4dloybDBhSFZpTG1OdmJTOU9iMkpzWlVwVEwzTmxkRWx0YldWa2FXRjBaVnh1SUNBZ0lDQWdJQ0JwWmlBb2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ4ZFdWemRGUnBZMnNnUFNCelpYUkpiVzFsWkdsaGRHVXVZbWx1WkNoM2FXNWtiM2NzSUdac2RYTm9LVHRjYmlBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxjWFZsYzNSVWFXTnJJRDBnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lITmxkRWx0YldWa2FXRjBaU2htYkhWemFDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCOU8xeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQk5aWE56WVdkbFEyaGhibTVsYkNBaFBUMGdYQ0oxYm1SbFptbHVaV1JjSWlrZ2UxeHVJQ0FnSUNBZ0lDQXZMeUJ0YjJSbGNtNGdZbkp2ZDNObGNuTmNiaUFnSUNBZ0lDQWdMeThnYUhSMGNEb3ZMM2QzZHk1dWIyNWliRzlqYTJsdVp5NXBieTh5TURFeEx6QTJMM2RwYm1SdmQyNWxlSFIwYVdOckxtaDBiV3hjYmlBZ0lDQWdJQ0FnZG1GeUlHTm9ZVzV1Wld3Z1BTQnVaWGNnVFdWemMyRm5aVU5vWVc1dVpXd29LVHRjYmlBZ0lDQWdJQ0FnTHk4Z1FYUWdiR1ZoYzNRZ1UyRm1ZWEpwSUZabGNuTnBiMjRnTmk0d0xqVWdLRGcxTXpZdU16QXVNU2tnYVc1MFpYSnRhWFIwWlc1MGJIa2dZMkZ1Ym05MElHTnlaV0YwWlZ4dUlDQWdJQ0FnSUNBdkx5QjNiM0pyYVc1bklHMWxjM05oWjJVZ2NHOXlkSE1nZEdobElHWnBjbk4wSUhScGJXVWdZU0J3WVdkbElHeHZZV1J6TGx4dUlDQWdJQ0FnSUNCamFHRnVibVZzTG5CdmNuUXhMbTl1YldWemMyRm5aU0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdjbVZ4ZFdWemRGQnZjblJVYVdOck8xeHVJQ0FnSUNBZ0lDQWdJQ0FnWTJoaGJtNWxiQzV3YjNKME1TNXZibTFsYzNOaFoyVWdQU0JtYkhWemFEdGNiaUFnSUNBZ0lDQWdJQ0FnSUdac2RYTm9LQ2s3WEc0Z0lDQWdJQ0FnSUgwN1hHNGdJQ0FnSUNBZ0lIWmhjaUJ5WlhGMVpYTjBVRzl5ZEZScFkyc2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCUGNHVnlZU0J5WlhGMWFYSmxjeUIxY3lCMGJ5QndjbTkyYVdSbElHRWdiV1Z6YzJGblpTQndZWGxzYjJGa0xDQnlaV2RoY21Sc1pYTnpJRzltWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUIzYUdWMGFHVnlJSGRsSUhWelpTQnBkQzVjYmlBZ0lDQWdJQ0FnSUNBZ0lHTm9ZVzV1Wld3dWNHOXlkREl1Y0c5emRFMWxjM05oWjJVb01DazdYRzRnSUNBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlYwVkdsdFpXOTFkQ2htYkhWemFDd2dNQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWEYxWlhOMFVHOXlkRlJwWTJzb0tUdGNiaUFnSUNBZ0lDQWdmVHRjYmx4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQzh2SUc5c1pDQmljbTkzYzJWeWMxeHVJQ0FnSUNBZ0lDQnlaWEYxWlhOMFZHbGpheUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhObGRGUnBiV1Z2ZFhRb1pteDFjMmdzSURBcE8xeHVJQ0FnSUNBZ0lDQjlPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnlkVzV6SUdFZ2RHRnpheUJoWm5SbGNpQmhiR3dnYjNSb1pYSWdkR0Z6YTNNZ2FHRjJaU0JpWldWdUlISjFibHh1SUNBZ0lDOHZJSFJvYVhNZ2FYTWdkWE5sWm5Wc0lHWnZjaUIxYm1oaGJtUnNaV1FnY21WcVpXTjBhVzl1SUhSeVlXTnJhVzVuSUhSb1lYUWdibVZsWkhNZ2RHOGdhR0Z3Y0dWdVhHNGdJQ0FnTHk4Z1lXWjBaWElnWVd4c0lHQjBhR1Z1WUdRZ2RHRnphM01nYUdGMlpTQmlaV1Z1SUhKMWJpNWNiaUFnSUNCdVpYaDBWR2xqYXk1eWRXNUJablJsY2lBOUlHWjFibU4wYVc5dUlDaDBZWE5yS1NCN1hHNGdJQ0FnSUNBZ0lHeGhkR1Z5VVhWbGRXVXVjSFZ6YUNoMFlYTnJLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tDRm1iSFZ6YUdsdVp5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pteDFjMmhwYm1jZ1BTQjBjblZsTzF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ4ZFdWemRGUnBZMnNvS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwN1hHNGdJQ0FnY21WMGRYSnVJRzVsZUhSVWFXTnJPMXh1ZlNrb0tUdGNibHh1THk4Z1FYUjBaVzF3ZENCMGJ5QnRZV3RsSUdkbGJtVnlhV056SUhOaFptVWdhVzRnZEdobElHWmhZMlVnYjJZZ1pHOTNibk4wY21WaGJWeHVMeThnYlc5a2FXWnBZMkYwYVc5dWN5NWNiaTh2SUZSb1pYSmxJR2x6SUc1dklITnBkSFZoZEdsdmJpQjNhR1Z5WlNCMGFHbHpJR2x6SUc1bFkyVnpjMkZ5ZVM1Y2JpOHZJRWxtSUhsdmRTQnVaV1ZrSUdFZ2MyVmpkWEpwZEhrZ1ozVmhjbUZ1ZEdWbExDQjBhR1Z6WlNCd2NtbHRiM0prYVdGc2N5QnVaV1ZrSUhSdklHSmxYRzR2THlCa1pXVndiSGtnWm5KdmVtVnVJR0Z1ZVhkaGVTd2dZVzVrSUdsbUlIbHZkU0JrYjI3aWdKbDBJRzVsWldRZ1lTQnpaV04xY21sMGVTQm5kV0Z5WVc1MFpXVXNYRzR2THlCMGFHbHpJR2x6SUdwMWMzUWdjR3hoYVc0Z2NHRnlZVzV2YVdRdVhHNHZMeUJJYjNkbGRtVnlMQ0IwYUdseklDb3FiV2xuYUhRcUtpQm9ZWFpsSUhSb1pTQnVhV05sSUhOcFpHVXRaV1ptWldOMElHOW1JSEpsWkhWamFXNW5JSFJvWlNCemFYcGxJRzltWEc0dkx5QjBhR1VnYldsdWFXWnBaV1FnWTI5a1pTQmllU0J5WldSMVkybHVaeUI0TG1OaGJHd29LU0IwYnlCdFpYSmxiSGtnZUNncFhHNHZMeUJUWldVZ1RXRnlheUJOYVd4c1pYTGlnSmx6SUdWNGNHeGhibUYwYVc5dUlHOW1JSGRvWVhRZ2RHaHBjeUJrYjJWekxseHVMeThnYUhSMGNEb3ZMM2RwYTJrdVpXTnRZWE5qY21sd2RDNXZjbWN2Wkc5cmRTNXdhSEEvYVdROVkyOXVkbVZ1ZEdsdmJuTTZjMkZtWlY5dFpYUmhYM0J5YjJkeVlXMXRhVzVuWEc1MllYSWdZMkZzYkNBOUlFWjFibU4wYVc5dUxtTmhiR3c3WEc1bWRXNWpkR2x2YmlCMWJtTjFjbko1VkdocGN5aG1LU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd3dVlYQndiSGtvWml3Z1lYSm5kVzFsYm5SektUdGNiaUFnSUNCOU8xeHVmVnh1THk4Z1ZHaHBjeUJwY3lCbGNYVnBkbUZzWlc1MExDQmlkWFFnYzJ4dmQyVnlPbHh1THk4Z2RXNWpkWEp5ZVZSb2FYTWdQU0JHZFc1amRHbHZibDlpYVc1a0xtSnBibVFvUm5WdVkzUnBiMjVmWW1sdVpDNWpZV3hzS1R0Y2JpOHZJR2gwZEhBNkx5OXFjM0JsY21ZdVkyOXRMM1Z1WTNWeWNubDBhR2x6WEc1Y2JuWmhjaUJoY25KaGVWOXpiR2xqWlNBOUlIVnVZM1Z5Y25sVWFHbHpLRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXpiR2xqWlNrN1hHNWNiblpoY2lCaGNuSmhlVjl5WldSMVkyVWdQU0IxYm1OMWNuSjVWR2hwY3loY2JpQWdJQ0JCY25KaGVTNXdjbTkwYjNSNWNHVXVjbVZrZFdObElIeDhJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheXdnWW1GemFYTXBJSHRjYmlBZ0lDQWdJQ0FnZG1GeUlHbHVaR1Y0SUQwZ01DeGNiaUFnSUNBZ0lDQWdJQ0FnSUd4bGJtZDBhQ0E5SUhSb2FYTXViR1Z1WjNSb08xeHVJQ0FnSUNBZ0lDQXZMeUJqYjI1alpYSnVhVzVuSUhSb1pTQnBibWwwYVdGc0lIWmhiSFZsTENCcFppQnZibVVnYVhNZ2JtOTBJSEJ5YjNacFpHVmtYRzRnSUNBZ0lDQWdJR2xtSUNoaGNtZDFiV1Z1ZEhNdWJHVnVaM1JvSUQwOVBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJ6WldWcklIUnZJSFJvWlNCbWFYSnpkQ0IyWVd4MVpTQnBiaUIwYUdVZ1lYSnlZWGtzSUdGalkyOTFiblJwYm1kY2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUdadmNpQjBhR1VnY0c5emMybGlhV3hwZEhrZ2RHaGhkQ0JwY3lCcGN5QmhJSE53WVhKelpTQmhjbkpoZVZ4dUlDQWdJQ0FnSUNBZ0lDQWdaRzhnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDaHBibVJsZUNCcGJpQjBhR2x6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR0poYzJseklEMGdkR2hwYzF0cGJtUmxlQ3NyWFR0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdZbkpsWVdzN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2dySzJsdVpHVjRJRDQ5SUd4bGJtZDBhQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBhSEp2ZHlCdVpYY2dWSGx3WlVWeWNtOXlLQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU0IzYUdsc1pTQW9NU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0x5OGdjbVZrZFdObFhHNGdJQ0FnSUNBZ0lHWnZjaUFvT3lCcGJtUmxlQ0E4SUd4bGJtZDBhRHNnYVc1a1pYZ3JLeWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdMeThnWVdOamIzVnVkQ0JtYjNJZ2RHaGxJSEJ2YzNOcFltbHNhWFI1SUhSb1lYUWdkR2hsSUdGeWNtRjVJR2x6SUhOd1lYSnpaVnh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR2x1WkdWNElHbHVJSFJvYVhNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmlZWE5wY3lBOUlHTmhiR3hpWVdOcktHSmhjMmx6TENCMGFHbHpXMmx1WkdWNFhTd2dhVzVrWlhncE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCaVlYTnBjenRjYmlBZ0lDQjlYRzRwTzF4dVhHNTJZWElnWVhKeVlYbGZhVzVrWlhoUFppQTlJSFZ1WTNWeWNubFVhR2x6S0Z4dUlDQWdJRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXBibVJsZUU5bUlIeDhJR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0F2THlCdWIzUWdZU0IyWlhKNUlHZHZiMlFnYzJocGJTd2dZblYwSUdkdmIyUWdaVzV2ZFdkb0lHWnZjaUJ2ZFhJZ2IyNWxJSFZ6WlNCdlppQnBkRnh1SUNBZ0lDQWdJQ0JtYjNJZ0tIWmhjaUJwSUQwZ01Ec2dhU0E4SUhSb2FYTXViR1Z1WjNSb095QnBLeXNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMGFHbHpXMmxkSUQwOVBTQjJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlBdE1UdGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdZWEp5WVhsZmJXRndJRDBnZFc1amRYSnllVlJvYVhNb1hHNGdJQ0FnUVhKeVlYa3VjSEp2ZEc5MGVYQmxMbTFoY0NCOGZDQm1kVzVqZEdsdmJpQW9ZMkZzYkdKaFkyc3NJSFJvYVhOd0tTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCelpXeG1JRDBnZEdocGN6dGNiaUFnSUNBZ0lDQWdkbUZ5SUdOdmJHeGxZM1FnUFNCYlhUdGNiaUFnSUNBZ0lDQWdZWEp5WVhsZmNtVmtkV05sS0hObGJHWXNJR1oxYm1OMGFXOXVJQ2gxYm1SbFptbHVaV1FzSUhaaGJIVmxMQ0JwYm1SbGVDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1kyOXNiR1ZqZEM1d2RYTm9LR05oYkd4aVlXTnJMbU5oYkd3b2RHaHBjM0FzSUhaaGJIVmxMQ0JwYm1SbGVDd2djMlZzWmlrcE8xeHVJQ0FnSUNBZ0lDQjlMQ0IyYjJsa0lEQXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdZMjlzYkdWamREdGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdiMkpxWldOMFgyTnlaV0YwWlNBOUlFOWlhbVZqZEM1amNtVmhkR1VnZkh3Z1puVnVZM1JwYjI0Z0tIQnliM1J2ZEhsd1pTa2dlMXh1SUNBZ0lHWjFibU4wYVc5dUlGUjVjR1VvS1NCN0lIMWNiaUFnSUNCVWVYQmxMbkJ5YjNSdmRIbHdaU0E5SUhCeWIzUnZkSGx3WlR0Y2JpQWdJQ0J5WlhSMWNtNGdibVYzSUZSNWNHVW9LVHRjYm4wN1hHNWNiblpoY2lCdlltcGxZM1JmYUdGelQzZHVVSEp2Y0dWeWRIa2dQU0IxYm1OMWNuSjVWR2hwY3loUFltcGxZM1F1Y0hKdmRHOTBlWEJsTG1oaGMwOTNibEJ5YjNCbGNuUjVLVHRjYmx4dWRtRnlJRzlpYW1WamRGOXJaWGx6SUQwZ1QySnFaV04wTG10bGVYTWdmSHdnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSFpoY2lCclpYbHpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaDJZWElnYTJWNUlHbHVJRzlpYW1WamRDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2IySnFaV04wWDJoaGMwOTNibEJ5YjNCbGNuUjVLRzlpYW1WamRDd2dhMlY1S1NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYTJWNWN5NXdkWE5vS0d0bGVTazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUd0bGVYTTdYRzU5TzF4dVhHNTJZWElnYjJKcVpXTjBYM1J2VTNSeWFXNW5JRDBnZFc1amRYSnllVlJvYVhNb1QySnFaV04wTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1WnlrN1hHNWNibVoxYm1OMGFXOXVJR2x6VDJKcVpXTjBLSFpoYkhWbEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUhaaGJIVmxJRDA5UFNCUFltcGxZM1FvZG1Gc2RXVXBPMXh1ZlZ4dVhHNHZMeUJuWlc1bGNtRjBiM0lnY21Wc1lYUmxaQ0J6YUdsdGMxeHVYRzR2THlCR1NWaE5SVG9nVW1WdGIzWmxJSFJvYVhNZ1puVnVZM1JwYjI0Z2IyNWpaU0JGVXpZZ1oyVnVaWEpoZEc5eWN5QmhjbVVnYVc0Z1UzQnBaR1Z5VFc5dWEyVjVMbHh1Wm5WdVkzUnBiMjRnYVhOVGRHOXdTWFJsY21GMGFXOXVLR1Y0WTJWd2RHbHZiaWtnZTF4dUlDQWdJSEpsZEhWeWJpQW9YRzRnSUNBZ0lDQWdJRzlpYW1WamRGOTBiMU4wY21sdVp5aGxlR05sY0hScGIyNHBJRDA5UFNCY0lsdHZZbXBsWTNRZ1UzUnZjRWwwWlhKaGRHbHZibDFjSWlCOGZGeHVJQ0FnSUNBZ0lDQmxlR05sY0hScGIyNGdhVzV6ZEdGdVkyVnZaaUJSVW1WMGRYSnVWbUZzZFdWY2JpQWdJQ0FwTzF4dWZWeHVYRzR2THlCR1NWaE5SVG9nVW1WdGIzWmxJSFJvYVhNZ2FHVnNjR1Z5SUdGdVpDQlJMbkpsZEhWeWJpQnZibU5sSUVWVE5pQm5aVzVsY21GMGIzSnpJR0Z5WlNCcGJseHVMeThnVTNCcFpHVnlUVzl1YTJWNUxseHVkbUZ5SUZGU1pYUjFjbTVXWVd4MVpUdGNibWxtSUNoMGVYQmxiMllnVW1WMGRYSnVWbUZzZFdVZ0lUMDlJRndpZFc1a1pXWnBibVZrWENJcElIdGNiaUFnSUNCUlVtVjBkWEp1Vm1Gc2RXVWdQU0JTWlhSMWNtNVdZV3gxWlR0Y2JuMGdaV3h6WlNCN1hHNGdJQ0FnVVZKbGRIVnlibFpoYkhWbElEMGdablZ1WTNScGIyNGdLSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWRtRnNkV1VnUFNCMllXeDFaVHRjYmlBZ0lDQjlPMXh1ZlZ4dVhHNHZMeUJzYjI1bklITjBZV05ySUhSeVlXTmxjMXh1WEc1MllYSWdVMVJCUTB0ZlNsVk5VRjlUUlZCQlVrRlVUMUlnUFNCY0lrWnliMjBnY0hKbGRtbHZkWE1nWlhabGJuUTZYQ0k3WEc1Y2JtWjFibU4wYVc5dUlHMWhhMlZUZEdGamExUnlZV05sVEc5dVp5aGxjbkp2Y2l3Z2NISnZiV2x6WlNrZ2UxeHVJQ0FnSUM4dklFbG1JSEJ2YzNOcFlteGxMQ0IwY21GdWMyWnZjbTBnZEdobElHVnljbTl5SUhOMFlXTnJJSFJ5WVdObElHSjVJSEpsYlc5MmFXNW5JRTV2WkdVZ1lXNWtJRkZjYmlBZ0lDQXZMeUJqY25WbWRDd2dkR2hsYmlCamIyNWpZWFJsYm1GMGFXNW5JSGRwZEdnZ2RHaGxJSE4wWVdOcklIUnlZV05sSUc5bUlHQndjbTl0YVhObFlDNGdVMlZsSUNNMU55NWNiaUFnSUNCcFppQW9hR0Z6VTNSaFkydHpJQ1ltWEc0Z0lDQWdJQ0FnSUhCeWIyMXBjMlV1YzNSaFkyc2dKaVpjYmlBZ0lDQWdJQ0FnZEhsd1pXOW1JR1Z5Y205eUlEMDlQU0JjSW05aWFtVmpkRndpSUNZbVhHNGdJQ0FnSUNBZ0lHVnljbTl5SUNFOVBTQnVkV3hzSUNZbVhHNGdJQ0FnSUNBZ0lHVnljbTl5TG5OMFlXTnJJQ1ltWEc0Z0lDQWdJQ0FnSUdWeWNtOXlMbk4wWVdOckxtbHVaR1Y0VDJZb1UxUkJRMHRmU2xWTlVGOVRSVkJCVWtGVVQxSXBJRDA5UFNBdE1WeHVJQ0FnSUNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYzNSaFkydHpJRDBnVzEwN1hHNGdJQ0FnSUNBZ0lHWnZjaUFvZG1GeUlIQWdQU0J3Y205dGFYTmxPeUFoSVhBN0lIQWdQU0J3TG5OdmRYSmpaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0hBdWMzUmhZMnNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCemRHRmphM011ZFc1emFHbG1kQ2h3TG5OMFlXTnJLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0J6ZEdGamEzTXVkVzV6YUdsbWRDaGxjbkp2Y2k1emRHRmpheWs3WEc1Y2JpQWdJQ0FnSUNBZ2RtRnlJR052Ym1OaGRHVmtVM1JoWTJ0eklEMGdjM1JoWTJ0ekxtcHZhVzRvWENKY1hHNWNJaUFySUZOVVFVTkxYMHBWVFZCZlUwVlFRVkpCVkU5U0lDc2dYQ0pjWEc1Y0lpazdYRzRnSUNBZ0lDQWdJR1Z5Y205eUxuTjBZV05ySUQwZ1ptbHNkR1Z5VTNSaFkydFRkSEpwYm1jb1kyOXVZMkYwWldSVGRHRmphM01wTzF4dUlDQWdJSDFjYm4xY2JseHVablZ1WTNScGIyNGdabWxzZEdWeVUzUmhZMnRUZEhKcGJtY29jM1JoWTJ0VGRISnBibWNwSUh0Y2JpQWdJQ0IyWVhJZ2JHbHVaWE1nUFNCemRHRmphMU4wY21sdVp5NXpjR3hwZENoY0lseGNibHdpS1R0Y2JpQWdJQ0IyWVhJZ1pHVnphWEpsWkV4cGJtVnpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaDJZWElnYVNBOUlEQTdJR2tnUENCc2FXNWxjeTVzWlc1bmRHZzdJQ3NyYVNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYkdsdVpTQTlJR3hwYm1WelcybGRPMXh1WEc0Z0lDQWdJQ0FnSUdsbUlDZ2hhWE5KYm5SbGNtNWhiRVp5WVcxbEtHeHBibVVwSUNZbUlDRnBjMDV2WkdWR2NtRnRaU2hzYVc1bEtTQW1KaUJzYVc1bEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pYTnBjbVZrVEdsdVpYTXVjSFZ6YUNoc2FXNWxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDFjYmlBZ0lDQnlaWFIxY200Z1pHVnphWEpsWkV4cGJtVnpMbXB2YVc0b1hDSmNYRzVjSWlrN1hHNTlYRzVjYm1aMWJtTjBhVzl1SUdselRtOWtaVVp5WVcxbEtITjBZV05yVEdsdVpTa2dlMXh1SUNBZ0lISmxkSFZ5YmlCemRHRmphMHhwYm1VdWFXNWtaWGhQWmloY0lpaHRiMlIxYkdVdWFuTTZYQ0lwSUNFOVBTQXRNU0I4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQnpkR0ZqYTB4cGJtVXVhVzVrWlhoUFppaGNJaWh1YjJSbExtcHpPbHdpS1NBaFBUMGdMVEU3WEc1OVhHNWNibVoxYm1OMGFXOXVJR2RsZEVacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNpaHpkR0ZqYTB4cGJtVXBJSHRjYmlBZ0lDQXZMeUJPWVcxbFpDQm1kVzVqZEdsdmJuTTZJRndpWVhRZ1puVnVZM1JwYjI1T1lXMWxJQ2htYVd4bGJtRnRaVHBzYVc1bFRuVnRZbVZ5T21OdmJIVnRiazUxYldKbGNpbGNJbHh1SUNBZ0lDOHZJRWx1SUVsRk1UQWdablZ1WTNScGIyNGdibUZ0WlNCallXNGdhR0YyWlNCemNHRmpaWE1nS0Z3aVFXNXZibmx0YjNWeklHWjFibU4wYVc5dVhDSXBJRTlmYjF4dUlDQWdJSFpoY2lCaGRIUmxiWEIwTVNBOUlDOWhkQ0F1S3lCY1hDZ29MaXNwT2loY1hHUXJLVG9vUHpwY1hHUXJLVnhjS1NRdkxtVjRaV01vYzNSaFkydE1hVzVsS1R0Y2JpQWdJQ0JwWmlBb1lYUjBaVzF3ZERFcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlGdGhkSFJsYlhCME1Wc3hYU3dnVG5WdFltVnlLR0YwZEdWdGNIUXhXekpkS1YwN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnTHk4Z1FXNXZibmx0YjNWeklHWjFibU4wYVc5dWN6b2dYQ0poZENCbWFXeGxibUZ0WlRwc2FXNWxUblZ0WW1WeU9tTnZiSFZ0Yms1MWJXSmxjbHdpWEc0Z0lDQWdkbUZ5SUdGMGRHVnRjSFF5SUQwZ0wyRjBJQ2hiWGlCZEt5azZLRnhjWkNzcE9pZy9PbHhjWkNzcEpDOHVaWGhsWXloemRHRmphMHhwYm1VcE8xeHVJQ0FnSUdsbUlDaGhkSFJsYlhCME1pa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdXMkYwZEdWdGNIUXlXekZkTENCT2RXMWlaWElvWVhSMFpXMXdkREpiTWwwcFhUdGNiaUFnSUNCOVhHNWNiaUFnSUNBdkx5QkdhWEpsWm05NElITjBlV3hsT2lCY0ltWjFibU4wYVc5dVFHWnBiR1Z1WVcxbE9teHBibVZPZFcxaVpYSWdiM0lnUUdacGJHVnVZVzFsT214cGJtVk9kVzFpWlhKY0lseHVJQ0FnSUhaaGNpQmhkSFJsYlhCME15QTlJQzh1S2tBb0xpc3BPaWhjWEdRcktTUXZMbVY0WldNb2MzUmhZMnRNYVc1bEtUdGNiaUFnSUNCcFppQW9ZWFIwWlcxd2RETXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRnRoZEhSbGJYQjBNMXN4WFN3Z1RuVnRZbVZ5S0dGMGRHVnRjSFF6V3pKZEtWMDdYRzRnSUNBZ2ZWeHVmVnh1WEc1bWRXNWpkR2x2YmlCcGMwbHVkR1Z5Ym1Gc1JuSmhiV1VvYzNSaFkydE1hVzVsS1NCN1hHNGdJQ0FnZG1GeUlHWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjaUE5SUdkbGRFWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjaWh6ZEdGamEweHBibVVwTzF4dVhHNGdJQ0FnYVdZZ0tDRm1hV3hsVG1GdFpVRnVaRXhwYm1WT2RXMWlaWElwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdaaGJITmxPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIWmhjaUJtYVd4bFRtRnRaU0E5SUdacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNsc3dYVHRjYmlBZ0lDQjJZWElnYkdsdVpVNTFiV0psY2lBOUlHWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjbHN4WFR0Y2JseHVJQ0FnSUhKbGRIVnliaUJtYVd4bFRtRnRaU0E5UFQwZ2NVWnBiR1ZPWVcxbElDWW1YRzRnSUNBZ0lDQWdJR3hwYm1WT2RXMWlaWElnUGowZ2NWTjBZWEowYVc1blRHbHVaU0FtSmx4dUlDQWdJQ0FnSUNCc2FXNWxUblZ0WW1WeUlEdzlJSEZGYm1ScGJtZE1hVzVsTzF4dWZWeHVYRzR2THlCa2FYTmpiM1psY2lCdmQyNGdabWxzWlNCdVlXMWxJR0Z1WkNCc2FXNWxJRzUxYldKbGNpQnlZVzVuWlNCbWIzSWdabWxzZEdWeWFXNW5JSE4wWVdOclhHNHZMeUIwY21GalpYTmNibVoxYm1OMGFXOXVJR05oY0hSMWNtVk1hVzVsS0NrZ2UxeHVJQ0FnSUdsbUlDZ2hhR0Z6VTNSaFkydHpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzVjYmlBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvS1R0Y2JpQWdJQ0I5SUdOaGRHTm9JQ2hsS1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJzYVc1bGN5QTlJR1V1YzNSaFkyc3VjM0JzYVhRb1hDSmNYRzVjSWlrN1hHNGdJQ0FnSUNBZ0lIWmhjaUJtYVhKemRFeHBibVVnUFNCc2FXNWxjMXN3WFM1cGJtUmxlRTltS0Z3aVFGd2lLU0ErSURBZ1B5QnNhVzVsYzFzeFhTQTZJR3hwYm1Weld6SmRPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1ptbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlJRDBnWjJWMFJtbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlLR1pwY25OMFRHbHVaU2s3WEc0Z0lDQWdJQ0FnSUdsbUlDZ2habWxzWlU1aGJXVkJibVJNYVc1bFRuVnRZbVZ5S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCeFJtbHNaVTVoYldVZ1BTQm1hV3hsVG1GdFpVRnVaRXhwYm1WT2RXMWlaWEpiTUYwN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCbWFXeGxUbUZ0WlVGdVpFeHBibVZPZFcxaVpYSmJNVjA3WEc0Z0lDQWdmVnh1ZlZ4dVhHNW1kVzVqZEdsdmJpQmtaWEJ5WldOaGRHVW9ZMkZzYkdKaFkyc3NJRzVoYldVc0lHRnNkR1Z5Ym1GMGFYWmxLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIUjVjR1Z2WmlCamIyNXpiMnhsSUNFOVBTQmNJblZ1WkdWbWFXNWxaRndpSUNZbVhHNGdJQ0FnSUNBZ0lDQWdJQ0IwZVhCbGIyWWdZMjl1YzI5c1pTNTNZWEp1SUQwOVBTQmNJbVoxYm1OMGFXOXVYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR052Ym5OdmJHVXVkMkZ5YmlodVlXMWxJQ3NnWENJZ2FYTWdaR1Z3Y21WallYUmxaQ3dnZFhObElGd2lJQ3NnWVd4MFpYSnVZWFJwZG1VZ0sxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lJR2x1YzNSbFlXUXVYQ0lzSUc1bGR5QkZjbkp2Y2loY0lsd2lLUzV6ZEdGamF5azdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtHTmhiR3hpWVdOckxDQmhjbWQxYldWdWRITXBPMXh1SUNBZ0lIMDdYRzU5WEc1Y2JpOHZJR1Z1WkNCdlppQnphR2x0YzF4dUx5OGdZbVZuYVc1dWFXNW5JRzltSUhKbFlXd2dkMjl5YTF4dVhHNHZLaXBjYmlBcUlFTnZibk4wY25WamRITWdZU0J3Y205dGFYTmxJR1p2Y2lCaGJpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxMQ0J3WVhOelpYTWdjSEp2YldselpYTWdkR2h5YjNWbmFDd2diM0pjYmlBcUlHTnZaWEpqWlhNZ2NISnZiV2x6WlhNZ1puSnZiU0JrYVdabVpYSmxiblFnYzNsemRHVnRjeTVjYmlBcUlFQndZWEpoYlNCMllXeDFaU0JwYlcxbFpHbGhkR1VnY21WbVpYSmxibU5sSUc5eUlIQnliMjFwYzJWY2JpQXFMMXh1Wm5WdVkzUnBiMjRnVVNoMllXeDFaU2tnZTF4dUlDQWdJQzh2SUVsbUlIUm9aU0J2WW1wbFkzUWdhWE1nWVd4eVpXRmtlU0JoSUZCeWIyMXBjMlVzSUhKbGRIVnliaUJwZENCa2FYSmxZM1JzZVM0Z0lGUm9hWE1nWlc1aFlteGxjMXh1SUNBZ0lDOHZJSFJvWlNCeVpYTnZiSFpsSUdaMWJtTjBhVzl1SUhSdklHSnZkR2dnWW1VZ2RYTmxaQ0IwYnlCamNtVmhkR1ZrSUhKbFptVnlaVzVqWlhNZ1puSnZiU0J2WW1wbFkzUnpMRnh1SUNBZ0lDOHZJR0oxZENCMGJ5QjBiMnhsY21GaWJIa2dZMjlsY21ObElHNXZiaTF3Y205dGFYTmxjeUIwYnlCd2NtOXRhWE5sY3k1Y2JpQWdJQ0JwWmlBb2RtRnNkV1VnYVc1emRHRnVZMlZ2WmlCUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCMllXeDFaVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQXZMeUJoYzNOcGJXbHNZWFJsSUhSb1pXNWhZbXhsYzF4dUlDQWdJR2xtSUNocGMxQnliMjFwYzJWQmJHbHJaU2gyWVd4MVpTa3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR052WlhKalpTaDJZV3gxWlNrN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1oxYkdacGJHd29kbUZzZFdVcE8xeHVJQ0FnSUgxY2JuMWNibEV1Y21WemIyeDJaU0E5SUZFN1hHNWNiaThxS2x4dUlDb2dVR1Z5Wm05eWJYTWdZU0IwWVhOcklHbHVJR0VnWm5WMGRYSmxJSFIxY200Z2IyWWdkR2hsSUdWMlpXNTBJR3h2YjNBdVhHNGdLaUJBY0dGeVlXMGdlMFoxYm1OMGFXOXVmU0IwWVhOclhHNGdLaTljYmxFdWJtVjRkRlJwWTJzZ1BTQnVaWGgwVkdsamF6dGNibHh1THlvcVhHNGdLaUJEYjI1MGNtOXNjeUIzYUdWMGFHVnlJRzl5SUc1dmRDQnNiMjVuSUhOMFlXTnJJSFJ5WVdObGN5QjNhV3hzSUdKbElHOXVYRzRnS2k5Y2JsRXViRzl1WjFOMFlXTnJVM1Z3Y0c5eWRDQTlJR1poYkhObE8xeHVYRzR2THlCbGJtRmliR1VnYkc5dVp5QnpkR0ZqYTNNZ2FXWWdVVjlFUlVKVlJ5QnBjeUJ6WlhSY2JtbG1JQ2gwZVhCbGIyWWdjSEp2WTJWemN5QTlQVDBnWENKdlltcGxZM1JjSWlBbUppQndjbTlqWlhOeklDWW1JSEJ5YjJObGMzTXVaVzUySUNZbUlIQnliMk5sYzNNdVpXNTJMbEZmUkVWQ1ZVY3BJSHRjYmlBZ0lDQlJMbXh2Ym1kVGRHRmphMU4xY0hCdmNuUWdQU0IwY25WbE8xeHVmVnh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQjdjSEp2YldselpTd2djbVZ6YjJ4MlpTd2djbVZxWldOMGZTQnZZbXBsWTNRdVhHNGdLbHh1SUNvZ1lISmxjMjlzZG1WZ0lHbHpJR0VnWTJGc2JHSmhZMnNnZEc4Z2FXNTJiMnRsSUhkcGRHZ2dZU0J0YjNKbElISmxjMjlzZG1Wa0lIWmhiSFZsSUdadmNpQjBhR1ZjYmlBcUlIQnliMjFwYzJVdUlGUnZJR1oxYkdacGJHd2dkR2hsSUhCeWIyMXBjMlVzSUdsdWRtOXJaU0JnY21WemIyeDJaV0FnZDJsMGFDQmhibmtnZG1Gc2RXVWdkR2hoZENCcGMxeHVJQ29nYm05MElHRWdkR2hsYm1GaWJHVXVJRlJ2SUhKbGFtVmpkQ0IwYUdVZ2NISnZiV2x6WlN3Z2FXNTJiMnRsSUdCeVpYTnZiSFpsWUNCM2FYUm9JR0VnY21WcVpXTjBaV1JjYmlBcUlIUm9aVzVoWW14bExDQnZjaUJwYm5admEyVWdZSEpsYW1WamRHQWdkMmwwYUNCMGFHVWdjbVZoYzI5dUlHUnBjbVZqZEd4NUxpQlVieUJ5WlhOdmJIWmxJSFJvWlZ4dUlDb2djSEp2YldselpTQjBieUJoYm05MGFHVnlJSFJvWlc1aFlteGxMQ0IwYUhWeklIQjFkSFJwYm1jZ2FYUWdhVzRnZEdobElITmhiV1VnYzNSaGRHVXNJR2x1ZG05clpWeHVJQ29nWUhKbGMyOXNkbVZnSUhkcGRHZ2dkR2hoZENCdmRHaGxjaUIwYUdWdVlXSnNaUzVjYmlBcUwxeHVVUzVrWldabGNpQTlJR1JsWm1WeU8xeHVablZ1WTNScGIyNGdaR1ZtWlhJb0tTQjdYRzRnSUNBZ0x5OGdhV1lnWENKdFpYTnpZV2RsYzF3aUlHbHpJR0Z1SUZ3aVFYSnlZWGxjSWl3Z2RHaGhkQ0JwYm1ScFkyRjBaWE1nZEdoaGRDQjBhR1VnY0hKdmJXbHpaU0JvWVhNZ2JtOTBJSGxsZEZ4dUlDQWdJQzh2SUdKbFpXNGdjbVZ6YjJ4MlpXUXVJQ0JKWmlCcGRDQnBjeUJjSW5WdVpHVm1hVzVsWkZ3aUxDQnBkQ0JvWVhNZ1ltVmxiaUJ5WlhOdmJIWmxaQzRnSUVWaFkyaGNiaUFnSUNBdkx5QmxiR1Z0Wlc1MElHOW1JSFJvWlNCdFpYTnpZV2RsY3lCaGNuSmhlU0JwY3lCcGRITmxiR1lnWVc0Z1lYSnlZWGtnYjJZZ1kyOXRjR3hsZEdVZ1lYSm5kVzFsYm5SeklIUnZYRzRnSUNBZ0x5OGdabTl5ZDJGeVpDQjBieUIwYUdVZ2NtVnpiMngyWldRZ2NISnZiV2x6WlM0Z0lGZGxJR052WlhKalpTQjBhR1VnY21WemIyeDFkR2x2YmlCMllXeDFaU0IwYnlCaFhHNGdJQ0FnTHk4Z2NISnZiV2x6WlNCMWMybHVaeUIwYUdVZ1lISmxjMjlzZG1WZ0lHWjFibU4wYVc5dUlHSmxZMkYxYzJVZ2FYUWdhR0Z1Wkd4bGN5QmliM1JvSUdaMWJHeDVYRzRnSUNBZ0x5OGdibTl1TFhSb1pXNWhZbXhsSUhaaGJIVmxjeUJoYm1RZ2IzUm9aWElnZEdobGJtRmliR1Z6SUdkeVlXTmxablZzYkhrdVhHNGdJQ0FnZG1GeUlHMWxjM05oWjJWeklEMGdXMTBzSUhCeWIyZHlaWE56VEdsemRHVnVaWEp6SUQwZ1cxMHNJSEpsYzI5c2RtVmtVSEp2YldselpUdGNibHh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUc5aWFtVmpkRjlqY21WaGRHVW9aR1ZtWlhJdWNISnZkRzkwZVhCbEtUdGNiaUFnSUNCMllYSWdjSEp2YldselpTQTlJRzlpYW1WamRGOWpjbVZoZEdVb1VISnZiV2x6WlM1d2NtOTBiM1I1Y0dVcE8xeHVYRzRnSUNBZ2NISnZiV2x6WlM1d2NtOXRhWE5sUkdsemNHRjBZMmdnUFNCbWRXNWpkR2x2YmlBb2NtVnpiMngyWlN3Z2IzQXNJRzl3WlhKaGJtUnpLU0I3WEc0Z0lDQWdJQ0FnSUhaaGNpQmhjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWxjM05oWjJWektTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCdFpYTnpZV2RsY3k1d2RYTm9LR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHOXdJRDA5UFNCY0luZG9aVzVjSWlBbUppQnZjR1Z5WVc1a2Mxc3hYU2tnZXlBdkx5QndjbTluY21WemN5QnZjR1Z5WVc1a1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZaM0psYzNOTWFYTjBaVzVsY25NdWNIVnphQ2h2Y0dWeVlXNWtjMXN4WFNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQlJMbTVsZUhSVWFXTnJLR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYTnZiSFpsWkZCeWIyMXBjMlV1Y0hKdmJXbHpaVVJwYzNCaGRHTm9MbUZ3Y0d4NUtISmxjMjlzZG1Wa1VISnZiV2x6WlN3Z1lYSm5jeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDA3WEc1Y2JpQWdJQ0F2THlCWVdGZ2daR1Z3Y21WallYUmxaRnh1SUNBZ0lIQnliMjFwYzJVdWRtRnNkV1ZQWmlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWxjM05oWjJWektTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMllYSWdibVZoY21WeVZtRnNkV1VnUFNCdVpXRnlaWElvY21WemIyeDJaV1JRY205dGFYTmxLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHbHpVSEp2YldselpTaHVaV0Z5WlhKV1lXeDFaU2twSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzI5c2RtVmtVSEp2YldselpTQTlJRzVsWVhKbGNsWmhiSFZsT3lBdkx5QnphRzl5ZEdWdUlHTm9ZV2x1WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUc1bFlYSmxjbFpoYkhWbE8xeHVJQ0FnSUgwN1hHNWNiaUFnSUNCd2NtOXRhWE5sTG1sdWMzQmxZM1FnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJR2xtSUNnaGNtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdleUJ6ZEdGMFpUb2dYQ0p3Wlc1a2FXNW5YQ0lnZlR0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2NtVnpiMngyWldSUWNtOXRhWE5sTG1sdWMzQmxZM1FvS1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnYVdZZ0tGRXViRzl1WjFOMFlXTnJVM1Z3Y0c5eWRDQW1KaUJvWVhOVGRHRmphM01wSUh0Y2JpQWdJQ0FnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUc1bGR5QkZjbkp2Y2lncE8xeHVJQ0FnSUNBZ0lDQjlJR05oZEdOb0lDaGxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJPVDFSRk9pQmtiMjRuZENCMGNua2dkRzhnZFhObElHQkZjbkp2Y2k1allYQjBkWEpsVTNSaFkydFVjbUZqWldBZ2IzSWdkSEpoYm5ObVpYSWdkR2hsWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJoWTJObGMzTnZjaUJoY205MWJtUTdJSFJvWVhRZ1kyRjFjMlZ6SUcxbGJXOXllU0JzWldGcmN5QmhjeUJ3WlhJZ1IwZ3RNVEV4TGlCS2RYTjBYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QnlaV2xtZVNCMGFHVWdjM1JoWTJzZ2RISmhZMlVnWVhNZ1lTQnpkSEpwYm1jZ1FWTkJVQzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QkJkQ0IwYUdVZ2MyRnRaU0IwYVcxbExDQmpkWFFnYjJabUlIUm9aU0JtYVhKemRDQnNhVzVsT3lCcGRDZHpJR0ZzZDJGNWN5QnFkWE4wWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJjSWx0dlltcGxZM1FnVUhKdmJXbHpaVjFjWEc1Y0lpd2dZWE1nY0dWeUlIUm9aU0JnZEc5VGRISnBibWRnTGx4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTNXpkR0ZqYXlBOUlHVXVjM1JoWTJzdWMzVmljM1J5YVc1bktHVXVjM1JoWTJzdWFXNWtaWGhQWmloY0lseGNibHdpS1NBcklERXBPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdmVnh1WEc0Z0lDQWdMeThnVGs5VVJUb2dkMlVnWkc4Z2RHaGxJR05vWldOcmN5Qm1iM0lnWUhKbGMyOXNkbVZrVUhKdmJXbHpaV0FnYVc0Z1pXRmphQ0J0WlhSb2IyUXNJR2x1YzNSbFlXUWdiMlpjYmlBZ0lDQXZMeUJqYjI1emIyeHBaR0YwYVc1bklIUm9aVzBnYVc1MGJ5QmdZbVZqYjIxbFlDd2djMmx1WTJVZ2IzUm9aWEozYVhObElIZGxKMlFnWTNKbFlYUmxJRzVsZDF4dUlDQWdJQzh2SUhCeWIyMXBjMlZ6SUhkcGRHZ2dkR2hsSUd4cGJtVnpJR0JpWldOdmJXVW9kMmhoZEdWMlpYSW9kbUZzZFdVcEtXQXVJRk5sWlNCbExtY3VJRWRJTFRJMU1pNWNibHh1SUNBZ0lHWjFibU4wYVc5dUlHSmxZMjl0WlNodVpYZFFjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJSEpsYzI5c2RtVmtVSEp2YldselpTQTlJRzVsZDFCeWIyMXBjMlU3WEc0Z0lDQWdJQ0FnSUhCeWIyMXBjMlV1YzI5MWNtTmxJRDBnYm1WM1VISnZiV2x6WlR0Y2JseHVJQ0FnSUNBZ0lDQmhjbkpoZVY5eVpXUjFZMlVvYldWemMyRm5aWE1zSUdaMWJtTjBhVzl1SUNoMWJtUmxabWx1WldRc0lHMWxjM05oWjJVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzVsZDFCeWIyMXBjMlV1Y0hKdmJXbHpaVVJwYzNCaGRHTm9MbUZ3Y0d4NUtHNWxkMUJ5YjIxcGMyVXNJRzFsYzNOaFoyVXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTazdYRzRnSUNBZ0lDQWdJSDBzSUhadmFXUWdNQ2s3WEc1Y2JpQWdJQ0FnSUNBZ2JXVnpjMkZuWlhNZ1BTQjJiMmxrSURBN1hHNGdJQ0FnSUNBZ0lIQnliMmR5WlhOelRHbHpkR1Z1WlhKeklEMGdkbTlwWkNBd08xeHVJQ0FnSUgxY2JseHVJQ0FnSUdSbFptVnljbVZrTG5CeWIyMXBjMlVnUFNCd2NtOXRhWE5sTzF4dUlDQWdJR1JsWm1WeWNtVmtMbkpsYzI5c2RtVWdQU0JtZFc1amRHbHZiaUFvZG1Gc2RXVXBJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tISmxjMjlzZG1Wa1VISnZiV2x6WlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVPMXh1SUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ1ltVmpiMjFsS0ZFb2RtRnNkV1VwS1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnWkdWbVpYSnlaV1F1Wm5Wc1ptbHNiQ0E5SUdaMWJtTjBhVzl1SUNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9jbVZ6YjJ4MlpXUlFjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTQ3WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQmlaV052YldVb1puVnNabWxzYkNoMllXeDFaU2twTzF4dUlDQWdJSDA3WEc0Z0lDQWdaR1ZtWlhKeVpXUXVjbVZxWldOMElEMGdablZ1WTNScGIyNGdLSEpsWVhOdmJpa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2NtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCaVpXTnZiV1VvY21WcVpXTjBLSEpsWVhOdmJpa3BPMXh1SUNBZ0lIMDdYRzRnSUNBZ1pHVm1aWEp5WldRdWJtOTBhV1o1SUQwZ1puVnVZM1JwYjI0Z0tIQnliMmR5WlhOektTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoeVpYTnZiSFpsWkZCeWIyMXBjMlVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJqdGNiaUFnSUNBZ0lDQWdmVnh1WEc0Z0lDQWdJQ0FnSUdGeWNtRjVYM0psWkhWalpTaHdjbTluY21WemMweHBjM1JsYm1WeWN5d2dablZ1WTNScGIyNGdLSFZ1WkdWbWFXNWxaQ3dnY0hKdlozSmxjM05NYVhOMFpXNWxjaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdVUzV1WlhoMFZHbGpheWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZaM0psYzNOTWFYTjBaVzVsY2lod2NtOW5jbVZ6Y3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0FnSUNBZ2ZTd2dkbTlwWkNBd0tUdGNiaUFnSUNCOU8xeHVYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTzF4dWZWeHVYRzR2S2lwY2JpQXFJRU55WldGMFpYTWdZU0JPYjJSbExYTjBlV3hsSUdOaGJHeGlZV05ySUhSb1lYUWdkMmxzYkNCeVpYTnZiSFpsSUc5eUlISmxhbVZqZENCMGFHVWdaR1ZtWlhKeVpXUmNiaUFxSUhCeWIyMXBjMlV1WEc0Z0tpQkFjbVYwZFhKdWN5QmhJRzV2WkdWaVlXTnJYRzRnS2k5Y2JtUmxabVZ5TG5CeWIzUnZkSGx3WlM1dFlXdGxUbTlrWlZKbGMyOXNkbVZ5SUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0J5WlhSMWNtNGdablZ1WTNScGIyNGdLR1Z5Y205eUxDQjJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvWlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lITmxiR1l1Y21WcVpXTjBLR1Z5Y205eUtUdGNiaUFnSUNBZ0lDQWdmU0JsYkhObElHbG1JQ2hoY21kMWJXVnVkSE11YkdWdVozUm9JRDRnTWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWc1ppNXlaWE52YkhabEtHRnljbUY1WDNOc2FXTmxLR0Z5WjNWdFpXNTBjeXdnTVNrcE8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWc1ppNXlaWE52YkhabEtIWmhiSFZsS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVCd1lYSmhiU0J5WlhOdmJIWmxjaUI3Um5WdVkzUnBiMjU5SUdFZ1puVnVZM1JwYjI0Z2RHaGhkQ0J5WlhSMWNtNXpJRzV2ZEdocGJtY2dZVzVrSUdGalkyVndkSE5jYmlBcUlIUm9aU0J5WlhOdmJIWmxMQ0J5WldwbFkzUXNJR0Z1WkNCdWIzUnBabmtnWm5WdVkzUnBiMjV6SUdadmNpQmhJR1JsWm1WeWNtVmtMbHh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElIUm9ZWFFnYldGNUlHSmxJSEpsYzI5c2RtVmtJSGRwZEdnZ2RHaGxJR2RwZG1WdUlISmxjMjlzZG1VZ1lXNWtJSEpsYW1WamRGeHVJQ29nWm5WdVkzUnBiMjV6TENCdmNpQnlaV3BsWTNSbFpDQmllU0JoSUhSb2NtOTNiaUJsZUdObGNIUnBiMjRnYVc0Z2NtVnpiMngyWlhKY2JpQXFMMXh1VVM1UWNtOXRhWE5sSUQwZ2NISnZiV2x6WlRzZ0x5OGdSVk0yWEc1UkxuQnliMjFwYzJVZ1BTQndjbTl0YVhObE8xeHVablZ1WTNScGIyNGdjSEp2YldselpTaHlaWE52YkhabGNpa2dlMXh1SUNBZ0lHbG1JQ2gwZVhCbGIyWWdjbVZ6YjJ4MlpYSWdJVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0IwYUhKdmR5QnVaWGNnVkhsd1pVVnljbTl5S0Z3aWNtVnpiMngyWlhJZ2JYVnpkQ0JpWlNCaElHWjFibU4wYVc5dUxsd2lLVHRjYmlBZ0lDQjlYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNCeVpYTnZiSFpsY2loa1pXWmxjbkpsWkM1eVpYTnZiSFpsTENCa1pXWmxjbkpsWkM1eVpXcGxZM1FzSUdSbFptVnljbVZrTG01dmRHbG1lU2s3WEc0Z0lDQWdmU0JqWVhSamFDQW9jbVZoYzI5dUtTQjdYRzRnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYW1WamRDaHlaV0Z6YjI0cE8xeHVJQ0FnSUgxY2JpQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNibjFjYmx4dWNISnZiV2x6WlM1eVlXTmxJRDBnY21GalpUc2dMeThnUlZNMlhHNXdjbTl0YVhObExtRnNiQ0E5SUdGc2JEc2dMeThnUlZNMlhHNXdjbTl0YVhObExuSmxhbVZqZENBOUlISmxhbVZqZERzZ0x5OGdSVk0yWEc1d2NtOXRhWE5sTG5KbGMyOXNkbVVnUFNCUk95QXZMeUJGVXpaY2JseHVMeThnV0ZoWUlHVjRjR1Z5YVcxbGJuUmhiQzRnSUZSb2FYTWdiV1YwYUc5a0lHbHpJR0VnZDJGNUlIUnZJR1JsYm05MFpTQjBhR0YwSUdFZ2JHOWpZV3dnZG1Gc2RXVWdhWE5jYmk4dklITmxjbWxoYkdsNllXSnNaU0JoYm1RZ2MyaHZkV3hrSUdKbElHbHRiV1ZrYVdGMFpXeDVJR1JwYzNCaGRHTm9aV1FnZEc4Z1lTQnlaVzF2ZEdVZ2RYQnZiaUJ5WlhGMVpYTjBMRnh1THk4Z2FXNXpkR1ZoWkNCdlppQndZWE56YVc1bklHRWdjbVZtWlhKbGJtTmxMbHh1VVM1d1lYTnpRbmxEYjNCNUlEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDa2dlMXh1SUNBZ0lDOHZabkpsWlhwbEtHOWlhbVZqZENrN1hHNGdJQ0FnTHk5d1lYTnpRbmxEYjNCcFpYTXVjMlYwS0c5aWFtVmpkQ3dnZEhKMVpTazdYRzRnSUNBZ2NtVjBkWEp1SUc5aWFtVmpkRHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkJoYzNOQ2VVTnZjSGtnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0x5OW1jbVZsZW1Vb2IySnFaV04wS1R0Y2JpQWdJQ0F2TDNCaGMzTkNlVU52Y0dsbGN5NXpaWFFvYjJKcVpXTjBMQ0IwY25WbEtUdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN6dGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1NXWWdkSGR2SUhCeWIyMXBjMlZ6SUdWMlpXNTBkV0ZzYkhrZ1puVnNabWxzYkNCMGJ5QjBhR1VnYzJGdFpTQjJZV3gxWlN3Z2NISnZiV2x6WlhNZ2RHaGhkQ0IyWVd4MVpTeGNiaUFxSUdKMWRDQnZkR2hsY25kcGMyVWdjbVZxWldOMGN5NWNiaUFxSUVCd1lYSmhiU0I0SUh0QmJua3FmVnh1SUNvZ1FIQmhjbUZ0SUhrZ2UwRnVlU3A5WEc0Z0tpQkFjbVYwZFhKdWN5QjdRVzU1S24wZ1lTQndjbTl0YVhObElHWnZjaUI0SUdGdVpDQjVJR2xtSUhSb1pYa2dZWEpsSUhSb1pTQnpZVzFsTENCaWRYUWdZU0J5WldwbFkzUnBiMjVjYmlBcUlHOTBhR1Z5ZDJselpTNWNiaUFxWEc0Z0tpOWNibEV1YW05cGJpQTlJR1oxYm1OMGFXOXVJQ2g0TENCNUtTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2VDa3VhbTlwYmloNUtUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtcHZhVzRnUFNCbWRXNWpkR2x2YmlBb2RHaGhkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRnQwYUdsekxDQjBhR0YwWFNrdWMzQnlaV0ZrS0daMWJtTjBhVzl1SUNoNExDQjVLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDRJRDA5UFNCNUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QlVUMFJQT2lCY0lqMDlQVndpSUhOb2IzVnNaQ0JpWlNCUFltcGxZM1F1YVhNZ2IzSWdaWEYxYVhaY2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjRPMXh1SUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Z3aVEyRnVKM1FnYW05cGJqb2dibTkwSUhSb1pTQnpZVzFsT2lCY0lpQXJJSGdnS3lCY0lpQmNJaUFySUhrcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZTazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ1ptbHljM1FnYjJZZ1lXNGdZWEp5WVhrZ2IyWWdjSEp2YldselpYTWdkRzhnWW1WamIyMWxJSE5sZEhSc1pXUXVYRzRnS2lCQWNHRnlZVzBnWVc1emQyVnljeUI3UVhKeVlYbGJRVzU1S2wxOUlIQnliMjFwYzJWeklIUnZJSEpoWTJWY2JpQXFJRUJ5WlhSMWNtNXpJSHRCYm5rcWZTQjBhR1VnWm1seWMzUWdjSEp2YldselpTQjBieUJpWlNCelpYUjBiR1ZrWEc0Z0tpOWNibEV1Y21GalpTQTlJSEpoWTJVN1hHNW1kVzVqZEdsdmJpQnlZV05sS0dGdWMzZGxjbEJ6S1NCN1hHNGdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVW9ablZ1WTNScGIyNGdLSEpsYzI5c2RtVXNJSEpsYW1WamRDa2dlMXh1SUNBZ0lDQWdJQ0F2THlCVGQybDBZMmdnZEc4Z2RHaHBjeUJ2Ym1ObElIZGxJR05oYmlCaGMzTjFiV1VnWVhRZ2JHVmhjM1FnUlZNMVhHNGdJQ0FnSUNBZ0lDOHZJR0Z1YzNkbGNsQnpMbVp2Y2tWaFkyZ29ablZ1WTNScGIyNGdLR0Z1YzNkbGNsQXBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z0lDQWdJRkVvWVc1emQyVnlVQ2t1ZEdobGJpaHlaWE52YkhabExDQnlaV3BsWTNRcE8xeHVJQ0FnSUNBZ0lDQXZMeUI5S1R0Y2JpQWdJQ0FnSUNBZ0x5OGdWWE5sSUhSb2FYTWdhVzRnZEdobElHMWxZVzUwYVcxbFhHNGdJQ0FnSUNBZ0lHWnZjaUFvZG1GeUlHa2dQU0F3TENCc1pXNGdQU0JoYm5OM1pYSlFjeTVzWlc1bmRHZzdJR2tnUENCc1pXNDdJR2tyS3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnVVNoaGJuTjNaWEpRYzF0cFhTa3VkR2hsYmloeVpYTnZiSFpsTENCeVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlNrN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG5KaFkyVWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWRHaGxiaWhSTG5KaFkyVXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkRiMjV6ZEhKMVkzUnpJR0VnVUhKdmJXbHpaU0IzYVhSb0lHRWdjSEp2YldselpTQmtaWE5qY21sd2RHOXlJRzlpYW1WamRDQmhibVFnYjNCMGFXOXVZV3dnWm1Gc2JHSmhZMnRjYmlBcUlHWjFibU4wYVc5dUxpQWdWR2hsSUdSbGMyTnlhWEIwYjNJZ1kyOXVkR0ZwYm5NZ2JXVjBhRzlrY3lCc2FXdGxJSGRvWlc0b2NtVnFaV04wWldRcExDQm5aWFFvYm1GdFpTa3NYRzRnS2lCelpYUW9ibUZ0WlN3Z2RtRnNkV1VwTENCd2IzTjBLRzVoYldVc0lHRnlaM01wTENCaGJtUWdaR1ZzWlhSbEtHNWhiV1VwTENCM2FHbGphQ0JoYkd4Y2JpQXFJSEpsZEhWeWJpQmxhWFJvWlhJZ1lTQjJZV3gxWlN3Z1lTQndjbTl0YVhObElHWnZjaUJoSUhaaGJIVmxMQ0J2Y2lCaElISmxhbVZqZEdsdmJpNGdJRlJvWlNCbVlXeHNZbUZqYTF4dUlDb2dZV05qWlhCMGN5QjBhR1VnYjNCbGNtRjBhVzl1SUc1aGJXVXNJR0VnY21WemIyeDJaWElzSUdGdVpDQmhibmtnWm5WeWRHaGxjaUJoY21kMWJXVnVkSE1nZEdoaGRDQjNiM1ZzWkZ4dUlDb2dhR0YyWlNCaVpXVnVJR1p2Y25kaGNtUmxaQ0IwYnlCMGFHVWdZWEJ3Y205d2NtbGhkR1VnYldWMGFHOWtJR0ZpYjNabElHaGhaQ0JoSUcxbGRHaHZaQ0JpWldWdVhHNGdLaUJ3Y205MmFXUmxaQ0IzYVhSb0lIUm9aU0J3Y205d1pYSWdibUZ0WlM0Z0lGUm9aU0JCVUVrZ2JXRnJaWE1nYm04Z1ozVmhjbUZ1ZEdWbGN5QmhZbTkxZENCMGFHVWdibUYwZFhKbFhHNGdLaUJ2WmlCMGFHVWdjbVYwZFhKdVpXUWdiMkpxWldOMExDQmhjR0Z5ZENCbWNtOXRJSFJvWVhRZ2FYUWdhWE1nZFhOaFlteGxJSGRvWlhKbFpYWmxjaUJ3Y205dGFYTmxjeUJoY21WY2JpQXFJR0p2ZFdkb2RDQmhibVFnYzI5c1pDNWNiaUFxTDF4dVVTNXRZV3RsVUhKdmJXbHpaU0E5SUZCeWIyMXBjMlU3WEc1bWRXNWpkR2x2YmlCUWNtOXRhWE5sS0dSbGMyTnlhWEIwYjNJc0lHWmhiR3hpWVdOckxDQnBibk53WldOMEtTQjdYRzRnSUNBZ2FXWWdLR1poYkd4aVlXTnJJRDA5UFNCMmIybGtJREFwSUh0Y2JpQWdJQ0FnSUNBZ1ptRnNiR0poWTJzZ1BTQm1kVzVqZEdsdmJpQW9iM0FwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNRb2JtVjNJRVZ5Y205eUtGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lVSEp2YldselpTQmtiMlZ6SUc1dmRDQnpkWEJ3YjNKMElHOXdaWEpoZEdsdmJqb2dYQ0lnS3lCdmNGeHVJQ0FnSUNBZ0lDQWdJQ0FnS1NrN1hHNGdJQ0FnSUNBZ0lIMDdYRzRnSUNBZ2ZWeHVJQ0FnSUdsbUlDaHBibk53WldOMElEMDlQU0IyYjJsa0lEQXBJSHRjYmlBZ0lDQWdJQ0FnYVc1emNHVmpkQ0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUI3YzNSaGRHVTZJRndpZFc1cmJtOTNibHdpZlR0Y2JpQWdJQ0FnSUNBZ2ZUdGNiaUFnSUNCOVhHNWNiaUFnSUNCMllYSWdjSEp2YldselpTQTlJRzlpYW1WamRGOWpjbVZoZEdVb1VISnZiV2x6WlM1d2NtOTBiM1I1Y0dVcE8xeHVYRzRnSUNBZ2NISnZiV2x6WlM1d2NtOXRhWE5sUkdsemNHRjBZMmdnUFNCbWRXNWpkR2x2YmlBb2NtVnpiMngyWlN3Z2IzQXNJR0Z5WjNNcElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUhKbGMzVnNkRHRjYmlBZ0lDQWdJQ0FnZEhKNUlIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtaWE5qY21sd2RHOXlXMjl3WFNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxjM1ZzZENBOUlHUmxjMk55YVhCMGIzSmJiM0JkTG1Gd2NHeDVLSEJ5YjIxcGMyVXNJR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J5WlhOMWJIUWdQU0JtWVd4c1ltRmpheTVqWVd4c0tIQnliMjFwYzJVc0lHOXdMQ0JoY21kektUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYTjFiSFFnUFNCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnBaaUFvY21WemIyeDJaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ6YjJ4MlpTaHlaWE4xYkhRcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lIQnliMjFwYzJVdWFXNXpjR1ZqZENBOUlHbHVjM0JsWTNRN1hHNWNiaUFnSUNBdkx5QllXRmdnWkdWd2NtVmpZWFJsWkNCZ2RtRnNkV1ZQWm1BZ1lXNWtJR0JsZUdObGNIUnBiMjVnSUhOMWNIQnZjblJjYmlBZ0lDQnBaaUFvYVc1emNHVmpkQ2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdhVzV6Y0dWamRHVmtJRDBnYVc1emNHVmpkQ2dwTzF4dUlDQWdJQ0FnSUNCcFppQW9hVzV6Y0dWamRHVmtMbk4wWVhSbElEMDlQU0JjSW5KbGFtVmpkR1ZrWENJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhCeWIyMXBjMlV1WlhoalpYQjBhVzl1SUQwZ2FXNXpjR1ZqZEdWa0xuSmxZWE52Ymp0Y2JpQWdJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVkbUZzZFdWUFppQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFpoY2lCcGJuTndaV04wWldRZ1BTQnBibk53WldOMEtDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9hVzV6Y0dWamRHVmtMbk4wWVhSbElEMDlQU0JjSW5CbGJtUnBibWRjSWlCOGZGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbHVjM0JsWTNSbFpDNXpkR0YwWlNBOVBUMGdYQ0p5WldwbFkzUmxaRndpS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhCeWIyMXBjMlU3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnYVc1emNHVmpkR1ZrTG5aaGJIVmxPMXh1SUNBZ0lDQWdJQ0I5TzF4dUlDQWdJSDFjYmx4dUlDQWdJSEpsZEhWeWJpQndjbTl0YVhObE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1WnlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z1hDSmJiMkpxWldOMElGQnliMjFwYzJWZFhDSTdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBhR1Z1SUQwZ1puVnVZM1JwYjI0Z0tHWjFiR1pwYkd4bFpDd2djbVZxWldOMFpXUXNJSEJ5YjJkeVpYTnpaV1FwSUh0Y2JpQWdJQ0IyWVhJZ2MyVnNaaUE5SUhSb2FYTTdYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQjJZWElnWkc5dVpTQTlJR1poYkhObE95QWdJQzh2SUdWdWMzVnlaU0IwYUdVZ2RXNTBjblZ6ZEdWa0lIQnliMjFwYzJVZ2JXRnJaWE1nWVhRZ2JXOXpkQ0JoWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCemFXNW5iR1VnWTJGc2JDQjBieUJ2Ym1VZ2IyWWdkR2hsSUdOaGJHeGlZV05yYzF4dVhHNGdJQ0FnWm5WdVkzUnBiMjRnWDJaMWJHWnBiR3hsWkNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhSNWNHVnZaaUJtZFd4bWFXeHNaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaUEvSUdaMWJHWnBiR3hsWkNoMllXeDFaU2tnT2lCMllXeDFaVHRjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdjbVZxWldOMEtHVjRZMlZ3ZEdsdmJpazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzVjYmlBZ0lDQm1kVzVqZEdsdmJpQmZjbVZxWldOMFpXUW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDBlWEJsYjJZZ2NtVnFaV04wWldRZ1BUMDlJRndpWm5WdVkzUnBiMjVjSWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYldGclpWTjBZV05yVkhKaFkyVk1iMjVuS0dWNFkyVndkR2x2Yml3Z2MyVnNaaWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJ5WldwbFkzUmxaQ2hsZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JqWVhSamFDQW9ibVYzUlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkQ2h1WlhkRmVHTmxjSFJwYjI0cE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0JtZFc1amRHbHZiaUJmY0hKdlozSmxjM05sWkNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZEhsd1pXOW1JSEJ5YjJkeVpYTnpaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaUEvSUhCeWIyZHlaWE56WldRb2RtRnNkV1VwSURvZ2RtRnNkV1U3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdVUzV1WlhoMFZHbGpheWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lITmxiR1l1Y0hKdmJXbHpaVVJwYzNCaGRHTm9LR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2Ym1VcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtiMjVsSUQwZ2RISjFaVHRjYmx4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZtWlhKeVpXUXVjbVZ6YjJ4MlpTaGZablZzWm1sc2JHVmtLSFpoYkhWbEtTazdYRzRnSUNBZ0lDQWdJSDBzSUZ3aWQyaGxibHdpTENCYlpuVnVZM1JwYjI0Z0tHVjRZMlZ3ZEdsdmJpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2Ym1VcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtiMjVsSUQwZ2RISjFaVHRjYmx4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZtWlhKeVpXUXVjbVZ6YjJ4MlpTaGZjbVZxWldOMFpXUW9aWGhqWlhCMGFXOXVLU2s3WEc0Z0lDQWdJQ0FnSUgxZEtUdGNiaUFnSUNCOUtUdGNibHh1SUNBZ0lDOHZJRkJ5YjJkeVpYTnpJSEJ5YjNCaFoyRjBiM0lnYm1WbFpDQjBieUJpWlNCaGRIUmhZMmhsWkNCcGJpQjBhR1VnWTNWeWNtVnVkQ0IwYVdOckxseHVJQ0FnSUhObGJHWXVjSEp2YldselpVUnBjM0JoZEdOb0tIWnZhV1FnTUN3Z1hDSjNhR1Z1WENJc0lGdDJiMmxrSURBc0lHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYm1WM1ZtRnNkV1U3WEc0Z0lDQWdJQ0FnSUhaaGNpQjBhSEpsZHlBOUlHWmhiSE5sTzF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2JtVjNWbUZzZFdVZ1BTQmZjSEp2WjNKbGMzTmxaQ2gyWVd4MVpTazdYRzRnSUNBZ0lDQWdJSDBnWTJGMFkyZ2dLR1VwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvY21WM0lEMGdkSEoxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoUkxtOXVaWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQlJMbTl1WlhKeWIzSW9aU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUdVN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQnBaaUFvSVhSb2NtVjNLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtaV1psY25KbFpDNXViM1JwWm5rb2JtVjNWbUZzZFdVcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZWMHBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc1UkxuUmhjQ0E5SUdaMWJtTjBhVzl1SUNod2NtOXRhWE5sTENCallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlVwTG5SaGNDaGpZV3hzWW1GamF5azdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGZHZjbXR6SUdGc2JXOXpkQ0JzYVd0bElGd2labWx1WVd4c2VWd2lMQ0JpZFhRZ2JtOTBJR05oYkd4bFpDQm1iM0lnY21WcVpXTjBhVzl1Y3k1Y2JpQXFJRTl5YVdkcGJtRnNJSEpsYzI5c2RYUnBiMjRnZG1Gc2RXVWdhWE1nY0dGemMyVmtJSFJvY205MVoyZ2dZMkZzYkdKaFkyc2dkVzVoWm1abFkzUmxaQzVjYmlBcUlFTmhiR3hpWVdOcklHMWhlU0J5WlhSMWNtNGdZU0J3Y205dGFYTmxJSFJvWVhRZ2QybHNiQ0JpWlNCaGQyRnBkR1ZrSUdadmNpNWNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU5SUdOaGJHeGlZV05yWEc0Z0tpQkFjbVYwZFhKdWN5QjdVUzVRY205dGFYTmxmVnh1SUNvZ1FHVjRZVzF3YkdWY2JpQXFJR1J2VTI5dFpYUm9hVzVuS0NsY2JpQXFJQ0FnTG5Sb1pXNG9MaTR1S1Z4dUlDb2dJQ0F1ZEdGd0tHTnZibk52YkdVdWJHOW5LVnh1SUNvZ0lDQXVkR2hsYmlndUxpNHBPMXh1SUNvdlhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBZWEFnUFNCbWRXNWpkR2x2YmlBb1kyRnNiR0poWTJzcElIdGNiaUFnSUNCallXeHNZbUZqYXlBOUlGRW9ZMkZzYkdKaFkyc3BPMXh1WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtWmpZV3hzS0haaGJIVmxLUzUwYUdWdVVtVnpiMngyWlNoMllXeDFaU2s3WEc0Z0lDQWdmU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRkpsWjJsemRHVnljeUJoYmlCdlluTmxjblpsY2lCdmJpQmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dSM1ZoY21GdWRHVmxjenBjYmlBcVhHNGdLaUF4TGlCMGFHRjBJR1oxYkdacGJHeGxaQ0JoYm1RZ2NtVnFaV04wWldRZ2QybHNiQ0JpWlNCallXeHNaV1FnYjI1c2VTQnZibU5sTGx4dUlDb2dNaTRnZEdoaGRDQmxhWFJvWlhJZ2RHaGxJR1oxYkdacGJHeGxaQ0JqWVd4c1ltRmpheUJ2Y2lCMGFHVWdjbVZxWldOMFpXUWdZMkZzYkdKaFkyc2dkMmxzYkNCaVpWeHVJQ29nSUNBZ1kyRnNiR1ZrTENCaWRYUWdibTkwSUdKdmRHZ3VYRzRnS2lBekxpQjBhR0YwSUdaMWJHWnBiR3hsWkNCaGJtUWdjbVZxWldOMFpXUWdkMmxzYkNCdWIzUWdZbVVnWTJGc2JHVmtJR2x1SUhSb2FYTWdkSFZ5Ymk1Y2JpQXFYRzRnS2lCQWNHRnlZVzBnZG1Gc2RXVWdJQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdkRzhnYjJKelpYSjJaVnh1SUNvZ1FIQmhjbUZ0SUdaMWJHWnBiR3hsWkNBZ1puVnVZM1JwYjI0Z2RHOGdZbVVnWTJGc2JHVmtJSGRwZEdnZ2RHaGxJR1oxYkdacGJHeGxaQ0IyWVd4MVpWeHVJQ29nUUhCaGNtRnRJSEpsYW1WamRHVmtJQ0FnWm5WdVkzUnBiMjRnZEc4Z1ltVWdZMkZzYkdWa0lIZHBkR2dnZEdobElISmxhbVZqZEdsdmJpQmxlR05sY0hScGIyNWNiaUFxSUVCd1lYSmhiU0J3Y205bmNtVnpjMlZrSUdaMWJtTjBhVzl1SUhSdklHSmxJR05oYkd4bFpDQnZiaUJoYm5rZ2NISnZaM0psYzNNZ2JtOTBhV1pwWTJGMGFXOXVjMXh1SUNvZ1FISmxkSFZ5YmlCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WMGRYSnVJSFpoYkhWbElHWnliMjBnZEdobElHbHVkbTlyWldRZ1kyRnNiR0poWTJ0Y2JpQXFMMXh1VVM1M2FHVnVJRDBnZDJobGJqdGNibVoxYm1OMGFXOXVJSGRvWlc0b2RtRnNkV1VzSUdaMWJHWnBiR3hsWkN3Z2NtVnFaV04wWldRc0lIQnliMmR5WlhOelpXUXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaDJZV3gxWlNrdWRHaGxiaWhtZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrTENCd2NtOW5jbVZ6YzJWa0tUdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWRHaGxibEpsYzI5c2RtVWdQU0JtZFc1amRHbHZiaUFvZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTUwYUdWdUtHWjFibU4wYVc5dUlDZ3BJSHNnY21WMGRYSnVJSFpoYkhWbE95QjlLVHRjYm4wN1hHNWNibEV1ZEdobGJsSmxjMjlzZG1VZ1BTQm1kVzVqZEdsdmJpQW9jSEp2YldselpTd2dkbUZzZFdVcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNod2NtOXRhWE5sS1M1MGFHVnVVbVZ6YjJ4MlpTaDJZV3gxWlNrN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGFHVnVVbVZxWldOMElEMGdablZ1WTNScGIyNGdLSEpsWVhOdmJpa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMblJvWlc0b1puVnVZM1JwYjI0Z0tDa2dleUIwYUhKdmR5QnlaV0Z6YjI0N0lIMHBPMXh1ZlR0Y2JseHVVUzUwYUdWdVVtVnFaV04wSUQwZ1puVnVZM1JwYjI0Z0tIQnliMjFwYzJVc0lISmxZWE52YmlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlVwTG5Sb1pXNVNaV3BsWTNRb2NtVmhjMjl1S1R0Y2JuMDdYRzVjYmk4cUtseHVJQ29nU1dZZ1lXNGdiMkpxWldOMElHbHpJRzV2ZENCaElIQnliMjFwYzJVc0lHbDBJR2x6SUdGeklGd2libVZoY2x3aUlHRnpJSEJ2YzNOcFlteGxMbHh1SUNvZ1NXWWdZU0J3Y205dGFYTmxJR2x6SUhKbGFtVmpkR1ZrTENCcGRDQnBjeUJoY3lCY0ltNWxZWEpjSWlCaGN5QndiM056YVdKc1pTQjBiMjh1WEc0Z0tpQkpaaUJwZE9LQW1YTWdZU0JtZFd4bWFXeHNaV1FnY0hKdmJXbHpaU3dnZEdobElHWjFiR1pwYkd4dFpXNTBJSFpoYkhWbElHbHpJRzVsWVhKbGNpNWNiaUFxSUVsbUlHbDA0b0NaY3lCaElHUmxabVZ5Y21Wa0lIQnliMjFwYzJVZ1lXNWtJSFJvWlNCa1pXWmxjbkpsWkNCb1lYTWdZbVZsYmlCeVpYTnZiSFpsWkN3Z2RHaGxYRzRnS2lCeVpYTnZiSFYwYVc5dUlHbHpJRndpYm1WaGNtVnlYQ0l1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wWEc0Z0tpQkFjbVYwZFhKdWN5QnRiM04wSUhKbGMyOXNkbVZrSUNodVpXRnlaWE4wS1NCbWIzSnRJRzltSUhSb1pTQnZZbXBsWTNSY2JpQXFMMXh1WEc0dkx5QllXRmdnYzJodmRXeGtJSGRsSUhKbExXUnZJSFJvYVhNL1hHNVJMbTVsWVhKbGNpQTlJRzVsWVhKbGNqdGNibVoxYm1OMGFXOXVJRzVsWVhKbGNpaDJZV3gxWlNrZ2UxeHVJQ0FnSUdsbUlDaHBjMUJ5YjIxcGMyVW9kbUZzZFdVcEtTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCcGJuTndaV04wWldRZ1BTQjJZV3gxWlM1cGJuTndaV04wS0NrN1hHNGdJQ0FnSUNBZ0lHbG1JQ2hwYm5Od1pXTjBaV1F1YzNSaGRHVWdQVDA5SUZ3aVpuVnNabWxzYkdWa1hDSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCcGJuTndaV04wWldRdWRtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lDQWdjbVYwZFhKdUlIWmhiSFZsTzF4dWZWeHVYRzR2S2lwY2JpQXFJRUJ5WlhSMWNtNXpJSGRvWlhSb1pYSWdkR2hsSUdkcGRtVnVJRzlpYW1WamRDQnBjeUJoSUhCeWIyMXBjMlV1WEc0Z0tpQlBkR2hsY25kcGMyVWdhWFFnYVhNZ1lTQm1kV3htYVd4c1pXUWdkbUZzZFdVdVhHNGdLaTljYmxFdWFYTlFjbTl0YVhObElEMGdhWE5RY205dGFYTmxPMXh1Wm5WdVkzUnBiMjRnYVhOUWNtOXRhWE5sS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQnZZbXBsWTNRZ2FXNXpkR0Z1WTJWdlppQlFjbTl0YVhObE8xeHVmVnh1WEc1UkxtbHpVSEp2YldselpVRnNhV3RsSUQwZ2FYTlFjbTl0YVhObFFXeHBhMlU3WEc1bWRXNWpkR2x2YmlCcGMxQnliMjFwYzJWQmJHbHJaU2h2WW1wbFkzUXBJSHRjYmlBZ0lDQnlaWFIxY200Z2FYTlBZbXBsWTNRb2IySnFaV04wS1NBbUppQjBlWEJsYjJZZ2IySnFaV04wTG5Sb1pXNGdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lqdGNibjFjYmx4dUx5b3FYRzRnS2lCQWNtVjBkWEp1Y3lCM2FHVjBhR1Z5SUhSb1pTQm5hWFpsYmlCdlltcGxZM1FnYVhNZ1lTQndaVzVrYVc1bklIQnliMjFwYzJVc0lHMWxZVzVwYm1jZ2JtOTBYRzRnS2lCbWRXeG1hV3hzWldRZ2IzSWdjbVZxWldOMFpXUXVYRzRnS2k5Y2JsRXVhWE5RWlc1a2FXNW5JRDBnYVhOUVpXNWthVzVuTzF4dVpuVnVZM1JwYjI0Z2FYTlFaVzVrYVc1bktHOWlhbVZqZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUJwYzFCeWIyMXBjMlVvYjJKcVpXTjBLU0FtSmlCdlltcGxZM1F1YVc1emNHVmpkQ2dwTG5OMFlYUmxJRDA5UFNCY0luQmxibVJwYm1kY0lqdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWFYTlFaVzVrYVc1bklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1sdWMzQmxZM1FvS1M1emRHRjBaU0E5UFQwZ1hDSndaVzVrYVc1blhDSTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSFpoYkhWbElHOXlJR1oxYkdacGJHeGxaRnh1SUNvZ2NISnZiV2x6WlM1Y2JpQXFMMXh1VVM1cGMwWjFiR1pwYkd4bFpDQTlJR2x6Um5Wc1ptbHNiR1ZrTzF4dVpuVnVZM1JwYjI0Z2FYTkdkV3htYVd4c1pXUW9iMkpxWldOMEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUNGcGMxQnliMjFwYzJVb2IySnFaV04wS1NCOGZDQnZZbXBsWTNRdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbVoxYkdacGJHeGxaRndpTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVwYzBaMWJHWnBiR3hsWkNBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVwYm5Od1pXTjBLQ2t1YzNSaGRHVWdQVDA5SUZ3aVpuVnNabWxzYkdWa1hDSTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVXVYRzRnS2k5Y2JsRXVhWE5TWldwbFkzUmxaQ0E5SUdselVtVnFaV04wWldRN1hHNW1kVzVqZEdsdmJpQnBjMUpsYW1WamRHVmtLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCcGMxQnliMjFwYzJVb2IySnFaV04wS1NBbUppQnZZbXBsWTNRdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbkpsYW1WamRHVmtYQ0k3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbWx6VW1WcVpXTjBaV1FnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVhVzV6Y0dWamRDZ3BMbk4wWVhSbElEMDlQU0JjSW5KbGFtVmpkR1ZrWENJN1hHNTlPMXh1WEc0dkx5OHZJRUpGUjBsT0lGVk9TRUZPUkV4RlJDQlNSVXBGUTFSSlQwNGdWRkpCUTB0SlRrZGNibHh1THk4Z1ZHaHBjeUJ3Y205dGFYTmxJR3hwWW5KaGNua2dZMjl1YzNWdFpYTWdaWGhqWlhCMGFXOXVjeUIwYUhKdmQyNGdhVzRnYUdGdVpHeGxjbk1nYzI4Z2RHaGxlU0JqWVc0Z1ltVmNiaTh2SUdoaGJtUnNaV1FnWW5rZ1lTQnpkV0p6WlhGMVpXNTBJSEJ5YjIxcGMyVXVJQ0JVYUdVZ1pYaGpaWEIwYVc5dWN5Qm5aWFFnWVdSa1pXUWdkRzhnZEdocGN5QmhjbkpoZVNCM2FHVnVYRzR2THlCMGFHVjVJR0Z5WlNCamNtVmhkR1ZrTENCaGJtUWdjbVZ0YjNabFpDQjNhR1Z1SUhSb1pYa2dZWEpsSUdoaGJtUnNaV1F1SUNCT2IzUmxJSFJvWVhRZ2FXNGdSVk0ySUc5eVhHNHZMeUJ6YUdsdGJXVmtJR1Z1ZG1seWIyNXRaVzUwY3l3Z2RHaHBjeUIzYjNWc1pDQnVZWFIxY21Gc2JIa2dZbVVnWVNCZ1UyVjBZQzVjYm5aaGNpQjFibWhoYm1Sc1pXUlNaV0Z6YjI1eklEMGdXMTA3WEc1MllYSWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeUE5SUZ0ZE8xeHVkbUZ5SUhKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlGdGRPMXh1ZG1GeUlIUnlZV05yVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlIUnlkV1U3WEc1Y2JtWjFibU4wYVc5dUlISmxjMlYwVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lncElIdGNiaUFnSUNCMWJtaGhibVJzWldSU1pXRnpiMjV6TG14bGJtZDBhQ0E5SURBN1hHNGdJQ0FnZFc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3k1c1pXNW5kR2dnUFNBd08xeHVYRzRnSUNBZ2FXWWdLQ0YwY21GamExVnVhR0Z1Wkd4bFpGSmxhbVZqZEdsdmJuTXBJSHRjYmlBZ0lDQWdJQ0FnZEhKaFkydFZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpJRDBnZEhKMVpUdGNiaUFnSUNCOVhHNTlYRzVjYm1aMWJtTjBhVzl1SUhSeVlXTnJVbVZxWldOMGFXOXVLSEJ5YjIxcGMyVXNJSEpsWVhOdmJpa2dlMXh1SUNBZ0lHbG1JQ2doZEhKaFkydFZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQndjbTlqWlhOeklEMDlQU0JjSW05aWFtVmpkRndpSUNZbUlIUjVjR1Z2WmlCd2NtOWpaWE56TG1WdGFYUWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0JSTG01bGVIUlVhV05yTG5KMWJrRm1kR1Z5S0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGhjbkpoZVY5cGJtUmxlRTltS0hWdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ym5Nc0lIQnliMjFwYzJVcElDRTlQU0F0TVNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIQnliMk5sYzNNdVpXMXBkQ2hjSW5WdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ymx3aUxDQnlaV0Z6YjI0c0lIQnliMjFwYzJVcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxjRzl5ZEdWa1ZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5NXdkWE5vS0hCeWIyMXBjMlVwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0IxYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6TG5CMWMyZ29jSEp2YldselpTazdYRzRnSUNBZ2FXWWdLSEpsWVhOdmJpQW1KaUIwZVhCbGIyWWdjbVZoYzI5dUxuTjBZV05ySUNFOVBTQmNJblZ1WkdWbWFXNWxaRndpS1NCN1hHNGdJQ0FnSUNBZ0lIVnVhR0Z1Wkd4bFpGSmxZWE52Ym5NdWNIVnphQ2h5WldGemIyNHVjM1JoWTJzcE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUhWdWFHRnVaR3hsWkZKbFlYTnZibk11Y0hWemFDaGNJaWh1YnlCemRHRmpheWtnWENJZ0t5QnlaV0Z6YjI0cE8xeHVJQ0FnSUgxY2JuMWNibHh1Wm5WdVkzUnBiMjRnZFc1MGNtRmphMUpsYW1WamRHbHZiaWh3Y205dGFYTmxLU0I3WEc0Z0lDQWdhV1lnS0NGMGNtRmphMVZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1wSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1TzF4dUlDQWdJSDFjYmx4dUlDQWdJSFpoY2lCaGRDQTlJR0Z5Y21GNVgybHVaR1Y0VDJZb2RXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5d2djSEp2YldselpTazdYRzRnSUNBZ2FXWWdLR0YwSUNFOVBTQXRNU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9kSGx3Wlc5bUlIQnliMk5sYzNNZ1BUMDlJRndpYjJKcVpXTjBYQ0lnSmlZZ2RIbHdaVzltSUhCeWIyTmxjM011WlcxcGRDQTlQVDBnWENKbWRXNWpkR2x2Ymx3aUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCUkxtNWxlSFJVYVdOckxuSjFia0ZtZEdWeUtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IyWVhJZ1lYUlNaWEJ2Y25RZ1BTQmhjbkpoZVY5cGJtUmxlRTltS0hKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3l3Z2NISnZiV2x6WlNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR0YwVW1Wd2IzSjBJQ0U5UFNBdE1Ta2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCd2NtOWpaWE56TG1WdGFYUW9YQ0p5WldwbFkzUnBiMjVJWVc1a2JHVmtYQ0lzSUhWdWFHRnVaR3hsWkZKbFlYTnZibk5iWVhSZExDQndjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21Wd2IzSjBaV1JWYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6TG5Od2JHbGpaU2hoZEZKbGNHOXlkQ3dnTVNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeTV6Y0d4cFkyVW9ZWFFzSURFcE8xeHVJQ0FnSUNBZ0lDQjFibWhoYm1Sc1pXUlNaV0Z6YjI1ekxuTndiR2xqWlNoaGRDd2dNU2s3WEc0Z0lDQWdmVnh1ZlZ4dVhHNVJMbkpsYzJWMFZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5QTlJSEpsYzJWMFZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN6dGNibHh1VVM1blpYUlZibWhoYm1Sc1pXUlNaV0Z6YjI1eklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQzh2SUUxaGEyVWdZU0JqYjNCNUlITnZJSFJvWVhRZ1kyOXVjM1Z0WlhKeklHTmhiaWQwSUdsdWRHVnlabVZ5WlNCM2FYUm9JRzkxY2lCcGJuUmxjbTVoYkNCemRHRjBaUzVjYmlBZ0lDQnlaWFIxY200Z2RXNW9ZVzVrYkdWa1VtVmhjMjl1Y3k1emJHbGpaU2dwTzF4dWZUdGNibHh1VVM1emRHOXdWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVWSEpoWTJ0cGJtY2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WelpYUlZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpLQ2s3WEc0Z0lDQWdkSEpoWTJ0VmJtaGhibVJzWldSU1pXcGxZM1JwYjI1eklEMGdabUZzYzJVN1hHNTlPMXh1WEc1eVpYTmxkRlZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1vS1R0Y2JseHVMeTh2THlCRlRrUWdWVTVJUVU1RVRFVkVJRkpGU2tWRFZFbFBUaUJVVWtGRFMwbE9SMXh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQnlaV3BsWTNSbFpDQndjbTl0YVhObExseHVJQ29nUUhCaGNtRnRJSEpsWVhOdmJpQjJZV3gxWlNCa1pYTmpjbWxpYVc1bklIUm9aU0JtWVdsc2RYSmxYRzRnS2k5Y2JsRXVjbVZxWldOMElEMGdjbVZxWldOME8xeHVablZ1WTNScGIyNGdjbVZxWldOMEtISmxZWE52YmlrZ2UxeHVJQ0FnSUhaaGNpQnlaV3BsWTNScGIyNGdQU0JRY205dGFYTmxLSHRjYmlBZ0lDQWdJQ0FnWENKM2FHVnVYQ0k2SUdaMWJtTjBhVzl1SUNoeVpXcGxZM1JsWkNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z2JtOTBaU0IwYUdGMElIUm9aU0JsY25KdmNpQm9ZWE1nWW1WbGJpQm9ZVzVrYkdWa1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2NtVnFaV04wWldRcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjFiblJ5WVdOclVtVnFaV04wYVc5dUtIUm9hWE1wTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkR1ZrSUQ4Z2NtVnFaV04wWldRb2NtVmhjMjl1S1NBNklIUm9hWE03WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5TENCbWRXNWpkR2x2YmlCbVlXeHNZbUZqYXlncElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlIUm9hWE03WEc0Z0lDQWdmU3dnWm5WdVkzUnBiMjRnYVc1emNHVmpkQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhzZ2MzUmhkR1U2SUZ3aWNtVnFaV04wWldSY0lpd2djbVZoYzI5dU9pQnlaV0Z6YjI0Z2ZUdGNiaUFnSUNCOUtUdGNibHh1SUNBZ0lDOHZJRTV2ZEdVZ2RHaGhkQ0IwYUdVZ2NtVmhjMjl1SUdoaGN5QnViM1FnWW1WbGJpQm9ZVzVrYkdWa0xseHVJQ0FnSUhSeVlXTnJVbVZxWldOMGFXOXVLSEpsYW1WamRHbHZiaXdnY21WaGMyOXVLVHRjYmx4dUlDQWdJSEpsZEhWeWJpQnlaV3BsWTNScGIyNDdYRzU5WEc1Y2JpOHFLbHh1SUNvZ1EyOXVjM1J5ZFdOMGN5QmhJR1oxYkdacGJHeGxaQ0J3Y205dGFYTmxJR1p2Y2lCaGJpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxMbHh1SUNvZ1FIQmhjbUZ0SUhaaGJIVmxJR2x0YldWa2FXRjBaU0J5WldabGNtVnVZMlZjYmlBcUwxeHVVUzVtZFd4bWFXeHNJRDBnWm5Wc1ptbHNiRHRjYm1aMWJtTjBhVzl1SUdaMWJHWnBiR3dvZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VISnZiV2x6WlNoN1hHNGdJQ0FnSUNBZ0lGd2lkMmhsYmx3aU9pQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2laMlYwWENJNklHWjFibU4wYVc5dUlDaHVZVzFsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdWYmJtRnRaVjA3WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2ljMlYwWENJNklHWjFibU4wYVc5dUlDaHVZVzFsTENCeWFITXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIWmhiSFZsVzI1aGJXVmRJRDBnY21oek8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW1SbGJHVjBaVndpT2lCbWRXNWpkR2x2YmlBb2JtRnRaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZzWlhSbElIWmhiSFZsVzI1aGJXVmRPMXh1SUNBZ0lDQWdJQ0I5TEZ4dUlDQWdJQ0FnSUNCY0luQnZjM1JjSWpvZ1puVnVZM1JwYjI0Z0tHNWhiV1VzSUdGeVozTXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRTFoY21zZ1RXbHNiR1Z5SUhCeWIzQnZjMlZ6SUhSb1lYUWdjRzl6ZENCM2FYUm9JRzV2SUc1aGJXVWdjMmh2ZFd4a0lHRndjR3g1SUdGY2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUhCeWIyMXBjMlZrSUdaMWJtTjBhVzl1TGx4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0c1aGJXVWdQVDA5SUc1MWJHd2dmSHdnYm1GdFpTQTlQVDBnZG05cFpDQXdLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSFpoYkhWbExtRndjR3g1S0hadmFXUWdNQ3dnWVhKbmN5azdYRzRnSUNBZ0lDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUIyWVd4MVpWdHVZVzFsWFM1aGNIQnNlU2gyWVd4MVpTd2dZWEpuY3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2lZWEJ3YkhsY0lqb2dablZ1WTNScGIyNGdLSFJvYVhOd0xDQmhjbWR6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdVdVlYQndiSGtvZEdocGMzQXNJR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW10bGVYTmNJam9nWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJRzlpYW1WamRGOXJaWGx6S0haaGJIVmxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDBzSUhadmFXUWdNQ3dnWm5WdVkzUnBiMjRnYVc1emNHVmpkQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhzZ2MzUmhkR1U2SUZ3aVpuVnNabWxzYkdWa1hDSXNJSFpoYkhWbE9pQjJZV3gxWlNCOU8xeHVJQ0FnSUgwcE8xeHVmVnh1WEc0dktpcGNiaUFxSUVOdmJuWmxjblJ6SUhSb1pXNWhZbXhsY3lCMGJ5QlJJSEJ5YjIxcGMyVnpMbHh1SUNvZ1FIQmhjbUZ0SUhCeWIyMXBjMlVnZEdobGJtRmliR1VnY0hKdmJXbHpaVnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQlJJSEJ5YjIxcGMyVmNiaUFxTDF4dVpuVnVZM1JwYjI0Z1kyOWxjbU5sS0hCeWIyMXBjMlVwSUh0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY0hKdmJXbHpaUzUwYUdWdUtHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vc0lHUmxabVZ5Y21Wa0xuSmxhbVZqZEN3Z1pHVm1aWEp5WldRdWJtOTBhV1o1S1R0Y2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwcE8xeHVJQ0FnSUhKbGRIVnliaUJrWldabGNuSmxaQzV3Y205dGFYTmxPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlFRnVibTkwWVhSbGN5QmhiaUJ2WW1wbFkzUWdjM1ZqYUNCMGFHRjBJR2wwSUhkcGJHd2dibVYyWlhJZ1ltVmNiaUFxSUhSeVlXNXpabVZ5Y21Wa0lHRjNZWGtnWm5KdmJTQjBhR2x6SUhCeWIyTmxjM01nYjNabGNpQmhibmtnY0hKdmJXbHpaVnh1SUNvZ1kyOXRiWFZ1YVdOaGRHbHZiaUJqYUdGdWJtVnNMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkRnh1SUNvZ1FISmxkSFZ5Ym5NZ2NISnZiV2x6WlNCaElIZHlZWEJ3YVc1bklHOW1JSFJvWVhRZ2IySnFaV04wSUhSb1lYUmNiaUFxSUdGa1pHbDBhVzl1WVd4c2VTQnlaWE53YjI1a2N5QjBieUIwYUdVZ1hDSnBjMFJsWmx3aUlHMWxjM05oWjJWY2JpQXFJSGRwZEdodmRYUWdZU0J5WldwbFkzUnBiMjR1WEc0Z0tpOWNibEV1YldGemRHVnlJRDBnYldGemRHVnlPMXh1Wm5WdVkzUnBiMjRnYldGemRHVnlLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUWNtOXRhWE5sS0h0Y2JpQWdJQ0FnSUNBZ1hDSnBjMFJsWmx3aU9pQm1kVzVqZEdsdmJpQW9LU0I3ZlZ4dUlDQWdJSDBzSUdaMWJtTjBhVzl1SUdaaGJHeGlZV05yS0c5d0xDQmhjbWR6S1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCa2FYTndZWFJqYUNodlltcGxZM1FzSUc5d0xDQmhjbWR6S1R0Y2JpQWdJQ0I5TENCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lIMHBPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlGTndjbVZoWkhNZ2RHaGxJSFpoYkhWbGN5QnZaaUJoSUhCeWIyMXBjMlZrSUdGeWNtRjVJRzltSUdGeVozVnRaVzUwY3lCcGJuUnZJSFJvWlZ4dUlDb2dablZzWm1sc2JHMWxiblFnWTJGc2JHSmhZMnN1WEc0Z0tpQkFjR0Z5WVcwZ1puVnNabWxzYkdWa0lHTmhiR3hpWVdOcklIUm9ZWFFnY21WalpXbDJaWE1nZG1GeWFXRmthV01nWVhKbmRXMWxiblJ6SUdaeWIyMGdkR2hsWEc0Z0tpQndjbTl0YVhObFpDQmhjbkpoZVZ4dUlDb2dRSEJoY21GdElISmxhbVZqZEdWa0lHTmhiR3hpWVdOcklIUm9ZWFFnY21WalpXbDJaWE1nZEdobElHVjRZMlZ3ZEdsdmJpQnBaaUIwYUdVZ2NISnZiV2x6WlZ4dUlDb2dhWE1nY21WcVpXTjBaV1F1WEc0Z0tpQkFjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1VnYjNJZ2RHaHliM2R1SUdWNFkyVndkR2x2YmlCdlpseHVJQ29nWldsMGFHVnlJR05oYkd4aVlXTnJMbHh1SUNvdlhHNVJMbk53Y21WaFpDQTlJSE53Y21WaFpEdGNibVoxYm1OMGFXOXVJSE53Y21WaFpDaDJZV3gxWlN3Z1puVnNabWxzYkdWa0xDQnlaV3BsWTNSbFpDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktIWmhiSFZsS1M1emNISmxZV1FvWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkNrN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG5Od2NtVmhaQ0E5SUdaMWJtTjBhVzl1SUNobWRXeG1hV3hzWldRc0lISmxhbVZqZEdWa0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVZV3hzS0NrdWRHaGxiaWhtZFc1amRHbHZiaUFvWVhKeVlYa3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1oxYkdacGJHeGxaQzVoY0hCc2VTaDJiMmxrSURBc0lHRnljbUY1S1R0Y2JpQWdJQ0I5TENCeVpXcGxZM1JsWkNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZSb1pTQmhjM2x1WXlCbWRXNWpkR2x2YmlCcGN5QmhJR1JsWTI5eVlYUnZjaUJtYjNJZ1oyVnVaWEpoZEc5eUlHWjFibU4wYVc5dWN5d2dkSFZ5Ym1sdVoxeHVJQ29nZEdobGJTQnBiblJ2SUdGemVXNWphSEp2Ym05MWN5Qm5aVzVsY21GMGIzSnpMaUFnUVd4MGFHOTFaMmdnWjJWdVpYSmhkRzl5Y3lCaGNtVWdiMjVzZVNCd1lYSjBYRzRnS2lCdlppQjBhR1VnYm1WM1pYTjBJRVZEVFVGVFkzSnBjSFFnTmlCa2NtRm1kSE1zSUhSb2FYTWdZMjlrWlNCa2IyVnpJRzV2ZENCallYVnpaU0J6ZVc1MFlYaGNiaUFxSUdWeWNtOXljeUJwYmlCdmJHUmxjaUJsYm1kcGJtVnpMaUFnVkdocGN5QmpiMlJsSUhOb2IzVnNaQ0JqYjI1MGFXNTFaU0IwYnlCM2IzSnJJR0Z1WkNCM2FXeHNYRzRnS2lCcGJpQm1ZV04wSUdsdGNISnZkbVVnYjNabGNpQjBhVzFsSUdGeklIUm9aU0JzWVc1bmRXRm5aU0JwYlhCeWIzWmxjeTVjYmlBcVhHNGdLaUJGVXpZZ1oyVnVaWEpoZEc5eWN5QmhjbVVnWTNWeWNtVnVkR3g1SUhCaGNuUWdiMllnVmpnZ2RtVnljMmx2YmlBekxqRTVJSGRwZEdnZ2RHaGxYRzRnS2lBdExXaGhjbTF2Ym5rdFoyVnVaWEpoZEc5eWN5QnlkVzUwYVcxbElHWnNZV2NnWlc1aFlteGxaQzRnSUZOd2FXUmxjazF2Ym10bGVTQm9ZWE1nYUdGa0lIUm9aVzFjYmlBcUlHWnZjaUJzYjI1blpYSXNJR0oxZENCMWJtUmxjaUJoYmlCdmJHUmxjaUJRZVhSb2IyNHRhVzV6Y0dseVpXUWdabTl5YlM0Z0lGUm9hWE1nWm5WdVkzUnBiMjVjYmlBcUlIZHZjbXR6SUc5dUlHSnZkR2dnYTJsdVpITWdiMllnWjJWdVpYSmhkRzl5Y3k1Y2JpQXFYRzRnS2lCRVpXTnZjbUYwWlhNZ1lTQm5aVzVsY21GMGIzSWdablZ1WTNScGIyNGdjM1ZqYUNCMGFHRjBPbHh1SUNvZ0lDMGdhWFFnYldGNUlIbHBaV3hrSUhCeWIyMXBjMlZ6WEc0Z0tpQWdMU0JsZUdWamRYUnBiMjRnZDJsc2JDQmpiMjUwYVc1MVpTQjNhR1Z1SUhSb1lYUWdjSEp2YldselpTQnBjeUJtZFd4bWFXeHNaV1JjYmlBcUlDQXRJSFJvWlNCMllXeDFaU0J2WmlCMGFHVWdlV2xsYkdRZ1pYaHdjbVZ6YzJsdmJpQjNhV3hzSUdKbElIUm9aU0JtZFd4bWFXeHNaV1FnZG1Gc2RXVmNiaUFxSUNBdElHbDBJSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsSUNoM2FHVnVJSFJvWlNCblpXNWxjbUYwYjNKY2JpQXFJQ0FnSUhOMGIzQnpJR2wwWlhKaGRHbHVaeWxjYmlBcUlDQXRJSFJvWlNCa1pXTnZjbUYwWldRZ1puVnVZM1JwYjI0Z2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVZ1ptOXlJSFJvWlNCeVpYUjFjbTRnZG1Gc2RXVmNiaUFxSUNBZ0lHOW1JSFJvWlNCblpXNWxjbUYwYjNJZ2IzSWdkR2hsSUdacGNuTjBJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVWdZVzF2Ym1jZ2RHaHZjMlZjYmlBcUlDQWdJSGxwWld4a1pXUXVYRzRnS2lBZ0xTQnBaaUJoYmlCbGNuSnZjaUJwY3lCMGFISnZkMjRnYVc0Z2RHaGxJR2RsYm1WeVlYUnZjaXdnYVhRZ2NISnZjR0ZuWVhSbGN5QjBhSEp2ZFdkb1hHNGdLaUFnSUNCbGRtVnllU0JtYjJ4c2IzZHBibWNnZVdsbGJHUWdkVzUwYVd3Z2FYUWdhWE1nWTJGMVoyaDBMQ0J2Y2lCMWJuUnBiQ0JwZENCbGMyTmhjR1Z6WEc0Z0tpQWdJQ0IwYUdVZ1oyVnVaWEpoZEc5eUlHWjFibU4wYVc5dUlHRnNkRzluWlhSb1pYSXNJR0Z1WkNCcGN5QjBjbUZ1YzJ4aGRHVmtJR2x1ZEc4Z1lWeHVJQ29nSUNBZ2NtVnFaV04wYVc5dUlHWnZjaUIwYUdVZ2NISnZiV2x6WlNCeVpYUjFjbTVsWkNCaWVTQjBhR1VnWkdWamIzSmhkR1ZrSUdkbGJtVnlZWFJ2Y2k1Y2JpQXFMMXh1VVM1aGMzbHVZeUE5SUdGemVXNWpPMXh1Wm5WdVkzUnBiMjRnWVhONWJtTW9iV0ZyWlVkbGJtVnlZWFJ2Y2lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDOHZJSGRvWlc0Z2RtVnlZaUJwY3lCY0luTmxibVJjSWl3Z1lYSm5JR2x6SUdFZ2RtRnNkV1ZjYmlBZ0lDQWdJQ0FnTHk4Z2QyaGxiaUIyWlhKaUlHbHpJRndpZEdoeWIzZGNJaXdnWVhKbklHbHpJR0Z1SUdWNFkyVndkR2x2Ymx4dUlDQWdJQ0FnSUNCbWRXNWpkR2x2YmlCamIyNTBhVzUxWlhJb2RtVnlZaXdnWVhKbktTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllYSWdjbVZ6ZFd4ME8xeHVYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QlZiblJwYkNCV09DQXpMakU1SUM4Z1EyaHliMjFwZFcwZ01qa2dhWE1nY21Wc1pXRnpaV1FzSUZOd2FXUmxjazF2Ym10bGVTQnBjeUIwYUdVZ2IyNXNlVnh1SUNBZ0lDQWdJQ0FnSUNBZ0x5OGdaVzVuYVc1bElIUm9ZWFFnYUdGeklHRWdaR1Z3Ykc5NVpXUWdZbUZ6WlNCdlppQmljbTkzYzJWeWN5QjBhR0YwSUhOMWNIQnZjblFnWjJWdVpYSmhkRzl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUVodmQyVjJaWElzSUZOTkozTWdaMlZ1WlhKaGRHOXljeUIxYzJVZ2RHaGxJRkI1ZEdodmJpMXBibk53YVhKbFpDQnpaVzFoYm5ScFkzTWdiMlpjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRzkxZEdSaGRHVmtJRVZUTmlCa2NtRm1kSE11SUNCWFpTQjNiM1ZzWkNCc2FXdGxJSFJ2SUhOMWNIQnZjblFnUlZNMkxDQmlkWFFnZDJVblpDQmhiSE52WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJzYVd0bElIUnZJRzFoYTJVZ2FYUWdjRzl6YzJsaWJHVWdkRzhnZFhObElHZGxibVZ5WVhSdmNuTWdhVzRnWkdWd2JHOTVaV1FnWW5KdmQzTmxjbk1zSUhOdlhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCM1pTQmhiSE52SUhOMWNIQnZjblFnVUhsMGFHOXVMWE4wZVd4bElHZGxibVZ5WVhSdmNuTXVJQ0JCZENCemIyMWxJSEJ2YVc1MElIZGxJR05oYmlCeVpXMXZkbVZjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJSFJvYVhNZ1lteHZZMnN1WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMGVYQmxiMllnVTNSdmNFbDBaWEpoZEdsdmJpQTlQVDBnWENKMWJtUmxabWx1WldSY0lpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQzh2SUVWVE5pQkhaVzVsY21GMGIzSnpYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVZ6ZFd4MElEMGdaMlZ1WlhKaGRHOXlXM1psY21KZEtHRnlaeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNRb1pYaGpaWEIwYVc5dUtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhV1lnS0hKbGMzVnNkQzVrYjI1bEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJSS0hKbGMzVnNkQzUyWVd4MVpTazdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSGRvWlc0b2NtVnpkV3gwTG5aaGJIVmxMQ0JqWVd4c1ltRmpheXdnWlhKeVltRmpheWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJUY0dsa1pYSk5iMjVyWlhrZ1IyVnVaWEpoZEc5eWMxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDOHZJRVpKV0UxRk9pQlNaVzF2ZG1VZ2RHaHBjeUJqWVhObElIZG9aVzRnVTAwZ1pHOWxjeUJGVXpZZ1oyVnVaWEpoZEc5eWN5NWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWE4xYkhRZ1BTQm5aVzVsY21GMGIzSmJkbVZ5WWwwb1lYSm5LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsZUdObGNIUnBiMjRwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhV1lnS0dselUzUnZjRWwwWlhKaGRHbHZiaWhsZUdObGNIUnBiMjRwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnVVNobGVHTmxjSFJwYjI0dWRtRnNkV1VwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkQ2hsZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjNhR1Z1S0hKbGMzVnNkQ3dnWTJGc2JHSmhZMnNzSUdWeWNtSmhZMnNwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhaaGNpQm5aVzVsY21GMGIzSWdQU0J0WVd0bFIyVnVaWEpoZEc5eUxtRndjR3g1S0hSb2FYTXNJR0Z5WjNWdFpXNTBjeWs3WEc0Z0lDQWdJQ0FnSUhaaGNpQmpZV3hzWW1GamF5QTlJR052Ym5ScGJuVmxjaTVpYVc1a0tHTnZiblJwYm5WbGNpd2dYQ0p1WlhoMFhDSXBPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pYSnlZbUZqYXlBOUlHTnZiblJwYm5WbGNpNWlhVzVrS0dOdmJuUnBiblZsY2l3Z1hDSjBhSEp2ZDF3aUtUdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOcktDazdYRzRnSUNBZ2ZUdGNibjFjYmx4dUx5b3FYRzRnS2lCVWFHVWdjM0JoZDI0Z1puVnVZM1JwYjI0Z2FYTWdZU0J6YldGc2JDQjNjbUZ3Y0dWeUlHRnliM1Z1WkNCaGMzbHVZeUIwYUdGMElHbHRiV1ZrYVdGMFpXeDVYRzRnS2lCallXeHNjeUIwYUdVZ1oyVnVaWEpoZEc5eUlHRnVaQ0JoYkhOdklHVnVaSE1nZEdobElIQnliMjFwYzJVZ1kyaGhhVzRzSUhOdklIUm9ZWFFnWVc1NVhHNGdLaUIxYm1oaGJtUnNaV1FnWlhKeWIzSnpJR0Z5WlNCMGFISnZkMjRnYVc1emRHVmhaQ0J2WmlCbWIzSjNZWEprWldRZ2RHOGdkR2hsSUdWeWNtOXlYRzRnS2lCb1lXNWtiR1Z5TGlCVWFHbHpJR2x6SUhWelpXWjFiQ0JpWldOaGRYTmxJR2wwSjNNZ1pYaDBjbVZ0Wld4NUlHTnZiVzF2YmlCMGJ5QnlkVzVjYmlBcUlHZGxibVZ5WVhSdmNuTWdZWFFnZEdobElIUnZjQzFzWlhabGJDQjBieUIzYjNKcklIZHBkR2dnYkdsaWNtRnlhV1Z6TGx4dUlDb3ZYRzVSTG5Od1lYZHVJRDBnYzNCaGQyNDdYRzVtZFc1amRHbHZiaUJ6Y0dGM2JpaHRZV3RsUjJWdVpYSmhkRzl5S1NCN1hHNGdJQ0FnVVM1a2IyNWxLRkV1WVhONWJtTW9iV0ZyWlVkbGJtVnlZWFJ2Y2lrb0tTazdYRzU5WEc1Y2JpOHZJRVpKV0UxRk9pQlNaVzF2ZG1VZ2RHaHBjeUJwYm5SbGNtWmhZMlVnYjI1alpTQkZVellnWjJWdVpYSmhkRzl5Y3lCaGNtVWdhVzRnVTNCcFpHVnlUVzl1YTJWNUxseHVMeW9xWEc0Z0tpQlVhSEp2ZDNNZ1lTQlNaWFIxY201V1lXeDFaU0JsZUdObGNIUnBiMjRnZEc4Z2MzUnZjQ0JoYmlCaGMzbHVZMmh5YjI1dmRYTWdaMlZ1WlhKaGRHOXlMbHh1SUNwY2JpQXFJRlJvYVhNZ2FXNTBaWEptWVdObElHbHpJR0VnYzNSdmNDMW5ZWEFnYldWaGMzVnlaU0IwYnlCemRYQndiM0owSUdkbGJtVnlZWFJ2Y2lCeVpYUjFjbTVjYmlBcUlIWmhiSFZsY3lCcGJpQnZiR1JsY2lCR2FYSmxabTk0TDFOd2FXUmxjazF2Ym10bGVTNGdJRWx1SUdKeWIzZHpaWEp6SUhSb1lYUWdjM1Z3Y0c5eWRDQkZVelpjYmlBcUlHZGxibVZ5WVhSdmNuTWdiR2xyWlNCRGFISnZiV2wxYlNBeU9Td2dhblZ6ZENCMWMyVWdYQ0p5WlhSMWNtNWNJaUJwYmlCNWIzVnlJR2RsYm1WeVlYUnZjbHh1SUNvZ1puVnVZM1JwYjI1ekxseHVJQ3BjYmlBcUlFQndZWEpoYlNCMllXeDFaU0IwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJR1p2Y2lCMGFHVWdjM1Z5Y205MWJtUnBibWNnWjJWdVpYSmhkRzl5WEc0Z0tpQkFkR2h5YjNkeklGSmxkSFZ5YmxaaGJIVmxJR1Y0WTJWd2RHbHZiaUIzYVhSb0lIUm9aU0IyWVd4MVpTNWNiaUFxSUVCbGVHRnRjR3hsWEc0Z0tpQXZMeUJGVXpZZ2MzUjViR1ZjYmlBcUlGRXVZWE41Ym1Nb1puVnVZM1JwYjI0cUlDZ3BJSHRjYmlBcUlDQWdJQ0FnZG1GeUlHWnZieUE5SUhscFpXeGtJR2RsZEVadmIxQnliMjFwYzJVb0tUdGNiaUFxSUNBZ0lDQWdkbUZ5SUdKaGNpQTlJSGxwWld4a0lHZGxkRUpoY2xCeWIyMXBjMlVvS1R0Y2JpQXFJQ0FnSUNBZ2NtVjBkWEp1SUdadmJ5QXJJR0poY2p0Y2JpQXFJSDBwWEc0Z0tpQXZMeUJQYkdSbGNpQlRjR2xrWlhKTmIyNXJaWGtnYzNSNWJHVmNiaUFxSUZFdVlYTjVibU1vWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ29nSUNBZ0lDQjJZWElnWm05dklEMGdlV2xsYkdRZ1oyVjBSbTl2VUhKdmJXbHpaU2dwTzF4dUlDb2dJQ0FnSUNCMllYSWdZbUZ5SUQwZ2VXbGxiR1FnWjJWMFFtRnlVSEp2YldselpTZ3BPMXh1SUNvZ0lDQWdJQ0JSTG5KbGRIVnliaWhtYjI4Z0t5QmlZWElwTzF4dUlDb2dmU2xjYmlBcUwxeHVVVnRjSW5KbGRIVnlibHdpWFNBOUlGOXlaWFIxY200N1hHNW1kVzVqZEdsdmJpQmZjbVYwZFhKdUtIWmhiSFZsS1NCN1hHNGdJQ0FnZEdoeWIzY2dibVYzSUZGU1pYUjFjbTVXWVd4MVpTaDJZV3gxWlNrN1hHNTlYRzVjYmk4cUtseHVJQ29nVkdobElIQnliMjFwYzJWa0lHWjFibU4wYVc5dUlHUmxZMjl5WVhSdmNpQmxibk4xY21WeklIUm9ZWFFnWVc1NUlIQnliMjFwYzJVZ1lYSm5kVzFsYm5SelhHNGdLaUJoY21VZ2MyVjBkR3hsWkNCaGJtUWdjR0Z6YzJWa0lHRnpJSFpoYkhWbGN5QW9ZSFJvYVhOZ0lHbHpJR0ZzYzI4Z2MyVjBkR3hsWkNCaGJtUWdjR0Z6YzJWa1hHNGdLaUJoY3lCaElIWmhiSFZsS1M0Z0lFbDBJSGRwYkd3Z1lXeHpieUJsYm5OMWNtVWdkR2hoZENCMGFHVWdjbVZ6ZFd4MElHOW1JR0VnWm5WdVkzUnBiMjRnYVhOY2JpQXFJR0ZzZDJGNWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dRR1Y0WVcxd2JHVmNiaUFxSUhaaGNpQmhaR1FnUFNCUkxuQnliMjFwYzJWa0tHWjFibU4wYVc5dUlDaGhMQ0JpS1NCN1hHNGdLaUFnSUNBZ2NtVjBkWEp1SUdFZ0t5QmlPMXh1SUNvZ2ZTazdYRzRnS2lCaFpHUW9VU2hoS1N3Z1VTaENLU2s3WEc0Z0tseHVJQ29nUUhCaGNtRnRJSHRtZFc1amRHbHZibjBnWTJGc2JHSmhZMnNnVkdobElHWjFibU4wYVc5dUlIUnZJR1JsWTI5eVlYUmxYRzRnS2lCQWNtVjBkWEp1Y3lCN1puVnVZM1JwYjI1OUlHRWdablZ1WTNScGIyNGdkR2hoZENCb1lYTWdZbVZsYmlCa1pXTnZjbUYwWldRdVhHNGdLaTljYmxFdWNISnZiV2x6WldRZ1BTQndjbTl0YVhObFpEdGNibVoxYm1OMGFXOXVJSEJ5YjIxcGMyVmtLR05oYkd4aVlXTnJLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSE53Y21WaFpDaGJkR2hwY3l3Z1lXeHNLR0Z5WjNWdFpXNTBjeWxkTENCbWRXNWpkR2x2YmlBb2MyVnNaaXdnWVhKbmN5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yTG1Gd2NHeDVLSE5sYkdZc0lHRnlaM01wTzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOU8xeHVmVnh1WEc0dktpcGNiaUFxSUhObGJtUnpJR0VnYldWemMyRm5aU0IwYnlCaElIWmhiSFZsSUdsdUlHRWdablYwZFhKbElIUjFjbTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FxSUhSb1pTQnlaV05wY0dsbGJuUmNiaUFxSUVCd1lYSmhiU0J2Y0NCMGFHVWdibUZ0WlNCdlppQjBhR1VnYldWemMyRm5aU0J2Y0dWeVlYUnBiMjRzSUdVdVp5NHNJRndpZDJobGJsd2lMRnh1SUNvZ1FIQmhjbUZ0SUdGeVozTWdablZ5ZEdobGNpQmhjbWQxYldWdWRITWdkRzhnWW1VZ1ptOXlkMkZ5WkdWa0lIUnZJSFJvWlNCdmNHVnlZWFJwYjI1Y2JpQXFJRUJ5WlhSMWNtNXpJSEpsYzNWc2RDQjdVSEp2YldselpYMGdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6ZFd4MElHOW1JSFJvWlNCdmNHVnlZWFJwYjI1Y2JpQXFMMXh1VVM1a2FYTndZWFJqYUNBOUlHUnBjM0JoZEdOb08xeHVablZ1WTNScGIyNGdaR2x6Y0dGMFkyZ29iMkpxWldOMExDQnZjQ3dnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdVpHbHpjR0YwWTJnb2IzQXNJR0Z5WjNNcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1a2FYTndZWFJqYUNBOUlHWjFibU4wYVc5dUlDaHZjQ3dnWVhKbmN5a2dlMXh1SUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0J6Wld4bUxuQnliMjFwYzJWRWFYTndZWFJqYUNoa1pXWmxjbkpsWkM1eVpYTnZiSFpsTENCdmNDd2dZWEpuY3lrN1hHNGdJQ0FnZlNrN1hHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFZGxkSE1nZEdobElIWmhiSFZsSUc5bUlHRWdjSEp2Y0dWeWRIa2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdjSEp2Y0dWeWRIa2dkRzhnWjJWMFhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQndjbTl3WlhKMGVTQjJZV3gxWlZ4dUlDb3ZYRzVSTG1kbGRDQTlJR1oxYm1OMGFXOXVJQ2h2WW1wbFkzUXNJR3RsZVNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2t1WkdsemNHRjBZMmdvWENKblpYUmNJaXdnVzJ0bGVWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVaMlYwSUQwZ1puVnVZM1JwYjI0Z0tHdGxlU2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aVoyVjBYQ0lzSUZ0clpYbGRLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dVMlYwY3lCMGFHVWdkbUZzZFdVZ2IyWWdZU0J3Y205d1pYSjBlU0JwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUc5aWFtVmpkQ0J2WW1wbFkzUmNiaUFxSUVCd1lYSmhiU0J1WVcxbElDQWdJQ0FnYm1GdFpTQnZaaUJ3Y205d1pYSjBlU0IwYnlCelpYUmNiaUFxSUVCd1lYSmhiU0IyWVd4MVpTQWdJQ0FnYm1WM0lIWmhiSFZsSUc5bUlIQnliM0JsY25SNVhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1ZjYmlBcUwxeHVVUzV6WlhRZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQnJaWGtzSUhaaGJIVmxLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbk5sZEZ3aUxDQmJhMlY1TENCMllXeDFaVjBwTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1YzJWMElEMGdablZ1WTNScGIyNGdLR3RsZVN3Z2RtRnNkV1VwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0luTmxkRndpTENCYmEyVjVMQ0IyWVd4MVpWMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkVaV3hsZEdWeklHRWdjSEp2Y0dWeWRIa2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdjSEp2Y0dWeWRIa2dkRzhnWkdWc1pYUmxYRzRnS2lCQWNtVjBkWEp1SUhCeWIyMXBjMlVnWm05eUlIUm9aU0J5WlhSMWNtNGdkbUZzZFdWY2JpQXFMMXh1VVM1a1pXd2dQU0F2THlCWVdGZ2diR1ZuWVdONVhHNVJXMXdpWkdWc1pYUmxYQ0pkSUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZEN3Z2EyVjVLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbVJsYkdWMFpWd2lMQ0JiYTJWNVhTazdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNWtaV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaVnRjSW1SbGJHVjBaVndpWFNBOUlHWjFibU4wYVc5dUlDaHJaWGtwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0ltUmxiR1YwWlZ3aUxDQmJhMlY1WFNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVsdWRtOXJaWE1nWVNCdFpYUm9iMlFnYVc0Z1lTQm1kWFIxY21VZ2RIVnliaTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnSUNBZ2NISnZiV2x6WlNCdmNpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxJR1p2Y2lCMFlYSm5aWFFnYjJKcVpXTjBYRzRnS2lCQWNHRnlZVzBnYm1GdFpTQWdJQ0FnSUc1aGJXVWdiMllnYldWMGFHOWtJSFJ2SUdsdWRtOXJaVnh1SUNvZ1FIQmhjbUZ0SUhaaGJIVmxJQ0FnSUNCaElIWmhiSFZsSUhSdklIQnZjM1FzSUhSNWNHbGpZV3hzZVNCaGJpQmhjbkpoZVNCdlpseHVJQ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JwYm5adlkyRjBhVzl1SUdGeVozVnRaVzUwY3lCbWIzSWdjSEp2YldselpYTWdkR2hoZEZ4dUlDb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmhjbVVnZFd4MGFXMWhkR1ZzZVNCaVlXTnJaV1FnZDJsMGFDQmdjbVZ6YjJ4MlpXQWdkbUZzZFdWekxGeHVJQ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JoY3lCdmNIQnZjMlZrSUhSdklIUm9iM05sSUdKaFkydGxaQ0IzYVhSb0lGVlNUSE5jYmlBcUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2QyaGxjbVZwYmlCMGFHVWdjRzl6ZEdWa0lIWmhiSFZsSUdOaGJpQmlaU0JoYm5sY2JpQXFJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdTbE5QVGlCelpYSnBZV3hwZW1GaWJHVWdiMkpxWldOMExseHVJQ29nUUhKbGRIVnliaUJ3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsWEc0Z0tpOWNiaTh2SUdKdmRXNWtJR3h2WTJGc2JIa2dZbVZqWVhWelpTQnBkQ0JwY3lCMWMyVmtJR0o1SUc5MGFHVnlJRzFsZEdodlpITmNibEV1YldGd2NHeDVJRDBnTHk4Z1dGaFlJRUZ6SUhCeWIzQnZjMlZrSUdKNUlGd2lVbVZrYzJGdVpISnZYQ0pjYmxFdWNHOXpkQ0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUc1aGJXVXNJR0Z5WjNNcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKbmMxMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkJ2YzNRZ1BTQm1kVzVqZEdsdmJpQW9ibUZ0WlN3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKbmMxMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkpiblp2YTJWeklHRWdiV1YwYUc5a0lHbHVJR0VnWm5WMGRYSmxJSFIxY200dVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHOWlhbVZqZEZ4dUlDb2dRSEJoY21GdElHNWhiV1VnSUNBZ0lDQnVZVzFsSUc5bUlHMWxkR2h2WkNCMGJ5QnBiblp2YTJWY2JpQXFJRUJ3WVhKaGJTQXVMaTVoY21keklDQWdZWEp5WVhrZ2IyWWdhVzUyYjJOaGRHbHZiaUJoY21kMWJXVnVkSE5jYmlBcUlFQnlaWFIxY200Z2NISnZiV2x6WlNCbWIzSWdkR2hsSUhKbGRIVnliaUIyWVd4MVpWeHVJQ292WEc1UkxuTmxibVFnUFNBdkx5QllXRmdnVFdGeWF5Qk5hV3hzWlhJbmN5QndjbTl3YjNObFpDQndZWEpzWVc1alpWeHVVUzV0WTJGc2JDQTlJQzh2SUZoWVdDQkJjeUJ3Y205d2IzTmxaQ0JpZVNCY0lsSmxaSE5oYm1SeWIxd2lYRzVSTG1sdWRtOXJaU0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUc1aGJXVWdMeW91TGk1aGNtZHpLaThwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeUtWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVjMlZ1WkNBOUlDOHZJRmhZV0NCTllYSnJJRTFwYkd4bGNpZHpJSEJ5YjNCdmMyVmtJSEJoY214aGJtTmxYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV0WTJGc2JDQTlJQzh2SUZoWVdDQkJjeUJ3Y205d2IzTmxaQ0JpZVNCY0lsSmxaSE5oYm1SeWIxd2lYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVwYm5admEyVWdQU0JtZFc1amRHbHZiaUFvYm1GdFpTQXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SekxDQXhLVjBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJCY0hCc2FXVnpJSFJvWlNCd2NtOXRhWE5sWkNCbWRXNWpkR2x2YmlCcGJpQmhJR1oxZEhWeVpTQjBkWEp1TGx4dUlDb2dRSEJoY21GdElHOWlhbVZqZENBZ0lDQndjbTl0YVhObElHOXlJR2x0YldWa2FXRjBaU0J5WldabGNtVnVZMlVnWm05eUlIUmhjbWRsZENCbWRXNWpkR2x2Ymx4dUlDb2dRSEJoY21GdElHRnlaM01nSUNBZ0lDQmhjbkpoZVNCdlppQmhjSEJzYVdOaGRHbHZiaUJoY21kMWJXVnVkSE5jYmlBcUwxeHVVUzVtWVhCd2JIa2dQU0JtZFc1amRHbHZiaUFvYjJKcVpXTjBMQ0JoY21kektTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a2FYTndZWFJqYUNoY0ltRndjR3g1WENJc0lGdDJiMmxrSURBc0lHRnlaM05kS1R0Y2JuMDdYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoaGNtZHpLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WkdsemNHRjBZMmdvWENKaGNIQnNlVndpTENCYmRtOXBaQ0F3TENCaGNtZHpYU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oYkd4eklIUm9aU0J3Y205dGFYTmxaQ0JtZFc1amRHbHZiaUJwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUhSaGNtZGxkQ0JtZFc1amRHbHZibHh1SUNvZ1FIQmhjbUZ0SUM0dUxtRnlaM01nSUNCaGNuSmhlU0J2WmlCaGNIQnNhV05oZEdsdmJpQmhjbWQxYldWdWRITmNiaUFxTDF4dVVWdGNJblJ5ZVZ3aVhTQTlYRzVSTG1aallXeHNJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ0F2S2lBdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aVlYQndiSGxjSWl3Z1czWnZhV1FnTUN3Z1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpMQ0F4S1YwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVptTmhiR3dnUFNCbWRXNWpkR2x2YmlBb0x5b3VMaTVoY21kektpOHBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0MmIybGtJREFzSUdGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5bGRLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dRbWx1WkhNZ2RHaGxJSEJ5YjIxcGMyVmtJR1oxYm1OMGFXOXVMQ0IwY21GdWMyWnZjbTFwYm1jZ2NtVjBkWEp1SUhaaGJIVmxjeUJwYm5SdklHRWdablZzWm1sc2JHVmtYRzRnS2lCd2NtOXRhWE5sSUdGdVpDQjBhSEp2ZDI0Z1pYSnliM0p6SUdsdWRHOGdZU0J5WldwbFkzUmxaQ0J2Ym1VdVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHWjFibU4wYVc5dVhHNGdLaUJBY0dGeVlXMGdMaTR1WVhKbmN5QWdJR0Z5Y21GNUlHOW1JR0Z3Y0d4cFkyRjBhVzl1SUdGeVozVnRaVzUwYzF4dUlDb3ZYRzVSTG1aaWFXNWtJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQndjbTl0YVhObElEMGdVU2h2WW1wbFkzUXBPMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeEtUdGNiaUFnSUNCeVpYUjFjbTRnWm5WdVkzUnBiMjRnWm1KdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoY21kekxtTnZibU5oZENoaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXBLVnh1SUNBZ0lDQWdJQ0JkS1R0Y2JpQWdJQ0I5TzF4dWZUdGNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVppYVc1a0lEMGdablZ1WTNScGIyNGdLQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlIQnliMjFwYzJVZ1BTQjBhR2x6TzF4dUlDQWdJSFpoY2lCaGNtZHpJRDBnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SektUdGNiaUFnSUNCeVpYUjFjbTRnWm5WdVkzUnBiMjRnWm1KdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoY21kekxtTnZibU5oZENoaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXBLVnh1SUNBZ0lDQWdJQ0JkS1R0Y2JpQWdJQ0I5TzF4dWZUdGNibHh1THlvcVhHNGdLaUJTWlhGMVpYTjBjeUIwYUdVZ2JtRnRaWE1nYjJZZ2RHaGxJRzkzYm1Wa0lIQnliM0JsY25ScFpYTWdiMllnWVNCd2NtOXRhWE5sWkZ4dUlDb2diMkpxWldOMElHbHVJR0VnWm5WMGRYSmxJSFIxY200dVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHOWlhbVZqZEZ4dUlDb2dRSEpsZEhWeWJpQndjbTl0YVhObElHWnZjaUIwYUdVZ2EyVjVjeUJ2WmlCMGFHVWdaWFpsYm5SMVlXeHNlU0J6WlhSMGJHVmtJRzlpYW1WamRGeHVJQ292WEc1UkxtdGxlWE1nUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wS1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzVrYVhOd1lYUmphQ2hjSW10bGVYTmNJaXdnVzEwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWEyVjVjeUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWthWE53WVhSamFDaGNJbXRsZVhOY0lpd2dXMTBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJVZFhKdWN5QmhiaUJoY25KaGVTQnZaaUJ3Y205dGFYTmxjeUJwYm5SdklHRWdjSEp2YldselpTQm1iM0lnWVc0Z1lYSnlZWGt1SUNCSlppQmhibmtnYjJaY2JpQXFJSFJvWlNCd2NtOXRhWE5sY3lCblpYUnpJSEpsYW1WamRHVmtMQ0IwYUdVZ2QyaHZiR1VnWVhKeVlYa2dhWE1nY21WcVpXTjBaV1FnYVcxdFpXUnBZWFJsYkhrdVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNUtuMGdZVzRnWVhKeVlYa2dLRzl5SUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUtTQnZaaUIyWVd4MVpYTWdLRzl5WEc0Z0tpQndjbTl0YVhObGN5Qm1iM0lnZG1Gc2RXVnpLVnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUJoYmlCaGNuSmhlU0J2WmlCMGFHVWdZMjl5Y21WemNHOXVaR2x1WnlCMllXeDFaWE5jYmlBcUwxeHVMeThnUW5rZ1RXRnlheUJOYVd4c1pYSmNiaTh2SUdoMGRIQTZMeTkzYVd0cExtVmpiV0Z6WTNKcGNIUXViM0puTDJSdmEzVXVjR2h3UDJsa1BYTjBjbUYzYldGdU9tTnZibU4xY25KbGJtTjVKbkpsZGoweE16QTROemMyTlRJeEkyRnNiR1oxYkdacGJHeGxaRnh1VVM1aGJHd2dQU0JoYkd3N1hHNW1kVzVqZEdsdmJpQmhiR3dvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkMmhsYmlod2NtOXRhWE5sY3l3Z1puVnVZM1JwYjI0Z0tIQnliMjFwYzJWektTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCd1pXNWthVzVuUTI5MWJuUWdQU0F3TzF4dUlDQWdJQ0FnSUNCMllYSWdaR1ZtWlhKeVpXUWdQU0JrWldabGNpZ3BPMXh1SUNBZ0lDQWdJQ0JoY25KaGVWOXlaV1IxWTJVb2NISnZiV2x6WlhNc0lHWjFibU4wYVc5dUlDaDFibVJsWm1sdVpXUXNJSEJ5YjIxcGMyVXNJR2x1WkdWNEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllYSWdjMjVoY0hOb2IzUTdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9YRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhWE5RY205dGFYTmxLSEJ5YjIxcGMyVXBJQ1ltWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnS0hOdVlYQnphRzkwSUQwZ2NISnZiV2x6WlM1cGJuTndaV04wS0NrcExuTjBZWFJsSUQwOVBTQmNJbVoxYkdacGJHeGxaRndpWEc0Z0lDQWdJQ0FnSUNBZ0lDQXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205dGFYTmxjMXRwYm1SbGVGMGdQU0J6Ym1Gd2MyaHZkQzUyWVd4MVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnS3l0d1pXNWthVzVuUTI5MWJuUTdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkMmhsYmloY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTeGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnS0haaGJIVmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205dGFYTmxjMXRwYm1SbGVGMGdQU0IyWVd4MVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2d0TFhCbGJtUnBibWREYjNWdWRDQTlQVDBnTUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYzI5c2RtVW9jSEp2YldselpYTXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOUxGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WldwbFkzUXNYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUNod2NtOW5jbVZ6Y3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWJtOTBhV1o1S0hzZ2FXNWtaWGc2SUdsdVpHVjRMQ0IyWVd4MVpUb2djSEp2WjNKbGMzTWdmU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlMQ0IyYjJsa0lEQXBPMXh1SUNBZ0lDQWdJQ0JwWmlBb2NHVnVaR2x1WjBOdmRXNTBJRDA5UFNBd0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpYTnZiSFpsS0hCeWIyMXBjMlZ6S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JpQWdJQ0I5S1R0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1WVd4c0lEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQmhiR3dvZEdocGN5azdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ2RHaGxJR1pwY25OMElISmxjMjlzZG1Wa0lIQnliMjFwYzJVZ2IyWWdZVzRnWVhKeVlYa3VJRkJ5YVc5eUlISmxhbVZqZEdWa0lIQnliMjFwYzJWeklHRnlaVnh1SUNvZ2FXZHViM0psWkM0Z0lGSmxhbVZqZEhNZ2IyNXNlU0JwWmlCaGJHd2djSEp2YldselpYTWdZWEpsSUhKbGFtVmpkR1ZrTGx4dUlDb2dRSEJoY21GdElIdEJjbkpoZVNwOUlHRnVJR0Z5Y21GNUlHTnZiblJoYVc1cGJtY2dkbUZzZFdWeklHOXlJSEJ5YjIxcGMyVnpJR1p2Y2lCMllXeDFaWE5jYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1kV3htYVd4c1pXUWdkMmwwYUNCMGFHVWdkbUZzZFdVZ2IyWWdkR2hsSUdacGNuTjBJSEpsYzI5c2RtVmtJSEJ5YjIxcGMyVXNYRzRnS2lCdmNpQmhJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVWdhV1lnWVd4c0lIQnliMjFwYzJWeklHRnlaU0J5WldwbFkzUmxaQzVjYmlBcUwxeHVVUzVoYm5rZ1BTQmhibms3WEc1Y2JtWjFibU4wYVc5dUlHRnVlU2h3Y205dGFYTmxjeWtnZTF4dUlDQWdJR2xtSUNod2NtOXRhWE5sY3k1c1pXNW5kR2dnUFQwOUlEQXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRkV1Y21WemIyeDJaU2dwTzF4dUlDQWdJSDFjYmx4dUlDQWdJSFpoY2lCa1pXWmxjbkpsWkNBOUlGRXVaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdjR1Z1WkdsdVowTnZkVzUwSUQwZ01EdGNiaUFnSUNCaGNuSmhlVjl5WldSMVkyVW9jSEp2YldselpYTXNJR1oxYm1OMGFXOXVJQ2h3Y21WMkxDQmpkWEp5Wlc1MExDQnBibVJsZUNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnY0hKdmJXbHpaU0E5SUhCeWIyMXBjMlZ6VzJsdVpHVjRYVHRjYmx4dUlDQWdJQ0FnSUNCd1pXNWthVzVuUTI5MWJuUXJLenRjYmx4dUlDQWdJQ0FnSUNCM2FHVnVLSEJ5YjIxcGMyVXNJRzl1Um5Wc1ptbHNiR1ZrTENCdmJsSmxhbVZqZEdWa0xDQnZibEJ5YjJkeVpYTnpLVHRjYmlBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnYjI1R2RXeG1hV3hzWldRb2NtVnpkV3gwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WlhOdmJIWmxLSEpsYzNWc2RDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnYjI1U1pXcGxZM1JsWkNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhCbGJtUnBibWREYjNWdWRDMHRPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLSEJsYm1ScGJtZERiM1Z1ZENBOVBUMGdNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdSbFptVnljbVZrTG5KbGFtVmpkQ2h1WlhjZ1JYSnliM0lvWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lRMkZ1SjNRZ1oyVjBJR1oxYkdacGJHeHRaVzUwSUhaaGJIVmxJR1p5YjIwZ1lXNTVJSEJ5YjIxcGMyVXNJR0ZzYkNCY0lpQXJYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aWNISnZiV2x6WlhNZ2QyVnlaU0J5WldwbFkzUmxaQzVjSWx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNrcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlHOXVVSEp2WjNKbGMzTW9jSEp2WjNKbGMzTXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xtNXZkR2xtZVNoN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXNWtaWGc2SUdsdVpHVjRMRnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSFpoYkhWbE9pQndjbTluY21WemMxeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOUxDQjFibVJsWm1sdVpXUXBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1GdWVTQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdZVzU1S0hSb2FYTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlhZV2wwY3lCbWIzSWdZV3hzSUhCeWIyMXBjMlZ6SUhSdklHSmxJSE5sZEhSc1pXUXNJR1ZwZEdobGNpQm1kV3htYVd4c1pXUWdiM0pjYmlBcUlISmxhbVZqZEdWa0xpQWdWR2hwY3lCcGN5QmthWE4wYVc1amRDQm1jbTl0SUdCaGJHeGdJSE5wYm1ObElIUm9ZWFFnZDI5MWJHUWdjM1J2Y0Z4dUlDb2dkMkZwZEdsdVp5QmhkQ0IwYUdVZ1ptbHljM1FnY21WcVpXTjBhVzl1TGlBZ1ZHaGxJSEJ5YjIxcGMyVWdjbVYwZFhKdVpXUWdZbmxjYmlBcUlHQmhiR3hTWlhOdmJIWmxaR0FnZDJsc2JDQnVaWFpsY2lCaVpTQnlaV3BsWTNSbFpDNWNiaUFxSUVCd1lYSmhiU0J3Y205dGFYTmxjeUJoSUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUlDaHZjaUJoYmlCaGNuSmhlU2tnYjJZZ2NISnZiV2x6WlhOY2JpQXFJQ2h2Y2lCMllXeDFaWE1wWEc0Z0tpQkFjbVYwZFhKdUlHRWdjSEp2YldselpTQm1iM0lnWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhOY2JpQXFMMXh1VVM1aGJHeFNaWE52YkhabFpDQTlJR1JsY0hKbFkyRjBaU2hoYkd4U1pYTnZiSFpsWkN3Z1hDSmhiR3hTWlhOdmJIWmxaRndpTENCY0ltRnNiRk5sZEhSc1pXUmNJaWs3WEc1bWRXNWpkR2x2YmlCaGJHeFNaWE52YkhabFpDaHdjbTl0YVhObGN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCM2FHVnVLSEJ5YjIxcGMyVnpMQ0JtZFc1amRHbHZiaUFvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ2NISnZiV2x6WlhNZ1BTQmhjbkpoZVY5dFlYQW9jSEp2YldselpYTXNJRkVwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZDJobGJpaGhiR3dvWVhKeVlYbGZiV0Z3S0hCeWIyMXBjMlZ6TENCbWRXNWpkR2x2YmlBb2NISnZiV2x6WlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSGRvWlc0b2NISnZiV2x6WlN3Z2JtOXZjQ3dnYm05dmNDazdYRzRnSUNBZ0lDQWdJSDBwS1N3Z1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhCeWIyMXBjMlZ6TzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOUtUdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVlXeHNVbVZ6YjJ4MlpXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJR0ZzYkZKbGMyOXNkbVZrS0hSb2FYTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkFjMlZsSUZCeWIyMXBjMlVqWVd4c1UyVjBkR3hsWkZ4dUlDb3ZYRzVSTG1Gc2JGTmxkSFJzWldRZ1BTQmhiR3hUWlhSMGJHVmtPMXh1Wm5WdVkzUnBiMjRnWVd4c1UyVjBkR3hsWkNod2NtOXRhWE5sY3lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlZ6S1M1aGJHeFRaWFIwYkdWa0tDazdYRzU5WEc1Y2JpOHFLbHh1SUNvZ1ZIVnlibk1nWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhNZ2FXNTBieUJoSUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUlHOW1JSFJvWldseUlITjBZWFJsY3lBb1lYTmNiaUFxSUhKbGRIVnlibVZrSUdKNUlHQnBibk53WldOMFlDa2dkMmhsYmlCMGFHVjVJR2hoZG1VZ1lXeHNJSE5sZEhSc1pXUXVYRzRnS2lCQWNHRnlZVzBnZTBGeWNtRjVXMEZ1ZVNwZGZTQjJZV3gxWlhNZ1lXNGdZWEp5WVhrZ0tHOXlJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1S1NCdlppQjJZV3gxWlhNZ0tHOXlYRzRnS2lCd2NtOXRhWE5sY3lCbWIzSWdkbUZzZFdWektWeHVJQ29nUUhKbGRIVnlibk1nZTBGeWNtRjVXMU4wWVhSbFhYMGdZVzRnWVhKeVlYa2diMllnYzNSaGRHVnpJR1p2Y2lCMGFHVWdjbVZ6Y0dWamRHbDJaU0IyWVd4MVpYTXVYRzRnS2k5Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtRnNiRk5sZEhSc1pXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWRHaGxiaWhtZFc1amRHbHZiaUFvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdGc2JDaGhjbkpoZVY5dFlYQW9jSEp2YldselpYTXNJR1oxYm1OMGFXOXVJQ2h3Y205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQndjbTl0YVhObElEMGdVU2h3Y205dGFYTmxLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlISmxaMkZ5Wkd4bGMzTW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVXVhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVXVkR2hsYmloeVpXZGhjbVJzWlhOekxDQnlaV2RoY21Sc1pYTnpLVHRjYmlBZ0lDQWdJQ0FnZlNrcE8xeHVJQ0FnSUgwcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCRFlYQjBkWEpsY3lCMGFHVWdabUZwYkhWeVpTQnZaaUJoSUhCeWIyMXBjMlVzSUdkcGRtbHVaeUJoYmlCdmNHOXlkSFZ1YVhSNUlIUnZJSEpsWTI5MlpYSmNiaUFxSUhkcGRHZ2dZU0JqWVd4c1ltRmpheTRnSUVsbUlIUm9aU0JuYVhabGJpQndjbTl0YVhObElHbHpJR1oxYkdacGJHeGxaQ3dnZEdobElISmxkSFZ5Ym1Wa1hHNGdLaUJ3Y205dGFYTmxJR2x6SUdaMWJHWnBiR3hsWkM1Y2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ2NISnZiV2x6WlNCbWIzSWdjMjl0WlhSb2FXNW5YRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCallXeHNZbUZqYXlCMGJ5Qm1kV3htYVd4c0lIUm9aU0J5WlhSMWNtNWxaQ0J3Y205dGFYTmxJR2xtSUhSb1pWeHVJQ29nWjJsMlpXNGdjSEp2YldselpTQnBjeUJ5WldwbFkzUmxaRnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJRzltSUhSb1pTQmpZV3hzWW1GamExeHVJQ292WEc1UkxtWmhhV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVSVzF3aVkyRjBZMmhjSWwwZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQnlaV3BsWTNSbFpDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdWRHaGxiaWgyYjJsa0lEQXNJSEpsYW1WamRHVmtLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVpoYVd3Z1BTQXZMeUJZV0ZnZ2JHVm5ZV041WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlZ0Y0ltTmhkR05vWENKZElEMGdablZ1WTNScGIyNGdLSEpsYW1WamRHVmtLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaDJiMmxrSURBc0lISmxhbVZqZEdWa0tUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1FYUjBZV05vWlhNZ1lTQnNhWE4wWlc1bGNpQjBhR0YwSUdOaGJpQnlaWE53YjI1a0lIUnZJSEJ5YjJkeVpYTnpJRzV2ZEdsbWFXTmhkR2x2Ym5NZ1puSnZiU0JoWEc0Z0tpQndjbTl0YVhObEozTWdiM0pwWjJsdVlYUnBibWNnWkdWbVpYSnlaV1F1SUZSb2FYTWdiR2x6ZEdWdVpYSWdjbVZqWldsMlpYTWdkR2hsSUdWNFlXTjBJR0Z5WjNWdFpXNTBjMXh1SUNvZ2NHRnpjMlZrSUhSdklHQmdaR1ZtWlhKeVpXUXVibTkwYVdaNVlHQXVYRzRnS2lCQWNHRnlZVzBnZTBGdWVTcDlJSEJ5YjIxcGMyVWdabTl5SUhOdmJXVjBhR2x1WjF4dUlDb2dRSEJoY21GdElIdEdkVzVqZEdsdmJuMGdZMkZzYkdKaFkyc2dkRzhnY21WalpXbDJaU0JoYm5rZ2NISnZaM0psYzNNZ2JtOTBhV1pwWTJGMGFXOXVjMXh1SUNvZ1FISmxkSFZ5Ym5NZ2RHaGxJR2RwZG1WdUlIQnliMjFwYzJVc0lIVnVZMmhoYm1kbFpGeHVJQ292WEc1UkxuQnliMmR5WlhOeklEMGdjSEp2WjNKbGMzTTdYRzVtZFc1amRHbHZiaUJ3Y205bmNtVnpjeWh2WW1wbFkzUXNJSEJ5YjJkeVpYTnpaV1FwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMblJvWlc0b2RtOXBaQ0F3TENCMmIybGtJREFzSUhCeWIyZHlaWE56WldRcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1d2NtOW5jbVZ6Y3lBOUlHWjFibU4wYVc5dUlDaHdjbTluY21WemMyVmtLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaDJiMmxrSURBc0lIWnZhV1FnTUN3Z2NISnZaM0psYzNObFpDazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGQnliM1pwWkdWeklHRnVJRzl3Y0c5eWRIVnVhWFI1SUhSdklHOWljMlZ5ZG1VZ2RHaGxJSE5sZEhSc2FXNW5JRzltSUdFZ2NISnZiV2x6WlN4Y2JpQXFJSEpsWjJGeVpHeGxjM01nYjJZZ2QyaGxkR2hsY2lCMGFHVWdjSEp2YldselpTQnBjeUJtZFd4bWFXeHNaV1FnYjNJZ2NtVnFaV04wWldRdUlDQkdiM0ozWVhKa2MxeHVJQ29nZEdobElISmxjMjlzZFhScGIyNGdkRzhnZEdobElISmxkSFZ5Ym1Wa0lIQnliMjFwYzJVZ2QyaGxiaUIwYUdVZ1kyRnNiR0poWTJzZ2FYTWdaRzl1WlM1Y2JpQXFJRlJvWlNCallXeHNZbUZqYXlCallXNGdjbVYwZFhKdUlHRWdjSEp2YldselpTQjBieUJrWldabGNpQmpiMjF3YkdWMGFXOXVMbHh1SUNvZ1FIQmhjbUZ0SUh0QmJua3FmU0J3Y205dGFYTmxYRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCallXeHNZbUZqYXlCMGJ5QnZZbk5sY25abElIUm9aU0J5WlhOdmJIVjBhVzl1SUc5bUlIUm9aU0JuYVhabGJseHVJQ29nY0hKdmJXbHpaU3dnZEdGclpYTWdibThnWVhKbmRXMWxiblJ6TGx4dUlDb2dRSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6YjJ4MWRHbHZiaUJ2WmlCMGFHVWdaMmwyWlc0Z2NISnZiV2x6WlNCM2FHVnVYRzRnS2lCZ1lHWnBibUJnSUdseklHUnZibVV1WEc0Z0tpOWNibEV1Wm1sdUlEMGdMeThnV0ZoWUlHeGxaMkZqZVZ4dVVWdGNJbVpwYm1Gc2JIbGNJbDBnUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wTENCallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2xiWENKbWFXNWhiR3g1WENKZEtHTmhiR3hpWVdOcktUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtWnBiaUE5SUM4dklGaFlXQ0JzWldkaFkzbGNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxXMXdpWm1sdVlXeHNlVndpWFNBOUlHWjFibU4wYVc5dUlDaGpZV3hzWW1GamF5a2dlMXh1SUNBZ0lHTmhiR3hpWVdOcklEMGdVU2hqWVd4c1ltRmpheWs3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtWmpZV3hzS0NrdWRHaGxiaWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdVN1hHNGdJQ0FnSUNBZ0lIMHBPMXh1SUNBZ0lIMHNJR1oxYm1OMGFXOXVJQ2h5WldGemIyNHBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z1ZFOUVUeUJoZEhSbGJYQjBJSFJ2SUhKbFkzbGpiR1VnZEdobElISmxhbVZqZEdsdmJpQjNhWFJvSUZ3aWRHaHBjMXdpTGx4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWTJGc2JHSmhZMnN1Wm1OaGJHd29LUzUwYUdWdUtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUhKbFlYTnZianRjYmlBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZSbGNtMXBibUYwWlhNZ1lTQmphR0ZwYmlCdlppQndjbTl0YVhObGN5d2dabTl5WTJsdVp5QnlaV3BsWTNScGIyNXpJSFJ2SUdKbFhHNGdLaUIwYUhKdmQyNGdZWE1nWlhoalpYQjBhVzl1Y3k1Y2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ2NISnZiV2x6WlNCaGRDQjBhR1VnWlc1a0lHOW1JR0VnWTJoaGFXNGdiMllnY0hKdmJXbHpaWE5jYmlBcUlFQnlaWFIxY201eklHNXZkR2hwYm1kY2JpQXFMMXh1VVM1a2IyNWxJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkN3Z2NISnZaM0psYzNNcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1SdmJtVW9ablZzWm1sc2JHVmtMQ0J5WldwbFkzUmxaQ3dnY0hKdlozSmxjM01wTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1Wkc5dVpTQTlJR1oxYm1OMGFXOXVJQ2htZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrTENCd2NtOW5jbVZ6Y3lrZ2UxeHVJQ0FnSUhaaGNpQnZibFZ1YUdGdVpHeGxaRVZ5Y205eUlEMGdablZ1WTNScGIyNGdLR1Z5Y205eUtTQjdYRzRnSUNBZ0lDQWdJQzh2SUdadmNuZGhjbVFnZEc4Z1lTQm1kWFIxY21VZ2RIVnliaUJ6YnlCMGFHRjBJR0JnZDJobGJtQmdYRzRnSUNBZ0lDQWdJQzh2SUdSdlpYTWdibTkwSUdOaGRHTm9JR2wwSUdGdVpDQjBkWEp1SUdsMElHbHVkRzhnWVNCeVpXcGxZM1JwYjI0dVhHNGdJQ0FnSUNBZ0lGRXVibVY0ZEZScFkyc29ablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdiV0ZyWlZOMFlXTnJWSEpoWTJWTWIyNW5LR1Z5Y205eUxDQndjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaFJMbTl1WlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JSTG05dVpYSnliM0lvWlhKeWIzSXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsY25KdmNqdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZTazdYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lDOHZJRUYyYjJsa0lIVnVibVZqWlhOellYSjVJR0J1WlhoMFZHbGphMkJwYm1jZ2RtbGhJR0Z1SUhWdWJtVmpaWE56WVhKNUlHQjNhR1Z1WUM1Y2JpQWdJQ0IyWVhJZ2NISnZiV2x6WlNBOUlHWjFiR1pwYkd4bFpDQjhmQ0J5WldwbFkzUmxaQ0I4ZkNCd2NtOW5jbVZ6Y3lBL1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdobGJpaG1kV3htYVd4c1pXUXNJSEpsYW1WamRHVmtMQ0J3Y205bmNtVnpjeWtnT2x4dUlDQWdJQ0FnSUNCMGFHbHpPMXh1WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJ3Y205alpYTnpJRDA5UFNCY0ltOWlhbVZqZEZ3aUlDWW1JSEJ5YjJObGMzTWdKaVlnY0hKdlkyVnpjeTVrYjIxaGFXNHBJSHRjYmlBZ0lDQWdJQ0FnYjI1VmJtaGhibVJzWldSRmNuSnZjaUE5SUhCeWIyTmxjM011Wkc5dFlXbHVMbUpwYm1Rb2IyNVZibWhoYm1Sc1pXUkZjbkp2Y2lrN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnY0hKdmJXbHpaUzUwYUdWdUtIWnZhV1FnTUN3Z2IyNVZibWhoYm1Sc1pXUkZjbkp2Y2lrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVOaGRYTmxjeUJoSUhCeWIyMXBjMlVnZEc4Z1ltVWdjbVZxWldOMFpXUWdhV1lnYVhRZ1pHOWxjeUJ1YjNRZ1oyVjBJR1oxYkdacGJHeGxaQ0JpWldadmNtVmNiaUFxSUhOdmJXVWdiV2xzYkdselpXTnZibVJ6SUhScGJXVWdiM1YwTGx4dUlDb2dRSEJoY21GdElIdEJibmtxZlNCd2NtOXRhWE5sWEc0Z0tpQkFjR0Z5WVcwZ2UwNTFiV0psY24wZ2JXbHNiR2x6WldOdmJtUnpJSFJwYldWdmRYUmNiaUFxSUVCd1lYSmhiU0I3UVc1NUtuMGdZM1Z6ZEc5dElHVnljbTl5SUcxbGMzTmhaMlVnYjNJZ1JYSnliM0lnYjJKcVpXTjBJQ2h2Y0hScGIyNWhiQ2xjYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1iM0lnZEdobElISmxjMjlzZFhScGIyNGdiMllnZEdobElHZHBkbVZ1SUhCeWIyMXBjMlVnYVdZZ2FYUWdhWE5jYmlBcUlHWjFiR1pwYkd4bFpDQmlaV1p2Y21VZ2RHaGxJSFJwYldWdmRYUXNJRzkwYUdWeWQybHpaU0J5WldwbFkzUmxaQzVjYmlBcUwxeHVVUzUwYVcxbGIzVjBJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnYlhNc0lHVnljbTl5S1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzUwYVcxbGIzVjBLRzF6TENCbGNuSnZjaWs3WEc1OU8xeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzUwYVcxbGIzVjBJRDBnWm5WdVkzUnBiMjRnS0cxekxDQmxjbkp2Y2lrZ2UxeHVJQ0FnSUhaaGNpQmtaV1psY25KbFpDQTlJR1JsWm1WeUtDazdYRzRnSUNBZ2RtRnlJSFJwYldWdmRYUkpaQ0E5SUhObGRGUnBiV1Z2ZFhRb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb0lXVnljbTl5SUh4OElGd2ljM1J5YVc1blhDSWdQVDA5SUhSNWNHVnZaaUJsY25KdmNpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pYSnliM0lnUFNCdVpYY2dSWEp5YjNJb1pYSnliM0lnZkh3Z1hDSlVhVzFsWkNCdmRYUWdZV1owWlhJZ1hDSWdLeUJ0Y3lBcklGd2lJRzF6WENJcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnWlhKeWIzSXVZMjlrWlNBOUlGd2lSVlJKVFVWRVQxVlVYQ0k3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWNtVnFaV04wS0dWeWNtOXlLVHRjYmlBZ0lDQjlMQ0J0Y3lrN1hHNWNiaUFnSUNCMGFHbHpMblJvWlc0b1puVnVZM1JwYjI0Z0tIWmhiSFZsS1NCN1hHNGdJQ0FnSUNBZ0lHTnNaV0Z5VkdsdFpXOTFkQ2gwYVcxbGIzVjBTV1FwTzF4dUlDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpYTnZiSFpsS0haaGJIVmxLVHRjYmlBZ0lDQjlMQ0JtZFc1amRHbHZiaUFvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lHTnNaV0Z5VkdsdFpXOTFkQ2gwYVcxbGIzVjBTV1FwTzF4dUlDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0I5TENCa1pXWmxjbkpsWkM1dWIzUnBabmtwTzF4dVhHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ1oybDJaVzRnZG1Gc2RXVWdLRzl5SUhCeWIyMXBjMlZrSUhaaGJIVmxLU3dnYzI5dFpWeHVJQ29nYldsc2JHbHpaV052Ym1SeklHRm1kR1Z5SUdsMElISmxjMjlzZG1Wa0xpQlFZWE56WlhNZ2NtVnFaV04wYVc5dWN5QnBiVzFsWkdsaGRHVnNlUzVjYmlBcUlFQndZWEpoYlNCN1FXNTVLbjBnY0hKdmJXbHpaVnh1SUNvZ1FIQmhjbUZ0SUh0T2RXMWlaWEo5SUcxcGJHeHBjMlZqYjI1a2MxeHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WemIyeDFkR2x2YmlCdlppQjBhR1VnWjJsMlpXNGdjSEp2YldselpTQmhablJsY2lCdGFXeHNhWE5sWTI5dVpITmNiaUFxSUhScGJXVWdhR0Z6SUdWc1lYQnpaV1FnYzJsdVkyVWdkR2hsSUhKbGMyOXNkWFJwYjI0Z2IyWWdkR2hsSUdkcGRtVnVJSEJ5YjIxcGMyVXVYRzRnS2lCSlppQjBhR1VnWjJsMlpXNGdjSEp2YldselpTQnlaV3BsWTNSekxDQjBhR0YwSUdseklIQmhjM05sWkNCcGJXMWxaR2xoZEdWc2VTNWNiaUFxTDF4dVVTNWtaV3hoZVNBOUlHWjFibU4wYVc5dUlDaHZZbXBsWTNRc0lIUnBiV1Z2ZFhRcElIdGNiaUFnSUNCcFppQW9kR2x0Wlc5MWRDQTlQVDBnZG05cFpDQXdLU0I3WEc0Z0lDQWdJQ0FnSUhScGJXVnZkWFFnUFNCdlltcGxZM1E3WEc0Z0lDQWdJQ0FnSUc5aWFtVmpkQ0E5SUhadmFXUWdNRHRjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a1pXeGhlU2gwYVcxbGIzVjBLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVJsYkdGNUlEMGdablZ1WTNScGIyNGdLSFJwYldWdmRYUXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTUwYUdWdUtHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJQ0FnSUNCelpYUlVhVzFsYjNWMEtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vb2RtRnNkV1VwTzF4dUlDQWdJQ0FnSUNCOUxDQjBhVzFsYjNWMEtUdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZCaGMzTmxjeUJoSUdOdmJuUnBiblZoZEdsdmJpQjBieUJoSUU1dlpHVWdablZ1WTNScGIyNHNJSGRvYVdOb0lHbHpJR05oYkd4bFpDQjNhWFJvSUhSb1pTQm5hWFpsYmx4dUlDb2dZWEpuZFcxbGJuUnpJSEJ5YjNacFpHVmtJR0Z6SUdGdUlHRnljbUY1TENCaGJtUWdjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dJQ0FnSUNCUkxtNW1ZWEJ3Ykhrb1JsTXVjbVZoWkVacGJHVXNJRnRmWDJacGJHVnVZVzFsWFNsY2JpQXFJQ0FnSUNBZ0xuUm9aVzRvWm5WdVkzUnBiMjRnS0dOdmJuUmxiblFwSUh0Y2JpQXFJQ0FnSUNBZ2ZTbGNiaUFxWEc0Z0tpOWNibEV1Ym1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoallXeHNZbUZqYXl3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLR05oYkd4aVlXTnJLUzV1Wm1Gd2NHeDVLR0Z5WjNNcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtWmhjSEJzZVNBOUlHWjFibU4wYVc5dUlDaGhjbWR6S1NCN1hHNGdJQ0FnZG1GeUlHUmxabVZ5Y21Wa0lEMGdaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdibTlrWlVGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZHpLVHRjYmlBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnZEdocGN5NW1ZWEJ3Ykhrb2JtOWtaVUZ5WjNNcExtWmhhV3dvWkdWbVpYSnlaV1F1Y21WcVpXTjBLVHRjYmlBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JuMDdYRzVjYmk4cUtseHVJQ29nVUdGemMyVnpJR0VnWTI5dWRHbHVkV0YwYVc5dUlIUnZJR0VnVG05a1pTQm1kVzVqZEdsdmJpd2dkMmhwWTJnZ2FYTWdZMkZzYkdWa0lIZHBkR2dnZEdobElHZHBkbVZ1WEc0Z0tpQmhjbWQxYldWdWRITWdjSEp2ZG1sa1pXUWdhVzVrYVhacFpIVmhiR3g1TENCaGJtUWdjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2lCQVpYaGhiWEJzWlZ4dUlDb2dVUzV1Wm1OaGJHd29SbE11Y21WaFpFWnBiR1VzSUY5ZlptbHNaVzVoYldVcFhHNGdLaUF1ZEdobGJpaG1kVzVqZEdsdmJpQW9ZMjl1ZEdWdWRDa2dlMXh1SUNvZ2ZTbGNiaUFxWEc0Z0tpOWNibEV1Ym1aallXeHNJRDBnWm5WdVkzUnBiMjRnS0dOaGJHeGlZV05ySUM4cUxpNHVZWEpuY3lvdktTQjdYRzRnSUNBZ2RtRnlJR0Z5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kMWJXVnVkSE1zSURFcE8xeHVJQ0FnSUhKbGRIVnliaUJSS0dOaGJHeGlZV05yS1M1dVptRndjR3g1S0dGeVozTXBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibVpqWVd4c0lEMGdablZ1WTNScGIyNGdLQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlHNXZaR1ZCY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUc1dlpHVkJjbWR6TG5CMWMyZ29aR1ZtWlhKeVpXUXViV0ZyWlU1dlpHVlNaWE52YkhabGNpZ3BLVHRjYmlBZ0lDQjBhR2x6TG1aaGNIQnNlU2h1YjJSbFFYSm5jeWt1Wm1GcGJDaGtaV1psY25KbFpDNXlaV3BsWTNRcE8xeHVJQ0FnSUhKbGRIVnliaUJrWldabGNuSmxaQzV3Y205dGFYTmxPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlhjbUZ3Y3lCaElFNXZaR1ZLVXlCamIyNTBhVzUxWVhScGIyNGdjR0Z6YzJsdVp5Qm1kVzVqZEdsdmJpQmhibVFnY21WMGRYSnVjeUJoYmlCbGNYVnBkbUZzWlc1MFhHNGdLaUIyWlhKemFXOXVJSFJvWVhRZ2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVdVhHNGdLaUJBWlhoaGJYQnNaVnh1SUNvZ1VTNXVabUpwYm1Rb1JsTXVjbVZoWkVacGJHVXNJRjlmWm1sc1pXNWhiV1VwS0Z3aWRYUm1MVGhjSWlsY2JpQXFJQzUwYUdWdUtHTnZibk52YkdVdWJHOW5LVnh1SUNvZ0xtUnZibVVvS1Z4dUlDb3ZYRzVSTG01bVltbHVaQ0E5WEc1UkxtUmxibTlrWldsbWVTQTlJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheUF2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmlZWE5sUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01TazdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1ltRnpaVUZ5WjNNdVkyOXVZMkYwS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5a3BPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnSUNBZ0lGRW9ZMkZzYkdKaFkyc3BMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibVppYVc1a0lEMWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVJsYm05a1pXbG1lU0E5SUdaMWJtTjBhVzl1SUNndktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0JoY21kekxuVnVjMmhwWm5Rb2RHaHBjeWs3WEc0Z0lDQWdjbVYwZFhKdUlGRXVaR1Z1YjJSbGFXWjVMbUZ3Y0d4NUtIWnZhV1FnTUN3Z1lYSm5jeWs3WEc1OU8xeHVYRzVSTG01aWFXNWtJRDBnWm5WdVkzUnBiMjRnS0dOaGJHeGlZV05yTENCMGFHbHpjQ0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmlZWE5sUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01pazdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1ltRnpaVUZ5WjNNdVkyOXVZMkYwS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5a3BPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlHSnZkVzVrS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtIUm9hWE53TENCaGNtZDFiV1Z1ZEhNcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJRkVvWW05MWJtUXBMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibUpwYm1RZ1BTQm1kVzVqZEdsdmJpQW9MeXAwYUdsemNDd2dMaTR1WVhKbmN5b3ZLU0I3WEc0Z0lDQWdkbUZ5SUdGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNc0lEQXBPMXh1SUNBZ0lHRnlaM011ZFc1emFHbG1kQ2gwYUdsektUdGNiaUFnSUNCeVpYUjFjbTRnVVM1dVltbHVaQzVoY0hCc2VTaDJiMmxrSURBc0lHRnlaM01wTzF4dWZUdGNibHh1THlvcVhHNGdLaUJEWVd4c2N5QmhJRzFsZEdodlpDQnZaaUJoSUU1dlpHVXRjM1I1YkdVZ2IySnFaV04wSUhSb1lYUWdZV05qWlhCMGN5QmhJRTV2WkdVdGMzUjViR1ZjYmlBcUlHTmhiR3hpWVdOcklIZHBkR2dnWVNCbmFYWmxiaUJoY25KaGVTQnZaaUJoY21kMWJXVnVkSE1zSUhCc2RYTWdZU0J3Y205MmFXUmxaQ0JqWVd4c1ltRmpheTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVc0Z2IySnFaV04wSUhSb1lYUWdhR0Z6SUhSb1pTQnVZVzFsWkNCdFpYUm9iMlJjYmlBcUlFQndZWEpoYlNCN1UzUnlhVzVuZlNCdVlXMWxJRzVoYldVZ2IyWWdkR2hsSUcxbGRHaHZaQ0J2WmlCdlltcGxZM1JjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUdGeVozTWdZWEpuZFcxbGJuUnpJSFJ2SUhCaGMzTWdkRzhnZEdobElHMWxkR2h2WkRzZ2RHaGxJR05oYkd4aVlXTnJYRzRnS2lCM2FXeHNJR0psSUhCeWIzWnBaR1ZrSUdKNUlGRWdZVzVrSUdGd2NHVnVaR1ZrSUhSdklIUm9aWE5sSUdGeVozVnRaVzUwY3k1Y2JpQXFJRUJ5WlhSMWNtNXpJR0VnY0hKdmJXbHpaU0JtYjNJZ2RHaGxJSFpoYkhWbElHOXlJR1Z5Y205eVhHNGdLaTljYmxFdWJtMWhjSEJzZVNBOUlDOHZJRmhZV0NCQmN5QndjbTl3YjNObFpDQmllU0JjSWxKbFpITmhibVJ5YjF3aVhHNVJMbTV3YjNOMElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dibUZ0WlN3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VibkJ2YzNRb2JtRnRaU3dnWVhKbmN5azdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbTV3YjNOMElEMGdablZ1WTNScGIyNGdLRzVoYldVc0lHRnlaM01wSUh0Y2JpQWdJQ0IyWVhJZ2JtOWtaVUZ5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21keklIeDhJRnRkS1R0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUc1dlpHVkJjbWR6TG5CMWMyZ29aR1ZtWlhKeVpXUXViV0ZyWlU1dlpHVlNaWE52YkhabGNpZ3BLVHRjYmlBZ0lDQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnYm05a1pVRnlaM05kS1M1bVlXbHNLR1JsWm1WeWNtVmtMbkpsYW1WamRDazdYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oYkd4eklHRWdiV1YwYUc5a0lHOW1JR0VnVG05a1pTMXpkSGxzWlNCdlltcGxZM1FnZEdoaGRDQmhZMk5sY0hSeklHRWdUbTlrWlMxemRIbHNaVnh1SUNvZ1kyRnNiR0poWTJzc0lHWnZjbmRoY21ScGJtY2dkR2hsSUdkcGRtVnVJSFpoY21saFpHbGpJR0Z5WjNWdFpXNTBjeXdnY0d4MWN5QmhJSEJ5YjNacFpHVmtYRzRnS2lCallXeHNZbUZqYXlCaGNtZDFiV1Z1ZEM1Y2JpQXFJRUJ3WVhKaGJTQnZZbXBsWTNRZ1lXNGdiMkpxWldOMElIUm9ZWFFnYUdGeklIUm9aU0J1WVcxbFpDQnRaWFJvYjJSY2JpQXFJRUJ3WVhKaGJTQjdVM1J5YVc1bmZTQnVZVzFsSUc1aGJXVWdiMllnZEdobElHMWxkR2h2WkNCdlppQnZZbXBsWTNSY2JpQXFJRUJ3WVhKaGJTQXVMaTVoY21keklHRnlaM1Z0Wlc1MGN5QjBieUJ3WVhOeklIUnZJSFJvWlNCdFpYUm9iMlE3SUhSb1pTQmpZV3hzWW1GamF5QjNhV3hzWEc0Z0tpQmlaU0J3Y205MmFXUmxaQ0JpZVNCUklHRnVaQ0JoY0hCbGJtUmxaQ0IwYnlCMGFHVnpaU0JoY21kMWJXVnVkSE11WEc0Z0tpQkFjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQjJZV3gxWlNCdmNpQmxjbkp2Y2x4dUlDb3ZYRzVSTG01elpXNWtJRDBnTHk4Z1dGaFlJRUpoYzJWa0lHOXVJRTFoY21zZ1RXbHNiR1Z5SjNNZ2NISnZjRzl6WldRZ1hDSnpaVzVrWENKY2JsRXVibTFqWVd4c0lEMGdMeThnV0ZoWUlFSmhjMlZrSUc5dUlGd2lVbVZrYzJGdVpISnZKM05jSWlCd2NtOXdiM05oYkZ4dVVTNXVhVzUyYjJ0bElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dibUZ0WlNBdktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lIWmhjaUJ1YjJSbFFYSm5jeUE5SUdGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5d2dNaWs3WEc0Z0lDQWdkbUZ5SUdSbFptVnljbVZrSUQwZ1pHVm1aWElvS1R0Y2JpQWdJQ0J1YjJSbFFYSm5jeTV3ZFhOb0tHUmxabVZ5Y21Wa0xtMWhhMlZPYjJSbFVtVnpiMngyWlhJb0tTazdYRzRnSUNBZ1VTaHZZbXBsWTNRcExtUnBjM0JoZEdOb0tGd2ljRzl6ZEZ3aUxDQmJibUZ0WlN3Z2JtOWtaVUZ5WjNOZEtTNW1ZV2xzS0dSbFptVnljbVZrTG5KbGFtVmpkQ2s3WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWMyVnVaQ0E5SUM4dklGaFlXQ0JDWVhObFpDQnZiaUJOWVhKcklFMXBiR3hsY2lkeklIQnliM0J2YzJWa0lGd2ljMlZ1WkZ3aVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViV05oYkd3Z1BTQXZMeUJZV0ZnZ1FtRnpaV1FnYjI0Z1hDSlNaV1J6WVc1a2NtOG5jMXdpSUhCeWIzQnZjMkZzWEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWFXNTJiMnRsSUQwZ1puVnVZM1JwYjI0Z0tHNWhiV1VnTHlvdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCMllYSWdibTlrWlVGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNc0lERXBPMXh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUdSbFptVnlLQ2s3WEc0Z0lDQWdibTlrWlVGeVozTXVjSFZ6YUNoa1pXWmxjbkpsWkM1dFlXdGxUbTlrWlZKbGMyOXNkbVZ5S0NrcE8xeHVJQ0FnSUhSb2FYTXVaR2x6Y0dGMFkyZ29YQ0p3YjNOMFhDSXNJRnR1WVcxbExDQnViMlJsUVhKbmMxMHBMbVpoYVd3b1pHVm1aWEp5WldRdWNtVnFaV04wS1R0Y2JpQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1NXWWdZU0JtZFc1amRHbHZiaUIzYjNWc1pDQnNhV3RsSUhSdklITjFjSEJ2Y25RZ1ltOTBhQ0JPYjJSbElHTnZiblJwYm5WaGRHbHZiaTF3WVhOemFXNW5MWE4wZVd4bElHRnVaRnh1SUNvZ2NISnZiV2x6WlMxeVpYUjFjbTVwYm1jdGMzUjViR1VzSUdsMElHTmhiaUJsYm1RZ2FYUnpJR2x1ZEdWeWJtRnNJSEJ5YjIxcGMyVWdZMmhoYVc0Z2QybDBhRnh1SUNvZ1lHNXZaR1ZwWm5rb2JtOWtaV0poWTJzcFlDd2dabTl5ZDJGeVpHbHVaeUIwYUdVZ2IzQjBhVzl1WVd3Z2JtOWtaV0poWTJzZ1lYSm5kVzFsYm5RdUlDQkpaaUIwYUdVZ2RYTmxjbHh1SUNvZ1pXeGxZM1J6SUhSdklIVnpaU0JoSUc1dlpHVmlZV05yTENCMGFHVWdjbVZ6ZFd4MElIZHBiR3dnWW1VZ2MyVnVkQ0IwYUdWeVpTNGdJRWxtSUhSb1pYa2daRzhnYm05MFhHNGdLaUJ3WVhOeklHRWdibTlrWldKaFkyc3NJSFJvWlhrZ2QybHNiQ0J5WldObGFYWmxJSFJvWlNCeVpYTjFiSFFnY0hKdmJXbHpaUzVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVNCeVpYTjFiSFFnS0c5eUlHRWdjSEp2YldselpTQm1iM0lnWVNCeVpYTjFiSFFwWEc0Z0tpQkFjR0Z5WVcwZ2UwWjFibU4wYVc5dWZTQnViMlJsWW1GamF5QmhJRTV2WkdVdWFuTXRjM1I1YkdVZ1kyRnNiR0poWTJ0Y2JpQXFJRUJ5WlhSMWNtNXpJR1ZwZEdobGNpQjBhR1VnY0hKdmJXbHpaU0J2Y2lCdWIzUm9hVzVuWEc0Z0tpOWNibEV1Ym05a1pXbG1lU0E5SUc1dlpHVnBabms3WEc1bWRXNWpkR2x2YmlCdWIyUmxhV1o1S0c5aWFtVmpkQ3dnYm05a1pXSmhZMnNwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbTV2WkdWcFpua29ibTlrWldKaFkyc3BPMXh1ZlZ4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViMlJsYVdaNUlEMGdablZ1WTNScGIyNGdLRzV2WkdWaVlXTnJLU0I3WEc0Z0lDQWdhV1lnS0c1dlpHVmlZV05yS1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzV2WkdWaVlXTnJLRzUxYkd3c0lIWmhiSFZsS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDBwTzF4dUlDQWdJQ0FnSUNCOUxDQm1kVzVqZEdsdmJpQW9aWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzV2WkdWaVlXTnJLR1Z5Y205eUtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgwcE8xeHVJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2RHaHBjenRjYmlBZ0lDQjlYRzU5TzF4dVhHNVJMbTV2UTI5dVpteHBZM1FnUFNCbWRXNWpkR2x2YmlncElIdGNiaUFnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvWENKUkxtNXZRMjl1Wm14cFkzUWdiMjVzZVNCM2IzSnJjeUIzYUdWdUlGRWdhWE1nZFhObFpDQmhjeUJoSUdkc2IySmhiRndpS1R0Y2JuMDdYRzVjYmk4dklFRnNiQ0JqYjJSbElHSmxabTl5WlNCMGFHbHpJSEJ2YVc1MElIZHBiR3dnWW1VZ1ptbHNkR1Z5WldRZ1puSnZiU0J6ZEdGamF5QjBjbUZqWlhNdVhHNTJZWElnY1VWdVpHbHVaMHhwYm1VZ1BTQmpZWEIwZFhKbFRHbHVaU2dwTzF4dVhHNXlaWFIxY200Z1VUdGNibHh1ZlNrN1hHNGlYWDA9IiwiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnZW1pdHRlcicpO1xudmFyIHJlZHVjZSA9IHJlcXVpcmUoJ3JlZHVjZScpO1xudmFyIHJlcXVlc3RCYXNlID0gcmVxdWlyZSgnLi9yZXF1ZXN0LWJhc2UnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXMtb2JqZWN0Jyk7XG5cbi8qKlxuICogUm9vdCByZWZlcmVuY2UgZm9yIGlmcmFtZXMuXG4gKi9cblxudmFyIHJvb3Q7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsgLy8gQnJvd3NlciB3aW5kb3dcbiAgcm9vdCA9IHdpbmRvdztcbn0gZWxzZSBpZiAodHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnKSB7IC8vIFdlYiBXb3JrZXJcbiAgcm9vdCA9IHNlbGY7XG59IGVsc2UgeyAvLyBPdGhlciBlbnZpcm9ubWVudHNcbiAgcm9vdCA9IHRoaXM7XG59XG5cbi8qKlxuICogTm9vcC5cbiAqL1xuXG5mdW5jdGlvbiBub29wKCl7fTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIGhvc3Qgb2JqZWN0LFxuICogd2UgZG9uJ3Qgd2FudCB0byBzZXJpYWxpemUgdGhlc2UgOilcbiAqXG4gKiBUT0RPOiBmdXR1cmUgcHJvb2YsIG1vdmUgdG8gY29tcG9lbnQgbGFuZFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0hvc3Qob2JqKSB7XG4gIHZhciBzdHIgPSB7fS50b1N0cmluZy5jYWxsKG9iaik7XG5cbiAgc3dpdGNoIChzdHIpIHtcbiAgICBjYXNlICdbb2JqZWN0IEZpbGVdJzpcbiAgICBjYXNlICdbb2JqZWN0IEJsb2JdJzpcbiAgICBjYXNlICdbb2JqZWN0IEZvcm1EYXRhXSc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogRXhwb3NlIGByZXF1ZXN0YC5cbiAqL1xuXG52YXIgcmVxdWVzdCA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9yZXF1ZXN0JykuYmluZChudWxsLCBSZXF1ZXN0KTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgWEhSLlxuICovXG5cbnJlcXVlc3QuZ2V0WEhSID0gZnVuY3Rpb24gKCkge1xuICBpZiAocm9vdC5YTUxIdHRwUmVxdWVzdFxuICAgICAgJiYgKCFyb290LmxvY2F0aW9uIHx8ICdmaWxlOicgIT0gcm9vdC5sb2NhdGlvbi5wcm90b2NvbFxuICAgICAgICAgIHx8ICFyb290LkFjdGl2ZVhPYmplY3QpKSB7XG4gICAgcmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdDtcbiAgfSBlbHNlIHtcbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01pY3Jvc29mdC5YTUxIVFRQJyk7IH0gY2F0Y2goZSkge31cbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQLjYuMCcpOyB9IGNhdGNoKGUpIHt9XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUC4zLjAnKTsgfSBjYXRjaChlKSB7fVxuICAgIHRyeSB7IHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTXN4bWwyLlhNTEhUVFAnKTsgfSBjYXRjaChlKSB7fVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogUmVtb3ZlcyBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLCBhZGRlZCB0byBzdXBwb3J0IElFLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG52YXIgdHJpbSA9ICcnLnRyaW1cbiAgPyBmdW5jdGlvbihzKSB7IHJldHVybiBzLnRyaW0oKTsgfVxuICA6IGZ1bmN0aW9uKHMpIHsgcmV0dXJuIHMucmVwbGFjZSgvKF5cXHMqfFxccyokKS9nLCAnJyk7IH07XG5cbi8qKlxuICogU2VyaWFsaXplIHRoZSBnaXZlbiBgb2JqYC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzZXJpYWxpemUob2JqKSB7XG4gIGlmICghaXNPYmplY3Qob2JqKSkgcmV0dXJuIG9iajtcbiAgdmFyIHBhaXJzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAobnVsbCAhPSBvYmpba2V5XSkge1xuICAgICAgcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSwgb2JqW2tleV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gIHJldHVybiBwYWlycy5qb2luKCcmJyk7XG59XG5cbi8qKlxuICogSGVscHMgJ3NlcmlhbGl6ZScgd2l0aCBzZXJpYWxpemluZyBhcnJheXMuXG4gKiBNdXRhdGVzIHRoZSBwYWlycyBhcnJheS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwYWlyc1xuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHtNaXhlZH0gdmFsXG4gKi9cblxuZnVuY3Rpb24gcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSwgdmFsKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICByZXR1cm4gdmFsLmZvckVhY2goZnVuY3Rpb24odikge1xuICAgICAgcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSwgdik7XG4gICAgfSk7XG4gIH1cbiAgcGFpcnMucHVzaChlbmNvZGVVUklDb21wb25lbnQoa2V5KVxuICAgICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbCkpO1xufVxuXG4vKipcbiAqIEV4cG9zZSBzZXJpYWxpemF0aW9uIG1ldGhvZC5cbiAqL1xuXG4gcmVxdWVzdC5zZXJpYWxpemVPYmplY3QgPSBzZXJpYWxpemU7XG5cbiAvKipcbiAgKiBQYXJzZSB0aGUgZ2l2ZW4geC13d3ctZm9ybS11cmxlbmNvZGVkIGBzdHJgLlxuICAqXG4gICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICAqIEByZXR1cm4ge09iamVjdH1cbiAgKiBAYXBpIHByaXZhdGVcbiAgKi9cblxuZnVuY3Rpb24gcGFyc2VTdHJpbmcoc3RyKSB7XG4gIHZhciBvYmogPSB7fTtcbiAgdmFyIHBhaXJzID0gc3RyLnNwbGl0KCcmJyk7XG4gIHZhciBwYXJ0cztcbiAgdmFyIHBhaXI7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHBhaXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgcGFpciA9IHBhaXJzW2ldO1xuICAgIHBhcnRzID0gcGFpci5zcGxpdCgnPScpO1xuICAgIG9ialtkZWNvZGVVUklDb21wb25lbnQocGFydHNbMF0pXSA9IGRlY29kZVVSSUNvbXBvbmVudChwYXJ0c1sxXSk7XG4gIH1cblxuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIEV4cG9zZSBwYXJzZXIuXG4gKi9cblxucmVxdWVzdC5wYXJzZVN0cmluZyA9IHBhcnNlU3RyaW5nO1xuXG4vKipcbiAqIERlZmF1bHQgTUlNRSB0eXBlIG1hcC5cbiAqXG4gKiAgICAgc3VwZXJhZ2VudC50eXBlcy54bWwgPSAnYXBwbGljYXRpb24veG1sJztcbiAqXG4gKi9cblxucmVxdWVzdC50eXBlcyA9IHtcbiAgaHRtbDogJ3RleHQvaHRtbCcsXG4gIGpzb246ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgeG1sOiAnYXBwbGljYXRpb24veG1sJyxcbiAgdXJsZW5jb2RlZDogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcsXG4gICdmb3JtJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcsXG4gICdmb3JtLWRhdGEnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJ1xufTtcblxuLyoqXG4gKiBEZWZhdWx0IHNlcmlhbGl6YXRpb24gbWFwLlxuICpcbiAqICAgICBzdXBlcmFnZW50LnNlcmlhbGl6ZVsnYXBwbGljYXRpb24veG1sJ10gPSBmdW5jdGlvbihvYmope1xuICogICAgICAgcmV0dXJuICdnZW5lcmF0ZWQgeG1sIGhlcmUnO1xuICogICAgIH07XG4gKlxuICovXG5cbiByZXF1ZXN0LnNlcmlhbGl6ZSA9IHtcbiAgICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnOiBzZXJpYWxpemUsXG4gICAnYXBwbGljYXRpb24vanNvbic6IEpTT04uc3RyaW5naWZ5XG4gfTtcblxuIC8qKlxuICAqIERlZmF1bHQgcGFyc2Vycy5cbiAgKlxuICAqICAgICBzdXBlcmFnZW50LnBhcnNlWydhcHBsaWNhdGlvbi94bWwnXSA9IGZ1bmN0aW9uKHN0cil7XG4gICogICAgICAgcmV0dXJuIHsgb2JqZWN0IHBhcnNlZCBmcm9tIHN0ciB9O1xuICAqICAgICB9O1xuICAqXG4gICovXG5cbnJlcXVlc3QucGFyc2UgPSB7XG4gICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnOiBwYXJzZVN0cmluZyxcbiAgJ2FwcGxpY2F0aW9uL2pzb24nOiBKU09OLnBhcnNlXG59O1xuXG4vKipcbiAqIFBhcnNlIHRoZSBnaXZlbiBoZWFkZXIgYHN0cmAgaW50b1xuICogYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIG1hcHBlZCBmaWVsZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7T2JqZWN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcGFyc2VIZWFkZXIoc3RyKSB7XG4gIHZhciBsaW5lcyA9IHN0ci5zcGxpdCgvXFxyP1xcbi8pO1xuICB2YXIgZmllbGRzID0ge307XG4gIHZhciBpbmRleDtcbiAgdmFyIGxpbmU7XG4gIHZhciBmaWVsZDtcbiAgdmFyIHZhbDtcblxuICBsaW5lcy5wb3AoKTsgLy8gdHJhaWxpbmcgQ1JMRlxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBsaW5lcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIGxpbmUgPSBsaW5lc1tpXTtcbiAgICBpbmRleCA9IGxpbmUuaW5kZXhPZignOicpO1xuICAgIGZpZWxkID0gbGluZS5zbGljZSgwLCBpbmRleCkudG9Mb3dlckNhc2UoKTtcbiAgICB2YWwgPSB0cmltKGxpbmUuc2xpY2UoaW5kZXggKyAxKSk7XG4gICAgZmllbGRzW2ZpZWxkXSA9IHZhbDtcbiAgfVxuXG4gIHJldHVybiBmaWVsZHM7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYG1pbWVgIGlzIGpzb24gb3IgaGFzICtqc29uIHN0cnVjdHVyZWQgc3ludGF4IHN1ZmZpeC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWltZVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGlzSlNPTihtaW1lKSB7XG4gIHJldHVybiAvW1xcLytdanNvblxcYi8udGVzdChtaW1lKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIG1pbWUgdHlwZSBmb3IgdGhlIGdpdmVuIGBzdHJgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHR5cGUoc3RyKXtcbiAgcmV0dXJuIHN0ci5zcGxpdCgvICo7ICovKS5zaGlmdCgpO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gaGVhZGVyIGZpZWxkIHBhcmFtZXRlcnMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7T2JqZWN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcGFyYW1zKHN0cil7XG4gIHJldHVybiByZWR1Y2Uoc3RyLnNwbGl0KC8gKjsgKi8pLCBmdW5jdGlvbihvYmosIHN0cil7XG4gICAgdmFyIHBhcnRzID0gc3RyLnNwbGl0KC8gKj0gKi8pXG4gICAgICAsIGtleSA9IHBhcnRzLnNoaWZ0KClcbiAgICAgICwgdmFsID0gcGFydHMuc2hpZnQoKTtcblxuICAgIGlmIChrZXkgJiYgdmFsKSBvYmpba2V5XSA9IHZhbDtcbiAgICByZXR1cm4gb2JqO1xuICB9LCB7fSk7XG59O1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYFJlc3BvbnNlYCB3aXRoIHRoZSBnaXZlbiBgeGhyYC5cbiAqXG4gKiAgLSBzZXQgZmxhZ3MgKC5vaywgLmVycm9yLCBldGMpXG4gKiAgLSBwYXJzZSBoZWFkZXJcbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgQWxpYXNpbmcgYHN1cGVyYWdlbnRgIGFzIGByZXF1ZXN0YCBpcyBuaWNlOlxuICpcbiAqICAgICAgcmVxdWVzdCA9IHN1cGVyYWdlbnQ7XG4gKlxuICogIFdlIGNhbiB1c2UgdGhlIHByb21pc2UtbGlrZSBBUEksIG9yIHBhc3MgY2FsbGJhY2tzOlxuICpcbiAqICAgICAgcmVxdWVzdC5nZXQoJy8nKS5lbmQoZnVuY3Rpb24ocmVzKXt9KTtcbiAqICAgICAgcmVxdWVzdC5nZXQoJy8nLCBmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqICBTZW5kaW5nIGRhdGEgY2FuIGJlIGNoYWluZWQ6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJylcbiAqICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAuZW5kKGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogIE9yIHBhc3NlZCB0byBgLnNlbmQoKWA6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJylcbiAqICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSwgZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiAgT3IgcGFzc2VkIHRvIGAucG9zdCgpYDpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInLCB7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAuZW5kKGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogT3IgZnVydGhlciByZWR1Y2VkIHRvIGEgc2luZ2xlIGNhbGwgZm9yIHNpbXBsZSBjYXNlczpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInLCB7IG5hbWU6ICd0aicgfSwgZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiBAcGFyYW0ge1hNTEhUVFBSZXF1ZXN0fSB4aHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBSZXNwb25zZShyZXEsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRoaXMucmVxID0gcmVxO1xuICB0aGlzLnhociA9IHRoaXMucmVxLnhocjtcbiAgLy8gcmVzcG9uc2VUZXh0IGlzIGFjY2Vzc2libGUgb25seSBpZiByZXNwb25zZVR5cGUgaXMgJycgb3IgJ3RleHQnIGFuZCBvbiBvbGRlciBicm93c2Vyc1xuICB0aGlzLnRleHQgPSAoKHRoaXMucmVxLm1ldGhvZCAhPSdIRUFEJyAmJiAodGhpcy54aHIucmVzcG9uc2VUeXBlID09PSAnJyB8fCB0aGlzLnhoci5yZXNwb25zZVR5cGUgPT09ICd0ZXh0JykpIHx8IHR5cGVvZiB0aGlzLnhoci5yZXNwb25zZVR5cGUgPT09ICd1bmRlZmluZWQnKVxuICAgICA/IHRoaXMueGhyLnJlc3BvbnNlVGV4dFxuICAgICA6IG51bGw7XG4gIHRoaXMuc3RhdHVzVGV4dCA9IHRoaXMucmVxLnhoci5zdGF0dXNUZXh0O1xuICB0aGlzLnNldFN0YXR1c1Byb3BlcnRpZXModGhpcy54aHIuc3RhdHVzKTtcbiAgdGhpcy5oZWFkZXIgPSB0aGlzLmhlYWRlcnMgPSBwYXJzZUhlYWRlcih0aGlzLnhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSk7XG4gIC8vIGdldEFsbFJlc3BvbnNlSGVhZGVycyBzb21ldGltZXMgZmFsc2VseSByZXR1cm5zIFwiXCIgZm9yIENPUlMgcmVxdWVzdHMsIGJ1dFxuICAvLyBnZXRSZXNwb25zZUhlYWRlciBzdGlsbCB3b3Jrcy4gc28gd2UgZ2V0IGNvbnRlbnQtdHlwZSBldmVuIGlmIGdldHRpbmdcbiAgLy8gb3RoZXIgaGVhZGVycyBmYWlscy5cbiAgdGhpcy5oZWFkZXJbJ2NvbnRlbnQtdHlwZSddID0gdGhpcy54aHIuZ2V0UmVzcG9uc2VIZWFkZXIoJ2NvbnRlbnQtdHlwZScpO1xuICB0aGlzLnNldEhlYWRlclByb3BlcnRpZXModGhpcy5oZWFkZXIpO1xuICB0aGlzLmJvZHkgPSB0aGlzLnJlcS5tZXRob2QgIT0gJ0hFQUQnXG4gICAgPyB0aGlzLnBhcnNlQm9keSh0aGlzLnRleHQgPyB0aGlzLnRleHQgOiB0aGlzLnhoci5yZXNwb25zZSlcbiAgICA6IG51bGw7XG59XG5cbi8qKlxuICogR2V0IGNhc2UtaW5zZW5zaXRpdmUgYGZpZWxkYCB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGZpZWxkKXtcbiAgcmV0dXJuIHRoaXMuaGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldO1xufTtcblxuLyoqXG4gKiBTZXQgaGVhZGVyIHJlbGF0ZWQgcHJvcGVydGllczpcbiAqXG4gKiAgIC0gYC50eXBlYCB0aGUgY29udGVudCB0eXBlIHdpdGhvdXQgcGFyYW1zXG4gKlxuICogQSByZXNwb25zZSBvZiBcIkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOFwiXG4gKiB3aWxsIHByb3ZpZGUgeW91IHdpdGggYSBgLnR5cGVgIG9mIFwidGV4dC9wbGFpblwiLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoZWFkZXJcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS5zZXRIZWFkZXJQcm9wZXJ0aWVzID0gZnVuY3Rpb24oaGVhZGVyKXtcbiAgLy8gY29udGVudC10eXBlXG4gIHZhciBjdCA9IHRoaXMuaGVhZGVyWydjb250ZW50LXR5cGUnXSB8fCAnJztcbiAgdGhpcy50eXBlID0gdHlwZShjdCk7XG5cbiAgLy8gcGFyYW1zXG4gIHZhciBvYmogPSBwYXJhbXMoY3QpO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB0aGlzW2tleV0gPSBvYmpba2V5XTtcbn07XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGJvZHkgYHN0cmAuXG4gKlxuICogVXNlZCBmb3IgYXV0by1wYXJzaW5nIG9mIGJvZGllcy4gUGFyc2Vyc1xuICogYXJlIGRlZmluZWQgb24gdGhlIGBzdXBlcmFnZW50LnBhcnNlYCBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUucGFyc2VCb2R5ID0gZnVuY3Rpb24oc3RyKXtcbiAgdmFyIHBhcnNlID0gcmVxdWVzdC5wYXJzZVt0aGlzLnR5cGVdO1xuICBpZiAoIXBhcnNlICYmIGlzSlNPTih0aGlzLnR5cGUpKSB7XG4gICAgcGFyc2UgPSByZXF1ZXN0LnBhcnNlWydhcHBsaWNhdGlvbi9qc29uJ107XG4gIH1cbiAgcmV0dXJuIHBhcnNlICYmIHN0ciAmJiAoc3RyLmxlbmd0aCB8fCBzdHIgaW5zdGFuY2VvZiBPYmplY3QpXG4gICAgPyBwYXJzZShzdHIpXG4gICAgOiBudWxsO1xufTtcblxuLyoqXG4gKiBTZXQgZmxhZ3Mgc3VjaCBhcyBgLm9rYCBiYXNlZCBvbiBgc3RhdHVzYC5cbiAqXG4gKiBGb3IgZXhhbXBsZSBhIDJ4eCByZXNwb25zZSB3aWxsIGdpdmUgeW91IGEgYC5va2Agb2YgX190cnVlX19cbiAqIHdoZXJlYXMgNXh4IHdpbGwgYmUgX19mYWxzZV9fIGFuZCBgLmVycm9yYCB3aWxsIGJlIF9fdHJ1ZV9fLiBUaGVcbiAqIGAuY2xpZW50RXJyb3JgIGFuZCBgLnNlcnZlckVycm9yYCBhcmUgYWxzbyBhdmFpbGFibGUgdG8gYmUgbW9yZVxuICogc3BlY2lmaWMsIGFuZCBgLnN0YXR1c1R5cGVgIGlzIHRoZSBjbGFzcyBvZiBlcnJvciByYW5naW5nIGZyb20gMS4uNVxuICogc29tZXRpbWVzIHVzZWZ1bCBmb3IgbWFwcGluZyByZXNwb25kIGNvbG9ycyBldGMuXG4gKlxuICogXCJzdWdhclwiIHByb3BlcnRpZXMgYXJlIGFsc28gZGVmaW5lZCBmb3IgY29tbW9uIGNhc2VzLiBDdXJyZW50bHkgcHJvdmlkaW5nOlxuICpcbiAqICAgLSAubm9Db250ZW50XG4gKiAgIC0gLmJhZFJlcXVlc3RcbiAqICAgLSAudW5hdXRob3JpemVkXG4gKiAgIC0gLm5vdEFjY2VwdGFibGVcbiAqICAgLSAubm90Rm91bmRcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gc3RhdHVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuc2V0U3RhdHVzUHJvcGVydGllcyA9IGZ1bmN0aW9uKHN0YXR1cyl7XG4gIC8vIGhhbmRsZSBJRTkgYnVnOiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwMDQ2OTcyL21zaWUtcmV0dXJucy1zdGF0dXMtY29kZS1vZi0xMjIzLWZvci1hamF4LXJlcXVlc3RcbiAgaWYgKHN0YXR1cyA9PT0gMTIyMykge1xuICAgIHN0YXR1cyA9IDIwNDtcbiAgfVxuXG4gIHZhciB0eXBlID0gc3RhdHVzIC8gMTAwIHwgMDtcblxuICAvLyBzdGF0dXMgLyBjbGFzc1xuICB0aGlzLnN0YXR1cyA9IHRoaXMuc3RhdHVzQ29kZSA9IHN0YXR1cztcbiAgdGhpcy5zdGF0dXNUeXBlID0gdHlwZTtcblxuICAvLyBiYXNpY3NcbiAgdGhpcy5pbmZvID0gMSA9PSB0eXBlO1xuICB0aGlzLm9rID0gMiA9PSB0eXBlO1xuICB0aGlzLmNsaWVudEVycm9yID0gNCA9PSB0eXBlO1xuICB0aGlzLnNlcnZlckVycm9yID0gNSA9PSB0eXBlO1xuICB0aGlzLmVycm9yID0gKDQgPT0gdHlwZSB8fCA1ID09IHR5cGUpXG4gICAgPyB0aGlzLnRvRXJyb3IoKVxuICAgIDogZmFsc2U7XG5cbiAgLy8gc3VnYXJcbiAgdGhpcy5hY2NlcHRlZCA9IDIwMiA9PSBzdGF0dXM7XG4gIHRoaXMubm9Db250ZW50ID0gMjA0ID09IHN0YXR1cztcbiAgdGhpcy5iYWRSZXF1ZXN0ID0gNDAwID09IHN0YXR1cztcbiAgdGhpcy51bmF1dGhvcml6ZWQgPSA0MDEgPT0gc3RhdHVzO1xuICB0aGlzLm5vdEFjY2VwdGFibGUgPSA0MDYgPT0gc3RhdHVzO1xuICB0aGlzLm5vdEZvdW5kID0gNDA0ID09IHN0YXR1cztcbiAgdGhpcy5mb3JiaWRkZW4gPSA0MDMgPT0gc3RhdHVzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYW4gYEVycm9yYCByZXByZXNlbnRhdGl2ZSBvZiB0aGlzIHJlc3BvbnNlLlxuICpcbiAqIEByZXR1cm4ge0Vycm9yfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUudG9FcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciByZXEgPSB0aGlzLnJlcTtcbiAgdmFyIG1ldGhvZCA9IHJlcS5tZXRob2Q7XG4gIHZhciB1cmwgPSByZXEudXJsO1xuXG4gIHZhciBtc2cgPSAnY2Fubm90ICcgKyBtZXRob2QgKyAnICcgKyB1cmwgKyAnICgnICsgdGhpcy5zdGF0dXMgKyAnKSc7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IobXNnKTtcbiAgZXJyLnN0YXR1cyA9IHRoaXMuc3RhdHVzO1xuICBlcnIubWV0aG9kID0gbWV0aG9kO1xuICBlcnIudXJsID0gdXJsO1xuXG4gIHJldHVybiBlcnI7XG59O1xuXG4vKipcbiAqIEV4cG9zZSBgUmVzcG9uc2VgLlxuICovXG5cbnJlcXVlc3QuUmVzcG9uc2UgPSBSZXNwb25zZTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IGBSZXF1ZXN0YCB3aXRoIHRoZSBnaXZlbiBgbWV0aG9kYCBhbmQgYHVybGAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0KG1ldGhvZCwgdXJsKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5fcXVlcnkgPSB0aGlzLl9xdWVyeSB8fCBbXTtcbiAgdGhpcy5tZXRob2QgPSBtZXRob2Q7XG4gIHRoaXMudXJsID0gdXJsO1xuICB0aGlzLmhlYWRlciA9IHt9OyAvLyBwcmVzZXJ2ZXMgaGVhZGVyIG5hbWUgY2FzZVxuICB0aGlzLl9oZWFkZXIgPSB7fTsgLy8gY29lcmNlcyBoZWFkZXIgbmFtZXMgdG8gbG93ZXJjYXNlXG4gIHRoaXMub24oJ2VuZCcsIGZ1bmN0aW9uKCl7XG4gICAgdmFyIGVyciA9IG51bGw7XG4gICAgdmFyIHJlcyA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgcmVzID0gbmV3IFJlc3BvbnNlKHNlbGYpO1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgZXJyID0gbmV3IEVycm9yKCdQYXJzZXIgaXMgdW5hYmxlIHRvIHBhcnNlIHRoZSByZXNwb25zZScpO1xuICAgICAgZXJyLnBhcnNlID0gdHJ1ZTtcbiAgICAgIGVyci5vcmlnaW5hbCA9IGU7XG4gICAgICAvLyBpc3N1ZSAjNjc1OiByZXR1cm4gdGhlIHJhdyByZXNwb25zZSBpZiB0aGUgcmVzcG9uc2UgcGFyc2luZyBmYWlsc1xuICAgICAgZXJyLnJhd1Jlc3BvbnNlID0gc2VsZi54aHIgJiYgc2VsZi54aHIucmVzcG9uc2VUZXh0ID8gc2VsZi54aHIucmVzcG9uc2VUZXh0IDogbnVsbDtcbiAgICAgIC8vIGlzc3VlICM4NzY6IHJldHVybiB0aGUgaHR0cCBzdGF0dXMgY29kZSBpZiB0aGUgcmVzcG9uc2UgcGFyc2luZyBmYWlsc1xuICAgICAgZXJyLnN0YXR1c0NvZGUgPSBzZWxmLnhociAmJiBzZWxmLnhoci5zdGF0dXMgPyBzZWxmLnhoci5zdGF0dXMgOiBudWxsO1xuICAgICAgcmV0dXJuIHNlbGYuY2FsbGJhY2soZXJyKTtcbiAgICB9XG5cbiAgICBzZWxmLmVtaXQoJ3Jlc3BvbnNlJywgcmVzKTtcblxuICAgIGlmIChlcnIpIHtcbiAgICAgIHJldHVybiBzZWxmLmNhbGxiYWNrKGVyciwgcmVzKTtcbiAgICB9XG5cbiAgICBpZiAocmVzLnN0YXR1cyA+PSAyMDAgJiYgcmVzLnN0YXR1cyA8IDMwMCkge1xuICAgICAgcmV0dXJuIHNlbGYuY2FsbGJhY2soZXJyLCByZXMpO1xuICAgIH1cblxuICAgIHZhciBuZXdfZXJyID0gbmV3IEVycm9yKHJlcy5zdGF0dXNUZXh0IHx8ICdVbnN1Y2Nlc3NmdWwgSFRUUCByZXNwb25zZScpO1xuICAgIG5ld19lcnIub3JpZ2luYWwgPSBlcnI7XG4gICAgbmV3X2Vyci5yZXNwb25zZSA9IHJlcztcbiAgICBuZXdfZXJyLnN0YXR1cyA9IHJlcy5zdGF0dXM7XG5cbiAgICBzZWxmLmNhbGxiYWNrKG5ld19lcnIsIHJlcyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIE1peGluIGBFbWl0dGVyYCBhbmQgYHJlcXVlc3RCYXNlYC5cbiAqL1xuXG5FbWl0dGVyKFJlcXVlc3QucHJvdG90eXBlKTtcbmZvciAodmFyIGtleSBpbiByZXF1ZXN0QmFzZSkge1xuICBSZXF1ZXN0LnByb3RvdHlwZVtrZXldID0gcmVxdWVzdEJhc2Vba2V5XTtcbn1cblxuLyoqXG4gKiBBYm9ydCB0aGUgcmVxdWVzdCwgYW5kIGNsZWFyIHBvdGVudGlhbCB0aW1lb3V0LlxuICpcbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmFib3J0ID0gZnVuY3Rpb24oKXtcbiAgaWYgKHRoaXMuYWJvcnRlZCkgcmV0dXJuO1xuICB0aGlzLmFib3J0ZWQgPSB0cnVlO1xuICB0aGlzLnhoci5hYm9ydCgpO1xuICB0aGlzLmNsZWFyVGltZW91dCgpO1xuICB0aGlzLmVtaXQoJ2Fib3J0Jyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgQ29udGVudC1UeXBlIHRvIGB0eXBlYCwgbWFwcGluZyB2YWx1ZXMgZnJvbSBgcmVxdWVzdC50eXBlc2AuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICBzdXBlcmFnZW50LnR5cGVzLnhtbCA9ICdhcHBsaWNhdGlvbi94bWwnO1xuICpcbiAqICAgICAgcmVxdWVzdC5wb3N0KCcvJylcbiAqICAgICAgICAudHlwZSgneG1sJylcbiAqICAgICAgICAuc2VuZCh4bWxzdHJpbmcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogICAgICByZXF1ZXN0LnBvc3QoJy8nKVxuICogICAgICAgIC50eXBlKCdhcHBsaWNhdGlvbi94bWwnKVxuICogICAgICAgIC5zZW5kKHhtbHN0cmluZylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnR5cGUgPSBmdW5jdGlvbih0eXBlKXtcbiAgdGhpcy5zZXQoJ0NvbnRlbnQtVHlwZScsIHJlcXVlc3QudHlwZXNbdHlwZV0gfHwgdHlwZSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgcmVzcG9uc2VUeXBlIHRvIGB2YWxgLiBQcmVzZW50bHkgdmFsaWQgcmVzcG9uc2VUeXBlcyBhcmUgJ2Jsb2InIGFuZCBcbiAqICdhcnJheWJ1ZmZlcicuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAucmVzcG9uc2VUeXBlKCdibG9iJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUucmVzcG9uc2VUeXBlID0gZnVuY3Rpb24odmFsKXtcbiAgdGhpcy5fcmVzcG9uc2VUeXBlID0gdmFsO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IEFjY2VwdCB0byBgdHlwZWAsIG1hcHBpbmcgdmFsdWVzIGZyb20gYHJlcXVlc3QudHlwZXNgLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgc3VwZXJhZ2VudC50eXBlcy5qc29uID0gJ2FwcGxpY2F0aW9uL2pzb24nO1xuICpcbiAqICAgICAgcmVxdWVzdC5nZXQoJy9hZ2VudCcpXG4gKiAgICAgICAgLmFjY2VwdCgnanNvbicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogICAgICByZXF1ZXN0LmdldCgnL2FnZW50JylcbiAqICAgICAgICAuYWNjZXB0KCdhcHBsaWNhdGlvbi9qc29uJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYWNjZXB0XG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24odHlwZSl7XG4gIHRoaXMuc2V0KCdBY2NlcHQnLCByZXF1ZXN0LnR5cGVzW3R5cGVdIHx8IHR5cGUpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IEF1dGhvcml6YXRpb24gZmllbGQgdmFsdWUgd2l0aCBgdXNlcmAgYW5kIGBwYXNzYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXNlclxuICogQHBhcmFtIHtTdHJpbmd9IHBhc3NcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIHdpdGggJ3R5cGUnIHByb3BlcnR5ICdhdXRvJyBvciAnYmFzaWMnIChkZWZhdWx0ICdiYXNpYycpXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYXV0aCA9IGZ1bmN0aW9uKHVzZXIsIHBhc3MsIG9wdGlvbnMpe1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgdHlwZTogJ2Jhc2ljJ1xuICAgIH1cbiAgfVxuXG4gIHN3aXRjaCAob3B0aW9ucy50eXBlKSB7XG4gICAgY2FzZSAnYmFzaWMnOlxuICAgICAgdmFyIHN0ciA9IGJ0b2EodXNlciArICc6JyArIHBhc3MpO1xuICAgICAgdGhpcy5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmFzaWMgJyArIHN0cik7XG4gICAgYnJlYWs7XG5cbiAgICBjYXNlICdhdXRvJzpcbiAgICAgIHRoaXMudXNlcm5hbWUgPSB1c2VyO1xuICAgICAgdGhpcy5wYXNzd29yZCA9IHBhc3M7XG4gICAgYnJlYWs7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiogQWRkIHF1ZXJ5LXN0cmluZyBgdmFsYC5cbipcbiogRXhhbXBsZXM6XG4qXG4qICAgcmVxdWVzdC5nZXQoJy9zaG9lcycpXG4qICAgICAucXVlcnkoJ3NpemU9MTAnKVxuKiAgICAgLnF1ZXJ5KHsgY29sb3I6ICdibHVlJyB9KVxuKlxuKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IHZhbFxuKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiogQGFwaSBwdWJsaWNcbiovXG5cblJlcXVlc3QucHJvdG90eXBlLnF1ZXJ5ID0gZnVuY3Rpb24odmFsKXtcbiAgaWYgKCdzdHJpbmcnICE9IHR5cGVvZiB2YWwpIHZhbCA9IHNlcmlhbGl6ZSh2YWwpO1xuICBpZiAodmFsKSB0aGlzLl9xdWVyeS5wdXNoKHZhbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBRdWV1ZSB0aGUgZ2l2ZW4gYGZpbGVgIGFzIGFuIGF0dGFjaG1lbnQgdG8gdGhlIHNwZWNpZmllZCBgZmllbGRgLFxuICogd2l0aCBvcHRpb25hbCBgZmlsZW5hbWVgLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmF0dGFjaChuZXcgQmxvYihbJzxhIGlkPVwiYVwiPjxiIGlkPVwiYlwiPmhleSE8L2I+PC9hPiddLCB7IHR5cGU6IFwidGV4dC9odG1sXCJ9KSlcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEBwYXJhbSB7QmxvYnxGaWxlfSBmaWxlXG4gKiBAcGFyYW0ge1N0cmluZ30gZmlsZW5hbWVcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hdHRhY2ggPSBmdW5jdGlvbihmaWVsZCwgZmlsZSwgZmlsZW5hbWUpe1xuICB0aGlzLl9nZXRGb3JtRGF0YSgpLmFwcGVuZChmaWVsZCwgZmlsZSwgZmlsZW5hbWUgfHwgZmlsZS5uYW1lKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5fZ2V0Rm9ybURhdGEgPSBmdW5jdGlvbigpe1xuICBpZiAoIXRoaXMuX2Zvcm1EYXRhKSB7XG4gICAgdGhpcy5fZm9ybURhdGEgPSBuZXcgcm9vdC5Gb3JtRGF0YSgpO1xuICB9XG4gIHJldHVybiB0aGlzLl9mb3JtRGF0YTtcbn07XG5cbi8qKlxuICogU2VuZCBgZGF0YWAgYXMgdGhlIHJlcXVlc3QgYm9keSwgZGVmYXVsdGluZyB0aGUgYC50eXBlKClgIHRvIFwianNvblwiIHdoZW5cbiAqIGFuIG9iamVjdCBpcyBnaXZlbi5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgICAvLyBtYW51YWwganNvblxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC50eXBlKCdqc29uJylcbiAqICAgICAgICAgLnNlbmQoJ3tcIm5hbWVcIjpcInRqXCJ9JylcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBhdXRvIGpzb25cbiAqICAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBtYW51YWwgeC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2Zvcm0nKVxuICogICAgICAgICAuc2VuZCgnbmFtZT10aicpXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gYXV0byB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAqICAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgICAudHlwZSgnZm9ybScpXG4gKiAgICAgICAgIC5zZW5kKHsgbmFtZTogJ3RqJyB9KVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIGRlZmF1bHRzIHRvIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICAqICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gICogICAgICAgIC5zZW5kKCduYW1lPXRvYmknKVxuICAqICAgICAgICAuc2VuZCgnc3BlY2llcz1mZXJyZXQnKVxuICAqICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gZGF0YVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbihkYXRhKXtcbiAgdmFyIG9iaiA9IGlzT2JqZWN0KGRhdGEpO1xuICB2YXIgdHlwZSA9IHRoaXMuX2hlYWRlclsnY29udGVudC10eXBlJ107XG5cbiAgLy8gbWVyZ2VcbiAgaWYgKG9iaiAmJiBpc09iamVjdCh0aGlzLl9kYXRhKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICB0aGlzLl9kYXRhW2tleV0gPSBkYXRhW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgaWYgKCF0eXBlKSB0aGlzLnR5cGUoJ2Zvcm0nKTtcbiAgICB0eXBlID0gdGhpcy5faGVhZGVyWydjb250ZW50LXR5cGUnXTtcbiAgICBpZiAoJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgPT0gdHlwZSkge1xuICAgICAgdGhpcy5fZGF0YSA9IHRoaXMuX2RhdGFcbiAgICAgICAgPyB0aGlzLl9kYXRhICsgJyYnICsgZGF0YVxuICAgICAgICA6IGRhdGE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2RhdGEgPSAodGhpcy5fZGF0YSB8fCAnJykgKyBkYXRhO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9kYXRhID0gZGF0YTtcbiAgfVxuXG4gIGlmICghb2JqIHx8IGlzSG9zdChkYXRhKSkgcmV0dXJuIHRoaXM7XG4gIGlmICghdHlwZSkgdGhpcy50eXBlKCdqc29uJyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBAZGVwcmVjYXRlZFxuICovXG5SZXNwb25zZS5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiBzZXJpYWxpemUoZm4pe1xuICBpZiAocm9vdC5jb25zb2xlKSB7XG4gICAgY29uc29sZS53YXJuKFwiQ2xpZW50LXNpZGUgcGFyc2UoKSBtZXRob2QgaGFzIGJlZW4gcmVuYW1lZCB0byBzZXJpYWxpemUoKS4gVGhpcyBtZXRob2QgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBzdXBlcmFnZW50IHYyLjBcIik7XG4gIH1cbiAgdGhpcy5zZXJpYWxpemUoZm4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cblJlc3BvbnNlLnByb3RvdHlwZS5zZXJpYWxpemUgPSBmdW5jdGlvbiBzZXJpYWxpemUoZm4pe1xuICB0aGlzLl9wYXJzZXIgPSBmbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEludm9rZSB0aGUgY2FsbGJhY2sgd2l0aCBgZXJyYCBhbmQgYHJlc2BcbiAqIGFuZCBoYW5kbGUgYXJpdHkgY2hlY2suXG4gKlxuICogQHBhcmFtIHtFcnJvcn0gZXJyXG4gKiBAcGFyYW0ge1Jlc3BvbnNlfSByZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNhbGxiYWNrID0gZnVuY3Rpb24oZXJyLCByZXMpe1xuICB2YXIgZm4gPSB0aGlzLl9jYWxsYmFjaztcbiAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgZm4oZXJyLCByZXMpO1xufTtcblxuLyoqXG4gKiBJbnZva2UgY2FsbGJhY2sgd2l0aCB4LWRvbWFpbiBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jcm9zc0RvbWFpbkVycm9yID0gZnVuY3Rpb24oKXtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgYmVlbiB0ZXJtaW5hdGVkXFxuUG9zc2libGUgY2F1c2VzOiB0aGUgbmV0d29yayBpcyBvZmZsaW5lLCBPcmlnaW4gaXMgbm90IGFsbG93ZWQgYnkgQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luLCB0aGUgcGFnZSBpcyBiZWluZyB1bmxvYWRlZCwgZXRjLicpO1xuICBlcnIuY3Jvc3NEb21haW4gPSB0cnVlO1xuXG4gIGVyci5zdGF0dXMgPSB0aGlzLnN0YXR1cztcbiAgZXJyLm1ldGhvZCA9IHRoaXMubWV0aG9kO1xuICBlcnIudXJsID0gdGhpcy51cmw7XG5cbiAgdGhpcy5jYWxsYmFjayhlcnIpO1xufTtcblxuLyoqXG4gKiBJbnZva2UgY2FsbGJhY2sgd2l0aCB0aW1lb3V0IGVycm9yLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnRpbWVvdXRFcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcigndGltZW91dCBvZiAnICsgdGltZW91dCArICdtcyBleGNlZWRlZCcpO1xuICBlcnIudGltZW91dCA9IHRpbWVvdXQ7XG4gIHRoaXMuY2FsbGJhY2soZXJyKTtcbn07XG5cbi8qKlxuICogRW5hYmxlIHRyYW5zbWlzc2lvbiBvZiBjb29raWVzIHdpdGggeC1kb21haW4gcmVxdWVzdHMuXG4gKlxuICogTm90ZSB0aGF0IGZvciB0aGlzIHRvIHdvcmsgdGhlIG9yaWdpbiBtdXN0IG5vdCBiZVxuICogdXNpbmcgXCJBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW5cIiB3aXRoIGEgd2lsZGNhcmQsXG4gKiBhbmQgYWxzbyBtdXN0IHNldCBcIkFjY2Vzcy1Db250cm9sLUFsbG93LUNyZWRlbnRpYWxzXCJcbiAqIHRvIFwidHJ1ZVwiLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUud2l0aENyZWRlbnRpYWxzID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5fd2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEluaXRpYXRlIHJlcXVlc3QsIGludm9raW5nIGNhbGxiYWNrIGBmbihyZXMpYFxuICogd2l0aCBhbiBpbnN0YW5jZW9mIGBSZXNwb25zZWAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihmbil7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHhociA9IHRoaXMueGhyID0gcmVxdWVzdC5nZXRYSFIoKTtcbiAgdmFyIHF1ZXJ5ID0gdGhpcy5fcXVlcnkuam9pbignJicpO1xuICB2YXIgdGltZW91dCA9IHRoaXMuX3RpbWVvdXQ7XG4gIHZhciBkYXRhID0gdGhpcy5fZm9ybURhdGEgfHwgdGhpcy5fZGF0YTtcblxuICAvLyBzdG9yZSBjYWxsYmFja1xuICB0aGlzLl9jYWxsYmFjayA9IGZuIHx8IG5vb3A7XG5cbiAgLy8gc3RhdGUgY2hhbmdlXG4gIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpe1xuICAgIGlmICg0ICE9IHhoci5yZWFkeVN0YXRlKSByZXR1cm47XG5cbiAgICAvLyBJbiBJRTksIHJlYWRzIHRvIGFueSBwcm9wZXJ0eSAoZS5nLiBzdGF0dXMpIG9mZiBvZiBhbiBhYm9ydGVkIFhIUiB3aWxsXG4gICAgLy8gcmVzdWx0IGluIHRoZSBlcnJvciBcIkNvdWxkIG5vdCBjb21wbGV0ZSB0aGUgb3BlcmF0aW9uIGR1ZSB0byBlcnJvciBjMDBjMDIzZlwiXG4gICAgdmFyIHN0YXR1cztcbiAgICB0cnkgeyBzdGF0dXMgPSB4aHIuc3RhdHVzIH0gY2F0Y2goZSkgeyBzdGF0dXMgPSAwOyB9XG5cbiAgICBpZiAoMCA9PSBzdGF0dXMpIHtcbiAgICAgIGlmIChzZWxmLnRpbWVkb3V0KSByZXR1cm4gc2VsZi50aW1lb3V0RXJyb3IoKTtcbiAgICAgIGlmIChzZWxmLmFib3J0ZWQpIHJldHVybjtcbiAgICAgIHJldHVybiBzZWxmLmNyb3NzRG9tYWluRXJyb3IoKTtcbiAgICB9XG4gICAgc2VsZi5lbWl0KCdlbmQnKTtcbiAgfTtcblxuICAvLyBwcm9ncmVzc1xuICB2YXIgaGFuZGxlUHJvZ3Jlc3MgPSBmdW5jdGlvbihlKXtcbiAgICBpZiAoZS50b3RhbCA+IDApIHtcbiAgICAgIGUucGVyY2VudCA9IGUubG9hZGVkIC8gZS50b3RhbCAqIDEwMDtcbiAgICB9XG4gICAgZS5kaXJlY3Rpb24gPSAnZG93bmxvYWQnO1xuICAgIHNlbGYuZW1pdCgncHJvZ3Jlc3MnLCBlKTtcbiAgfTtcbiAgaWYgKHRoaXMuaGFzTGlzdGVuZXJzKCdwcm9ncmVzcycpKSB7XG4gICAgeGhyLm9ucHJvZ3Jlc3MgPSBoYW5kbGVQcm9ncmVzcztcbiAgfVxuICB0cnkge1xuICAgIGlmICh4aHIudXBsb2FkICYmIHRoaXMuaGFzTGlzdGVuZXJzKCdwcm9ncmVzcycpKSB7XG4gICAgICB4aHIudXBsb2FkLm9ucHJvZ3Jlc3MgPSBoYW5kbGVQcm9ncmVzcztcbiAgICB9XG4gIH0gY2F0Y2goZSkge1xuICAgIC8vIEFjY2Vzc2luZyB4aHIudXBsb2FkIGZhaWxzIGluIElFIGZyb20gYSB3ZWIgd29ya2VyLCBzbyBqdXN0IHByZXRlbmQgaXQgZG9lc24ndCBleGlzdC5cbiAgICAvLyBSZXBvcnRlZCBoZXJlOlxuICAgIC8vIGh0dHBzOi8vY29ubmVjdC5taWNyb3NvZnQuY29tL0lFL2ZlZWRiYWNrL2RldGFpbHMvODM3MjQ1L3htbGh0dHByZXF1ZXN0LXVwbG9hZC10aHJvd3MtaW52YWxpZC1hcmd1bWVudC13aGVuLXVzZWQtZnJvbS13ZWItd29ya2VyLWNvbnRleHRcbiAgfVxuXG4gIC8vIHRpbWVvdXRcbiAgaWYgKHRpbWVvdXQgJiYgIXRoaXMuX3RpbWVyKSB7XG4gICAgdGhpcy5fdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICBzZWxmLnRpbWVkb3V0ID0gdHJ1ZTtcbiAgICAgIHNlbGYuYWJvcnQoKTtcbiAgICB9LCB0aW1lb3V0KTtcbiAgfVxuXG4gIC8vIHF1ZXJ5c3RyaW5nXG4gIGlmIChxdWVyeSkge1xuICAgIHF1ZXJ5ID0gcmVxdWVzdC5zZXJpYWxpemVPYmplY3QocXVlcnkpO1xuICAgIHRoaXMudXJsICs9IH50aGlzLnVybC5pbmRleE9mKCc/JylcbiAgICAgID8gJyYnICsgcXVlcnlcbiAgICAgIDogJz8nICsgcXVlcnk7XG4gIH1cblxuICAvLyBpbml0aWF0ZSByZXF1ZXN0XG4gIGlmICh0aGlzLnVzZXJuYW1lICYmIHRoaXMucGFzc3dvcmQpIHtcbiAgICB4aHIub3Blbih0aGlzLm1ldGhvZCwgdGhpcy51cmwsIHRydWUsIHRoaXMudXNlcm5hbWUsIHRoaXMucGFzc3dvcmQpO1xuICB9IGVsc2Uge1xuICAgIHhoci5vcGVuKHRoaXMubWV0aG9kLCB0aGlzLnVybCwgdHJ1ZSk7XG4gIH1cblxuICAvLyBDT1JTXG4gIGlmICh0aGlzLl93aXRoQ3JlZGVudGlhbHMpIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuXG4gIC8vIGJvZHlcbiAgaWYgKCdHRVQnICE9IHRoaXMubWV0aG9kICYmICdIRUFEJyAhPSB0aGlzLm1ldGhvZCAmJiAnc3RyaW5nJyAhPSB0eXBlb2YgZGF0YSAmJiAhaXNIb3N0KGRhdGEpKSB7XG4gICAgLy8gc2VyaWFsaXplIHN0dWZmXG4gICAgdmFyIGNvbnRlbnRUeXBlID0gdGhpcy5faGVhZGVyWydjb250ZW50LXR5cGUnXTtcbiAgICB2YXIgc2VyaWFsaXplID0gdGhpcy5fcGFyc2VyIHx8IHJlcXVlc3Quc2VyaWFsaXplW2NvbnRlbnRUeXBlID8gY29udGVudFR5cGUuc3BsaXQoJzsnKVswXSA6ICcnXTtcbiAgICBpZiAoIXNlcmlhbGl6ZSAmJiBpc0pTT04oY29udGVudFR5cGUpKSBzZXJpYWxpemUgPSByZXF1ZXN0LnNlcmlhbGl6ZVsnYXBwbGljYXRpb24vanNvbiddO1xuICAgIGlmIChzZXJpYWxpemUpIGRhdGEgPSBzZXJpYWxpemUoZGF0YSk7XG4gIH1cblxuICAvLyBzZXQgaGVhZGVyIGZpZWxkc1xuICBmb3IgKHZhciBmaWVsZCBpbiB0aGlzLmhlYWRlcikge1xuICAgIGlmIChudWxsID09IHRoaXMuaGVhZGVyW2ZpZWxkXSkgY29udGludWU7XG4gICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoZmllbGQsIHRoaXMuaGVhZGVyW2ZpZWxkXSk7XG4gIH1cblxuICBpZiAodGhpcy5fcmVzcG9uc2VUeXBlKSB7XG4gICAgeGhyLnJlc3BvbnNlVHlwZSA9IHRoaXMuX3Jlc3BvbnNlVHlwZTtcbiAgfVxuXG4gIC8vIHNlbmQgc3R1ZmZcbiAgdGhpcy5lbWl0KCdyZXF1ZXN0JywgdGhpcyk7XG5cbiAgLy8gSUUxMSB4aHIuc2VuZCh1bmRlZmluZWQpIHNlbmRzICd1bmRlZmluZWQnIHN0cmluZyBhcyBQT1NUIHBheWxvYWQgKGluc3RlYWQgb2Ygbm90aGluZylcbiAgLy8gV2UgbmVlZCBudWxsIGhlcmUgaWYgZGF0YSBpcyB1bmRlZmluZWRcbiAgeGhyLnNlbmQodHlwZW9mIGRhdGEgIT09ICd1bmRlZmluZWQnID8gZGF0YSA6IG51bGwpO1xuICByZXR1cm4gdGhpcztcbn07XG5cblxuLyoqXG4gKiBFeHBvc2UgYFJlcXVlc3RgLlxuICovXG5cbnJlcXVlc3QuUmVxdWVzdCA9IFJlcXVlc3Q7XG5cbi8qKlxuICogR0VUIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IGRhdGEgb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LmdldCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnR0VUJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEucXVlcnkoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIEhFQUQgYHVybGAgd2l0aCBvcHRpb25hbCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZHxGdW5jdGlvbn0gZGF0YSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QuaGVhZCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnSEVBRCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIERFTEVURSBgdXJsYCB3aXRoIG9wdGlvbmFsIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZGVsKHVybCwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnREVMRVRFJywgdXJsKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbnJlcXVlc3RbJ2RlbCddID0gZGVsO1xucmVxdWVzdFsnZGVsZXRlJ10gPSBkZWw7XG5cbi8qKlxuICogUEFUQ0ggYHVybGAgd2l0aCBvcHRpb25hbCBgZGF0YWAgYW5kIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfSBkYXRhXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5wYXRjaCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUEFUQ0gnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBQT1NUIGB1cmxgIHdpdGggb3B0aW9uYWwgYGRhdGFgIGFuZCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZH0gZGF0YVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QucG9zdCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUE9TVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIFBVVCBgdXJsYCB3aXRoIG9wdGlvbmFsIGBkYXRhYCBhbmQgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IGRhdGEgb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LnB1dCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUFVUJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEuc2VuZChkYXRhKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG4iLCIvKipcbiAqIENoZWNrIGlmIGBvYmpgIGlzIGFuIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNPYmplY3Qob2JqKSB7XG4gIHJldHVybiBudWxsICE9IG9iaiAmJiAnb2JqZWN0JyA9PSB0eXBlb2Ygb2JqO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0O1xuIiwiLyoqXG4gKiBNb2R1bGUgb2YgbWl4ZWQtaW4gZnVuY3Rpb25zIHNoYXJlZCBiZXR3ZWVuIG5vZGUgYW5kIGNsaWVudCBjb2RlXG4gKi9cbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXMtb2JqZWN0Jyk7XG5cbi8qKlxuICogQ2xlYXIgcHJldmlvdXMgdGltZW91dC5cbiAqXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5jbGVhclRpbWVvdXQgPSBmdW5jdGlvbiBfY2xlYXJUaW1lb3V0KCl7XG4gIHRoaXMuX3RpbWVvdXQgPSAwO1xuICBjbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRm9yY2UgZ2l2ZW4gcGFyc2VyXG4gKlxuICogU2V0cyB0aGUgYm9keSBwYXJzZXIgbm8gbWF0dGVyIHR5cGUuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5wYXJzZSA9IGZ1bmN0aW9uIHBhcnNlKGZuKXtcbiAgdGhpcy5fcGFyc2VyID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgdGltZW91dCB0byBgbXNgLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtc1xuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMudGltZW91dCA9IGZ1bmN0aW9uIHRpbWVvdXQobXMpe1xuICB0aGlzLl90aW1lb3V0ID0gbXM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBGYXV4IHByb21pc2Ugc3VwcG9ydFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bGZpbGxcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHJlamVjdFxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqL1xuXG5leHBvcnRzLnRoZW4gPSBmdW5jdGlvbiB0aGVuKGZ1bGZpbGwsIHJlamVjdCkge1xuICByZXR1cm4gdGhpcy5lbmQoZnVuY3Rpb24oZXJyLCByZXMpIHtcbiAgICBlcnIgPyByZWplY3QoZXJyKSA6IGZ1bGZpbGwocmVzKTtcbiAgfSk7XG59XG5cbi8qKlxuICogQWxsb3cgZm9yIGV4dGVuc2lvblxuICovXG5cbmV4cG9ydHMudXNlID0gZnVuY3Rpb24gdXNlKGZuKSB7XG4gIGZuKHRoaXMpO1xuICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIEdldCByZXF1ZXN0IGhlYWRlciBgZmllbGRgLlxuICogQ2FzZS1pbnNlbnNpdGl2ZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5nZXQgPSBmdW5jdGlvbihmaWVsZCl7XG4gIHJldHVybiB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV07XG59O1xuXG4vKipcbiAqIEdldCBjYXNlLWluc2Vuc2l0aXZlIGhlYWRlciBgZmllbGRgIHZhbHVlLlxuICogVGhpcyBpcyBhIGRlcHJlY2F0ZWQgaW50ZXJuYWwgQVBJLiBVc2UgYC5nZXQoZmllbGQpYCBpbnN0ZWFkLlxuICpcbiAqIChnZXRIZWFkZXIgaXMgbm8gbG9uZ2VyIHVzZWQgaW50ZXJuYWxseSBieSB0aGUgc3VwZXJhZ2VudCBjb2RlIGJhc2UpXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqIEBkZXByZWNhdGVkXG4gKi9cblxuZXhwb3J0cy5nZXRIZWFkZXIgPSBleHBvcnRzLmdldDtcblxuLyoqXG4gKiBTZXQgaGVhZGVyIGBmaWVsZGAgdG8gYHZhbGAsIG9yIG11bHRpcGxlIGZpZWxkcyB3aXRoIG9uZSBvYmplY3QuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICogICAgICAgIC5zZXQoJ1gtQVBJLUtleScsICdmb29iYXInKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnNldCh7IEFjY2VwdDogJ2FwcGxpY2F0aW9uL2pzb24nLCAnWC1BUEktS2V5JzogJ2Zvb2JhcicgfSlcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGZpZWxkXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5zZXQgPSBmdW5jdGlvbihmaWVsZCwgdmFsKXtcbiAgaWYgKGlzT2JqZWN0KGZpZWxkKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBmaWVsZCkge1xuICAgICAgdGhpcy5zZXQoa2V5LCBmaWVsZFtrZXldKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldID0gdmFsO1xuICB0aGlzLmhlYWRlcltmaWVsZF0gPSB2YWw7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgaGVhZGVyIGBmaWVsZGAuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAudW5zZXQoJ1VzZXItQWdlbnQnKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICovXG5leHBvcnRzLnVuc2V0ID0gZnVuY3Rpb24oZmllbGQpe1xuICBkZWxldGUgdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldO1xuICBkZWxldGUgdGhpcy5oZWFkZXJbZmllbGRdO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogV3JpdGUgdGhlIGZpZWxkIGBuYW1lYCBhbmQgYHZhbGAgZm9yIFwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiXG4gKiByZXF1ZXN0IGJvZGllcy5cbiAqXG4gKiBgYGAganNcbiAqIHJlcXVlc3QucG9zdCgnL3VwbG9hZCcpXG4gKiAgIC5maWVsZCgnZm9vJywgJ2JhcicpXG4gKiAgIC5lbmQoY2FsbGJhY2spO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7U3RyaW5nfEJsb2J8RmlsZXxCdWZmZXJ8ZnMuUmVhZFN0cmVhbX0gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cbmV4cG9ydHMuZmllbGQgPSBmdW5jdGlvbihuYW1lLCB2YWwpIHtcbiAgdGhpcy5fZ2V0Rm9ybURhdGEoKS5hcHBlbmQobmFtZSwgdmFsKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuIiwiLy8gVGhlIG5vZGUgYW5kIGJyb3dzZXIgbW9kdWxlcyBleHBvc2UgdmVyc2lvbnMgb2YgdGhpcyB3aXRoIHRoZVxuLy8gYXBwcm9wcmlhdGUgY29uc3RydWN0b3IgZnVuY3Rpb24gYm91bmQgYXMgZmlyc3QgYXJndW1lbnRcbi8qKlxuICogSXNzdWUgYSByZXF1ZXN0OlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgIHJlcXVlc3QoJ0dFVCcsICcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnLCBjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gdXJsIG9yIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiByZXF1ZXN0KFJlcXVlc3RDb25zdHJ1Y3RvciwgbWV0aG9kLCB1cmwpIHtcbiAgLy8gY2FsbGJhY2tcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIHVybCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdENvbnN0cnVjdG9yKCdHRVQnLCBtZXRob2QpLmVuZCh1cmwpO1xuICB9XG5cbiAgLy8gdXJsIGZpcnN0XG4gIGlmICgyID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gbmV3IFJlcXVlc3RDb25zdHJ1Y3RvcignR0VUJywgbWV0aG9kKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVxdWVzdENvbnN0cnVjdG9yKG1ldGhvZCwgdXJsKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXF1ZXN0O1xuIiwiXHJcbi8qKlxyXG4gKiBFeHBvc2UgYEVtaXR0ZXJgLlxyXG4gKi9cclxuXHJcbmlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJykge1xyXG4gIG1vZHVsZS5leHBvcnRzID0gRW1pdHRlcjtcclxufVxyXG5cclxuLyoqXHJcbiAqIEluaXRpYWxpemUgYSBuZXcgYEVtaXR0ZXJgLlxyXG4gKlxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbmZ1bmN0aW9uIEVtaXR0ZXIob2JqKSB7XHJcbiAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7XHJcbn07XHJcblxyXG4vKipcclxuICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy5cclxuICpcclxuICogQHBhcmFtIHtPYmplY3R9IG9ialxyXG4gKiBAcmV0dXJuIHtPYmplY3R9XHJcbiAqIEBhcGkgcHJpdmF0ZVxyXG4gKi9cclxuXHJcbmZ1bmN0aW9uIG1peGluKG9iaikge1xyXG4gIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkge1xyXG4gICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xyXG4gIH1cclxuICByZXR1cm4gb2JqO1xyXG59XHJcblxyXG4vKipcclxuICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXHJcbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUub24gPVxyXG5FbWl0dGVyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcclxuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XHJcbiAgKHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdKVxyXG4gICAgLnB1c2goZm4pO1xyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxyXG4gKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cclxuICogQHJldHVybiB7RW1pdHRlcn1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcclxuICBmdW5jdGlvbiBvbigpIHtcclxuICAgIHRoaXMub2ZmKGV2ZW50LCBvbik7XHJcbiAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG4gIH1cclxuXHJcbiAgb24uZm4gPSBmbjtcclxuICB0aGlzLm9uKGV2ZW50LCBvbik7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxyXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkVtaXR0ZXIucHJvdG90eXBlLm9mZiA9XHJcbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cclxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID1cclxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XHJcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xyXG5cclxuICAvLyBhbGxcclxuICBpZiAoMCA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XHJcbiAgICB0aGlzLl9jYWxsYmFja3MgPSB7fTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLy8gc3BlY2lmaWMgZXZlbnRcclxuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcclxuICBpZiAoIWNhbGxiYWNrcykgcmV0dXJuIHRoaXM7XHJcblxyXG4gIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcclxuICBpZiAoMSA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XHJcbiAgICBkZWxldGUgdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICB2YXIgY2I7XHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcclxuICAgIGNiID0gY2FsbGJhY2tzW2ldO1xyXG4gICAgaWYgKGNiID09PSBmbiB8fCBjYi5mbiA9PT0gZm4pIHtcclxuICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcclxuICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEVtaXQgYGV2ZW50YCB3aXRoIHRoZSBnaXZlbiBhcmdzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHBhcmFtIHtNaXhlZH0gLi4uXHJcbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KXtcclxuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XHJcbiAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSlcclxuICAgICwgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcclxuXHJcbiAgaWYgKGNhbGxiYWNrcykge1xyXG4gICAgY2FsbGJhY2tzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xyXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICBjYWxsYmFja3NbaV0uYXBwbHkodGhpcywgYXJncyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHJldHVybiB7QXJyYXl9XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xyXG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcclxuICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XSB8fCBbXTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiB0aGlzIGVtaXR0ZXIgaGFzIGBldmVudGAgaGFuZGxlcnMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcmV0dXJuIHtCb29sZWFufVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkVtaXR0ZXIucHJvdG90eXBlLmhhc0xpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcclxuICByZXR1cm4gISEgdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcclxufTtcclxuIiwiXG4vKipcbiAqIFJlZHVjZSBgYXJyYCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYXJyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtNaXhlZH0gaW5pdGlhbFxuICpcbiAqIFRPRE86IGNvbWJhdGlibGUgZXJyb3IgaGFuZGxpbmc/XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihhcnIsIGZuLCBpbml0aWFsKXsgIFxuICB2YXIgaWR4ID0gMDtcbiAgdmFyIGxlbiA9IGFyci5sZW5ndGg7XG4gIHZhciBjdXJyID0gYXJndW1lbnRzLmxlbmd0aCA9PSAzXG4gICAgPyBpbml0aWFsXG4gICAgOiBhcnJbaWR4KytdO1xuXG4gIHdoaWxlIChpZHggPCBsZW4pIHtcbiAgICBjdXJyID0gZm4uY2FsbChudWxsLCBjdXJyLCBhcnJbaWR4XSwgKytpZHgsIGFycik7XG4gIH1cbiAgXG4gIHJldHVybiBjdXJyO1xufTsiXX0= |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21263 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21264 | /*global JSONEditor*/ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21265 | 'use strict'; |
| 21266 | |
| 21267 | window.SwaggerUi = Backbone.Router.extend({ |
| 21268 | |
| 21269 | dom_id: 'swagger_ui', |
| 21270 | |
| 21271 | // Attributes |
| 21272 | options: null, |
| 21273 | api: null, |
| 21274 | headerView: null, |
| 21275 | mainView: null, |
| 21276 | |
| 21277 | // SwaggerUi accepts all the same options as SwaggerApi |
| 21278 | initialize: function(options) { |
| 21279 | options = options || {}; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21280 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 21281 | if (options.defaultModelRendering !== 'model') { |
| 21282 | options.defaultModelRendering = 'schema'; |
| 21283 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21284 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 21285 | if (!options.highlightSizeThreshold) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21286 | options.highlightSizeThreshold = 100000; |
| 21287 | } |
| 21288 | |
| 21289 | // Allow dom_id to be overridden |
| 21290 | if (options.dom_id) { |
| 21291 | this.dom_id = options.dom_id; |
| 21292 | delete options.dom_id; |
| 21293 | } |
| 21294 | |
| 21295 | if (!options.supportedSubmitMethods){ |
| 21296 | options.supportedSubmitMethods = [ |
| 21297 | 'get', |
| 21298 | 'put', |
| 21299 | 'post', |
| 21300 | 'delete', |
| 21301 | 'head', |
| 21302 | 'options', |
| 21303 | 'patch' |
| 21304 | ]; |
| 21305 | } |
| 21306 | |
| 21307 | if (typeof options.oauth2RedirectUrl === 'string') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21308 | window.oAuthRedirectUrl = options.oauth2RedirectUrl; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21309 | } |
| 21310 | |
| 21311 | // Create an empty div which contains the dom_id |
| 21312 | if (! $('#' + this.dom_id).length){ |
| 21313 | $('body').append('<div id="' + this.dom_id + '"></div>') ; |
| 21314 | } |
| 21315 | |
| 21316 | this.options = options; |
| 21317 | |
| 21318 | // set marked options |
| 21319 | marked.setOptions({gfm: true}); |
| 21320 | |
| 21321 | // Set the callbacks |
| 21322 | var that = this; |
| 21323 | this.options.success = function() { return that.render(); }; |
| 21324 | this.options.progress = function(d) { return that.showMessage(d); }; |
| 21325 | this.options.failure = function(d) { return that.onLoadFailure(d); }; |
| 21326 | |
| 21327 | // Create view to handle the header inputs |
| 21328 | this.headerView = new SwaggerUi.Views.HeaderView({el: $('#header')}); |
| 21329 | |
| 21330 | // Event handler for when the baseUrl/apiKey is entered by user |
| 21331 | this.headerView.on('update-swagger-ui', function(data) { |
| 21332 | return that.updateSwaggerUi(data); |
| 21333 | }); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 21334 | |
| 21335 | // JSon Editor custom theming |
| 21336 | JSONEditor.defaults.iconlibs.swagger = JSONEditor.AbstractIconLib.extend({ |
| 21337 | mapping: { |
| 21338 | collapse: 'collapse', |
| 21339 | expand: 'expand' |
| 21340 | }, |
| 21341 | icon_prefix: 'swagger-' |
| 21342 | }); |
| 21343 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21344 | }, |
| 21345 | |
| 21346 | // Set an option after initializing |
| 21347 | setOption: function(option, value) { |
| 21348 | this.options[option] = value; |
| 21349 | }, |
| 21350 | |
| 21351 | // Get the value of a previously set option |
| 21352 | getOption: function(option) { |
| 21353 | return this.options[option]; |
| 21354 | }, |
| 21355 | |
| 21356 | // Event handler for when url/key is received from user |
| 21357 | updateSwaggerUi: function(data){ |
| 21358 | this.options.url = data.url; |
| 21359 | this.load(); |
| 21360 | }, |
| 21361 | |
| 21362 | // Create an api and render |
| 21363 | load: function(){ |
| 21364 | // Initialize the API object |
| 21365 | if (this.mainView) { |
| 21366 | this.mainView.clear(); |
| 21367 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21368 | |
| 21369 | if (this.authView) { |
| 21370 | this.authView.remove(); |
| 21371 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21372 | var url = this.options.url; |
| 21373 | if (url && url.indexOf('http') !== 0) { |
| 21374 | url = this.buildUrl(window.location.href.toString(), url); |
| 21375 | } |
| 21376 | if(this.api) { |
| 21377 | this.options.authorizations = this.api.clientAuthorizations.authz; |
| 21378 | } |
| 21379 | this.options.url = url; |
| 21380 | this.headerView.update(url); |
| 21381 | |
| 21382 | this.api = new SwaggerClient(this.options); |
| 21383 | }, |
| 21384 | |
| 21385 | // collapse all sections |
| 21386 | collapseAll: function(){ |
| 21387 | Docs.collapseEndpointListForResource(''); |
| 21388 | }, |
| 21389 | |
| 21390 | // list operations for all sections |
| 21391 | listAll: function(){ |
| 21392 | Docs.collapseOperationsForResource(''); |
| 21393 | }, |
| 21394 | |
| 21395 | // expand operations for all sections |
| 21396 | expandAll: function(){ |
| 21397 | Docs.expandOperationsForResource(''); |
| 21398 | }, |
| 21399 | |
| 21400 | // This is bound to success handler for SwaggerApi |
| 21401 | // so it gets called when SwaggerApi completes loading |
| 21402 | render: function(){ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21403 | var authsModel; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21404 | this.showMessage('Finished Loading Resource Information. Rendering Swagger UI...'); |
| 21405 | this.mainView = new SwaggerUi.Views.MainView({ |
| 21406 | model: this.api, |
| 21407 | el: $('#' + this.dom_id), |
| 21408 | swaggerOptions: this.options, |
| 21409 | router: this |
| 21410 | }).render(); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21411 | if (!_.isEmpty(this.api.securityDefinitions)){ |
| 21412 | authsModel = _.map(this.api.securityDefinitions, function (auth, name) { |
| 21413 | var result = {}; |
| 21414 | result[name] = auth; |
| 21415 | return result; |
| 21416 | }); |
| 21417 | this.authView = new SwaggerUi.Views.AuthButtonView({ |
| 21418 | data: SwaggerUi.utils.parseSecurityDefinitions(authsModel), |
| 21419 | router: this |
| 21420 | }); |
| 21421 | $('#auth_container').append(this.authView.render().el); |
| 21422 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21423 | this.showMessage(); |
| 21424 | switch (this.options.docExpansion) { |
| 21425 | case 'full': |
| 21426 | this.expandAll(); break; |
| 21427 | case 'list': |
| 21428 | this.listAll(); break; |
| 21429 | default: |
| 21430 | break; |
| 21431 | } |
| 21432 | this.renderGFM(); |
| 21433 | |
| 21434 | if (this.options.onComplete){ |
| 21435 | this.options.onComplete(this.api, this); |
| 21436 | } |
| 21437 | |
| 21438 | setTimeout(Docs.shebang.bind(this), 100); |
| 21439 | }, |
| 21440 | |
| 21441 | buildUrl: function(base, url){ |
| 21442 | if (url.indexOf('/') === 0) { |
| 21443 | var parts = base.split('/'); |
| 21444 | base = parts[0] + '//' + parts[2]; |
| 21445 | return base + url; |
| 21446 | } else { |
| 21447 | var endOfPath = base.length; |
| 21448 | |
| 21449 | if (base.indexOf('?') > -1){ |
| 21450 | endOfPath = Math.min(endOfPath, base.indexOf('?')); |
| 21451 | } |
| 21452 | |
| 21453 | if (base.indexOf('#') > -1){ |
| 21454 | endOfPath = Math.min(endOfPath, base.indexOf('#')); |
| 21455 | } |
| 21456 | |
| 21457 | base = base.substring(0, endOfPath); |
| 21458 | |
| 21459 | if (base.indexOf('/', base.length - 1 ) !== -1){ |
| 21460 | return base + url; |
| 21461 | } |
| 21462 | |
| 21463 | return base + '/' + url; |
| 21464 | } |
| 21465 | }, |
| 21466 | |
| 21467 | // Shows message on topbar of the ui |
| 21468 | showMessage: function(data){ |
| 21469 | if (data === undefined) { |
| 21470 | data = ''; |
| 21471 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 21472 | var $msgbar = $('#message-bar'); |
| 21473 | $msgbar.removeClass('message-fail'); |
| 21474 | $msgbar.addClass('message-success'); |
| 21475 | $msgbar.text(data); |
| 21476 | if(window.SwaggerTranslator) { |
| 21477 | window.SwaggerTranslator.translate($msgbar); |
| 21478 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21479 | }, |
| 21480 | |
| 21481 | // shows message in red |
| 21482 | onLoadFailure: function(data){ |
| 21483 | if (data === undefined) { |
| 21484 | data = ''; |
| 21485 | } |
| 21486 | $('#message-bar').removeClass('message-success'); |
| 21487 | $('#message-bar').addClass('message-fail'); |
| 21488 | |
| 21489 | var val = $('#message-bar').text(data); |
| 21490 | |
| 21491 | if (this.options.onFailure) { |
| 21492 | this.options.onFailure(data); |
| 21493 | } |
| 21494 | |
| 21495 | return val; |
| 21496 | }, |
| 21497 | |
| 21498 | // Renders GFM for elements with 'markdown' class |
| 21499 | renderGFM: function(){ |
| 21500 | $('.markdown').each(function(){ |
| 21501 | $(this).html(marked($(this).html())); |
| 21502 | }); |
| 21503 | |
| 21504 | $('.propDesc', '.model-signature .description').each(function () { |
| 21505 | $(this).html(marked($(this).html())).addClass('markdown'); |
| 21506 | }); |
| 21507 | } |
| 21508 | |
| 21509 | }); |
| 21510 | |
| 21511 | window.SwaggerUi.Views = {}; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21512 | window.SwaggerUi.Models = {}; |
| 21513 | window.SwaggerUi.Collections = {}; |
| 21514 | window.SwaggerUi.partials = {}; |
| 21515 | window.SwaggerUi.utils = {}; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21516 | |
| 21517 | // don't break backward compatibility with previous versions and warn users to upgrade their code |
| 21518 | (function(){ |
| 21519 | window.authorizations = { |
| 21520 | add: function() { |
| 21521 | warn('Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add().'); |
| 21522 | |
| 21523 | if (typeof window.swaggerUi === 'undefined') { |
| 21524 | throw new TypeError('window.swaggerUi is not defined'); |
| 21525 | } |
| 21526 | |
| 21527 | if (window.swaggerUi instanceof SwaggerUi) { |
| 21528 | window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations, arguments); |
| 21529 | } |
| 21530 | } |
| 21531 | }; |
| 21532 | |
| 21533 | window.ApiKeyAuthorization = function() { |
| 21534 | warn('window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization.'); |
| 21535 | SwaggerClient.ApiKeyAuthorization.apply(window, arguments); |
| 21536 | }; |
| 21537 | |
| 21538 | window.PasswordAuthorization = function() { |
| 21539 | warn('window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization.'); |
| 21540 | SwaggerClient.PasswordAuthorization.apply(window, arguments); |
| 21541 | }; |
| 21542 | |
| 21543 | function warn(message) { |
| 21544 | if ('console' in window && typeof window.console.warn === 'function') { |
| 21545 | console.warn(message); |
| 21546 | } |
| 21547 | } |
| 21548 | })(); |
| 21549 | |
| 21550 | |
| 21551 | // UMD |
| 21552 | (function (root, factory) { |
| 21553 | if (typeof define === 'function' && define.amd) { |
| 21554 | // AMD. Register as an anonymous module. |
| 21555 | define(['b'], function (b) { |
| 21556 | return (root.SwaggerUi = factory(b)); |
| 21557 | }); |
| 21558 | } else if (typeof exports === 'object') { |
| 21559 | // Node. Does not work with strict CommonJS, but |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 21560 | // only CommonJS-like environments that support module.exports, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21561 | // like Node. |
| 21562 | module.exports = factory(require('b')); |
| 21563 | } else { |
| 21564 | // Browser globals |
| 21565 | root.SwaggerUi = factory(root.b); |
| 21566 | } |
| 21567 | }(this, function () { |
| 21568 | return SwaggerUi; |
| 21569 | })); |
| 21570 | |
| 21571 | 'use strict'; |
| 21572 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21573 | window.SwaggerUi.utils = { |
| 21574 | parseSecurityDefinitions: function (security) { |
| 21575 | var auths = Object.assign({}, window.swaggerUi.api.authSchemes || window.swaggerUi.api.securityDefinitions); |
| 21576 | var oauth2Arr = []; |
| 21577 | var authsArr = []; |
| 21578 | var scopes = []; |
| 21579 | var utils = window.SwaggerUi.utils; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21580 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21581 | if (!Array.isArray(security)) { return null; } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21582 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21583 | security.forEach(function (item) { |
| 21584 | var singleSecurity = {}; |
| 21585 | var singleOauth2Security = {}; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21586 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21587 | for (var key in item) { |
| 21588 | if (Array.isArray(item[key])) { |
| 21589 | if (!auths[key]) { continue; } |
| 21590 | auths[key] = auths[key] || {}; |
| 21591 | if (auths[key].type === 'oauth2') { |
| 21592 | singleOauth2Security[key] = Object.assign({}, auths[key]); |
| 21593 | singleOauth2Security[key].scopes = Object.assign({}, auths[key].scopes); |
| 21594 | for (var i in singleOauth2Security[key].scopes) { |
| 21595 | if (item[key].indexOf(i) < 0) { |
| 21596 | delete singleOauth2Security[key].scopes[i]; |
| 21597 | } |
| 21598 | } |
| 21599 | singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes); |
| 21600 | scopes = _.merge(scopes, singleOauth2Security[key].scopes); |
| 21601 | } else { |
| 21602 | singleSecurity[key] = Object.assign({}, auths[key]); |
| 21603 | } |
| 21604 | } else { |
| 21605 | if (item[key].type === 'oauth2') { |
| 21606 | singleOauth2Security[key] = Object.assign({}, item[key]); |
| 21607 | singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes); |
| 21608 | scopes = _.merge(scopes, singleOauth2Security[key].scopes); |
| 21609 | } else { |
| 21610 | singleSecurity[key] = item[key]; |
| 21611 | } |
| 21612 | } |
| 21613 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21614 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21615 | if (!_.isEmpty(singleSecurity)) { |
| 21616 | authsArr.push(singleSecurity); |
| 21617 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21618 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21619 | if (!_.isEmpty(singleOauth2Security)){ |
| 21620 | oauth2Arr.push(singleOauth2Security); |
| 21621 | } |
| 21622 | }); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21623 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21624 | return { |
| 21625 | auths : authsArr, |
| 21626 | oauth2: oauth2Arr, |
| 21627 | scopes: scopes |
| 21628 | }; |
| 21629 | }, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21630 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21631 | parseOauth2Scopes: function (data) { |
| 21632 | var scopes = Object.assign({}, data); |
| 21633 | var result = []; |
| 21634 | var key; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21635 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21636 | for (key in scopes) { |
| 21637 | result.push({scope: key, description: scopes[key]}); |
| 21638 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21639 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21640 | return result; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21641 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21642 | }; |
| 21643 | 'use strict'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21644 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21645 | SwaggerUi.Models.ApiKeyAuthModel = Backbone.Model.extend({ |
| 21646 | defaults: { |
| 21647 | 'in': '', |
| 21648 | name: '', |
| 21649 | title: '', |
| 21650 | value: '' |
| 21651 | }, |
| 21652 | |
| 21653 | initialize: function () { |
| 21654 | this.on('change', this.validate); |
| 21655 | }, |
| 21656 | |
| 21657 | validate: function () { |
| 21658 | var valid = !!this.get('value'); |
| 21659 | |
| 21660 | this.set('valid', valid); |
| 21661 | |
| 21662 | return valid; |
| 21663 | } |
| 21664 | }); |
| 21665 | 'use strict'; |
| 21666 | |
| 21667 | SwaggerUi.Views.ApiKeyAuthView = Backbone.View.extend({ // TODO: append this to global SwaggerUi |
| 21668 | |
| 21669 | events: { |
| 21670 | 'change .input_apiKey_entry': 'apiKeyChange' |
| 21671 | }, |
| 21672 | |
| 21673 | selectors: { |
| 21674 | apikeyInput: '.input_apiKey_entry' |
| 21675 | }, |
| 21676 | |
| 21677 | template: Handlebars.templates.apikey_auth, |
| 21678 | |
| 21679 | initialize: function(opts) { |
| 21680 | this.options = opts || {}; |
| 21681 | this.router = this.options.router; |
| 21682 | }, |
| 21683 | |
| 21684 | render: function (){ |
| 21685 | this.$el.html(this.template(this.model.toJSON())); |
| 21686 | |
| 21687 | return this; |
| 21688 | }, |
| 21689 | |
| 21690 | apiKeyChange: function (e) { |
| 21691 | var val = $(e.target).val(); |
| 21692 | if (val) { |
| 21693 | this.$(this.selectors.apikeyInput).removeClass('error'); |
| 21694 | } |
| 21695 | |
| 21696 | this.model.set('value', val); |
| 21697 | }, |
| 21698 | |
| 21699 | isValid: function () { |
| 21700 | return this.model.validate(); |
| 21701 | }, |
| 21702 | |
| 21703 | highlightInvalid: function () { |
| 21704 | if (!this.isValid()) { |
| 21705 | this.$(this.selectors.apikeyInput).addClass('error'); |
| 21706 | } |
| 21707 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21708 | |
| 21709 | }); |
| 21710 | 'use strict'; |
| 21711 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21712 | SwaggerUi.Views.AuthButtonView = Backbone.View.extend({ |
| 21713 | events: { |
| 21714 | 'click .authorize__btn': 'authorizeBtnClick' |
| 21715 | }, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21716 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21717 | tpls: { |
| 21718 | popup: Handlebars.templates.popup, |
| 21719 | authBtn: Handlebars.templates.auth_button, |
| 21720 | authBtnOperation: Handlebars.templates.auth_button_operation |
| 21721 | }, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21722 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21723 | initialize: function(opts) { |
| 21724 | this.options = opts || {}; |
| 21725 | this.options.data = this.options.data || {}; |
| 21726 | this.isOperation = this.options.isOperation; |
| 21727 | this.model = this.model || {}; |
| 21728 | this.router = this.options.router; |
| 21729 | this.auths = this.options.data.oauth2.concat(this.options.data.auths); |
| 21730 | }, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21731 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21732 | render: function () { |
| 21733 | var tplName = this.isOperation ? 'authBtnOperation' : 'authBtn'; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21734 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21735 | this.$authEl = this.renderAuths(this.auths); |
| 21736 | this.$el.html(this.tpls[tplName](this.model)); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21737 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21738 | return this; |
| 21739 | }, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21740 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21741 | authorizeBtnClick: function (e) { |
| 21742 | var authsModel; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21743 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21744 | e.preventDefault(); |
| 21745 | |
| 21746 | authsModel = { |
| 21747 | title: 'Available authorizations', |
| 21748 | content: this.$authEl |
| 21749 | }; |
| 21750 | |
| 21751 | // The content of the popup is removed and all events unbound after clicking the 'Cancel' button of the popup. |
| 21752 | // We'll have to re-render the contents before creating a new popup view. |
| 21753 | this.render(); |
| 21754 | |
| 21755 | this.popup = new SwaggerUi.Views.PopupView({model: authsModel}); |
| 21756 | this.popup.render(); |
| 21757 | }, |
| 21758 | |
| 21759 | renderAuths: function (auths) { |
| 21760 | var $el = $('<div>'); |
| 21761 | var isLogout = false; |
| 21762 | |
| 21763 | auths.forEach(function (auth) { |
| 21764 | var authView = new SwaggerUi.Views.AuthView({data: auth, router: this.router}); |
| 21765 | var authEl = authView.render().el; |
| 21766 | $el.append(authEl); |
| 21767 | if (authView.isLogout) { |
| 21768 | isLogout = true; |
| 21769 | } |
| 21770 | }, this); |
| 21771 | |
| 21772 | this.model.isLogout = isLogout; |
| 21773 | |
| 21774 | return $el; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21775 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 21776 | |
| 21777 | }); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 21778 | |
| 21779 | 'use strict'; |
| 21780 | |
| 21781 | SwaggerUi.Collections.AuthsCollection = Backbone.Collection.extend({ |
| 21782 | constructor: function() { |
| 21783 | var args = Array.prototype.slice.call(arguments); |
| 21784 | |
| 21785 | args[0] = this.parse(args[0]); |
| 21786 | |
| 21787 | Backbone.Collection.apply(this, args); |
| 21788 | }, |
| 21789 | |
| 21790 | add: function (model) { |
| 21791 | var args = Array.prototype.slice.call(arguments); |
| 21792 | |
| 21793 | if (Array.isArray(model)) { |
| 21794 | args[0] = _.map(model, function(val) { |
| 21795 | return this.handleOne(val); |
| 21796 | }, this); |
| 21797 | } else { |
| 21798 | args[0] = this.handleOne(model); |
| 21799 | } |
| 21800 | |
| 21801 | Backbone.Collection.prototype.add.apply(this, args); |
| 21802 | }, |
| 21803 | |
| 21804 | handleOne: function (model) { |
| 21805 | var result = model; |
| 21806 | |
| 21807 | if (! (model instanceof Backbone.Model) ) { |
| 21808 | switch (model.type) { |
| 21809 | case 'oauth2': |
| 21810 | result = new SwaggerUi.Models.Oauth2Model(model); |
| 21811 | break; |
| 21812 | case 'basic': |
| 21813 | result = new SwaggerUi.Models.BasicAuthModel(model); |
| 21814 | break; |
| 21815 | case 'apiKey': |
| 21816 | result = new SwaggerUi.Models.ApiKeyAuthModel(model); |
| 21817 | break; |
| 21818 | default: |
| 21819 | result = new Backbone.Model(model); |
| 21820 | } |
| 21821 | } |
| 21822 | |
| 21823 | return result; |
| 21824 | }, |
| 21825 | |
| 21826 | isValid: function () { |
| 21827 | var valid = true; |
| 21828 | |
| 21829 | this.models.forEach(function(model) { |
| 21830 | if (!model.validate()) { |
| 21831 | valid = false; |
| 21832 | } |
| 21833 | }); |
| 21834 | |
| 21835 | return valid; |
| 21836 | }, |
| 21837 | |
| 21838 | isAuthorized: function () { |
| 21839 | return this.length === this.where({ isLogout: true }).length; |
| 21840 | }, |
| 21841 | |
| 21842 | isPartiallyAuthorized: function () { |
| 21843 | return this.where({ isLogout: true }).length > 0; |
| 21844 | }, |
| 21845 | |
| 21846 | parse: function (data) { |
| 21847 | var authz = Object.assign({}, window.swaggerUi.api.clientAuthorizations.authz); |
| 21848 | |
| 21849 | return _.map(data, function (auth, name) { |
| 21850 | var isBasic = authz[name] && auth.type === 'basic' && authz[name].username && authz[name].password; |
| 21851 | |
| 21852 | _.extend(auth, { |
| 21853 | title: name |
| 21854 | }); |
| 21855 | |
| 21856 | if (authz[name] || isBasic) { |
| 21857 | _.extend(auth, { |
| 21858 | isLogout: true, |
| 21859 | value: isBasic ? undefined : authz[name].value, |
| 21860 | username: isBasic ? authz[name].username : undefined, |
| 21861 | password: isBasic ? authz[name].password : undefined, |
| 21862 | valid: true |
| 21863 | }); |
| 21864 | } |
| 21865 | |
| 21866 | return auth; |
| 21867 | }); |
| 21868 | } |
| 21869 | }); |
| 21870 | 'use strict'; |
| 21871 | |
| 21872 | SwaggerUi.Views.AuthsCollectionView = Backbone.View.extend({ |
| 21873 | |
| 21874 | initialize: function(opts) { |
| 21875 | this.options = opts || {}; |
| 21876 | this.options.data = this.options.data || {}; |
| 21877 | this.router = this.options.router; |
| 21878 | |
| 21879 | this.collection = new SwaggerUi.Collections.AuthsCollection(opts.data); |
| 21880 | |
| 21881 | this.$innerEl = $('<div>'); |
| 21882 | this.authViews = []; |
| 21883 | }, |
| 21884 | |
| 21885 | render: function () { |
| 21886 | this.collection.each(function (auth) { |
| 21887 | this.renderOneAuth(auth); |
| 21888 | }, this); |
| 21889 | |
| 21890 | this.$el.html(this.$innerEl.html() ? this.$innerEl : ''); |
| 21891 | |
| 21892 | return this; |
| 21893 | }, |
| 21894 | |
| 21895 | renderOneAuth: function (authModel) { |
| 21896 | var authViewEl, authView, authViewName; |
| 21897 | var type = authModel.get('type'); |
| 21898 | |
| 21899 | if (type === 'apiKey') { |
| 21900 | authViewName = 'ApiKeyAuthView'; |
| 21901 | } else if (type === 'basic' && this.$innerEl.find('.basic_auth_container').length === 0) { |
| 21902 | authViewName = 'BasicAuthView'; |
| 21903 | } else if (type === 'oauth2') { |
| 21904 | authViewName = 'Oauth2View'; |
| 21905 | } |
| 21906 | |
| 21907 | if (authViewName) { |
| 21908 | authView = new SwaggerUi.Views[authViewName]({model: authModel, router: this.router}); |
| 21909 | authViewEl = authView.render().el; |
| 21910 | this.authViews.push(authView); |
| 21911 | } |
| 21912 | |
| 21913 | this.$innerEl.append(authViewEl); |
| 21914 | }, |
| 21915 | |
| 21916 | highlightInvalid: function () { |
| 21917 | this.authViews.forEach(function (view) { |
| 21918 | view.highlightInvalid(); |
| 21919 | }, this); |
| 21920 | } |
| 21921 | |
| 21922 | }); |
| 21923 | |
| 21924 | 'use strict'; |
| 21925 | |
| 21926 | /* global redirect_uri:true */ |
| 21927 | /* global clientId */ |
| 21928 | /* global scopeSeparator */ |
| 21929 | /* global additionalQueryStringParams */ |
| 21930 | /* global clientSecret */ |
| 21931 | /* global onOAuthComplete */ |
| 21932 | /* global realm */ |
| 21933 | /*jshint unused:false*/ |
| 21934 | |
| 21935 | SwaggerUi.Views.AuthView = Backbone.View.extend({ |
| 21936 | events: { |
| 21937 | 'click .auth_submit__button': 'authorizeClick', |
| 21938 | 'click .auth_logout__button': 'logoutClick' |
| 21939 | }, |
| 21940 | |
| 21941 | tpls: { |
| 21942 | main: Handlebars.templates.auth_view |
| 21943 | }, |
| 21944 | |
| 21945 | selectors: { |
| 21946 | innerEl: '.auth_inner', |
| 21947 | authBtn: '.auth_submit__button' |
| 21948 | }, |
| 21949 | |
| 21950 | initialize: function(opts) { |
| 21951 | this.options = opts || {}; |
| 21952 | opts.data = opts.data || {}; |
| 21953 | this.router = this.options.router; |
| 21954 | |
| 21955 | this.authsCollectionView = new SwaggerUi.Views.AuthsCollectionView({data: opts.data}); |
| 21956 | |
| 21957 | this.$el.html(this.tpls.main({ |
| 21958 | isLogout: this.authsCollectionView.collection.isAuthorized(), |
| 21959 | isAuthorized: this.authsCollectionView.collection.isPartiallyAuthorized() |
| 21960 | })); |
| 21961 | this.$innerEl = this.$(this.selectors.innerEl); |
| 21962 | this.isLogout = this.authsCollectionView.collection.isPartiallyAuthorized(); |
| 21963 | }, |
| 21964 | |
| 21965 | render: function () { |
| 21966 | this.$innerEl.html(this.authsCollectionView.render().el); |
| 21967 | |
| 21968 | return this; |
| 21969 | }, |
| 21970 | |
| 21971 | authorizeClick: function (e) { |
| 21972 | e.preventDefault(); |
| 21973 | e.stopPropagation(); |
| 21974 | |
| 21975 | if (this.authsCollectionView.collection.isValid()) { |
| 21976 | this.authorize(); |
| 21977 | } else { |
| 21978 | this.authsCollectionView.highlightInvalid(); |
| 21979 | } |
| 21980 | }, |
| 21981 | |
| 21982 | authorize: function () { |
| 21983 | this.authsCollectionView.collection.forEach(function (auth) { |
| 21984 | var keyAuth, basicAuth; |
| 21985 | var type = auth.get('type'); |
| 21986 | |
| 21987 | if (type === 'apiKey') { |
| 21988 | keyAuth = new SwaggerClient.ApiKeyAuthorization( |
| 21989 | auth.get('name'), |
| 21990 | auth.get('value'), |
| 21991 | auth.get('in') |
| 21992 | ); |
| 21993 | |
| 21994 | this.router.api.clientAuthorizations.add(auth.get('title'), keyAuth); |
| 21995 | } else if (type === 'basic') { |
| 21996 | basicAuth = new SwaggerClient.PasswordAuthorization(auth.get('username'), auth.get('password')); |
| 21997 | this.router.api.clientAuthorizations.add(auth.get('title'), basicAuth); |
| 21998 | } else if (type === 'oauth2') { |
| 21999 | this.handleOauth2Login(auth); |
| 22000 | } |
| 22001 | }, this); |
| 22002 | |
| 22003 | this.router.load(); |
| 22004 | }, |
| 22005 | |
| 22006 | logoutClick: function (e) { |
| 22007 | e.preventDefault(); |
| 22008 | |
| 22009 | this.authsCollectionView.collection.forEach(function (auth) { |
| 22010 | window.swaggerUi.api.clientAuthorizations.remove(auth.get('title')); |
| 22011 | }); |
| 22012 | |
| 22013 | this.router.load(); |
| 22014 | }, |
| 22015 | |
| 22016 | // taken from lib/swagger-oauth.js |
| 22017 | handleOauth2Login: function (auth) { |
| 22018 | var host = window.location; |
| 22019 | var pathname = location.pathname.substring(0, location.pathname.lastIndexOf('/')); |
| 22020 | var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html'; |
| 22021 | var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl; |
| 22022 | var url = null; |
| 22023 | var scopes = _.map(auth.get('scopes'), function (scope) { |
| 22024 | return scope.scope; |
| 22025 | }); |
| 22026 | var state, dets, ep; |
| 22027 | window.OAuthSchemeKey = auth.get('title'); |
| 22028 | |
| 22029 | window.enabledScopes = scopes; |
| 22030 | var flow = auth.get('flow'); |
| 22031 | |
| 22032 | if(auth.get('type') === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) { |
| 22033 | dets = auth.attributes; |
| 22034 | url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code'); |
| 22035 | window.swaggerUi.tokenName = dets.tokenName || 'access_token'; |
| 22036 | window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null); |
| 22037 | state = window.OAuthSchemeKey; |
| 22038 | } |
| 22039 | else if(auth.get('type') === 'oauth2' && flow && (flow === 'application')) { |
| 22040 | dets = auth.attributes; |
| 22041 | window.swaggerUi.tokenName = dets.tokenName || 'access_token'; |
| 22042 | this.clientCredentialsFlow(scopes, dets.tokenUrl, window.OAuthSchemeKey); |
| 22043 | return; |
| 22044 | } |
| 22045 | else if(auth.get('grantTypes')) { |
| 22046 | // 1.2 support |
| 22047 | var o = auth.get('grantTypes'); |
| 22048 | for(var t in o) { |
| 22049 | if(o.hasOwnProperty(t) && t === 'implicit') { |
| 22050 | dets = o[t]; |
| 22051 | ep = dets.loginEndpoint.url; |
| 22052 | url = dets.loginEndpoint.url + '?response_type=token'; |
| 22053 | window.swaggerUi.tokenName = dets.tokenName; |
| 22054 | } |
| 22055 | else if (o.hasOwnProperty(t) && t === 'accessCode') { |
| 22056 | dets = o[t]; |
| 22057 | ep = dets.tokenRequestEndpoint.url; |
| 22058 | url = dets.tokenRequestEndpoint.url + '?response_type=code'; |
| 22059 | window.swaggerUi.tokenName = dets.tokenName; |
| 22060 | } |
| 22061 | } |
| 22062 | } |
| 22063 | |
| 22064 | redirect_uri = redirectUrl; |
| 22065 | |
| 22066 | url += '&redirect_uri=' + encodeURIComponent(redirectUrl); |
| 22067 | url += '&realm=' + encodeURIComponent(realm); |
| 22068 | url += '&client_id=' + encodeURIComponent(clientId); |
| 22069 | url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator)); |
| 22070 | url += '&state=' + encodeURIComponent(state); |
| 22071 | for (var key in additionalQueryStringParams) { |
| 22072 | url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]); |
| 22073 | } |
| 22074 | |
| 22075 | window.open(url); |
| 22076 | }, |
| 22077 | |
| 22078 | // taken from lib/swagger-oauth.js |
| 22079 | clientCredentialsFlow: function (scopes, tokenUrl, OAuthSchemeKey) { |
| 22080 | var params = { |
| 22081 | 'client_id': clientId, |
| 22082 | 'client_secret': clientSecret, |
| 22083 | 'scope': scopes.join(' '), |
| 22084 | 'grant_type': 'client_credentials' |
| 22085 | }; |
| 22086 | $.ajax({ |
| 22087 | url : tokenUrl, |
| 22088 | type: 'POST', |
| 22089 | data: params, |
| 22090 | success: function (data) |
| 22091 | { |
| 22092 | onOAuthComplete(data, OAuthSchemeKey); |
| 22093 | }, |
| 22094 | error: function () |
| 22095 | { |
| 22096 | onOAuthComplete(''); |
| 22097 | } |
| 22098 | }); |
| 22099 | } |
| 22100 | |
| 22101 | }); |
| 22102 | |
| 22103 | 'use strict'; |
| 22104 | |
| 22105 | SwaggerUi.Models.BasicAuthModel = Backbone.Model.extend({ |
| 22106 | defaults: { |
| 22107 | username: '', |
| 22108 | password: '', |
| 22109 | title: 'basic' |
| 22110 | }, |
| 22111 | |
| 22112 | initialize: function () { |
| 22113 | this.on('change', this.validate); |
| 22114 | }, |
| 22115 | |
| 22116 | validate: function () { |
| 22117 | var valid = !!this.get('password') && !!this.get('username'); |
| 22118 | |
| 22119 | this.set('valid', valid); |
| 22120 | |
| 22121 | return valid; |
| 22122 | } |
| 22123 | }); |
| 22124 | 'use strict'; |
| 22125 | |
| 22126 | SwaggerUi.Views.BasicAuthView = Backbone.View.extend({ |
| 22127 | |
| 22128 | initialize: function (opts) { |
| 22129 | this.options = opts || {}; |
| 22130 | this.router = this.options.router; |
| 22131 | }, |
| 22132 | |
| 22133 | events: { |
| 22134 | 'change .auth_input': 'inputChange' |
| 22135 | }, |
| 22136 | |
| 22137 | selectors: { |
| 22138 | usernameInput: '.basic_auth__username', |
| 22139 | passwordInput: '.basic_auth__password' |
| 22140 | }, |
| 22141 | |
| 22142 | cls: { |
| 22143 | error: 'error' |
| 22144 | }, |
| 22145 | |
| 22146 | template: Handlebars.templates.basic_auth, |
| 22147 | |
| 22148 | render: function(){ |
| 22149 | $(this.el).html(this.template(this.model.toJSON())); |
| 22150 | |
| 22151 | return this; |
| 22152 | }, |
| 22153 | |
| 22154 | inputChange: function (e) { |
| 22155 | var $el = $(e.target); |
| 22156 | var val = $el.val(); |
| 22157 | var attr = $el.prop('name'); |
| 22158 | |
| 22159 | if (val) { |
| 22160 | $el.removeClass(this.cls.error); |
| 22161 | } |
| 22162 | |
| 22163 | this.model.set(attr, val); |
| 22164 | }, |
| 22165 | |
| 22166 | isValid: function () { |
| 22167 | return this.model.validate(); |
| 22168 | }, |
| 22169 | |
| 22170 | highlightInvalid: function () { |
| 22171 | if (!this.model.get('username')) { |
| 22172 | this.$(this.selectors.usernameInput).addClass(this.cls.error); |
| 22173 | } |
| 22174 | } |
| 22175 | }); |
| 22176 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22177 | 'use strict'; |
| 22178 | |
| 22179 | SwaggerUi.Views.ContentTypeView = Backbone.View.extend({ |
| 22180 | initialize: function() {}, |
| 22181 | |
| 22182 | render: function(){ |
| 22183 | this.model.contentTypeId = 'ct' + Math.random(); |
| 22184 | $(this.el).html(Handlebars.templates.content_type(this.model)); |
| 22185 | return this; |
| 22186 | } |
| 22187 | }); |
| 22188 | 'use strict'; |
| 22189 | |
| 22190 | SwaggerUi.Views.HeaderView = Backbone.View.extend({ |
| 22191 | events: { |
| 22192 | 'click #show-pet-store-icon' : 'showPetStore', |
| 22193 | 'click #explore' : 'showCustom', |
| 22194 | 'keyup #input_baseUrl' : 'showCustomOnKeyup', |
| 22195 | 'keyup #input_apiKey' : 'showCustomOnKeyup' |
| 22196 | }, |
| 22197 | |
| 22198 | initialize: function(){}, |
| 22199 | |
| 22200 | showPetStore: function(){ |
| 22201 | this.trigger('update-swagger-ui', { |
| 22202 | url:'http://petstore.swagger.io/v2/swagger.json' |
| 22203 | }); |
| 22204 | }, |
| 22205 | |
| 22206 | showCustomOnKeyup: function(e){ |
| 22207 | if (e.keyCode === 13) { |
| 22208 | this.showCustom(); |
| 22209 | } |
| 22210 | }, |
| 22211 | |
| 22212 | showCustom: function(e){ |
| 22213 | if (e) { |
| 22214 | e.preventDefault(); |
| 22215 | } |
| 22216 | |
| 22217 | this.trigger('update-swagger-ui', { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22218 | url: $('#input_baseUrl').val() |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22219 | }); |
| 22220 | }, |
| 22221 | |
| 22222 | update: function(url, apiKey, trigger){ |
| 22223 | if (trigger === undefined) { |
| 22224 | trigger = false; |
| 22225 | } |
| 22226 | |
| 22227 | $('#input_baseUrl').val(url); |
| 22228 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22229 | if (trigger) { |
| 22230 | this.trigger('update-swagger-ui', {url:url}); |
| 22231 | } |
| 22232 | } |
| 22233 | }); |
| 22234 | |
| 22235 | 'use strict'; |
| 22236 | |
| 22237 | SwaggerUi.Views.MainView = Backbone.View.extend({ |
| 22238 | apisSorter : { |
| 22239 | alpha : function(a,b){ return a.name.localeCompare(b.name); } |
| 22240 | }, |
| 22241 | operationsSorters : { |
| 22242 | alpha : function(a,b){ return a.path.localeCompare(b.path); }, |
| 22243 | method : function(a,b){ return a.method.localeCompare(b.method); } |
| 22244 | }, |
| 22245 | initialize: function(opts){ |
| 22246 | var sorterOption, sorterFn, key, value; |
| 22247 | opts = opts || {}; |
| 22248 | |
| 22249 | this.router = opts.router; |
| 22250 | |
| 22251 | // Sort APIs |
| 22252 | if (opts.swaggerOptions.apisSorter) { |
| 22253 | sorterOption = opts.swaggerOptions.apisSorter; |
| 22254 | if (_.isFunction(sorterOption)) { |
| 22255 | sorterFn = sorterOption; |
| 22256 | } else { |
| 22257 | sorterFn = this.apisSorter[sorterOption]; |
| 22258 | } |
| 22259 | if (_.isFunction(sorterFn)) { |
| 22260 | this.model.apisArray.sort(sorterFn); |
| 22261 | } |
| 22262 | } |
| 22263 | // Sort operations of each API |
| 22264 | if (opts.swaggerOptions.operationsSorter) { |
| 22265 | sorterOption = opts.swaggerOptions.operationsSorter; |
| 22266 | if (_.isFunction(sorterOption)) { |
| 22267 | sorterFn = sorterOption; |
| 22268 | } else { |
| 22269 | sorterFn = this.operationsSorters[sorterOption]; |
| 22270 | } |
| 22271 | if (_.isFunction(sorterFn)) { |
| 22272 | for (key in this.model.apisArray) { |
| 22273 | this.model.apisArray[key].operationsArray.sort(sorterFn); |
| 22274 | } |
| 22275 | } |
| 22276 | } |
| 22277 | |
| 22278 | // set up the UI for input |
| 22279 | this.model.auths = []; |
| 22280 | |
| 22281 | for (key in this.model.securityDefinitions) { |
| 22282 | value = this.model.securityDefinitions[key]; |
| 22283 | |
| 22284 | this.model.auths.push({ |
| 22285 | name: key, |
| 22286 | type: value.type, |
| 22287 | value: value |
| 22288 | }); |
| 22289 | } |
| 22290 | |
| 22291 | if ('validatorUrl' in opts.swaggerOptions) { |
| 22292 | // Validator URL specified explicitly |
| 22293 | this.model.validatorUrl = opts.swaggerOptions.validatorUrl; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22294 | } else if (this.model.url.indexOf('localhost') > 0 || this.model.url.indexOf('127.0.0.1') > 0) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22295 | // Localhost override |
| 22296 | this.model.validatorUrl = null; |
| 22297 | } else { |
| 22298 | // Default validator |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22299 | if(window.location.protocol === 'https:') { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22300 | this.model.validatorUrl = 'https://online.swagger.io/validator'; |
| 22301 | } |
| 22302 | else { |
| 22303 | this.model.validatorUrl = 'http://online.swagger.io/validator'; |
| 22304 | } |
| 22305 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22306 | |
| 22307 | // JSonEditor requires type='object' to be present on defined types, we add it if it's missing |
| 22308 | // is there any valid case were it should not be added ? |
| 22309 | var def; |
| 22310 | for(def in this.model.definitions){ |
| 22311 | if (!this.model.definitions[def].type){ |
| 22312 | this.model.definitions[def].type = 'object'; |
| 22313 | } |
| 22314 | } |
| 22315 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22316 | }, |
| 22317 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22318 | render: function () { |
| 22319 | $(this.el).html(Handlebars.templates.main(this.model)); |
| 22320 | this.info = this.$('.info')[0]; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22321 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22322 | if (this.info) { |
| 22323 | this.info.addEventListener('click', this.onLinkClick, true); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22324 | } |
| 22325 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22326 | this.model.securityDefinitions = this.model.securityDefinitions || {}; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22327 | |
| 22328 | // Render each resource |
| 22329 | |
| 22330 | var resources = {}; |
| 22331 | var counter = 0; |
| 22332 | for (var i = 0; i < this.model.apisArray.length; i++) { |
| 22333 | var resource = this.model.apisArray[i]; |
| 22334 | var id = resource.name; |
| 22335 | while (typeof resources[id] !== 'undefined') { |
| 22336 | id = id + '_' + counter; |
| 22337 | counter += 1; |
| 22338 | } |
| 22339 | resource.id = id; |
| 22340 | resources[id] = resource; |
| 22341 | this.addResource(resource, this.model.auths); |
| 22342 | } |
| 22343 | |
| 22344 | $('.propWrap').hover(function onHover(){ |
| 22345 | $('.optionsWrapper', $(this)).show(); |
| 22346 | }, function offhover(){ |
| 22347 | $('.optionsWrapper', $(this)).hide(); |
| 22348 | }); |
| 22349 | return this; |
| 22350 | }, |
| 22351 | |
| 22352 | addResource: function(resource, auths){ |
| 22353 | // Render a resource and add it to resources li |
| 22354 | resource.id = resource.id.replace(/\s/g, '_'); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22355 | |
| 22356 | // Make all definitions available at the root of the resource so that they can |
| 22357 | // be loaded by the JSonEditor |
| 22358 | resource.definitions = this.model.definitions; |
| 22359 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22360 | var resourceView = new SwaggerUi.Views.ResourceView({ |
| 22361 | model: resource, |
| 22362 | router: this.router, |
| 22363 | tagName: 'li', |
| 22364 | id: 'resource_' + resource.id, |
| 22365 | className: 'resource', |
| 22366 | auths: auths, |
| 22367 | swaggerOptions: this.options.swaggerOptions |
| 22368 | }); |
| 22369 | $('#resources', this.el).append(resourceView.render().el); |
| 22370 | }, |
| 22371 | |
| 22372 | clear: function(){ |
| 22373 | $(this.el).html(''); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22374 | }, |
| 22375 | |
| 22376 | onLinkClick: function (e) { |
| 22377 | var el = e.target; |
| 22378 | |
| 22379 | if (el.tagName === 'A' && el.href && !el.target) { |
| 22380 | e.preventDefault(); |
| 22381 | window.open(el.href, '_blank'); |
| 22382 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22383 | } |
| 22384 | }); |
| 22385 | |
| 22386 | 'use strict'; |
| 22387 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22388 | SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({ |
| 22389 | defaults: { |
| 22390 | scopes: {} |
| 22391 | }, |
| 22392 | |
| 22393 | initialize: function () { |
| 22394 | this.on('change', this.validate); |
| 22395 | }, |
| 22396 | |
| 22397 | setScopes: function (name, val) { |
| 22398 | var auth = _.extend({}, this.attributes); |
| 22399 | var index = _.findIndex(auth.scopes, function(o) { |
| 22400 | return o.scope === name; |
| 22401 | }); |
| 22402 | auth.scopes[index].checked = val; |
| 22403 | |
| 22404 | this.set(auth); |
| 22405 | this.validate(); |
| 22406 | }, |
| 22407 | |
| 22408 | validate: function () { |
| 22409 | var valid = false; |
| 22410 | var scp = this.get('scopes'); |
| 22411 | var idx = _.findIndex(scp, function (o) { |
| 22412 | return o.checked === true; |
| 22413 | }); |
| 22414 | |
| 22415 | if(scp.length > 0 && idx >= 0) { |
| 22416 | valid = true; |
| 22417 | } |
| 22418 | |
| 22419 | if(scp.length === 0) { |
| 22420 | valid = true; |
| 22421 | } |
| 22422 | |
| 22423 | this.set('valid', valid); |
| 22424 | |
| 22425 | return valid; |
| 22426 | } |
| 22427 | }); |
| 22428 | |
| 22429 | 'use strict'; |
| 22430 | |
| 22431 | SwaggerUi.Views.Oauth2View = Backbone.View.extend({ |
| 22432 | events: { |
| 22433 | 'change .oauth-scope': 'scopeChange' |
| 22434 | }, |
| 22435 | |
| 22436 | template: Handlebars.templates.oauth2, |
| 22437 | |
| 22438 | render: function () { |
| 22439 | this.$el.html(this.template(this.model.toJSON())); |
| 22440 | |
| 22441 | return this; |
| 22442 | }, |
| 22443 | |
| 22444 | scopeChange: function (e) { |
| 22445 | var val = $(e.target).prop('checked'); |
| 22446 | var scope = $(e.target).data('scope'); |
| 22447 | |
| 22448 | this.model.setScopes(scope, val); |
| 22449 | } |
| 22450 | }); |
| 22451 | 'use strict'; |
| 22452 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22453 | SwaggerUi.Views.OperationView = Backbone.View.extend({ |
| 22454 | invocationUrl: null, |
| 22455 | |
| 22456 | events: { |
| 22457 | 'submit .sandbox' : 'submitOperation', |
| 22458 | 'click .submit' : 'submitOperation', |
| 22459 | 'click .response_hider' : 'hideResponse', |
| 22460 | 'click .toggleOperation' : 'toggleOperationContent', |
| 22461 | 'mouseenter .api-ic' : 'mouseEnter', |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22462 | 'dblclick .curl' : 'selectText', |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22463 | 'change [name=responseContentType]' : 'showSnippet' |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22464 | }, |
| 22465 | |
| 22466 | initialize: function(opts) { |
| 22467 | opts = opts || {}; |
| 22468 | this.router = opts.router; |
| 22469 | this.auths = opts.auths; |
| 22470 | this.parentId = this.model.parentId; |
| 22471 | this.nickname = this.model.nickname; |
| 22472 | this.model.encodedParentId = encodeURIComponent(this.parentId); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22473 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22474 | if (opts.swaggerOptions) { |
| 22475 | this.model.defaultRendering = opts.swaggerOptions.defaultModelRendering; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22476 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22477 | if (opts.swaggerOptions.showRequestHeaders) { |
| 22478 | this.model.showRequestHeaders = true; |
| 22479 | } |
| 22480 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22481 | return this; |
| 22482 | }, |
| 22483 | |
| 22484 | selectText: function(event) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22485 | var doc = document, |
| 22486 | text = event.target.firstChild, |
| 22487 | range, |
| 22488 | selection; |
| 22489 | if (doc.body.createTextRange) { |
| 22490 | range = document.body.createTextRange(); |
| 22491 | range.moveToElementText(text); |
| 22492 | range.select(); |
| 22493 | } else if (window.getSelection) { |
| 22494 | selection = window.getSelection(); |
| 22495 | range = document.createRange(); |
| 22496 | range.selectNodeContents(text); |
| 22497 | selection.removeAllRanges(); |
| 22498 | selection.addRange(range); |
| 22499 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22500 | }, |
| 22501 | |
| 22502 | mouseEnter: function(e) { |
| 22503 | var elem = $(this.el).find('.content'); |
| 22504 | var x = e.pageX; |
| 22505 | var y = e.pageY; |
| 22506 | var scX = $(window).scrollLeft(); |
| 22507 | var scY = $(window).scrollTop(); |
| 22508 | var scMaxX = scX + $(window).width(); |
| 22509 | var scMaxY = scY + $(window).height(); |
| 22510 | var wd = elem.width(); |
| 22511 | var hgh = elem.height(); |
| 22512 | |
| 22513 | if (x + wd > scMaxX) { |
| 22514 | x = scMaxX - wd; |
| 22515 | } |
| 22516 | |
| 22517 | if (x < scX) { |
| 22518 | x = scX; |
| 22519 | } |
| 22520 | |
| 22521 | if (y + hgh > scMaxY) { |
| 22522 | y = scMaxY - hgh; |
| 22523 | } |
| 22524 | |
| 22525 | if (y < scY) { |
| 22526 | y = scY; |
| 22527 | } |
| 22528 | |
| 22529 | var pos = {}; |
| 22530 | pos.top = y; |
| 22531 | pos.left = x; |
| 22532 | elem.css(pos); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22533 | }, |
| 22534 | |
| 22535 | // Note: copied from CoffeeScript compiled file |
| 22536 | // TODO: redactor |
| 22537 | render: function() { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22538 | 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; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22539 | isMethodSubmissionSupported = jQuery.inArray(this.model.method, this.model.supportedSubmitMethods()) >= 0; |
| 22540 | if (!isMethodSubmissionSupported) { |
| 22541 | this.model.isReadOnly = true; |
| 22542 | } |
| 22543 | this.model.description = this.model.description || this.model.notes; |
| 22544 | this.model.oauth = null; |
| 22545 | modelAuths = this.model.authorizations || this.model.security; |
| 22546 | if (modelAuths) { |
| 22547 | if (Array.isArray(modelAuths)) { |
| 22548 | for (l = 0, len = modelAuths.length; l < len; l++) { |
| 22549 | auths = modelAuths[l]; |
| 22550 | for (key in auths) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22551 | for (a in this.auths) { |
| 22552 | auth = this.auths[a]; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22553 | if (key === auth.name) { |
| 22554 | if (auth.type === 'oauth2') { |
| 22555 | this.model.oauth = {}; |
| 22556 | this.model.oauth.scopes = []; |
| 22557 | ref1 = auth.value.scopes; |
| 22558 | for (k in ref1) { |
| 22559 | v = ref1[k]; |
| 22560 | scopeIndex = auths[key].indexOf(k); |
| 22561 | if (scopeIndex >= 0) { |
| 22562 | o = { |
| 22563 | scope: k, |
| 22564 | description: v |
| 22565 | }; |
| 22566 | this.model.oauth.scopes.push(o); |
| 22567 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22568 | } |
| 22569 | } |
| 22570 | } |
| 22571 | } |
| 22572 | } |
| 22573 | } |
| 22574 | } else { |
| 22575 | for (k in modelAuths) { |
| 22576 | v = modelAuths[k]; |
| 22577 | if (k === 'oauth2') { |
| 22578 | if (this.model.oauth === null) { |
| 22579 | this.model.oauth = {}; |
| 22580 | } |
| 22581 | if (this.model.oauth.scopes === void 0) { |
| 22582 | this.model.oauth.scopes = []; |
| 22583 | } |
| 22584 | for (m = 0, len1 = v.length; m < len1; m++) { |
| 22585 | o = v[m]; |
| 22586 | this.model.oauth.scopes.push(o); |
| 22587 | } |
| 22588 | } |
| 22589 | } |
| 22590 | } |
| 22591 | } |
| 22592 | if (typeof this.model.responses !== 'undefined') { |
| 22593 | this.model.responseMessages = []; |
| 22594 | ref2 = this.model.responses; |
| 22595 | for (code in ref2) { |
| 22596 | value = ref2[code]; |
| 22597 | schema = null; |
| 22598 | schemaObj = this.model.responses[code].schema; |
| 22599 | if (schemaObj && schemaObj.$ref) { |
| 22600 | schema = schemaObj.$ref; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22601 | if (schema.indexOf('#/definitions/') !== -1) { |
| 22602 | schema = schema.replace(/^.*#\/definitions\//, ''); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22603 | } |
| 22604 | } |
| 22605 | this.model.responseMessages.push({ |
| 22606 | code: code, |
| 22607 | message: value.description, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22608 | responseModel: schema, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22609 | headers: value.headers, |
| 22610 | schema: schemaObj |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22611 | }); |
| 22612 | } |
| 22613 | } |
| 22614 | if (typeof this.model.responseMessages === 'undefined') { |
| 22615 | this.model.responseMessages = []; |
| 22616 | } |
| 22617 | signatureModel = null; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22618 | produces = this.model.produces; |
| 22619 | isXML = this.contains(produces, 'xml'); |
| 22620 | isJSON = isXML ? this.contains(produces, 'json') : true; |
| 22621 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22622 | if (this.model.successResponse) { |
| 22623 | successResponse = this.model.successResponse; |
| 22624 | for (key in successResponse) { |
| 22625 | value = successResponse[key]; |
| 22626 | this.model.successCode = key; |
| 22627 | if (typeof value === 'object' && typeof value.createJSONSample === 'function') { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22628 | this.model.successDescription = value.description; |
| 22629 | this.model.headers = this.parseResponseHeaders(value.headers); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22630 | signatureModel = { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22631 | sampleJSON: isJSON ? JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2) : false, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22632 | isParam: false, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22633 | sampleXML: isXML ? SwaggerUi.partials.signature.createXMLSample(value.name, value.definition, value.models) : false, |
| 22634 | signature: SwaggerUi.partials.signature.getModelSignature(value.name, value.definition, value.models, value.modelPropertyMacro) |
| 22635 | }; |
| 22636 | } else { |
| 22637 | signatureModel = { |
| 22638 | signature: SwaggerUi.partials.signature.getPrimitiveSignature(value) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22639 | }; |
| 22640 | } |
| 22641 | } |
| 22642 | } else if (this.model.responseClassSignature && this.model.responseClassSignature !== 'string') { |
| 22643 | signatureModel = { |
| 22644 | sampleJSON: this.model.responseSampleJSON, |
| 22645 | isParam: false, |
| 22646 | signature: this.model.responseClassSignature |
| 22647 | }; |
| 22648 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22649 | $(this.el).html(Handlebars.templates.operation(this.model)); |
| 22650 | if (signatureModel) { |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22651 | signatureModel.defaultRendering = this.model.defaultRendering; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22652 | responseSignatureView = new SwaggerUi.Views.SignatureView({ |
| 22653 | model: signatureModel, |
| 22654 | router: this.router, |
| 22655 | tagName: 'div' |
| 22656 | }); |
| 22657 | $('.model-signature', $(this.el)).append(responseSignatureView.render().el); |
| 22658 | } else { |
| 22659 | this.model.responseClassSignature = 'string'; |
| 22660 | $('.model-signature', $(this.el)).html(this.model.type); |
| 22661 | } |
| 22662 | contentTypeModel = { |
| 22663 | isParam: false |
| 22664 | }; |
| 22665 | contentTypeModel.consumes = this.model.consumes; |
| 22666 | contentTypeModel.produces = this.model.produces; |
| 22667 | ref3 = this.model.parameters; |
| 22668 | for (n = 0, len2 = ref3.length; n < len2; n++) { |
| 22669 | param = ref3[n]; |
| 22670 | type = param.type || param.dataType || ''; |
| 22671 | if (typeof type === 'undefined') { |
| 22672 | schema = param.schema; |
| 22673 | if (schema && schema.$ref) { |
| 22674 | ref = schema.$ref; |
| 22675 | if (ref.indexOf('#/definitions/') === 0) { |
| 22676 | type = ref.substring('#/definitions/'.length); |
| 22677 | } else { |
| 22678 | type = ref; |
| 22679 | } |
| 22680 | } |
| 22681 | } |
| 22682 | if (type && type.toLowerCase() === 'file') { |
| 22683 | if (!contentTypeModel.consumes) { |
| 22684 | contentTypeModel.consumes = 'multipart/form-data'; |
| 22685 | } |
| 22686 | } |
| 22687 | param.type = type; |
| 22688 | } |
| 22689 | responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({ |
| 22690 | model: contentTypeModel, |
| 22691 | router: this.router |
| 22692 | }); |
| 22693 | $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el); |
| 22694 | ref4 = this.model.parameters; |
| 22695 | for (p = 0, len3 = ref4.length; p < len3; p++) { |
| 22696 | param = ref4[p]; |
| 22697 | this.addParameter(param, contentTypeModel.consumes); |
| 22698 | } |
| 22699 | ref5 = this.model.responseMessages; |
| 22700 | for (q = 0, len4 = ref5.length; q < len4; q++) { |
| 22701 | statusCode = ref5[q]; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22702 | statusCode.isXML = isXML; |
| 22703 | statusCode.isJSON = isJSON; |
| 22704 | if (!_.isUndefined(statusCode.headers)) { |
| 22705 | statusCode.headers = this.parseHeadersType(statusCode.headers); |
| 22706 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22707 | this.addStatusCode(statusCode); |
| 22708 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22709 | |
| 22710 | if (Array.isArray(this.model.security)) { |
| 22711 | var authsModel = SwaggerUi.utils.parseSecurityDefinitions(this.model.security); |
| 22712 | |
| 22713 | authsModel.isLogout = !_.isEmpty(window.swaggerUi.api.clientAuthorizations.authz); |
| 22714 | this.authView = new SwaggerUi.Views.AuthButtonView({ |
| 22715 | data: authsModel, |
| 22716 | router: this.router, |
| 22717 | isOperation: true, |
| 22718 | model: { |
| 22719 | scopes: authsModel.scopes |
| 22720 | } |
| 22721 | }); |
| 22722 | this.$('.authorize-wrapper').append(this.authView.render().el); |
| 22723 | } |
| 22724 | |
| 22725 | this.showSnippet(); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22726 | return this; |
| 22727 | }, |
| 22728 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22729 | parseHeadersType: function (headers) { |
| 22730 | var map = { |
| 22731 | 'string': { |
| 22732 | 'date-time': 'dateTime', |
| 22733 | 'date' : 'date' |
| 22734 | } |
| 22735 | }; |
| 22736 | |
| 22737 | _.forEach(headers, function (header) { |
| 22738 | var value; |
| 22739 | header = header || {}; |
| 22740 | value = map[header.type] && map[header.type][header.format]; |
| 22741 | if (!_.isUndefined(value)) { |
| 22742 | header.type = value; |
| 22743 | } |
| 22744 | }); |
| 22745 | |
| 22746 | return headers; |
| 22747 | }, |
| 22748 | |
| 22749 | contains: function (produces, type) { |
| 22750 | return produces.filter(function (val) { |
| 22751 | if (val.indexOf(type) > -1) { |
| 22752 | return true; |
| 22753 | } |
| 22754 | }).length; |
| 22755 | }, |
| 22756 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22757 | parseResponseHeaders: function (data) { |
| 22758 | var HEADERS_SEPARATOR = '; '; |
| 22759 | var headers = _.clone(data); |
| 22760 | |
| 22761 | _.forEach(headers, function (header) { |
| 22762 | var other = []; |
| 22763 | _.forEach(header, function (value, key) { |
| 22764 | var properties = ['type', 'description']; |
| 22765 | if (properties.indexOf(key.toLowerCase()) === -1) { |
| 22766 | other.push(key + ': ' + value); |
| 22767 | } |
| 22768 | }); |
| 22769 | |
| 22770 | other.join(HEADERS_SEPARATOR); |
| 22771 | header.other = other; |
| 22772 | }); |
| 22773 | |
| 22774 | return headers; |
| 22775 | }, |
| 22776 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22777 | addParameter: function(param, consumes) { |
| 22778 | // Render a parameter |
| 22779 | param.consumes = consumes; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22780 | param.defaultRendering = this.model.defaultRendering; |
| 22781 | |
| 22782 | // Copy this param JSON spec so that it will be available for JsonEditor |
| 22783 | if(param.schema){ |
| 22784 | $.extend(true, param.schema, this.model.definitions[param.type]); |
| 22785 | param.schema.definitions = this.model.definitions; |
| 22786 | // This is required for JsonEditor to display the root properly |
| 22787 | if(!param.schema.type){ |
| 22788 | param.schema.type = 'object'; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22789 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22790 | // This is the title that will be used by JsonEditor for the root |
| 22791 | // Since we already display the parameter's name in the Parameter column |
| 22792 | // We set this to space, we can't set it to null or space otherwise JsonEditor |
| 22793 | // will replace it with the text "root" which won't look good on screen |
| 22794 | if(!param.schema.title){ |
| 22795 | param.schema.title = ' '; |
| 22796 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22797 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22798 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22799 | var paramView = new SwaggerUi.Views.ParameterView({ |
| 22800 | model: param, |
| 22801 | tagName: 'tr', |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22802 | readOnly: this.model.isReadOnly, |
| 22803 | swaggerOptions: this.options.swaggerOptions |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22804 | }); |
| 22805 | $('.operation-params', $(this.el)).append(paramView.render().el); |
| 22806 | }, |
| 22807 | |
| 22808 | addStatusCode: function(statusCode) { |
| 22809 | // Render status codes |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22810 | statusCode.defaultRendering = this.model.defaultRendering; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22811 | var statusCodeView = new SwaggerUi.Views.StatusCodeView({ |
| 22812 | model: statusCode, |
| 22813 | tagName: 'tr', |
| 22814 | router: this.router |
| 22815 | }); |
| 22816 | $('.operation-status', $(this.el)).append(statusCodeView.render().el); |
| 22817 | }, |
| 22818 | |
| 22819 | // Note: copied from CoffeeScript compiled file |
| 22820 | // TODO: redactor |
| 22821 | submitOperation: function(e) { |
| 22822 | var error_free, form, isFileUpload, map, opts; |
| 22823 | if (e !== null) { |
| 22824 | e.preventDefault(); |
| 22825 | } |
| 22826 | form = $('.sandbox', $(this.el)); |
| 22827 | error_free = true; |
| 22828 | form.find('input.required').each(function() { |
| 22829 | $(this).removeClass('error'); |
| 22830 | if (jQuery.trim($(this).val()) === '') { |
| 22831 | $(this).addClass('error'); |
| 22832 | $(this).wiggle({ |
| 22833 | callback: (function(_this) { |
| 22834 | return function() { |
| 22835 | $(_this).focus(); |
| 22836 | }; |
| 22837 | })(this) |
| 22838 | }); |
| 22839 | error_free = false; |
| 22840 | } |
| 22841 | }); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22842 | form.find('textarea.required:visible').each(function() { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22843 | $(this).removeClass('error'); |
| 22844 | if (jQuery.trim($(this).val()) === '') { |
| 22845 | $(this).addClass('error'); |
| 22846 | $(this).wiggle({ |
| 22847 | callback: (function(_this) { |
| 22848 | return function() { |
| 22849 | return $(_this).focus(); |
| 22850 | }; |
| 22851 | })(this) |
| 22852 | }); |
| 22853 | error_free = false; |
| 22854 | } |
| 22855 | }); |
| 22856 | form.find('select.required').each(function() { |
| 22857 | $(this).removeClass('error'); |
| 22858 | if (this.selectedIndex === -1) { |
| 22859 | $(this).addClass('error'); |
| 22860 | $(this).wiggle({ |
| 22861 | callback: (function(_this) { |
| 22862 | return function() { |
| 22863 | $(_this).focus(); |
| 22864 | }; |
| 22865 | })(this) |
| 22866 | }); |
| 22867 | error_free = false; |
| 22868 | } |
| 22869 | }); |
| 22870 | if (error_free) { |
| 22871 | map = this.getInputMap(form); |
| 22872 | isFileUpload = this.isFileUpload(form); |
| 22873 | opts = { |
| 22874 | parent: this |
| 22875 | }; |
| 22876 | if (this.options.swaggerOptions) { |
| 22877 | for(var key in this.options.swaggerOptions) { |
| 22878 | opts[key] = this.options.swaggerOptions[key]; |
| 22879 | } |
| 22880 | } |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22881 | |
| 22882 | var pi; |
| 22883 | for(pi = 0; pi < this.model.parameters.length; pi++){ |
| 22884 | var p = this.model.parameters[pi]; |
| 22885 | if( p.jsonEditor && p.jsonEditor.isEnabled()){ |
| 22886 | var json = p.jsonEditor.getValue(); |
| 22887 | map[p.name] = JSON.stringify(json); |
| 22888 | } |
| 22889 | } |
| 22890 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22891 | opts.responseContentType = $('div select[name=responseContentType]', $(this.el)).val(); |
| 22892 | opts.requestContentType = $('div select[name=parameterContentType]', $(this.el)).val(); |
| 22893 | $('.response_throbber', $(this.el)).show(); |
| 22894 | if (isFileUpload) { |
| 22895 | $('.request_url', $(this.el)).html('<pre></pre>'); |
| 22896 | $('.request_url pre', $(this.el)).text(this.invocationUrl); |
| 22897 | |
| 22898 | opts.useJQuery = true; |
| 22899 | map.parameterContentType = 'multipart/form-data'; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 22900 | this.map = map; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22901 | return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this); |
| 22902 | } else { |
| 22903 | this.map = map; |
| 22904 | return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this); |
| 22905 | } |
| 22906 | } |
| 22907 | }, |
| 22908 | |
| 22909 | getInputMap: function (form) { |
| 22910 | var map, ref1, l, len, o, ref2, m, len1, val, ref3, n, len2; |
| 22911 | map = {}; |
| 22912 | ref1 = form.find('input'); |
| 22913 | for (l = 0, len = ref1.length; l < len; l++) { |
| 22914 | o = ref1[l]; |
| 22915 | if ((o.value !== null) && jQuery.trim(o.value).length > 0) { |
| 22916 | map[o.name] = o.value; |
| 22917 | } |
| 22918 | if (o.type === 'file') { |
| 22919 | map[o.name] = o.files[0]; |
| 22920 | } |
| 22921 | } |
| 22922 | ref2 = form.find('textarea'); |
| 22923 | for (m = 0, len1 = ref2.length; m < len1; m++) { |
| 22924 | o = ref2[m]; |
| 22925 | val = this.getTextAreaValue(o); |
| 22926 | if ((val !== null) && jQuery.trim(val).length > 0) { |
| 22927 | map[o.name] = val; |
| 22928 | } |
| 22929 | } |
| 22930 | ref3 = form.find('select'); |
| 22931 | for (n = 0, len2 = ref3.length; n < len2; n++) { |
| 22932 | o = ref3[n]; |
| 22933 | val = this.getSelectedValue(o); |
| 22934 | if ((val !== null) && jQuery.trim(val).length > 0) { |
| 22935 | map[o.name] = val; |
| 22936 | } |
| 22937 | } |
| 22938 | return map; |
| 22939 | }, |
| 22940 | |
| 22941 | isFileUpload: function (form) { |
| 22942 | var ref1, l, len, o; |
| 22943 | var isFileUpload = false; |
| 22944 | ref1 = form.find('input'); |
| 22945 | for (l = 0, len = ref1.length; l < len; l++) { |
| 22946 | o = ref1[l]; |
| 22947 | if (o.type === 'file') { |
| 22948 | isFileUpload = true; |
| 22949 | } |
| 22950 | } |
| 22951 | return isFileUpload; |
| 22952 | }, |
| 22953 | |
| 22954 | success: function(response, parent) { |
| 22955 | parent.showCompleteStatus(response); |
| 22956 | }, |
| 22957 | |
| 22958 | // wraps a jquery response as a shred response |
| 22959 | wrap: function(data) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 22960 | var h, headerArray, headers, i, l, len, o; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 22961 | headers = {}; |
| 22962 | headerArray = data.getAllResponseHeaders().split('\r'); |
| 22963 | for (l = 0, len = headerArray.length; l < len; l++) { |
| 22964 | i = headerArray[l]; |
| 22965 | h = i.match(/^([^:]*?):(.*)$/); |
| 22966 | if (!h) { |
| 22967 | h = []; |
| 22968 | } |
| 22969 | h.shift(); |
| 22970 | if (h[0] !== void 0 && h[1] !== void 0) { |
| 22971 | headers[h[0].trim()] = h[1].trim(); |
| 22972 | } |
| 22973 | } |
| 22974 | o = {}; |
| 22975 | o.content = {}; |
| 22976 | o.content.data = data.responseText; |
| 22977 | o.headers = headers; |
| 22978 | o.request = {}; |
| 22979 | o.request.url = this.invocationUrl; |
| 22980 | o.status = data.status; |
| 22981 | return o; |
| 22982 | }, |
| 22983 | |
| 22984 | getSelectedValue: function(select) { |
| 22985 | if (!select.multiple) { |
| 22986 | return select.value; |
| 22987 | } else { |
| 22988 | var options = []; |
| 22989 | for (var l = 0, len = select.options.length; l < len; l++) { |
| 22990 | var opt = select.options[l]; |
| 22991 | if (opt.selected) { |
| 22992 | options.push(opt.value); |
| 22993 | } |
| 22994 | } |
| 22995 | if (options.length > 0) { |
| 22996 | return options; |
| 22997 | } else { |
| 22998 | return null; |
| 22999 | } |
| 23000 | } |
| 23001 | }, |
| 23002 | |
| 23003 | // handler for hide response link |
| 23004 | hideResponse: function(e) { |
| 23005 | if (e) { e.preventDefault(); } |
| 23006 | $('.response', $(this.el)).slideUp(); |
| 23007 | $('.response_hider', $(this.el)).fadeOut(); |
| 23008 | }, |
| 23009 | |
| 23010 | // Show response from server |
| 23011 | showResponse: function(response) { |
| 23012 | var prettyJson = JSON.stringify(response, null, '\t').replace(/\n/g, '<br>'); |
| 23013 | $('.response_body', $(this.el)).html(_.escape(prettyJson)); |
| 23014 | }, |
| 23015 | |
| 23016 | // Show error from server |
| 23017 | showErrorStatus: function(data, parent) { |
| 23018 | parent.showStatus(data); |
| 23019 | }, |
| 23020 | |
| 23021 | // show the status codes |
| 23022 | showCompleteStatus: function(data, parent){ |
| 23023 | parent.showStatus(data); |
| 23024 | }, |
| 23025 | |
| 23026 | // Adapted from http://stackoverflow.com/a/2893259/454004 |
| 23027 | // Note: directly ported from CoffeeScript |
| 23028 | // TODO: Cleanup CoffeeScript artifacts |
| 23029 | formatXml: function(xml) { |
| 23030 | var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp; |
| 23031 | reg = /(>)(<)(\/*)/g; |
| 23032 | wsexp = /[ ]*(.*)[ ]+\n/g; |
| 23033 | contexp = /(<.+>)(.+\n)/g; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23034 | xml = xml.replace(/\r\n/g, '\n').replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23035 | pad = 0; |
| 23036 | formatted = ''; |
| 23037 | lines = xml.split('\n'); |
| 23038 | indent = 0; |
| 23039 | lastType = 'other'; |
| 23040 | transitions = { |
| 23041 | 'single->single': 0, |
| 23042 | 'single->closing': -1, |
| 23043 | 'single->opening': 0, |
| 23044 | 'single->other': 0, |
| 23045 | 'closing->single': 0, |
| 23046 | 'closing->closing': -1, |
| 23047 | 'closing->opening': 0, |
| 23048 | 'closing->other': 0, |
| 23049 | 'opening->single': 1, |
| 23050 | 'opening->closing': 0, |
| 23051 | 'opening->opening': 1, |
| 23052 | 'opening->other': 1, |
| 23053 | 'other->single': 0, |
| 23054 | 'other->closing': -1, |
| 23055 | 'other->opening': 0, |
| 23056 | 'other->other': 0 |
| 23057 | }; |
| 23058 | fn = function(ln) { |
| 23059 | var fromTo, j, key, padding, type, types, value; |
| 23060 | types = { |
| 23061 | single: Boolean(ln.match(/<.+\/>/)), |
| 23062 | closing: Boolean(ln.match(/<\/.+>/)), |
| 23063 | opening: Boolean(ln.match(/<[^!?].*>/)) |
| 23064 | }; |
| 23065 | type = ((function() { |
| 23066 | var results; |
| 23067 | results = []; |
| 23068 | for (key in types) { |
| 23069 | value = types[key]; |
| 23070 | if (value) { |
| 23071 | results.push(key); |
| 23072 | } |
| 23073 | } |
| 23074 | return results; |
| 23075 | })())[0]; |
| 23076 | type = type === void 0 ? 'other' : type; |
| 23077 | fromTo = lastType + '->' + type; |
| 23078 | lastType = type; |
| 23079 | padding = ''; |
| 23080 | indent += transitions[fromTo]; |
| 23081 | padding = ((function() { |
| 23082 | var m, ref1, results; |
| 23083 | results = []; |
| 23084 | for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) { |
| 23085 | results.push(' '); |
| 23086 | } |
| 23087 | return results; |
| 23088 | })()).join(''); |
| 23089 | if (fromTo === 'opening->closing') { |
| 23090 | formatted = formatted.substr(0, formatted.length - 1) + ln + '\n'; |
| 23091 | } else { |
| 23092 | formatted += padding + ln + '\n'; |
| 23093 | } |
| 23094 | }; |
| 23095 | for (l = 0, len = lines.length; l < len; l++) { |
| 23096 | ln = lines[l]; |
| 23097 | fn(ln); |
| 23098 | } |
| 23099 | return formatted; |
| 23100 | }, |
| 23101 | |
| 23102 | // puts the response data in UI |
| 23103 | showStatus: function(response) { |
| 23104 | var url, content; |
| 23105 | if (response.content === undefined) { |
| 23106 | content = response.data; |
| 23107 | url = response.url; |
| 23108 | } else { |
| 23109 | content = response.content.data; |
| 23110 | url = response.request.url; |
| 23111 | } |
| 23112 | var headers = response.headers; |
| 23113 | content = jQuery.trim(content); |
| 23114 | |
| 23115 | // if server is nice, and sends content-type back, we can use it |
| 23116 | var contentType = null; |
| 23117 | if (headers) { |
| 23118 | contentType = headers['Content-Type'] || headers['content-type']; |
| 23119 | if (contentType) { |
| 23120 | contentType = contentType.split(';')[0].trim(); |
| 23121 | } |
| 23122 | } |
| 23123 | $('.response_body', $(this.el)).removeClass('json'); |
| 23124 | $('.response_body', $(this.el)).removeClass('xml'); |
| 23125 | |
| 23126 | var supportsAudioPlayback = function(contentType){ |
| 23127 | var audioElement = document.createElement('audio'); |
| 23128 | return !!(audioElement.canPlayType && audioElement.canPlayType(contentType).replace(/no/, '')); |
| 23129 | }; |
| 23130 | |
| 23131 | var pre; |
| 23132 | var code; |
| 23133 | if (!content) { |
| 23134 | code = $('<code />').text('no content'); |
| 23135 | pre = $('<pre class="json" />').append(code); |
| 23136 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23137 | // JSON |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23138 | } else if (contentType === 'application/json' || /\+json$/.test(contentType)) { |
| 23139 | var json = null; |
| 23140 | try { |
| 23141 | json = JSON.stringify(JSON.parse(content), null, ' '); |
| 23142 | } catch (_error) { |
| 23143 | json = 'can\'t parse JSON. Raw result:\n\n' + content; |
| 23144 | } |
| 23145 | code = $('<code />').text(json); |
| 23146 | pre = $('<pre class="json" />').append(code); |
| 23147 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23148 | // XML |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23149 | } else if (contentType === 'application/xml' || /\+xml$/.test(contentType)) { |
| 23150 | code = $('<code />').text(this.formatXml(content)); |
| 23151 | pre = $('<pre class="xml" />').append(code); |
| 23152 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23153 | // HTML |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23154 | } else if (contentType === 'text/html') { |
| 23155 | code = $('<code />').html(_.escape(content)); |
| 23156 | pre = $('<pre class="xml" />').append(code); |
| 23157 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23158 | // Plain Text |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23159 | } else if (/text\/plain/.test(contentType)) { |
| 23160 | code = $('<code />').text(content); |
| 23161 | pre = $('<pre class="plain" />').append(code); |
| 23162 | |
| 23163 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23164 | // Image |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23165 | } else if (/^image\//.test(contentType)) { |
| 23166 | pre = $('<img>').attr('src', url); |
| 23167 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23168 | // Audio |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23169 | } else if (/^audio\//.test(contentType) && supportsAudioPlayback(contentType)) { |
| 23170 | pre = $('<audio controls>').append($('<source>').attr('src', url).attr('type', contentType)); |
| 23171 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23172 | // Download |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23173 | } else if (headers['Content-Disposition'] && (/attachment/).test(headers['Content-Disposition']) || |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23174 | headers['content-disposition'] && (/attachment/).test(headers['content-disposition']) || |
| 23175 | headers['Content-Description'] && (/File Transfer/).test(headers['Content-Description']) || |
| 23176 | headers['content-description'] && (/File Transfer/).test(headers['content-description'])) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23177 | |
| 23178 | if ('Blob' in window) { |
| 23179 | var type = contentType || 'text/html'; |
| 23180 | var blob = new Blob([content], {type: type}); |
| 23181 | var a = document.createElement('a'); |
| 23182 | var href = window.URL.createObjectURL(blob); |
| 23183 | var fileName = response.url.substr(response.url.lastIndexOf('/') + 1); |
| 23184 | var download = [type, fileName, href].join(':'); |
| 23185 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23186 | // Use filename from response header |
| 23187 | var disposition = headers['content-disposition'] || headers['Content-Disposition']; |
| 23188 | if(typeof disposition !== 'undefined') { |
| 23189 | var responseFilename = /filename=([^;]*);?/.exec(disposition); |
| 23190 | if(responseFilename !== null && responseFilename.length > 1) { |
| 23191 | download = responseFilename[1]; |
| 23192 | } |
| 23193 | } |
| 23194 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23195 | a.setAttribute('href', href); |
| 23196 | a.setAttribute('download', download); |
| 23197 | a.innerText = 'Download ' + fileName; |
| 23198 | |
| 23199 | pre = $('<div/>').append(a); |
| 23200 | } else { |
| 23201 | pre = $('<pre class="json" />').append('Download headers detected but your browser does not support downloading binary via XHR (Blob).'); |
| 23202 | } |
| 23203 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23204 | // Location header based redirect download |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23205 | } else if(headers.location || headers.Location) { |
| 23206 | window.location = response.url; |
| 23207 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23208 | // Anything else (CORS) |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23209 | } else { |
| 23210 | code = $('<code />').text(content); |
| 23211 | pre = $('<pre class="json" />').append(code); |
| 23212 | } |
| 23213 | var response_body = pre; |
| 23214 | $('.request_url', $(this.el)).html('<pre></pre>'); |
| 23215 | $('.request_url pre', $(this.el)).text(url); |
| 23216 | $('.response_code', $(this.el)).html('<pre>' + response.status + '</pre>'); |
| 23217 | $('.response_body', $(this.el)).html(response_body); |
| 23218 | $('.response_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(response.headers, null, ' ')).replace(/\n/g, '<br>') + '</pre>'); |
| 23219 | $('.response', $(this.el)).slideDown(); |
| 23220 | $('.response_hider', $(this.el)).show(); |
| 23221 | $('.response_throbber', $(this.el)).hide(); |
| 23222 | |
| 23223 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 23224 | // adds curl output |
| 23225 | var curlCommand = this.model.asCurl(this.map, {responseContentType: contentType}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23226 | curlCommand = curlCommand.replace('!', '!'); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23227 | $( 'div.curl', $(this.el)).html('<pre>' + _.escape(curlCommand) + '</pre>'); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23228 | |
| 23229 | // only highlight the response if response is less than threshold, default state is highlight response |
| 23230 | var opts = this.options.swaggerOptions; |
| 23231 | |
| 23232 | if (opts.showRequestHeaders) { |
| 23233 | var form = $('.sandbox', $(this.el)), |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23234 | map = this.getInputMap(form), |
| 23235 | requestHeaders = this.model.getHeaderParams(map); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23236 | delete requestHeaders['Content-Type']; |
| 23237 | $('.request_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(requestHeaders, null, ' ')).replace(/\n/g, '<br>') + '</pre>'); |
| 23238 | } |
| 23239 | |
| 23240 | var response_body_el = $('.response_body', $(this.el))[0]; |
| 23241 | // only highlight the response if response is less than threshold, default state is highlight response |
| 23242 | if (opts.highlightSizeThreshold && typeof response.data !== 'undefined' && response.data.length > opts.highlightSizeThreshold) { |
| 23243 | return response_body_el; |
| 23244 | } else { |
| 23245 | return hljs.highlightBlock(response_body_el); |
| 23246 | } |
| 23247 | }, |
| 23248 | |
| 23249 | toggleOperationContent: function (event) { |
| 23250 | var elem = $('#' + Docs.escapeResourceName(this.parentId + '_' + this.nickname + '_content')); |
| 23251 | if (elem.is(':visible')){ |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23252 | $.bbq.pushState('#/', 2); |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 23253 | event.preventDefault(); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23254 | Docs.collapseOperation(elem); |
| 23255 | } else { |
| 23256 | Docs.expandOperation(elem); |
| 23257 | } |
| 23258 | }, |
| 23259 | |
| 23260 | getTextAreaValue: function(textArea) { |
| 23261 | var param, parsed, result, i; |
| 23262 | if (textArea.value === null || jQuery.trim(textArea.value).length === 0) { |
| 23263 | return null; |
| 23264 | } |
| 23265 | param = this.getParamByName(textArea.name); |
| 23266 | if (param && param.type && param.type.toLowerCase() === 'array') { |
| 23267 | parsed = textArea.value.split('\n'); |
| 23268 | result = []; |
| 23269 | for (i = 0; i < parsed.length; i++) { |
| 23270 | if (parsed[i] !== null && jQuery.trim(parsed[i]).length > 0) { |
| 23271 | result.push(parsed[i]); |
| 23272 | } |
| 23273 | } |
| 23274 | return result.length > 0 ? result : null; |
| 23275 | } else { |
| 23276 | return textArea.value; |
| 23277 | } |
| 23278 | }, |
| 23279 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23280 | showSnippet: function () { |
| 23281 | var contentTypeEl = this.$('[name=responseContentType]'); |
| 23282 | var xmlSnippetEl = this.$('.operation-status .snippet_xml, .response-class .snippet_xml'); |
| 23283 | var jsonSnippetEl = this.$('.operation-status .snippet_json, .response-class .snippet_json'); |
| 23284 | var contentType; |
| 23285 | |
| 23286 | if (!contentTypeEl.length) { return; } |
| 23287 | contentType = contentTypeEl.val(); |
| 23288 | |
| 23289 | if (contentType.indexOf('xml') > -1) { |
| 23290 | xmlSnippetEl.show(); |
| 23291 | jsonSnippetEl.hide(); |
| 23292 | } else { |
| 23293 | jsonSnippetEl.show(); |
| 23294 | xmlSnippetEl.hide(); |
| 23295 | } |
| 23296 | }, |
| 23297 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23298 | getParamByName: function(name) { |
| 23299 | var i; |
| 23300 | if (this.model.parameters) { |
| 23301 | for(i = 0; i < this.model.parameters.length; i++) { |
| 23302 | if (this.model.parameters[i].name === name) { |
| 23303 | return this.model.parameters[i]; |
| 23304 | } |
| 23305 | } |
| 23306 | } |
| 23307 | return null; |
| 23308 | } |
| 23309 | |
| 23310 | }); |
| 23311 | |
| 23312 | 'use strict'; |
| 23313 | |
| 23314 | SwaggerUi.Views.ParameterContentTypeView = Backbone.View.extend({ |
| 23315 | initialize: function () {}, |
| 23316 | |
| 23317 | render: function(){ |
| 23318 | this.model.parameterContentTypeId = 'pct' + Math.random(); |
| 23319 | $(this.el).html(Handlebars.templates.parameter_content_type(this.model)); |
| 23320 | return this; |
| 23321 | } |
| 23322 | |
| 23323 | }); |
| 23324 | 'use strict'; |
| 23325 | |
| 23326 | SwaggerUi.Views.ParameterView = Backbone.View.extend({ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23327 | events: { |
| 23328 | 'change [name=parameterContentType]' : 'toggleParameterSnippet' |
| 23329 | }, |
| 23330 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23331 | initialize: function(){ |
| 23332 | Handlebars.registerHelper('isArray', function(param, opts) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23333 | var paramType = param.type && param.type.toLowerCase(); |
| 23334 | if (paramType === 'array' || param.allowMultiple) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23335 | return opts.fn(this); |
| 23336 | } else { |
| 23337 | return opts.inverse(this); |
| 23338 | } |
| 23339 | }); |
| 23340 | }, |
| 23341 | |
| 23342 | render: function() { |
| 23343 | var type = this.model.type || this.model.dataType; |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23344 | var modelType = this.model.modelSignature.type; |
| 23345 | var modelDefinitions = this.model.modelSignature.definitions; |
| 23346 | var schema = this.model.schema || {}; |
| 23347 | var consumes = this.model.consumes || []; |
| 23348 | var sampleJSON, signatureView; |
| 23349 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23350 | |
| 23351 | if (typeof type === 'undefined') { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23352 | if (schema.$ref) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23353 | var ref = schema.$ref; |
| 23354 | if (ref.indexOf('#/definitions/') === 0) { |
| 23355 | type = ref.substring('#/definitions/'.length); |
| 23356 | } else { |
| 23357 | type = ref; |
| 23358 | } |
| 23359 | } |
| 23360 | } |
| 23361 | |
| 23362 | this.model.type = type; |
| 23363 | this.model.paramType = this.model.in || this.model.paramType; |
| 23364 | this.model.isBody = this.model.paramType === 'body' || this.model.in === 'body'; |
| 23365 | this.model.isFile = type && type.toLowerCase() === 'file'; |
| 23366 | |
| 23367 | // Allow for default === false |
| 23368 | if(typeof this.model.default === 'undefined') { |
| 23369 | this.model.default = this.model.defaultValue; |
| 23370 | } |
| 23371 | |
| 23372 | this.model.hasDefault = (typeof this.model.default !== 'undefined'); |
| 23373 | this.model.valueId = 'm' + this.model.name + Math.random(); |
| 23374 | |
| 23375 | if (this.model.allowableValues) { |
| 23376 | this.model.isList = true; |
| 23377 | } |
| 23378 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23379 | var isXML = this.contains(consumes, 'xml'); |
| 23380 | var isJSON = isXML ? this.contains(consumes, 'json') : true; |
| 23381 | sampleJSON = SwaggerUi.partials.signature.createParameterJSONSample(modelType, modelDefinitions); |
| 23382 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23383 | var template = this.template(); |
| 23384 | $(this.el).html(template(this.model)); |
| 23385 | |
| 23386 | var signatureModel = { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23387 | sampleJSON: isJSON ? sampleJSON : false, |
| 23388 | sampleXML: sampleJSON && isXML ? SwaggerUi.partials.signature.createXMLSample('', schema, modelDefinitions, true) : false, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23389 | isParam: true, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23390 | signature: SwaggerUi.partials.signature.getParameterModelSignature(modelType, modelDefinitions), |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 23391 | defaultRendering: this.model.defaultRendering |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23392 | }; |
| 23393 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23394 | if (sampleJSON) { |
| 23395 | signatureView = new SwaggerUi.Views.SignatureView({model: signatureModel, tagName: 'div'}); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23396 | $('.model-signature', $(this.el)).append(signatureView.render().el); |
| 23397 | } |
| 23398 | else { |
| 23399 | $('.model-signature', $(this.el)).html(this.model.signature); |
| 23400 | } |
| 23401 | |
| 23402 | var isParam = false; |
| 23403 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 23404 | if( this.options.swaggerOptions.jsonEditor && this.model.isBody && this.model.schema){ |
| 23405 | var $self = $(this.el); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23406 | this.model.jsonEditor = |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 23407 | /* global JSONEditor */ |
| 23408 | new JSONEditor($('.editor_holder', $self)[0], |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23409 | {schema: this.model.schema, startval : this.model.default, |
| 23410 | ajax:true, |
| 23411 | disable_properties:true, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 23412 | disable_edit_json:true, |
| 23413 | iconlib: 'swagger' }); |
| 23414 | // This is so that the signature can send back the sample to the json editor |
| 23415 | // TODO: SignatureView should expose an event "onSampleClicked" instead |
| 23416 | signatureModel.jsonEditor = this.model.jsonEditor; |
| 23417 | $('.body-textarea', $self).hide(); |
| 23418 | $('.editor_holder', $self).show(); |
| 23419 | $('.parameter-content-type', $self) |
| 23420 | .change(function(e){ |
| 23421 | if(e.target.value === 'application/xml'){ |
| 23422 | $('.body-textarea', $self).show(); |
| 23423 | $('.editor_holder', $self).hide(); |
| 23424 | this.model.jsonEditor.disable(); |
| 23425 | } |
| 23426 | else { |
| 23427 | $('.body-textarea', $self).hide(); |
| 23428 | $('.editor_holder', $self).show(); |
| 23429 | this.model.jsonEditor.enable(); |
| 23430 | } |
| 23431 | }); |
| 23432 | } |
| 23433 | |
| 23434 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23435 | if (this.model.isBody) { |
| 23436 | isParam = true; |
| 23437 | } |
| 23438 | |
| 23439 | var contentTypeModel = { |
| 23440 | isParam: isParam |
| 23441 | }; |
| 23442 | |
| 23443 | contentTypeModel.consumes = this.model.consumes; |
| 23444 | |
| 23445 | if (isParam) { |
| 23446 | var parameterContentTypeView = new SwaggerUi.Views.ParameterContentTypeView({model: contentTypeModel}); |
| 23447 | $('.parameter-content-type', $(this.el)).append(parameterContentTypeView.render().el); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23448 | this.toggleParameterSnippet(); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23449 | } |
| 23450 | |
| 23451 | else { |
| 23452 | var responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({model: contentTypeModel}); |
| 23453 | $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23454 | this.toggleResponseSnippet(); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23455 | } |
| 23456 | |
| 23457 | return this; |
| 23458 | }, |
| 23459 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23460 | contains: function (consumes, type) { |
| 23461 | return consumes.filter(function (val) { |
| 23462 | if (val.indexOf(type) > -1) { |
| 23463 | return true; |
| 23464 | } |
| 23465 | }).length; |
| 23466 | }, |
| 23467 | |
| 23468 | toggleParameterSnippet: function () { |
| 23469 | var contentType = this.$('[name=parameterContentType]').val(); |
| 23470 | |
| 23471 | this.toggleSnippet(contentType); |
| 23472 | }, |
| 23473 | |
| 23474 | toggleResponseSnippet: function () { |
| 23475 | var contentEl = this.$('[name=responseContentType]'); |
| 23476 | |
| 23477 | if (!contentEl.length) { return; } |
| 23478 | |
| 23479 | this.toggleSnippet(contentEl.val()); |
| 23480 | }, |
| 23481 | |
| 23482 | toggleSnippet: function (type) { |
| 23483 | type = type || ''; |
| 23484 | if (type.indexOf('xml') > -1) { |
| 23485 | this.$('.snippet_xml').show(); |
| 23486 | this.$('.snippet_json').hide(); |
| 23487 | } else { |
| 23488 | this.$('.snippet_json').show(); |
| 23489 | this.$('.snippet_xml').hide(); |
| 23490 | } |
| 23491 | }, |
| 23492 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 23493 | // Return an appropriate template based on if the parameter is a list, readonly, required |
| 23494 | template: function(){ |
| 23495 | if (this.model.isList) { |
| 23496 | return Handlebars.templates.param_list; |
| 23497 | } else { |
| 23498 | if (this.options.readOnly) { |
| 23499 | if (this.model.required) { |
| 23500 | return Handlebars.templates.param_readonly_required; |
| 23501 | } else { |
| 23502 | return Handlebars.templates.param_readonly; |
| 23503 | } |
| 23504 | } else { |
| 23505 | if (this.model.required) { |
| 23506 | return Handlebars.templates.param_required; |
| 23507 | } else { |
| 23508 | return Handlebars.templates.param; |
| 23509 | } |
| 23510 | } |
| 23511 | } |
| 23512 | } |
| 23513 | }); |
| 23514 | |
| 23515 | 'use strict'; |
| 23516 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 23517 | /* jshint -W122 */ |
| 23518 | SwaggerUi.partials.signature = (function () { |
| 23519 | // copy-pasted from swagger-js |
| 23520 | var resolveSchema = function (schema) { |
| 23521 | if (_.isPlainObject(schema.schema)) { |
| 23522 | schema = resolveSchema(schema.schema); |
| 23523 | } |
| 23524 | |
| 23525 | return schema; |
| 23526 | }; |
| 23527 | |
| 23528 | // copy-pasted from swagger-js |
| 23529 | var simpleRef = function (name) { |
| 23530 | if (typeof name === 'undefined') { |
| 23531 | return null; |
| 23532 | } |
| 23533 | |
| 23534 | if (name.indexOf('#/definitions/') === 0) { |
| 23535 | return name.substring('#/definitions/'.length); |
| 23536 | } else { |
| 23537 | return name; |
| 23538 | } |
| 23539 | }; |
| 23540 | |
| 23541 | // copy-pasted from swagger-js |
| 23542 | var getInlineModel = function(inlineStr) { |
| 23543 | if(/^Inline Model \d+$/.test(inlineStr) && this.inlineModels) { |
| 23544 | var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); // |
| 23545 | var model = this.inlineModels[id]; |
| 23546 | return model; |
| 23547 | } |
| 23548 | // I'm returning null here, should I rather throw an error? |
| 23549 | return null; |
| 23550 | }; |
| 23551 | |
| 23552 | // copy-pasted from swagger-js |
| 23553 | var formatXml = function(xml) { |
| 23554 | var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp; |
| 23555 | reg = /(>)(<)(\/*)/g; |
| 23556 | wsexp = /[ ]*(.*)[ ]+\n/g; |
| 23557 | contexp = /(<.+>)(.+\n)/g; |
| 23558 | xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2'); |
| 23559 | pad = 0; |
| 23560 | formatted = ''; |
| 23561 | lines = xml.split('\n'); |
| 23562 | indent = 0; |
| 23563 | lastType = 'other'; |
| 23564 | transitions = { |
| 23565 | 'single->single': 0, |
| 23566 | 'single->closing': -1, |
| 23567 | 'single->opening': 0, |
| 23568 | 'single->other': 0, |
| 23569 | 'closing->single': 0, |
| 23570 | 'closing->closing': -1, |
| 23571 | 'closing->opening': 0, |
| 23572 | 'closing->other': 0, |
| 23573 | 'opening->single': 1, |
| 23574 | 'opening->closing': 0, |
| 23575 | 'opening->opening': 1, |
| 23576 | 'opening->other': 1, |
| 23577 | 'other->single': 0, |
| 23578 | 'other->closing': -1, |
| 23579 | 'other->opening': 0, |
| 23580 | 'other->other': 0 |
| 23581 | }; |
| 23582 | fn = function(ln) { |
| 23583 | var fromTo, j, key, padding, type, types, value; |
| 23584 | types = { |
| 23585 | single: Boolean(ln.match(/<.+\/>/)), |
| 23586 | closing: Boolean(ln.match(/<\/.+>/)), |
| 23587 | opening: Boolean(ln.match(/<[^!?].*>/)) |
| 23588 | }; |
| 23589 | type = ((function() { |
| 23590 | var results; |
| 23591 | results = []; |
| 23592 | for (key in types) { |
| 23593 | value = types[key]; |
| 23594 | if (value) { |
| 23595 | results.push(key); |
| 23596 | } |
| 23597 | } |
| 23598 | return results; |
| 23599 | })())[0]; |
| 23600 | type = type === void 0 ? 'other' : type; |
| 23601 | fromTo = lastType + '->' + type; |
| 23602 | lastType = type; |
| 23603 | padding = ''; |
| 23604 | indent += transitions[fromTo]; |
| 23605 | padding = ((function() { |
| 23606 | var m, ref1, results; |
| 23607 | results = []; |
| 23608 | for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) { |
| 23609 | results.push(' '); |
| 23610 | } |
| 23611 | return results; |
| 23612 | })()).join(''); |
| 23613 | if (fromTo === 'opening->closing') { |
| 23614 | formatted = formatted.substr(0, formatted.length - 1) + ln + '\n'; |
| 23615 | } else { |
| 23616 | formatted += padding + ln + '\n'; |
| 23617 | } |
| 23618 | }; |
| 23619 | for (l = 0, len = lines.length; l < len; l++) { |
| 23620 | ln = lines[l]; |
| 23621 | fn(ln); |
| 23622 | } |
| 23623 | return formatted; |
| 23624 | }; |
| 23625 | |
| 23626 | // copy-pasted from swagger-js |
| 23627 | var getModelSignature = function (name, schema, models, modelPropertyMacro) { |
| 23628 | var strongOpen = '<span class="strong">'; |
| 23629 | var strongClose = '</span>'; |
| 23630 | |
| 23631 | var optionHtml = function (label, value) { |
| 23632 | return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>'; |
| 23633 | }; |
| 23634 | |
| 23635 | |
| 23636 | // Allow for ignoring the 'name' argument.... shifting the rest |
| 23637 | if(_.isObject(arguments[0])) { |
| 23638 | name = void 0; |
| 23639 | schema = arguments[0]; |
| 23640 | models = arguments[1]; |
| 23641 | modelPropertyMacro = arguments[2]; |
| 23642 | } |
| 23643 | |
| 23644 | models = models || {}; |
| 23645 | |
| 23646 | // Resolve the schema (Handle nested schemas) |
| 23647 | schema = resolveSchema(schema); |
| 23648 | |
| 23649 | // Return for empty object |
| 23650 | if(_.isEmpty(schema)) { |
| 23651 | return strongOpen + 'Empty' + strongClose; |
| 23652 | } |
| 23653 | |
| 23654 | // Dereference $ref from 'models' |
| 23655 | if(typeof schema.$ref === 'string') { |
| 23656 | name = simpleRef(schema.$ref); |
| 23657 | schema = models[name]; |
| 23658 | if(typeof schema === 'undefined') |
| 23659 | { |
| 23660 | return strongOpen + name + ' is not defined!' + strongClose; |
| 23661 | } |
| 23662 | } |
| 23663 | |
| 23664 | if(typeof name !== 'string') { |
| 23665 | name = schema.title || 'Inline Model'; |
| 23666 | } |
| 23667 | |
| 23668 | // If we are a Model object... adjust accordingly |
| 23669 | if(schema.definition) { |
| 23670 | schema = schema.definition; |
| 23671 | } |
| 23672 | |
| 23673 | if(typeof modelPropertyMacro !== 'function') { |
| 23674 | modelPropertyMacro = function(prop){ |
| 23675 | return (prop || {}).default; |
| 23676 | }; |
| 23677 | } |
| 23678 | |
| 23679 | var references = {}; |
| 23680 | var seenModels = []; |
| 23681 | var inlineModels = 0; |
| 23682 | |
| 23683 | // Generate current HTML |
| 23684 | var html = processModel(schema, name); |
| 23685 | |
| 23686 | // Generate references HTML |
| 23687 | while (_.keys(references).length > 0) { |
| 23688 | /* jshint ignore:start */ |
| 23689 | _.forEach(references, function (schema, name) { |
| 23690 | var seenModel = _.indexOf(seenModels, name) > -1; |
| 23691 | |
| 23692 | delete references[name]; |
| 23693 | |
| 23694 | if (!seenModel) { |
| 23695 | seenModels.push(name); |
| 23696 | |
| 23697 | html += '<br />' + processModel(schema, name); |
| 23698 | } |
| 23699 | }); |
| 23700 | /* jshint ignore:end */ |
| 23701 | } |
| 23702 | |
| 23703 | return html; |
| 23704 | |
| 23705 | |
| 23706 | function addReference(schema, name, skipRef) { |
| 23707 | var modelName = name; |
| 23708 | var model; |
| 23709 | |
| 23710 | if (schema.$ref) { |
| 23711 | modelName = schema.title || simpleRef(schema.$ref); |
| 23712 | model = models[simpleRef(schema.$ref)]; |
| 23713 | } else if (_.isUndefined(name)) { |
| 23714 | modelName = schema.title || 'Inline Model ' + (++inlineModels); |
| 23715 | model = {definition: schema}; |
| 23716 | } |
| 23717 | |
| 23718 | if (skipRef !== true) { |
| 23719 | references[modelName] = _.isUndefined(model) ? {} : model.definition; |
| 23720 | } |
| 23721 | |
| 23722 | return modelName; |
| 23723 | } |
| 23724 | |
| 23725 | function primitiveToHTML(schema) { |
| 23726 | var html = '<span class="propType">'; |
| 23727 | var type = schema.type || 'object'; |
| 23728 | |
| 23729 | if (schema.$ref) { |
| 23730 | html += addReference(schema, simpleRef(schema.$ref)); |
| 23731 | } else if (type === 'object') { |
| 23732 | if (!_.isUndefined(schema.properties)) { |
| 23733 | html += addReference(schema); |
| 23734 | } else { |
| 23735 | html += 'object'; |
| 23736 | } |
| 23737 | } else if (type === 'array') { |
| 23738 | html += 'Array['; |
| 23739 | |
| 23740 | if (_.isArray(schema.items)) { |
| 23741 | html += _.map(schema.items, addReference).join(','); |
| 23742 | } else if (_.isPlainObject(schema.items)) { |
| 23743 | if (_.isUndefined(schema.items.$ref)) { |
| 23744 | if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) { |
| 23745 | html += schema.items.type; |
| 23746 | } else { |
| 23747 | html += addReference(schema.items); |
| 23748 | } |
| 23749 | } else { |
| 23750 | html += addReference(schema.items, simpleRef(schema.items.$ref)); |
| 23751 | } |
| 23752 | } else { |
| 23753 | console.log('Array type\'s \'items\' schema is not an array or an object, cannot process'); |
| 23754 | html += 'object'; |
| 23755 | } |
| 23756 | |
| 23757 | html += ']'; |
| 23758 | } else { |
| 23759 | html += schema.type; |
| 23760 | } |
| 23761 | |
| 23762 | html += '</span>'; |
| 23763 | |
| 23764 | return html; |
| 23765 | } |
| 23766 | |
| 23767 | function primitiveToOptionsHTML(schema, html) { |
| 23768 | var options = ''; |
| 23769 | var type = schema.type || 'object'; |
| 23770 | var isArray = type === 'array'; |
| 23771 | |
| 23772 | if (!_.isUndefined(schema.description)) { |
| 23773 | html += ': ' + '<span class="propDesc">' + schema.description + '</span>'; |
| 23774 | } |
| 23775 | |
| 23776 | if (schema.enum) { |
| 23777 | html += ' = <span class="propVals">[\'' + schema.enum.join('\', \'') + '\']</span>'; |
| 23778 | } |
| 23779 | |
| 23780 | if (isArray) { |
| 23781 | if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) { |
| 23782 | type = schema.items.type; |
| 23783 | } else { |
| 23784 | type = 'object'; |
| 23785 | } |
| 23786 | } |
| 23787 | |
| 23788 | if (!_.isUndefined(schema.default)) { |
| 23789 | options += optionHtml('Default', schema.default); |
| 23790 | } |
| 23791 | |
| 23792 | switch (type) { |
| 23793 | case 'string': |
| 23794 | if (schema.minLength) { |
| 23795 | options += optionHtml('Min. Length', schema.minLength); |
| 23796 | } |
| 23797 | |
| 23798 | if (schema.maxLength) { |
| 23799 | options += optionHtml('Max. Length', schema.maxLength); |
| 23800 | } |
| 23801 | |
| 23802 | if (schema.pattern) { |
| 23803 | options += optionHtml('Reg. Exp.', schema.pattern); |
| 23804 | } |
| 23805 | break; |
| 23806 | case 'integer': |
| 23807 | case 'number': |
| 23808 | if (schema.minimum) { |
| 23809 | options += optionHtml('Min. Value', schema.minimum); |
| 23810 | } |
| 23811 | |
| 23812 | if (schema.exclusiveMinimum) { |
| 23813 | options += optionHtml('Exclusive Min.', 'true'); |
| 23814 | } |
| 23815 | |
| 23816 | if (schema.maximum) { |
| 23817 | options += optionHtml('Max. Value', schema.maximum); |
| 23818 | } |
| 23819 | |
| 23820 | if (schema.exclusiveMaximum) { |
| 23821 | options += optionHtml('Exclusive Max.', 'true'); |
| 23822 | } |
| 23823 | |
| 23824 | if (schema.multipleOf) { |
| 23825 | options += optionHtml('Multiple Of', schema.multipleOf); |
| 23826 | } |
| 23827 | |
| 23828 | break; |
| 23829 | } |
| 23830 | |
| 23831 | if (isArray) { |
| 23832 | if (schema.minItems) { |
| 23833 | options += optionHtml('Min. Items', schema.minItems); |
| 23834 | } |
| 23835 | |
| 23836 | if (schema.maxItems) { |
| 23837 | options += optionHtml('Max. Items', schema.maxItems); |
| 23838 | } |
| 23839 | |
| 23840 | if (schema.uniqueItems) { |
| 23841 | options += optionHtml('Unique Items', 'true'); |
| 23842 | } |
| 23843 | |
| 23844 | if (schema.collectionFormat) { |
| 23845 | options += optionHtml('Coll. Format', schema.collectionFormat); |
| 23846 | } |
| 23847 | } |
| 23848 | |
| 23849 | if (_.isUndefined(schema.items)) { |
| 23850 | if (_.isArray(schema.enum)) { |
| 23851 | var enumString; |
| 23852 | |
| 23853 | if (type === 'number' || type === 'integer') { |
| 23854 | enumString = schema.enum.join(', '); |
| 23855 | } else { |
| 23856 | enumString = '"' + schema.enum.join('", "') + '"'; |
| 23857 | } |
| 23858 | |
| 23859 | options += optionHtml('Enum', enumString); |
| 23860 | } |
| 23861 | } |
| 23862 | |
| 23863 | if (options.length > 0) { |
| 23864 | html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>'; |
| 23865 | } |
| 23866 | |
| 23867 | return html; |
| 23868 | } |
| 23869 | |
| 23870 | function processModel(schema, name) { |
| 23871 | var type = schema.type || 'object'; |
| 23872 | var isArray = schema.type === 'array'; |
| 23873 | var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose; |
| 23874 | var contents; |
| 23875 | |
| 23876 | if (name) { |
| 23877 | seenModels.push(name); |
| 23878 | } |
| 23879 | |
| 23880 | if (isArray) { |
| 23881 | if (_.isArray(schema.items)) { |
| 23882 | html += '<div>' + _.map(schema.items, function (item) { |
| 23883 | var type = item.type || 'object'; |
| 23884 | |
| 23885 | if (_.isUndefined(item.$ref)) { |
| 23886 | if (_.indexOf(['array', 'object'], type) > -1) { |
| 23887 | if (type === 'object' && _.isUndefined(item.properties)) { |
| 23888 | return 'object'; |
| 23889 | } else { |
| 23890 | return addReference(item); |
| 23891 | } |
| 23892 | } else { |
| 23893 | return primitiveToOptionsHTML(item, type); |
| 23894 | } |
| 23895 | } else { |
| 23896 | return addReference(item, simpleRef(item.$ref)); |
| 23897 | } |
| 23898 | }).join(',</div><div>'); |
| 23899 | } else if (_.isPlainObject(schema.items)) { |
| 23900 | if (_.isUndefined(schema.items.$ref)) { |
| 23901 | if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) { |
| 23902 | if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) { |
| 23903 | html += '<div>object</div>'; |
| 23904 | } else { |
| 23905 | html += '<div>' + addReference(schema.items) + '</div>'; |
| 23906 | } |
| 23907 | } else { |
| 23908 | html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>'; |
| 23909 | } |
| 23910 | } else { |
| 23911 | html += '<div>' + addReference(schema.items, simpleRef(schema.items.$ref)) + '</div>'; |
| 23912 | } |
| 23913 | } else { |
| 23914 | console.log('Array type\'s \'items\' property is not an array or an object, cannot process'); |
| 23915 | html += '<div>object</div>'; |
| 23916 | } |
| 23917 | } else { |
| 23918 | if (schema.$ref) { |
| 23919 | html += '<div>' + addReference(schema, name) + '</div>'; |
| 23920 | } else if (type === 'object') { |
| 23921 | if (_.isPlainObject(schema.properties)) { |
| 23922 | contents = _.map(schema.properties, function (property, name) { |
| 23923 | var propertyIsRequired = (_.indexOf(schema.required, name) >= 0); |
| 23924 | var cProperty = _.cloneDeep(property); |
| 23925 | |
| 23926 | var requiredClass = propertyIsRequired ? 'required' : ''; |
| 23927 | var html = '<span class="propName ' + requiredClass + '">' + name + '</span> ('; |
| 23928 | var model; |
| 23929 | |
| 23930 | // Allow macro to set the default value |
| 23931 | cProperty.default = modelPropertyMacro(cProperty); |
| 23932 | |
| 23933 | // Resolve the schema (Handle nested schemas) |
| 23934 | cProperty = resolveSchema(cProperty); |
| 23935 | |
| 23936 | // We need to handle property references to primitives (Issue 339) |
| 23937 | if (!_.isUndefined(cProperty.$ref)) { |
| 23938 | model = models[simpleRef(cProperty.$ref)]; |
| 23939 | |
| 23940 | if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) { |
| 23941 | // Use referenced schema |
| 23942 | cProperty = resolveSchema(model.definition); |
| 23943 | } |
| 23944 | } |
| 23945 | |
| 23946 | html += primitiveToHTML(cProperty); |
| 23947 | |
| 23948 | if(!propertyIsRequired) { |
| 23949 | html += ', <span class="propOptKey">optional</span>'; |
| 23950 | } |
| 23951 | |
| 23952 | if(property.readOnly) { |
| 23953 | html += ', <span class="propReadOnly">read only</span>'; |
| 23954 | } |
| 23955 | |
| 23956 | html += ')'; |
| 23957 | |
| 23958 | return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html); |
| 23959 | }).join(',</div>'); |
| 23960 | } |
| 23961 | |
| 23962 | if (contents) { |
| 23963 | html += contents + '</div>'; |
| 23964 | } |
| 23965 | } else { |
| 23966 | html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>'; |
| 23967 | } |
| 23968 | } |
| 23969 | |
| 23970 | return html + strongOpen + (isArray ? ']' : '}') + strongClose; |
| 23971 | } |
| 23972 | |
| 23973 | }; |
| 23974 | |
| 23975 | // copy-pasted from swagger-js |
| 23976 | var schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) { |
| 23977 | // Resolve the schema (Handle nested schemas) |
| 23978 | schema = resolveSchema(schema); |
| 23979 | |
| 23980 | if(typeof modelPropertyMacro !== 'function') { |
| 23981 | modelPropertyMacro = function(prop){ |
| 23982 | return (prop || {}).default; |
| 23983 | }; |
| 23984 | } |
| 23985 | |
| 23986 | modelsToIgnore= modelsToIgnore || {}; |
| 23987 | |
| 23988 | var type = schema.type || 'object'; |
| 23989 | var format = schema.format; |
| 23990 | var model; |
| 23991 | var output; |
| 23992 | |
| 23993 | if (!_.isUndefined(schema.example)) { |
| 23994 | output = schema.example; |
| 23995 | } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) { |
| 23996 | output = schema.enum[0]; |
| 23997 | } |
| 23998 | |
| 23999 | if (_.isUndefined(output)) { |
| 24000 | if (schema.$ref) { |
| 24001 | model = models[simpleRef(schema.$ref)]; |
| 24002 | |
| 24003 | if (!_.isUndefined(model)) { |
| 24004 | if (_.isUndefined(modelsToIgnore[model.name])) { |
| 24005 | modelsToIgnore[model.name] = model; |
| 24006 | output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro); |
| 24007 | delete modelsToIgnore[model.name]; |
| 24008 | } else { |
| 24009 | if (model.type === 'array') { |
| 24010 | output = []; |
| 24011 | } else { |
| 24012 | output = {}; |
| 24013 | } |
| 24014 | } |
| 24015 | } |
| 24016 | } else if (!_.isUndefined(schema.default)) { |
| 24017 | output = schema.default; |
| 24018 | } else if (type === 'string') { |
| 24019 | if (format === 'date-time') { |
| 24020 | output = new Date().toISOString(); |
| 24021 | } else if (format === 'date') { |
| 24022 | output = new Date().toISOString().split('T')[0]; |
| 24023 | } else { |
| 24024 | output = 'string'; |
| 24025 | } |
| 24026 | } else if (type === 'integer') { |
| 24027 | output = 0; |
| 24028 | } else if (type === 'number') { |
| 24029 | output = 0.0; |
| 24030 | } else if (type === 'boolean') { |
| 24031 | output = true; |
| 24032 | } else if (type === 'object') { |
| 24033 | output = {}; |
| 24034 | |
| 24035 | _.forEach(schema.properties, function (property, name) { |
| 24036 | var cProperty = _.cloneDeep(property); |
| 24037 | |
| 24038 | // Allow macro to set the default value |
| 24039 | cProperty.default = modelPropertyMacro(property); |
| 24040 | |
| 24041 | output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro); |
| 24042 | }); |
| 24043 | } else if (type === 'array') { |
| 24044 | output = []; |
| 24045 | |
| 24046 | if (_.isArray(schema.items)) { |
| 24047 | _.forEach(schema.items, function (item) { |
| 24048 | output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro)); |
| 24049 | }); |
| 24050 | } else if (_.isPlainObject(schema.items)) { |
| 24051 | output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro)); |
| 24052 | } else if (_.isUndefined(schema.items)) { |
| 24053 | output.push({}); |
| 24054 | } else { |
| 24055 | console.log('Array type\'s \'items\' property is not an array or an object, cannot process'); |
| 24056 | } |
| 24057 | } |
| 24058 | } |
| 24059 | |
| 24060 | return output; |
| 24061 | }; |
| 24062 | |
| 24063 | // copy-pasted from swagger-js |
| 24064 | var createJSONSample = function (value, modelsToIgnore) { |
| 24065 | modelsToIgnore = modelsToIgnore || {}; |
| 24066 | |
| 24067 | modelsToIgnore[value.name] = value; |
| 24068 | |
| 24069 | // Response support |
| 24070 | if (value.examples && _.isPlainObject(value.examples) && value.examples['application/json']) { |
| 24071 | value.definition.example = value.examples['application/json']; |
| 24072 | |
| 24073 | if (_.isString(value.definition.example)) { |
| 24074 | value.definition.example = jsyaml.safeLoad(value.definition.example); |
| 24075 | } |
| 24076 | } else if (!value.definition.example) { |
| 24077 | value.definition.example = value.examples; |
| 24078 | } |
| 24079 | |
| 24080 | return schemaToJSON(value.definition, value.models, modelsToIgnore, value.modelPropertyMacro); |
| 24081 | }; |
| 24082 | |
| 24083 | // copy-pasted from swagger-js |
| 24084 | var getParameterModelSignature = function (type, definitions) { |
| 24085 | var isPrimitive, listType; |
| 24086 | |
| 24087 | if (type instanceof Array) { |
| 24088 | listType = true; |
| 24089 | type = type[0]; |
| 24090 | } |
| 24091 | |
| 24092 | // Convert undefined to string of 'undefined' |
| 24093 | if (typeof type === 'undefined') { |
| 24094 | type = 'undefined'; |
| 24095 | isPrimitive = true; |
| 24096 | |
| 24097 | } else if (definitions[type]){ |
| 24098 | // a model def exists? |
| 24099 | type = definitions[type]; /* Model */ |
| 24100 | isPrimitive = false; |
| 24101 | |
| 24102 | } else if (getInlineModel(type)) { |
| 24103 | type = getInlineModel(type); /* Model */ |
| 24104 | isPrimitive = false; |
| 24105 | |
| 24106 | } else { |
| 24107 | // We default to primitive |
| 24108 | isPrimitive = true; |
| 24109 | } |
| 24110 | |
| 24111 | if (isPrimitive) { |
| 24112 | if (listType) { |
| 24113 | return 'Array[' + type + ']'; |
| 24114 | } else { |
| 24115 | return type.toString(); |
| 24116 | } |
| 24117 | } else { |
| 24118 | if (listType) { |
| 24119 | return 'Array[' + getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro) + ']'; |
| 24120 | } else { |
| 24121 | return getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro); |
| 24122 | } |
| 24123 | } |
| 24124 | }; |
| 24125 | |
| 24126 | // copy-pasted from swagger-js |
| 24127 | var createParameterJSONSample = function (type, models) { |
| 24128 | var listType, sampleJson, innerType; |
| 24129 | models = models || {}; |
| 24130 | |
| 24131 | listType = (type instanceof Array); |
| 24132 | innerType = listType ? type[0] : type; |
| 24133 | |
| 24134 | if(models[innerType]) { |
| 24135 | sampleJson = createJSONSample(models[innerType]); |
| 24136 | } else if (getInlineModel(innerType)){ |
| 24137 | sampleJson = createJSONSample(getInlineModel(innerType)); // may return null, if type isn't correct |
| 24138 | } |
| 24139 | |
| 24140 | |
| 24141 | if (sampleJson) { |
| 24142 | sampleJson = listType ? [sampleJson] : sampleJson; |
| 24143 | |
| 24144 | if (typeof sampleJson === 'string') { |
| 24145 | return sampleJson; |
| 24146 | } else if (_.isObject(sampleJson)) { |
| 24147 | var t = sampleJson; |
| 24148 | |
| 24149 | if (sampleJson instanceof Array && sampleJson.length > 0) { |
| 24150 | t = sampleJson[0]; |
| 24151 | } |
| 24152 | |
| 24153 | if (t.nodeName && typeof t === 'Node') { |
| 24154 | var xmlString = new XMLSerializer().serializeToString(t); |
| 24155 | |
| 24156 | return formatXml(xmlString); |
| 24157 | } else { |
| 24158 | return JSON.stringify(sampleJson, null, 2); |
| 24159 | } |
| 24160 | } else { |
| 24161 | return sampleJson; |
| 24162 | } |
| 24163 | } |
| 24164 | }; |
| 24165 | |
| 24166 | var wrapTag = function (name, value, attrs) { |
| 24167 | var str, attributes; |
| 24168 | |
| 24169 | attrs = attrs || []; |
| 24170 | |
| 24171 | attributes = attrs.map(function (attr) { |
| 24172 | return ' ' + attr.name + '="' + attr.value + '"'; |
| 24173 | }).join(''); |
| 24174 | |
| 24175 | if (!name) { |
| 24176 | return getErrorMessage('Node name is not provided'); |
| 24177 | } |
| 24178 | |
| 24179 | str = [ |
| 24180 | '<', name, |
| 24181 | attributes, |
| 24182 | '>', |
| 24183 | value, |
| 24184 | '</', name, '>' |
| 24185 | ]; |
| 24186 | |
| 24187 | return str.join(''); |
| 24188 | }; |
| 24189 | |
| 24190 | var getName = function (name, xml) { |
| 24191 | var result = name || ''; |
| 24192 | |
| 24193 | xml = xml || {}; |
| 24194 | |
| 24195 | if (xml.name) { |
| 24196 | result = xml.name; |
| 24197 | } |
| 24198 | |
| 24199 | if (xml.prefix) { |
| 24200 | result = xml.prefix + ':' + result; |
| 24201 | } |
| 24202 | |
| 24203 | return result; |
| 24204 | }; |
| 24205 | |
| 24206 | var getNamespace = function (xml) { |
| 24207 | var namespace = ''; |
| 24208 | var name = 'xmlns'; |
| 24209 | |
| 24210 | xml = xml || {}; |
| 24211 | |
| 24212 | if (xml.namespace) { |
| 24213 | namespace = xml.namespace; |
| 24214 | } else { |
| 24215 | return namespace; |
| 24216 | } |
| 24217 | |
| 24218 | if (xml.prefix) { |
| 24219 | name += ':' + xml.prefix; |
| 24220 | } |
| 24221 | |
| 24222 | return { |
| 24223 | name: name, |
| 24224 | value: namespace |
| 24225 | }; |
| 24226 | }; |
| 24227 | |
| 24228 | var createArrayXML = function (descriptor) { |
| 24229 | var name = descriptor.name; |
| 24230 | var config = descriptor.config; |
| 24231 | var definition = descriptor.definition; |
| 24232 | var models = descriptor.models; |
| 24233 | var value; |
| 24234 | var items = definition.items; |
| 24235 | var xml = definition.xml || {}; |
| 24236 | var namespace = getNamespace(xml); |
| 24237 | var attributes = []; |
| 24238 | |
| 24239 | if (!items) { return getErrorMessage(); } |
| 24240 | |
| 24241 | value = createSchemaXML(name, items, models, config); |
| 24242 | |
| 24243 | if (namespace) { |
| 24244 | attributes.push(namespace); |
| 24245 | } |
| 24246 | |
| 24247 | if (xml.wrapped) { |
| 24248 | value = wrapTag(name, value, attributes); |
| 24249 | } |
| 24250 | |
| 24251 | return value; |
| 24252 | }; |
| 24253 | |
| 24254 | var getPrimitiveSignature = function (schema) { |
| 24255 | var type, items; |
| 24256 | |
| 24257 | schema = schema || {}; |
| 24258 | items = schema.items || {}; |
| 24259 | type = schema.type || ''; |
| 24260 | |
| 24261 | switch (type) { |
| 24262 | case 'object': return 'Object is not a primitive'; |
| 24263 | case 'array' : return 'Array[' + (items.format || items.type) + ']'; |
| 24264 | default: return schema.format || type; |
| 24265 | } |
| 24266 | }; |
| 24267 | |
| 24268 | var createPrimitiveXML = function (descriptor) { |
| 24269 | var name = descriptor.name; |
| 24270 | var definition = descriptor.definition; |
| 24271 | var primitivesMap = { |
| 24272 | 'string': { |
| 24273 | 'date': new Date(1).toISOString().split('T')[0], |
| 24274 | 'date-time' : new Date(1).toISOString(), |
| 24275 | 'default': 'string' |
| 24276 | }, |
| 24277 | 'integer': { |
| 24278 | 'default': 1 |
| 24279 | }, |
| 24280 | 'number': { |
| 24281 | 'default': 1.1 |
| 24282 | }, |
| 24283 | 'boolean': { |
| 24284 | 'default': true |
| 24285 | } |
| 24286 | }; |
| 24287 | var type = definition.type; |
| 24288 | var format = definition.format; |
| 24289 | var xml = definition.xml || {}; |
| 24290 | var namespace = getNamespace(xml); |
| 24291 | var attributes = []; |
| 24292 | var value; |
| 24293 | |
| 24294 | if (_.keys(primitivesMap).indexOf(type) < 0) { return getErrorMessage(); } |
| 24295 | |
| 24296 | if (_.isArray(definition.enum)){ |
| 24297 | value = definition.enum[0]; |
| 24298 | } else { |
| 24299 | value = definition.example || primitivesMap[type][format] || primitivesMap[type].default; |
| 24300 | } |
| 24301 | |
| 24302 | if (xml.attribute) { |
| 24303 | return {name: name, value: value}; |
| 24304 | } |
| 24305 | |
| 24306 | if (namespace) { |
| 24307 | attributes.push(namespace); |
| 24308 | } |
| 24309 | |
| 24310 | return wrapTag(name, value, attributes); |
| 24311 | }; |
| 24312 | |
| 24313 | function createObjectXML (descriptor) { |
| 24314 | var name = descriptor.name; |
| 24315 | var definition = descriptor.definition; |
| 24316 | var config = descriptor.config; |
| 24317 | var models = descriptor.models; |
| 24318 | var isParam = descriptor.config.isParam; |
| 24319 | var serializedProperties; |
| 24320 | var attrs = []; |
| 24321 | var properties = definition.properties; |
| 24322 | var additionalProperties = definition.additionalProperties; |
| 24323 | var xml = definition.xml; |
| 24324 | var namespace = getNamespace(xml); |
| 24325 | |
| 24326 | if (namespace) { |
| 24327 | attrs.push(namespace); |
| 24328 | } |
| 24329 | |
| 24330 | if (!properties && !additionalProperties) { return getErrorMessage(); } |
| 24331 | |
| 24332 | properties = properties || {}; |
| 24333 | |
| 24334 | serializedProperties = _.map(properties, function (prop, key) { |
| 24335 | var xml, result; |
| 24336 | |
| 24337 | if (isParam && prop.readOnly) { |
| 24338 | return ''; |
| 24339 | } |
| 24340 | |
| 24341 | xml = prop.xml || {}; |
| 24342 | result = createSchemaXML(key, prop, models, config); |
| 24343 | |
| 24344 | if (xml.attribute) { |
| 24345 | attrs.push(result); |
| 24346 | return ''; |
| 24347 | } |
| 24348 | |
| 24349 | return result; |
| 24350 | }).join(''); |
| 24351 | |
| 24352 | if (additionalProperties) { |
| 24353 | serializedProperties += '<!-- additional elements allowed -->'; |
| 24354 | } |
| 24355 | |
| 24356 | return wrapTag(name, serializedProperties, attrs); |
| 24357 | } |
| 24358 | |
| 24359 | function getInfiniteLoopMessage (name, loopTo) { |
| 24360 | return wrapTag(name, '<!-- Infinite loop $ref:' + loopTo + ' -->'); |
| 24361 | } |
| 24362 | |
| 24363 | function getErrorMessage (details) { |
| 24364 | details = details ? ': ' + details : ''; |
| 24365 | return '<!-- invalid XML' + details + ' -->'; |
| 24366 | } |
| 24367 | |
| 24368 | function createSchemaXML (name, definition, models, config) { |
| 24369 | var $ref = _.isObject(definition) ? definition.$ref : null; |
| 24370 | var output, index; |
| 24371 | config = config || {}; |
| 24372 | config.modelsToIgnore = config.modelsToIgnore || []; |
| 24373 | var descriptor = _.isString($ref) ? getDescriptorByRef($ref, name, models, config) |
| 24374 | : getDescriptor(name, definition, models, config); |
| 24375 | |
| 24376 | if (!descriptor) { |
| 24377 | return getErrorMessage(); |
| 24378 | } |
| 24379 | |
| 24380 | switch (descriptor.type) { |
| 24381 | case 'array': |
| 24382 | output = createArrayXML(descriptor); break; |
| 24383 | case 'object': |
| 24384 | output = createObjectXML(descriptor); break; |
| 24385 | case 'loop': |
| 24386 | output = getInfiniteLoopMessage(descriptor.name, descriptor.config.loopTo); break; |
| 24387 | default: |
| 24388 | output = createPrimitiveXML(descriptor); |
| 24389 | } |
| 24390 | |
| 24391 | if ($ref && descriptor.type !== 'loop') { |
| 24392 | index = config.modelsToIgnore.indexOf($ref); |
| 24393 | if (index > -1) { |
| 24394 | config.modelsToIgnore.splice(index, 1); |
| 24395 | } |
| 24396 | } |
| 24397 | |
| 24398 | return output; |
| 24399 | } |
| 24400 | |
| 24401 | function Descriptor (name, type, definition, models, config) { |
| 24402 | if (arguments.length < 4) { |
| 24403 | throw new Error(); |
| 24404 | } |
| 24405 | |
| 24406 | this.config = config || {}; |
| 24407 | this.config.modelsToIgnore = this.config.modelsToIgnore || []; |
| 24408 | this.name = getName(name, definition.xml); |
| 24409 | this.definition = definition; |
| 24410 | this.models = models; |
| 24411 | this.type = type; |
| 24412 | } |
| 24413 | |
| 24414 | function getDescriptorByRef($ref, name, models, config) { |
| 24415 | var modelType = simpleRef($ref); |
| 24416 | var model = models[modelType] || {}; |
| 24417 | var type = model.definition && model.definition.type ? model.definition.type : 'object'; |
| 24418 | name = name || model.name; |
| 24419 | |
| 24420 | if (config.modelsToIgnore.indexOf($ref) > -1) { |
| 24421 | type = 'loop'; |
| 24422 | config.loopTo = modelType; |
| 24423 | } else { |
| 24424 | config.modelsToIgnore.push($ref); |
| 24425 | } |
| 24426 | |
| 24427 | if (!model.definition) { |
| 24428 | return null; |
| 24429 | } |
| 24430 | |
| 24431 | return new Descriptor(name, type, model.definition, models, config); |
| 24432 | } |
| 24433 | |
| 24434 | function getDescriptor (name, definition, models, config){ |
| 24435 | var type = definition.type || 'object'; |
| 24436 | |
| 24437 | if (!definition) { |
| 24438 | return null; |
| 24439 | } |
| 24440 | |
| 24441 | return new Descriptor(name, type, definition, models, config); |
| 24442 | } |
| 24443 | |
| 24444 | function createXMLSample (name, definition, models, isParam) { |
| 24445 | var prolog = '<?xml version="1.0"?>'; |
| 24446 | |
| 24447 | return formatXml(prolog + createSchemaXML(name, definition, models, { isParam: isParam } )); |
| 24448 | } |
| 24449 | |
| 24450 | return { |
| 24451 | getModelSignature: getModelSignature, |
| 24452 | createJSONSample: createJSONSample, |
| 24453 | getParameterModelSignature: getParameterModelSignature, |
| 24454 | createParameterJSONSample: createParameterJSONSample, |
| 24455 | createSchemaXML: createSchemaXML, |
| 24456 | createXMLSample: createXMLSample, |
| 24457 | getPrimitiveSignature: getPrimitiveSignature |
| 24458 | }; |
| 24459 | |
| 24460 | })(); |
| 24461 | |
| 24462 | 'use strict'; |
| 24463 | |
| 24464 | SwaggerUi.Views.PopupView = Backbone.View.extend({ |
| 24465 | events: { |
| 24466 | 'click .api-popup-cancel': 'cancelClick' |
| 24467 | }, |
| 24468 | |
| 24469 | template: Handlebars.templates.popup, |
| 24470 | className: 'api-popup-dialog', |
| 24471 | |
| 24472 | selectors: { |
| 24473 | content: '.api-popup-content', |
| 24474 | main : '#swagger-ui-container' |
| 24475 | }, |
| 24476 | |
| 24477 | initialize: function(){ |
| 24478 | this.$el.html(this.template(this.model)); |
| 24479 | }, |
| 24480 | |
| 24481 | render: function () { |
| 24482 | this.$(this.selectors.content).append(this.model.content); |
| 24483 | $(this.selectors.main).first().append(this.el); |
| 24484 | this.showPopup(); |
| 24485 | |
| 24486 | return this; |
| 24487 | }, |
| 24488 | |
| 24489 | showPopup: function () { |
| 24490 | this.$el.show(); |
| 24491 | }, |
| 24492 | |
| 24493 | cancelClick: function () { |
| 24494 | this.remove(); |
| 24495 | } |
| 24496 | |
| 24497 | }); |
| 24498 | |
| 24499 | 'use strict'; |
| 24500 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24501 | SwaggerUi.Views.ResourceView = Backbone.View.extend({ |
| 24502 | initialize: function(opts) { |
| 24503 | opts = opts || {}; |
| 24504 | this.router = opts.router; |
| 24505 | this.auths = opts.auths; |
| 24506 | if ('' === this.model.description) { |
| 24507 | this.model.description = null; |
| 24508 | } |
| 24509 | if (this.model.description) { |
| 24510 | this.model.summary = this.model.description; |
| 24511 | } |
| 24512 | }, |
| 24513 | |
| 24514 | render: function(){ |
| 24515 | var methods = {}; |
| 24516 | |
| 24517 | |
| 24518 | $(this.el).html(Handlebars.templates.resource(this.model)); |
| 24519 | |
| 24520 | // Render each operation |
| 24521 | for (var i = 0; i < this.model.operationsArray.length; i++) { |
| 24522 | var operation = this.model.operationsArray[i]; |
| 24523 | var counter = 0; |
| 24524 | var id = operation.nickname; |
| 24525 | |
| 24526 | while (typeof methods[id] !== 'undefined') { |
| 24527 | id = id + '_' + counter; |
| 24528 | counter += 1; |
| 24529 | } |
| 24530 | |
| 24531 | methods[id] = operation; |
| 24532 | |
| 24533 | operation.nickname = id; |
| 24534 | operation.parentId = this.model.id; |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 24535 | operation.definitions = this.model.definitions; // make Json Schema available for JSonEditor in this operation |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24536 | this.addOperation(operation); |
| 24537 | } |
| 24538 | |
| 24539 | $('.toggleEndpointList', this.el).click(this.callDocs.bind(this, 'toggleEndpointListForResource')); |
| 24540 | $('.collapseResource', this.el).click(this.callDocs.bind(this, 'collapseOperationsForResource')); |
| 24541 | $('.expandResource', this.el).click(this.callDocs.bind(this, 'expandOperationsForResource')); |
| 24542 | |
| 24543 | return this; |
| 24544 | }, |
| 24545 | |
| 24546 | addOperation: function(operation) { |
| 24547 | |
| 24548 | operation.number = this.number; |
| 24549 | |
| 24550 | // Render an operation and add it to operations li |
| 24551 | var operationView = new SwaggerUi.Views.OperationView({ |
| 24552 | model: operation, |
| 24553 | router: this.router, |
| 24554 | tagName: 'li', |
| 24555 | className: 'endpoint', |
| 24556 | swaggerOptions: this.options.swaggerOptions, |
| 24557 | auths: this.auths |
| 24558 | }); |
| 24559 | |
| 24560 | $('.endpoints', $(this.el)).append(operationView.render().el); |
| 24561 | |
| 24562 | this.number++; |
| 24563 | |
| 24564 | }, |
| 24565 | // Generic Event handler (`Docs` is global) |
| 24566 | |
| 24567 | |
| 24568 | callDocs: function(fnName, e) { |
| 24569 | e.preventDefault(); |
| 24570 | Docs[fnName](e.currentTarget.getAttribute('data-id')); |
| 24571 | } |
| 24572 | }); |
| 24573 | 'use strict'; |
| 24574 | |
| 24575 | SwaggerUi.Views.ResponseContentTypeView = Backbone.View.extend({ |
| 24576 | initialize: function(){}, |
| 24577 | |
| 24578 | render: function(){ |
| 24579 | this.model.responseContentTypeId = 'rct' + Math.random(); |
| 24580 | $(this.el).html(Handlebars.templates.response_content_type(this.model)); |
| 24581 | return this; |
| 24582 | } |
| 24583 | }); |
| 24584 | 'use strict'; |
| 24585 | |
| 24586 | SwaggerUi.Views.SignatureView = Backbone.View.extend({ |
| 24587 | events: { |
| 24588 | 'click a.description-link' : 'switchToDescription', |
| 24589 | 'click a.snippet-link' : 'switchToSnippet', |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 24590 | 'mousedown .snippet_json' : 'jsonSnippetMouseDown', |
| 24591 | 'mousedown .snippet_xml' : 'xmlSnippetMouseDown' |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24592 | }, |
| 24593 | |
| 24594 | initialize: function () { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24595 | }, |
| 24596 | |
| 24597 | render: function(){ |
| 24598 | |
| 24599 | $(this.el).html(Handlebars.templates.signature(this.model)); |
| 24600 | |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 24601 | if (this.model.defaultRendering === 'model') { |
| 24602 | this.switchToDescription(); |
| 24603 | } else { |
| 24604 | this.switchToSnippet(); |
| 24605 | } |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24606 | |
| 24607 | return this; |
| 24608 | }, |
| 24609 | |
| 24610 | // handler for show signature |
| 24611 | switchToDescription: function(e){ |
| 24612 | if (e) { e.preventDefault(); } |
| 24613 | |
| 24614 | $('.snippet', $(this.el)).hide(); |
| 24615 | $('.description', $(this.el)).show(); |
| 24616 | $('.description-link', $(this.el)).addClass('selected'); |
| 24617 | $('.snippet-link', $(this.el)).removeClass('selected'); |
| 24618 | }, |
| 24619 | |
| 24620 | // handler for show sample |
| 24621 | switchToSnippet: function(e){ |
| 24622 | if (e) { e.preventDefault(); } |
| 24623 | |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24624 | $('.snippet', $(this.el)).show(); |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 24625 | $('.description', $(this.el)).hide(); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24626 | $('.snippet-link', $(this.el)).addClass('selected'); |
| 24627 | $('.description-link', $(this.el)).removeClass('selected'); |
| 24628 | }, |
| 24629 | |
| 24630 | // handler for snippet to text area |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 24631 | snippetToTextArea: function(val) { |
| 24632 | var textArea = $('textarea', $(this.el.parentNode.parentNode.parentNode)); |
| 24633 | |
| 24634 | // Fix for bug in IE 10/11 which causes placeholder text to be copied to "value" |
| 24635 | if ($.trim(textArea.val()) === '' || textArea.prop('placeholder') === textArea.val()) { |
| 24636 | textArea.val(val); |
| 24637 | // TODO move this code outside of the view and expose an event instead |
| 24638 | if( this.model.jsonEditor && this.model.jsonEditor.isEnabled()){ |
| 24639 | this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON)); |
| 24640 | } |
| 24641 | } |
| 24642 | }, |
| 24643 | |
| 24644 | jsonSnippetMouseDown: function (e) { |
| 24645 | if (this.model.isParam) { |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24646 | if (e) { e.preventDefault(); } |
| 24647 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 24648 | this.snippetToTextArea(this.model.sampleJSON); |
| 24649 | } |
| 24650 | }, |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 24651 | |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 24652 | xmlSnippetMouseDown: function (e) { |
| 24653 | if (this.model.isParam) { |
| 24654 | if (e) { e.preventDefault(); } |
| 24655 | |
| 24656 | this.snippetToTextArea(this.model.sampleXML); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24657 | } |
| 24658 | } |
| 24659 | }); |
| 24660 | 'use strict'; |
| 24661 | |
| 24662 | SwaggerUi.Views.StatusCodeView = Backbone.View.extend({ |
| 24663 | initialize: function (opts) { |
| 24664 | this.options = opts || {}; |
| 24665 | this.router = this.options.router; |
| 24666 | }, |
| 24667 | |
| 24668 | render: function(){ |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 24669 | var responseModel, responseModelView; |
| 24670 | var value = this.router.api.models[this.model.responseModel]; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24671 | $(this.el).html(Handlebars.templates.status_code(this.model)); |
| 24672 | |
| 24673 | if (this.router.api.models.hasOwnProperty(this.model.responseModel)) { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 24674 | responseModel = { |
| 24675 | sampleJSON: JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2), |
| 24676 | sampleXML: this.model.isXML ? SwaggerUi.partials.signature.createXMLSample('', this.model.schema, this.router.api.models) : false, |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24677 | isParam: false, |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 24678 | signature: SwaggerUi.partials.signature.getModelSignature(this.model.responseModel, value, this.router.api.models), |
Jian Li | 83d87a7 | 2016-04-20 15:38:24 -0700 | [diff] [blame] | 24679 | defaultRendering: this.model.defaultRendering |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24680 | }; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24681 | } else { |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 24682 | responseModel = { |
| 24683 | signature: SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema) |
| 24684 | }; |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24685 | } |
Jian Li | 8afbbee | 2016-07-27 19:16:51 +0900 | [diff] [blame] | 24686 | |
| 24687 | responseModelView = new SwaggerUi.Views.SignatureView({model: responseModel, tagName: 'div'}); |
| 24688 | $('.model-signature', this.$el).append(responseModelView.render().el); |
Thomas Vachuska | 0fa2aa1 | 2015-08-18 12:53:04 -0700 | [diff] [blame] | 24689 | return this; |
| 24690 | } |
| 24691 | });}).call(this); |